Merge
This commit is contained in:
commit
296990a1e8
@ -430,3 +430,5 @@ df64bd4757d0d130d62a22b8143ba31d3a16ac18 jdk-10+10
|
||||
a5506b425f1bf91530d8417b57360e5d89328c0c jdk-9+173
|
||||
42f18c931bd4fae5c206ccf6d8e591e4c4e69d31 jdk-9+174
|
||||
5f504872a75b71f2fb19299f0d1e3395cf32eaa0 jdk-10+12
|
||||
e6c4f6ef717d104dba880e2dae538690c993b46f jdk-9+175
|
||||
4540d6376f3ef22305cca546f85f9b2ce9a210c4 jdk-10+13
|
||||
|
@ -1 +1,2 @@
|
||||
project=jdk10
|
||||
bugids=dup
|
||||
|
@ -49,7 +49,4 @@ TOOL_ADD_PACKAGES_ATTRIBUTE := $(BUILD_JAVA) $(JAVA_FLAGS_SMALL) \
|
||||
--add-exports java.base/jdk.internal.module=ALL-UNNAMED \
|
||||
build.tools.jigsaw.AddPackagesAttribute
|
||||
|
||||
TOOL_GEN_DOCS_BUNDLE_PAGE := $(BUILD_JAVA) -esa -ea -cp $(TOOLS_CLASSES_DIR) \
|
||||
build.tools.docs.GenDocsBundlePage
|
||||
|
||||
endif # _MODULE_TOOLS_GMK
|
||||
|
@ -278,7 +278,6 @@ SUNWprivate_1.1 {
|
||||
Java_java_lang_Module_addExports0;
|
||||
Java_java_lang_Module_addExportsToAll0;
|
||||
Java_java_lang_Module_addExportsToAllUnnamed0;
|
||||
Java_java_lang_Module_addPackage0;
|
||||
|
||||
Java_jdk_internal_loader_BootLoader_getSystemPackageLocation;
|
||||
Java_jdk_internal_loader_BootLoader_getSystemPackageNames;
|
||||
|
@ -1,247 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package build.tools.docs;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleFinder;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
import static java.util.stream.Collectors.*;
|
||||
|
||||
/**
|
||||
* Build tool to generate the docs bundle index page.
|
||||
*/
|
||||
public class GenDocsBundlePage {
|
||||
private static String DOCS_BUNDLE_PAGE = "docs-bundle-page.html";
|
||||
private static String MODULE_GROUPS_PROPS = "docs-module-groups.properties";
|
||||
|
||||
private static String USAGE =
|
||||
"GenDocsBundlePage --output <file path> --title <title>" +
|
||||
" [--template <template>]";
|
||||
|
||||
public static void main(String... args) throws IOException {
|
||||
String title = null;
|
||||
Path outputfile = null;
|
||||
Path template = null;
|
||||
for (int i=0; i < args.length; i++) {
|
||||
String option = args[i];
|
||||
if (option.equals("--output")) {
|
||||
outputfile = Paths.get(getArgument(args, option, ++i));
|
||||
} else if (option.equals("--title")) {
|
||||
title = getArgument(args, option, ++i);
|
||||
} else if (option.equals("--template")) {
|
||||
template = Paths.get(getArgument(args, option, ++i));
|
||||
} else if (option.startsWith("-")) {
|
||||
throw new IllegalArgumentException("Invalid option: " + option);
|
||||
}
|
||||
}
|
||||
|
||||
if (outputfile == null) {
|
||||
System.err.println("ERROR: must specify --output option");
|
||||
System.exit(1);
|
||||
}
|
||||
if (title == null) {
|
||||
System.err.println("ERROR: must specify --title option");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
try (InputStream is = readTemplate(template);
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(is)))
|
||||
{
|
||||
new GenDocsBundlePage(title, outputfile).run(reader);
|
||||
}
|
||||
}
|
||||
|
||||
private static String getArgument(String[] args, String option, int index) {
|
||||
if (index < args.length) {
|
||||
return args[index];
|
||||
}
|
||||
throw new IllegalArgumentException("Argument must be specified for " + option);
|
||||
}
|
||||
|
||||
private static InputStream readTemplate(Path template) throws IOException {
|
||||
if (template != null) {
|
||||
return Files.newInputStream(template);
|
||||
} else {
|
||||
return GenDocsBundlePage.class.getResourceAsStream(DOCS_BUNDLE_PAGE);
|
||||
}
|
||||
}
|
||||
|
||||
private static final String HEADER_TITLE = "@HEADER_TITLE@";
|
||||
|
||||
|
||||
final Path outputfile;
|
||||
final String title;
|
||||
final Map<String, Set<ModuleDescriptor>> moduleGroups = new HashMap<>();
|
||||
GenDocsBundlePage(String title, Path outputfile) throws IOException
|
||||
{
|
||||
this.outputfile = outputfile;
|
||||
this.title = title;
|
||||
|
||||
// read module groups
|
||||
ModuleFinder finder = ModuleFinder.ofSystem();
|
||||
try (InputStream in = GenDocsBundlePage.class.getResourceAsStream(MODULE_GROUPS_PROPS)) {
|
||||
Properties props = new Properties();
|
||||
props.load(in);
|
||||
for (String key: props.stringPropertyNames()) {
|
||||
Set<ModuleDescriptor> mods =
|
||||
Stream.of(props.getProperty(key).split("\\s+"))
|
||||
.map(String::trim)
|
||||
.flatMap(mn -> finder.find(mn).stream())
|
||||
.map(ModuleReference::descriptor)
|
||||
.collect(toSet());
|
||||
|
||||
String name = "@" + key.toUpperCase(Locale.ENGLISH) + "@";
|
||||
moduleGroups.put(name, mods);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void run(BufferedReader reader) throws IOException {
|
||||
if (Files.notExists(outputfile.getParent())) {
|
||||
Files.createDirectories(outputfile.getParent());
|
||||
}
|
||||
try (BufferedWriter bw = Files.newBufferedWriter(outputfile, StandardCharsets.UTF_8);
|
||||
PrintWriter writer = new PrintWriter(bw)) {
|
||||
reader.lines().map(this::genOutputLine)
|
||||
.forEach(writer::println);
|
||||
}
|
||||
}
|
||||
|
||||
String genOutputLine(String line) {
|
||||
if (line.contains(HEADER_TITLE)) {
|
||||
line = line.replace(HEADER_TITLE, title);
|
||||
}
|
||||
int i = line.indexOf('@');
|
||||
int j = line.indexOf('@', i+1);
|
||||
if (i >= 0 && i < j) {
|
||||
String name = line.substring(i, j+1);
|
||||
if (moduleGroups.containsKey(name)) {
|
||||
line = line.replace(name, formatModuleGroup(name));
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,171 +0,0 @@
|
||||
<!--
|
||||
Copyright (c) 2017, 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. Oracle designates this
|
||||
particular file as subject to the "Classpath" exception as provided
|
||||
by Oracle in the LICENSE file that accompanied this code.
|
||||
|
||||
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.
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>@HEADER_TITLE@</title>
|
||||
|
||||
<meta http-equiv="content-type" content="text/html;" charset="utf-8">
|
||||
<link rel="stylesheet" href="resources/jdk-default.css" 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 {
|
||||
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>
|
||||
</head>
|
||||
|
||||
<h1>@HEADER_TITLE@</h1>
|
||||
|
||||
<ul>
|
||||
<li><a href="api/index.html">JDK API Specification</a></li>
|
||||
<li><a href="https://docs.oracle.com/javase/specs/">
|
||||
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>
|
||||
|
||||
|
||||
<table>
|
||||
<caption style="display:none">JDK Modules</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Group</th>
|
||||
<th scope="col">Modules</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">Foundation</th>
|
||||
<td>@JAVA_BASE@</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Integration</th>
|
||||
<td>@INTEGRATION_MODULES@</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">User Interface</th>
|
||||
<td>@UI_MODULES@</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Compilation</th>
|
||||
<td>@COMPILER_MODULES@</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Scripting</th>
|
||||
<td>@SCRIPTING_MODULES@</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Security</th>
|
||||
<td>@SECURITY_MODULES@</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<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>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Non-Java SE</th>
|
||||
<td>@OTHER_MODULES@</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Java EE</th>
|
||||
<td>@JAVA_EE_MODULES@</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Aggregator</th>
|
||||
<td>@AGGREGATOR_MODULES@</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p class="key">Key:
|
||||
<ul class="key">
|
||||
<li><span class="javase"> </span> Java SE
|
||||
<li><span class="jdk"> </span> JDK
|
||||
<li><span class="javafx"> </span> JavaFX
|
||||
<li><span class="jcp"> </span> Non-Java SE
|
||||
<li><i>italic</i> No Exported API (e.g. a tool or provider)</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
<hr>
|
||||
<a href="legal/cpyr.html">Copyright</a> © 1993, 2017, Oracle and/or its affiliates. All rights reserved.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
@ -1,114 +0,0 @@
|
||||
# Module Grouping for the docs bundle page
|
||||
#
|
||||
|
||||
java_base=\
|
||||
java.base
|
||||
|
||||
java_ee_modules=\
|
||||
java.activation \
|
||||
java.corba \
|
||||
java.transaction \
|
||||
java.xml.bind \
|
||||
java.xml.ws \
|
||||
java.xml.ws.annotation \
|
||||
jdk.xml.bind \
|
||||
jdk.xml.ws
|
||||
|
||||
aggregator_modules=\
|
||||
java.se \
|
||||
java.se.ee
|
||||
|
||||
security_modules=\
|
||||
java.security.jgss \
|
||||
java.security.sasl \
|
||||
java.xml.crypto \
|
||||
jdk.security.auth \
|
||||
jdk.security.jgss \
|
||||
jdk.crypto.cryptoki \
|
||||
jdk.crypto.ec \
|
||||
jdk.crypto.mscapi \
|
||||
jdk.crypto.ucrypto \
|
||||
jdk.policytool
|
||||
|
||||
instrument_modules=\
|
||||
java.instrument
|
||||
|
||||
management_modules=\
|
||||
java.management \
|
||||
java.management.rmi \
|
||||
jdk.management \
|
||||
jdk.management.agent \
|
||||
jdk.management.cmm \
|
||||
jdk.management.jfr \
|
||||
jdk.management.resource \
|
||||
jdk.snmp \
|
||||
jdk.jconsole
|
||||
|
||||
integration_modules=\
|
||||
java.logging \
|
||||
java.naming \
|
||||
java.prefs \
|
||||
java.rmi \
|
||||
java.sql \
|
||||
java.sql.rowset \
|
||||
java.xml \
|
||||
jdk.charsets \
|
||||
jdk.localedata \
|
||||
jdk.net \
|
||||
jdk.sctp \
|
||||
jdk.jsobject \
|
||||
jdk.httpserver \
|
||||
jdk.naming.dns \
|
||||
jdk.naming.rmi \
|
||||
jdk.xml.dom \
|
||||
jdk.zipfs
|
||||
|
||||
ui_modules=\
|
||||
java.datatransfer \
|
||||
java.desktop \
|
||||
javafx.base \
|
||||
javafx.controls \
|
||||
javafx.fxml \
|
||||
javafx.graphics \
|
||||
javafx.media \
|
||||
javafx.swing \
|
||||
javafx.web \
|
||||
jdk.accessibility
|
||||
|
||||
svc_modules=\
|
||||
jdk.jfr \
|
||||
jdk.attach \
|
||||
jdk.jcmd \
|
||||
jdk.jdi \
|
||||
jdk.jdwp.agent \
|
||||
jdk.jstatd \
|
||||
jdk.hotspot.agent
|
||||
|
||||
packaging_modules=\
|
||||
jdk.jartool \
|
||||
jdk.jlink \
|
||||
jdk.pack \
|
||||
jdk.packager.services
|
||||
|
||||
compiler_modules=\
|
||||
java.compiler \
|
||||
jdk.compiler \
|
||||
jdk.javadoc \
|
||||
jdk.jdeps \
|
||||
jdk.editpad \
|
||||
jdk.jshell \
|
||||
jdk.rmic
|
||||
|
||||
scripting_modules=\
|
||||
java.scripting \
|
||||
jdk.dynalink \
|
||||
jdk.scripting.nashorn \
|
||||
jdk.scripting.nashorn.shell
|
||||
|
||||
other_modules=\
|
||||
java.jnlp \
|
||||
java.smartcardio
|
||||
|
||||
incubator_modules=\
|
||||
jdk.incubator.httpclient
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -916,23 +916,28 @@ public class File
|
||||
* Returns the time that the file denoted by this abstract pathname was
|
||||
* last modified.
|
||||
*
|
||||
* @apiNote
|
||||
* While the unit of time of the return value is milliseconds, the
|
||||
* granularity of the value depends on the underlying file system and may
|
||||
* be larger. For example, some file systems use time stamps in units of
|
||||
* seconds.
|
||||
*
|
||||
* <p> Where it is required to distinguish an I/O exception from the case
|
||||
* where {@code 0L} is returned, or where several attributes of the
|
||||
* same file are required at the same time, or where the time of last
|
||||
* access or the creation time are required, then the {@link
|
||||
* java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
|
||||
* Files.readAttributes} method may be used.
|
||||
*
|
||||
* @apiNote
|
||||
* While the unit of time of the return value is milliseconds,
|
||||
* the granularity of the value depends on the underlying
|
||||
* file system and may be larger. For example, some
|
||||
* file systems use time stamps in units of seconds.
|
||||
* Files.readAttributes} method may be used. If however only the
|
||||
* time of last modification is required, then the
|
||||
* {@link java.nio.file.Files#getLastModifiedTime(Path,LinkOption[])
|
||||
* Files.getLastModifiedTime} method may be used instead.
|
||||
*
|
||||
* @return A <code>long</code> value representing the time the file was
|
||||
* last modified, measured in milliseconds since the epoch
|
||||
* (00:00:00 GMT, January 1, 1970), or <code>0L</code> if the
|
||||
* file does not exist or if an I/O error occurs
|
||||
* file does not exist or if an I/O error occurs. The value may
|
||||
* be negative indicating the number of milliseconds before the
|
||||
* epoch
|
||||
*
|
||||
* @throws SecurityException
|
||||
* If a security manager exists and its {@link
|
||||
|
@ -50,6 +50,7 @@ import java.net.URL;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@ -2066,25 +2067,6 @@ public final class Class<T> implements java.io.Serializable,
|
||||
return getReflectionFactory().copyMethod(method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code Method} object that reflects the specified public
|
||||
* member method of the class or interface represented by this
|
||||
* {@code Class} object.
|
||||
*
|
||||
* @param name the name of the method
|
||||
* @param parameterTypes the list of parameters
|
||||
* @return the {@code Method} object that matches the specified
|
||||
* {@code name} and {@code parameterTypes}; {@code null}
|
||||
* if the method is not found or the name is
|
||||
* "<init>"or "<clinit>".
|
||||
*/
|
||||
Method getMethodOrNull(String name, Class<?>... parameterTypes) {
|
||||
Objects.requireNonNull(name);
|
||||
Method method = getMethod0(name, parameterTypes);
|
||||
return method == null ? null : getReflectionFactory().copyMethod(method);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a {@code Constructor} object that reflects the specified
|
||||
* public constructor of the class represented by this {@code Class}
|
||||
@ -2225,7 +2207,6 @@ public final class Class<T> implements java.io.Serializable,
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns an array containing {@code Method} objects reflecting all the
|
||||
* declared methods of the class or interface represented by this {@code
|
||||
* Class} object, including public, protected, default (package)
|
||||
@ -2453,6 +2434,30 @@ public final class Class<T> implements java.io.Serializable,
|
||||
return getReflectionFactory().copyMethod(method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of {@code Method} objects for the declared public
|
||||
* methods of this class or interface that have the specified method name
|
||||
* and parameter types.
|
||||
*
|
||||
* @param name the name of the method
|
||||
* @param parameterTypes the parameter array
|
||||
* @return the list of {@code Method} objects for the public methods of
|
||||
* this class matching the specified name and parameters
|
||||
*/
|
||||
List<Method> getDeclaredPublicMethods(String name, Class<?>... parameterTypes) {
|
||||
Method[] methods = privateGetDeclaredMethods(/* publicOnly */ true);
|
||||
ReflectionFactory factory = getReflectionFactory();
|
||||
List<Method> result = new ArrayList<>();
|
||||
for (Method method : methods) {
|
||||
if (method.getName().equals(name)
|
||||
&& Arrays.equals(
|
||||
factory.getExecutableSharedParameterTypes(method),
|
||||
parameterTypes)) {
|
||||
result.add(factory.copyMethod(method));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code Constructor} object that reflects the specified
|
||||
|
@ -93,12 +93,20 @@ import sun.security.util.SecurityConstants;
|
||||
* <p> Class loaders may typically be used by security managers to indicate
|
||||
* security domains.
|
||||
*
|
||||
* <p> In addition to loading classes, a class loader is also responsible for
|
||||
* locating resources. A resource is some data (a "{@code .class}" file,
|
||||
* configuration data, or an image for example) that is identified with an
|
||||
* abstract '/'-separated path name. Resources are typically packaged with an
|
||||
* application or library so that they can be located by code in the
|
||||
* application or library. In some cases, the resources are included so that
|
||||
* they can be located by other libraries.
|
||||
*
|
||||
* <p> The {@code ClassLoader} class uses a delegation model to search for
|
||||
* classes and resources. Each instance of {@code ClassLoader} has an
|
||||
* associated parent class loader. When requested to find a class or
|
||||
* resource, a {@code ClassLoader} instance will delegate the search for the
|
||||
* class or resource to its parent class loader before attempting to find the
|
||||
* class or resource itself.
|
||||
* associated parent class loader. When requested to find a class or
|
||||
* resource, a {@code ClassLoader} instance will usually delegate the search
|
||||
* for the class or resource to its parent class loader before attempting to
|
||||
* find the class or resource itself.
|
||||
*
|
||||
* <p> Class loaders that support concurrent loading of classes are known as
|
||||
* <em>{@linkplain #isRegisteredAsParallelCapable() parallel capable}</em> class
|
||||
@ -129,11 +137,13 @@ import sun.security.util.SecurityConstants;
|
||||
* classes and JDK-specific run-time classes that are defined by the
|
||||
* platform class loader or its ancestors.
|
||||
* <p> To allow for upgrading/overriding of modules defined to the platform
|
||||
* class loader, and where classes in the upgraded version link to
|
||||
* classes in modules defined to the application class loader, the
|
||||
* platform class loader may delegate to the application class loader.
|
||||
* In other words, classes in named modules defined to the application
|
||||
* class loader may be visible to the platform class loader. </li>
|
||||
* class loader, and where upgraded modules read modules defined to class
|
||||
* loaders other than the platform class loader and its ancestors, then
|
||||
* the platform class loader may have to delegate to other class loaders,
|
||||
* the application class loader for example.
|
||||
* In other words, classes in named modules defined to class loaders
|
||||
* other than the platform class loader and its ancestors may be visible
|
||||
* to the platform class loader. </li>
|
||||
* <li><p>{@linkplain #getSystemClassLoader() System class loader}.
|
||||
* It is also known as <em>application class loader</em> and is distinct
|
||||
* from the platform class loader.
|
||||
@ -498,7 +508,7 @@ public abstract class ClassLoader {
|
||||
*
|
||||
* <li><p> Invoke the {@link #loadClass(String) loadClass} method
|
||||
* on the parent class loader. If the parent is {@code null} the class
|
||||
* loader built-in to the virtual machine is used, instead. </p></li>
|
||||
* loader built into the virtual machine is used, instead. </p></li>
|
||||
*
|
||||
* <li><p> Invoke the {@link #findClass(String)} method to find the
|
||||
* class. </p></li>
|
||||
@ -681,8 +691,9 @@ public abstract class ClassLoader {
|
||||
* This method should be overridden by class loader implementations that
|
||||
* follow the delegation model for loading classes, and will be invoked by
|
||||
* the {@link #loadClass loadClass} method after checking the
|
||||
* parent class loader for the requested class. The default implementation
|
||||
* throws a {@code ClassNotFoundException}.
|
||||
* parent class loader for the requested class.
|
||||
*
|
||||
* @implSpec The default implementation throws {@code ClassNotFoundException}.
|
||||
*
|
||||
* @param name
|
||||
* The <a href="#name">binary name</a> of the class
|
||||
@ -1127,8 +1138,9 @@ public abstract class ClassLoader {
|
||||
putIfAbsent(pname, (certs == null? nocerts:certs));
|
||||
}
|
||||
if (pcerts != null && !compareCerts(pcerts, certs)) {
|
||||
throw new SecurityException("class \""+ name +
|
||||
"\"'s signer information does not match signer information of other classes in the same package");
|
||||
throw new SecurityException("class \"" + name
|
||||
+ "\"'s signer information does not match signer information"
|
||||
+ " of other classes in the same package");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1329,12 +1341,7 @@ public abstract class ClassLoader {
|
||||
* that is independent of the location of the code.
|
||||
*
|
||||
* <p> The name of a resource is a '{@code /}'-separated path name that
|
||||
* identifies the resource.
|
||||
*
|
||||
* <p> This method will first search the parent class loader for the
|
||||
* resource; if the parent is {@code null} the path of the class loader
|
||||
* built-in to the virtual machine is searched. That failing, this method
|
||||
* will invoke {@link #findResource(String)} to find the resource. </p>
|
||||
* identifies the resource. </p>
|
||||
*
|
||||
* <p> Resources in named modules are subject to the encapsulation rules
|
||||
* specified by {@link Module#getResourceAsStream Module.getResourceAsStream}.
|
||||
@ -1344,6 +1351,11 @@ public abstract class ClassLoader {
|
||||
* opened} unconditionally (even if the caller of this method is in the
|
||||
* same module as the resource). </p>
|
||||
*
|
||||
* @implSpec The default implementation will first search the parent class
|
||||
* loader for the resource; if the parent is {@code null} the path of the
|
||||
* class loader built into the virtual machine is searched. If not found,
|
||||
* this method will invoke {@link #findResource(String)} to find the resource.
|
||||
*
|
||||
* @apiNote Where several modules are defined to the same class loader,
|
||||
* and where more than one module contains a resource with the given name,
|
||||
* then the ordering that modules are searched is not specified and may be
|
||||
@ -1387,10 +1399,7 @@ public abstract class ClassLoader {
|
||||
* that is independent of the location of the code.
|
||||
*
|
||||
* <p> The name of a resource is a {@code /}-separated path name that
|
||||
* identifies the resource.
|
||||
*
|
||||
* <p> The delegation order for searching is described in the documentation
|
||||
* for {@link #getResource(String)}. </p>
|
||||
* identifies the resource. </p>
|
||||
*
|
||||
* <p> Resources in named modules are subject to the encapsulation rules
|
||||
* specified by {@link Module#getResourceAsStream Module.getResourceAsStream}.
|
||||
@ -1398,7 +1407,15 @@ public abstract class ClassLoader {
|
||||
* name ending with "{@code .class}", this method will only find resources in
|
||||
* packages of named modules when the package is {@link Module#isOpen(String)
|
||||
* opened} unconditionally (even if the caller of this method is in the
|
||||
* same module as the resource).</p>
|
||||
* same module as the resource). </p>
|
||||
*
|
||||
* @implSpec The default implementation will first search the parent class
|
||||
* loader for the resource; if the parent is {@code null} the path of the
|
||||
* class loader built into the virtual machine is searched. It then
|
||||
* invokes {@link #findResources(String)} to find the resources with the
|
||||
* name in this class loader. It returns an enumeration whose elements
|
||||
* are the URLs found by searching the parent class loader followed by
|
||||
* the elements found with {@code findResources}.
|
||||
*
|
||||
* @apiNote Where several modules are defined to the same class loader,
|
||||
* and where more than one module contains a resource with the given name,
|
||||
@ -1424,8 +1441,6 @@ public abstract class ClassLoader {
|
||||
* If I/O errors occur
|
||||
* @throws NullPointerException If {@code name} is {@code null}
|
||||
*
|
||||
* @see #findResources(String)
|
||||
*
|
||||
* @since 1.2
|
||||
* @revised 9
|
||||
* @spec JPMS
|
||||
@ -1453,9 +1468,6 @@ public abstract class ClassLoader {
|
||||
* <p> The name of a resource is a {@code /}-separated path name that
|
||||
* identifies the resource.
|
||||
*
|
||||
* <p> The search order is described in the documentation for {@link
|
||||
* #getResource(String)}.
|
||||
*
|
||||
* <p> The resources will be located when the returned stream is evaluated.
|
||||
* If the evaluation results in an {@code IOException} then the I/O
|
||||
* exception is wrapped in an {@link UncheckedIOException} that is then
|
||||
@ -1469,6 +1481,10 @@ public abstract class ClassLoader {
|
||||
* opened} unconditionally (even if the caller of this method is in the
|
||||
* same module as the resource). </p>
|
||||
*
|
||||
* @implSpec The default implementation invokes {@link #getResources(String)
|
||||
* getResources} to find all the resources with the given name and returns
|
||||
* a stream with the elements in the enumeration as the source.
|
||||
*
|
||||
* @apiNote When overriding this method it is recommended that an
|
||||
* implementation ensures that any delegation is consistent with the {@link
|
||||
* #getResource(java.lang.String) getResource(String)} method. This should
|
||||
@ -1486,8 +1502,6 @@ public abstract class ClassLoader {
|
||||
*
|
||||
* @throws NullPointerException If {@code name} is {@code null}
|
||||
*
|
||||
* @see #findResources(String)
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
public Stream<URL> resources(String name) {
|
||||
@ -1506,7 +1520,7 @@ public abstract class ClassLoader {
|
||||
|
||||
/**
|
||||
* Finds the resource with the given name. Class loader implementations
|
||||
* should override this method to specify where to find resources.
|
||||
* should override this method.
|
||||
*
|
||||
* <p> For resources in named modules then the method must implement the
|
||||
* rules for encapsulation specified in the {@code Module} {@link
|
||||
@ -1515,6 +1529,8 @@ public abstract class ClassLoader {
|
||||
* modules unless the package is {@link Module#isOpen(String) opened}
|
||||
* unconditionally. </p>
|
||||
*
|
||||
* @implSpec The default implementation returns {@code null}.
|
||||
*
|
||||
* @param name
|
||||
* The resource name
|
||||
*
|
||||
@ -1535,8 +1551,7 @@ public abstract class ClassLoader {
|
||||
/**
|
||||
* Returns an enumeration of {@link java.net.URL URL} objects
|
||||
* representing all the resources with the given name. Class loader
|
||||
* implementations should override this method to specify where to load
|
||||
* resources from.
|
||||
* implementations should override this method.
|
||||
*
|
||||
* <p> For resources in named modules then the method must implement the
|
||||
* rules for encapsulation specified in the {@code Module} {@link
|
||||
@ -1545,6 +1560,9 @@ public abstract class ClassLoader {
|
||||
* modules unless the package is {@link Module#isOpen(String) opened}
|
||||
* unconditionally. </p>
|
||||
*
|
||||
* @implSpec The default implementation returns an enumeration that
|
||||
* contains no elements.
|
||||
*
|
||||
* @param name
|
||||
* The resource name
|
||||
*
|
||||
@ -1899,7 +1917,8 @@ public abstract class ClassLoader {
|
||||
// the system class loader is the built-in app class loader during startup
|
||||
return getBuiltinAppClassLoader();
|
||||
case 3:
|
||||
throw new InternalError("getSystemClassLoader should only be called after VM booted");
|
||||
String msg = "getSystemClassLoader should only be called after VM booted";
|
||||
throw new InternalError(msg);
|
||||
case 4:
|
||||
// system fully initialized
|
||||
assert VM.isBooted() && scl != null;
|
||||
@ -2146,7 +2165,7 @@ public abstract class ClassLoader {
|
||||
* @revised 9
|
||||
* @spec JPMS
|
||||
*
|
||||
* @see <a href="../../../technotes/guides/jar/jar.html#sealing">
|
||||
* @see <a href="{@docRoot}/../specs/jar/jar.html#sealing">
|
||||
* The JAR File Specification: Package Sealing</a>
|
||||
*/
|
||||
protected Package definePackage(String name, String specTitle,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2017, 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
|
||||
@ -116,6 +116,10 @@ class FdLibm {
|
||||
private static final double F = 0x1.9b6db6db6db6ep0; // 45/28 ~= 1.60714285714285720630e+00
|
||||
private static final double G = 0x1.6db6db6db6db7p-2; // 5/14 ~= 3.57142857142857150787e-01
|
||||
|
||||
private Cbrt() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public static strictfp double compute(double x) {
|
||||
double t = 0.0;
|
||||
double sign;
|
||||
@ -195,6 +199,10 @@ class FdLibm {
|
||||
public static final double TWO_MINUS_600 = 0x1.0p-600;
|
||||
public static final double TWO_PLUS_600 = 0x1.0p+600;
|
||||
|
||||
private Hypot() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public static strictfp double compute(double x, double y) {
|
||||
double a = Math.abs(x);
|
||||
double b = Math.abs(y);
|
||||
@ -331,6 +339,10 @@ class FdLibm {
|
||||
* representable.
|
||||
*/
|
||||
public static class Pow {
|
||||
private Pow() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public static strictfp double compute(final double x, final double y) {
|
||||
double z;
|
||||
double r, s, t, u, v, w;
|
||||
@ -664,6 +676,10 @@ class FdLibm {
|
||||
private static final double P4 = -0x1.bbd41c5d26bf1p-20; // -1.65339022054652515390e-06
|
||||
private static final double P5 = 0x1.6376972bea4d0p-25; // 4.13813679705723846039e-08
|
||||
|
||||
private Exp() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
// should be able to forgo strictfp due to controlled over/underflow
|
||||
public static strictfp double compute(double x) {
|
||||
double y;
|
||||
|
@ -63,8 +63,8 @@ public class LayerInstantiationException extends RuntimeException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a {@code FindException} with the given detail message
|
||||
* and cause.
|
||||
* Constructs a {@code LayerInstantiationException} with the given detail
|
||||
* message and cause.
|
||||
*
|
||||
* @param msg
|
||||
* The detail message; can be {@code null}
|
||||
@ -74,6 +74,5 @@ public class LayerInstantiationException extends RuntimeException {
|
||||
public LayerInstantiationException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,7 @@ import java.security.PrivilegedAction;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@ -55,8 +56,10 @@ import java.util.stream.Stream;
|
||||
|
||||
import jdk.internal.loader.BuiltinClassLoader;
|
||||
import jdk.internal.loader.BootLoader;
|
||||
import jdk.internal.loader.ClassLoaders;
|
||||
import jdk.internal.misc.JavaLangAccess;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
import jdk.internal.module.IllegalAccessLogger;
|
||||
import jdk.internal.module.ModuleLoaderMap;
|
||||
import jdk.internal.module.ServicesCatalog;
|
||||
import jdk.internal.module.Resources;
|
||||
@ -162,7 +165,6 @@ public final class Module implements AnnotatedElement {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this module is a named module.
|
||||
*
|
||||
@ -249,12 +251,10 @@ public final class Module implements AnnotatedElement {
|
||||
|
||||
// special Module to mean "all unnamed modules"
|
||||
private static final Module ALL_UNNAMED_MODULE = new Module(null);
|
||||
private static final Set<Module> ALL_UNNAMED_MODULE_SET = Set.of(ALL_UNNAMED_MODULE);
|
||||
|
||||
// special Module to mean "everyone"
|
||||
private static final Module EVERYONE_MODULE = new Module(null);
|
||||
|
||||
// set contains EVERYONE_MODULE, used when a package is opened or
|
||||
// exported unconditionally
|
||||
private static final Set<Module> EVERYONE_SET = Set.of(EVERYONE_MODULE);
|
||||
|
||||
|
||||
@ -534,12 +534,12 @@ public final class Module implements AnnotatedElement {
|
||||
return true;
|
||||
|
||||
// all packages are exported/open to self
|
||||
if (other == this && containsPackage(pn))
|
||||
if (other == this && descriptor.packages().contains(pn))
|
||||
return true;
|
||||
|
||||
// all packages in open and automatic modules are open
|
||||
if (descriptor.isOpen() || descriptor.isAutomatic())
|
||||
return containsPackage(pn);
|
||||
return descriptor.packages().contains(pn);
|
||||
|
||||
// exported/opened via module declaration/descriptor
|
||||
if (isStaticallyExportedOrOpen(pn, other, open))
|
||||
@ -555,42 +555,48 @@ public final class Module implements AnnotatedElement {
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this module exports or opens a package to
|
||||
* the given module via its module declaration.
|
||||
* the given module via its module declaration or CLI options.
|
||||
*/
|
||||
private boolean isStaticallyExportedOrOpen(String pn, Module other, boolean open) {
|
||||
// package is open to everyone or <other>
|
||||
// test if package is open to everyone or <other>
|
||||
Map<String, Set<Module>> openPackages = this.openPackages;
|
||||
if (openPackages != null) {
|
||||
Set<Module> targets = openPackages.get(pn);
|
||||
if (targets != null) {
|
||||
if (targets.contains(EVERYONE_MODULE))
|
||||
return true;
|
||||
if (other != EVERYONE_MODULE && targets.contains(other))
|
||||
return true;
|
||||
}
|
||||
if (openPackages != null && allows(openPackages.get(pn), other)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!open) {
|
||||
// package is exported to everyone or <other>
|
||||
// test package is exported to everyone or <other>
|
||||
Map<String, Set<Module>> exportedPackages = this.exportedPackages;
|
||||
if (exportedPackages != null) {
|
||||
Set<Module> targets = exportedPackages.get(pn);
|
||||
if (targets != null) {
|
||||
if (targets.contains(EVERYONE_MODULE))
|
||||
return true;
|
||||
if (other != EVERYONE_MODULE && targets.contains(other))
|
||||
return true;
|
||||
}
|
||||
if (exportedPackages != null && allows(exportedPackages.get(pn), other)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if targets is non-null and contains EVERYONE_MODULE
|
||||
* or the given module. Also returns true if the given module is an unnamed
|
||||
* module and targets contains ALL_UNNAMED_MODULE.
|
||||
*/
|
||||
private boolean allows(Set<Module> targets, Module module) {
|
||||
if (targets != null) {
|
||||
if (targets.contains(EVERYONE_MODULE))
|
||||
return true;
|
||||
if (module != EVERYONE_MODULE) {
|
||||
if (targets.contains(module))
|
||||
return true;
|
||||
if (!module.isNamed() && targets.contains(ALL_UNNAMED_MODULE))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this module reflectively exports or opens given
|
||||
* package package to the given module.
|
||||
* Returns {@code true} if this module reflectively exports or opens the
|
||||
* given package to the given module.
|
||||
*/
|
||||
private boolean isReflectivelyExportedOrOpen(String pn, Module other, boolean open) {
|
||||
// exported or open to all modules
|
||||
@ -632,6 +638,22 @@ public final class Module implements AnnotatedElement {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this module reflectively exports the
|
||||
* given package to the given module.
|
||||
*/
|
||||
boolean isReflectivelyExported(String pn, Module other) {
|
||||
return isReflectivelyExportedOrOpen(pn, other, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this module reflectively opens the
|
||||
* given package to the given module.
|
||||
*/
|
||||
boolean isReflectivelyOpened(String pn, Module other) {
|
||||
return isReflectivelyExportedOrOpen(pn, other, true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If the caller's module is this module then update this module to export
|
||||
@ -800,7 +822,7 @@ public final class Module implements AnnotatedElement {
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates this module to export a package to all unnamed modules.
|
||||
* Updates this module to open a package to all unnamed modules.
|
||||
*
|
||||
* @apiNote Used by the --add-opens command line option.
|
||||
*/
|
||||
@ -808,7 +830,6 @@ public final class Module implements AnnotatedElement {
|
||||
implAddExportsOrOpens(pn, Module.ALL_UNNAMED_MODULE, true, true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates a module to export or open a module to another module.
|
||||
*
|
||||
@ -825,12 +846,31 @@ public final class Module implements AnnotatedElement {
|
||||
if (!isNamed() || descriptor.isOpen() || descriptor.isAutomatic())
|
||||
return;
|
||||
|
||||
// nothing to do if already exported/open to other
|
||||
if (implIsExportedOrOpen(pn, other, open))
|
||||
return;
|
||||
// check if the package is already exported/open to other
|
||||
if (implIsExportedOrOpen(pn, other, open)) {
|
||||
|
||||
// if the package is exported/open for illegal access then we need
|
||||
// to record that it has also been exported/opened reflectively so
|
||||
// that the IllegalAccessLogger doesn't emit a warning.
|
||||
boolean needToAdd = false;
|
||||
if (!other.isNamed()) {
|
||||
IllegalAccessLogger l = IllegalAccessLogger.illegalAccessLogger();
|
||||
if (l != null) {
|
||||
if (open) {
|
||||
needToAdd = l.isOpenForIllegalAccess(this, pn);
|
||||
} else {
|
||||
needToAdd = l.isExportedForIllegalAccess(this, pn);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!needToAdd) {
|
||||
// nothing to do
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// can only export a package in the module
|
||||
if (!containsPackage(pn)) {
|
||||
if (!descriptor.packages().contains(pn)) {
|
||||
throw new IllegalArgumentException("package " + pn
|
||||
+ " not in contents");
|
||||
}
|
||||
@ -850,7 +890,6 @@ public final class Module implements AnnotatedElement {
|
||||
Map<String, Boolean> map = reflectivelyExports
|
||||
.computeIfAbsent(this, other,
|
||||
(m1, m2) -> new ConcurrentHashMap<>());
|
||||
|
||||
if (open) {
|
||||
map.put(pn, Boolean.TRUE); // may need to promote from FALSE to TRUE
|
||||
} else {
|
||||
@ -858,6 +897,38 @@ public final class Module implements AnnotatedElement {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a module to open all packages returned by the given iterator to
|
||||
* all unnamed modules.
|
||||
*
|
||||
* @apiNote Used during startup to open packages for illegal access.
|
||||
*/
|
||||
void implAddOpensToAllUnnamed(Iterator<String> iterator) {
|
||||
if (jdk.internal.misc.VM.isModuleSystemInited()) {
|
||||
throw new IllegalStateException("Module system already initialized");
|
||||
}
|
||||
|
||||
// replace this module's openPackages map with a new map that opens
|
||||
// the packages to all unnamed modules.
|
||||
Map<String, Set<Module>> openPackages = this.openPackages;
|
||||
if (openPackages == null) {
|
||||
openPackages = new HashMap<>();
|
||||
} else {
|
||||
openPackages = new HashMap<>(openPackages);
|
||||
}
|
||||
while (iterator.hasNext()) {
|
||||
String pn = iterator.next();
|
||||
Set<Module> prev = openPackages.putIfAbsent(pn, ALL_UNNAMED_MODULE_SET);
|
||||
if (prev != null) {
|
||||
prev.add(ALL_UNNAMED_MODULE);
|
||||
}
|
||||
|
||||
// update VM to export the package
|
||||
addExportsToAllUnnamed0(this, pn);
|
||||
}
|
||||
this.openPackages = openPackages;
|
||||
}
|
||||
|
||||
|
||||
// -- services --
|
||||
|
||||
@ -947,19 +1018,6 @@ public final class Module implements AnnotatedElement {
|
||||
|
||||
// -- packages --
|
||||
|
||||
// Additional packages that are added to the module at run-time.
|
||||
private volatile Map<String, Boolean> extraPackages;
|
||||
|
||||
private boolean containsPackage(String pn) {
|
||||
if (descriptor.packages().contains(pn))
|
||||
return true;
|
||||
Map<String, Boolean> extraPackages = this.extraPackages;
|
||||
if (extraPackages != null && extraPackages.containsKey(pn))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the set of package names for the packages in this module.
|
||||
*
|
||||
@ -974,89 +1032,19 @@ public final class Module implements AnnotatedElement {
|
||||
*/
|
||||
public Set<String> getPackages() {
|
||||
if (isNamed()) {
|
||||
|
||||
Set<String> packages = descriptor.packages();
|
||||
Map<String, Boolean> extraPackages = this.extraPackages;
|
||||
if (extraPackages == null) {
|
||||
return packages;
|
||||
} else {
|
||||
return Stream.concat(packages.stream(),
|
||||
extraPackages.keySet().stream())
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
return descriptor.packages();
|
||||
} else {
|
||||
// unnamed module
|
||||
Stream<Package> packages;
|
||||
if (loader == null) {
|
||||
packages = BootLoader.packages();
|
||||
} else {
|
||||
packages = SharedSecrets.getJavaLangAccess().packages(loader);
|
||||
packages = loader.packages();
|
||||
}
|
||||
return packages.map(Package::getName).collect(Collectors.toSet());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a package to this module without notifying the VM.
|
||||
*
|
||||
* @apiNote This method is VM white-box testing.
|
||||
*/
|
||||
void implAddPackageNoSync(String pn) {
|
||||
implAddPackage(pn.replace('/', '.'), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a package to this module.
|
||||
*
|
||||
* If {@code syncVM} is {@code true} then the VM is notified. This method is
|
||||
* a no-op if this is an unnamed module or the module already contains the
|
||||
* package.
|
||||
*
|
||||
* @throws IllegalArgumentException if the package name is not legal
|
||||
* @throws IllegalStateException if the package is defined to another module
|
||||
*/
|
||||
private void implAddPackage(String pn, boolean syncVM) {
|
||||
// no-op if unnamed module
|
||||
if (!isNamed())
|
||||
return;
|
||||
|
||||
// no-op if module contains the package
|
||||
if (containsPackage(pn))
|
||||
return;
|
||||
|
||||
// check package name is legal for named modules
|
||||
if (pn.isEmpty())
|
||||
throw new IllegalArgumentException("Cannot add <unnamed> package");
|
||||
for (int i=0; i<pn.length(); i++) {
|
||||
char c = pn.charAt(i);
|
||||
if (c == '/' || c == ';' || c == '[') {
|
||||
throw new IllegalArgumentException("Illegal character: " + c);
|
||||
}
|
||||
}
|
||||
|
||||
// create extraPackages if needed
|
||||
Map<String, Boolean> extraPackages = this.extraPackages;
|
||||
if (extraPackages == null) {
|
||||
synchronized (this) {
|
||||
extraPackages = this.extraPackages;
|
||||
if (extraPackages == null)
|
||||
this.extraPackages = extraPackages = new ConcurrentHashMap<>();
|
||||
}
|
||||
}
|
||||
|
||||
// update VM first in case it fails. This is a no-op if another thread
|
||||
// beats us to add the package first
|
||||
if (syncVM) {
|
||||
// throws IllegalStateException if defined to another module
|
||||
addPackage0(this, pn);
|
||||
if (descriptor.isOpen() || descriptor.isAutomatic()) {
|
||||
addExportsToAll0(this, pn);
|
||||
}
|
||||
}
|
||||
extraPackages.putIfAbsent(pn, Boolean.TRUE);
|
||||
}
|
||||
|
||||
|
||||
// -- creating Module objects --
|
||||
|
||||
@ -1075,18 +1063,22 @@ public final class Module implements AnnotatedElement {
|
||||
Map<String, Module> nameToModule = new HashMap<>();
|
||||
Map<String, ClassLoader> moduleToLoader = new HashMap<>();
|
||||
|
||||
boolean isBootLayer = (ModuleLayer.boot() == null);
|
||||
Set<ClassLoader> loaders = new HashSet<>();
|
||||
boolean hasPlatformModules = false;
|
||||
|
||||
// map each module to a class loader
|
||||
for (ResolvedModule resolvedModule : cf.modules()) {
|
||||
String name = resolvedModule.name();
|
||||
ClassLoader loader = clf.apply(name);
|
||||
if (loader != null) {
|
||||
moduleToLoader.put(name, loader);
|
||||
moduleToLoader.put(name, loader);
|
||||
if (loader == null || loader == ClassLoaders.platformClassLoader()) {
|
||||
if (!(clf instanceof ModuleLoaderMap.Mapper)) {
|
||||
throw new IllegalArgumentException("loader can't be 'null'"
|
||||
+ " or the platform class loader");
|
||||
}
|
||||
hasPlatformModules = true;
|
||||
} else {
|
||||
loaders.add(loader);
|
||||
} else if (!(clf instanceof ModuleLoaderMap.Mapper)) {
|
||||
throw new IllegalArgumentException("loader can't be 'null'");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1098,7 +1090,7 @@ public final class Module implements AnnotatedElement {
|
||||
URI uri = mref.location().orElse(null);
|
||||
ClassLoader loader = moduleToLoader.get(resolvedModule.name());
|
||||
Module m;
|
||||
if (loader == null && isBootLayer && name.equals("java.base")) {
|
||||
if (loader == null && name.equals("java.base")) {
|
||||
// java.base is already defined to the VM
|
||||
m = Object.class.getModule();
|
||||
} else {
|
||||
@ -1157,8 +1149,12 @@ public final class Module implements AnnotatedElement {
|
||||
initExportsAndOpens(m, nameToSource, nameToModule, layer.parents());
|
||||
}
|
||||
|
||||
// register the modules in the boot layer
|
||||
if (isBootLayer) {
|
||||
// if there are modules defined to the boot or platform class loaders
|
||||
// then register the modules in the class loader's services catalog
|
||||
if (hasPlatformModules) {
|
||||
ClassLoader pcl = ClassLoaders.platformClassLoader();
|
||||
ServicesCatalog bootCatalog = BootLoader.getServicesCatalog();
|
||||
ServicesCatalog pclCatalog = ServicesCatalog.getServicesCatalog(pcl);
|
||||
for (ResolvedModule resolvedModule : cf.modules()) {
|
||||
ModuleReference mref = resolvedModule.reference();
|
||||
ModuleDescriptor descriptor = mref.descriptor();
|
||||
@ -1166,13 +1162,11 @@ public final class Module implements AnnotatedElement {
|
||||
String name = descriptor.name();
|
||||
Module m = nameToModule.get(name);
|
||||
ClassLoader loader = moduleToLoader.get(name);
|
||||
ServicesCatalog catalog;
|
||||
if (loader == null) {
|
||||
catalog = BootLoader.getServicesCatalog();
|
||||
} else {
|
||||
catalog = ServicesCatalog.getServicesCatalog(loader);
|
||||
bootCatalog.register(m);
|
||||
} else if (loader == pcl) {
|
||||
pclCatalog.register(m);
|
||||
}
|
||||
catalog.register(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1587,7 +1581,4 @@ public final class Module implements AnnotatedElement {
|
||||
|
||||
// JVM_AddModuleExportsToAllUnnamed
|
||||
private static native void addExportsToAllUnnamed0(Module from, String pn);
|
||||
|
||||
// JVM_AddModulePackage
|
||||
private static native void addPackage0(Module m, String pn);
|
||||
}
|
||||
|
@ -244,6 +244,32 @@ public final class ModuleLayer {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates module {@code source} in the layer to export a package to
|
||||
* module {@code target}. This method is a no-op if {@code source}
|
||||
* already exports the package to at least {@code target}.
|
||||
*
|
||||
* @param source
|
||||
* The source module
|
||||
* @param pn
|
||||
* The package name
|
||||
* @param target
|
||||
* The target module
|
||||
*
|
||||
* @return This controller
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* If {@code source} is not in the module layer or the package
|
||||
* is not in the source module
|
||||
*
|
||||
* @see Module#addExports
|
||||
*/
|
||||
public Controller addExports(Module source, String pn, Module target) {
|
||||
ensureInLayer(source);
|
||||
source.implAddExports(pn, target);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates module {@code source} in the layer to open a package to
|
||||
* module {@code target}. This method is a no-op if {@code source}
|
||||
@ -254,7 +280,7 @@ public final class ModuleLayer {
|
||||
* @param pn
|
||||
* The package name
|
||||
* @param target
|
||||
* The target module to read
|
||||
* The target module
|
||||
*
|
||||
* @return This controller
|
||||
*
|
||||
@ -397,7 +423,7 @@ public final class ModuleLayer {
|
||||
* class loader and defines all modules to that class loader.
|
||||
*
|
||||
* <p> The class loader created by this method implements <em>direct
|
||||
* delegation</em> when loading types from modules. When its {@link
|
||||
* delegation</em> when loading classes from modules. If the {@link
|
||||
* ClassLoader#loadClass(String, boolean) loadClass} method is invoked to
|
||||
* load a class then it uses the package name of the class to map it to a
|
||||
* module. This may be a module in this layer and hence defined to the same
|
||||
@ -408,6 +434,12 @@ public final class ModuleLayer {
|
||||
* When {@code loadClass} is invoked to load classes that do not map to a
|
||||
* module then it delegates to the parent class loader. </p>
|
||||
*
|
||||
* <p> The class loader created by this method locates resources
|
||||
* ({@link ClassLoader#getResource(String) getResource}, {@link
|
||||
* ClassLoader#getResources(String) getResources}, and other resource
|
||||
* methods) in all modules in the layer before searching the parent class
|
||||
* loader. </p>
|
||||
*
|
||||
* <p> Attempting to create a layer with all modules defined to the same
|
||||
* class loader can fail for the following reasons:
|
||||
*
|
||||
@ -417,8 +449,8 @@ public final class ModuleLayer {
|
||||
* configuration have the same package. </p></li>
|
||||
*
|
||||
* <li><p> <em>Split delegation</em>: The resulting class loader would
|
||||
* need to delegate to more than one class loader in order to load types
|
||||
* in a specific package. </p></li>
|
||||
* need to delegate to more than one class loader in order to load
|
||||
* classes in a specific package. </p></li>
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
@ -481,7 +513,7 @@ public final class ModuleLayer {
|
||||
* class loader.
|
||||
*
|
||||
* <p> The class loaders created by this method implement <em>direct
|
||||
* delegation</em> when loading types from modules. When {@link
|
||||
* delegation</em> when loading classes from modules. If the {@link
|
||||
* ClassLoader#loadClass(String, boolean) loadClass} method is invoked to
|
||||
* load a class then it uses the package name of the class to map it to a
|
||||
* module. The package may be in the module defined to the class loader.
|
||||
@ -489,9 +521,15 @@ public final class ModuleLayer {
|
||||
* module defined to the class loader. It may be in a package exported by a
|
||||
* module in a parent layer. The class loader delegates to the class loader
|
||||
* of the module, throwing {@code ClassNotFoundException} if not found by
|
||||
* that class loader.
|
||||
* When {@code loadClass} is invoked to load classes that do not map to a
|
||||
* module then it delegates to the parent class loader. </p>
|
||||
* that class loader. When {@code loadClass} is invoked to load a class
|
||||
* that does not map to a module then it delegates to the parent class
|
||||
* loader. </p>
|
||||
*
|
||||
* <p> The class loaders created by this method locate resources
|
||||
* ({@link ClassLoader#getResource(String) getResource}, {@link
|
||||
* ClassLoader#getResources(String) getResources}, and other resource
|
||||
* methods) in the module defined to the class loader before searching
|
||||
* the parent class loader. </p>
|
||||
*
|
||||
* <p> If there is a security manager then the class loaders created by
|
||||
* this method will load classes and resources with privileges that are
|
||||
@ -576,10 +614,9 @@ public final class ModuleLayer {
|
||||
* <p> In addition, a layer cannot be created if the configuration contains
|
||||
* a module named "{@code java.base}", a configuration contains a module
|
||||
* with a package named "{@code java}" or a package name starting with
|
||||
* "{@code java.}" and the module is mapped to a class loader other than
|
||||
* the {@link ClassLoader#getPlatformClassLoader() platform class loader},
|
||||
* or the function to map a module name to a class loader returns
|
||||
* {@code null}. </p>
|
||||
* "{@code java.}", or the function to map a module name to a class loader
|
||||
* returns {@code null} or the {@linkplain ClassLoader#getPlatformClassLoader()
|
||||
* platform class loader}. </p>
|
||||
*
|
||||
* <p> If the function to map a module name to class loader throws an error
|
||||
* or runtime exception then it is propagated to the caller of this method.
|
||||
|
@ -109,7 +109,7 @@ import jdk.internal.reflect.Reflection;
|
||||
* and have no specification and implementation versioning information.
|
||||
*
|
||||
* @jvms 5.3 Run-time package
|
||||
* @see <a href="../../../technotes/guides/jar/jar.html#sealing">
|
||||
* @see <a href="{@docRoot}/../specs/jar/jar.html#sealing">
|
||||
* The JAR File Specification: Package Sealing</a>
|
||||
* @see ClassLoader#definePackage(String, String, String, String, String, String, String, URL)
|
||||
*
|
||||
|
@ -194,18 +194,15 @@ import sun.security.util.SecurityConstants;
|
||||
* of system administrators who might need to perform multiple
|
||||
* tasks that require all (or numerous) permissions.
|
||||
* <p>
|
||||
* See <a href ="../../../technotes/guides/security/permissions.html">
|
||||
* Permissions in the JDK</a> for permission-related information.
|
||||
* See {@extLink security_guide_permissions
|
||||
* Permissions in the Java Development Kit (JDK)}
|
||||
* for permission-related information.
|
||||
* This document includes, for example, a table listing the various SecurityManager
|
||||
* <code>check</code> methods and the permission(s) the default
|
||||
* implementation of each such method requires.
|
||||
* It also contains a table of all the version 1.2 methods
|
||||
* that require permissions, and for each such method tells
|
||||
* which permission it requires.
|
||||
* <p>
|
||||
* For more information about <code>SecurityManager</code> changes made in
|
||||
* the JDK and advice regarding porting of 1.1-style security managers,
|
||||
* see the <a href="../../../technotes/guides/security/index.html">security documentation</a>.
|
||||
*
|
||||
* @author Arthur van Hoff
|
||||
* @author Roland Schemers
|
||||
@ -1496,7 +1493,10 @@ class SecurityManager {
|
||||
* Throws a {@code SecurityException} if the calling thread is not allowed
|
||||
* to access the specified package.
|
||||
* <p>
|
||||
* This method is called by the {@code loadClass} method of class loaders.
|
||||
* During class loading, this method may be called by the {@code loadClass}
|
||||
* method of class loaders and by the Java Virtual Machine to ensure that
|
||||
* the caller is allowed to access the package of the class that is
|
||||
* being loaded.
|
||||
* <p>
|
||||
* This method checks if the specified package starts with or equals
|
||||
* any of the packages in the {@code package.access} Security Property.
|
||||
|
@ -47,6 +47,8 @@ import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.nio.channels.Channel;
|
||||
import java.nio.channels.spi.SelectorProvider;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
@ -2069,8 +2071,8 @@ public final class System {
|
||||
private static void setJavaLangAccess() {
|
||||
// Allow privileged classes outside of java.lang
|
||||
SharedSecrets.setJavaLangAccess(new JavaLangAccess() {
|
||||
public Method getMethodOrNull(Class<?> klass, String name, Class<?>... parameterTypes) {
|
||||
return klass.getMethodOrNull(name, parameterTypes);
|
||||
public List<Method> getDeclaredPublicMethods(Class<?> klass, String name, Class<?>... parameterTypes) {
|
||||
return klass.getDeclaredPublicMethods(name, parameterTypes);
|
||||
}
|
||||
public jdk.internal.reflect.ConstantPool getConstantPool(Class<?> klass) {
|
||||
return klass.getConstantPool();
|
||||
@ -2094,7 +2096,7 @@ public final class System {
|
||||
return Class.getExecutableTypeAnnotationBytes(executable);
|
||||
}
|
||||
public <E extends Enum<E>>
|
||||
E[] getEnumConstantsShared(Class<E> klass) {
|
||||
E[] getEnumConstantsShared(Class<E> klass) {
|
||||
return klass.getEnumConstantsShared();
|
||||
}
|
||||
public void blockedOn(Thread t, Interruptible b) {
|
||||
@ -2122,9 +2124,6 @@ public final class System {
|
||||
public Class<?> findBootstrapClassOrNull(ClassLoader cl, String name) {
|
||||
return cl.findBootstrapClassOrNull(name);
|
||||
}
|
||||
public Stream<Package> packages(ClassLoader cl) {
|
||||
return cl.packages();
|
||||
}
|
||||
public Package definePackage(ClassLoader cl, String name, Module module) {
|
||||
return cl.definePackage(name, module);
|
||||
}
|
||||
@ -2163,9 +2162,18 @@ public final class System {
|
||||
public void addOpensToAllUnnamed(Module m, String pn) {
|
||||
m.implAddOpensToAllUnnamed(pn);
|
||||
}
|
||||
public void addOpensToAllUnnamed(Module m, Iterator<String> packages) {
|
||||
m.implAddOpensToAllUnnamed(packages);
|
||||
}
|
||||
public void addUses(Module m, Class<?> service) {
|
||||
m.implAddUses(service);
|
||||
}
|
||||
public boolean isReflectivelyExported(Module m, String pn, Module other) {
|
||||
return m.isReflectivelyExported(pn, other);
|
||||
}
|
||||
public boolean isReflectivelyOpened(Module m, String pn, Module other) {
|
||||
return m.isReflectivelyOpened(pn, other);
|
||||
}
|
||||
public ServicesCatalog getServicesCatalog(ModuleLayer layer) {
|
||||
return layer.getServicesCatalog();
|
||||
}
|
||||
|
@ -212,7 +212,7 @@ public class MethodHandles {
|
||||
if (!callerModule.isNamed() && targetModule.isNamed()) {
|
||||
IllegalAccessLogger logger = IllegalAccessLogger.illegalAccessLogger();
|
||||
if (logger != null) {
|
||||
logger.logIfOpenedByBackdoor(lookup, targetClass);
|
||||
logger.logIfOpenedForIllegalAccess(lookup, targetClass);
|
||||
}
|
||||
}
|
||||
return new Lookup(targetClass);
|
||||
|
@ -110,6 +110,20 @@ import static java.lang.invoke.MethodHandleStatics.newInternalError;
|
||||
* boolean r = avh.compareAndSet(sa, 10, "expected", "new");
|
||||
* }</pre>
|
||||
*
|
||||
* <p>Access modes control atomicity and consistency properties.
|
||||
* <em>Plain</em> read ({@code get}) and write ({@code set})
|
||||
* accesses are guaranteed to be bitwise atomic only for references
|
||||
* and for primitive values of at most 32 bits, and impose no observable
|
||||
* ordering constraints with respect to threads other than the
|
||||
* executing thread. <em>Opaque</em> operations are bitwise atomic and
|
||||
* coherently ordered with respect to accesses to the same variable.
|
||||
* In addition to obeying Opaque properties, <em>Acquire</em> mode
|
||||
* reads and their subsequent accesses are ordered after matching
|
||||
* <em>Release</em> mode writes and their previous accesses. In
|
||||
* addition to obeying Acquire and Release properties, all
|
||||
* <em>Volatile</em> operations are totally ordered with respect to
|
||||
* each other.
|
||||
*
|
||||
* <p>Access modes are grouped into the following categories:
|
||||
* <ul>
|
||||
* <li>read access modes that get the value of a variable under specified
|
||||
|
@ -43,11 +43,10 @@ import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* A configuration that is the result of <a href="package-summary.html#resolution">
|
||||
* resolution</a> or resolution with <a href="package-summary.html#servicebinding">
|
||||
* service binding</a>.
|
||||
* resolution</a> or resolution with <a href="#service-binding">service binding</a>.
|
||||
*
|
||||
* <p> A configuration encapsulates the <em>readability graph</em> that is the
|
||||
* output of resolution. A readability graph is a directed graph where the nodes
|
||||
* output of resolution. A readability graph is a directed graph whose vertices
|
||||
* are of type {@link ResolvedModule} and the edges represent the readability
|
||||
* amongst the modules. {@code Configuration} defines the {@link #modules()
|
||||
* modules()} method to get the set of resolved modules in the graph. {@code
|
||||
@ -176,8 +175,8 @@ public final class Configuration {
|
||||
* If resolution fails for any of the observability-related reasons
|
||||
* specified by the static {@code resolve} method
|
||||
* @throws ResolutionException
|
||||
* If any of the post-resolution consistency checks specified by
|
||||
* the static {@code resolve} method fail
|
||||
* If resolution fails any of the consistency checks specified by
|
||||
* the static {@code resolve} method
|
||||
* @throws SecurityException
|
||||
* If locating a module is denied by the security manager
|
||||
*/
|
||||
@ -219,8 +218,8 @@ public final class Configuration {
|
||||
* If resolution fails for any of the observability-related reasons
|
||||
* specified by the static {@code resolve} method
|
||||
* @throws ResolutionException
|
||||
* If any of the post-resolution consistency checks specified by
|
||||
* the static {@code resolve} method fail
|
||||
* If resolution fails any of the consistency checks specified by
|
||||
* the static {@code resolve} method
|
||||
* @throws SecurityException
|
||||
* If locating a module is denied by the security manager
|
||||
*/
|
||||
@ -234,7 +233,7 @@ public final class Configuration {
|
||||
|
||||
/**
|
||||
* Resolves a collection of root modules, with service binding, and with
|
||||
* the empty configuration as its parent. The post resolution checks
|
||||
* the empty configuration as its parent. The consistency checks
|
||||
* are optionally run.
|
||||
*
|
||||
* This method is used to create the configuration for the boot layer.
|
||||
@ -264,10 +263,9 @@ public final class Configuration {
|
||||
* or dependences that are located in a parent configuration are resolved
|
||||
* no further and are not included in the resulting configuration. </p>
|
||||
*
|
||||
* <p> When all modules have been resolved then the resulting dependency
|
||||
* graph is checked to ensure that it does not contain cycles. A
|
||||
* readability graph is constructed, and in conjunction with the module
|
||||
* exports and service use, checked for consistency. </p>
|
||||
* <p> When all modules have been enumerated then a readability graph
|
||||
* is computed, and in conjunction with the module exports and service use,
|
||||
* checked for consistency. </p>
|
||||
*
|
||||
* <p> Resolution may fail with {@code FindException} for the following
|
||||
* <em>observability-related</em> reasons: </p>
|
||||
@ -284,8 +282,8 @@ public final class Configuration {
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* <p> Post-resolution consistency checks may fail with {@code
|
||||
* ResolutionException} for the following reasons: </p>
|
||||
* <p> Resolution may fail with {@code ResolutionException} if any of the
|
||||
* following consistency checks fail: </p>
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
@ -329,9 +327,11 @@ public final class Configuration {
|
||||
* root modules
|
||||
*
|
||||
* @throws FindException
|
||||
* If resolution fails for an observability-related reason
|
||||
* If resolution fails for any of observability-related reasons
|
||||
* specified above
|
||||
* @throws ResolutionException
|
||||
* If a post-resolution consistency checks fails
|
||||
* If resolution fails for any of the consistency checks specified
|
||||
* above
|
||||
* @throws IllegalArgumentException
|
||||
* If the list of parents is empty, or the list has two or more
|
||||
* parents with modules for different target operating systems,
|
||||
@ -368,11 +368,11 @@ public final class Configuration {
|
||||
* resolve} except that the graph of resolved modules is augmented
|
||||
* with modules induced by the service-use dependence relation. </p>
|
||||
*
|
||||
* <p> More specifically, the root modules are resolved as if by calling
|
||||
* {@code resolve}. The resolved modules, and all modules in the
|
||||
* parent configurations, with {@link ModuleDescriptor#uses() service
|
||||
* dependences} are then examined. All modules found by the given module
|
||||
* finders that {@link ModuleDescriptor#provides() provide} an
|
||||
* <p id="service-binding"> More specifically, the root modules are
|
||||
* resolved as if by calling {@code resolve}. The resolved modules, and
|
||||
* all modules in the parent configurations, with {@link ModuleDescriptor#uses()
|
||||
* service dependences} are then examined. All modules found by the given
|
||||
* module finders that {@link ModuleDescriptor#provides() provide} an
|
||||
* implementation of one or more of the service types are added to the
|
||||
* module graph and then resolved as if by calling the {@code
|
||||
* resolve} method. Adding modules to the module graph may introduce new
|
||||
@ -402,8 +402,8 @@ public final class Configuration {
|
||||
* If resolution fails for any of the observability-related reasons
|
||||
* specified by the static {@code resolve} method
|
||||
* @throws ResolutionException
|
||||
* If any of the post-resolution consistency checks specified by
|
||||
* the static {@code resolve} method fail
|
||||
* If resolution fails any of the consistency checks specified by
|
||||
* the static {@code resolve} method
|
||||
* @throws IllegalArgumentException
|
||||
* If the list of parents is empty, or the list has two or more
|
||||
* parents with modules for different target operating systems,
|
||||
|
@ -48,7 +48,7 @@ import jdk.internal.module.SystemModuleFinder;
|
||||
/**
|
||||
* A finder of modules. A {@code ModuleFinder} is used to find modules during
|
||||
* <a href="package-summary.html#resolution">resolution</a> or
|
||||
* <a href="package-summary.html#servicebinding">service binding</a>.
|
||||
* <a href="Configuration.html#service-binding">service binding</a>.
|
||||
*
|
||||
* <p> A {@code ModuleFinder} can only find one module with a given name. A
|
||||
* {@code ModuleFinder} that finds modules in a sequence of directories, for
|
||||
@ -239,30 +239,35 @@ public interface ModuleFinder {
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li><p> The module {@link ModuleDescriptor#name() name}, and {@link
|
||||
* ModuleDescriptor#version() version} if applicable, is derived from
|
||||
* the file name of the JAR file as follows: </p>
|
||||
* <li><p> If the JAR file has the attribute "{@code Automatic-Module-Name}"
|
||||
* in its main manifest then its value is the {@linkplain
|
||||
* ModuleDescriptor#name() module name}. The module name is otherwise
|
||||
* derived from the name of the JAR file. </p></li>
|
||||
*
|
||||
* <li><p> The {@link ModuleDescriptor#version() version}, and the
|
||||
* module name when the attribute "{@code Automatic-Module-Name}" is not
|
||||
* present, are derived from the file name of the JAR file as follows: </p>
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li><p> The {@code .jar} suffix is removed. </p></li>
|
||||
* <li><p> The "{@code .jar}" suffix is removed. </p></li>
|
||||
*
|
||||
* <li><p> If the name matches the regular expression {@code
|
||||
* "-(\\d+(\\.|$))"} then the module name will be derived from the
|
||||
* subsequence preceding the hyphen of the first occurrence. The
|
||||
* subsequence after the hyphen is parsed as a {@link
|
||||
* ModuleDescriptor.Version} and ignored if it cannot be parsed as
|
||||
* a {@code Version}. </p></li>
|
||||
* ModuleDescriptor.Version Version} and ignored if it cannot be
|
||||
* parsed as a {@code Version}. </p></li>
|
||||
*
|
||||
* <li><p> All non-alphanumeric characters ({@code [^A-Za-z0-9]})
|
||||
* in the module name are replaced with a dot ({@code "."}), all
|
||||
* repeating dots are replaced with one dot, and all leading and
|
||||
* trailing dots are removed. </p></li>
|
||||
*
|
||||
* <li><p> As an example, a JAR file named {@code foo-bar.jar} will
|
||||
* derive a module name {@code foo.bar} and no version. A JAR file
|
||||
* named {@code foo-bar-1.2.3-SNAPSHOT.jar} will derive a module
|
||||
* name {@code foo.bar} and {@code 1.2.3-SNAPSHOT} as the version.
|
||||
* <li><p> As an example, a JAR file named "{@code foo-bar.jar}" will
|
||||
* derive a module name "{@code foo.bar}" and no version. A JAR file
|
||||
* named "{@code foo-bar-1.2.3-SNAPSHOT.jar}" will derive a module
|
||||
* name "{@code foo.bar}" and "{@code 1.2.3-SNAPSHOT}" as the version.
|
||||
* </p></li>
|
||||
*
|
||||
* </ul></li>
|
||||
@ -295,11 +300,12 @@ public interface ModuleFinder {
|
||||
* <p> If a {@code ModuleDescriptor} cannot be created (by means of the
|
||||
* {@link ModuleDescriptor.Builder ModuleDescriptor.Builder} API) for an
|
||||
* automatic module then {@code FindException} is thrown. This can arise
|
||||
* when a legal module name cannot be derived from the file name of the JAR
|
||||
* file, where the JAR file contains a {@code .class} in the top-level
|
||||
* directory of the JAR file, where an entry in a service configuration
|
||||
* file is not a legal class name or its package name is not in the set of
|
||||
* packages derived for the module. </p>
|
||||
* when the value of the "{@code Automatic-Module-Name}" attribute is not a
|
||||
* legal module name, a legal module name cannot be derived from the file
|
||||
* name of the JAR file, where the JAR file contains a {@code .class} in
|
||||
* the top-level directory of the JAR file, where an entry in a service
|
||||
* configuration file is not a legal class name or its package name is not
|
||||
* in the set of packages derived for the module. </p>
|
||||
*
|
||||
* <p> In addition to JAR files, an implementation may also support modules
|
||||
* that are packaged in other implementation specific module formats. If
|
||||
|
@ -27,118 +27,185 @@
|
||||
* Classes to support module descriptors and creating configurations of modules
|
||||
* by means of resolution and service binding.
|
||||
*
|
||||
* <h2><a id="resolution">Resolution</a></h2>
|
||||
*
|
||||
* <p> Resolution is the process of computing the transitive closure of a set
|
||||
* of root modules over a set of observable modules by resolving the
|
||||
* dependences expressed by {@link
|
||||
* java.lang.module.ModuleDescriptor.Requires requires} clauses.
|
||||
* The <em>dependence graph</em> is augmented with edges that take account of
|
||||
* implicitly declared dependences ({@code requires transitive}) to create a
|
||||
* <em>readability graph</em>. The result of resolution is a {@link
|
||||
* java.lang.module.Configuration Configuration} that encapsulates the
|
||||
* readability graph. </p>
|
||||
*
|
||||
* <p> As an example, suppose we have the following observable modules: </p>
|
||||
* <pre> {@code
|
||||
* module m1 { requires m2; }
|
||||
* module m2 { requires transitive m3; }
|
||||
* module m3 { }
|
||||
* module m4 { }
|
||||
* } </pre>
|
||||
*
|
||||
* <p> If the module {@code m1} is resolved then the resulting configuration
|
||||
* contains three modules ({@code m1}, {@code m2}, {@code m3}). The edges in
|
||||
* its readability graph are: </p>
|
||||
* <pre> {@code
|
||||
* m1 --> m2 (meaning m1 reads m2)
|
||||
* m1 --> m3
|
||||
* m2 --> m3
|
||||
* } </pre>
|
||||
*
|
||||
* <p> Resolution is an additive process. When computing the transitive closure
|
||||
* then the dependence relation may include dependences on modules in {@link
|
||||
* java.lang.module.Configuration#parents() parent} configurations. The result
|
||||
* is a <em>relative configuration</em> that is relative to one or more parent
|
||||
* configurations and where the readability graph may have edges from modules
|
||||
* in the configuration to modules in parent configurations. </p>
|
||||
*
|
||||
* <p> As an example, suppose we have the following observable modules: </p>
|
||||
* <pre> {@code
|
||||
* module m1 { requires m2; requires java.xml; }
|
||||
* module m2 { }
|
||||
* } </pre>
|
||||
*
|
||||
* <p> If module {@code m1} is resolved with the configuration for the {@link
|
||||
* java.lang.ModuleLayer#boot() boot} layer as the parent then the resulting
|
||||
* configuration contains two modules ({@code m1}, {@code m2}). The edges in
|
||||
* its readability graph are:
|
||||
* <pre> {@code
|
||||
* m1 --> m2
|
||||
* m1 --> java.xml
|
||||
* } </pre>
|
||||
* where module {@code java.xml} is in the parent configuration. For
|
||||
* simplicity, this example omits the implicitly declared dependence on the
|
||||
* {@code java.base} module.
|
||||
*
|
||||
* <p> Requires clauses that are "{@code requires static}" express an optional
|
||||
* dependence (except at compile-time). If a module declares that it
|
||||
* "{@code requires static M}" then resolution does not search the observable
|
||||
* modules for "{@code M}". However, if "{@code M}" is resolved (because resolution
|
||||
* resolves a module that requires "{@code M}" without the {@link
|
||||
* java.lang.module.ModuleDescriptor.Requires.Modifier#STATIC static} modifier)
|
||||
* then the readability graph will contain read edges for each module that
|
||||
* "{@code requires static M}". </p>
|
||||
*
|
||||
* <p> {@link java.lang.module.ModuleDescriptor#isAutomatic() Automatic} modules
|
||||
* receive special treatment during resolution. Each automatic module is resolved
|
||||
* as if it "{@code requires transitive}" all observable automatic modules and
|
||||
* all automatic modules in the parent configurations. Each automatic module is
|
||||
* resolved so that it reads all other modules in the resulting configuration and
|
||||
* all modules in parent configurations. </p>
|
||||
*
|
||||
* <h2><a id="servicebinding">Service binding</a></h2>
|
||||
*
|
||||
* <p> Service binding is the process of augmenting a graph of resolved modules
|
||||
* from the set of observable modules induced by the service-use dependence
|
||||
* ({@code uses} and {@code provides} clauses). Any module that was not
|
||||
* previously in the graph requires resolution to compute its transitive
|
||||
* closure. Service binding is an iterative process in that adding a module
|
||||
* that satisfies some service-use dependence may introduce new service-use
|
||||
* dependences. </p>
|
||||
*
|
||||
* <p> Suppose we have the following observable modules: </p>
|
||||
* <pre> {@code
|
||||
* module m1 { exports p; uses p.S; }
|
||||
* module m2 { requires m1; provides p.S with p2.S2; }
|
||||
* module m3 { requires m1; requires m4; provides p.S with p3.S3; }
|
||||
* module m4 { }
|
||||
* } </pre>
|
||||
*
|
||||
* <p> If the module {@code m1} is resolved then the resulting graph of modules
|
||||
* has one module ({@code m1}). If the graph is augmented with modules induced
|
||||
* by the service-use dependence relation then the configuration will contain
|
||||
* four modules ({@code m1}, {@code m2}, {@code m3}, {@code m4}). The edges in
|
||||
* its readability graph are: </p>
|
||||
* <pre> {@code
|
||||
* m2 --> m1
|
||||
* m3 --> m1
|
||||
* m3 --> m4
|
||||
* } </pre>
|
||||
* <p> The edges in the conceptual service-use graph are: </p>
|
||||
* <pre> {@code
|
||||
* m1 --> m2 (meaning m1 uses a service that is provided by m2)
|
||||
* m1 --> m3
|
||||
* } </pre>
|
||||
*
|
||||
* <h2>General Exceptions</h2>
|
||||
*
|
||||
* <p> Unless otherwise noted, passing a {@code null} argument to a constructor
|
||||
* or method of any class or interface in this package will cause a {@link
|
||||
* java.lang.NullPointerException NullPointerException} to be thrown. Additionally,
|
||||
* invoking a method with an array or collection containing a {@code null} element
|
||||
* will cause a {@code NullPointerException}, unless otherwise specified. </p>
|
||||
*
|
||||
*
|
||||
* <h1><a id="resolution">Resolution</a></h1>
|
||||
*
|
||||
* <p> Resolution is the process of computing how modules depend on each other.
|
||||
* The process occurs at compile time and run time. </p>
|
||||
*
|
||||
* <p> Resolution is a two-step process. The first step recursively enumerates
|
||||
* the 'requires' directives of a set of root modules. If all the enumerated
|
||||
* modules are observable, then the second step computes their readability graph.
|
||||
* The readability graph embodies how modules depend on each other, which in
|
||||
* turn controls access across module boundaries. </p>
|
||||
*
|
||||
* <h2> Step 1: Recursive enumeration </h2>
|
||||
*
|
||||
* <p> Recursive enumeration takes a set of module names, looks up each of their
|
||||
* module declarations, and for each module declaration, recursively enumerates:
|
||||
*
|
||||
* <ul>
|
||||
* <li> <p> the module names given by the 'requires' directives with the
|
||||
* 'transitive' modifier, and </p></li>
|
||||
* <li> <p> at the discretion of the host system, the module names given by
|
||||
* the 'requires' directives without the 'transitive' modifier. </p></li>
|
||||
* </ul>
|
||||
*
|
||||
* <p> Module declarations are looked up in a set of observable modules. The set
|
||||
* of observable modules is determined in an implementation specific manner. The
|
||||
* set of observable modules may include modules with explicit declarations
|
||||
* (that is, with a {@code module-info.java} source file or {@code module-info.class}
|
||||
* file) and modules with implicit declarations (that is,
|
||||
* <a href="ModuleFinder.html#automatic-modules">automatic modules</a>).
|
||||
* Because an automatic module has no explicit module declaration, it has no
|
||||
* 'requires' directives of its own, although its name may be given by a
|
||||
* 'requires' directive of an explicit module declaration. </p>
|
||||
|
||||
* <p> The set of root modules, whose names are the initial input to this
|
||||
* algorithm, is determined in an implementation specific manner. The set of
|
||||
* root modules may include automatic modules. </p>
|
||||
*
|
||||
* <p> If at least one automatic module is enumerated by this algorithm, then
|
||||
* every observable automatic module must be enumerated, regardless of whether
|
||||
* any of their names are given by 'requires' directives of explicit module
|
||||
* declarations. </p>
|
||||
*
|
||||
* <p> If any of the following conditions occur, then resolution fails:
|
||||
* <ul>
|
||||
* <li><p> Any root module is not observable. </p></li>
|
||||
* <li><p> Any module whose name is given by a 'requires' directive with the
|
||||
* 'transitive' modifier is not observable. </p></li>
|
||||
* <li><p> At the discretion of the host system, any module whose name is given
|
||||
* by a 'requires' directive without the 'transitive' modifier is not
|
||||
* observable. </p></li>
|
||||
* <li><p> The algorithm in this step enumerates the same module name twice. This
|
||||
* indicates a cycle in the 'requires' directives, disregarding any 'transitive'
|
||||
* modifiers. </p></li>
|
||||
* </ul>
|
||||
*
|
||||
* <p> Otherwise, resolution proceeds to step 2. </p>
|
||||
*
|
||||
* <h2> Step 2: Computing the readability graph </h2>
|
||||
*
|
||||
* <p> A 'requires' directive (irrespective of 'transitive') expresses that
|
||||
* one module depends on some other module. The effect of the 'transitive'
|
||||
* modifier is to cause additional modules to also depend on the other module.
|
||||
* If module M 'requires transitive N', then not only does M depend on N, but
|
||||
* any module that depends on M also depends on N. This allows M to be
|
||||
* refactored so that some or all of its content can be moved to a new module N
|
||||
* without breaking modules that have a 'requires M' directive. </p>
|
||||
*
|
||||
* <p> Module dependencies are represented by the readability graph. The
|
||||
* readability graph is a directed graph whose vertices are the modules
|
||||
* enumerated in step 1 and whose edges represent readability between pairs of
|
||||
* modules. The edges are specified as follows:
|
||||
*
|
||||
* <p> First, readability is determined by the 'requires' directives of the
|
||||
* enumerated modules, disregarding any 'transitive' modifiers:
|
||||
*
|
||||
* <ul>
|
||||
* <li><p> For each enumerated module A that 'requires' B: A "reads" B. </p></li>
|
||||
* <li><p> For each enumerated module X that is automatic: X "reads" every
|
||||
* other enumerated module (it is "as if" an automatic module has 'requires'
|
||||
* directives for every other enumerated module). </p></li>
|
||||
* </ul>
|
||||
*
|
||||
* <p> Second, readability is augmented to account for 'transitive' modifiers:
|
||||
* <ul>
|
||||
* <li> <p> For each enumerated module A that "reads" B: </p>
|
||||
* <ul>
|
||||
* <li><p> If B 'requires transitive' C, then A "reads" C as well as B. This
|
||||
* augmentation is recursive: since A "reads" C, if C 'requires transitive'
|
||||
* D, then A "reads" D as well as C and B. </p></li>
|
||||
* <li><p> If B is an automatic module, then A "reads" every other enumerated
|
||||
* automatic module. (It is "as if" an automatic module has 'requires transitive'
|
||||
* directives for every other enumerated automatic module).</p> </li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* <p> Finally, every module "reads" itself. </p>
|
||||
*
|
||||
* <p> If any of the following conditions occur in the readability graph, then
|
||||
* resolution fails:
|
||||
* <ul>
|
||||
* <li><p> A module "reads" two or more modules with the same name. This includes
|
||||
* the case where a module "reads" another with the same name as itself. </p></li>
|
||||
* <li><p> Two or more modules export a package with the same name to a module
|
||||
* that "reads" both. This includes the case where a module M containing package
|
||||
* p "reads" another module that exports p to M. </p></li>
|
||||
* <li><p> A module M declares that it 'uses p.S' or 'provides p.S with ...' but
|
||||
* package p is neither in module M nor exported to M by any module that M
|
||||
* "reads". </p></li>
|
||||
* </ul>
|
||||
* <p> Otherwise, resolution succeeds, and the result of resolution is the
|
||||
* readability graph.
|
||||
*
|
||||
* <h2> Root modules </h2>
|
||||
*
|
||||
* <p> The set of root modules at compile-time is usually the set of modules
|
||||
* being compiled. At run-time, the set of root modules is usually the
|
||||
* application module specified to the 'java' launcher. When compiling code in
|
||||
* the unnamed module, or at run-time when the main application class is loaded
|
||||
* from the class path, then the default set of root modules is implementation
|
||||
* specific (In the JDK implementation it is the module "java.se", if observable,
|
||||
* and every observable module that exports an API). </p>
|
||||
*
|
||||
* <h2> Observable modules </h2>
|
||||
*
|
||||
* <p> The set of observable modules at both compile-time and run-time is
|
||||
* determined by searching several different paths, and also by searching
|
||||
* the compiled modules built in to the environment. The search order is as
|
||||
* follows: </p>
|
||||
*
|
||||
* <ol>
|
||||
* <li><p> At compile time only, the compilation module path. This path
|
||||
* contains module definitions in source form. </p></li>
|
||||
*
|
||||
* <li><p> The upgrade module path. This path contains compiled definitions of
|
||||
* modules that will be observed in preference to the compiled definitions of
|
||||
* any <i>upgradeable modules</i> that are present in (3) and (4). See the Java
|
||||
* SE Platform for the designation of which standard modules are upgradeable.
|
||||
* </p></li>
|
||||
*
|
||||
* <li><p> The system modules, which are the compiled definitions built in to
|
||||
* the environment. </p></li>
|
||||
*
|
||||
* <li><p> The application module path. This path contains compiled definitions
|
||||
* of library and application modules. </p></li>
|
||||
*
|
||||
* </ol>
|
||||
*
|
||||
* <h2> 'requires' directives with 'static' modifier </h2>
|
||||
*
|
||||
* <p> 'requires' directives that have the 'static' modifier express an optional
|
||||
* dependence at run time. If a module declares that it 'requires static M' then
|
||||
* resolution does not search the observable modules for M to satisfy the dependency.
|
||||
* However, if M is recursively enumerated at step 1 then all modules that are
|
||||
* enumerated and `requires static M` will read M. </p>
|
||||
*
|
||||
* <h2> Completeness </h2>
|
||||
*
|
||||
* <p> Resolution may be partial at compile-time in that the complete transitive
|
||||
* closure may not be required to compile a set of modules. Minimally, the
|
||||
* readability graph that is constructed and validated at compile-time includes
|
||||
* the modules being compiled, their direct dependences, and all implicitly
|
||||
* declared dependences (requires transitive). </p>
|
||||
*
|
||||
* <p> At run-time, resolution is an additive process. The recursive enumeration
|
||||
* at step 1 may be relative to previous resolutions so that a root module,
|
||||
* or a module named in a 'requires' directive, is not enumerated when it was
|
||||
* enumerated by a previous (or parent) resolution. The readability graph that
|
||||
* is the result of resolution may therefore have a vertex for a module enumerated
|
||||
* in step 1 but with an edge to represent that the module reads a module that
|
||||
* was enumerated by previous (or parent) resolution. </p>
|
||||
*
|
||||
* @since 9
|
||||
* @spec JPMS
|
||||
*/
|
||||
|
@ -304,7 +304,7 @@ public class AccessibleObject implements AnnotatedElement {
|
||||
if (isClassPublic && declaringModule.isExported(pn, callerModule)) {
|
||||
// member is public
|
||||
if (Modifier.isPublic(modifiers)) {
|
||||
logIfExportedByBackdoor(caller, declaringClass);
|
||||
logIfExportedForIllegalAccess(caller, declaringClass);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -312,14 +312,14 @@ public class AccessibleObject implements AnnotatedElement {
|
||||
if (Modifier.isProtected(modifiers)
|
||||
&& Modifier.isStatic(modifiers)
|
||||
&& isSubclassOf(caller, declaringClass)) {
|
||||
logIfExportedByBackdoor(caller, declaringClass);
|
||||
logIfExportedForIllegalAccess(caller, declaringClass);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// package is open to caller
|
||||
if (declaringModule.isOpen(pn, callerModule)) {
|
||||
logIfOpenedByBackdoor(caller, declaringClass);
|
||||
logIfOpenedForIllegalAccess(caller, declaringClass);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -353,26 +353,26 @@ public class AccessibleObject implements AnnotatedElement {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void logIfOpenedByBackdoor(Class<?> caller, Class<?> declaringClass) {
|
||||
private void logIfOpenedForIllegalAccess(Class<?> caller, Class<?> declaringClass) {
|
||||
Module callerModule = caller.getModule();
|
||||
Module targetModule = declaringClass.getModule();
|
||||
// callerModule is null during early startup
|
||||
if (callerModule != null && !callerModule.isNamed() && targetModule.isNamed()) {
|
||||
IllegalAccessLogger logger = IllegalAccessLogger.illegalAccessLogger();
|
||||
if (logger != null) {
|
||||
logger.logIfOpenedByBackdoor(caller, declaringClass, this::toShortString);
|
||||
logger.logIfOpenedForIllegalAccess(caller, declaringClass, this::toShortString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void logIfExportedByBackdoor(Class<?> caller, Class<?> declaringClass) {
|
||||
private void logIfExportedForIllegalAccess(Class<?> caller, Class<?> declaringClass) {
|
||||
Module callerModule = caller.getModule();
|
||||
Module targetModule = declaringClass.getModule();
|
||||
// callerModule is null during early startup
|
||||
if (callerModule != null && !callerModule.isNamed() && targetModule.isNamed()) {
|
||||
IllegalAccessLogger logger = IllegalAccessLogger.illegalAccessLogger();
|
||||
if (logger != null) {
|
||||
logger.logIfExportedByBackdoor(caller, declaringClass, this::toShortString);
|
||||
logger.logIfExportedForIllegalAccess(caller, declaringClass, this::toShortString);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -634,7 +634,7 @@ public class AccessibleObject implements AnnotatedElement {
|
||||
}
|
||||
|
||||
// access okay
|
||||
logIfExportedByBackdoor(caller, memberClass);
|
||||
logIfExportedForIllegalAccess(caller, memberClass);
|
||||
|
||||
// Success: Update the cache.
|
||||
Object cache = (targetClass != null
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2017, 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,4 +36,21 @@ package java.lang.reflect;
|
||||
*/
|
||||
public class MalformedParameterizedTypeException extends RuntimeException {
|
||||
private static final long serialVersionUID = -5696557788586220964L;
|
||||
|
||||
/**
|
||||
* Constructs a {@code MalformedParameterizedTypeException} with
|
||||
* no detail message.
|
||||
*/
|
||||
public MalformedParameterizedTypeException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a {@code MalformedParameterizedTypeException} with
|
||||
* the given detail message.
|
||||
* @param message the detail message; may be {@code null}
|
||||
*/
|
||||
public MalformedParameterizedTypeException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
@ -64,8 +64,7 @@ import java.util.Objects;
|
||||
* AlgorithmParameterGenerator (via a call to an {@code init} method),
|
||||
* each provider must supply (and document) a default initialization.
|
||||
* See the Keysize Restriction sections of the
|
||||
* <a href="{@docRoot}/../technotes/guides/security/SunProviders.html">
|
||||
* JDK Providers</a>
|
||||
* {@extLink security_guide_jdk_providers JDK Providers}
|
||||
* document for information on the AlgorithmParameterGenerator defaults
|
||||
* used by JDK providers.
|
||||
* However, note that defaults may vary across different providers.
|
||||
|
@ -40,8 +40,7 @@ import java.security.spec.AlgorithmParameterSpec;
|
||||
* AlgorithmParameterGenerator (via a call to an {@code engineInit}
|
||||
* method), each provider must supply (and document) a default initialization.
|
||||
* See the Keysize Restriction sections of the
|
||||
* <a href="{@docRoot}/../technotes/guides/security/SunProviders.html">
|
||||
* JDK Providers</a>
|
||||
* {@extLink security_guide_jdk_providers JDK Providers}
|
||||
* document for information on the AlgorithmParameterGenerator defaults
|
||||
* used by JDK providers.
|
||||
* However, note that defaults may vary across different providers.
|
||||
|
@ -114,10 +114,10 @@ public interface Key extends java.io.Serializable {
|
||||
/**
|
||||
* Returns the standard algorithm name for this key. For
|
||||
* example, "DSA" would indicate that this key is a DSA key.
|
||||
* See Appendix A in the <a href=
|
||||
* "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
|
||||
* Java Cryptography Architecture API Specification & Reference </a>
|
||||
* for information about standard algorithm names.
|
||||
* See the <a href=
|
||||
* "{@docRoot}/../specs/security/standard-names.html">
|
||||
* Java Security Standard Algorithm Names</a> document
|
||||
* for more information.
|
||||
*
|
||||
* @return the name of the algorithm associated with this key.
|
||||
*/
|
||||
|
@ -96,8 +96,7 @@ import sun.security.util.Debug;
|
||||
* (via a call to an {@code initialize} method), each provider must
|
||||
* supply (and document) a default initialization.
|
||||
* See the Keysize Restriction sections of the
|
||||
* <a href="{@docRoot}/../technotes/guides/security/SunProviders.html">
|
||||
* JDK Providers</a>
|
||||
* {@extLink security_guide_jdk_providers JDK Providers}
|
||||
* document for information on the KeyPairGenerator defaults used by
|
||||
* JDK providers.
|
||||
* However, note that defaults may vary across different providers.
|
||||
|
@ -40,8 +40,7 @@ import java.security.spec.AlgorithmParameterSpec;
|
||||
* (via a call to an {@code initialize} method), each provider must
|
||||
* supply (and document) a default initialization.
|
||||
* See the Keysize Restriction sections of the
|
||||
* <a href="{@docRoot}/../technotes/guides/security/SunProviders.html">
|
||||
* JDK Providers</a>
|
||||
* {@extLink security_guide_jdk_providers JDK Providers}
|
||||
* document for information on the KeyPairGenerator defaults used by
|
||||
* JDK providers.
|
||||
* However, note that defaults may vary across different providers.
|
||||
|
@ -94,9 +94,9 @@ import java.util.function.Function;
|
||||
* The JDK implementation supports static registration of the security
|
||||
* providers via the {@code conf/security/java.security} file in the Java
|
||||
* installation directory. These providers are automatically installed by
|
||||
* the JDK runtime, see <a href =
|
||||
* "../../../technotes/guides/security/crypto/CryptoSpec.html#Provider">The Provider Class</a>
|
||||
* in the "Java Cryptography Architecture API Specification & Reference"
|
||||
* the JDK runtime, see {@extLink security_guide_jca_provider
|
||||
* The Provider Class}
|
||||
* in the Java Cryptography Architecture (JCA) Reference Guide
|
||||
* for information about how a particular type of provider, the cryptographic
|
||||
* service provider, works and is installed.
|
||||
*
|
||||
@ -1310,8 +1310,8 @@ public abstract class Provider extends Properties {
|
||||
* it is replaced by the new service.
|
||||
* This method also places information about this service
|
||||
* in the provider's Hashtable values in the format described in the
|
||||
* <a href="../../../technotes/guides/security/crypto/CryptoSpec.html">
|
||||
* Java Cryptography Architecture API Specification & Reference </a>.
|
||||
* {@extLink security_guide_jca
|
||||
* Java Cryptography Architecture (JCA) Reference Guide}.
|
||||
*
|
||||
* <p>Also, if there is a security manager, its
|
||||
* {@code checkSecurityAccess} method is called with the string
|
||||
@ -1593,8 +1593,8 @@ public abstract class Provider extends Properties {
|
||||
* suitable services and instantiates them. The valid arguments to those
|
||||
* methods depend on the type of service. For the service types defined
|
||||
* within Java SE, see the
|
||||
* <a href="../../../technotes/guides/security/crypto/CryptoSpec.html">
|
||||
* Java Cryptography Architecture API Specification & Reference </a>
|
||||
* {@extLink security_guide_jca
|
||||
* Java Cryptography Architecture (JCA) Reference Guide}
|
||||
* for the valid values.
|
||||
* Note that components outside of Java SE can define additional types of
|
||||
* services and their behavior.
|
||||
@ -1769,9 +1769,8 @@ public abstract class Provider extends Properties {
|
||||
* instantiation in a different way.
|
||||
* For details and the values of constructorParameter that are
|
||||
* valid for the various types of services see the
|
||||
* <a href="../../../technotes/guides/security/crypto/CryptoSpec.html">
|
||||
* Java Cryptography Architecture API Specification &
|
||||
* Reference</a>.
|
||||
* {@extLink security_guide_jca
|
||||
* Java Cryptography Architecture (JCA) Reference Guide}.
|
||||
*
|
||||
* @param constructorParameter the value to pass to the constructor,
|
||||
* or null if this type of service does not use a constructorParameter.
|
||||
@ -1878,9 +1877,8 @@ public abstract class Provider extends Properties {
|
||||
*
|
||||
* <p>For details and the values of parameter that are valid for the
|
||||
* various types of services see the top of this class and the
|
||||
* <a href="../../../technotes/guides/security/crypto/CryptoSpec.html">
|
||||
* Java Cryptography Architecture API Specification &
|
||||
* Reference</a>.
|
||||
* {@extLink security_guide_jca
|
||||
* Java Cryptography Architecture (JCA) Reference Guide}.
|
||||
* Security providers can override it to implement their own test.
|
||||
*
|
||||
* @param parameter the parameter to test
|
||||
|
@ -1041,8 +1041,8 @@ public final class Security {
|
||||
* an empty Set if there is no provider that supports the
|
||||
* specified service or if serviceName is null. For a complete list
|
||||
* of Java cryptographic services, please see the
|
||||
* <a href="../../../technotes/guides/security/crypto/CryptoSpec.html">Java
|
||||
* Cryptography Architecture API Specification & Reference</a>.
|
||||
* {@extLink security_guide_jca
|
||||
* Java Cryptography Architecture (JCA) Reference Guide}.
|
||||
* Note: the returned set is immutable.
|
||||
*
|
||||
* @param serviceName the name of the Java cryptographic
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2017, 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
|
||||
@ -52,9 +52,9 @@ public abstract class CRL {
|
||||
* Creates a CRL of the specified type.
|
||||
*
|
||||
* @param type the standard name of the CRL type.
|
||||
* See Appendix A in the <a href=
|
||||
* "../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
|
||||
* Java Cryptography Architecture API Specification & Reference </a>
|
||||
* See the <a href=
|
||||
* "{@docRoot}/../specs/security/standard-names.html">
|
||||
* Java Security Standard Algorithm Names</a> document
|
||||
* for information about standard CRL types.
|
||||
*/
|
||||
protected CRL(String type) {
|
||||
|
@ -32,15 +32,14 @@
|
||||
* <h2>Package Specification</h2>
|
||||
*
|
||||
* <ul>
|
||||
* <li><a href="{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html">
|
||||
* <b>Java™
|
||||
* Cryptography Architecture (JCA) Reference Guide</b></a>
|
||||
* <li>{@extLink security_guide_jca
|
||||
* Java Cryptography Architecture (JCA) Reference Guide}
|
||||
* <li>RFC 5280: Internet X.509 Public Key Infrastructure Certificate and
|
||||
* Certificate Revocation List (CRL) Profile
|
||||
* <li>RFC 2560: X.509 Internet Public Key Infrastructure Online Certificate
|
||||
* Status Protocol - OCSP
|
||||
* <li><a href="{@docRoot}/../specs/security/standard-names.html">
|
||||
* <b>Java™ Security Standard Algorithm Names Specification
|
||||
* <b>Java Security Standard Algorithm Names Specification
|
||||
* </b></a></li>
|
||||
* </ul>
|
||||
*
|
||||
@ -50,12 +49,7 @@
|
||||
* <ul>
|
||||
* <li><a href="http://www.ietf.org/rfc/rfc5280.txt">
|
||||
* http://www.ietf.org/rfc/rfc5280.txt</a>
|
||||
* <li><a href=
|
||||
* "{@docRoot}/../technotes/guides/security/certpath/CertPathProgGuide.html">
|
||||
* <b>Java™
|
||||
* PKI Programmer's Guide</b></a>
|
||||
* <li><a href="{@docRoot}/../technotes/guides/security/cert3.html">
|
||||
* <b>X.509 Certificates and Certificate Revocation Lists (CRLs)</b></a>
|
||||
* <li> {@extLink security_guide_pki Java PKI Programmer's Guide}
|
||||
* </ul>
|
||||
*
|
||||
* @since 1.2
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2017, 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
|
||||
@ -42,11 +42,10 @@
|
||||
* {@code Key} classes for hardware devices, please refer
|
||||
* to these cryptographic provider developer guides:
|
||||
* <ul>
|
||||
* <li><a href=
|
||||
* "{@docRoot}/../technotes/guides/security/crypto/HowToImplAProvider.html">
|
||||
* <b>How to Implement a Provider for the
|
||||
* Java™ Cryptography Architecture
|
||||
* </b></a></li>
|
||||
* <li>
|
||||
* {@extLink security_guide_impl_provider
|
||||
* How to Implement a Provider in the Java Cryptography Architecture}
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* <h2>Package Specification</h2>
|
||||
@ -61,12 +60,8 @@
|
||||
*
|
||||
* For further documentation, please see:
|
||||
* <ul>
|
||||
* <li>
|
||||
* <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html">
|
||||
* <b>Java™
|
||||
* Cryptography Architecture API Specification and Reference
|
||||
* </b></a></li>
|
||||
* <li> {extLink security_guide_jca
|
||||
* Java Cryptography Architecture Reference Guide}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @since 1.1
|
||||
|
@ -46,63 +46,36 @@
|
||||
* <h2>Package Specification</h2>
|
||||
*
|
||||
* <ul>
|
||||
* <li><a href="{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html">
|
||||
* <b>Java™
|
||||
* Cryptography Architecture (JCA) Reference Guide</b></a></li>
|
||||
* <li> {@extLink security_guide_jca
|
||||
* Java Cryptography Architecture (JCA) Reference Guide}</li>
|
||||
*
|
||||
* <li>PKCS #8: Private-Key Information Syntax Standard, Version 1.2,
|
||||
* November 1993</li>
|
||||
*
|
||||
* <li><a href="{@docRoot}/../specs/security/standard-names.html">
|
||||
* <b>Java™ Security Standard Algorithm Names Specification
|
||||
* </b></a></li>
|
||||
* Java Security Standard Algorithm Names Specification
|
||||
* </a></li>
|
||||
* </ul>
|
||||
*
|
||||
* <h2>Related Documentation</h2>
|
||||
*
|
||||
* For further documentation, please see:
|
||||
* <ul>
|
||||
* <li><a href=
|
||||
* "{@docRoot}/../technotes/guides/security/spec/security-spec.doc.html">
|
||||
* <b>Java™
|
||||
* SE Platform Security Architecture</b></a></li>
|
||||
* <li> {@extLink security_guide_overview
|
||||
* Java Security Overview} </li>
|
||||
*
|
||||
* <li><a href=
|
||||
* "{@docRoot}/../technotes/guides/security/crypto/HowToImplAProvider.html">
|
||||
* <b>How to Implement a Provider in the
|
||||
* Java™ Cryptography Architecture
|
||||
* </b></a></li>
|
||||
* <li> {@extLink security_guide_impl_provider
|
||||
* How to Implement a Provider in the Java Cryptography Architecture}</li>
|
||||
*
|
||||
* <li><a href=
|
||||
* "{@docRoot}/../technotes/guides/security/PolicyFiles.html"><b>
|
||||
* Default Policy Implementation and Policy File Syntax
|
||||
* </b></a></li>
|
||||
* <li> {@extLink security_guide_default_policy
|
||||
* Default Policy Implementation and Policy File Syntax}</li>
|
||||
*
|
||||
* <li><a href=
|
||||
* "{@docRoot}/../technotes/guides/security/permissions.html"><b>
|
||||
* Permissions in the
|
||||
* Java™ SE Development Kit (JDK)
|
||||
* </b></a></li>
|
||||
* <li> {@extLink security_guide_permissions
|
||||
* Permissions in the Java Development Kit (JDK)}</li>
|
||||
*
|
||||
* <li><a href=
|
||||
* "{@docRoot}/../technotes/guides/security/SecurityToolsSummary.html"><b>
|
||||
* Summary of Tools for
|
||||
* Java™ Platform Security
|
||||
* </b></a></li>
|
||||
*
|
||||
* <li><b>keytool</b>
|
||||
* (<a href="{@docRoot}/../technotes/tools/unix/keytool.html">
|
||||
* for Solaris/Linux</a>)
|
||||
* (<a href="{@docRoot}/../technotes/tools/windows/keytool.html">
|
||||
* for Windows</a>)
|
||||
* </li>
|
||||
*
|
||||
* <li><b>jarsigner</b>
|
||||
* (<a href="{@docRoot}/../technotes/tools/unix/jarsigner.html">
|
||||
* for Solaris/Linux</a>)
|
||||
* (<a href="{@docRoot}/../technotes/tools/windows/jarsigner.html">
|
||||
* for Windows</a>)
|
||||
* </li>
|
||||
* <li> {@extLink security_guide_tools
|
||||
* Summary of Tools for Java Platform Security}
|
||||
* (for example {@code keytool} and {@code jarsigner}),</li>
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2017, 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
|
||||
@ -54,18 +54,10 @@
|
||||
* For documentation that includes information about algorithm parameter
|
||||
* and key specifications, please see:
|
||||
* <ul>
|
||||
* <li>
|
||||
* <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html">
|
||||
* <b>Java™
|
||||
* Cryptography Architecture API Specification and Reference
|
||||
* </b></a></li>
|
||||
* <li>
|
||||
* <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/crypto/HowToImplAProvider.html">
|
||||
* <b>How to Implement a Provider for the
|
||||
* Java™ Cryptography Architecture
|
||||
* </b></a></li>
|
||||
* <li> {@extLink security_guide_jca
|
||||
* Java Cryptography Architecture (JCA) Reference Guide}</li>
|
||||
* <li> {@extLink security_guide_impl_provider
|
||||
* How to Implement a Provider in the Java Cryptography Architecture}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @since 1.2
|
||||
|
@ -72,24 +72,24 @@ package java.util;
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Insert</b></td>
|
||||
* <td>{@link Deque#addFirst addFirst(e)}</td>
|
||||
* <td>{@link Deque#offerFirst offerFirst(e)}</td>
|
||||
* <td>{@link Deque#addLast addLast(e)}</td>
|
||||
* <td>{@link Deque#offerLast offerLast(e)}</td>
|
||||
* <td>{@link #addFirst(Object) addFirst(e)}</td>
|
||||
* <td>{@link #offerFirst(Object) offerFirst(e)}</td>
|
||||
* <td>{@link #addLast(Object) addLast(e)}</td>
|
||||
* <td>{@link #offerLast(Object) offerLast(e)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Remove</b></td>
|
||||
* <td>{@link Deque#removeFirst removeFirst()}</td>
|
||||
* <td>{@link Deque#pollFirst pollFirst()}</td>
|
||||
* <td>{@link Deque#removeLast removeLast()}</td>
|
||||
* <td>{@link Deque#pollLast pollLast()}</td>
|
||||
* <td>{@link #removeFirst() removeFirst()}</td>
|
||||
* <td>{@link #pollFirst() pollFirst()}</td>
|
||||
* <td>{@link #removeLast() removeLast()}</td>
|
||||
* <td>{@link #pollLast() pollLast()}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Examine</b></td>
|
||||
* <td>{@link Deque#getFirst getFirst()}</td>
|
||||
* <td>{@link Deque#peekFirst peekFirst()}</td>
|
||||
* <td>{@link Deque#getLast getLast()}</td>
|
||||
* <td>{@link Deque#peekLast peekLast()}</td>
|
||||
* <td>{@link #getFirst() getFirst()}</td>
|
||||
* <td>{@link #peekFirst() peekFirst()}</td>
|
||||
* <td>{@link #getLast() getLast()}</td>
|
||||
* <td>{@link #peekLast() peekLast()}</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
@ -106,28 +106,28 @@ package java.util;
|
||||
* <td style="text-align:center"> <b>Equivalent {@code Deque} Method</b></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link java.util.Queue#add add(e)}</td>
|
||||
* <td>{@link #addLast addLast(e)}</td>
|
||||
* <td>{@link #add(Object) add(e)}</td>
|
||||
* <td>{@link #addLast(Object) addLast(e)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link java.util.Queue#offer offer(e)}</td>
|
||||
* <td>{@link #offerLast offerLast(e)}</td>
|
||||
* <td>{@link #offer(Object) offer(e)}</td>
|
||||
* <td>{@link #offerLast(Object) offerLast(e)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link java.util.Queue#remove remove()}</td>
|
||||
* <td>{@link #removeFirst removeFirst()}</td>
|
||||
* <td>{@link #remove() remove()}</td>
|
||||
* <td>{@link #removeFirst() removeFirst()}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link java.util.Queue#poll poll()}</td>
|
||||
* <td>{@link #pollFirst pollFirst()}</td>
|
||||
* <td>{@link #poll() poll()}</td>
|
||||
* <td>{@link #pollFirst() pollFirst()}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link java.util.Queue#element element()}</td>
|
||||
* <td>{@link #getFirst getFirst()}</td>
|
||||
* <td>{@link #element() element()}</td>
|
||||
* <td>{@link #getFirst() getFirst()}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link java.util.Queue#peek peek()}</td>
|
||||
* <td>{@link #peek peekFirst()}</td>
|
||||
* <td>{@link #peek() peek()}</td>
|
||||
* <td>{@link #peekFirst() peekFirst()}</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
@ -144,16 +144,16 @@ package java.util;
|
||||
* <td style="text-align:center"> <b>Equivalent {@code Deque} Method</b></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #push push(e)}</td>
|
||||
* <td>{@link #addFirst addFirst(e)}</td>
|
||||
* <td>{@link #push(Object) push(e)}</td>
|
||||
* <td>{@link #addFirst(Object) addFirst(e)}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #pop pop()}</td>
|
||||
* <td>{@link #removeFirst removeFirst()}</td>
|
||||
* <td>{@link #pop() pop()}</td>
|
||||
* <td>{@link #removeFirst() removeFirst()}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #peek peek()}</td>
|
||||
* <td>{@link #peekFirst peekFirst()}</td>
|
||||
* <td>{@link #peek() peek()}</td>
|
||||
* <td>{@link #peekFirst() peekFirst()}</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
@ -430,8 +430,8 @@ public interface Deque<E> extends Queue<E> {
|
||||
/**
|
||||
* Retrieves and removes the head of the queue represented by this deque
|
||||
* (in other words, the first element of this deque).
|
||||
* This method differs from {@link #poll poll} only in that it throws an
|
||||
* exception if this deque is empty.
|
||||
* This method differs from {@link #poll() poll()} only in that it
|
||||
* throws an exception if this deque is empty.
|
||||
*
|
||||
* <p>This method is equivalent to {@link #removeFirst()}.
|
||||
*
|
||||
@ -477,6 +477,31 @@ public interface Deque<E> extends Queue<E> {
|
||||
*/
|
||||
E peek();
|
||||
|
||||
/**
|
||||
* Adds all of the elements in the specified collection at the end
|
||||
* of this deque, as if by calling {@link #addLast} on each one,
|
||||
* in the order that they are returned by the collection's iterator.
|
||||
*
|
||||
* <p>When using a capacity-restricted deque, it is generally preferable
|
||||
* to call {@link #offer(Object) offer} separately on each element.
|
||||
*
|
||||
* <p>An exception encountered while trying to add an element may result
|
||||
* in only some of the elements having been successfully added when
|
||||
* the associated exception is thrown.
|
||||
*
|
||||
* @param c the elements to be inserted into this deque
|
||||
* @return {@code true} if this deque changed as a result of the call
|
||||
* @throws IllegalStateException if not all the elements can be added at
|
||||
* this time due to insertion restrictions
|
||||
* @throws ClassCastException if the class of an element of the specified
|
||||
* collection prevents it from being added to this deque
|
||||
* @throws NullPointerException if the specified collection contains a
|
||||
* null element and this deque does not permit null elements,
|
||||
* or if the specified collection is null
|
||||
* @throws IllegalArgumentException if some property of an element of the
|
||||
* specified collection prevents it from being added to this deque
|
||||
*/
|
||||
boolean addAll(Collection<? extends E> c);
|
||||
|
||||
// *** Stack methods ***
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2017, 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,33 +27,12 @@ package java.util;
|
||||
|
||||
|
||||
/**
|
||||
* Error thrown when something goes wrong while loading a service provider.
|
||||
*
|
||||
* <p> This error will be thrown in the following situations:
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li> The format of a provider-configuration file violates the <a
|
||||
* href="ServiceLoader.html#format">specification</a>; </li>
|
||||
*
|
||||
* <li> An {@link java.io.IOException IOException} occurs while reading a
|
||||
* provider-configuration file; </li>
|
||||
*
|
||||
* <li> A concrete provider class named in a provider-configuration file
|
||||
* cannot be found; </li>
|
||||
*
|
||||
* <li> A concrete provider class is not a subclass of the service class;
|
||||
* </li>
|
||||
*
|
||||
* <li> A concrete provider class cannot be instantiated; or
|
||||
*
|
||||
* <li> Some other kind of error occurs. </li>
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* Error thrown when something goes wrong while locating, loading, or
|
||||
* instantiating a service provider.
|
||||
*
|
||||
* @author Mark Reinhold
|
||||
* @since 1.6
|
||||
* @see ServiceLoader
|
||||
*/
|
||||
|
||||
public class ServiceConfigurationError
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -249,7 +249,8 @@ public class AtomicInteger extends Number implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the current value with the results of
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the current value with the results of
|
||||
* applying the given function, returning the previous value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads.
|
||||
@ -270,7 +271,8 @@ public class AtomicInteger extends Number implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the current value with the results of
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the current value with the results of
|
||||
* applying the given function, returning the updated value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads.
|
||||
@ -291,13 +293,14 @@ public class AtomicInteger extends Number implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the current value with the results of
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the current value with the results of
|
||||
* applying the given function to the current and given values,
|
||||
* returning the previous value. The function should be
|
||||
* side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads. The function
|
||||
* is applied with the current value as its first argument,
|
||||
* and the given update as the second argument.
|
||||
* updates fail due to contention among threads. The function is
|
||||
* applied with the current value as its first argument, and the
|
||||
* given update as the second argument.
|
||||
*
|
||||
* @param x the update value
|
||||
* @param accumulatorFunction a side-effect-free function of two arguments
|
||||
@ -317,13 +320,14 @@ public class AtomicInteger extends Number implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the current value with the results of
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the current value with the results of
|
||||
* applying the given function to the current and given values,
|
||||
* returning the updated value. The function should be
|
||||
* side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads. The function
|
||||
* is applied with the current value as its first argument,
|
||||
* and the given update as the second argument.
|
||||
* updates fail due to contention among threads. The function is
|
||||
* applied with the current value as its first argument, and the
|
||||
* given update as the second argument.
|
||||
*
|
||||
* @param x the update value
|
||||
* @param accumulatorFunction a side-effect-free function of two arguments
|
||||
|
@ -260,10 +260,12 @@ public class AtomicIntegerArray implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the element at index {@code i} with the results
|
||||
* of applying the given function, returning the previous value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads.
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the element at index {@code i} with
|
||||
* the results of applying the given function, returning the
|
||||
* previous value. The function should be side-effect-free, since
|
||||
* it may be re-applied when attempted updates fail due to
|
||||
* contention among threads.
|
||||
*
|
||||
* @param i the index
|
||||
* @param updateFunction a side-effect-free function
|
||||
@ -282,10 +284,12 @@ public class AtomicIntegerArray implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the element at index {@code i} with the results
|
||||
* of applying the given function, returning the updated value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads.
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the element at index {@code i} with
|
||||
* the results of applying the given function, returning the
|
||||
* updated value. The function should be side-effect-free, since it
|
||||
* may be re-applied when attempted updates fail due to contention
|
||||
* among threads.
|
||||
*
|
||||
* @param i the index
|
||||
* @param updateFunction a side-effect-free function
|
||||
@ -304,10 +308,11 @@ public class AtomicIntegerArray implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the element at index {@code i} with the
|
||||
* results of applying the given function to the current and given
|
||||
* values, returning the previous value. The function should be
|
||||
* side-effect-free, since it may be re-applied when attempted
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the element at index {@code i} with
|
||||
* the results of applying the given function to the current and
|
||||
* given values, returning the previous value. The function should
|
||||
* be side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads. The function is
|
||||
* applied with the current value of the element at index {@code i}
|
||||
* as its first argument, and the given update as the second
|
||||
@ -332,10 +337,11 @@ public class AtomicIntegerArray implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the element at index {@code i} with the
|
||||
* results of applying the given function to the current and given
|
||||
* values, returning the updated value. The function should be
|
||||
* side-effect-free, since it may be re-applied when attempted
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the element at index {@code i} with
|
||||
* the results of applying the given function to the current and
|
||||
* given values, returning the updated value. The function should
|
||||
* be side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads. The function is
|
||||
* applied with the current value of the element at index {@code i}
|
||||
* as its first argument, and the given update as the second
|
||||
|
@ -46,6 +46,7 @@ import java.util.function.IntUnaryOperator;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
import jdk.internal.reflect.CallerSensitive;
|
||||
import jdk.internal.reflect.Reflection;
|
||||
import java.lang.invoke.VarHandle;
|
||||
|
||||
/**
|
||||
* A reflection-based utility that enables atomic updates to
|
||||
@ -275,10 +276,12 @@ public abstract class AtomicIntegerFieldUpdater<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the field of the given object managed by this updater
|
||||
* with the results of applying the given function, returning the previous
|
||||
* value. The function should be side-effect-free, since it may be
|
||||
* re-applied when attempted updates fail due to contention among threads.
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the field of the given object managed
|
||||
* by this updater with the results of applying the given
|
||||
* function, returning the previous value. The function should be
|
||||
* side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads.
|
||||
*
|
||||
* @param obj An object whose field to get and set
|
||||
* @param updateFunction a side-effect-free function
|
||||
@ -295,10 +298,12 @@ public abstract class AtomicIntegerFieldUpdater<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the field of the given object managed by this updater
|
||||
* with the results of applying the given function, returning the updated
|
||||
* value. The function should be side-effect-free, since it may be
|
||||
* re-applied when attempted updates fail due to contention among threads.
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the field of the given object managed
|
||||
* by this updater with the results of applying the given
|
||||
* function, returning the updated value. The function should be
|
||||
* side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads.
|
||||
*
|
||||
* @param obj An object whose field to get and set
|
||||
* @param updateFunction a side-effect-free function
|
||||
@ -315,13 +320,14 @@ public abstract class AtomicIntegerFieldUpdater<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the field of the given object managed by this
|
||||
* updater with the results of applying the given function to the
|
||||
* current and given values, returning the previous value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads. The
|
||||
* function is applied with the current value as its first argument,
|
||||
* and the given update as the second argument.
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the field of the given object managed
|
||||
* by this updater with the results of applying the given function
|
||||
* to the current and given values, returning the previous value.
|
||||
* The function should be side-effect-free, since it may be
|
||||
* re-applied when attempted updates fail due to contention among
|
||||
* threads. The function is applied with the current value as its
|
||||
* first argument, and the given update as the second argument.
|
||||
*
|
||||
* @param obj An object whose field to get and set
|
||||
* @param x the update value
|
||||
@ -340,13 +346,14 @@ public abstract class AtomicIntegerFieldUpdater<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the field of the given object managed by this
|
||||
* updater with the results of applying the given function to the
|
||||
* current and given values, returning the updated value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads. The
|
||||
* function is applied with the current value as its first argument,
|
||||
* and the given update as the second argument.
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the field of the given object managed
|
||||
* by this updater with the results of applying the given function
|
||||
* to the current and given values, returning the updated value.
|
||||
* The function should be side-effect-free, since it may be
|
||||
* re-applied when attempted updates fail due to contention among
|
||||
* threads. The function is applied with the current value as its
|
||||
* first argument, and the given update as the second argument.
|
||||
*
|
||||
* @param obj An object whose field to get and set
|
||||
* @param x the update value
|
||||
|
@ -118,8 +118,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
|
||||
* @param newValue the new value
|
||||
*/
|
||||
public final void set(long newValue) {
|
||||
// Use putLongVolatile instead of ordinary volatile store when
|
||||
// using compareAndSetLong, for sake of some 32bit systems.
|
||||
// See JDK-8180620: Clarify VarHandle mixed-access subtleties
|
||||
U.putLongVolatile(this, VALUE, newValue);
|
||||
}
|
||||
|
||||
@ -265,7 +264,8 @@ public class AtomicLong extends Number implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the current value with the results of
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the current value with the results of
|
||||
* applying the given function, returning the previous value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads.
|
||||
@ -286,7 +286,8 @@ public class AtomicLong extends Number implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the current value with the results of
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the current value with the results of
|
||||
* applying the given function, returning the updated value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads.
|
||||
@ -307,13 +308,14 @@ public class AtomicLong extends Number implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the current value with the results of
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the current value with the results of
|
||||
* applying the given function to the current and given values,
|
||||
* returning the previous value. The function should be
|
||||
* side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads. The function
|
||||
* is applied with the current value as its first argument,
|
||||
* and the given update as the second argument.
|
||||
* updates fail due to contention among threads. The function is
|
||||
* applied with the current value as its first argument, and the
|
||||
* given update as the second argument.
|
||||
*
|
||||
* @param x the update value
|
||||
* @param accumulatorFunction a side-effect-free function of two arguments
|
||||
@ -333,13 +335,14 @@ public class AtomicLong extends Number implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the current value with the results of
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the current value with the results of
|
||||
* applying the given function to the current and given values,
|
||||
* returning the updated value. The function should be
|
||||
* side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads. The function
|
||||
* is applied with the current value as its first argument,
|
||||
* and the given update as the second argument.
|
||||
* updates fail due to contention among threads. The function is
|
||||
* applied with the current value as its first argument, and the
|
||||
* given update as the second argument.
|
||||
*
|
||||
* @param x the update value
|
||||
* @param accumulatorFunction a side-effect-free function of two arguments
|
||||
|
@ -260,10 +260,12 @@ public class AtomicLongArray implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the element at index {@code i} with the results
|
||||
* of applying the given function, returning the previous value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads.
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the element at index {@code i} with
|
||||
* the results of applying the given function, returning the
|
||||
* previous value. The function should be side-effect-free, since
|
||||
* it may be re-applied when attempted updates fail due to
|
||||
* contention among threads.
|
||||
*
|
||||
* @param i the index
|
||||
* @param updateFunction a side-effect-free function
|
||||
@ -282,10 +284,12 @@ public class AtomicLongArray implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the element at index {@code i} with the results
|
||||
* of applying the given function, returning the updated value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads.
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the element at index {@code i} with
|
||||
* the results of applying the given function, returning the
|
||||
* updated value. The function should be side-effect-free, since it
|
||||
* may be re-applied when attempted updates fail due to contention
|
||||
* among threads.
|
||||
*
|
||||
* @param i the index
|
||||
* @param updateFunction a side-effect-free function
|
||||
@ -304,10 +308,11 @@ public class AtomicLongArray implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the element at index {@code i} with the
|
||||
* results of applying the given function to the current and given
|
||||
* values, returning the previous value. The function should be
|
||||
* side-effect-free, since it may be re-applied when attempted
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the element at index {@code i} with
|
||||
* the results of applying the given function to the current and
|
||||
* given values, returning the previous value. The function should
|
||||
* be side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads. The function is
|
||||
* applied with the current value of the element at index {@code i}
|
||||
* as its first argument, and the given update as the second
|
||||
@ -332,10 +337,11 @@ public class AtomicLongArray implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the element at index {@code i} with the
|
||||
* results of applying the given function to the current and given
|
||||
* values, returning the updated value. The function should be
|
||||
* side-effect-free, since it may be re-applied when attempted
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the element at index {@code i} with
|
||||
* the results of applying the given function to the current and
|
||||
* given values, returning the updated value. The function should
|
||||
* be side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads. The function is
|
||||
* applied with the current value of the element at index {@code i}
|
||||
* as its first argument, and the given update as the second
|
||||
|
@ -46,6 +46,7 @@ import java.util.function.LongUnaryOperator;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
import jdk.internal.reflect.CallerSensitive;
|
||||
import jdk.internal.reflect.Reflection;
|
||||
import java.lang.invoke.VarHandle;
|
||||
|
||||
/**
|
||||
* A reflection-based utility that enables atomic updates to
|
||||
@ -278,10 +279,12 @@ public abstract class AtomicLongFieldUpdater<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the field of the given object managed by this updater
|
||||
* with the results of applying the given function, returning the previous
|
||||
* value. The function should be side-effect-free, since it may be
|
||||
* re-applied when attempted updates fail due to contention among threads.
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the field of the given object managed
|
||||
* by this updater with the results of applying the given
|
||||
* function, returning the previous value. The function should be
|
||||
* side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads.
|
||||
*
|
||||
* @param obj An object whose field to get and set
|
||||
* @param updateFunction a side-effect-free function
|
||||
@ -298,10 +301,12 @@ public abstract class AtomicLongFieldUpdater<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the field of the given object managed by this updater
|
||||
* with the results of applying the given function, returning the updated
|
||||
* value. The function should be side-effect-free, since it may be
|
||||
* re-applied when attempted updates fail due to contention among threads.
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the field of the given object managed
|
||||
* by this updater with the results of applying the given
|
||||
* function, returning the updated value. The function should be
|
||||
* side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads.
|
||||
*
|
||||
* @param obj An object whose field to get and set
|
||||
* @param updateFunction a side-effect-free function
|
||||
@ -318,13 +323,14 @@ public abstract class AtomicLongFieldUpdater<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the field of the given object managed by this
|
||||
* updater with the results of applying the given function to the
|
||||
* current and given values, returning the previous value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads. The
|
||||
* function is applied with the current value as its first argument,
|
||||
* and the given update as the second argument.
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the field of the given object managed
|
||||
* by this updater with the results of applying the given function
|
||||
* to the current and given values, returning the previous value.
|
||||
* The function should be side-effect-free, since it may be
|
||||
* re-applied when attempted updates fail due to contention among
|
||||
* threads. The function is applied with the current value as its
|
||||
* first argument, and the given update as the second argument.
|
||||
*
|
||||
* @param obj An object whose field to get and set
|
||||
* @param x the update value
|
||||
@ -343,13 +349,14 @@ public abstract class AtomicLongFieldUpdater<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the field of the given object managed by this
|
||||
* updater with the results of applying the given function to the
|
||||
* current and given values, returning the updated value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads. The
|
||||
* function is applied with the current value as its first argument,
|
||||
* and the given update as the second argument.
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the field of the given object managed
|
||||
* by this updater with the results of applying the given function
|
||||
* to the current and given values, returning the updated value.
|
||||
* The function should be side-effect-free, since it may be
|
||||
* re-applied when attempted updates fail due to contention among
|
||||
* threads. The function is applied with the current value as its
|
||||
* first argument, and the given update as the second argument.
|
||||
*
|
||||
* @param obj An object whose field to get and set
|
||||
* @param x the update value
|
||||
|
@ -170,7 +170,8 @@ public class AtomicReference<V> implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the current value with the results of
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the current value with the results of
|
||||
* applying the given function, returning the previous value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads.
|
||||
@ -191,7 +192,8 @@ public class AtomicReference<V> implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the current value with the results of
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the current value with the results of
|
||||
* applying the given function, returning the updated value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads.
|
||||
@ -212,13 +214,14 @@ public class AtomicReference<V> implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the current value with the results of
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the current value with the results of
|
||||
* applying the given function to the current and given values,
|
||||
* returning the previous value. The function should be
|
||||
* side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads. The function
|
||||
* is applied with the current value as its first argument,
|
||||
* and the given update as the second argument.
|
||||
* updates fail due to contention among threads. The function is
|
||||
* applied with the current value as its first argument, and the
|
||||
* given update as the second argument.
|
||||
*
|
||||
* @param x the update value
|
||||
* @param accumulatorFunction a side-effect-free function of two arguments
|
||||
@ -238,13 +241,14 @@ public class AtomicReference<V> implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the current value with the results of
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the current value with the results of
|
||||
* applying the given function to the current and given values,
|
||||
* returning the updated value. The function should be
|
||||
* side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads. The function
|
||||
* is applied with the current value as its first argument,
|
||||
* and the given update as the second argument.
|
||||
* updates fail due to contention among threads. The function is
|
||||
* applied with the current value as its first argument, and the
|
||||
* given update as the second argument.
|
||||
*
|
||||
* @param x the update value
|
||||
* @param accumulatorFunction a side-effect-free function of two arguments
|
||||
|
@ -190,10 +190,12 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the element at index {@code i} with the results
|
||||
* of applying the given function, returning the previous value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads.
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the element at index {@code i} with
|
||||
* the results of applying the given function, returning the
|
||||
* previous value. The function should be side-effect-free, since
|
||||
* it may be re-applied when attempted updates fail due to
|
||||
* contention among threads.
|
||||
*
|
||||
* @param i the index
|
||||
* @param updateFunction a side-effect-free function
|
||||
@ -212,10 +214,12 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the element at index {@code i} with the results
|
||||
* of applying the given function, returning the updated value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads.
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the element at index {@code i} with
|
||||
* the results of applying the given function, returning the
|
||||
* updated value. The function should be side-effect-free, since it
|
||||
* may be re-applied when attempted updates fail due to contention
|
||||
* among threads.
|
||||
*
|
||||
* @param i the index
|
||||
* @param updateFunction a side-effect-free function
|
||||
@ -234,10 +238,11 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the element at index {@code i} with the
|
||||
* results of applying the given function to the current and given
|
||||
* values, returning the previous value. The function should be
|
||||
* side-effect-free, since it may be re-applied when attempted
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the element at index {@code i} with
|
||||
* the results of applying the given function to the current and
|
||||
* given values, returning the previous value. The function should
|
||||
* be side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads. The function is
|
||||
* applied with the current value of the element at index {@code i}
|
||||
* as its first argument, and the given update as the second
|
||||
@ -262,10 +267,11 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the element at index {@code i} with the
|
||||
* results of applying the given function to the current and given
|
||||
* values, returning the updated value. The function should be
|
||||
* side-effect-free, since it may be re-applied when attempted
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the element at index {@code i} with
|
||||
* the results of applying the given function to the current and
|
||||
* given values, returning the updated value. The function should
|
||||
* be side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads. The function is
|
||||
* applied with the current value of the element at index {@code i}
|
||||
* as its first argument, and the given update as the second
|
||||
|
@ -46,6 +46,7 @@ import java.util.function.UnaryOperator;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
import jdk.internal.reflect.CallerSensitive;
|
||||
import jdk.internal.reflect.Reflection;
|
||||
import java.lang.invoke.VarHandle;
|
||||
|
||||
/**
|
||||
* A reflection-based utility that enables atomic updates to
|
||||
@ -199,10 +200,12 @@ public abstract class AtomicReferenceFieldUpdater<T,V> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the field of the given object managed by this updater
|
||||
* with the results of applying the given function, returning the previous
|
||||
* value. The function should be side-effect-free, since it may be
|
||||
* re-applied when attempted updates fail due to contention among threads.
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the field of the given object managed
|
||||
* by this updater with the results of applying the given
|
||||
* function, returning the previous value. The function should be
|
||||
* side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads.
|
||||
*
|
||||
* @param obj An object whose field to get and set
|
||||
* @param updateFunction a side-effect-free function
|
||||
@ -219,10 +222,12 @@ public abstract class AtomicReferenceFieldUpdater<T,V> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the field of the given object managed by this updater
|
||||
* with the results of applying the given function, returning the updated
|
||||
* value. The function should be side-effect-free, since it may be
|
||||
* re-applied when attempted updates fail due to contention among threads.
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the field of the given object managed
|
||||
* by this updater with the results of applying the given
|
||||
* function, returning the updated value. The function should be
|
||||
* side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads.
|
||||
*
|
||||
* @param obj An object whose field to get and set
|
||||
* @param updateFunction a side-effect-free function
|
||||
@ -239,13 +244,14 @@ public abstract class AtomicReferenceFieldUpdater<T,V> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the field of the given object managed by this
|
||||
* updater with the results of applying the given function to the
|
||||
* current and given values, returning the previous value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads. The
|
||||
* function is applied with the current value as its first argument,
|
||||
* and the given update as the second argument.
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the field of the given object managed
|
||||
* by this updater with the results of applying the given function
|
||||
* to the current and given values, returning the previous value.
|
||||
* The function should be side-effect-free, since it may be
|
||||
* re-applied when attempted updates fail due to contention among
|
||||
* threads. The function is applied with the current value as its
|
||||
* first argument, and the given update as the second argument.
|
||||
*
|
||||
* @param obj An object whose field to get and set
|
||||
* @param x the update value
|
||||
@ -264,13 +270,14 @@ public abstract class AtomicReferenceFieldUpdater<T,V> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the field of the given object managed by this
|
||||
* updater with the results of applying the given function to the
|
||||
* current and given values, returning the updated value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads. The
|
||||
* function is applied with the current value as its first argument,
|
||||
* and the given update as the second argument.
|
||||
* Atomically updates (with memory effects as specified by {@link
|
||||
* VarHandle#compareAndSet}) the field of the given object managed
|
||||
* by this updater with the results of applying the given function
|
||||
* to the current and given values, returning the updated value.
|
||||
* The function should be side-effect-free, since it may be
|
||||
* re-applied when attempted updates fail due to contention among
|
||||
* threads. The function is applied with the current value as its
|
||||
* first argument, and the given update as the second argument.
|
||||
*
|
||||
* @param obj An object whose field to get and set
|
||||
* @param x the update value
|
||||
|
@ -0,0 +1,399 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<!--
|
||||
Copyright (c) 1998, 2017, 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. Oracle designates this
|
||||
particular file as subject to the "Classpath" exception as provided
|
||||
by Oracle in the LICENSE file that accompanied this code.
|
||||
|
||||
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.
|
||||
-->
|
||||
|
||||
<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml" xml:lang=
|
||||
"en-US">
|
||||
<head>
|
||||
<title>Java Collections API Design FAQ</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Java Collections API Design FAQ</h2>
|
||||
<!-- Body text begins here -->
|
||||
<hr />
|
||||
This document answers frequently asked questions concerning the
|
||||
design of the Java collections framework. It is derived from the
|
||||
large volume of traffic on the collections-comments alias. It
|
||||
serves as a design rationale for the collections framework.
|
||||
<h3>Core Interfaces - General Questions</h3>
|
||||
<ol>
|
||||
<li><a href="#a1"><b>Why don't you support immutability directly in
|
||||
the core collection interfaces so that you can do away with
|
||||
<em>optional operations</em> (and
|
||||
UnsupportedOperationException)?</b></a></li>
|
||||
<li><a href="#a2"><b>Won't programmers have to surround any code
|
||||
that calls optional operations with a try-catch clause in case they
|
||||
throw an UnsupportedOperationException?</b></a></li>
|
||||
<li><a href="#a3"><b>Why isn't there a core interface for "bags"
|
||||
(AKA multisets)?</b></a></li>
|
||||
<li><a href="#a28"><b>Why didn't you use "Beans-style names" for
|
||||
consistency?</b></a></li>
|
||||
</ol>
|
||||
<h3>Collection Interface</h3>
|
||||
<ol>
|
||||
<li><a href="#a5"><b>Why doesn't Collection extend Cloneable and
|
||||
Serializable?</b></a></li>
|
||||
<li><a href="#a6"><b>Why don't you provide an "apply" method in
|
||||
Collection to apply a given method ("upcall") to all the elements
|
||||
of the Collection?</b></a></li>
|
||||
<li><a href="#a7"><b>Why didn't you provide a "Predicate" interface,
|
||||
and related methods (e.g., a method to find the first element in
|
||||
the Collection satisfying the predicate)?</b></a></li>
|
||||
<li><a href="#a8"><b>Why don't you provide a form of the addAll
|
||||
method that takes an Enumeration (or an Iterator)?</b></a></li>
|
||||
<li><a href="#a9"><b>Why don't the concrete implementations in the
|
||||
JDK have Enumeration (or Iterator) constructors?</b></a></li>
|
||||
<li><a href="#a10"><b>Why don't you provide an Iterator.add
|
||||
method?</b></a></li>
|
||||
</ol>
|
||||
<h3>List Interface</h3>
|
||||
<ol>
|
||||
<li><a href="#a11"><b>Why don't you rename the List interface to
|
||||
Sequence; doesn't "list" generally suggest "linked list"? Also,
|
||||
doesn't it conflict with java.awt.List?</b></a></li>
|
||||
<li><a href="#a12"><b>Why don't you rename List's set method to
|
||||
replace, to avoid confusion with Set.</b></a></li>
|
||||
</ol>
|
||||
<h3>Map Interface</h3>
|
||||
<ol>
|
||||
<li><a href="#a14"><b>Why doesn't Map extend
|
||||
Collection?</b></a></li>
|
||||
</ol>
|
||||
<h3>Iterator Interface</h3>
|
||||
<ol>
|
||||
<li><a href="#a18"><b>Why doesn't Iterator extend
|
||||
Enumeration?</b></a></li>
|
||||
<li><a href="#a19"><b>Why don't you provide an Iterator.peek method
|
||||
that allows you to look at the next element in an iteration without
|
||||
advancing the iterator?</b></a></li>
|
||||
</ol>
|
||||
<h3>Miscellaneous</h3>
|
||||
<ol>
|
||||
<li><a href="#a23"><b>Why did you write a new collections framework
|
||||
instead of adopting JGL (a preexisting collections package from
|
||||
ObjectSpace, Inc.) into the JDK?</b></a></li>
|
||||
<li><a href="#a26"><b>Why don't you eliminate all of the methods and
|
||||
classes that return "views" (Collections backed by other
|
||||
collection-like objects). This would greatly reduce
|
||||
aliasing.</b></a></li>
|
||||
<li><a href="#a27"><b>Why don't you provide for "observable"
|
||||
collections that send out Events when they're
|
||||
modified?</b></a></li>
|
||||
</ol>
|
||||
<hr size="3" noshade="noshade" />
|
||||
<h3>Core Interfaces - General Questions</h3>
|
||||
<ol>
|
||||
<li><a name="a1" id="a1"><b>Why don't you support immutability
|
||||
directly in the core collection interfaces so that you can do away
|
||||
with <em>optional operations</em> (and
|
||||
UnsupportedOperationException)?</b></a>
|
||||
<p>This is the most controversial design decision in the whole API.
|
||||
Clearly, static (compile time) type checking is highly desirable,
|
||||
and is the norm in Java. We would have supported it if we believed
|
||||
it were feasible. Unfortunately, attempts to achieve this goal
|
||||
cause an explosion in the size of the interface hierarchy, and do
|
||||
not succeed in eliminating the need for runtime exceptions (though
|
||||
they reduce it substantially).</p>
|
||||
<p>Doug Lea, who wrote a popular Java collections package that did
|
||||
reflect mutability distinctions in its interface hierarchy, no
|
||||
longer believes it is a viable approach, based on user experience
|
||||
with his collections package. In his words (from personal
|
||||
correspondence) "Much as it pains me to say it, strong static
|
||||
typing does not work for collection interfaces in Java."</p>
|
||||
<p>To illustrate the problem in gory detail, suppose you want to
|
||||
add the notion of modifiability to the Hierarchy. You need four new
|
||||
interfaces: ModifiableCollection, ModifiableSet, ModifiableList,
|
||||
and ModifiableMap. What was previously a simple hierarchy is now a
|
||||
messy heterarchy. Also, you need a new Iterator interface for use
|
||||
with unmodifiable Collections, that does not contain the remove
|
||||
operation. Now can you do away with UnsupportedOperationException?
|
||||
Unfortunately not.</p>
|
||||
<p>Consider arrays. They implement most of the List operations, but
|
||||
not remove and add. They are "fixed-size" Lists. If you want to
|
||||
capture this notion in the hierarchy, you have to add two new
|
||||
interfaces: VariableSizeList and VariableSizeMap. You don't have to
|
||||
add VariableSizeCollection and VariableSizeSet, because they'd be
|
||||
identical to ModifiableCollection and ModifiableSet, but you might
|
||||
choose to add them anyway for consistency's sake. Also, you need a
|
||||
new variety of ListIterator that doesn't support the add and remove
|
||||
operations, to go along with unmodifiable List. Now we're up to ten
|
||||
or twelve interfaces, plus two new Iterator interfaces, instead of
|
||||
our original four. Are we done? No.</p>
|
||||
<p>Consider logs (such as error logs, audit logs and journals for
|
||||
recoverable data objects). They are natural append-only sequences,
|
||||
that support all of the List operations except for remove and set
|
||||
(replace). They require a new core interface, and a new
|
||||
iterator.</p>
|
||||
<p>And what about immutable Collections, as opposed to unmodifiable
|
||||
ones? (i.e., Collections that cannot be changed by the client AND
|
||||
will never change for any other reason). Many argue that this is
|
||||
the most important distinction of all, because it allows multiple
|
||||
threads to access a collection concurrently without the need for
|
||||
synchronization. Adding this support to the type hierarchy requires
|
||||
four more interfaces.</p>
|
||||
<p>Now we're up to twenty or so interfaces and five iterators, and
|
||||
it's almost certain that there are still collections arising in
|
||||
practice that don't fit cleanly into any of the interfaces. For
|
||||
example, the <em>collection-views</em> returned by Map are natural
|
||||
delete-only collections. Also, there are collections that will
|
||||
reject certain elements on the basis of their value, so we still
|
||||
haven't done away with runtime exceptions.</p>
|
||||
<p>When all was said and done, we felt that it was a sound
|
||||
engineering compromise to sidestep the whole issue by providing a
|
||||
very small set of core interfaces that can throw a runtime
|
||||
exception.</p>
|
||||
</li>
|
||||
<li><a name="a2" id="a2"><b>Won't programmers have to surround any
|
||||
code that calls optional operations with a try-catch clause in case
|
||||
they throw an UnsupportedOperationException?</b></a>
|
||||
<p>It was never our intention that programs should catch these
|
||||
exceptions: that's why they're unchecked (runtime) exceptions. They
|
||||
should only arise as a result of programming errors, in which case,
|
||||
your program will halt due to the uncaught exception.</p>
|
||||
</li>
|
||||
<li><a name="a3" id="a3"><b>Why isn't there a core interface for
|
||||
"bags" (AKA multisets)?</b></a>
|
||||
<p>The Collection interface provides this functionality. We are not
|
||||
providing any public implementations of this interface, as we think
|
||||
that it wouldn't be used frequently enough to "pull its weight." We
|
||||
occasionally return such Collections, which are implemented easily
|
||||
atop AbstractCollection (for example, the Collection returned by
|
||||
Map.values).</p>
|
||||
</li>
|
||||
<li><a name="a28" id="a28"><b>Why didn't you use "Beans-style
|
||||
names" for consistency?</b></a>
|
||||
<p>While the names of the new collections methods do not adhere to
|
||||
the "Beans naming conventions", we believe that they are
|
||||
reasonable, consistent and appropriate to their purpose. It should
|
||||
be remembered that the Beans naming conventions do not apply to the
|
||||
JDK as a whole; the AWT did adopt these conventions, but that
|
||||
decision was somewhat controversial. We suspect that the
|
||||
collections APIs will be used quite pervasively, often with
|
||||
multiple method calls on a single line of code, so it is important
|
||||
that the names be short. Consider, for example, the Iterator
|
||||
methods. Currently, a loop over a collection looks like this:</p>
|
||||
<pre>
|
||||
for (Iterator i = c.iterator(); i.hasNext(); )
|
||||
System.out.println(i.next());
|
||||
</pre>
|
||||
Everything fits neatly on one line, even if the Collection name is
|
||||
a long expression. If we named the methods "getIterator",
|
||||
"hasNextElement" and "getNextElement", this would no longer be the
|
||||
case. Thus, we adopted the "traditional" JDK style rather than the
|
||||
Beans style.</li>
|
||||
</ol>
|
||||
<hr />
|
||||
<h3>Collection Interface</h3>
|
||||
<ol>
|
||||
<li><a name="a5" id="a5"><b>Why doesn't Collection extend Cloneable
|
||||
and Serializable?</b></a>
|
||||
<p>Many Collection implementations (including all of the ones
|
||||
provided by the JDK) will have a public clone method, but it would
|
||||
be mistake to require it of all Collections. For example, what does
|
||||
it mean to clone a Collection that's backed by a terabyte SQL
|
||||
database? Should the method call cause the company to requisition a
|
||||
new disk farm? Similar arguments hold for serializable.</p>
|
||||
<p>If the client doesn't know the actual type of a Collection, it's
|
||||
much more flexible and less error prone to have the client decide
|
||||
what type of Collection is desired, create an empty Collection of
|
||||
this type, and use the addAll method to copy the elements of the
|
||||
original collection into the new one.</p>
|
||||
</li>
|
||||
<li><a name="a6" id="a6"><b>Why don't you provide an "apply" method
|
||||
in Collection to apply a given method ("upcall") to all the
|
||||
elements of the Collection?</b></a>
|
||||
<p>This is what is referred to as an "Internal Iterator" in the
|
||||
"Design Patterns" book (Gamma et al.). We considered providing it,
|
||||
but decided not to as it seems somewhat redundant to support
|
||||
internal and external iterators, and Java already has a precedent
|
||||
for external iterators (with Enumerations). The "throw weight" of
|
||||
this functionality is increased by the fact that it requires a
|
||||
public interface to describe upcalls.</p>
|
||||
</li>
|
||||
<li><a name="a7" id="a7"><b>Why didn't you provide a "Predicate"
|
||||
interface, and related methods (e.g., a method to find the first
|
||||
element in the Collection satisfying the predicate)?</b></a>
|
||||
<p>It's easy to implement this functionality atop Iterators, and
|
||||
the resulting code may actually look cleaner as the user can inline
|
||||
the predicate. Thus, it's not clear whether this facility pulls its
|
||||
weight. It could be added to the Collections class at a later date
|
||||
(implemented atop Iterator), if it's deemed useful.</p>
|
||||
</li>
|
||||
<li><a name="a8" id="a8"><b>Why don't you provide a form of the
|
||||
addAll method that takes an Enumeration (or an Iterator)?</b></a>
|
||||
<p>Because we don't believe in using Enumerations (or Iterators) as
|
||||
"poor man's collections." This was occasionally done in prior
|
||||
releases, but now that we have the Collection interface, it is the
|
||||
preferred way to pass around abstract collections of objects.</p>
|
||||
</li>
|
||||
<li><a name="a9" id="a9"><b>Why don't the concrete implementations
|
||||
in the JDK have Enumeration (or Iterator) constructors?</b></a>
|
||||
<p>Again, this is an instance of an Enumeration serving as a "poor
|
||||
man's collection" and we're trying to discourage that. Note
|
||||
however, that we strongly suggest that all concrete implementations
|
||||
should have constructors that take a Collection (and create a new
|
||||
Collection with the same elements).</p>
|
||||
</li>
|
||||
<li><a name="a10" id="a10"><b>Why don't you provide an Iterator.add
|
||||
method?</b></a>
|
||||
<p>The semantics are unclear, given that the contract for Iterator
|
||||
makes no guarantees about the order of iteration. Note, however,
|
||||
that ListIterator does provide an add operation, as it does
|
||||
guarantee the order of the iteration.</p>
|
||||
</li>
|
||||
</ol>
|
||||
<hr />
|
||||
<h3>List Interface</h3>
|
||||
<ol>
|
||||
<li><a name="a11" id="a11"><b>Why don't you rename the List
|
||||
interface to Sequence; doesn't "list" generally suggest "linked
|
||||
list"? Also, doesn't it conflict with java.awt.List?</b></a>
|
||||
<p>People were evenly divided as to whether List suggests linked
|
||||
lists. Given the implementation naming convention,
|
||||
<<em>Implementation</em>><<em>Interface</em>>, there
|
||||
was a strong desire to keep the core interface names short. Also,
|
||||
several existing names (AbstractSequentialList, LinkedList) would
|
||||
have been decidedly worse if we changed List to Sequence. The
|
||||
naming conflict can be dealt with by the following incantation:</p>
|
||||
<pre>
|
||||
import java.util.*;
|
||||
import java.awt.*;
|
||||
import java.util.List; // Dictates interpretation of "List"
|
||||
</pre></li>
|
||||
<li><a name="a12" id="a12"><b>Why don't you rename List's set
|
||||
method to replace, to avoid confusion with Set.</b></a>
|
||||
<p>It was decided that the "set/get" naming convention was strongly
|
||||
enough enshrined in the language that we'd stick with it.</p>
|
||||
</li>
|
||||
</ol>
|
||||
<hr />
|
||||
<h3>Map Interface</h3>
|
||||
<ol>
|
||||
<li><a name="a14" id="a14"><b>Why doesn't Map extend
|
||||
Collection?</b></a>
|
||||
<p>This was by design. We feel that mappings are not collections
|
||||
and collections are not mappings. Thus, it makes little sense for
|
||||
Map to extend the Collection interface (or vice versa).</p>
|
||||
<p>If a Map is a Collection, what are the elements? The only
|
||||
reasonable answer is "Key-value pairs", but this provides a very
|
||||
limited (and not particularly useful) Map abstraction. You can't
|
||||
ask what value a given key maps to, nor can you delete the entry
|
||||
for a given key without knowing what value it maps to.</p>
|
||||
<p>Collection could be made to extend Map, but this raises the
|
||||
question: what are the keys? There's no really satisfactory answer,
|
||||
and forcing one leads to an unnatural interface.</p>
|
||||
<p>Maps can be <em>viewed</em> as Collections (of keys, values, or
|
||||
pairs), and this fact is reflected in the three "Collection view
|
||||
operations" on Maps (keySet, entrySet, and values). While it is, in
|
||||
principle, possible to view a List as a Map mapping indices to
|
||||
elements, this has the nasty property that deleting an element from
|
||||
the List changes the Key associated with every element before the
|
||||
deleted element. That's why we don't have a map view operation on
|
||||
Lists.</p>
|
||||
</li>
|
||||
</ol>
|
||||
<hr />
|
||||
<h3>Iterator Interface</h3>
|
||||
<ol>
|
||||
<li><a name="a18" id="a18"><b>Why doesn't Iterator extend
|
||||
Enumeration?</b></a>
|
||||
<p>We view the method names for Enumeration as unfortunate. They're
|
||||
very long, and very frequently used. Given that we were adding a
|
||||
method and creating a whole new framework, we felt that it would be
|
||||
foolish not to take advantage of the opportunity to improve the
|
||||
names. Of course we could support the new and old names in
|
||||
Iterator, but it doesn't seem worthwhile.</p>
|
||||
</li>
|
||||
<li><a name="a19" id="a19"><b>Why don't you provide an
|
||||
Iterator.peek method that allows you to look at the next element in
|
||||
an iteration without advancing the iterator?</b></a>
|
||||
<p>It can be implemented atop the current Iterators (a similar
|
||||
pattern to java.io.PushbackInputStream). We believe that its use
|
||||
would be rare enough that it isn't worth including in the interface
|
||||
that everyone has to implement.</p>
|
||||
</li>
|
||||
</ol>
|
||||
<hr />
|
||||
<h3>Miscellaneous</h3>
|
||||
<ol>
|
||||
<li><a name="a23" id="a23"><b>Why did you write a new collections
|
||||
framework instead of adopting JGL (a preexisting collections
|
||||
package from ObjectSpace, Inc.) into the JDK?</b></a>
|
||||
<p>If you examine the goals for our Collections framework (in the
|
||||
Overview), you'll see that we are not really "playing in the same
|
||||
space" as JGL. Quoting from the "Design Goals" Section of the Java
|
||||
Collections Overview: "Our main design goal was to produce an API
|
||||
that was reasonably small, both in size, and (more importantly) in
|
||||
'conceptual weight.'"</p>
|
||||
<p>JGL consists of approximately 130 classes and interfaces; its
|
||||
main goal was consistency with the C++ Standard Template Library
|
||||
(STL). This was <em>not</em> one of our goals. Java has
|
||||
traditionally stayed away from C++'s more complex features (e.g.,
|
||||
multiple inheritance, operator overloading). Our entire framework,
|
||||
including all infrastructure, contains approximately 25 classes and
|
||||
interfaces.</p>
|
||||
<p>While this may cause some discomfort for some C++ programmers,
|
||||
we feel that it will be good for Java in the long run. As the Java
|
||||
libraries mature, they inevitably grow, but we are trying as hard
|
||||
as we can to keep them small and manageable, so that Java continues
|
||||
to be an easy, fun language to learn and to use.</p>
|
||||
</li>
|
||||
<li><a name="a26" id="a26"><b>Why don't you eliminate all of the
|
||||
methods and classes that return "views" (Collections backed by
|
||||
other collection-like objects). This would greatly reduce
|
||||
aliasing.</b></a>
|
||||
<p>Given that we provide core collection interfaces behind which
|
||||
programmers can "hide" their own implementations, there will be
|
||||
aliased collections whether the JDK provides them or not.
|
||||
Eliminating all views from the JDK would greatly increase the cost
|
||||
of common operations like making a Collection out of an array, and
|
||||
would do away with many useful facilities (like synchronizing
|
||||
wrappers). One view that we see as being particularly useful is
|
||||
<a href=
|
||||
"../List.html#subList-int-int-">List.subList</a>.
|
||||
The existence of this method means that people who write methods
|
||||
taking List on input do not have to write secondary forms taking an
|
||||
offset and a length (as they do for arrays).</p>
|
||||
</li>
|
||||
<li><a name="a27" id="a27"><b>Why don't you provide for
|
||||
"observable" collections that send out Events when they're
|
||||
modified?</b></a>
|
||||
<p>Primarily, resource constraints. If we're going to commit to
|
||||
such an API, it has to be something that works for everyone, that
|
||||
we can live with for the long haul. We may provide such a facility
|
||||
some day. In the meantime, it's not difficult to implement such a
|
||||
facility on top of the public APIs.</p>
|
||||
</li>
|
||||
</ol>
|
||||
<hr />
|
||||
<p style="font-size:smaller">
|
||||
Copyright © 1998, 2017, Oracle and/or its affiliates. 500 Oracle Parkway<br />
|
||||
Redwood Shores, CA 94065 USA. All rights reserved.</p>
|
||||
<!-- Body text ends here -->
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<!--
|
||||
Copyright (c) 1998, 2017, 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. Oracle designates this
|
||||
particular file as subject to the "Classpath" exception as provided
|
||||
by Oracle in the LICENSE file that accompanied this code.
|
||||
|
||||
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.
|
||||
-->
|
||||
|
||||
<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml" xml:lang=
|
||||
"en-US">
|
||||
<head>
|
||||
<meta name="generator" content="HTML Tidy, see www.w3.org" />
|
||||
<title>The Collections Framework</title>
|
||||
|
||||
<style type="text/css">
|
||||
/*<![CDATA[*/
|
||||
|
||||
ul li, ul ul li {font-weight: normal;}
|
||||
pre {margin-left: 42pt;}
|
||||
a {font-weight: bold;}
|
||||
|
||||
/*]]>*/
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>The Collections Framework</h1>
|
||||
<!-- Body text begins here -->
|
||||
<p>The collections framework is a unified architecture for
|
||||
representing and manipulating collections, enabling them to be
|
||||
manipulated independently of the details of their representation.
|
||||
It reduces programming effort while increasing performance. It
|
||||
enables interoperability among unrelated APIs, reduces effort in
|
||||
designing and learning new APIs, and fosters software reuse. The
|
||||
framework is based on more than a dozen collection interfaces. It
|
||||
includes implementations of these interfaces and algorithms to
|
||||
manipulate them.</p>
|
||||
<p>The documents in this section are non-normative portions of
|
||||
the Java™ Platform, Standard Edition API Specification.</p>
|
||||
<ul>
|
||||
<li><b><a href="coll-overview.html">Overview</a></b> - An overview of
|
||||
the collections framework.</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><b><a href="coll-reference.html">Annotated API Outline</a></b> - An
|
||||
annotated outline of the classes and interfaces comprising the
|
||||
collections framework, with links into the API Specification.</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><b><a href="coll-designfaq.html">Design FAQ</a></b> - Answers to
|
||||
frequently asked questions (FAQ) about the design of the
|
||||
collections framework.</li>
|
||||
</ul>
|
||||
<hr />
|
||||
<p style="font-size:smaller">
|
||||
Copyright © 1998, 2017, Oracle and/or its affiliates. 500 Oracle Parkway<br />
|
||||
Redwood Shores, CA 94065 USA. All rights reserved.</p>
|
||||
<!-- Body text ends here -->
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,359 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<!--
|
||||
Copyright (c) 1998, 2017, 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. Oracle designates this
|
||||
particular file as subject to the "Classpath" exception as provided
|
||||
by Oracle in the LICENSE file that accompanied this code.
|
||||
|
||||
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.
|
||||
-->
|
||||
|
||||
<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml" xml:lang=
|
||||
"en-US">
|
||||
<head>
|
||||
<title>Collections Framework Overview</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Collections Framework Overview</h1>
|
||||
<!-- Body text begins here -->
|
||||
<h2>Introduction</h2>
|
||||
The Java platform includes a <i>collections framework</i>. A
|
||||
<i>collection</i> is an object that represents a group of objects
|
||||
(such as the classic <a href="../ArrayList.html">ArrayList</a> class).
|
||||
A collections framework is a unified architecture for representing
|
||||
and manipulating collections, enabling collections to be
|
||||
manipulated independently of implementation details.
|
||||
<p>The primary advantages of a collections framework are that
|
||||
it:</p>
|
||||
<ul>
|
||||
<li><strong>Reduces programming effort</strong> by providing data
|
||||
structures and algorithms so you don't have to write them
|
||||
yourself.</li>
|
||||
<li><strong>Increases performance</strong> by providing
|
||||
high-performance implementations of data structures and algorithms.
|
||||
Because the various implementations of each interface are
|
||||
interchangeable, programs can be tuned by switching
|
||||
implementations.</li>
|
||||
<li><strong>Provides interoperability between unrelated
|
||||
APIs</strong> by establishing a common language to pass collections
|
||||
back and forth.</li>
|
||||
<li><strong>Reduces the effort required to learn APIs</strong> by
|
||||
requiring you to learn multiple ad hoc collection APIs.</li>
|
||||
<li><strong>Reduces the effort required to design and implement
|
||||
APIs</strong> by not requiring you to produce ad hoc collections
|
||||
APIs.</li>
|
||||
<li><strong>Fosters software reuse</strong> by providing a standard
|
||||
interface for collections and algorithms with which to manipulate
|
||||
them.</li>
|
||||
</ul>
|
||||
<p>The collections framework consists of:</p>
|
||||
<ul>
|
||||
<li><strong>Collection interfaces</strong>. Represent different
|
||||
types of collections, such as sets, lists, and maps. These
|
||||
interfaces form the basis of the framework.</li>
|
||||
<li><strong>General-purpose implementations</strong>. Primary
|
||||
implementations of the collection interfaces.</li>
|
||||
<li><strong>Legacy implementations</strong>. The collection classes
|
||||
from earlier releases, <tt>Vector</tt> and <tt>Hashtable</tt>, were
|
||||
retrofitted to implement the collection interfaces.</li>
|
||||
<li><strong>Special-purpose implementations</strong>.
|
||||
Implementations designed for use in special situations. These
|
||||
implementations display nonstandard performance characteristics,
|
||||
usage restrictions, or behavior.</li>
|
||||
<li><strong>Concurrent implementations</strong>. Implementations
|
||||
designed for highly concurrent use.</li>
|
||||
<li><strong>Wrapper implementations</strong>. Add functionality,
|
||||
such as synchronization, to other implementations.</li>
|
||||
<li><strong>Convenience implementations</strong>. High-performance
|
||||
"mini-implementations" of the collection interfaces.</li>
|
||||
<li><strong>Abstract implementations</strong>. Partial
|
||||
implementations of the collection interfaces to facilitate custom
|
||||
implementations.</li>
|
||||
<li><strong>Algorithms</strong>. Static methods that perform useful
|
||||
functions on collections, such as sorting a list.</li>
|
||||
<li><strong>Infrastructure</strong>. Interfaces that provide
|
||||
essential support for the collection interfaces.</li>
|
||||
<li><strong>Array Utilities</strong>. Utility functions for arrays
|
||||
of primitive types and reference objects. Not, strictly speaking, a
|
||||
part of the collections framework, this feature was added to the
|
||||
Java platform at the same time as the collections framework and
|
||||
relies on some of the same infrastructure.</li>
|
||||
</ul>
|
||||
<hr />
|
||||
<h2>Collection Interfaces</h2>
|
||||
<p>The <i>collection interfaces</i> are divided into two groups.
|
||||
The most basic interface, <tt><a href=
|
||||
"../Collection.html">java.util.Collection</a></tt>,
|
||||
has the following descendants:</p>
|
||||
<ul>
|
||||
<li><tt><a href=
|
||||
"../Set.html">java.util.Set</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../SortedSet.html">java.util.SortedSet</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../NavigableSet.html">java.util.NavigableSet</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../Queue.html">java.util.Queue</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/BlockingQueue.html">java.util.concurrent.BlockingQueue</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/TransferQueue.html">java.util.concurrent.TransferQueue</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../Deque.html">java.util.Deque</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/BlockingDeque.html">java.util.concurrent.BlockingDeque</a></tt></li>
|
||||
</ul>
|
||||
<p>The other collection interfaces are based on <tt><a href=
|
||||
"../Map.html">java.util.Map</a></tt> and are
|
||||
not true collections. However, these interfaces contain
|
||||
<i>collection-view</i> operations, which enable them to be
|
||||
manipulated as collections. <tt>Map</tt> has the following
|
||||
offspring:</p>
|
||||
<ul>
|
||||
<li><tt><a href=
|
||||
"../SortedMap.html">java.util.SortedMap</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../NavigableMap.html">java.util.NavigableMap</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/ConcurrentMap.html">java.util.concurrent.ConcurrentMap</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/ConcurrentNavigableMap.html">java.util.concurrent.ConcurrentNavigableMap</a></tt></li>
|
||||
</ul>
|
||||
<p>Many of the modification methods in the collection interfaces
|
||||
are labeled <i>optional</i>. Implementations are permitted to not
|
||||
perform one or more of these operations, throwing a runtime
|
||||
exception (<tt>UnsupportedOperationException</tt>) if they are
|
||||
attempted. The documentation for each implementation must specify
|
||||
which optional operations are supported. Several terms are
|
||||
introduced to aid in this specification:</p>
|
||||
<ul>
|
||||
<li>Collections that do not support modification operations (such
|
||||
as <tt>add</tt>, <tt>remove</tt> and <tt>clear</tt>) are referred
|
||||
to as <i>unmodifiable</i>. Collections that are not unmodifiable
|
||||
are <i>modifiable.</i></li>
|
||||
<li>Collections that additionally guarantee that no change in the
|
||||
<tt>Collection</tt> object will be visible are referred to as
|
||||
<i>immutable</i>. Collections that are not immutable are
|
||||
<i>mutable</i>.</li>
|
||||
<li>Lists that guarantee that their size remains constant even
|
||||
though the elements can change are referred to as
|
||||
<i>fixed-size</i>. Lists that are not fixed-size are referred to as
|
||||
<i>variable-size</i>.</li>
|
||||
<li>Lists that support fast (generally constant time) indexed
|
||||
element access are known as <i>random access</i> lists. Lists that
|
||||
do not support fast indexed element access are known as
|
||||
<i>sequential access</i> lists. The <tt><a href=
|
||||
"../RandomAccess.html">RandomAccess</a></tt>
|
||||
marker interface enables lists to advertise the fact that they
|
||||
support random access. This enables generic algorithms to change
|
||||
their behavior to provide good performance when applied to either
|
||||
random or sequential access lists.</li>
|
||||
</ul>
|
||||
<p>Some implementations restrict what elements (or in the case of
|
||||
<tt>Maps</tt>, keys and values) can be stored. Possible
|
||||
restrictions include requiring elements to:</p>
|
||||
<ul>
|
||||
<li>Be of a particular type.</li>
|
||||
<li>Be not null.</li>
|
||||
<li>Obey some arbitrary predicate.</li>
|
||||
</ul>
|
||||
<p>Attempting to add an element that violates an implementation's
|
||||
restrictions results in a runtime exception, typically a
|
||||
<tt>ClassCastException</tt>, an <tt>IllegalArgumentException</tt>,
|
||||
or a <tt>NullPointerException</tt>. Attempting to remove or test
|
||||
for the presence of an element that violates an implementation's
|
||||
restrictions can result in an exception. Some restricted
|
||||
collections permit this usage.</p>
|
||||
<hr />
|
||||
<h2>Collection Implementations</h2>
|
||||
<p>Classes that implement the collection interfaces typically have
|
||||
names in the form of
|
||||
<<em>Implementation-style</em>><<em>Interface</em>>.
|
||||
The general purpose implementations are summarized in the following
|
||||
table:</p>
|
||||
<table border="2" summary=
|
||||
"general purpose implementations and interfaces" align="center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th id="interfaces">Interface</th>
|
||||
<th id="hashtable">Hash Table</th>
|
||||
<th id="resizablearray">Resizable Array</th>
|
||||
<th id="balancedtree">Balanced Tree</th>
|
||||
<th id="linkedlist">Linked List</th>
|
||||
<th id="hashtableandlinkedlist">Hash Table + Linked List</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="interfaces"><code>Set</code></td>
|
||||
<td headers="hashtable"><a href=
|
||||
"../HashSet.html"><tt>HashSet</tt></a></td>
|
||||
<td headers="resizablearray"> </td>
|
||||
<td headers="balancedtree"><a href=
|
||||
"../TreeSet.html"><tt>TreeSet</tt></a></td>
|
||||
<td headers="linkedlist"> </td>
|
||||
<td headers="hashtableandlinkedlist"><a href=
|
||||
"../LinkedHashSet.html"><tt>LinkedHashSet</tt></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="interfaces"><code>List</code></td>
|
||||
<td headers="hashtable"> </td>
|
||||
<td headers="resizablearray"><a href=
|
||||
"../ArrayList.html"><tt>ArrayList</tt></a></td>
|
||||
<td headers="balancedtree"> </td>
|
||||
<td headers="linkedlist"><a href=
|
||||
"../LinkedList.html"><tt>LinkedList</tt></a></td>
|
||||
<td headers="hashtableandlinkedlist"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="interfaces"><code>Deque</code></td>
|
||||
<td headers="hashtable"> </td>
|
||||
<td headers="resizablearray"><a href=
|
||||
"../ArrayDeque.html"><tt>ArrayDeque</tt></a></td>
|
||||
<td headers="balancedtree"> </td>
|
||||
<td headers="linkedlist"><a href=
|
||||
"../LinkedList.html"><tt>LinkedList</tt></a></td>
|
||||
<td headers="hashtableandlinkedlist"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="interfaces"><code>Map</code></td>
|
||||
<td headers="hashtable"><a href=
|
||||
"../HashMap.html"><tt>HashMap</tt></a></td>
|
||||
<td headers="resizablearray"> </td>
|
||||
<td headers="balancedtree"><a href=
|
||||
"../TreeMap.html"><tt>TreeMap</tt></a></td>
|
||||
<td headers="linkedlist"> </td>
|
||||
<td headers="hashtableandlinkedlist"><a href=
|
||||
"../LinkedHashMap.html"><tt>LinkedHashMap</tt></a></td>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
<p>The general-purpose implementations support all of the
|
||||
<i>optional operations</i> in the collection interfaces and have no
|
||||
restrictions on the elements they may contain. They are
|
||||
unsynchronized, but the <tt>Collections</tt> class contains static
|
||||
factories called <a href=
|
||||
"../Collections.html#synchronizedCollection-java.util.Collection-">
|
||||
<em>synchronization wrappers</em></a> that can be used to add
|
||||
synchronization to many unsynchronized collections. All of the new
|
||||
implementations have <i>fail-fast iterators</i>, which detect
|
||||
invalid concurrent modification, and fail quickly and cleanly
|
||||
(rather than behaving erratically).</p>
|
||||
<p>The <tt>AbstractCollection</tt>, <tt>AbstractSet</tt>,
|
||||
<tt>AbstractList</tt>, <tt>AbstractSequentialList</tt> and
|
||||
<tt>AbstractMap</tt> classes provide basic implementations of the
|
||||
core collection interfaces, to minimize the effort required to
|
||||
implement them. The API documentation for these classes describes
|
||||
precisely how each method is implemented so the implementer knows
|
||||
which methods must be overridden, given the performance of the
|
||||
basic operations of a specific implementation.</p>
|
||||
<hr />
|
||||
<h2>Concurrent Collections</h2>
|
||||
<p>Applications that use collections from more than one thread must
|
||||
be carefully programmed. In general, this is known as <i>concurrent
|
||||
programming</i>. The Java platform includes extensive support for
|
||||
concurrent programming. See <a href=
|
||||
"../concurrent/package-summary.html">Java Concurrency
|
||||
Utilities</a> for details.</p>
|
||||
<p>Collections are so frequently used that various concurrent
|
||||
friendly interfaces and implementations of collections are included
|
||||
in the APIs. These types go beyond the synchronization wrappers
|
||||
discussed previously to provide features that are frequently needed
|
||||
in concurrent programming.</p>
|
||||
<p>These concurrent-aware interfaces are available:</p>
|
||||
<ul>
|
||||
<li><tt><a href=
|
||||
"../concurrent/BlockingQueue.html">BlockingQueue</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/TransferQueue.html">TransferQueue</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/BlockingDeque.html">BlockingDeque</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/ConcurrentMap.html">ConcurrentMap</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/ConcurrentNavigableMap.html">ConcurrentNavigableMap</a></tt></li>
|
||||
</ul>
|
||||
<p>The following concurrent-aware implementation classes are
|
||||
available. See the API documentation for the correct usage of these
|
||||
implementations.</p>
|
||||
<ul>
|
||||
<li><tt><a href=
|
||||
"../concurrent/LinkedBlockingQueue.html">LinkedBlockingQueue</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/ArrayBlockingQueue.html">ArrayBlockingQueue</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/PriorityBlockingQueue.html">PriorityBlockingQueue</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/DelayQueue.html">DelayQueue</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/SynchronousQueue.html">SynchronousQueue</a></tt></li>
|
||||
<li><a href=
|
||||
"../concurrent/LinkedBlockingDeque.html"><tt>LinkedBlockingDeque</tt></a></li>
|
||||
<li><a href=
|
||||
"../concurrent/LinkedTransferQueue.html"><tt>LinkedTransferQueue</tt></a></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/CopyOnWriteArrayList.html">CopyOnWriteArrayList</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/CopyOnWriteArraySet.html">CopyOnWriteArraySet</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/ConcurrentSkipListSet.html">ConcurrentSkipListSet</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/ConcurrentHashMap.html">ConcurrentHashMap</a></tt></li>
|
||||
<li><tt><a href=
|
||||
"../concurrent/ConcurrentSkipListMap.html">ConcurrentSkipListMap</a></tt></li>
|
||||
</ul>
|
||||
<hr />
|
||||
<h2>Design Goals</h2>
|
||||
<p>The main design goal was to produce an API that was small in
|
||||
size and, more importantly, in "conceptual weight." It
|
||||
was critical that the new functionality not seem too different to
|
||||
current Java programmers; it had to augment current facilities,
|
||||
rather than replace them. At the same time, the new API had to be
|
||||
powerful enough to provide all the advantages described
|
||||
previously.</p>
|
||||
<p>To keep the number of core interfaces small, the interfaces do
|
||||
not attempt to capture such subtle distinctions as mutability,
|
||||
modifiability, and resizability. Instead, certain calls in the core
|
||||
interfaces are <i>optional</i>, enabling implementations to throw
|
||||
an <tt>UnsupportedOperationException</tt> to indicate that they do
|
||||
not support a specified optional operation. Collection implementers
|
||||
must clearly document which optional operations are supported by an
|
||||
implementation.</p>
|
||||
<p>To keep the number of methods in each core interface small, an
|
||||
interface contains a method only if either:</p>
|
||||
<ul>
|
||||
<li>It is a truly <i>fundamental operation</i>: a basic operations
|
||||
in terms of which others could be reasonably defined,</li>
|
||||
<li>There is a compelling performance reason why an important
|
||||
implementation would want to override it.</li>
|
||||
</ul>
|
||||
<p>It was critical that all reasonable representations of
|
||||
collections interoperate well. This included arrays, which cannot
|
||||
be made to implement the <tt>Collection</tt> interface directly
|
||||
without changing the language. Thus, the framework includes methods
|
||||
to enable collections to be moved into arrays, arrays to be viewed
|
||||
as collections, and maps to be viewed as collections.</p>
|
||||
<hr />
|
||||
<p style="font-size:smaller">
|
||||
Copyright © 1998, 2017, Oracle and/or its affiliates. 500 Oracle Parkway<br />
|
||||
Redwood Shores, CA 94065 USA. All rights reserved.</p>
|
||||
<!-- Body text ends here -->
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,564 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<!--
|
||||
Copyright (c) 1998, 2017, 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. Oracle designates this
|
||||
particular file as subject to the "Classpath" exception as provided
|
||||
by Oracle in the LICENSE file that accompanied this code.
|
||||
|
||||
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.
|
||||
-->
|
||||
|
||||
<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml" xml:lang=
|
||||
"en-US">
|
||||
<head>
|
||||
<title>Outline of the Collections Framework</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Outline of the Collections Framework</h1>
|
||||
<!-- Body text begins here -->
|
||||
The collections framework consists of:
|
||||
<ul>
|
||||
<li><strong>Collection interfaces</strong> - The primary means by
|
||||
which collections are manipulated.
|
||||
<ul>
|
||||
<li><a href=
|
||||
"../Collection.html"><strong>Collection</strong></a>
|
||||
- A group of objects. No assumptions are made about the order of
|
||||
the collection (if any) or whether it can contain duplicate
|
||||
elements.</li>
|
||||
<li><a href=
|
||||
"../Set.html"><strong>Set</strong></a> - The
|
||||
familiar set abstraction. No duplicate elements permitted. May or
|
||||
may not be ordered. Extends the <tt>Collection</tt> interface.</li>
|
||||
<li><a href=
|
||||
"../List.html"><strong>List</strong></a> -
|
||||
Ordered collection, also known as a <i>sequence</i>. Duplicates are
|
||||
generally permitted. Allows positional access. Extends the
|
||||
<tt>Collection</tt> interface.</li>
|
||||
<li><a href=
|
||||
"../Queue.html"><strong>Queue</strong></a> - A
|
||||
collection designed for holding elements before processing. Besides
|
||||
basic <tt>Collection</tt> operations, queues provide additional
|
||||
insertion, extraction, and inspection operations.</li>
|
||||
<li><a href=
|
||||
"../Deque.html"><strong>Deque</strong></a> - A
|
||||
<em>double ended queue</em>, supporting element insertion and
|
||||
removal at both ends. Extends the <tt>Queue</tt> interface.</li>
|
||||
<li><a href=
|
||||
"../Map.html"><strong>Map</strong></a> - A
|
||||
mapping from keys to values. Each key can map to one value.</li>
|
||||
<li><a href=
|
||||
"../SortedSet.html"><strong>SortedSet</strong></a>
|
||||
- A set whose elements are automatically sorted, either in their
|
||||
<i>natural ordering</i> (see the <a href=
|
||||
"../../lang/Comparable.html"><tt>Comparable</tt></a>
|
||||
interface) or by a <a href=
|
||||
"../Comparator.html"><tt>Comparator</tt></a>
|
||||
object provided when a <tt>SortedSet</tt> instance is created.
|
||||
Extends the <tt>Set</tt> interface.</li>
|
||||
<li><a href=
|
||||
"../SortedMap.html"><strong>SortedMap</strong></a>
|
||||
- A map whose mappings are automatically sorted by key, either
|
||||
using the <i>natural ordering</i> of the keys or by a comparator
|
||||
provided when a <tt>SortedMap</tt> instance is created. Extends the
|
||||
<tt>Map</tt> interface.</li>
|
||||
<li><a href=
|
||||
"../NavigableSet.html"><strong>NavigableSet</strong></a>
|
||||
- A <tt>SortedSet</tt> extended with navigation methods reporting
|
||||
closest matches for given search targets. A <tt>NavigableSet</tt>
|
||||
may be accessed and traversed in either ascending or descending
|
||||
order.</li>
|
||||
<li><a href=
|
||||
"../NavigableMap.html"><strong>NavigableMap</strong></a>
|
||||
- A <tt>SortedMap</tt> extended with navigation methods returning
|
||||
the closest matches for given search targets. A
|
||||
<tt>NavigableMap</tt> can be accessed and traversed in either
|
||||
ascending or descending key order.</li>
|
||||
<li><a href=
|
||||
"../concurrent/BlockingQueue.html"><strong>BlockingQueue</strong></a>
|
||||
- A <tt>Queue</tt> with operations that wait for the queue to
|
||||
become nonempty when retrieving an element and that wait for space
|
||||
to become available in the queue when storing an element. (This
|
||||
interface is part of the <tt><a href=
|
||||
"../concurrent/package-summary.html">java.util.concurrent</a></tt>
|
||||
package.)</li>
|
||||
<li><a href=
|
||||
"../concurrent/TransferQueue.html"><strong>TransferQueue</strong></a>
|
||||
- A <tt>BlockingQueue</tt> in which producers can wait for
|
||||
consumers to receive elements. (This interface is part of the
|
||||
<tt><a href=
|
||||
"../concurrent/package-summary.html">java.util.concurrent</a></tt>
|
||||
package.)</li>
|
||||
<li><a href=
|
||||
"../concurrent/BlockingDeque.html"><strong>BlockingDeque</strong></a>
|
||||
- A <tt>Deque</tt> with operations that wait for the deque to
|
||||
become nonempty when retrieving an element and wait for space to
|
||||
become available in the deque when storing an element. Extends both
|
||||
the <tt>Deque</tt> and <tt>BlockingQueue</tt> interfaces. (This
|
||||
interface is part of the <tt><a href=
|
||||
"../concurrent/package-summary.html">java.util.concurrent</a></tt>
|
||||
package.)</li>
|
||||
<li><a href=
|
||||
"../concurrent/ConcurrentMap.html"><strong>ConcurrentMap</strong></a>
|
||||
- A <tt>Map</tt> with atomic <tt>putIfAbsent</tt>, <tt>remove</tt>,
|
||||
and <tt>replace</tt> methods. (This interface is part of the
|
||||
<tt>java.util.concurrent</tt> package.)</li>
|
||||
<li><a href=
|
||||
"../concurrent/ConcurrentNavigableMap.html"><strong>
|
||||
ConcurrentNavigableMap</strong></a> - A <tt>ConcurrentMap</tt> that
|
||||
is also a <tt>NavigableMap</tt>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>General-purpose implementations</strong> - The primary
|
||||
implementations of the collection interfaces.
|
||||
<ul>
|
||||
<li><strong><a href=
|
||||
"../HashSet.html">HashSet</a></strong> - Hash
|
||||
table implementation of the <tt>Set</tt> interface. The best
|
||||
all-around implementation of the <tt>Set</tt> interface.</li>
|
||||
<li><a href=
|
||||
"../TreeSet.html"><strong>TreeSet</strong></a>
|
||||
- Red-black tree implementation of the <tt>NavigableSet</tt>
|
||||
interface.</li>
|
||||
<li><strong><a href=
|
||||
"../LinkedHashSet.html">LinkedHashSet</a></strong>
|
||||
- Hash table and linked list implementation of the <tt>Set</tt>
|
||||
interface. An insertion-ordered <tt>Set</tt> implementation that
|
||||
runs nearly as fast as <tt>HashSet</tt>.</li>
|
||||
<li><strong><a href=
|
||||
"../ArrayList.html">ArrayList</a></strong> -
|
||||
Resizable array implementation of the <tt>List</tt> interface (an
|
||||
unsynchronized <tt>Vector</tt>). The best all-around implementation
|
||||
of the <tt>List</tt> interface.</li>
|
||||
<li><strong><a href=
|
||||
"../ArrayDeque.html">ArrayDeque</a></strong> -
|
||||
Efficient, resizable array implementation of the <tt>Deque</tt>
|
||||
interface.</li>
|
||||
<li><a href=
|
||||
"../LinkedList.html"><strong>LinkedList</strong></a>
|
||||
- Doubly-linked list implementation of the <tt>List</tt> interface.
|
||||
Provides better performance than the <tt>ArrayList</tt>
|
||||
implementation if elements are frequently inserted or deleted
|
||||
within the list. Also implements the <tt>Deque</tt> interface. When
|
||||
accessed through the <tt>Queue</tt> interface, <tt>LinkedList</tt>
|
||||
acts as a FIFO queue.</li>
|
||||
<li><strong><a href=
|
||||
"../PriorityQueue.html">PriorityQueue</a></strong>
|
||||
- Heap implementation of an unbounded priority queue.</li>
|
||||
<li><strong><a href=
|
||||
"../HashMap.html">HashMap</a></strong> - Hash
|
||||
table implementation of the <tt>Map</tt> interface (an
|
||||
unsynchronized <tt>Hashtable</tt> that supports <tt>null</tt> keys
|
||||
and values). The best all-around implementation of the <tt>Map</tt>
|
||||
interface.</li>
|
||||
<li><a href=
|
||||
"../TreeMap.html"><strong>TreeMap</strong></a>
|
||||
Red-black tree implementation of the <tt>NavigableMap</tt>
|
||||
interface.</li>
|
||||
<li><strong><a href=
|
||||
"../LinkedHashMap.html">LinkedHashMap</a></strong>
|
||||
- Hash table and linked list implementation of the <tt>Map</tt>
|
||||
interface. An insertion-ordered <tt>Map</tt> implementation that
|
||||
runs nearly as fast as <tt>HashMap</tt>. Also useful for building
|
||||
caches (see <a href=
|
||||
"../LinkedHashMap.html#removeEldestEntry-java.util.Map.Entry-">
|
||||
removeEldestEntry(Map.Entry)</a> ).</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Wrapper implementations</strong> -
|
||||
Functionality-enhancing implementations for use with other
|
||||
implementations. Accessed solely through static factory methods.
|
||||
<ul>
|
||||
<li><a href=
|
||||
"../Collections.html#unmodifiableCollection-java.util.Collection-">
|
||||
<strong>Collections.unmodifiable<i>Interface</i></strong></a> -
|
||||
Returns an unmodifiable view of a specified collection that throws
|
||||
an <tt>UnsupportedOperationException</tt> if the user attempts to
|
||||
modify it.</li>
|
||||
<li><a name="synchWrappers" href=
|
||||
"../Collections.html#synchronizedCollection-java.util.Collection-"
|
||||
id=
|
||||
"synchWrappers"><strong>Collections.synchronized<i>Interface</i></strong></a>
|
||||
- Returns a synchronized collection that is backed by the specified
|
||||
(typically unsynchronized) collection. As long as all accesses to
|
||||
the backing collection are through the returned collection, thread
|
||||
safety is guaranteed.</li>
|
||||
<li><a href=
|
||||
"../Collections.html#checkedCollection-java.util.Collection-java.lang.Class-">
|
||||
<strong>Collections.checked<i>Interface</i></strong></a> - Returns
|
||||
a dynamically type-safe view of the specified collection, which
|
||||
throws a <tt>ClassCastException</tt> if a client attempts to add an
|
||||
element of the wrong type. The generics mechanism in the language
|
||||
provides compile-time (static) type checking, but it is possible to
|
||||
bypass this mechanism. Dynamically type-safe views eliminate this
|
||||
possibility.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Adapter implementations</strong> - Implementations that
|
||||
adapt one collections interface to another:
|
||||
<ul>
|
||||
<li><strong><a href=
|
||||
"../Collections.html#newSetFromMap-java.util.Map-">
|
||||
newSetFromMap(Map)</a></strong> - Creates a general-purpose
|
||||
<tt>Set</tt> implementation from a general-purpose <tt>Map</tt>
|
||||
implementation.</li>
|
||||
<li><strong><a href=
|
||||
"../Collections.html#asLifoQueue-java.util.Deque-">
|
||||
asLifoQueue(Deque)</a></strong> - Returns a view of a
|
||||
<tt>Deque</tt> as a Last In First Out (LIFO) <tt>Queue</tt>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Convenience implementations</strong> - High-performance
|
||||
"mini-implementations" of the collection interfaces.
|
||||
<ul>
|
||||
<li><a href=
|
||||
"../Arrays.html#asList-T...-"><strong>Arrays.asList</strong></a>
|
||||
- Enables an array to be viewed as a list.</li>
|
||||
<li><strong><a href=
|
||||
"../Collections.html#emptySet--">emptySet</a>,
|
||||
<a href=
|
||||
"../Collections.html#emptyList--">emptyList</a>
|
||||
and <a href=
|
||||
"../Collections.html#emptyMap--">emptyMap</a></strong>
|
||||
- Return an immutable empty set, list, or map.</li>
|
||||
<li><strong><a href=
|
||||
"../Collections.html#singleton-java.lang.Object-">
|
||||
singleton</a>, <a href=
|
||||
"../Collections.html#singletonList-java.lang.Object-">
|
||||
singletonList</a>, and <a href=
|
||||
"../Collections.html#singletonMap-K-V-">singletonMap</a></strong>
|
||||
- Return an immutable singleton set, list, or map, containing only
|
||||
the specified object (or key-value mapping).</li>
|
||||
<li><a href=
|
||||
"../Collections.html#nCopies-int-T-"><strong>
|
||||
nCopies</strong></a> - Returns an immutable list consisting of n
|
||||
copies of a specified object.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Legacy implementations</strong> - Older collection
|
||||
classes were retrofitted to implement the collection interfaces.
|
||||
<ul>
|
||||
<li><a href=
|
||||
"../Vector.html"><strong>Vector</strong></a> -
|
||||
Synchronized resizable array implementation of the <tt>List</tt>
|
||||
interface with additional legacy methods.</li>
|
||||
<li><a href=
|
||||
"../Hashtable.html"><strong>Hashtable</strong></a>
|
||||
- Synchronized hash table implementation of the <tt>Map</tt>
|
||||
interface that does not allow <tt>null</tt> keys or values, plus
|
||||
additional legacy methods.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Special-purpose implementations</strong>
|
||||
<ul>
|
||||
<li><strong><a href=
|
||||
"../WeakHashMap.html">WeakHashMap</a></strong>
|
||||
- An implementation of the <tt>Map</tt> interface that stores only
|
||||
<a href="../../lang/ref/WeakReference.html"><i>weak
|
||||
references</i></a> to its keys. Storing only weak references
|
||||
enables key-value pairs to be garbage collected when the key is no
|
||||
longer referenced outside of the <tt>WeakHashMap</tt>. This class
|
||||
is the easiest way to use the power of weak references. It is
|
||||
useful for implementing registry-like data structures, where the
|
||||
utility of an entry vanishes when its key is no longer reachable by
|
||||
any thread.</li>
|
||||
<li><strong><a href=
|
||||
"../IdentityHashMap.html">IdentityHashMap</a></strong>
|
||||
- Identity-based <tt>Map</tt> implementation based on a hash table.
|
||||
This class is useful for topology-preserving object graph
|
||||
transformations (such as serialization or deep copying). To perform
|
||||
these transformations, you must maintain an identity-based "node
|
||||
table" that keeps track of which objects have already been seen.
|
||||
Identity-based maps are also used to maintain
|
||||
object-to-meta-information mappings in dynamic debuggers and
|
||||
similar systems. Finally, identity-based maps are useful in
|
||||
preventing "spoof attacks" resulting from intentionally perverse
|
||||
equals methods. (<tt>IdentityHashMap</tt> never invokes the equals
|
||||
method on its keys.) An added benefit of this implementation is
|
||||
that it is fast.</li>
|
||||
<li><strong><a href=
|
||||
"../concurrent/CopyOnWriteArrayList.html">CopyOnWriteArrayList</a></strong>
|
||||
- A <tt>List</tt> implementation backed by an copy-on-write array.
|
||||
All mutative operations (such as <tt>add</tt>, <tt>set</tt>, and
|
||||
<tt>remove</tt>) are implemented by making a new copy of the array.
|
||||
No synchronization is necessary, even during iteration, and
|
||||
iterators are guaranteed never to throw
|
||||
<tt>ConcurrentModificationException</tt>. This implementation is
|
||||
well-suited to maintaining event-handler lists (where change is
|
||||
infrequent, and traversal is frequent and potentially
|
||||
time-consuming).</li>
|
||||
<li><strong><a href=
|
||||
"../concurrent/CopyOnWriteArraySet.html">CopyOnWriteArraySet</a></strong>
|
||||
- A <tt>Set</tt> implementation backed by a copy-on-write array.
|
||||
This implementation is similar to <tt>CopyOnWriteArrayList</tt>.
|
||||
Unlike most <tt>Set</tt> implementations, the <tt>add</tt>,
|
||||
<tt>remove</tt>, and <tt>contains</tt> methods require time
|
||||
proportional to the size of the set. This implementation is well
|
||||
suited to maintaining event-handler lists that must prevent
|
||||
duplicates.</li>
|
||||
<li><strong><a href=
|
||||
"../EnumSet.html">EnumSet</a></strong> - A
|
||||
high-performance <tt>Set</tt> implementation backed by a bit
|
||||
vector. All elements of each <tt>EnumSet</tt> instance must be
|
||||
elements of a single enum type.</li>
|
||||
<li><strong><a href=
|
||||
"../EnumMap.html">EnumMap</a></strong> - A
|
||||
high-performance <tt>Map</tt> implementation backed by an array.
|
||||
All keys in each <tt>EnumMap</tt> instance must be elements of a
|
||||
single enum type.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Concurrent implementations</strong> - These
|
||||
implementations are part of <tt>java.util.concurrent</tt>.
|
||||
<ul>
|
||||
<li><strong><a href=
|
||||
"../concurrent/ConcurrentLinkedQueue.html">ConcurrentLinkedQueue</a></strong>
|
||||
- An unbounded first in, first out (FIFO) queue based on linked
|
||||
nodes.</li>
|
||||
<li><a href=
|
||||
"../concurrent/LinkedBlockingQueue.html"><strong>
|
||||
LinkedBlockingQueue</strong></a> - An optionally bounded FIFO
|
||||
blocking queue backed by linked nodes.</li>
|
||||
<li><a href=
|
||||
"../concurrent/ArrayBlockingQueue.html"><strong>
|
||||
ArrayBlockingQueue</strong></a> - A bounded FIFO blocking queue
|
||||
backed by an array.</li>
|
||||
<li><a href=
|
||||
"../concurrent/PriorityBlockingQueue.html"><strong>
|
||||
PriorityBlockingQueue</strong></a> - An unbounded blocking priority
|
||||
queue backed by a priority heap.</li>
|
||||
<li><a href=
|
||||
"../concurrent/DelayQueue.html"><strong>DelayQueue</strong></a>
|
||||
- A time-based scheduling queue backed by a priority heap.</li>
|
||||
<li><a href=
|
||||
"../concurrent/SynchronousQueue.html"><strong>SynchronousQueue</strong></a>
|
||||
- A simple rendezvous mechanism that uses the
|
||||
<tt>BlockingQueue</tt> interface.</li>
|
||||
<li><a href=
|
||||
"../concurrent/LinkedBlockingDeque.html"><strong>
|
||||
LinkedBlockingDeque</strong></a> - An optionally bounded FIFO
|
||||
blocking deque backed by linked nodes.</li>
|
||||
<li><a href=
|
||||
"../concurrent/LinkedTransferQueue.html"><strong>
|
||||
LinkedTransferQueue</strong></a> - An unbounded
|
||||
<tt>TransferQueue</tt> backed by linked nodes.</li>
|
||||
<li><a href=
|
||||
"../concurrent/ConcurrentHashMap.html"><strong>ConcurrentHashMap</strong></a>
|
||||
- A highly concurrent, high-performance <tt>ConcurrentMap</tt>
|
||||
implementation based on a hash table. This implementation never
|
||||
blocks when performing retrievals and enables the client to select
|
||||
the concurrency level for updates. It is intended as a drop-in
|
||||
replacement for <tt><a href=
|
||||
"../Hashtable.html">Hashtable</a></tt>. In
|
||||
addition to implementing <tt>ConcurrentMap</tt>, it supports all of
|
||||
the legacy methods of <tt>Hashtable</tt>.</li>
|
||||
<li><a href=
|
||||
"../concurrent/ConcurrentSkipListSet.html"><strong>
|
||||
ConcurrentSkipListSet</strong></a> - Skips list implementation of
|
||||
the <tt>NavigableSet</tt> interface.</li>
|
||||
<li><a href=
|
||||
"../concurrent/ConcurrentSkipListMap.html"><strong>
|
||||
ConcurrentSkipListMap</strong></a> - Skips list implementation of
|
||||
the <tt>ConcurrentNavigableMap</tt> interface.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Abstract implementations</strong> - Skeletal
|
||||
implementations of the collection interfaces to facilitate custom
|
||||
implementations.
|
||||
<ul>
|
||||
<li><a href=
|
||||
"../AbstractCollection.html"><strong>AbstractCollection</strong></a>
|
||||
- Skeletal <tt>Collection</tt> implementation that is neither a set
|
||||
nor a list (such as a "bag" or multiset).</li>
|
||||
<li><a href=
|
||||
"../AbstractSet.html"><strong>AbstractSet</strong></a>
|
||||
- Skeletal <tt>Set</tt> implementation.</li>
|
||||
<li><a href=
|
||||
"../AbstractList.html"><strong>AbstractList</strong></a>
|
||||
- Skeletal <tt>List</tt> implementation backed by a random access
|
||||
data store (such as an array).</li>
|
||||
<li><a href=
|
||||
"../AbstractSequentialList.html"><strong>AbstractSequentialList</strong></a>
|
||||
- Skeletal <tt>List</tt> implementation backed by a sequential
|
||||
access data store (such as a linked list).</li>
|
||||
<li><a href=
|
||||
"../AbstractQueue.html"><strong>AbstractQueue</strong></a>
|
||||
- Skeletal <tt>Queue</tt> implementation.</li>
|
||||
<li><a href=
|
||||
"../AbstractMap.html"><strong>AbstractMap</strong></a>
|
||||
- Skeletal <tt>Map</tt> implementation.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Algorithms</strong> - The <a href=
|
||||
"../Collections.html"><strong>Collections</strong></a>
|
||||
class contains these useful static methods.
|
||||
<ul>
|
||||
<li><strong><a href=
|
||||
"../Collections.html#sort-java.util.List-">sort(List)</a></strong>
|
||||
- Sorts a list using a merge sort algorithm, which provides average
|
||||
case performance comparable to a high quality quicksort, guaranteed
|
||||
O(n*log n) performance (unlike quicksort), and <em>stability</em>
|
||||
(unlike quicksort). A stable sort is one that does not reorder
|
||||
equal elements.</li>
|
||||
<li><strong><a href=
|
||||
"../Collections.html#binarySearch-java.util.List-T-">
|
||||
binarySearch(List, Object)</a></strong> - Searches for an element
|
||||
in an ordered list using the binary search algorithm.</li>
|
||||
<li><strong><a href=
|
||||
"../Collections.html#reverse-java.util.List-">reverse(List)</a></strong>
|
||||
- Reverses the order of the elements in a list.</li>
|
||||
<li><strong><a href=
|
||||
"../Collections.html#shuffle-java.util.List-">shuffle(List)</a></strong>
|
||||
- Randomly changes the order of the elements in a list.</li>
|
||||
<li><strong><a href=
|
||||
"../Collections.html#fill-java.util.List-T-">
|
||||
fill(List, Object)</a></strong> - Overwrites every element in a
|
||||
list with the specified value.</li>
|
||||
<li><strong><a href=
|
||||
"../Collections.html#copy-java.util.List-java.util.List-">
|
||||
copy(List dest, List src)</a></strong> - Copies the source list
|
||||
into the destination list.</li>
|
||||
<li><strong><a href=
|
||||
"../Collections.html#min-java.util.Collection-">
|
||||
min(Collection)</a></strong> - Returns the minimum element in a
|
||||
collection.</li>
|
||||
<li><strong><a href=
|
||||
"../Collections.html#max-java.util.Collection-">
|
||||
max(Collection)</a></strong> - Returns the maximum element in a
|
||||
collection.</li>
|
||||
<li><strong><a href=
|
||||
"../Collections.html#rotate-java.util.List-int-">
|
||||
rotate(List list, int distance)</a></strong> - Rotates all of the
|
||||
elements in the list by the specified distance.</li>
|
||||
<li><strong><a href=
|
||||
"../Collections.html#replaceAll-java.util.List-T-T-">
|
||||
replaceAll(List list, Object oldVal, Object newVal)</a></strong> -
|
||||
Replaces all occurrences of one specified value with another.</li>
|
||||
<li><strong><a href=
|
||||
"../Collections.html#indexOfSubList-java.util.List-java.util.List-">
|
||||
indexOfSubList(List source, List target)</a></strong> - Returns the
|
||||
index of the first sublist of source that is equal to target.</li>
|
||||
<li><strong><a href=
|
||||
"../Collections.html#lastIndexOfSubList-java.util.List-java.util.List-">
|
||||
lastIndexOfSubList(List source, List target)</a></strong> - Returns
|
||||
the index of the last sublist of source that is equal to
|
||||
target.</li>
|
||||
<li><strong><a href=
|
||||
"../Collections.html#swap-java.util.List-int-int-">
|
||||
swap(List, int, int)</a></strong> - Swaps the elements at the
|
||||
specified positions in the specified list.</li>
|
||||
<li><strong><a href=
|
||||
"../Collections.html#frequency-java.util.Collection-java.lang.Object-">
|
||||
frequency(Collection, Object)</a></strong> - Counts the number of
|
||||
times the specified element occurs in the specified
|
||||
collection.</li>
|
||||
<li><strong><a href=
|
||||
"../Collections.html#disjoint-java.util.Collection-java.util.Collection-">
|
||||
disjoint(Collection, Collection)</a></strong> - Determines whether
|
||||
two collections are disjoint, in other words, whether they contain
|
||||
no elements in common.</li>
|
||||
<li><strong><a href=
|
||||
"../Collections.html#addAll-java.util.Collection-T...-">
|
||||
addAll(Collection<? super T>, T...)</a></strong> - Adds all
|
||||
of the elements in the specified array to the specified
|
||||
collection.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Infrastructure</strong>
|
||||
<ul>
|
||||
<li><strong>Iterators</strong> - Similar to the familiar <a href=
|
||||
"../Enumeration.html">Enumeration</a>
|
||||
interface, but more powerful, and with improved method names.
|
||||
<ul>
|
||||
<li><a href=
|
||||
"../Iterator.html"><strong>Iterator</strong></a>
|
||||
- In addition to the functionality of the <tt>Enumeration</tt>
|
||||
interface, enables the user to remove elements from the backing
|
||||
collection with well-defined, useful semantics.</li>
|
||||
<li><a href=
|
||||
"../ListIterator.html"><strong>ListIterator</strong></a>
|
||||
- Iterator for use with lists. In addition to the functionality of
|
||||
the <tt>Iterator</tt> interface, supports bidirectional iteration,
|
||||
element replacement, element insertion, and index retrieval.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Ordering</strong>
|
||||
<ul>
|
||||
<li><a href=
|
||||
"../../lang/Comparable.html"><strong>Comparable</strong></a>
|
||||
- Imparts a <i>natural ordering</i> to classes that implement it.
|
||||
The natural ordering can be used to sort a list or maintain order
|
||||
in a sorted set or map. Many classes were retrofitted to implement
|
||||
this interface.</li>
|
||||
<li><a href=
|
||||
"../Comparator.html"><strong>Comparator</strong></a>
|
||||
- Represents an order relation, which can be used to sort a list or
|
||||
maintain order in a sorted set or map. Can override a type's
|
||||
natural ordering or order objects of a type that does not implement
|
||||
the <tt>Comparable</tt> interface.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Runtime exceptions</strong>
|
||||
<ul>
|
||||
<li><a href=
|
||||
"../../lang/UnsupportedOperationException.html"><strong>
|
||||
UnsupportedOperationException</strong></a> - Thrown by collections
|
||||
if an unsupported optional operation is called.</li>
|
||||
<li><a href=
|
||||
"../ConcurrentModificationException.html"><strong>
|
||||
ConcurrentModificationException</strong></a> - Thrown by iterators
|
||||
and list iterators if the backing collection is changed
|
||||
unexpectedly while the iteration is in progress. Also thrown by
|
||||
<i>sublist</i> views of lists if the backing list is changed
|
||||
unexpectedly.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Performance</strong>
|
||||
<ul>
|
||||
<li><strong><a href=
|
||||
"../RandomAccess.html">RandomAccess</a></strong>
|
||||
- Marker interface that lets <tt>List</tt> implementations indicate
|
||||
that they support fast (generally constant time) random access.
|
||||
This lets generic algorithms change their behavior to provide good
|
||||
performance when applied to either random or sequential access
|
||||
lists.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Array Utilities</strong>
|
||||
<ul>
|
||||
<li><a href=
|
||||
"../Arrays.html"><strong>Arrays</strong></a> -
|
||||
Contains static methods to sort, search, compare, hash, copy,
|
||||
resize, convert to <tt>String</tt>, and fill arrays of primitives
|
||||
and objects.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<hr />
|
||||
<p style="font-size:smaller">
|
||||
Copyright © 1998, 2017, Oracle and/or its affiliates. 500 Oracle Parkway<br />
|
||||
Redwood Shores, CA 94065 USA. All rights reserved.</p>
|
||||
<!-- Body text ends here -->
|
||||
</body>
|
||||
</html>
|
@ -44,7 +44,7 @@ import java.util.Comparator;
|
||||
* the ASCII characters in the set [0-9a-zA-Z_-], and cannot exceed 70
|
||||
* characters in length. Attribute values can contain any characters and
|
||||
* will be UTF8-encoded when written to the output stream. See the
|
||||
* <a href="../../../../technotes/guides/jar/jar.html">JAR File Specification</a>
|
||||
* <a href="{@docRoot}/../specs/jar/jar.html">JAR File Specification</a>
|
||||
* for more information about valid attribute names and values.
|
||||
*
|
||||
* <p>This map and its views have a predictable iteration order, namely the
|
||||
@ -443,7 +443,7 @@ public class Attributes implements Map<Object,Object>, Cloneable {
|
||||
* to the ASCII characters in the set [0-9a-zA-Z_-], and cannot exceed
|
||||
* 70 characters in length. Attribute values can contain any characters
|
||||
* and will be UTF8-encoded when written to the output stream. See the
|
||||
* <a href="../../../../technotes/guides/jar/jar.html">JAR File Specification</a>
|
||||
* <a href="{@docRoot}/../specs/jar/jar.html">JAR File Specification</a>
|
||||
* for more information about valid attribute names and values.
|
||||
*/
|
||||
public static class Name {
|
||||
@ -529,7 +529,7 @@ public class Attributes implements Map<Object,Object>, Cloneable {
|
||||
* {@code Name} object for {@code Manifest-Version}
|
||||
* manifest attribute. This attribute indicates the version number
|
||||
* of the manifest standard to which a JAR file's manifest conforms.
|
||||
* @see <a href="../../../../technotes/guides/jar/jar.html#JAR_Manifest">
|
||||
* @see <a href="{@docRoot}/../specs/jar/jar.html#JAR_Manifest">
|
||||
* Manifest and Signature Specification</a>
|
||||
*/
|
||||
public static final Name MANIFEST_VERSION = new Name("Manifest-Version");
|
||||
@ -537,7 +537,7 @@ public class Attributes implements Map<Object,Object>, Cloneable {
|
||||
/**
|
||||
* {@code Name} object for {@code Signature-Version}
|
||||
* manifest attribute used when signing JAR files.
|
||||
* @see <a href="../../../../technotes/guides/jar/jar.html#JAR_Manifest">
|
||||
* @see <a href="{@docRoot}/../specs/jar/jar.html#JAR_Manifest">
|
||||
* Manifest and Signature Specification</a>
|
||||
*/
|
||||
public static final Name SIGNATURE_VERSION = new Name("Signature-Version");
|
||||
@ -551,7 +551,7 @@ public class Attributes implements Map<Object,Object>, Cloneable {
|
||||
/**
|
||||
* {@code Name} object for {@code Class-Path}
|
||||
* manifest attribute.
|
||||
* @see <a href="../../../../technotes/guides/jar/jar.html#classpath">
|
||||
* @see <a href="{@docRoot}/../specs/jar/jar.html#classpath">
|
||||
* JAR file specification</a>
|
||||
*/
|
||||
public static final Name CLASS_PATH = new Name("Class-Path");
|
||||
@ -568,7 +568,7 @@ public class Attributes implements Map<Object,Object>, Cloneable {
|
||||
/**
|
||||
* {@code Name} object for {@code Sealed} manifest attribute
|
||||
* used for sealing.
|
||||
* @see <a href="../../../../technotes/guides/jar/jar.html#sealing">
|
||||
* @see <a href="{@docRoot}/../specs/jar/jar.html#sealing">
|
||||
* Package Sealing</a>
|
||||
*/
|
||||
public static final Name SEALED = new Name("Sealed");
|
||||
|
@ -39,7 +39,7 @@ import java.util.Iterator;
|
||||
* associated Attributes. There are main Manifest Attributes as well as
|
||||
* per-entry Attributes. For information on the Manifest format, please
|
||||
* see the
|
||||
* <a href="../../../../technotes/guides/jar/jar.html">
|
||||
* <a href="{@docRoot}/../specs/jar/jar.html">
|
||||
* Manifest format specification</a>.
|
||||
*
|
||||
* @author David Connelly
|
||||
|
@ -34,8 +34,7 @@ import sun.security.action.GetPropertyAction;
|
||||
|
||||
/**
|
||||
* Transforms a JAR file to or from a packed stream in Pack200 format.
|
||||
* Please refer to Network Transfer Format JSR 200 Specification at
|
||||
* <a href=http://jcp.org/aboutJava/communityprocess/review/jsr200/index.html>http://jcp.org/aboutJava/communityprocess/review/jsr200/index.html</a>
|
||||
* Please refer to <a href="{@docRoot}/../specs/pack-spec.html">Network Transfer Format JSR 200 Specification</a>
|
||||
* <p>
|
||||
* Typically the packer engine is used by application developers
|
||||
* to deploy or host JAR files on a website.
|
||||
|
@ -40,7 +40,7 @@
|
||||
* <a href="../zip/package-summary.html#package_description">java.util.zip
|
||||
* package description.</a> <p>
|
||||
* In JAR files, all file names must be encoded in the UTF-8 encoding.
|
||||
* <li><a href="../../../../technotes/guides/jar/jar.html">
|
||||
* <li><a href="{@docRoot}/../specs/jar/jar.html">
|
||||
* Manifest and Signature Specification</a> - The manifest format specification.
|
||||
* </ul>
|
||||
*
|
||||
|
@ -24,27 +24,24 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the collections framework, legacy collection classes,
|
||||
* event model, date and time facilities, internationalization, and
|
||||
* miscellaneous utility classes (a string tokenizer, a random-number
|
||||
* generator, and a bit array).
|
||||
* Contains the collections framework, some internationalization support classes,
|
||||
* a service loader, properties, random number generation, string parsing
|
||||
* and scanning classes, base64 encoding and decoding, a bit array, and
|
||||
* several miscellaneous utility classes. This package also contains
|
||||
* legacy collection classes and legacy date and time classes.
|
||||
*
|
||||
* <h2><a id="CollectionsFramework"></a>{@index "Java Collections Framework"}</h2>
|
||||
* <p>For an overview, API outline, and design rationale, please see:
|
||||
* <ul>
|
||||
* <li><a href="../../../technotes/guides/collections/overview.html"><b>Collections Framework Overview</b></a>
|
||||
* <li><a href="../../../technotes/guides/collections/reference.html"><b>
|
||||
* Collections Framework Annotated Outline</b></a>
|
||||
* <li><a href="doc-files/coll-index.html">
|
||||
* <b>Collections Framework Documentation</b></a>
|
||||
* </ul>
|
||||
*
|
||||
* <h2>Related Documentation</h2>
|
||||
* For overviews, tutorials, examples, guides, and tool documentation,
|
||||
* please see:
|
||||
* <p>For a tutorial and programming guide with examples of use
|
||||
* of the collections framework, please see:
|
||||
* <ul>
|
||||
* <li><a href="http://docs.oracle.com/javase/tutorial/collections/index.html">
|
||||
* <b>Collections Framework Tutorial</b></a>
|
||||
* <li><a
|
||||
* href="../../../technotes/guides/collections/designfaq.html"><b>Collections
|
||||
* Framework Design FAQ</b></a>
|
||||
* <li><a href="http://docs.oracle.com/javase/tutorial/collections/index.html">
|
||||
* <b>Collections Framework Tutorial</b></a>
|
||||
* </ul>
|
||||
*
|
||||
* @since 1.0
|
||||
|
@ -2616,11 +2616,9 @@ public class Cipher {
|
||||
* according to the installed JCE jurisdiction policy files. If
|
||||
* JCE unlimited strength jurisdiction policy files are installed,
|
||||
* Integer.MAX_VALUE will be returned.
|
||||
* For more information on default key size in JCE jurisdiction
|
||||
* policy files, please see Appendix E in the
|
||||
* <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppC">
|
||||
* Java Cryptography Architecture Reference Guide</a>.
|
||||
* For more information on the default key sizes and the JCE jurisdiction
|
||||
* policy files, please see the Cryptographic defaults and limitations in
|
||||
* the {@extLink security_guide_jdk_providers JDK Providers Documentation}.
|
||||
*
|
||||
* @param transformation the cipher transformation.
|
||||
* @return the maximum key length in bits or Integer.MAX_VALUE.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2017, 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
|
||||
@ -116,10 +116,9 @@ public class EncryptedPrivateKeyInfo {
|
||||
* e.g. EncryptedPrivateKeyInfo(AlgorithmParameters, byte[]),
|
||||
* should be used.
|
||||
*
|
||||
* @param algName encryption algorithm name. See Appendix A in the
|
||||
* <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
|
||||
* Java Cryptography Architecture Reference Guide</a>
|
||||
* @param algName encryption algorithm name. See the
|
||||
* <a href="{@docRoot}/../specs/security/standard-names.html">
|
||||
* Java Security Standard Algorithm Names</a> document
|
||||
* for information about standard Cipher algorithm names.
|
||||
* @param encryptedData encrypted data. The contents of
|
||||
* <code>encrypedData</code> are copied to protect against subsequent
|
||||
@ -199,10 +198,8 @@ public class EncryptedPrivateKeyInfo {
|
||||
* Returns the encryption algorithm.
|
||||
* <p>Note: Standard name is returned instead of the specified one
|
||||
* in the constructor when such mapping is available.
|
||||
* See Appendix A in the
|
||||
* <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
|
||||
* Java Cryptography Architecture Reference Guide</a>
|
||||
* See the <a href="{@docRoot}/../specs/security/standard-names.html">
|
||||
* Java Security Standard Algorithm Names</a> document
|
||||
* for information about standard Cipher algorithm names.
|
||||
*
|
||||
* @return the encryption algorithm name.
|
||||
|
@ -84,8 +84,7 @@ import sun.security.util.Debug;
|
||||
* (via a call to an {@code init} method), each provider must
|
||||
* supply (and document) a default initialization.
|
||||
* See the Keysize Restriction sections of the
|
||||
* <a href="{@docRoot}/../technotes/guides/security/SunProviders.html">
|
||||
* JDK Providers</a>
|
||||
* {@extLink security_guide_jdk_providers JDK Providers}
|
||||
* document for information on the KeyGenerator defaults used by
|
||||
* JDK providers.
|
||||
* However, note that defaults may vary across different providers.
|
||||
|
@ -39,8 +39,7 @@ import java.security.spec.*;
|
||||
* (via a call to an {@code init} method), each provider must
|
||||
* supply (and document) a default initialization.
|
||||
* See the Keysize Restriction sections of the
|
||||
* <a href="{@docRoot}/../technotes/guides/security/SunProviders.html">
|
||||
* JDK Providers</a>
|
||||
* {@extLink security_guide_jdk_providers JDK Providers}
|
||||
* document for information on the KeyGenerator defaults used by
|
||||
* JDK providers.
|
||||
* However, note that defaults may vary across different providers.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2017, 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
|
||||
@ -39,10 +39,8 @@
|
||||
* developer guide:
|
||||
*
|
||||
* <ul>
|
||||
* <li><a href=
|
||||
* "{@docRoot}/../technotes/guides/security/crypto/HowToImplAProvider.html">
|
||||
* <b>How to Implement a Provider for the Java™ Cryptography Architecture
|
||||
* </b></a></li>
|
||||
* <li> {@extLink security_guide_impl_provider
|
||||
* How to Implement a Provider in the Java Cryptography Architecture}</li>
|
||||
* </ul>
|
||||
*
|
||||
* <h2>Package Specification</h2>
|
||||
@ -57,10 +55,8 @@
|
||||
* For further documentation, please see:
|
||||
* <ul>
|
||||
* <li>
|
||||
* <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html">
|
||||
* <b>Java™ Cryptography Architecture API Specification and Reference
|
||||
* </b></a></li>
|
||||
* {@extLink security_guide_jca
|
||||
* Java Cryptography Architecture (JCA) Reference Guide}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @since 1.4
|
||||
|
@ -43,7 +43,7 @@
|
||||
*
|
||||
* <ul>
|
||||
* <li><a href="{@docRoot}/../specs/security/standard-names.html">
|
||||
* <b>Java™ Security Standard Algorithm Names Specification
|
||||
* <b>Java Security Standard Algorithm Names Specification
|
||||
* </b></a></li>
|
||||
* </ul>
|
||||
*
|
||||
@ -52,15 +52,11 @@
|
||||
* For further documentation, please see:
|
||||
* <ul>
|
||||
* <li>
|
||||
* <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html">
|
||||
* <b>Java™ Cryptography Architecture (JCA) Reference Guide
|
||||
* </b></a></li>
|
||||
* {@extLink security_guide_jca
|
||||
* Java Cryptography Architecture (JCA) Reference Guide}</li>
|
||||
* <li>
|
||||
* <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/crypto/HowToImplAProvider.html">
|
||||
* <b>How to Implement a Provider in the Java™ Cryptography
|
||||
* Architecture </b></a></li>
|
||||
* {@extLink security_guide_impl_provider
|
||||
* How to Implement a Provider in the Java Cryptography Architecture}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @since 1.4
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2017, 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
|
||||
@ -81,9 +81,8 @@ public class SecretKeySpec implements KeySpec, SecretKey {
|
||||
* the array are copied to protect against subsequent modification.
|
||||
* @param algorithm the name of the secret-key algorithm to be associated
|
||||
* with the given key material.
|
||||
* See Appendix A in the <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
|
||||
* Java Cryptography Architecture Reference Guide</a>
|
||||
* See the <a href="{@docRoot}/../specs/security/standard-names.html">
|
||||
* Java Security Standard Algorithm Names</a> document
|
||||
* for information about standard algorithm names.
|
||||
* @exception IllegalArgumentException if <code>algorithm</code>
|
||||
* is null or <code>key</code> is null or empty.
|
||||
@ -126,9 +125,8 @@ public class SecretKeySpec implements KeySpec, SecretKey {
|
||||
* @param len the length of the key material.
|
||||
* @param algorithm the name of the secret-key algorithm to be associated
|
||||
* with the given key material.
|
||||
* See Appendix A in the <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
|
||||
* Java Cryptography Architecture Reference Guide</a>
|
||||
* See the <a href="{@docRoot}/../specs/security/standard-names.html">
|
||||
* Java Security Standard Algorithm Names</a> document
|
||||
* for information about standard algorithm names.
|
||||
* @exception IllegalArgumentException if <code>algorithm</code>
|
||||
* is null or <code>key</code> is null, empty, or too short,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2017, 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
|
||||
@ -57,16 +57,11 @@
|
||||
*
|
||||
* <ul>
|
||||
* <li>
|
||||
* <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html">
|
||||
* <b>Java™ Cryptography Architecture API Specification and Reference
|
||||
* </b></a></li>
|
||||
* {@extLink security_guide_jca
|
||||
* Java Cryptography Architecture (JCA) Reference Guide} </li>
|
||||
* <li>
|
||||
* <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/crypto/HowToImplAProvider.html">
|
||||
* <b>How to Implement a Provider for the
|
||||
* Java™ Cryptography Architecture
|
||||
* </b></a></li>
|
||||
* {@extLink security_guide_impl_provider
|
||||
* How to Implement a Provider in the Java Cryptography Architecture}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @since 1.4
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2017, 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
|
||||
@ -44,9 +44,9 @@ public abstract class ExtendedSSLSession implements SSLSession {
|
||||
* <p>
|
||||
* The signature algorithm name must be a standard Java Security
|
||||
* name (such as "SHA1withRSA", "SHA256withECDSA", and so on).
|
||||
* See Appendix A in the <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
|
||||
* Java Cryptography Architecture API Specification & Reference </a>
|
||||
* See the <a href=
|
||||
* "{@docRoot}/../specs/security/standard-names.html">
|
||||
* Java Security Standard Algorithm Names</a> document
|
||||
* for information about standard algorithm names.
|
||||
* <p>
|
||||
* Note: the local supported signature algorithms should conform to
|
||||
@ -72,9 +72,9 @@ public abstract class ExtendedSSLSession implements SSLSession {
|
||||
* <p>
|
||||
* The signature algorithm name must be a standard Java Security
|
||||
* name (such as "SHA1withRSA", "SHA256withECDSA", and so on).
|
||||
* See Appendix A in the <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
|
||||
* Java Cryptography Architecture API Specification & Reference </a>
|
||||
* See the <a href=
|
||||
* "{@docRoot}/../specs/security/standard-names.html">
|
||||
* Java Security Standard Algorithm Names</a> document
|
||||
* for information about standard algorithm names.
|
||||
*
|
||||
* @return An array of supported signature algorithms, in descending
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2017, 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,8 +127,8 @@ public class KeyManagerFactory {
|
||||
*
|
||||
* @param algorithm the standard name of the requested algorithm.
|
||||
* See the <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/jsse/JSSERefGuide.html">
|
||||
* Java Secure Socket Extension Reference Guide </a>
|
||||
* "{@docRoot}/../specs/security/standard-names.html">
|
||||
* Java Security Standard Algorithm Names</a> document
|
||||
* for information about standard algorithm names.
|
||||
*
|
||||
* @return the new {@code KeyManagerFactory} object
|
||||
@ -165,8 +165,8 @@ public class KeyManagerFactory {
|
||||
|
||||
* @param algorithm the standard name of the requested algorithm.
|
||||
* See the <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/jsse/JSSERefGuide.html">
|
||||
* Java Secure Socket Extension Reference Guide </a>
|
||||
* "{@docRoot}/../specs/security/standard-names.html">
|
||||
* Java Security Standard Algorithm Names</a> document
|
||||
* for information about standard algorithm names.
|
||||
*
|
||||
* @param provider the name of the provider.
|
||||
@ -209,8 +209,8 @@ public class KeyManagerFactory {
|
||||
*
|
||||
* @param algorithm the standard name of the requested algorithm.
|
||||
* See the <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/jsse/JSSERefGuide.html">
|
||||
* Java Secure Socket Extension Reference Guide </a>
|
||||
* "{@docRoot}/../specs/security/standard-names.html">
|
||||
* Java Security Standard Algorithm Names</a> document
|
||||
* for information about standard algorithm names.
|
||||
*
|
||||
* @param provider an instance of the provider.
|
||||
|
@ -294,9 +294,10 @@ public class SSLParameters {
|
||||
* SSL/TLS/DTLS handshaking. This is to prevent man-in-the-middle attacks.
|
||||
*
|
||||
* @param algorithm The standard string name of the endpoint
|
||||
* identification algorithm (or null). See Appendix A in the <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
|
||||
* Java Cryptography Architecture API Specification & Reference </a>
|
||||
* identification algorithm (or null).
|
||||
* See the <a href=
|
||||
* "{@docRoot}/../specs/security/standard-names.html">
|
||||
* Java Security Standard Algorithm Names</a> document
|
||||
* for information about standard algorithm names.
|
||||
*
|
||||
* @see X509ExtendedTrustManager
|
||||
|
@ -141,8 +141,8 @@ public class TrustManagerFactory {
|
||||
*
|
||||
* @param algorithm the standard name of the requested trust management
|
||||
* algorithm. See the <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/jsse/JSSERefGuide.html">
|
||||
* Java Secure Socket Extension Reference Guide </a>
|
||||
* "{@docRoot}/../specs/security/standard-names.html">
|
||||
* Java Security Standard Algorithm Names</a> document
|
||||
* for information about standard algorithm names.
|
||||
*
|
||||
* @return the new {@code TrustManagerFactory} object
|
||||
@ -179,8 +179,8 @@ public class TrustManagerFactory {
|
||||
*
|
||||
* @param algorithm the standard name of the requested trust management
|
||||
* algorithm. See the <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/jsse/JSSERefGuide.html">
|
||||
* Java Secure Socket Extension Reference Guide </a>
|
||||
* "{@docRoot}/../specs/security/standard-names.html">
|
||||
* Java Security Standard Algorithm Names</a> document
|
||||
* for information about standard algorithm names.
|
||||
*
|
||||
* @param provider the name of the provider.
|
||||
@ -223,8 +223,8 @@ public class TrustManagerFactory {
|
||||
*
|
||||
* @param algorithm the standard name of the requested trust management
|
||||
* algorithm. See the <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/jsse/JSSERefGuide.html">
|
||||
* Java Secure Socket Extension Reference Guide </a>
|
||||
* "{@docRoot}/../specs/security/standard-names.html">
|
||||
* Java Security Standard Algorithm Names</a> document
|
||||
* for information about standard algorithm names.
|
||||
*
|
||||
* @param provider an instance of the provider.
|
||||
|
@ -49,8 +49,10 @@ import java.security.SecureClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.jar.Attributes;
|
||||
@ -336,16 +338,43 @@ public class BuiltinClassLoader
|
||||
}
|
||||
}
|
||||
|
||||
// search class path
|
||||
// class path (not checked)
|
||||
Enumeration<URL> e = findResourcesOnClassPath(name);
|
||||
while (e.hasMoreElements()) {
|
||||
URL url = checkURL(e.nextElement());
|
||||
if (url != null) {
|
||||
checked.add(url);
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.enumeration(checked);
|
||||
// concat the checked URLs and the (not checked) class path
|
||||
return new Enumeration<>() {
|
||||
final Iterator<URL> iterator = checked.iterator();
|
||||
URL next;
|
||||
private boolean hasNext() {
|
||||
if (next != null) {
|
||||
return true;
|
||||
} else if (iterator.hasNext()) {
|
||||
next = iterator.next();
|
||||
return true;
|
||||
} else {
|
||||
// need to check each URL
|
||||
while (e.hasMoreElements() && next == null) {
|
||||
next = checkURL(e.nextElement());
|
||||
}
|
||||
return next != null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean hasMoreElements() {
|
||||
return hasNext();
|
||||
}
|
||||
@Override
|
||||
public URL nextElement() {
|
||||
if (hasNext()) {
|
||||
URL result = next;
|
||||
next = null;
|
||||
return result;
|
||||
} else {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -28,6 +28,7 @@ package jdk.internal.loader;
|
||||
import java.io.File;
|
||||
import java.io.FilePermission;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.lang.module.Configuration;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleReader;
|
||||
@ -52,11 +53,17 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Spliterator;
|
||||
import java.util.Spliterators;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
import jdk.internal.module.Resources;
|
||||
@ -79,8 +86,8 @@ import jdk.internal.module.Resources;
|
||||
* loader. This allows automatic modules (for example) to link to types in the
|
||||
* unnamed module of the parent class loader.
|
||||
*
|
||||
* @see ModuleModuleLayer#defineModulesWithOneLoader
|
||||
* @see ModuleModuleLayer#defineModulesWithManyLoaders
|
||||
* @see ModuleLayer#defineModulesWithOneLoader
|
||||
* @see ModuleLayer#defineModulesWithManyLoaders
|
||||
*/
|
||||
|
||||
public final class Loader extends SecureClassLoader {
|
||||
@ -303,7 +310,6 @@ public final class Loader extends SecureClassLoader {
|
||||
|
||||
// -- resources --
|
||||
|
||||
|
||||
/**
|
||||
* Returns a URL to a resource of the given name in a module defined to
|
||||
* this class loader.
|
||||
@ -388,33 +394,96 @@ public final class Loader extends SecureClassLoader {
|
||||
|
||||
@Override
|
||||
public Enumeration<URL> findResources(String name) throws IOException {
|
||||
List<URL> urls = new ArrayList<>();
|
||||
return Collections.enumeration(findResourcesAsList(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getResource(String name) {
|
||||
Objects.requireNonNull(name);
|
||||
|
||||
// this loader
|
||||
URL url = findResource(name);
|
||||
if (url != null) {
|
||||
return url;
|
||||
} else {
|
||||
// parent loader
|
||||
return parent.getResource(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration<URL> getResources(String name) throws IOException {
|
||||
Objects.requireNonNull(name);
|
||||
|
||||
// this loader
|
||||
List<URL> urls = findResourcesAsList(name);
|
||||
|
||||
// parent loader
|
||||
Enumeration<URL> e = parent.getResources(name);
|
||||
|
||||
// concat the URLs with the URLs returned by the parent
|
||||
return new Enumeration<>() {
|
||||
final Iterator<URL> iterator = urls.iterator();
|
||||
@Override
|
||||
public boolean hasMoreElements() {
|
||||
return (iterator.hasNext() || e.hasMoreElements());
|
||||
}
|
||||
@Override
|
||||
public URL nextElement() {
|
||||
if (iterator.hasNext()) {
|
||||
return iterator.next();
|
||||
} else {
|
||||
return e.nextElement();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<URL> resources(String name) {
|
||||
Objects.requireNonNull(name);
|
||||
// ordering not specified
|
||||
int characteristics = (Spliterator.NONNULL | Spliterator.IMMUTABLE |
|
||||
Spliterator.SIZED | Spliterator.SUBSIZED);
|
||||
Supplier<Spliterator<URL>> supplier = () -> {
|
||||
try {
|
||||
List<URL> urls = findResourcesAsList(name);
|
||||
return Spliterators.spliterator(urls, characteristics);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
};
|
||||
Stream<URL> s1 = StreamSupport.stream(supplier, characteristics, false);
|
||||
Stream<URL> s2 = parent.resources(name);
|
||||
return Stream.concat(s1, s2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the resources with the given name in this class loader.
|
||||
*/
|
||||
private List<URL> findResourcesAsList(String name) throws IOException {
|
||||
String pn = Resources.toPackageName(name);
|
||||
LoadedModule module = localPackageToModule.get(pn);
|
||||
if (module != null) {
|
||||
try {
|
||||
URL url = findResource(module.name(), name);
|
||||
if (url != null
|
||||
URL url = findResource(module.name(), name);
|
||||
if (url != null
|
||||
&& (name.endsWith(".class")
|
||||
|| url.toString().endsWith("/")
|
||||
|| isOpen(module.mref(), pn))) {
|
||||
urls.add(url);
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
// ignore
|
||||
|| url.toString().endsWith("/")
|
||||
|| isOpen(module.mref(), pn))) {
|
||||
return List.of(url);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
} else {
|
||||
List<URL> urls = new ArrayList<>();
|
||||
for (ModuleReference mref : nameToModule.values()) {
|
||||
try {
|
||||
URL url = findResource(mref.descriptor().name(), name);
|
||||
if (url != null)
|
||||
urls.add(url);
|
||||
} catch (IOException ioe) {
|
||||
// ignore
|
||||
URL url = findResource(mref.descriptor().name(), name);
|
||||
if (url != null) {
|
||||
urls.add(url);
|
||||
}
|
||||
}
|
||||
return urls;
|
||||
}
|
||||
return Collections.enumeration(urls);
|
||||
}
|
||||
|
||||
|
||||
|
@ -32,6 +32,8 @@ import java.lang.reflect.Method;
|
||||
import java.net.URI;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Stream;
|
||||
@ -44,13 +46,15 @@ import sun.nio.ch.Interruptible;
|
||||
public interface JavaLangAccess {
|
||||
|
||||
/**
|
||||
* Returns a {@code Method} object that reflects the specified public
|
||||
* member method of the given class. Returns {@code null} if the
|
||||
* method is not defined.
|
||||
* Returns the list of {@code Method} objects for the declared public
|
||||
* methods of this class or interface that have the specified method name
|
||||
* and parameter types.
|
||||
*/
|
||||
Method getMethodOrNull(Class<?> klass, String name, Class<?>... parameterTypes);
|
||||
List<Method> getDeclaredPublicMethods(Class<?> klass, String name, Class<?>... parameterTypes);
|
||||
|
||||
/** Return the constant pool for a class. */
|
||||
/**
|
||||
* Return the constant pool for a class.
|
||||
*/
|
||||
ConstantPool getConstantPool(Class<?> klass);
|
||||
|
||||
/**
|
||||
@ -95,7 +99,9 @@ public interface JavaLangAccess {
|
||||
*/
|
||||
<E extends Enum<E>> E[] getEnumConstantsShared(Class<E> klass);
|
||||
|
||||
/** Set thread's blocker field. */
|
||||
/**
|
||||
* Set thread's blocker field.
|
||||
*/
|
||||
void blockedOn(Thread t, Interruptible b);
|
||||
|
||||
/**
|
||||
@ -154,11 +160,6 @@ public interface JavaLangAccess {
|
||||
*/
|
||||
Class<?> findBootstrapClassOrNull(ClassLoader cl, String name);
|
||||
|
||||
/**
|
||||
* Returns the Packages for the given class loader.
|
||||
*/
|
||||
Stream<Package> packages(ClassLoader cl);
|
||||
|
||||
/**
|
||||
* Define a Package of the given name and module by the given class loader.
|
||||
*/
|
||||
@ -223,15 +224,30 @@ public interface JavaLangAccess {
|
||||
void addOpens(Module m1, String pkg, Module m2);
|
||||
|
||||
/**
|
||||
* Updates a module m to open a package to all unnamed modules.
|
||||
* Updates module m to open a package to all unnamed modules.
|
||||
*/
|
||||
void addOpensToAllUnnamed(Module m, String pkg);
|
||||
|
||||
/**
|
||||
* Updates a module m to use a service.
|
||||
* Updates module m to open all packages returned by the given iterator.
|
||||
*/
|
||||
void addOpensToAllUnnamed(Module m, Iterator<String> packages);
|
||||
|
||||
/**
|
||||
* Updates module m to use a service.
|
||||
*/
|
||||
void addUses(Module m, Class<?> service);
|
||||
|
||||
/**
|
||||
* Returns true if module m reflectively exports a package to other
|
||||
*/
|
||||
boolean isReflectivelyExported(Module module, String pn, Module other);
|
||||
|
||||
/**
|
||||
* Returns true if module m reflectively opens a package to other
|
||||
*/
|
||||
boolean isReflectivelyOpened(Module module, String pn, Module other);
|
||||
|
||||
/**
|
||||
* Returns the ServicesCatalog for the given Layer.
|
||||
*/
|
||||
|
@ -33,146 +33,240 @@ import java.security.CodeSource;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import static java.util.Collections.*;
|
||||
|
||||
import jdk.internal.loader.BootLoader;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
import jdk.internal.misc.JavaLangAccess;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
|
||||
/**
|
||||
* Supports logging of access to members of API packages that are exported or
|
||||
* opened via backdoor mechanisms to code in unnamed modules.
|
||||
* Supports logging of access to members of exported and concealed packages
|
||||
* that are opened to code in unnamed modules for illegal access.
|
||||
*/
|
||||
|
||||
public final class IllegalAccessLogger {
|
||||
|
||||
/**
|
||||
* Holder class to lazily create the StackWalker object and determine
|
||||
* if the stack trace should be printed
|
||||
* Logger modes
|
||||
*/
|
||||
static class Holder {
|
||||
static final StackWalker STACK_WALKER;
|
||||
static final boolean PRINT_STACK_TRACE;
|
||||
public static enum Mode {
|
||||
/**
|
||||
* Prints a warning when an illegal access succeeds and then
|
||||
* discards the logger so that there is no further output.
|
||||
*/
|
||||
ONESHOT,
|
||||
/**
|
||||
* Print warnings when illegal access succeeds
|
||||
*/
|
||||
WARN,
|
||||
/**
|
||||
* Prints warnings and a stack trace when illegal access succeeds
|
||||
*/
|
||||
DEBUG,
|
||||
}
|
||||
|
||||
static {
|
||||
PrivilegedAction<StackWalker> pa = () ->
|
||||
StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
|
||||
STACK_WALKER = AccessController.doPrivileged(pa);
|
||||
/**
|
||||
* A builder for IllegalAccessLogger objects.
|
||||
*/
|
||||
public static class Builder {
|
||||
private final Mode mode;
|
||||
private final PrintStream warningStream;
|
||||
private final Map<Module, Set<String>> moduleToConcealedPackages;
|
||||
private final Map<Module, Set<String>> moduleToExportedPackages;
|
||||
private boolean complete;
|
||||
|
||||
String name = "sun.reflect.debugModuleAccessChecks";
|
||||
String value = GetPropertyAction.privilegedGetProperty(name, null);
|
||||
PRINT_STACK_TRACE = "access" .equals(value);
|
||||
private void ensureNotComplete() {
|
||||
if (complete) throw new IllegalStateException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a builder.
|
||||
*/
|
||||
public Builder(Mode mode, PrintStream warningStream) {
|
||||
this.mode = mode;
|
||||
this.warningStream = warningStream;
|
||||
this.moduleToConcealedPackages = new HashMap<>();
|
||||
this.moduleToExportedPackages = new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adding logging of reflective-access to any member of a type in
|
||||
* otherwise concealed packages.
|
||||
*/
|
||||
public Builder logAccessToConcealedPackages(Module m, Set<String> packages) {
|
||||
ensureNotComplete();
|
||||
moduleToConcealedPackages.put(m, unmodifiableSet(packages));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adding logging of reflective-access to non-public members/types in
|
||||
* otherwise exported (not open) packages.
|
||||
*/
|
||||
public Builder logAccessToExportedPackages(Module m, Set<String> packages) {
|
||||
ensureNotComplete();
|
||||
moduleToExportedPackages.put(m, unmodifiableSet(packages));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the IllegalAccessLogger and sets it as the system-wise logger.
|
||||
*/
|
||||
public void complete() {
|
||||
Map<Module, Set<String>> map1 = unmodifiableMap(moduleToConcealedPackages);
|
||||
Map<Module, Set<String>> map2 = unmodifiableMap(moduleToExportedPackages);
|
||||
logger = new IllegalAccessLogger(mode, warningStream, map1, map2);
|
||||
complete = true;
|
||||
}
|
||||
}
|
||||
|
||||
// the maximum number of frames to capture
|
||||
private static final int MAX_STACK_FRAMES = 32;
|
||||
// need access to java.lang.Module
|
||||
private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
|
||||
|
||||
// lock to avoid interference when printing stack traces
|
||||
private static final Object OUTPUT_LOCK = new Object();
|
||||
// system-wide IllegalAccessLogger
|
||||
private static volatile IllegalAccessLogger logger;
|
||||
|
||||
// caller -> usages
|
||||
private final Map<Class<?>, Set<Usage>> callerToUsages = new WeakHashMap<>();
|
||||
|
||||
// module -> (package name -> CLI option)
|
||||
private final Map<Module, Map<String, String>> exported;
|
||||
private final Map<Module, Map<String, String>> opened;
|
||||
// logger mode
|
||||
private final Mode mode;
|
||||
|
||||
// the print stream to send the warnings
|
||||
private final PrintStream warningStream;
|
||||
|
||||
private IllegalAccessLogger(Map<Module, Map<String, String>> exported,
|
||||
Map<Module, Map<String, String>> opened,
|
||||
PrintStream warningStream) {
|
||||
this.exported = deepCopy(exported);
|
||||
this.opened = deepCopy(opened);
|
||||
// module -> packages open for illegal access
|
||||
private final Map<Module, Set<String>> moduleToConcealedPackages;
|
||||
private final Map<Module, Set<String>> moduleToExportedPackages;
|
||||
|
||||
// caller -> usages
|
||||
private final Map<Class<?>, Usages> callerToUsages = new WeakHashMap<>();
|
||||
|
||||
private IllegalAccessLogger(Mode mode,
|
||||
PrintStream warningStream,
|
||||
Map<Module, Set<String>> moduleToConcealedPackages,
|
||||
Map<Module, Set<String>> moduleToExportedPackages)
|
||||
{
|
||||
this.mode = mode;
|
||||
this.warningStream = warningStream;
|
||||
this.moduleToConcealedPackages = moduleToConcealedPackages;
|
||||
this.moduleToExportedPackages = moduleToExportedPackages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns that a Builder that is seeded with the packages known to this logger.
|
||||
* Returns the system-wide IllegalAccessLogger or {@code null} if there is
|
||||
* no logger.
|
||||
*/
|
||||
public Builder toBuilder() {
|
||||
return new Builder(exported, opened);
|
||||
public static IllegalAccessLogger illegalAccessLogger() {
|
||||
return logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the module exports a concealed package for illegal
|
||||
* access.
|
||||
*/
|
||||
public boolean isExportedForIllegalAccess(Module module, String pn) {
|
||||
Set<String> packages = moduleToConcealedPackages.get(module);
|
||||
if (packages != null && packages.contains(pn))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the module opens a concealed or exported package for
|
||||
* illegal access.
|
||||
*/
|
||||
public boolean isOpenForIllegalAccess(Module module, String pn) {
|
||||
if (isExportedForIllegalAccess(module, pn))
|
||||
return true;
|
||||
Set<String> packages = moduleToExportedPackages.get(module);
|
||||
if (packages != null && packages.contains(pn))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs access to the member of a target class by a caller class if the class
|
||||
* is in a package that is exported via a backdoor mechanism.
|
||||
* is in a package that is exported for illegal access.
|
||||
*
|
||||
* The {@code whatSupplier} supplies the message that describes the member.
|
||||
*/
|
||||
public void logIfExportedByBackdoor(Class<?> caller,
|
||||
Class<?> target,
|
||||
Supplier<String> whatSupplier) {
|
||||
Map<String, String> packages = exported.get(target.getModule());
|
||||
if (packages != null) {
|
||||
String how = packages.get(target.getPackageName());
|
||||
if (how != null) {
|
||||
log(caller, whatSupplier.get(), how);
|
||||
public void logIfExportedForIllegalAccess(Class<?> caller,
|
||||
Class<?> target,
|
||||
Supplier<String> whatSupplier) {
|
||||
Module targetModule = target.getModule();
|
||||
String targetPackage = target.getPackageName();
|
||||
if (isExportedForIllegalAccess(targetModule, targetPackage)) {
|
||||
Module callerModule = caller.getModule();
|
||||
if (!JLA.isReflectivelyExported(targetModule, targetPackage, callerModule)) {
|
||||
log(caller, whatSupplier.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs access to the member of a target class by a caller class if the class
|
||||
* is in a package that is opened via a backdoor mechanism.
|
||||
* is in a package that is opened for illegal access.
|
||||
*
|
||||
* The {@code what} parameter supplies the message that describes the member.
|
||||
*/
|
||||
public void logIfOpenedByBackdoor(Class<?> caller,
|
||||
Class<?> target,
|
||||
Supplier<String> whatSupplier) {
|
||||
Map<String, String> packages = opened.get(target.getModule());
|
||||
if (packages != null) {
|
||||
String how = packages.get(target.getPackageName());
|
||||
if (how != null) {
|
||||
log(caller, whatSupplier.get(), how);
|
||||
public void logIfOpenedForIllegalAccess(Class<?> caller,
|
||||
Class<?> target,
|
||||
Supplier<String> whatSupplier) {
|
||||
Module targetModule = target.getModule();
|
||||
String targetPackage = target.getPackageName();
|
||||
if (isOpenForIllegalAccess(targetModule, targetPackage)) {
|
||||
Module callerModule = caller.getModule();
|
||||
if (!JLA.isReflectivelyOpened(targetModule, targetPackage, callerModule)) {
|
||||
log(caller, whatSupplier.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs access by caller lookup if the target class is in a package that is
|
||||
* opened for illegal access.
|
||||
*/
|
||||
public void logIfOpenedForIllegalAccess(MethodHandles.Lookup caller, Class<?> target) {
|
||||
Module targetModule = target.getModule();
|
||||
String targetPackage = target.getPackageName();
|
||||
if (isOpenForIllegalAccess(targetModule, targetPackage)) {
|
||||
Class<?> callerClass = caller.lookupClass();
|
||||
Module callerModule = callerClass.getModule();
|
||||
if (!JLA.isReflectivelyOpened(targetModule, targetPackage, callerModule)) {
|
||||
URL url = codeSource(callerClass);
|
||||
final String source;
|
||||
if (url == null) {
|
||||
source = callerClass.getName();
|
||||
} else {
|
||||
source = callerClass.getName() + " (" + url + ")";
|
||||
}
|
||||
log(callerClass, target.getName(), () ->
|
||||
"WARNING: Illegal reflective access using Lookup on " + source
|
||||
+ " to " + target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs access by a caller class. The {@code what} parameter describes
|
||||
* the member is accessed, the {@code how} parameter is the means by which
|
||||
* access is allocated (CLI option for example).
|
||||
* the member being accessed.
|
||||
*/
|
||||
private void log(Class<?> caller, String what, String how) {
|
||||
private void log(Class<?> caller, String what) {
|
||||
log(caller, what, () -> {
|
||||
PrivilegedAction<ProtectionDomain> pa = caller::getProtectionDomain;
|
||||
CodeSource cs = AccessController.doPrivileged(pa).getCodeSource();
|
||||
URL url = (cs != null) ? cs.getLocation() : null;
|
||||
URL url = codeSource(caller);
|
||||
String source = caller.getName();
|
||||
if (url != null)
|
||||
source += " (" + url + ")";
|
||||
return "WARNING: Illegal access by " + source + " to " + what
|
||||
+ " (permitted by " + how + ")";
|
||||
return "WARNING: Illegal reflective access by " + source + " to " + what;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Logs access to caller class if the class is in a package that is opened via
|
||||
* a backdoor mechanism.
|
||||
*/
|
||||
public void logIfOpenedByBackdoor(MethodHandles.Lookup caller, Class<?> target) {
|
||||
Map<String, String> packages = opened.get(target.getModule());
|
||||
if (packages != null) {
|
||||
String how = packages.get(target.getPackageName());
|
||||
if (how != null) {
|
||||
log(caller.lookupClass(), target.getName(), () ->
|
||||
"WARNING: Illegal access using Lookup on " + caller.lookupClass()
|
||||
+ " to " + target + " (permitted by " + how + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log access by a caller. The {@code what} parameter describes the class or
|
||||
* member that is being accessed. The {@code msgSupplier} supplies the log
|
||||
@ -184,53 +278,73 @@ public final class IllegalAccessLogger {
|
||||
* keys so it can be expunged when the caller is GC'ed/unloaded.
|
||||
*/
|
||||
private void log(Class<?> caller, String what, Supplier<String> msgSupplier) {
|
||||
if (mode == Mode.ONESHOT) {
|
||||
synchronized (IllegalAccessLogger.class) {
|
||||
// discard the system wide logger
|
||||
if (logger == null)
|
||||
return;
|
||||
logger = null;
|
||||
}
|
||||
warningStream.println(loudWarning(caller, msgSupplier));
|
||||
return;
|
||||
}
|
||||
|
||||
// stack trace without the top-most frames in java.base
|
||||
List<StackWalker.StackFrame> stack = Holder.STACK_WALKER.walk(s ->
|
||||
List<StackWalker.StackFrame> stack = StackWalkerHolder.INSTANCE.walk(s ->
|
||||
s.dropWhile(this::isJavaBase)
|
||||
.limit(MAX_STACK_FRAMES)
|
||||
.limit(32)
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
|
||||
// check if the access has already been recorded
|
||||
// record usage if this is the first (or not recently recorded)
|
||||
Usage u = new Usage(what, hash(stack));
|
||||
boolean firstUsage;
|
||||
boolean added;
|
||||
synchronized (this) {
|
||||
firstUsage = callerToUsages.computeIfAbsent(caller, k -> new HashSet<>()).add(u);
|
||||
added = callerToUsages.computeIfAbsent(caller, k -> new Usages()).add(u);
|
||||
}
|
||||
|
||||
// log message if first usage
|
||||
if (firstUsage) {
|
||||
// print warning if this is the first (or not a recent) usage
|
||||
if (added) {
|
||||
String msg = msgSupplier.get();
|
||||
if (Holder.PRINT_STACK_TRACE) {
|
||||
synchronized (OUTPUT_LOCK) {
|
||||
warningStream.println(msg);
|
||||
stack.forEach(f -> warningStream.println("\tat " + f));
|
||||
}
|
||||
} else {
|
||||
warningStream.println(msg);
|
||||
if (mode == Mode.DEBUG) {
|
||||
StringBuilder sb = new StringBuilder(msg);
|
||||
stack.forEach(f ->
|
||||
sb.append(System.lineSeparator()).append("\tat " + f)
|
||||
);
|
||||
msg = sb.toString();
|
||||
}
|
||||
warningStream.println(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private static class Usage {
|
||||
private final String what;
|
||||
private final int stack;
|
||||
Usage(String what, int stack) {
|
||||
this.what = what;
|
||||
this.stack = stack;
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return what.hashCode() ^ stack;
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object ob) {
|
||||
if (ob instanceof Usage) {
|
||||
Usage that = (Usage)ob;
|
||||
return what.equals(that.what) && stack == (that.stack);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Returns the code source for the given class or null if there is no code source
|
||||
*/
|
||||
private URL codeSource(Class<?> clazz) {
|
||||
PrivilegedAction<ProtectionDomain> pa = clazz::getProtectionDomain;
|
||||
CodeSource cs = AccessController.doPrivileged(pa).getCodeSource();
|
||||
return (cs != null) ? cs.getLocation() : null;
|
||||
}
|
||||
|
||||
private String loudWarning(Class<?> caller, Supplier<String> msgSupplier) {
|
||||
StringJoiner sj = new StringJoiner(System.lineSeparator());
|
||||
sj.add("WARNING: An illegal reflective access operation has occurred");
|
||||
sj.add(msgSupplier.get());
|
||||
sj.add("WARNING: Please consider reporting this to the maintainers of "
|
||||
+ caller.getName());
|
||||
sj.add("WARNING: Use --illegal-access=warn to enable warnings of further"
|
||||
+ " illegal reflective access operations");
|
||||
sj.add("WARNING: All illegal access operations will be denied in a"
|
||||
+ " future release");
|
||||
return sj.toString();
|
||||
}
|
||||
|
||||
private static class StackWalkerHolder {
|
||||
static final StackWalker INSTANCE;
|
||||
static {
|
||||
PrivilegedAction<StackWalker> pa = () ->
|
||||
StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
|
||||
INSTANCE = AccessController.doPrivileged(pa);
|
||||
}
|
||||
}
|
||||
|
||||
@ -256,89 +370,39 @@ public final class IllegalAccessLogger {
|
||||
return hash;
|
||||
}
|
||||
|
||||
// system-wide IllegalAccessLogger
|
||||
private static volatile IllegalAccessLogger logger;
|
||||
|
||||
/**
|
||||
* Sets the system-wide IllegalAccessLogger
|
||||
*/
|
||||
public static void setIllegalAccessLogger(IllegalAccessLogger l) {
|
||||
if (l.exported.isEmpty() && l.opened.isEmpty()) {
|
||||
logger = null;
|
||||
} else {
|
||||
logger = l;
|
||||
private static class Usage {
|
||||
private final String what;
|
||||
private final int stack;
|
||||
Usage(String what, int stack) {
|
||||
this.what = what;
|
||||
this.stack = stack;
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return what.hashCode() ^ stack;
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object ob) {
|
||||
if (ob instanceof Usage) {
|
||||
Usage that = (Usage)ob;
|
||||
return what.equals(that.what) && stack == (that.stack);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the system-wide IllegalAccessLogger or {@code null} if there is
|
||||
* no logger.
|
||||
*/
|
||||
public static IllegalAccessLogger illegalAccessLogger() {
|
||||
return logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for IllegalAccessLogger objects.
|
||||
*/
|
||||
public static class Builder {
|
||||
private final Module UNNAMED = BootLoader.getUnnamedModule();
|
||||
private Map<Module, Map<String, String>> exported;
|
||||
private Map<Module, Map<String, String>> opened;
|
||||
private PrintStream warningStream = System.err;
|
||||
|
||||
public Builder() { }
|
||||
|
||||
public Builder(Map<Module, Map<String, String>> exported,
|
||||
Map<Module, Map<String, String>> opened) {
|
||||
this.exported = deepCopy(exported);
|
||||
this.opened = deepCopy(opened);
|
||||
@SuppressWarnings("serial")
|
||||
private static class Usages extends LinkedHashMap<Usage, Boolean> {
|
||||
Usages() { }
|
||||
boolean add(Usage u) {
|
||||
return (putIfAbsent(u, Boolean.TRUE) == null);
|
||||
}
|
||||
|
||||
public Builder logAccessToExportedPackage(Module m, String pn, String how) {
|
||||
if (!m.isExported(pn, UNNAMED)) {
|
||||
if (exported == null)
|
||||
exported = new HashMap<>();
|
||||
exported.computeIfAbsent(m, k -> new HashMap<>()).putIfAbsent(pn, how);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder logAccessToOpenPackage(Module m, String pn, String how) {
|
||||
// opens implies exported at run-time.
|
||||
logAccessToExportedPackage(m, pn, how);
|
||||
|
||||
if (!m.isOpen(pn, UNNAMED)) {
|
||||
if (opened == null)
|
||||
opened = new HashMap<>();
|
||||
opened.computeIfAbsent(m, k -> new HashMap<>()).putIfAbsent(pn, how);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder warningStream(PrintStream warningStream) {
|
||||
this.warningStream = Objects.requireNonNull(warningStream);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the logger.
|
||||
*/
|
||||
public IllegalAccessLogger build() {
|
||||
return new IllegalAccessLogger(exported, opened, warningStream);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static Map<Module, Map<String, String>> deepCopy(Map<Module, Map<String, String>> map) {
|
||||
if (map == null || map.isEmpty()) {
|
||||
return new HashMap<>();
|
||||
} else {
|
||||
Map<Module, Map<String, String>> newMap = new HashMap<>();
|
||||
for (Map.Entry<Module, Map<String, String>> e : map.entrySet()) {
|
||||
newMap.put(e.getKey(), new HashMap<>(e.getValue()));
|
||||
}
|
||||
return newMap;
|
||||
@Override
|
||||
protected boolean removeEldestEntry(Map.Entry<Usage, Boolean> oldest) {
|
||||
// prevent map growing too big, say where a utility class
|
||||
// is used by generated code to do illegal access
|
||||
return size() > 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package jdk.internal.module;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleFinder;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.*;
|
||||
|
||||
/**
|
||||
* Generates the maps of concealed and exported packages to open at run-time.
|
||||
*
|
||||
* This is used at run-time for exploded builds, and at link-time to generate
|
||||
* the maps for the system modules in the run-time image.
|
||||
*/
|
||||
|
||||
public class IllegalAccessMaps {
|
||||
private final Map<String, Set<String>> concealedPackagesToOpen;
|
||||
private final Map<String, Set<String>> exportedPackagesToOpen;
|
||||
|
||||
private IllegalAccessMaps(Map<String, Set<String>> map1,
|
||||
Map<String, Set<String>> map2) {
|
||||
this.concealedPackagesToOpen = map1;
|
||||
this.exportedPackagesToOpen = map2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the map of concealed packages to open. The map key is the
|
||||
* module name, the value is the set of concealed packages to open.
|
||||
*/
|
||||
public Map<String, Set<String>> concealedPackagesToOpen() {
|
||||
return concealedPackagesToOpen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the map of exported packages to open. The map key is the
|
||||
* module name, the value is the set of exported packages to open.
|
||||
*/
|
||||
public Map<String, Set<String>> exportedPackagesToOpen() {
|
||||
return exportedPackagesToOpen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the maps of module to concealed and exported packages for
|
||||
* the system modules that are observable with the given module finder.
|
||||
*/
|
||||
public static IllegalAccessMaps generate(ModuleFinder finder) {
|
||||
Map<String, ModuleDescriptor> map = new HashMap<>();
|
||||
finder.findAll().stream()
|
||||
.map(ModuleReference::descriptor)
|
||||
.forEach(md -> md.packages().forEach(pn -> map.putIfAbsent(pn, md)));
|
||||
|
||||
Map<String, Set<String>> concealedPackagesToOpen = new HashMap<>();
|
||||
Map<String, Set<String>> exportedPackagesToOpen = new HashMap<>();
|
||||
|
||||
String rn = "jdk8_packages.dat";
|
||||
InputStream in = IllegalAccessMaps.class.getResourceAsStream(rn);
|
||||
if (in == null) {
|
||||
throw new InternalError(rn + " not found");
|
||||
}
|
||||
try (BufferedReader br = new BufferedReader(new InputStreamReader(in, UTF_8))) {
|
||||
br.lines()
|
||||
.filter(line -> !line.isEmpty() && !line.startsWith("#"))
|
||||
.forEach(pn -> {
|
||||
ModuleDescriptor descriptor = map.get(pn);
|
||||
if (descriptor != null && !isOpen(descriptor, pn)) {
|
||||
String name = descriptor.name();
|
||||
if (isExported(descriptor, pn)) {
|
||||
exportedPackagesToOpen.computeIfAbsent(name,
|
||||
k -> new HashSet<>()).add(pn);
|
||||
} else {
|
||||
concealedPackagesToOpen.computeIfAbsent(name,
|
||||
k -> new HashSet<>()).add(pn);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} catch (IOException ioe) {
|
||||
throw new UncheckedIOException(ioe);
|
||||
}
|
||||
|
||||
return new IllegalAccessMaps(concealedPackagesToOpen, exportedPackagesToOpen);
|
||||
}
|
||||
|
||||
private static boolean isExported(ModuleDescriptor descriptor, String pn) {
|
||||
return descriptor.exports()
|
||||
.stream()
|
||||
.anyMatch(e -> e.source().equals(pn) && !e.isQualified());
|
||||
}
|
||||
|
||||
private static boolean isOpen(ModuleDescriptor descriptor, String pn) {
|
||||
return descriptor.opens()
|
||||
.stream()
|
||||
.anyMatch(e -> e.source().equals(pn) && !e.isQualified());
|
||||
}
|
||||
}
|
@ -39,14 +39,17 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import jdk.internal.loader.BootLoader;
|
||||
import jdk.internal.loader.BuiltinClassLoader;
|
||||
import jdk.internal.misc.JavaLangAccess;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
import jdk.internal.perf.PerfCounter;
|
||||
|
||||
@ -59,7 +62,7 @@ import jdk.internal.perf.PerfCounter;
|
||||
* -m and --add-modules options. The modules are located on a module path that
|
||||
* is constructed from the upgrade module path, system modules, and application
|
||||
* module path. The Configuration is instantiated as the boot layer with each
|
||||
* module in the the configuration defined to one of the built-in class loaders.
|
||||
* module in the the configuration defined to a class loader.
|
||||
*/
|
||||
|
||||
public final class ModuleBootstrap {
|
||||
@ -119,20 +122,20 @@ public final class ModuleBootstrap {
|
||||
*/
|
||||
public static ModuleLayer boot() {
|
||||
|
||||
long t0 = System.nanoTime();
|
||||
|
||||
// system modules (may be patched)
|
||||
ModuleFinder systemModules = ModuleFinder.ofSystem();
|
||||
|
||||
PerfCounters.systemModulesTime.addElapsedTimeFrom(t0);
|
||||
|
||||
// Step 1: Locate system modules (may be patched)
|
||||
|
||||
long t1 = System.nanoTime();
|
||||
ModuleFinder systemModules = ModuleFinder.ofSystem();
|
||||
PerfCounters.systemModulesTime.addElapsedTimeFrom(t1);
|
||||
|
||||
|
||||
// Step 2: Define and load java.base. This patches all classes loaded
|
||||
// to date so that they are members of java.base. Once java.base is
|
||||
// loaded then resources in java.base are available for error messages
|
||||
// needed from here on.
|
||||
|
||||
long t2 = System.nanoTime();
|
||||
|
||||
// Once we have the system modules then we define the base module to
|
||||
// the VM. We do this here so that java.base is defined as early as
|
||||
// possible and also that resources in the base module can be located
|
||||
// for error messages that may happen from here on.
|
||||
ModuleReference base = systemModules.find(JAVA_BASE).orElse(null);
|
||||
if (base == null)
|
||||
throw new InternalError(JAVA_BASE + " not found");
|
||||
@ -142,15 +145,23 @@ public final class ModuleBootstrap {
|
||||
BootLoader.loadModule(base);
|
||||
Modules.defineModule(null, base.descriptor(), baseUri);
|
||||
|
||||
PerfCounters.defineBaseTime.addElapsedTimeFrom(t1);
|
||||
PerfCounters.defineBaseTime.addElapsedTimeFrom(t2);
|
||||
|
||||
|
||||
// Step 2a: If --validate-modules is specified then the VM needs to
|
||||
// start with only java.base, all other options are ignored.
|
||||
|
||||
// special mode to boot with only java.base, ignores other options
|
||||
String propValue = getAndRemoveProperty("jdk.module.minimumBoot");
|
||||
if (propValue != null) {
|
||||
return createMinimalBootLayer();
|
||||
}
|
||||
|
||||
long t2 = System.nanoTime();
|
||||
|
||||
// Step 3: Construct the module path and the set of root modules to
|
||||
// resolve. If --limit-modules is specified then it limits the set
|
||||
// modules that are observable.
|
||||
|
||||
long t3 = System.nanoTime();
|
||||
|
||||
// --upgrade-module-path option specified to launcher
|
||||
ModuleFinder upgradeModulePath
|
||||
@ -269,10 +280,13 @@ public final class ModuleBootstrap {
|
||||
.forEach(mn -> roots.add(mn));
|
||||
}
|
||||
|
||||
PerfCounters.optionsAndRootsTime.addElapsedTimeFrom(t2);
|
||||
PerfCounters.optionsAndRootsTime.addElapsedTimeFrom(t3);
|
||||
|
||||
|
||||
long t3 = System.nanoTime();
|
||||
// Step 4: Resolve the root modules, with service binding, to create
|
||||
// the configuration for the boot layer.
|
||||
|
||||
long t4 = System.nanoTime();
|
||||
|
||||
// determine if post resolution checks are needed
|
||||
boolean needPostResolutionChecks = true;
|
||||
@ -295,11 +309,17 @@ public final class ModuleBootstrap {
|
||||
needPostResolutionChecks,
|
||||
traceOutput);
|
||||
|
||||
// time to create configuration
|
||||
PerfCounters.resolveTime.addElapsedTimeFrom(t3);
|
||||
PerfCounters.resolveTime.addElapsedTimeFrom(t4);
|
||||
|
||||
// check module names and incubating status
|
||||
checkModuleNamesAndStatus(cf);
|
||||
|
||||
// Step 5: Map the modules in the configuration to class loaders.
|
||||
// The static configuration provides the mapping of standard and JDK
|
||||
// modules to the boot and platform loaders. All other modules (JDK
|
||||
// tool modules, and both explicit and automatic modules on the
|
||||
// application module path) are defined to the application class
|
||||
// loader.
|
||||
|
||||
long t5 = System.nanoTime();
|
||||
|
||||
// mapping of modules to class loaders
|
||||
Function<String, ClassLoader> clf = ModuleLoaderMap.mappingFunction(cf);
|
||||
@ -312,11 +332,9 @@ public final class ModuleBootstrap {
|
||||
String name = mref.descriptor().name();
|
||||
ClassLoader cl = clf.apply(name);
|
||||
if (cl == null) {
|
||||
|
||||
if (upgradeModulePath != null
|
||||
&& upgradeModulePath.find(name).isPresent())
|
||||
fail(name + ": cannot be loaded from upgrade module path");
|
||||
|
||||
if (!systemModules.find(name).isPresent())
|
||||
fail(name + ": cannot be loaded from application module path");
|
||||
}
|
||||
@ -330,55 +348,38 @@ public final class ModuleBootstrap {
|
||||
}
|
||||
}
|
||||
|
||||
// if needed check that there are no split packages in the set of
|
||||
// resolved modules for the boot layer
|
||||
// check for split packages in the modules mapped to the built-in loaders
|
||||
if (SystemModules.hasSplitPackages() || needPostResolutionChecks) {
|
||||
Map<String, String> packageToModule = new HashMap<>();
|
||||
for (ResolvedModule resolvedModule : cf.modules()) {
|
||||
ModuleDescriptor descriptor = resolvedModule.reference().descriptor();
|
||||
String name = descriptor.name();
|
||||
for (String p : descriptor.packages()) {
|
||||
String other = packageToModule.putIfAbsent(p, name);
|
||||
if (other != null) {
|
||||
String msg = "Package " + p + " in both module "
|
||||
+ name + " and module " + other;
|
||||
throw new LayerInstantiationException(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
checkSplitPackages(cf, clf);
|
||||
}
|
||||
|
||||
long t4 = System.nanoTime();
|
||||
|
||||
// define modules to VM/runtime
|
||||
ModuleLayer bootLayer = ModuleLayer.empty().defineModules(cf, clf);
|
||||
|
||||
PerfCounters.layerCreateTime.addElapsedTimeFrom(t4);
|
||||
|
||||
|
||||
long t5 = System.nanoTime();
|
||||
|
||||
// define the module to its class loader, except java.base
|
||||
for (ResolvedModule resolvedModule : cf.modules()) {
|
||||
ModuleReference mref = resolvedModule.reference();
|
||||
String name = mref.descriptor().name();
|
||||
ClassLoader cl = clf.apply(name);
|
||||
if (cl == null) {
|
||||
if (!name.equals(JAVA_BASE)) BootLoader.loadModule(mref);
|
||||
} else {
|
||||
((BuiltinClassLoader)cl).loadModule(mref);
|
||||
}
|
||||
}
|
||||
// load/register the modules with the built-in class loaders
|
||||
loadModules(cf, clf);
|
||||
|
||||
PerfCounters.loadModulesTime.addElapsedTimeFrom(t5);
|
||||
|
||||
|
||||
// --add-reads, --add-exports/--add-opens
|
||||
// Step 6: Define all modules to the VM
|
||||
|
||||
long t6 = System.nanoTime();
|
||||
ModuleLayer bootLayer = ModuleLayer.empty().defineModules(cf, clf);
|
||||
PerfCounters.layerCreateTime.addElapsedTimeFrom(t6);
|
||||
|
||||
|
||||
// Step 7: Miscellaneous
|
||||
|
||||
// check incubating status
|
||||
checkIncubatingStatus(cf);
|
||||
|
||||
// --add-reads, --add-exports/--add-opens, and -illegal-access
|
||||
long t7 = System.nanoTime();
|
||||
addExtraReads(bootLayer);
|
||||
addExtraExportsAndOpens(bootLayer);
|
||||
boolean extraExportsOrOpens = addExtraExportsAndOpens(bootLayer);
|
||||
addIllegalAccess(bootLayer, upgradeModulePath, extraExportsOrOpens);
|
||||
PerfCounters.adjustModulesTime.addElapsedTimeFrom(t7);
|
||||
|
||||
// total time to initialize
|
||||
PerfCounters.bootstrapTime.addElapsedTimeFrom(t0);
|
||||
PerfCounters.bootstrapTime.addElapsedTimeFrom(t1);
|
||||
|
||||
return bootLayer;
|
||||
}
|
||||
@ -397,6 +398,51 @@ public final class ModuleBootstrap {
|
||||
return ModuleLayer.empty().defineModules(cf, clf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load/register the modules to the built-in class loaders.
|
||||
*/
|
||||
private static void loadModules(Configuration cf,
|
||||
Function<String, ClassLoader> clf) {
|
||||
for (ResolvedModule resolvedModule : cf.modules()) {
|
||||
ModuleReference mref = resolvedModule.reference();
|
||||
String name = resolvedModule.name();
|
||||
ClassLoader loader = clf.apply(name);
|
||||
if (loader == null) {
|
||||
// skip java.base as it is already loaded
|
||||
if (!name.equals(JAVA_BASE)) {
|
||||
BootLoader.loadModule(mref);
|
||||
}
|
||||
} else if (loader instanceof BuiltinClassLoader) {
|
||||
((BuiltinClassLoader) loader).loadModule(mref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for split packages between modules defined to the built-in class
|
||||
* loaders.
|
||||
*/
|
||||
private static void checkSplitPackages(Configuration cf,
|
||||
Function<String, ClassLoader> clf) {
|
||||
Map<String, String> packageToModule = new HashMap<>();
|
||||
for (ResolvedModule resolvedModule : cf.modules()) {
|
||||
ModuleDescriptor descriptor = resolvedModule.reference().descriptor();
|
||||
String name = descriptor.name();
|
||||
ClassLoader loader = clf.apply(name);
|
||||
if (loader == null || loader instanceof BuiltinClassLoader) {
|
||||
for (String p : descriptor.packages()) {
|
||||
String other = packageToModule.putIfAbsent(p, name);
|
||||
if (other != null) {
|
||||
String msg = "Package " + p + " in both module "
|
||||
+ name + " and module " + other;
|
||||
throw new LayerInstantiationException(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a ModuleFinder that limits observability to the given root
|
||||
* modules, their transitive dependences, plus a set of other modules.
|
||||
@ -458,15 +504,14 @@ public final class ModuleBootstrap {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the module patcher for the initial configuration passed on the
|
||||
* value of the --patch-module options.
|
||||
*/
|
||||
private static ModulePatcher initModulePatcher() {
|
||||
Map<String, List<String>> map = decode("jdk.module.patch.",
|
||||
File.pathSeparator,
|
||||
false);
|
||||
File.pathSeparator,
|
||||
false);
|
||||
return new ModulePatcher(map);
|
||||
}
|
||||
|
||||
@ -538,38 +583,27 @@ public final class ModuleBootstrap {
|
||||
* Process the --add-exports and --add-opens options to export/open
|
||||
* additional packages specified on the command-line.
|
||||
*/
|
||||
private static void addExtraExportsAndOpens(ModuleLayer bootLayer) {
|
||||
private static boolean addExtraExportsAndOpens(ModuleLayer bootLayer) {
|
||||
boolean extraExportsOrOpens = false;
|
||||
|
||||
// --add-exports
|
||||
String prefix = "jdk.module.addexports.";
|
||||
Map<String, List<String>> extraExports = decode(prefix);
|
||||
if (!extraExports.isEmpty()) {
|
||||
addExtraExportsOrOpens(bootLayer, extraExports, false);
|
||||
extraExportsOrOpens = true;
|
||||
}
|
||||
|
||||
|
||||
// --add-opens
|
||||
prefix = "jdk.module.addopens.";
|
||||
Map<String, List<String>> extraOpens = decode(prefix);
|
||||
if (!extraOpens.isEmpty()) {
|
||||
addExtraExportsOrOpens(bootLayer, extraOpens, true);
|
||||
extraExportsOrOpens = true;
|
||||
}
|
||||
|
||||
// --permit-illegal-access
|
||||
if (getAndRemoveProperty("jdk.module.permitIllegalAccess") != null) {
|
||||
warn("--permit-illegal-access will be removed in the next major release");
|
||||
IllegalAccessLogger.Builder builder = new IllegalAccessLogger.Builder();
|
||||
Module unnamed = BootLoader.getUnnamedModule();
|
||||
bootLayer.modules().stream().forEach(m -> {
|
||||
m.getDescriptor()
|
||||
.packages()
|
||||
.stream()
|
||||
.filter(pn -> !m.isOpen(pn, unnamed)) // skip if opened by --add-opens
|
||||
.forEach(pn -> {
|
||||
builder.logAccessToOpenPackage(m, pn, "--permit-illegal-access");
|
||||
Modules.addOpensToAllUnnamed(m, pn);
|
||||
});
|
||||
});
|
||||
IllegalAccessLogger.setIllegalAccessLogger(builder.build());
|
||||
}
|
||||
return extraExportsOrOpens;
|
||||
}
|
||||
|
||||
private static void addExtraExportsOrOpens(ModuleLayer bootLayer,
|
||||
@ -638,6 +672,102 @@ public final class ModuleBootstrap {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the --illegal-access option (and its default) to open packages
|
||||
* of system modules in the boot layer to code in unnamed modules.
|
||||
*/
|
||||
private static void addIllegalAccess(ModuleLayer bootLayer,
|
||||
ModuleFinder upgradeModulePath,
|
||||
boolean extraExportsOrOpens) {
|
||||
String value = getAndRemoveProperty("jdk.module.illegalAccess");
|
||||
IllegalAccessLogger.Mode mode = IllegalAccessLogger.Mode.ONESHOT;
|
||||
if (value != null) {
|
||||
switch (value) {
|
||||
case "deny":
|
||||
return;
|
||||
case "permit":
|
||||
break;
|
||||
case "warn":
|
||||
mode = IllegalAccessLogger.Mode.WARN;
|
||||
break;
|
||||
case "debug":
|
||||
mode = IllegalAccessLogger.Mode.DEBUG;
|
||||
break;
|
||||
default:
|
||||
fail("Value specified to --illegal-access not recognized:"
|
||||
+ " '" + value + "'");
|
||||
return;
|
||||
}
|
||||
}
|
||||
IllegalAccessLogger.Builder builder
|
||||
= new IllegalAccessLogger.Builder(mode, System.err);
|
||||
|
||||
Map<String, Set<String>> map1 = SystemModules.concealedPackagesToOpen();
|
||||
Map<String, Set<String>> map2 = SystemModules.exportedPackagesToOpen();
|
||||
if (map1.isEmpty() && map2.isEmpty()) {
|
||||
// need to generate maps when on exploded build
|
||||
IllegalAccessMaps maps = IllegalAccessMaps.generate(limitedFinder());
|
||||
map1 = maps.concealedPackagesToOpen();
|
||||
map2 = maps.exportedPackagesToOpen();
|
||||
}
|
||||
|
||||
// open specific packages in the system modules
|
||||
for (Module m : bootLayer.modules()) {
|
||||
ModuleDescriptor descriptor = m.getDescriptor();
|
||||
String name = m.getName();
|
||||
|
||||
// skip open modules
|
||||
if (descriptor.isOpen()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip modules loaded from the upgrade module path
|
||||
if (upgradeModulePath != null
|
||||
&& upgradeModulePath.find(name).isPresent()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Set<String> concealedPackages = map1.getOrDefault(name, Set.of());
|
||||
Set<String> exportedPackages = map2.getOrDefault(name, Set.of());
|
||||
|
||||
// refresh the set of concealed and exported packages if needed
|
||||
if (extraExportsOrOpens) {
|
||||
concealedPackages = new HashSet<>(concealedPackages);
|
||||
exportedPackages = new HashSet<>(exportedPackages);
|
||||
Iterator<String> iterator = concealedPackages.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
String pn = iterator.next();
|
||||
if (m.isExported(pn, BootLoader.getUnnamedModule())) {
|
||||
// concealed package is exported to ALL-UNNAMED
|
||||
iterator.remove();
|
||||
exportedPackages.add(pn);
|
||||
}
|
||||
}
|
||||
iterator = exportedPackages.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
String pn = iterator.next();
|
||||
if (m.isOpen(pn, BootLoader.getUnnamedModule())) {
|
||||
// exported package is opened to ALL-UNNAMED
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// log reflective access to all types in concealed packages
|
||||
builder.logAccessToConcealedPackages(m, concealedPackages);
|
||||
|
||||
// log reflective access to non-public members/types in exported packages
|
||||
builder.logAccessToExportedPackages(m, exportedPackages);
|
||||
|
||||
// open the packages to unnamed modules
|
||||
JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
|
||||
jla.addOpensToAllUnnamed(m, concat(concealedPackages.iterator(),
|
||||
exportedPackages.iterator()));
|
||||
}
|
||||
|
||||
builder.complete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the values of --add-reads, -add-exports, --add-opens or
|
||||
* --patch-modules options that are encoded in system properties.
|
||||
@ -708,17 +838,16 @@ public final class ModuleBootstrap {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the names and resolution bit of each module in the configuration,
|
||||
* emitting warnings if needed.
|
||||
* Checks incubating status of modules in the configuration
|
||||
*/
|
||||
private static void checkModuleNamesAndStatus(Configuration cf) {
|
||||
private static void checkIncubatingStatus(Configuration cf) {
|
||||
String incubating = null;
|
||||
for (ResolvedModule rm : cf.modules()) {
|
||||
ModuleReference mref = rm.reference();
|
||||
String mn = mref.descriptor().name();
|
||||
for (ResolvedModule resolvedModule : cf.modules()) {
|
||||
ModuleReference mref = resolvedModule.reference();
|
||||
|
||||
// emit warning if the WARN_INCUBATING module resolution bit set
|
||||
if (ModuleResolution.hasIncubatingWarning(mref)) {
|
||||
String mn = mref.descriptor().name();
|
||||
if (incubating == null) {
|
||||
incubating = mn;
|
||||
} else {
|
||||
@ -777,6 +906,21 @@ public final class ModuleBootstrap {
|
||||
}
|
||||
}
|
||||
|
||||
static <T> Iterator<T> concat(Iterator<T> iterator1, Iterator<T> iterator2) {
|
||||
return new Iterator<T>() {
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return iterator1.hasNext() || iterator2.hasNext();
|
||||
}
|
||||
@Override
|
||||
public T next() {
|
||||
if (iterator1.hasNext()) return iterator1.next();
|
||||
if (iterator2.hasNext()) return iterator2.next();
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static class PerfCounters {
|
||||
|
||||
static PerfCounter systemModulesTime
|
||||
@ -791,6 +935,8 @@ public final class ModuleBootstrap {
|
||||
= PerfCounter.newPerfCounter("jdk.module.bootstrap.layerCreateTime");
|
||||
static PerfCounter loadModulesTime
|
||||
= PerfCounter.newPerfCounter("jdk.module.bootstrap.loadModulesTime");
|
||||
static PerfCounter adjustModulesTime
|
||||
= PerfCounter.newPerfCounter("jdk.module.bootstrap.adjustModulesTime");
|
||||
static PerfCounter bootstrapTime
|
||||
= PerfCounter.newPerfCounter("jdk.module.bootstrap.totalTime");
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ import java.io.UncheckedIOException;
|
||||
import java.lang.module.FindException;
|
||||
import java.lang.module.InvalidModuleDescriptorException;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleDescriptor.Builder;
|
||||
import java.lang.module.ModuleFinder;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.net.URI;
|
||||
@ -404,6 +405,9 @@ public class ModulePath implements ModuleFinder {
|
||||
|
||||
private static final String SERVICES_PREFIX = "META-INF/services/";
|
||||
|
||||
private static final Attributes.Name AUTOMATIC_MODULE_NAME
|
||||
= new Attributes.Name("Automatic-Module-Name");
|
||||
|
||||
/**
|
||||
* Returns the service type corresponding to the name of a services
|
||||
* configuration file if it is a legal type name.
|
||||
@ -445,48 +449,68 @@ public class ModulePath implements ModuleFinder {
|
||||
/**
|
||||
* Treat the given JAR file as a module as follows:
|
||||
*
|
||||
* 1. The module name (and optionally the version) is derived from the file
|
||||
* name of the JAR file
|
||||
* 2. All packages are derived from the .class files in the JAR file
|
||||
* 3. The contents of any META-INF/services configuration files are mapped
|
||||
* 1. The value of the Automatic-Module-Name attribute is the module name
|
||||
* 2. The version, and the module name when the Automatic-Module-Name
|
||||
* attribute is not present, is derived from the file ame of the JAR file
|
||||
* 3. All packages are derived from the .class files in the JAR file
|
||||
* 4. The contents of any META-INF/services configuration files are mapped
|
||||
* to "provides" declarations
|
||||
* 4. The Main-Class attribute in the main attributes of the JAR manifest
|
||||
* 5. The Main-Class attribute in the main attributes of the JAR manifest
|
||||
* is mapped to the module descriptor mainClass if possible
|
||||
*/
|
||||
private ModuleDescriptor deriveModuleDescriptor(JarFile jf)
|
||||
throws IOException
|
||||
{
|
||||
// Derive module name and version from JAR file name
|
||||
// Read Automatic-Module-Name attribute if present
|
||||
Manifest man = jf.getManifest();
|
||||
Attributes attrs = null;
|
||||
String moduleName = null;
|
||||
if (man != null) {
|
||||
attrs = man.getMainAttributes();
|
||||
if (attrs != null) {
|
||||
moduleName = attrs.getValue(AUTOMATIC_MODULE_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
// Derive the version, and the module name if needed, from JAR file name
|
||||
String fn = jf.getName();
|
||||
int i = fn.lastIndexOf(File.separator);
|
||||
if (i != -1)
|
||||
fn = fn.substring(i+1);
|
||||
fn = fn.substring(i + 1);
|
||||
|
||||
// drop .jar
|
||||
String mn = fn.substring(0, fn.length()-4);
|
||||
// drop ".jar"
|
||||
String name = fn.substring(0, fn.length() - 4);
|
||||
String vs = null;
|
||||
|
||||
// find first occurrence of -${NUMBER}. or -${NUMBER}$
|
||||
Matcher matcher = Patterns.DASH_VERSION.matcher(mn);
|
||||
Matcher matcher = Patterns.DASH_VERSION.matcher(name);
|
||||
if (matcher.find()) {
|
||||
int start = matcher.start();
|
||||
|
||||
// attempt to parse the tail as a version string
|
||||
try {
|
||||
String tail = mn.substring(start+1);
|
||||
String tail = name.substring(start + 1);
|
||||
ModuleDescriptor.Version.parse(tail);
|
||||
vs = tail;
|
||||
} catch (IllegalArgumentException ignore) { }
|
||||
|
||||
mn = mn.substring(0, start);
|
||||
name = name.substring(0, start);
|
||||
}
|
||||
|
||||
// finally clean up the module name
|
||||
mn = cleanModuleName(mn);
|
||||
// Create builder, using the name derived from file name when
|
||||
// Automatic-Module-Name not present
|
||||
Builder builder;
|
||||
if (moduleName != null) {
|
||||
try {
|
||||
builder = ModuleDescriptor.newAutomaticModule(moduleName);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new FindException(AUTOMATIC_MODULE_NAME + ": " + e.getMessage());
|
||||
}
|
||||
} else {
|
||||
builder = ModuleDescriptor.newAutomaticModule(cleanModuleName(name));
|
||||
}
|
||||
|
||||
// Builder throws IAE if module name is empty or invalid
|
||||
ModuleDescriptor.Builder builder = ModuleDescriptor.newAutomaticModule(mn);
|
||||
// module version if present
|
||||
if (vs != null)
|
||||
builder.version(vs);
|
||||
|
||||
@ -541,9 +565,7 @@ public class ModulePath implements ModuleFinder {
|
||||
}
|
||||
|
||||
// Main-Class attribute if it exists
|
||||
Manifest man = jf.getManifest();
|
||||
if (man != null) {
|
||||
Attributes attrs = man.getMainAttributes();
|
||||
if (attrs != null) {
|
||||
String mainClass = attrs.getValue(Attributes.Name.MAIN_CLASS);
|
||||
if (mainClass != null) {
|
||||
mainClass = mainClass.replace("/", ".");
|
||||
|
@ -41,6 +41,10 @@ import java.util.function.Supplier;
|
||||
|
||||
public class ModuleReferenceImpl extends ModuleReference {
|
||||
|
||||
// location of module
|
||||
private final URI location;
|
||||
|
||||
// the module reader
|
||||
private final Supplier<ModuleReader> readerSupplier;
|
||||
|
||||
// non-null if the module is patched
|
||||
@ -74,6 +78,7 @@ public class ModuleReferenceImpl extends ModuleReference {
|
||||
ModuleResolution moduleResolution)
|
||||
{
|
||||
super(descriptor, Objects.requireNonNull(location));
|
||||
this.location = location;
|
||||
this.readerSupplier = readerSupplier;
|
||||
this.patcher = patcher;
|
||||
this.target = target;
|
||||
@ -148,7 +153,7 @@ public class ModuleReferenceImpl extends ModuleReference {
|
||||
int hc = hash;
|
||||
if (hc == 0) {
|
||||
hc = descriptor().hashCode();
|
||||
hc = 43 * hc + Objects.hashCode(location());
|
||||
hc = 43 * hc + Objects.hashCode(location);
|
||||
hc = 43 * hc + Objects.hashCode(patcher);
|
||||
if (hc == 0)
|
||||
hc = -1;
|
||||
@ -169,7 +174,7 @@ public class ModuleReferenceImpl extends ModuleReference {
|
||||
// when the modules have equal module descriptors, are at the
|
||||
// same location, and are patched by the same patcher.
|
||||
return Objects.equals(this.descriptor(), that.descriptor())
|
||||
&& Objects.equals(this.location(), that.location())
|
||||
&& Objects.equals(this.location, that.location)
|
||||
&& Objects.equals(this.patcher, that.patcher);
|
||||
}
|
||||
|
||||
@ -179,7 +184,7 @@ public class ModuleReferenceImpl extends ModuleReference {
|
||||
sb.append("[module ");
|
||||
sb.append(descriptor().name());
|
||||
sb.append(", location=");
|
||||
sb.append(location().orElseThrow(() -> new InternalError()));
|
||||
sb.append(location);
|
||||
if (isPatched()) sb.append(" (patched)");
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
|
@ -136,10 +136,12 @@ public class Modules {
|
||||
public static void addProvides(Module m, Class<?> service, Class<?> impl) {
|
||||
ModuleLayer layer = m.getLayer();
|
||||
|
||||
if (layer == null || layer == ModuleLayer.boot()) {
|
||||
PrivilegedAction<ClassLoader> pa = m::getClassLoader;
|
||||
ClassLoader loader = AccessController.doPrivileged(pa);
|
||||
|
||||
ClassLoader platformClassLoader = ClassLoaders.platformClassLoader();
|
||||
if (layer == null || loader == null || loader == platformClassLoader) {
|
||||
// update ClassLoader catalog
|
||||
PrivilegedAction<ClassLoader> pa = m::getClassLoader;
|
||||
ClassLoader loader = AccessController.doPrivileged(pa);
|
||||
ServicesCatalog catalog;
|
||||
if (loader == null) {
|
||||
catalog = BootLoader.getServicesCatalog();
|
||||
|
@ -26,6 +26,9 @@
|
||||
package jdk.internal.module;
|
||||
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* SystemModules class will be generated at link time to create
|
||||
@ -57,8 +60,7 @@ public final class SystemModules {
|
||||
public static int PACKAGES_IN_BOOT_LAYER = 1024;
|
||||
|
||||
/**
|
||||
* @return {@code false} if there are no split packages in the run-time
|
||||
* image, {@code true} if there are or if it's not been checked.
|
||||
* Return true if there are no split packages in the run-time image.
|
||||
*/
|
||||
public static boolean hasSplitPackages() {
|
||||
return true;
|
||||
@ -98,4 +100,20 @@ public final class SystemModules {
|
||||
public static ModuleResolution[] moduleResolutions() {
|
||||
throw new InternalError("expected to be overridden at link time");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the map of module concealed packages to open. The map key is the
|
||||
* module name, the value is the set of concealed packages to open.
|
||||
*/
|
||||
public static Map<String, Set<String>> concealedPackagesToOpen() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the map of module exported packages to open. The map key is the
|
||||
* module name, the value is the set of exported packages to open.
|
||||
*/
|
||||
public static Map<String, Set<String>> exportedPackagesToOpen() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -129,37 +129,6 @@ module java.base {
|
||||
exports javax.security.cert;
|
||||
|
||||
|
||||
// the service types defined by the APIs in this module
|
||||
|
||||
uses java.lang.System.LoggerFinder;
|
||||
uses java.net.ContentHandlerFactory;
|
||||
uses java.net.spi.URLStreamHandlerProvider;
|
||||
uses java.nio.channels.spi.AsynchronousChannelProvider;
|
||||
uses java.nio.channels.spi.SelectorProvider;
|
||||
uses java.nio.charset.spi.CharsetProvider;
|
||||
uses java.nio.file.spi.FileSystemProvider;
|
||||
uses java.nio.file.spi.FileTypeDetector;
|
||||
uses java.security.Provider;
|
||||
uses java.text.spi.BreakIteratorProvider;
|
||||
uses java.text.spi.CollatorProvider;
|
||||
uses java.text.spi.DateFormatProvider;
|
||||
uses java.text.spi.DateFormatSymbolsProvider;
|
||||
uses java.text.spi.DecimalFormatSymbolsProvider;
|
||||
uses java.text.spi.NumberFormatProvider;
|
||||
uses java.time.chrono.AbstractChronology;
|
||||
uses java.time.chrono.Chronology;
|
||||
uses java.time.zone.ZoneRulesProvider;
|
||||
uses java.util.spi.CalendarDataProvider;
|
||||
uses java.util.spi.CalendarNameProvider;
|
||||
uses java.util.spi.CurrencyNameProvider;
|
||||
uses java.util.spi.LocaleNameProvider;
|
||||
uses java.util.spi.ResourceBundleControlProvider;
|
||||
uses java.util.spi.ResourceBundleProvider;
|
||||
uses java.util.spi.TimeZoneNameProvider;
|
||||
uses java.util.spi.ToolProvider;
|
||||
uses javax.security.auth.spi.LoginModule;
|
||||
|
||||
|
||||
// additional qualified exports may be inserted at build time
|
||||
// see make/gensrc/GenModuleInfo.gmk
|
||||
|
||||
@ -192,11 +161,6 @@ module java.base {
|
||||
jdk.scripting.nashorn;
|
||||
exports jdk.internal.math to
|
||||
java.desktop;
|
||||
exports jdk.internal.module to
|
||||
java.instrument,
|
||||
java.management.rmi,
|
||||
jdk.jartool,
|
||||
jdk.jlink;
|
||||
exports jdk.internal.misc to
|
||||
java.desktop,
|
||||
java.logging,
|
||||
@ -218,6 +182,11 @@ module java.base {
|
||||
jdk.scripting.nashorn.shell,
|
||||
jdk.unsupported,
|
||||
jdk.internal.vm.ci;
|
||||
exports jdk.internal.module to
|
||||
java.instrument,
|
||||
java.management.rmi,
|
||||
jdk.jartool,
|
||||
jdk.jlink;
|
||||
exports jdk.internal.perf to
|
||||
java.desktop,
|
||||
java.management,
|
||||
@ -233,6 +202,9 @@ module java.base {
|
||||
jdk.dynalink,
|
||||
jdk.scripting.nashorn,
|
||||
jdk.unsupported;
|
||||
exports jdk.internal.vm to
|
||||
jdk.management.agent,
|
||||
jdk.internal.jvmstat;
|
||||
exports jdk.internal.vm.annotation to
|
||||
jdk.unsupported,
|
||||
jdk.internal.vm.ci,
|
||||
@ -241,9 +213,6 @@ module java.base {
|
||||
jdk.jartool,
|
||||
jdk.jdeps,
|
||||
jdk.jlink;
|
||||
exports jdk.internal.vm to
|
||||
jdk.management.agent,
|
||||
jdk.internal.jvmstat;
|
||||
exports sun.net to
|
||||
jdk.incubator.httpclient;
|
||||
exports sun.net.ext to
|
||||
@ -253,7 +222,8 @@ module java.base {
|
||||
jdk.naming.dns;
|
||||
exports sun.net.util to
|
||||
java.desktop,
|
||||
jdk.jconsole;
|
||||
jdk.jconsole,
|
||||
jdk.incubator.httpclient;
|
||||
exports sun.net.www to
|
||||
java.desktop,
|
||||
jdk.incubator.httpclient,
|
||||
@ -349,7 +319,39 @@ module java.base {
|
||||
exports sun.util.resources to
|
||||
jdk.localedata;
|
||||
|
||||
|
||||
// the service types defined by the APIs in this module
|
||||
|
||||
uses java.lang.System.LoggerFinder;
|
||||
uses java.net.ContentHandlerFactory;
|
||||
uses java.net.spi.URLStreamHandlerProvider;
|
||||
uses java.nio.channels.spi.AsynchronousChannelProvider;
|
||||
uses java.nio.channels.spi.SelectorProvider;
|
||||
uses java.nio.charset.spi.CharsetProvider;
|
||||
uses java.nio.file.spi.FileSystemProvider;
|
||||
uses java.nio.file.spi.FileTypeDetector;
|
||||
uses java.security.Provider;
|
||||
uses java.text.spi.BreakIteratorProvider;
|
||||
uses java.text.spi.CollatorProvider;
|
||||
uses java.text.spi.DateFormatProvider;
|
||||
uses java.text.spi.DateFormatSymbolsProvider;
|
||||
uses java.text.spi.DecimalFormatSymbolsProvider;
|
||||
uses java.text.spi.NumberFormatProvider;
|
||||
uses java.time.chrono.AbstractChronology;
|
||||
uses java.time.chrono.Chronology;
|
||||
uses java.time.zone.ZoneRulesProvider;
|
||||
uses java.util.spi.CalendarDataProvider;
|
||||
uses java.util.spi.CalendarNameProvider;
|
||||
uses java.util.spi.CurrencyNameProvider;
|
||||
uses java.util.spi.LocaleNameProvider;
|
||||
uses java.util.spi.ResourceBundleControlProvider;
|
||||
uses java.util.spi.ResourceBundleProvider;
|
||||
uses java.util.spi.TimeZoneNameProvider;
|
||||
uses java.util.spi.ToolProvider;
|
||||
uses javax.security.auth.spi.LoginModule;
|
||||
|
||||
// JDK-internal service types
|
||||
|
||||
uses jdk.internal.logger.DefaultLoggerFinder;
|
||||
uses sun.security.ssl.ClientKeyExchangeService;
|
||||
uses sun.text.spi.JavaTimeDateTimePatternProvider;
|
||||
@ -358,7 +360,6 @@ module java.base {
|
||||
uses sun.util.resources.LocaleData.CommonResourceBundleProvider;
|
||||
uses sun.util.resources.LocaleData.SupplementaryResourceBundleProvider;
|
||||
|
||||
|
||||
// Built-in service providers that are located via ServiceLoader
|
||||
|
||||
provides java.nio.file.spi.FileSystemProvider with
|
||||
|
@ -92,7 +92,6 @@ import jdk.internal.misc.VM;
|
||||
import jdk.internal.module.ModuleBootstrap;
|
||||
import jdk.internal.module.Modules;
|
||||
|
||||
|
||||
public final class LauncherHelper {
|
||||
|
||||
// No instantiation
|
||||
@ -488,16 +487,16 @@ public final class LauncherHelper {
|
||||
if (s.length == 2) {
|
||||
String mn = s[0];
|
||||
String pn = s[1];
|
||||
|
||||
ModuleLayer.boot().findModule(mn).ifPresent(m -> {
|
||||
if (m.getDescriptor().packages().contains(pn)) {
|
||||
ModuleLayer.boot()
|
||||
.findModule(mn)
|
||||
.filter(m -> m.getDescriptor().packages().contains(pn))
|
||||
.ifPresent(m -> {
|
||||
if (open) {
|
||||
Modules.addOpensToAllUnnamed(m, pn);
|
||||
} else {
|
||||
Modules.addExportsToAllUnnamed(m, pn);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -614,7 +613,7 @@ public final class LauncherHelper {
|
||||
}
|
||||
} catch (LinkageError le) {
|
||||
abort(null, "java.launcher.module.error3", mainClass, m.getName(),
|
||||
le.getClass().getName() + ": " + le.getLocalizedMessage());
|
||||
le.getClass().getName() + ": " + le.getLocalizedMessage());
|
||||
}
|
||||
if (c == null) {
|
||||
abort(null, "java.launcher.module.error2", mainClass, mainModule);
|
||||
@ -715,7 +714,7 @@ public final class LauncherHelper {
|
||||
mainClass.getName(), mainClass.getModule(),
|
||||
e.getClass().getName(), e.getLocalizedMessage());
|
||||
} else {
|
||||
abort(e,"java.launcher.cls.error7", mainClass.getName(),
|
||||
abort(e, "java.launcher.cls.error7", mainClass.getName(),
|
||||
e.getClass().getName(), e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ java.launcher.opt.footer = \
|
||||
\ ALL-MODULE-PATH.\n\
|
||||
\ --list-modules\n\
|
||||
\ list observable modules and exit\n\
|
||||
\ --d <module name>\n\
|
||||
\ -d <module name>\n\
|
||||
\ --describe-module <module name>\n\
|
||||
\ describe a module and exit\n\
|
||||
\ --dry-run create VM and load main class but do not execute main method.\n\
|
||||
@ -165,10 +165,11 @@ java.launcher.X.usage=\n\
|
||||
\ --add-opens <module>/<package>=<target-module>(,<target-module>)*\n\
|
||||
\ updates <module> to open <package> to\n\
|
||||
\ <target-module>, regardless of module declaration.\n\
|
||||
\ --permit-illegal-access\n\
|
||||
\ permit illegal access to members of types in named modules\n\
|
||||
\ by code in unnamed modules. This compatibility option will\n\
|
||||
\ be removed in the next release.\n\
|
||||
\ --illegal-access=<value>\n\
|
||||
\ permit or deny access to members of types in named modules\n\
|
||||
\ by code in unnamed modules.\n\
|
||||
\ <value> is one of "deny", "permit", "warn", or "debug"\n\
|
||||
\ This option will be removed in a future release.\n\
|
||||
\ --limit-modules <module name>[,<module name>...]\n\
|
||||
\ limit the universe of observable modules\n\
|
||||
\ --patch-module <module>=<file>({0}<file>)*\n\
|
||||
|
@ -2408,9 +2408,9 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
||||
{ 0x3081000201033081L, 0x0006092A864886F7L, 0x0D010701A0810004L },
|
||||
{ 0x3082000002010330L, 0x810006092A864886L, 0xF70D010701A08100L },
|
||||
{ 0x3083000000020103L, 0x3082000006092A86L, 0x4886F70D010701A0L },
|
||||
{ 0x3083000000020103L, 0x308200000006092AL, 0x864886F70D010701L },
|
||||
{ 0x3084000000000201L, 0x0330820000000609L, 0x2A864886F70D0107L },
|
||||
{ 0x3084000000000201L, 0x0330820000000006L, 0x092A864886F70D01L }
|
||||
{ 0x3083000000020103L, 0x308300000006092AL, 0x864886F70D010701L },
|
||||
{ 0x3084000000000201L, 0x0330830000000609L, 0x2A864886F70D0107L },
|
||||
{ 0x3084000000000201L, 0x0330840000000006L, 0x092A864886F70D01L }
|
||||
};
|
||||
|
||||
private static final long[][] PKCS12_HEADER_MASKS = {
|
||||
|
@ -20,9 +20,6 @@ grant codeBase "jrt:/java.corba" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
||||
grant codeBase "jrt:/jdk.incubator.httpclient" {
|
||||
};
|
||||
|
||||
grant codeBase "jrt:/java.scripting" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
@ -69,17 +66,7 @@ grant codeBase "jrt:/java.sql.rowset" {
|
||||
};
|
||||
|
||||
grant codeBase "jrt:/java.xml.bind" {
|
||||
permission java.lang.RuntimePermission
|
||||
"accessClassInPackage.sun.misc";
|
||||
permission java.lang.RuntimePermission
|
||||
"accessClassInPackage.com.sun.xml.internal.*";
|
||||
permission java.lang.RuntimePermission
|
||||
"accessClassInPackage.com.sun.istack.internal";
|
||||
permission java.lang.RuntimePermission
|
||||
"accessClassInPackage.com.sun.istack.internal.*";
|
||||
permission java.lang.RuntimePermission "accessDeclaredMembers";
|
||||
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
|
||||
permission java.util.PropertyPermission "*", "read";
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
||||
grant codeBase "jrt:/java.xml.crypto" {
|
||||
@ -104,19 +91,11 @@ grant codeBase "jrt:/java.xml.crypto" {
|
||||
};
|
||||
|
||||
grant codeBase "jrt:/java.xml.ws" {
|
||||
permission java.net.NetPermission
|
||||
"getProxySelector";
|
||||
permission java.lang.RuntimePermission
|
||||
"accessClassInPackage.sun.misc";
|
||||
permission java.lang.RuntimePermission
|
||||
"accessClassInPackage.com.sun.xml.internal.*";
|
||||
permission java.lang.RuntimePermission
|
||||
"accessClassInPackage.com.sun.istack.internal";
|
||||
permission java.lang.RuntimePermission
|
||||
"accessClassInPackage.com.sun.istack.internal.*";
|
||||
permission java.lang.RuntimePermission "accessDeclaredMembers";
|
||||
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
|
||||
permission java.util.PropertyPermission "*", "read";
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
||||
grant codeBase "jrt:/jdk.accessibility" {
|
||||
permission java.lang.RuntimePermission "accessClassInPackage.sun.awt";
|
||||
};
|
||||
|
||||
grant codeBase "jrt:/jdk.charsets" {
|
||||
@ -155,6 +134,10 @@ grant codeBase "jrt:/jdk.crypto.cryptoki" {
|
||||
permission java.io.FilePermission "<<ALL FILES>>", "read";
|
||||
};
|
||||
|
||||
grant codeBase "jrt:/jdk.desktop" {
|
||||
permission java.lang.RuntimePermission "accessClassInPackage.com.sun.awt";
|
||||
};
|
||||
|
||||
grant codeBase "jrt:/jdk.dynalink" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
@ -163,6 +146,10 @@ grant codeBase "jrt:/jdk.internal.le" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
||||
grant codeBase "jrt:/jdk.internal.vm.compiler" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
||||
grant codeBase "jrt:/jdk.jsobject" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
@ -198,14 +185,6 @@ grant codeBase "jrt:/jdk.zipfs" {
|
||||
permission java.util.PropertyPermission "os.name", "read";
|
||||
};
|
||||
|
||||
grant codeBase "jrt:/jdk.accessibility" {
|
||||
permission java.lang.RuntimePermission "accessClassInPackage.sun.awt";
|
||||
};
|
||||
|
||||
grant codeBase "jrt:/jdk.desktop" {
|
||||
permission java.lang.RuntimePermission "accessClassInPackage.com.sun.awt";
|
||||
};
|
||||
|
||||
// permissions needed by applications using java.desktop module
|
||||
grant {
|
||||
permission java.lang.RuntimePermission "accessClassInPackage.com.sun.beans";
|
||||
@ -213,7 +192,3 @@ grant {
|
||||
permission java.lang.RuntimePermission "accessClassInPackage.com.sun.java.swing.plaf.*";
|
||||
permission java.lang.RuntimePermission "accessClassInPackage.com.apple.*";
|
||||
};
|
||||
|
||||
grant codeBase "jrt:/jdk.internal.vm.compiler" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2017, 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
|
||||
@ -455,14 +455,6 @@ JVM_AddModuleExportsToAll(JNIEnv *env, jobject from_module, const char* package)
|
||||
JNIEXPORT void JNICALL
|
||||
JVM_AddReadsModule(JNIEnv *env, jobject from_module, jobject source_module);
|
||||
|
||||
/*
|
||||
* Add a package to a module.
|
||||
* module: module that will contain the package
|
||||
* package: package to add to the module
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
JVM_AddModulePackage(JNIEnv* env, jobject module, const char* package);
|
||||
|
||||
/*
|
||||
* Reflection support functions
|
||||
*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2017, 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
|
||||
@ -176,23 +176,3 @@ Java_java_lang_Module_addExportsToAllUnnamed0(JNIEnv *env, jclass cls,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_java_lang_Module_addPackage0(JNIEnv *env, jclass cls, jobject m, jstring pkg)
|
||||
{
|
||||
char buf[128];
|
||||
char* pkg_name;
|
||||
|
||||
if (pkg == NULL) {
|
||||
JNU_ThrowNullPointerException(env, "package is null");
|
||||
return;
|
||||
}
|
||||
|
||||
pkg_name = GetInternalPackageName(env, pkg, buf, (jsize)sizeof(buf));
|
||||
if (pkg_name != NULL) {
|
||||
JVM_AddModulePackage(env, m, pkg_name);
|
||||
if (pkg_name != buf) {
|
||||
free(pkg_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2017, 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
|
||||
@ -25,29 +25,26 @@
|
||||
|
||||
package java.awt.datatransfer;
|
||||
|
||||
import sun.datatransfer.DataFlavorUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.Arrays;
|
||||
|
||||
import java.io.IOException;
|
||||
import sun.datatransfer.DataFlavorUtil;
|
||||
|
||||
/**
|
||||
* A class that implements a mechanism to transfer data using
|
||||
* cut/copy/paste operations.
|
||||
* A class that implements a mechanism to transfer data using cut/copy/paste
|
||||
* operations.
|
||||
* <p>
|
||||
* {@link FlavorListener}s may be registered on an instance of the
|
||||
* Clipboard class to be notified about changes to the set of
|
||||
* {@link DataFlavor}s available on this clipboard (see
|
||||
* {@link #addFlavorListener}).
|
||||
* {@link FlavorListener}s may be registered on an instance of the Clipboard
|
||||
* class to be notified about changes to the set of {@link DataFlavor}s
|
||||
* available on this clipboard (see {@link #addFlavorListener}).
|
||||
*
|
||||
* @author Amy Fowler
|
||||
* @author Alexander Gerasimov
|
||||
* @see java.awt.Toolkit#getSystemClipboard
|
||||
* @see java.awt.Toolkit#getSystemSelection
|
||||
*
|
||||
* @author Amy Fowler
|
||||
* @author Alexander Gerasimov
|
||||
* @since 1.1
|
||||
*/
|
||||
public class Clipboard {
|
||||
@ -58,6 +55,7 @@ public class Clipboard {
|
||||
* The owner of the clipboard.
|
||||
*/
|
||||
protected ClipboardOwner owner;
|
||||
|
||||
/**
|
||||
* Contents of the clipboard.
|
||||
*/
|
||||
@ -71,9 +69,9 @@ public class Clipboard {
|
||||
private Set<FlavorListener> flavorListeners;
|
||||
|
||||
/**
|
||||
* A set of <code>DataFlavor</code>s that is available on
|
||||
* this local clipboard. It is used for tracking changes
|
||||
* of <code>DataFlavor</code>s available on this clipboard.
|
||||
* A set of {@code DataFlavor}s that is available on this local clipboard.
|
||||
* It is used for tracking changes of {@code DataFlavor}s available on this
|
||||
* clipboard.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
@ -81,7 +79,8 @@ public class Clipboard {
|
||||
|
||||
/**
|
||||
* Creates a clipboard object.
|
||||
* @param name for the clipboard
|
||||
*
|
||||
* @param name for the clipboard
|
||||
* @see java.awt.Toolkit#getSystemClipboard
|
||||
*/
|
||||
public Clipboard(String name) {
|
||||
@ -90,8 +89,8 @@ public class Clipboard {
|
||||
|
||||
/**
|
||||
* Returns the name of this clipboard object.
|
||||
* @return the name of this clipboard object
|
||||
*
|
||||
* @return the name of this clipboard object
|
||||
* @see java.awt.Toolkit#getSystemClipboard
|
||||
*/
|
||||
public String getName() {
|
||||
@ -99,27 +98,25 @@ public class Clipboard {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current contents of the clipboard to the specified
|
||||
* transferable object and registers the specified clipboard owner
|
||||
* as the owner of the new contents.
|
||||
* Sets the current contents of the clipboard to the specified transferable
|
||||
* object and registers the specified clipboard owner as the owner of the
|
||||
* new contents.
|
||||
* <p>
|
||||
* If there is an existing owner different from the argument
|
||||
* <code>owner</code>, that owner is notified that it no longer
|
||||
* holds ownership of the clipboard contents via an invocation
|
||||
* of <code>ClipboardOwner.lostOwnership()</code> on that owner.
|
||||
* An implementation of <code>setContents()</code> is free not
|
||||
* to invoke <code>lostOwnership()</code> directly from this method.
|
||||
* For example, <code>lostOwnership()</code> may be invoked later on
|
||||
* a different thread. The same applies to <code>FlavorListener</code>s
|
||||
* registered on this clipboard.
|
||||
* If there is an existing owner different from the argument {@code owner},
|
||||
* that owner is notified that it no longer holds ownership of the clipboard
|
||||
* contents via an invocation of {@code ClipboardOwner.lostOwnership()} on
|
||||
* that owner. An implementation of {@code setContents()} is free not to
|
||||
* invoke {@code lostOwnership()} directly from this method. For example,
|
||||
* {@code lostOwnership()} may be invoked later on a different thread. The
|
||||
* same applies to {@code FlavorListener}s registered on this clipboard.
|
||||
* <p>
|
||||
* The method throws <code>IllegalStateException</code> if the clipboard
|
||||
* is currently unavailable. For example, on some platforms, the system
|
||||
* The method throws {@code IllegalStateException} if the clipboard is
|
||||
* currently unavailable. For example, on some platforms, the system
|
||||
* clipboard is unavailable while it is accessed by another application.
|
||||
*
|
||||
* @param contents the transferable object representing the
|
||||
* clipboard content
|
||||
* @param owner the object which owns the clipboard content
|
||||
* @param contents the transferable object representing the clipboard
|
||||
* content
|
||||
* @param owner the object which owns the clipboard content
|
||||
* @throws IllegalStateException if the clipboard is currently unavailable
|
||||
* @see java.awt.Toolkit#getSystemClipboard
|
||||
*/
|
||||
@ -138,15 +135,14 @@ public class Clipboard {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a transferable object representing the current contents
|
||||
* of the clipboard. If the clipboard currently has no contents,
|
||||
* it returns <code>null</code>. The parameter Object requestor is
|
||||
* not currently used. The method throws
|
||||
* <code>IllegalStateException</code> if the clipboard is currently
|
||||
* unavailable. For example, on some platforms, the system clipboard is
|
||||
* Returns a transferable object representing the current contents of the
|
||||
* clipboard. If the clipboard currently has no contents, it returns
|
||||
* {@code null}. The parameter Object requestor is not currently used. The
|
||||
* method throws {@code IllegalStateException} if the clipboard is currently
|
||||
* unavailable. For example, on some platforms, the system clipboard is
|
||||
* unavailable while it is accessed by another application.
|
||||
*
|
||||
* @param requestor the object requesting the clip data (not used)
|
||||
* @param requestor the object requesting the clip data (not used)
|
||||
* @return the current transferable object on the clipboard
|
||||
* @throws IllegalStateException if the clipboard is currently unavailable
|
||||
* @see java.awt.Toolkit#getSystemClipboard
|
||||
@ -155,18 +151,14 @@ public class Clipboard {
|
||||
return contents;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of <code>DataFlavor</code>s in which the current
|
||||
* contents of this clipboard can be provided. If there are no
|
||||
* <code>DataFlavor</code>s available, this method returns a zero-length
|
||||
* array.
|
||||
*
|
||||
* @return an array of <code>DataFlavor</code>s in which the current
|
||||
* contents of this clipboard can be provided
|
||||
* Returns an array of {@code DataFlavor}s in which the current contents of
|
||||
* this clipboard can be provided. If there are no {@code DataFlavor}s
|
||||
* available, this method returns a zero-length array.
|
||||
*
|
||||
* @return an array of {@code DataFlavor}s in which the current contents of
|
||||
* this clipboard can be provided
|
||||
* @throws IllegalStateException if this clipboard is currently unavailable
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public DataFlavor[] getAvailableDataFlavors() {
|
||||
@ -179,17 +171,14 @@ public class Clipboard {
|
||||
|
||||
/**
|
||||
* Returns whether or not the current contents of this clipboard can be
|
||||
* provided in the specified <code>DataFlavor</code>.
|
||||
* provided in the specified {@code DataFlavor}.
|
||||
*
|
||||
* @param flavor the requested <code>DataFlavor</code> for the contents
|
||||
*
|
||||
* @return <code>true</code> if the current contents of this clipboard
|
||||
* can be provided in the specified <code>DataFlavor</code>;
|
||||
* <code>false</code> otherwise
|
||||
*
|
||||
* @throws NullPointerException if <code>flavor</code> is <code>null</code>
|
||||
* @param flavor the requested {@code DataFlavor} for the contents
|
||||
* @return {@code true} if the current contents of this clipboard can be
|
||||
* provided in the specified {@code DataFlavor}; {@code false}
|
||||
* otherwise
|
||||
* @throws NullPointerException if {@code flavor} is {@code null}
|
||||
* @throws IllegalStateException if this clipboard is currently unavailable
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public boolean isDataFlavorAvailable(DataFlavor flavor) {
|
||||
@ -205,25 +194,20 @@ public class Clipboard {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object representing the current contents of this clipboard
|
||||
* in the specified <code>DataFlavor</code>.
|
||||
* The class of the object returned is defined by the representation
|
||||
* class of <code>flavor</code>.
|
||||
* Returns an object representing the current contents of this clipboard in
|
||||
* the specified {@code DataFlavor}. The class of the object returned is
|
||||
* defined by the representation class of {@code flavor}.
|
||||
*
|
||||
* @param flavor the requested <code>DataFlavor</code> for the contents
|
||||
*
|
||||
* @return an object representing the current contents of this clipboard
|
||||
* in the specified <code>DataFlavor</code>
|
||||
*
|
||||
* @throws NullPointerException if <code>flavor</code> is <code>null</code>
|
||||
* @param flavor the requested {@code DataFlavor} for the contents
|
||||
* @return an object representing the current contents of this clipboard in
|
||||
* the specified {@code DataFlavor}
|
||||
* @throws NullPointerException if {@code flavor} is {@code null}
|
||||
* @throws IllegalStateException if this clipboard is currently unavailable
|
||||
* @throws UnsupportedFlavorException if the requested <code>DataFlavor</code>
|
||||
* is not available
|
||||
* @throws IOException if the data in the requested <code>DataFlavor</code>
|
||||
* can not be retrieved
|
||||
*
|
||||
* @throws UnsupportedFlavorException if the requested {@code DataFlavor} is
|
||||
* not available
|
||||
* @throws IOException if the data in the requested {@code DataFlavor} can
|
||||
* not be retrieved
|
||||
* @see DataFlavor#getRepresentationClass
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public Object getData(DataFlavor flavor)
|
||||
@ -239,15 +223,12 @@ public class Clipboard {
|
||||
return cntnts.getTransferData(flavor);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Registers the specified <code>FlavorListener</code> to receive
|
||||
* <code>FlavorEvent</code>s from this clipboard.
|
||||
* If <code>listener</code> is <code>null</code>, no exception
|
||||
* is thrown and no action is performed.
|
||||
*
|
||||
* @param listener the listener to be added
|
||||
* Registers the specified {@code FlavorListener} to receive
|
||||
* {@code FlavorEvent}s from this clipboard. If {@code listener} is
|
||||
* {@code null}, no exception is thrown and no action is performed.
|
||||
*
|
||||
* @param listener the listener to be added
|
||||
* @see #removeFlavorListener
|
||||
* @see #getFlavorListeners
|
||||
* @see FlavorListener
|
||||
@ -268,16 +249,14 @@ public class Clipboard {
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified <code>FlavorListener</code> so that it no longer
|
||||
* receives <code>FlavorEvent</code>s from this <code>Clipboard</code>.
|
||||
* This method performs no function, nor does it throw an exception, if
|
||||
* the listener specified by the argument was not previously added to this
|
||||
* <code>Clipboard</code>.
|
||||
* If <code>listener</code> is <code>null</code>, no exception
|
||||
* is thrown and no action is performed.
|
||||
*
|
||||
* @param listener the listener to be removed
|
||||
* Removes the specified {@code FlavorListener} so that it no longer
|
||||
* receives {@code FlavorEvent}s from this {@code Clipboard}. This method
|
||||
* performs no function, nor does it throw an exception, if the listener
|
||||
* specified by the argument was not previously added to this
|
||||
* {@code Clipboard}. If {@code listener} is {@code null}, no exception is
|
||||
* thrown and no action is performed.
|
||||
*
|
||||
* @param listener the listener to be removed
|
||||
* @see #addFlavorListener
|
||||
* @see #getFlavorListeners
|
||||
* @see FlavorListener
|
||||
@ -292,11 +271,11 @@ public class Clipboard {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the <code>FlavorListener</code>s currently
|
||||
* registered on this <code>Clipboard</code>.
|
||||
* Returns an array of all the {@code FlavorListener}s currently registered
|
||||
* on this {@code Clipboard}.
|
||||
*
|
||||
* @return all of this clipboard's <code>FlavorListener</code>s or an empty
|
||||
* array if no listeners are currently registered
|
||||
* @return all of this clipboard's {@code FlavorListener}s or an empty array
|
||||
* if no listeners are currently registered
|
||||
* @see #addFlavorListener
|
||||
* @see #removeFlavorListener
|
||||
* @see FlavorListener
|
||||
@ -309,9 +288,9 @@ public class Clipboard {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks change of the <code>DataFlavor</code>s and, if necessary,
|
||||
* notifies all listeners that have registered interest for notification
|
||||
* on <code>FlavorEvent</code>s.
|
||||
* Checks change of the {@code DataFlavor}s and, if necessary, notifies all
|
||||
* listeners that have registered interest for notification on
|
||||
* {@code FlavorEvent}s.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
@ -331,12 +310,11 @@ public class Clipboard {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a set of <code>DataFlavor</code>s currently available
|
||||
* on this clipboard.
|
||||
*
|
||||
* @return a set of <code>DataFlavor</code>s currently available
|
||||
* on this clipboard
|
||||
* Returns a set of {@code DataFlavor}s currently available on this
|
||||
* clipboard.
|
||||
*
|
||||
* @return a set of {@code DataFlavor}s currently available on this
|
||||
* clipboard
|
||||
* @since 1.5
|
||||
*/
|
||||
private Set<DataFlavor> getAvailableDataFlavorSet() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2002, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2017, 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
|
||||
@ -26,32 +26,28 @@
|
||||
package java.awt.datatransfer;
|
||||
|
||||
/**
|
||||
* Defines the interface for classes that will provide data to
|
||||
* a clipboard. An instance of this interface becomes the owner
|
||||
* of the contents of a clipboard (clipboard owner) if it is
|
||||
* passed as an argument to
|
||||
* {@link java.awt.datatransfer.Clipboard#setContents} method of
|
||||
* the clipboard and this method returns successfully.
|
||||
* The instance remains the clipboard owner until another application
|
||||
* or another object within this application asserts ownership
|
||||
* of this clipboard.
|
||||
* Defines the interface for classes that will provide data to a clipboard. An
|
||||
* instance of this interface becomes the owner of the contents of a clipboard
|
||||
* (clipboard owner) if it is passed as an argument to
|
||||
* {@link Clipboard#setContents} method of the clipboard and this method returns
|
||||
* successfully. The instance remains the clipboard owner until another
|
||||
* application or another object within this application asserts ownership of
|
||||
* this clipboard.
|
||||
*
|
||||
* @see java.awt.datatransfer.Clipboard
|
||||
*
|
||||
* @author Amy Fowler
|
||||
* @author Amy Fowler
|
||||
* @see Clipboard
|
||||
* @since 1.1
|
||||
*/
|
||||
|
||||
public interface ClipboardOwner {
|
||||
|
||||
/**
|
||||
* Notifies this object that it is no longer the clipboard owner.
|
||||
* This method will be called when another application or another
|
||||
* object within this application asserts ownership of the clipboard.
|
||||
* Notifies this object that it is no longer the clipboard owner. This
|
||||
* method will be called when another application or another object within
|
||||
* this application asserts ownership of the clipboard.
|
||||
*
|
||||
* @param clipboard the clipboard that is no longer owned
|
||||
* @param contents the contents which this owner had placed on the clipboard
|
||||
* @param clipboard the clipboard that is no longer owned
|
||||
* @param contents the contents which this owner had placed on the
|
||||
* {@code clipboard}
|
||||
*/
|
||||
public void lostOwnership(Clipboard clipboard, Transferable contents);
|
||||
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2017, 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
|
||||
@ -22,29 +22,27 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.datatransfer;
|
||||
|
||||
import java.util.EventObject;
|
||||
|
||||
|
||||
/**
|
||||
* <code>FlavorEvent</code> is used to notify interested parties
|
||||
* that available {@link DataFlavor}s have changed in the
|
||||
* {@link Clipboard} (the event source).
|
||||
*
|
||||
* @see FlavorListener
|
||||
* {@code FlavorEvent} is used to notify interested parties that available
|
||||
* {@link DataFlavor}s have changed in the {@link Clipboard} (the event source).
|
||||
*
|
||||
* @author Alexander Gerasimov
|
||||
* @see FlavorListener
|
||||
* @since 1.5
|
||||
*/
|
||||
public class FlavorEvent extends EventObject {
|
||||
|
||||
private static final long serialVersionUID = -5842664112252414548L;
|
||||
|
||||
/**
|
||||
* Constructs a <code>FlavorEvent</code> object.
|
||||
*
|
||||
* @param source the <code>Clipboard</code> that is the source of the event
|
||||
* Constructs a {@code FlavorEvent} object.
|
||||
*
|
||||
* @param source the {@code Clipboard} that is the source of the event
|
||||
* @throws IllegalArgumentException if the {@code source} is {@code null}
|
||||
*/
|
||||
public FlavorEvent(Clipboard source) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2017, 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
|
||||
@ -22,11 +22,11 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.datatransfer;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
|
||||
/**
|
||||
* Defines an object which listens for {@link FlavorEvent}s.
|
||||
*
|
||||
@ -34,22 +34,21 @@ import java.util.EventListener;
|
||||
* @since 1.5
|
||||
*/
|
||||
public interface FlavorListener extends EventListener {
|
||||
|
||||
/**
|
||||
* Invoked when the target {@link Clipboard} of the listener
|
||||
* has changed its available {@link DataFlavor}s.
|
||||
* Invoked when the target {@link Clipboard} of the listener has changed its
|
||||
* available {@link DataFlavor}s.
|
||||
* <p>
|
||||
* Some notifications may be redundant — they are not
|
||||
* caused by a change of the set of DataFlavors available
|
||||
* on the clipboard.
|
||||
* For example, if the clipboard subsystem supposes that
|
||||
* the system clipboard's contents has been changed but it
|
||||
* can't ascertain whether its DataFlavors have been changed
|
||||
* because of some exceptional condition when accessing the
|
||||
* clipboard, the notification is sent to ensure from omitting
|
||||
* a significant notification. Ordinarily, those redundant
|
||||
* notifications should be occasional.
|
||||
* Some notifications may be redundant — they are not caused by a
|
||||
* change of the set of DataFlavors available on the clipboard. For example,
|
||||
* if the clipboard subsystem supposes that the system clipboard's contents
|
||||
* has been changed but it can't ascertain whether its DataFlavors have been
|
||||
* changed because of some exceptional condition when accessing the
|
||||
* clipboard, the notification is sent to ensure from omitting a significant
|
||||
* notification. Ordinarily, those redundant notifications should be
|
||||
* occasional.
|
||||
*
|
||||
* @param e a <code>FlavorEvent</code> object
|
||||
* @param e a {@code FlavorEvent} object
|
||||
*/
|
||||
void flavorsChanged(FlavorEvent e);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2017, 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,49 +27,45 @@ package java.awt.datatransfer;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* A two-way Map between "natives" (Strings), which correspond to platform-
|
||||
* specific data formats, and "flavors" (DataFlavors), which correspond to
|
||||
* platform-independent MIME types. FlavorMaps need not be symmetric, but
|
||||
* A two-way Map between "natives" (Strings), which correspond to
|
||||
* platform-specific data formats, and "flavors" (DataFlavors), which correspond
|
||||
* to platform-independent MIME types. FlavorMaps need not be symmetric, but
|
||||
* typically are.
|
||||
*
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
public interface FlavorMap {
|
||||
|
||||
/**
|
||||
* Returns a <code>Map</code> of the specified <code>DataFlavor</code>s to
|
||||
* their corresponding <code>String</code> native. The returned
|
||||
* <code>Map</code> is a modifiable copy of this <code>FlavorMap</code>'s
|
||||
* internal data. Client code is free to modify the <code>Map</code>
|
||||
* without affecting this object.
|
||||
* Returns a {@code Map} of the specified {@code DataFlavor}s to their
|
||||
* corresponding {@code String} native. The returned {@code Map} is a
|
||||
* modifiable copy of this {@code FlavorMap}'s internal data. Client code is
|
||||
* free to modify the {@code Map} without affecting this object.
|
||||
*
|
||||
* @param flavors an array of <code>DataFlavor</code>s which will be the
|
||||
* key set of the returned <code>Map</code>. If <code>null</code> is
|
||||
* specified, a mapping of all <code>DataFlavor</code>s currently
|
||||
* known to this <code>FlavorMap</code> to their corresponding
|
||||
* <code>String</code> natives will be returned.
|
||||
* @return a <code>java.util.Map</code> of <code>DataFlavor</code>s to
|
||||
* <code>String</code> natives
|
||||
* @param flavors an array of {@code DataFlavor}s which will be the key set
|
||||
* of the returned {@code Map}. If {@code null} is specified, a
|
||||
* mapping of all {@code DataFlavor}s currently known to this
|
||||
* {@code FlavorMap} to their corresponding {@code String} natives
|
||||
* will be returned.
|
||||
* @return a {@code java.util.Map} of {@code DataFlavor}s to {@code String}
|
||||
* natives
|
||||
*/
|
||||
Map<DataFlavor,String> getNativesForFlavors(DataFlavor[] flavors);
|
||||
Map<DataFlavor, String> getNativesForFlavors(DataFlavor[] flavors);
|
||||
|
||||
/**
|
||||
* Returns a <code>Map</code> of the specified <code>String</code> natives
|
||||
* to their corresponding <code>DataFlavor</code>. The returned
|
||||
* <code>Map</code> is a modifiable copy of this <code>FlavorMap</code>'s
|
||||
* internal data. Client code is free to modify the <code>Map</code>
|
||||
* without affecting this object.
|
||||
* Returns a {@code Map} of the specified {@code String} natives to their
|
||||
* corresponding {@code DataFlavor}. The returned {@code Map} is a
|
||||
* modifiable copy of this {@code FlavorMap}'s internal data. Client code is
|
||||
* free to modify the {@code Map} without affecting this object.
|
||||
*
|
||||
* @param natives an array of <code>String</code>s which will be the
|
||||
* key set of the returned <code>Map</code>. If <code>null</code> is
|
||||
* specified, a mapping of all <code>String</code> natives currently
|
||||
* known to this <code>FlavorMap</code> to their corresponding
|
||||
* <code>DataFlavor</code>s will be returned.
|
||||
* @return a <code>java.util.Map</code> of <code>String</code> natives to
|
||||
* <code>DataFlavor</code>s
|
||||
* @param natives an array of {@code String}s which will be the key set of
|
||||
* the returned {@code Map}. If {@code null} is specified, a mapping
|
||||
* of all {@code String} natives currently known to this
|
||||
* {@code FlavorMap} to their corresponding {@code DataFlavor}s will
|
||||
* be returned.
|
||||
* @return a {@code java.util.Map} of {@code String} natives to
|
||||
* {@code DataFlavor}s
|
||||
*/
|
||||
Map<String,DataFlavor> getFlavorsForNatives(String[] natives);
|
||||
Map<String, DataFlavor> getFlavorsForNatives(String[] natives);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2017, 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,56 +27,52 @@ package java.awt.datatransfer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* A FlavorMap which relaxes the traditional 1-to-1 restriction of a Map. A
|
||||
* flavor is permitted to map to any number of natives, and likewise a native
|
||||
* is permitted to map to any number of flavors. FlavorTables need not be
|
||||
* flavor is permitted to map to any number of natives, and likewise a native is
|
||||
* permitted to map to any number of flavors. FlavorTables need not be
|
||||
* symmetric, but typically are.
|
||||
*
|
||||
* @author David Mendenhall
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public interface FlavorTable extends FlavorMap {
|
||||
|
||||
/**
|
||||
* Returns a <code>List</code> of <code>String</code> natives to which the
|
||||
* specified <code>DataFlavor</code> corresponds. The <code>List</code>
|
||||
* will be sorted from best native to worst. That is, the first native will
|
||||
* best reflect data in the specified flavor to the underlying native
|
||||
* platform. The returned <code>List</code> is a modifiable copy of this
|
||||
* <code>FlavorTable</code>'s internal data. Client code is free to modify
|
||||
* the <code>List</code> without affecting this object.
|
||||
* Returns a {@code List} of {@code String} natives to which the specified
|
||||
* {@code DataFlavor} corresponds. The {@code List} will be sorted from best
|
||||
* native to worst. That is, the first native will best reflect data in the
|
||||
* specified flavor to the underlying native platform. The returned
|
||||
* {@code List} is a modifiable copy of this {@code FlavorTable}'s internal
|
||||
* data. Client code is free to modify the {@code List} without affecting
|
||||
* this object.
|
||||
*
|
||||
* @param flav the <code>DataFlavor</code> whose corresponding natives
|
||||
* should be returned. If <code>null</code> is specified, all
|
||||
* natives currently known to this <code>FlavorTable</code> are
|
||||
* returned in a non-deterministic order.
|
||||
* @return a <code>java.util.List</code> of <code>java.lang.String</code>
|
||||
* objects which are platform-specific representations of platform-
|
||||
* specific data formats
|
||||
* @param flav the {@code DataFlavor} whose corresponding natives should be
|
||||
* returned. If {@code null} is specified, all natives currently
|
||||
* known to this {@code FlavorTable} are returned in a
|
||||
* non-deterministic order.
|
||||
* @return a {@code java.util.List} of {@code java.lang.String} objects
|
||||
* which are platform-specific representations of platform-specific
|
||||
* data formats
|
||||
*/
|
||||
List<String> getNativesForFlavor(DataFlavor flav);
|
||||
|
||||
/**
|
||||
* Returns a <code>List</code> of <code>DataFlavor</code>s to which the
|
||||
* specified <code>String</code> corresponds. The <code>List</code> will be
|
||||
* sorted from best <code>DataFlavor</code> to worst. That is, the first
|
||||
* <code>DataFlavor</code> will best reflect data in the specified
|
||||
* native to a Java application. The returned <code>List</code> is a
|
||||
* modifiable copy of this <code>FlavorTable</code>'s internal data.
|
||||
* Client code is free to modify the <code>List</code> without affecting
|
||||
* this object.
|
||||
* Returns a {@code List} of {@code DataFlavor}s to which the specified
|
||||
* {@code String} corresponds. The {@code List} will be sorted from best
|
||||
* {@code DataFlavor} to worst. That is, the first {@code DataFlavor} will
|
||||
* best reflect data in the specified native to a Java application. The
|
||||
* returned {@code List} is a modifiable copy of this {@code FlavorTable}'s
|
||||
* internal data. Client code is free to modify the {@code List} without
|
||||
* affecting this object.
|
||||
*
|
||||
* @param nat the native whose corresponding <code>DataFlavor</code>s
|
||||
* should be returned. If <code>null</code> is specified, all
|
||||
* <code>DataFlavor</code>s currently known to this
|
||||
* <code>FlavorTable</code> are returned in a non-deterministic
|
||||
* order.
|
||||
* @return a <code>java.util.List</code> of <code>DataFlavor</code>
|
||||
* objects into which platform-specific data in the specified,
|
||||
* platform-specific native can be translated
|
||||
* @param nat the native whose corresponding {@code DataFlavor}s should be
|
||||
* returned. If {@code null} is specified, all {@code DataFlavor}s
|
||||
* currently known to this {@code FlavorTable} are returned in a
|
||||
* non-deterministic order.
|
||||
* @return a {@code java.util.List} of {@code DataFlavor} objects into which
|
||||
* platform-specific data in the specified, platform-specific native
|
||||
* can be translated
|
||||
*/
|
||||
List<DataFlavor> getFlavorsForNative(String nat);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2017, 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
|
||||
@ -26,20 +26,18 @@
|
||||
package java.awt.datatransfer;
|
||||
|
||||
import java.io.Externalizable;
|
||||
import java.io.ObjectOutput;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
import java.util.Locale;
|
||||
|
||||
|
||||
/**
|
||||
* A Multipurpose Internet Mail Extension (MIME) type, as defined
|
||||
* in RFC 2045 and 2046.
|
||||
*
|
||||
* THIS IS *NOT* - REPEAT *NOT* - A PUBLIC CLASS! DataFlavor IS
|
||||
* THE PUBLIC INTERFACE, AND THIS IS PROVIDED AS A ***PRIVATE***
|
||||
* (THAT IS AS IN *NOT* PUBLIC) HELPER CLASS!
|
||||
* A Multipurpose Internet Mail Extension (MIME) type, as defined in RFC 2045
|
||||
* and 2046.
|
||||
* <p>
|
||||
* THIS IS *NOT* - REPEAT *NOT* - A PUBLIC CLASS! DataFlavor IS THE PUBLIC
|
||||
* INTERFACE, AND THIS IS PROVIDED AS A ***PRIVATE*** (THAT IS AS IN *NOT*
|
||||
* PUBLIC) HELPER CLASS!
|
||||
*/
|
||||
class MimeType implements Externalizable, Cloneable {
|
||||
|
||||
@ -50,45 +48,45 @@ class MimeType implements Externalizable, Cloneable {
|
||||
static final long serialVersionUID = -6568722458793895906L;
|
||||
|
||||
/**
|
||||
* Constructor for externalization; this constructor should not be
|
||||
* called directly by an application, since the result will be an
|
||||
* uninitialized, immutable <code>MimeType</code> object.
|
||||
* Constructor for externalization; this constructor should not be called
|
||||
* directly by an application, since the result will be an uninitialized,
|
||||
* immutable {@code MimeType} object.
|
||||
*/
|
||||
public MimeType() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a <code>MimeType</code> from a <code>String</code>.
|
||||
* Builds a {@code MimeType} from a {@code String}.
|
||||
*
|
||||
* @param rawdata text used to initialize the <code>MimeType</code>
|
||||
* @throws NullPointerException if <code>rawdata</code> is null
|
||||
* @param rawdata text used to initialize the {@code MimeType}
|
||||
* @throws NullPointerException if {@code rawdata} is {@code null}
|
||||
*/
|
||||
public MimeType(String rawdata) throws MimeTypeParseException {
|
||||
parse(rawdata);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a <code>MimeType</code> with the given primary and sub
|
||||
* type but has an empty parameter list.
|
||||
* Builds a {@code MimeType} with the given primary and sub type but has an
|
||||
* empty parameter list.
|
||||
*
|
||||
* @param primary the primary type of this <code>MimeType</code>
|
||||
* @param sub the subtype of this <code>MimeType</code>
|
||||
* @throws NullPointerException if either <code>primary</code> or
|
||||
* <code>sub</code> is null
|
||||
* @param primary the primary type of this {@code MimeType}
|
||||
* @param sub the subtype of this {@code MimeType}
|
||||
* @throws NullPointerException if either {@code primary} or {@code sub} is
|
||||
* {@code null}
|
||||
*/
|
||||
public MimeType(String primary, String sub) throws MimeTypeParseException {
|
||||
this(primary, sub, new MimeTypeParameterList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a <code>MimeType</code> with a pre-defined
|
||||
* and valid (or empty) parameter list.
|
||||
* Builds a {@code MimeType} with a pre-defined and valid (or empty)
|
||||
* parameter list.
|
||||
*
|
||||
* @param primary the primary type of this <code>MimeType</code>
|
||||
* @param sub the subtype of this <code>MimeType</code>
|
||||
* @param mtpl the requested parameter list
|
||||
* @throws NullPointerException if either <code>primary</code>,
|
||||
* <code>sub</code> or <code>mtpl</code> is null
|
||||
* @param primary the primary type of this {@code MimeType}
|
||||
* @param sub the subtype of this {@code MimeType}
|
||||
* @param mtpl the requested parameter list
|
||||
* @throws NullPointerException if either {@code primary}, {@code sub} or
|
||||
* {@code mtpl} is {@code null}
|
||||
*/
|
||||
public MimeType(String primary, String sub, MimeTypeParameterList mtpl) throws
|
||||
MimeTypeParseException {
|
||||
@ -121,13 +119,12 @@ MimeTypeParseException {
|
||||
} // hashCode()
|
||||
|
||||
/**
|
||||
* <code>MimeType</code>s are equal if their primary types,
|
||||
* subtypes, and parameters are all equal. No default values
|
||||
* are taken into account.
|
||||
* @param thatObject the object to be evaluated as a
|
||||
* <code>MimeType</code>
|
||||
* @return <code>true</code> if <code>thatObject</code> is
|
||||
* a <code>MimeType</code>; otherwise returns <code>false</code>
|
||||
* {@code MimeType}s are equal if their primary types, subtypes, and
|
||||
* parameters are all equal. No default values are taken into account.
|
||||
*
|
||||
* @param thatObject the object to be evaluated as a {@code MimeType}
|
||||
* @return {@code true} if {@code thatObject} is a {@code MimeType};
|
||||
* otherwise returns {@code false}
|
||||
*/
|
||||
public boolean equals(Object thatObject) {
|
||||
if (!(thatObject instanceof MimeType)) {
|
||||
@ -144,7 +141,7 @@ MimeTypeParseException {
|
||||
/**
|
||||
* A routine for parsing the MIME type out of a String.
|
||||
*
|
||||
* @throws NullPointerException if <code>rawdata</code> is null
|
||||
* @throws NullPointerException if {@code rawdata} is {@code null}
|
||||
*/
|
||||
private void parse(String rawdata) throws MimeTypeParseException {
|
||||
int slashIndex = rawdata.indexOf('/');
|
||||
@ -213,8 +210,8 @@ MimeTypeParameterList(rawdata.substring(semIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the value associated with the given name, or null if there
|
||||
* is no current association.
|
||||
* Retrieve the value associated with the given name, or {@code null} if
|
||||
* there is no current association.
|
||||
*/
|
||||
public String getParameter(String name) {
|
||||
return parameters.get(name);
|
||||
@ -247,23 +244,21 @@ MimeTypeParameterList(rawdata.substring(semIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a String representation of this object
|
||||
* without the parameter list.
|
||||
* Return a String representation of this object without the parameter list.
|
||||
*/
|
||||
public String getBaseType() {
|
||||
return primaryType + "/" + subType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the primary type and the
|
||||
* subtype of this object are the same as the specified
|
||||
* <code>type</code>; otherwise returns <code>false</code>.
|
||||
* Returns {@code true} if the primary type and the subtype of this object
|
||||
* are the same as the specified {@code type}; otherwise returns
|
||||
* {@code false}.
|
||||
*
|
||||
* @param type the type to compare to <code>this</code>'s type
|
||||
* @return <code>true</code> if the primary type and the
|
||||
* subtype of this object are the same as the
|
||||
* specified <code>type</code>; otherwise returns
|
||||
* <code>false</code>
|
||||
* @param type the type to compare to {@code this}'s type
|
||||
* @return {@code true} if the primary type and the subtype of this object
|
||||
* are the same as the specified {@code type}; otherwise returns
|
||||
* {@code false}
|
||||
*/
|
||||
public boolean match(MimeType type) {
|
||||
if (type == null)
|
||||
@ -275,17 +270,15 @@ MimeTypeParameterList(rawdata.substring(semIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the primary type and the
|
||||
* subtype of this object are the same as the content type
|
||||
* described in <code>rawdata</code>; otherwise returns
|
||||
* <code>false</code>.
|
||||
* Returns {@code true} if the primary type and the subtype of this object
|
||||
* are the same as the content type described in {@code rawdata}; otherwise
|
||||
* returns {@code false}.
|
||||
*
|
||||
* @param rawdata the raw data to be examined
|
||||
* @return <code>true</code> if the primary type and the
|
||||
* subtype of this object are the same as the content type
|
||||
* described in <code>rawdata</code>; otherwise returns
|
||||
* <code>false</code>; if <code>rawdata</code> is
|
||||
* <code>null</code>, returns <code>false</code>
|
||||
* @param rawdata the raw data to be examined
|
||||
* @return {@code true} if the primary type and the subtype of this object
|
||||
* are the same as the content type described in {@code rawdata};
|
||||
* otherwise returns {@code false}; if {@code rawdata} is
|
||||
* {@code null}, returns {@code false}
|
||||
*/
|
||||
public boolean match(String rawdata) throws MimeTypeParseException {
|
||||
if (rawdata == null)
|
||||
@ -294,11 +287,11 @@ MimeTypeParameterList(rawdata.substring(semIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
* The object implements the writeExternal method to save its contents
|
||||
* by calling the methods of DataOutput for its primitive values or
|
||||
* calling the writeObject method of ObjectOutput for objects, strings
|
||||
* and arrays.
|
||||
* @exception IOException Includes any I/O exceptions that may occur
|
||||
* The object implements the writeExternal method to save its contents by
|
||||
* calling the methods of DataOutput for its primitive values or calling the
|
||||
* writeObject method of ObjectOutput for objects, strings and arrays.
|
||||
*
|
||||
* @throws IOException Includes any I/O exceptions that may occur
|
||||
*/
|
||||
public void writeExternal(ObjectOutput out) throws IOException {
|
||||
String s = toString(); // contains ASCII chars only
|
||||
@ -314,13 +307,14 @@ MimeTypeParameterList(rawdata.substring(semIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
* The object implements the readExternal method to restore its
|
||||
* contents by calling the methods of DataInput for primitive
|
||||
* types and readObject for objects, strings and arrays. The
|
||||
* readExternal method must read the values in the same sequence
|
||||
* and with the same types as were written by writeExternal.
|
||||
* @exception ClassNotFoundException If the class for an object being
|
||||
* restored cannot be found.
|
||||
* The object implements the readExternal method to restore its contents by
|
||||
* calling the methods of DataInput for primitive types and readObject for
|
||||
* objects, strings and arrays. The readExternal method must read the values
|
||||
* in the same sequence and with the same types as were written by
|
||||
* writeExternal.
|
||||
*
|
||||
* @throws ClassNotFoundException If the class for an object being restored
|
||||
* cannot be found
|
||||
*/
|
||||
public void readExternal(ObjectInput in) throws IOException,
|
||||
ClassNotFoundException {
|
||||
@ -339,9 +333,9 @@ ClassNotFoundException {
|
||||
|
||||
/**
|
||||
* Returns a clone of this object.
|
||||
*
|
||||
* @return a clone of this object
|
||||
*/
|
||||
|
||||
public Object clone() {
|
||||
MimeType newObj = null;
|
||||
try {
|
||||
@ -368,7 +362,7 @@ ClassNotFoundException {
|
||||
/**
|
||||
* Determines whether or not a given string is a legal token.
|
||||
*
|
||||
* @throws NullPointerException if <code>s</code> is null
|
||||
* @throws NullPointerException if {@code s} is {@code null}
|
||||
*/
|
||||
private boolean isValidToken(String s) {
|
||||
int len = s.length();
|
||||
@ -388,7 +382,5 @@ ClassNotFoundException {
|
||||
/**
|
||||
* A string that holds all the special chars.
|
||||
*/
|
||||
|
||||
private static final String TSPECIALS = "()<>@,;:\\\"/[]?=";
|
||||
|
||||
} // class MimeType
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2017, 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,10 +31,9 @@ import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
/**
|
||||
* An object that encapsulates the parameter list of a MimeType
|
||||
* as defined in RFC 2045 and 2046.
|
||||
* An object that encapsulates the parameter list of a MimeType as defined in
|
||||
* RFC 2045 and 2046.
|
||||
*
|
||||
* @author jeff.dunn@eng.sun.com
|
||||
*/
|
||||
@ -71,9 +70,9 @@ class MimeTypeParameterList implements Cloneable {
|
||||
} // hashCode()
|
||||
|
||||
/**
|
||||
* Two parameter lists are considered equal if they have exactly
|
||||
* the same set of parameter names and associated values. The
|
||||
* order of the parameters is not considered.
|
||||
* Two parameter lists are considered equal if they have exactly the same
|
||||
* set of parameter names and associated values. The order of the parameters
|
||||
* is not considered.
|
||||
*/
|
||||
public boolean equals(Object thatObject) {
|
||||
//System.out.println("MimeTypeParameterList.equals("+this+","+thatObject+")");
|
||||
@ -246,16 +245,16 @@ class MimeTypeParameterList implements Cloneable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the value associated with the given name, or null if there
|
||||
* is no current association.
|
||||
* Retrieve the value associated with the given name, or {@code null} if
|
||||
* there is no current association.
|
||||
*/
|
||||
public String get(String name) {
|
||||
return parameters.get(name.trim().toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value to be associated with the given name, replacing
|
||||
* any previous association.
|
||||
* Set the value to be associated with the given name, replacing any
|
||||
* previous association.
|
||||
*/
|
||||
public void set(String name, String value) {
|
||||
parameters.put(name.trim().toLowerCase(), value);
|
||||
@ -294,18 +293,20 @@ class MimeTypeParameterList implements Cloneable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone of this object.
|
||||
*
|
||||
* @return a clone of this object
|
||||
*/
|
||||
@SuppressWarnings("unchecked") // Cast from clone
|
||||
public Object clone() {
|
||||
MimeTypeParameterList newObj = null;
|
||||
try {
|
||||
newObj = (MimeTypeParameterList)super.clone();
|
||||
} catch (CloneNotSupportedException cannotHappen) {
|
||||
}
|
||||
newObj.parameters = (Hashtable<String, String>)parameters.clone();
|
||||
return newObj;
|
||||
}
|
||||
public Object clone() {
|
||||
MimeTypeParameterList newObj = null;
|
||||
try {
|
||||
newObj = (MimeTypeParameterList)super.clone();
|
||||
} catch (CloneNotSupportedException cannotHappen) {
|
||||
}
|
||||
newObj.parameters = (Hashtable<String, String>)parameters.clone();
|
||||
return newObj;
|
||||
}
|
||||
|
||||
private Hashtable<String, String> parameters;
|
||||
|
||||
@ -319,8 +320,8 @@ class MimeTypeParameterList implements Cloneable {
|
||||
}
|
||||
|
||||
/**
|
||||
* return the index of the first non white space character in
|
||||
* rawdata at or after index i.
|
||||
* Returns the index of the first non white space character in
|
||||
* {@code rawdata} at or after index {@code i}.
|
||||
*/
|
||||
private static int skipWhiteSpace(String rawdata, int i) {
|
||||
int length = rawdata.length();
|
||||
@ -374,7 +375,8 @@ class MimeTypeParameterList implements Cloneable {
|
||||
}
|
||||
|
||||
/**
|
||||
* A routine that knows how to strip the quotes and escape sequences from the given value.
|
||||
* A routine that knows how to strip the quotes and escape sequences from
|
||||
* the given value.
|
||||
*/
|
||||
private static String unquote(String value) {
|
||||
int valueLength = value.length();
|
||||
@ -400,5 +402,4 @@ class MimeTypeParameterList implements Cloneable {
|
||||
* A string that holds all the special chars.
|
||||
*/
|
||||
private static final String TSPECIALS = "()<>@,;:\\\"/[]?=";
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2017, 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
|
||||
@ -25,12 +25,11 @@
|
||||
|
||||
package java.awt.datatransfer;
|
||||
|
||||
|
||||
/**
|
||||
* A class to encapsulate MimeType parsing related exceptions
|
||||
* A class to encapsulate MimeType parsing related exceptions.
|
||||
*
|
||||
* @serial exclude
|
||||
* @since 1.3
|
||||
* @serial exclude
|
||||
*/
|
||||
public class MimeTypeParseException extends Exception {
|
||||
|
||||
@ -47,7 +46,7 @@ public class MimeTypeParseException extends Exception {
|
||||
/**
|
||||
* Constructs a MimeTypeParseException with the specified detail message.
|
||||
*
|
||||
* @param s the detail message.
|
||||
* @param s the detail message
|
||||
*/
|
||||
public MimeTypeParseException(String s) {
|
||||
super(s);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2017, 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
|
||||
@ -25,23 +25,21 @@
|
||||
|
||||
package java.awt.datatransfer;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
|
||||
/**
|
||||
* A <code>Transferable</code> which implements the capability required
|
||||
* to transfer a <code>String</code>.
|
||||
*
|
||||
* This <code>Transferable</code> properly supports
|
||||
* <code>DataFlavor.stringFlavor</code>
|
||||
* and all equivalent flavors. Support for
|
||||
* <code>DataFlavor.plainTextFlavor</code>
|
||||
* and all equivalent flavors is <b>deprecated</b>. No other
|
||||
* <code>DataFlavor</code>s are supported.
|
||||
* A {@code Transferable} which implements the capability required to transfer a
|
||||
* {@code String}.
|
||||
* <p>
|
||||
* This {@code Transferable} properly supports {@code DataFlavor.stringFlavor}
|
||||
* and all equivalent flavors. Support for {@code DataFlavor.plainTextFlavor}
|
||||
* and all equivalent flavors is <b>deprecated</b>. No other {@code DataFlavor}s
|
||||
* are supported.
|
||||
*
|
||||
* @see DataFlavor#stringFlavor
|
||||
* @see DataFlavor#plainTextFlavor
|
||||
* @since 1.1
|
||||
* @see java.awt.datatransfer.DataFlavor#stringFlavor
|
||||
* @see java.awt.datatransfer.DataFlavor#plainTextFlavor
|
||||
*/
|
||||
public class StringSelection implements Transferable, ClipboardOwner {
|
||||
|
||||
@ -57,23 +55,23 @@ public class StringSelection implements Transferable, ClipboardOwner {
|
||||
private String data;
|
||||
|
||||
/**
|
||||
* Creates a <code>Transferable</code> capable of transferring
|
||||
* the specified <code>String</code>.
|
||||
* @param data the string to be transferred
|
||||
* Creates a {@code Transferable} capable of transferring the specified
|
||||
* {@code String}.
|
||||
*
|
||||
* @param data the string to be transferred
|
||||
*/
|
||||
public StringSelection(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of flavors in which this <code>Transferable</code>
|
||||
* can provide the data. <code>DataFlavor.stringFlavor</code>
|
||||
* is properly supported.
|
||||
* Support for <code>DataFlavor.plainTextFlavor</code> is
|
||||
* <b>deprecated</b>.
|
||||
* Returns an array of flavors in which this {@code Transferable} can
|
||||
* provide the data. {@code DataFlavor.stringFlavor} is properly supported.
|
||||
* Support for {@code DataFlavor.plainTextFlavor} is <b>deprecated</b>.
|
||||
*
|
||||
* @return an array of length two, whose elements are <code>DataFlavor.
|
||||
* stringFlavor</code> and <code>DataFlavor.plainTextFlavor</code>
|
||||
* @return an array of length two, whose elements are
|
||||
* {@code DataFlavor.stringFlavor} and
|
||||
* {@code DataFlavor.plainTextFlavor}
|
||||
*/
|
||||
public DataFlavor[] getTransferDataFlavors() {
|
||||
// returning flavors itself would allow client code to modify
|
||||
@ -83,14 +81,14 @@ public class StringSelection implements Transferable, ClipboardOwner {
|
||||
|
||||
/**
|
||||
* Returns whether the requested flavor is supported by this
|
||||
* <code>Transferable</code>.
|
||||
* {@code Transferable}.
|
||||
*
|
||||
* @param flavor the requested flavor for the data
|
||||
* @return true if <code>flavor</code> is equal to
|
||||
* <code>DataFlavor.stringFlavor</code> or
|
||||
* <code>DataFlavor.plainTextFlavor</code>; false if <code>flavor</code>
|
||||
* is not one of the above flavors
|
||||
* @throws NullPointerException if flavor is <code>null</code>
|
||||
* @param flavor the requested flavor for the data
|
||||
* @return {@code true} if {@code flavor} is equal to
|
||||
* {@code DataFlavor.stringFlavor} or
|
||||
* {@code DataFlavor.plainTextFlavor}; {@code false} if
|
||||
* {@code flavor} is not one of the above flavors
|
||||
* @throws NullPointerException if {@code flavor} is {@code null}
|
||||
*/
|
||||
public boolean isDataFlavorSupported(DataFlavor flavor) {
|
||||
// JCK Test StringSelection0003: if 'flavor' is null, throw NPE
|
||||
@ -103,27 +101,27 @@ public class StringSelection implements Transferable, ClipboardOwner {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>Transferable</code>'s data in the requested
|
||||
* <code>DataFlavor</code> if possible. If the desired flavor is
|
||||
* <code>DataFlavor.stringFlavor</code>, or an equivalent flavor,
|
||||
* the <code>String</code> representing the selection is
|
||||
* returned. If the desired flavor is
|
||||
* <code>DataFlavor.plainTextFlavor</code>,
|
||||
* or an equivalent flavor, a <code>Reader</code> is returned.
|
||||
* Returns the {@code Transferable}'s data in the requested
|
||||
* {@code DataFlavor} if possible. If the desired flavor is
|
||||
* {@code DataFlavor.stringFlavor}, or an equivalent flavor, the
|
||||
* {@code String} representing the selection is returned. If the desired
|
||||
* flavor is {@code DataFlavor.plainTextFlavor}, or an equivalent flavor, a
|
||||
* {@code Reader} is returned.
|
||||
* <br>
|
||||
* <b>Note:</b> The behavior of this method for
|
||||
* <code>DataFlavor.plainTextFlavor</code>
|
||||
* and equivalent <code>DataFlavor</code>s is inconsistent with the
|
||||
* definition of <code>DataFlavor.plainTextFlavor</code>.
|
||||
* {@code DataFlavor.plainTextFlavor}
|
||||
* and equivalent {@code DataFlavor}s is inconsistent with the definition of
|
||||
* {@code DataFlavor.plainTextFlavor}.
|
||||
*
|
||||
* @param flavor the requested flavor for the data
|
||||
* @param flavor the requested flavor for the data
|
||||
* @return the data in the requested flavor, as outlined above
|
||||
* @throws UnsupportedFlavorException if the requested data flavor is
|
||||
* not equivalent to either <code>DataFlavor.stringFlavor</code>
|
||||
* or <code>DataFlavor.plainTextFlavor</code>
|
||||
* @throws UnsupportedFlavorException if the requested data flavor is not
|
||||
* equivalent to either {@code DataFlavor.stringFlavor} or
|
||||
* {@code DataFlavor.plainTextFlavor}
|
||||
* @throws IOException if an IOException occurs while retrieving the data.
|
||||
* By default, StringSelection never throws this exception, but a
|
||||
* subclass may.
|
||||
* @throws NullPointerException if flavor is <code>null</code>
|
||||
* @throws NullPointerException if {@code flavor} is {@code null}
|
||||
* @see java.io.Reader
|
||||
*/
|
||||
public Object getTransferData(DataFlavor flavor)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2017, 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
|
||||
@ -25,9 +25,6 @@
|
||||
|
||||
package java.awt.datatransfer;
|
||||
|
||||
import sun.datatransfer.DataFlavorUtil;
|
||||
import sun.datatransfer.DesktopDatatransferService;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -45,11 +42,14 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import sun.datatransfer.DataFlavorUtil;
|
||||
import sun.datatransfer.DesktopDatatransferService;
|
||||
|
||||
/**
|
||||
* The SystemFlavorMap is a configurable map between "natives" (Strings), which
|
||||
* correspond to platform-specific data formats, and "flavors" (DataFlavors),
|
||||
* which correspond to platform-independent MIME types. This mapping is used
|
||||
* by the data transfer subsystem to transfer data between Java and native
|
||||
* which correspond to platform-independent MIME types. This mapping is used by
|
||||
* the data transfer subsystem to transfer data between Java and native
|
||||
* applications, and between Java applications in separate VMs.
|
||||
*
|
||||
* @since 1.2
|
||||
@ -57,8 +57,7 @@ import java.util.Set;
|
||||
public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
|
||||
/**
|
||||
* Constant prefix used to tag Java types converted to native platform
|
||||
* type.
|
||||
* Constant prefix used to tag Java types converted to native platform type.
|
||||
*/
|
||||
private static String JavaMIME = "JAVA_DATAFLAVOR:";
|
||||
|
||||
@ -93,14 +92,15 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
/**
|
||||
* Maps native Strings to Lists of DataFlavors (or base type Strings for
|
||||
* text DataFlavors).
|
||||
* Do not use the field directly, use getNativeToFlavor() instead.
|
||||
* <p>
|
||||
* Do not use the field directly, use {@link #getNativeToFlavor} instead.
|
||||
*/
|
||||
private final Map<String, LinkedHashSet<DataFlavor>> nativeToFlavor = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Accessor to nativeToFlavor map. Since we use lazy initialization we must
|
||||
* Accessor to nativeToFlavor map. Since we use lazy initialization we must
|
||||
* use this accessor instead of direct access to the field which may not be
|
||||
* initialized yet. This method will initialize the field if needed.
|
||||
* initialized yet. This method will initialize the field if needed.
|
||||
*
|
||||
* @return nativeToFlavor
|
||||
*/
|
||||
@ -114,14 +114,15 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
/**
|
||||
* Maps DataFlavors (or base type Strings for text DataFlavors) to Lists of
|
||||
* native Strings.
|
||||
* Do not use the field directly, use getFlavorToNative() instead.
|
||||
* <p>
|
||||
* Do not use the field directly, use {@link #getFlavorToNative} instead.
|
||||
*/
|
||||
private final Map<DataFlavor, LinkedHashSet<String>> flavorToNative = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Accessor to flavorToNative map. Since we use lazy initialization we must
|
||||
* Accessor to flavorToNative map. Since we use lazy initialization we must
|
||||
* use this accessor instead of direct access to the field which may not be
|
||||
* initialized yet. This method will initialize the field if needed.
|
||||
* initialized yet. This method will initialize the field if needed.
|
||||
*
|
||||
* @return flavorToNative
|
||||
*/
|
||||
@ -133,9 +134,10 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps a text DataFlavor primary mime-type to the native. Used only to store
|
||||
* standard mappings registered in the flavormap.properties
|
||||
* Do not use this field directly, use getTextTypeToNative() instead.
|
||||
* Maps a text DataFlavor primary mime-type to the native. Used only to
|
||||
* store standard mappings registered in the {@code flavormap.properties}.
|
||||
* <p>
|
||||
* Do not use this field directly, use {@link #getTextTypeToNative} instead.
|
||||
*/
|
||||
private Map<String, LinkedHashSet<String>> textTypeToNative = new HashMap<>();
|
||||
|
||||
@ -145,9 +147,9 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
private boolean isMapInitialized = false;
|
||||
|
||||
/**
|
||||
* An accessor to textTypeToNative map. Since we use lazy initialization we
|
||||
* must use this accessor instead of direct access to the field which may not
|
||||
* be initialized yet. This method will initialize the field if needed.
|
||||
* An accessor to textTypeToNative map. Since we use lazy initialization we
|
||||
* must use this accessor instead of direct access to the field which may
|
||||
* not be initialized yet. This method will initialize the field if needed.
|
||||
*
|
||||
* @return textTypeToNative
|
||||
*/
|
||||
@ -175,8 +177,8 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
/**
|
||||
* Dynamic mapping generation used for text mappings should not be applied
|
||||
* to the DataFlavors and String natives for which the mappings have been
|
||||
* explicitly specified with setFlavorsForNative() or
|
||||
* setNativesForFlavor(). This keeps all such keys.
|
||||
* explicitly specified with {@link #setFlavorsForNative} or
|
||||
* {@link #setNativesForFlavor}. This keeps all such keys.
|
||||
*/
|
||||
private Set<Object> disabledMappingGenerationKeys = new HashSet<>();
|
||||
|
||||
@ -193,8 +195,8 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a SystemFlavorMap by reading flavormap.properties
|
||||
* For thread-safety must be called under lock on this.
|
||||
* Initializes a SystemFlavorMap by reading {@code flavormap.properties}.
|
||||
* For thread-safety must be called under lock on {@code this}.
|
||||
*/
|
||||
private void initSystemFlavorMap() {
|
||||
if (isMapInitialized) {
|
||||
@ -366,10 +368,10 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Semantically equivalent to 'nativeToFlavor.get(nat)'. This method
|
||||
* handles the case where 'nat' is not found in 'nativeToFlavor'. In that
|
||||
* case, a new DataFlavor is synthesized, stored, and returned, if and
|
||||
* only if the specified native is encoded as a Java MIME type.
|
||||
* Semantically equivalent to 'nativeToFlavor.get(nat)'. This method handles
|
||||
* the case where 'nat' is not found in 'nativeToFlavor'. In that case, a
|
||||
* new DataFlavor is synthesized, stored, and returned, if and only if the
|
||||
* specified native is encoded as a Java MIME type.
|
||||
*/
|
||||
private LinkedHashSet<DataFlavor> nativeToFlavorLookup(String nat) {
|
||||
LinkedHashSet<DataFlavor> flavors = getNativeToFlavor().get(nat);
|
||||
@ -480,27 +482,25 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a <code>List</code> of <code>String</code> natives to which the
|
||||
* specified <code>DataFlavor</code> can be translated by the data transfer
|
||||
* subsystem. The <code>List</code> will be sorted from best native to
|
||||
* worst. That is, the first native will best reflect data in the specified
|
||||
* flavor to the underlying native platform.
|
||||
* Returns a {@code List} of {@code String} natives to which the specified
|
||||
* {@code DataFlavor} can be translated by the data transfer subsystem. The
|
||||
* {@code List} will be sorted from best native to worst. That is, the first
|
||||
* native will best reflect data in the specified flavor to the underlying
|
||||
* native platform.
|
||||
* <p>
|
||||
* If the specified <code>DataFlavor</code> is previously unknown to the
|
||||
* data transfer subsystem and the data transfer subsystem is unable to
|
||||
* translate this <code>DataFlavor</code> to any existing native, then
|
||||
* invoking this method will establish a
|
||||
* mapping in both directions between the specified <code>DataFlavor</code>
|
||||
* and an encoded version of its MIME type as its native.
|
||||
*
|
||||
* @param flav the <code>DataFlavor</code> whose corresponding natives
|
||||
* should be returned. If <code>null</code> is specified, all
|
||||
* natives currently known to the data transfer subsystem are
|
||||
* returned in a non-deterministic order.
|
||||
* @return a <code>java.util.List</code> of <code>java.lang.String</code>
|
||||
* objects which are platform-specific representations of platform-
|
||||
* specific data formats
|
||||
* If the specified {@code DataFlavor} is previously unknown to the data
|
||||
* transfer subsystem and the data transfer subsystem is unable to translate
|
||||
* this {@code DataFlavor} to any existing native, then invoking this method
|
||||
* will establish a mapping in both directions between the specified
|
||||
* {@code DataFlavor} and an encoded version of its MIME type as its native.
|
||||
*
|
||||
* @param flav the {@code DataFlavor} whose corresponding natives should be
|
||||
* returned. If {@code null} is specified, all natives currently
|
||||
* known to the data transfer subsystem are returned in a
|
||||
* non-deterministic order.
|
||||
* @return a {@code java.util.List} of {@code java.lang.String} objects
|
||||
* which are platform-specific representations of platform-specific
|
||||
* data formats
|
||||
* @see #encodeDataFlavor
|
||||
* @since 1.4
|
||||
*/
|
||||
@ -566,33 +566,30 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a <code>List</code> of <code>DataFlavor</code>s to which the
|
||||
* specified <code>String</code> native can be translated by the data
|
||||
* transfer subsystem. The <code>List</code> will be sorted from best
|
||||
* <code>DataFlavor</code> to worst. That is, the first
|
||||
* <code>DataFlavor</code> will best reflect data in the specified
|
||||
* native to a Java application.
|
||||
* Returns a {@code List} of {@code DataFlavor}s to which the specified
|
||||
* {@code String} native can be translated by the data transfer subsystem.
|
||||
* The {@code List} will be sorted from best {@code DataFlavor} to worst.
|
||||
* That is, the first {@code DataFlavor} will best reflect data in the
|
||||
* specified native to a Java application.
|
||||
* <p>
|
||||
* If the specified native is previously unknown to the data transfer
|
||||
* subsystem, and that native has been properly encoded, then invoking this
|
||||
* method will establish a mapping in both directions between the specified
|
||||
* native and a <code>DataFlavor</code> whose MIME type is a decoded
|
||||
* version of the native.
|
||||
* native and a {@code DataFlavor} whose MIME type is a decoded version of
|
||||
* the native.
|
||||
* <p>
|
||||
* If the specified native is not a properly encoded native and the
|
||||
* mappings for this native have not been altered with
|
||||
* <code>setFlavorsForNative</code>, then the contents of the
|
||||
* <code>List</code> is platform dependent, but <code>null</code>
|
||||
* cannot be returned.
|
||||
*
|
||||
* @param nat the native whose corresponding <code>DataFlavor</code>s
|
||||
* should be returned. If <code>null</code> is specified, all
|
||||
* <code>DataFlavor</code>s currently known to the data transfer
|
||||
* subsystem are returned in a non-deterministic order.
|
||||
* @return a <code>java.util.List</code> of <code>DataFlavor</code>
|
||||
* objects into which platform-specific data in the specified,
|
||||
* platform-specific native can be translated
|
||||
* If the specified native is not a properly encoded native and the mappings
|
||||
* for this native have not been altered with {@code setFlavorsForNative},
|
||||
* then the contents of the {@code List} is platform dependent, but
|
||||
* {@code null} cannot be returned.
|
||||
*
|
||||
* @param nat the native whose corresponding {@code DataFlavor}s should be
|
||||
* returned. If {@code null} is specified, all {@code DataFlavor}s
|
||||
* currently known to the data transfer subsystem are returned in a
|
||||
* non-deterministic order.
|
||||
* @return a {@code java.util.List} of {@code DataFlavor} objects into which
|
||||
* platform-specific data in the specified, platform-specific native
|
||||
* can be translated
|
||||
* @see #encodeJavaMIMEType
|
||||
* @since 1.4
|
||||
*/
|
||||
@ -741,24 +738,23 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a <code>Map</code> of the specified <code>DataFlavor</code>s to
|
||||
* their most preferred <code>String</code> native. Each native value will
|
||||
* be the same as the first native in the List returned by
|
||||
* <code>getNativesForFlavor</code> for the specified flavor.
|
||||
* Returns a {@code Map} of the specified {@code DataFlavor}s to their most
|
||||
* preferred {@code String} native. Each native value will be the same as
|
||||
* the first native in the List returned by {@code getNativesForFlavor} for
|
||||
* the specified flavor.
|
||||
* <p>
|
||||
* If a specified <code>DataFlavor</code> is previously unknown to the
|
||||
* data transfer subsystem, then invoking this method will establish a
|
||||
* mapping in both directions between the specified <code>DataFlavor</code>
|
||||
* and an encoded version of its MIME type as its native.
|
||||
*
|
||||
* @param flavors an array of <code>DataFlavor</code>s which will be the
|
||||
* key set of the returned <code>Map</code>. If <code>null</code> is
|
||||
* specified, a mapping of all <code>DataFlavor</code>s known to the
|
||||
* data transfer subsystem to their most preferred
|
||||
* <code>String</code> natives will be returned.
|
||||
* @return a <code>java.util.Map</code> of <code>DataFlavor</code>s to
|
||||
* <code>String</code> natives
|
||||
* If a specified {@code DataFlavor} is previously unknown to the data
|
||||
* transfer subsystem, then invoking this method will establish a mapping in
|
||||
* both directions between the specified {@code DataFlavor} and an encoded
|
||||
* version of its MIME type as its native.
|
||||
*
|
||||
* @param flavors an array of {@code DataFlavor}s which will be the key set
|
||||
* of the returned {@code Map}. If {@code null} is specified, a
|
||||
* mapping of all {@code DataFlavor}s known to the data transfer
|
||||
* subsystem to their most preferred {@code String} natives will be
|
||||
* returned.
|
||||
* @return a {@code java.util.Map} of {@code DataFlavor}s to {@code String}
|
||||
* natives
|
||||
* @see #getNativesForFlavor
|
||||
* @see #encodeDataFlavor
|
||||
*/
|
||||
@ -785,26 +781,23 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a <code>Map</code> of the specified <code>String</code> natives
|
||||
* to their most preferred <code>DataFlavor</code>. Each
|
||||
* <code>DataFlavor</code> value will be the same as the first
|
||||
* <code>DataFlavor</code> in the List returned by
|
||||
* <code>getFlavorsForNative</code> for the specified native.
|
||||
* Returns a {@code Map} of the specified {@code String} natives to their
|
||||
* most preferred {@code DataFlavor}. Each {@code DataFlavor} value will be
|
||||
* the same as the first {@code DataFlavor} in the List returned by
|
||||
* {@code getFlavorsForNative} for the specified native.
|
||||
* <p>
|
||||
* If a specified native is previously unknown to the data transfer
|
||||
* subsystem, and that native has been properly encoded, then invoking this
|
||||
* method will establish a mapping in both directions between the specified
|
||||
* native and a <code>DataFlavor</code> whose MIME type is a decoded
|
||||
* version of the native.
|
||||
*
|
||||
* @param natives an array of <code>String</code>s which will be the
|
||||
* key set of the returned <code>Map</code>. If <code>null</code> is
|
||||
* specified, a mapping of all supported <code>String</code> natives
|
||||
* to their most preferred <code>DataFlavor</code>s will be
|
||||
* returned.
|
||||
* @return a <code>java.util.Map</code> of <code>String</code> natives to
|
||||
* <code>DataFlavor</code>s
|
||||
* native and a {@code DataFlavor} whose MIME type is a decoded version of
|
||||
* the native.
|
||||
*
|
||||
* @param natives an array of {@code String}s which will be the key set of
|
||||
* the returned {@code Map}. If {@code null} is specified, a mapping
|
||||
* of all supported {@code String} natives to their most preferred
|
||||
* {@code DataFlavor}s will be returned.
|
||||
* @return a {@code java.util.Map} of {@code String} natives to
|
||||
* {@code DataFlavor}s
|
||||
* @see #getFlavorsForNative
|
||||
* @see #encodeJavaMIMEType
|
||||
*/
|
||||
@ -828,22 +821,19 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a mapping from the specified <code>DataFlavor</code> (and all
|
||||
* <code>DataFlavor</code>s equal to the specified <code>DataFlavor</code>)
|
||||
* to the specified <code>String</code> native.
|
||||
* Unlike <code>getNativesForFlavor</code>, the mapping will only be
|
||||
* established in one direction, and the native will not be encoded. To
|
||||
* establish a two-way mapping, call
|
||||
* <code>addFlavorForUnencodedNative</code> as well. The new mapping will
|
||||
* be of lower priority than any existing mapping.
|
||||
* This method has no effect if a mapping from the specified or equal
|
||||
* <code>DataFlavor</code> to the specified <code>String</code> native
|
||||
* already exists.
|
||||
*
|
||||
* @param flav the <code>DataFlavor</code> key for the mapping
|
||||
* @param nat the <code>String</code> native value for the mapping
|
||||
* @throws NullPointerException if flav or nat is <code>null</code>
|
||||
* Adds a mapping from the specified {@code DataFlavor} (and all
|
||||
* {@code DataFlavor}s equal to the specified {@code DataFlavor}) to the
|
||||
* specified {@code String} native. Unlike {@code getNativesForFlavor}, the
|
||||
* mapping will only be established in one direction, and the native will
|
||||
* not be encoded. To establish a two-way mapping, call
|
||||
* {@code addFlavorForUnencodedNative} as well. The new mapping will be of
|
||||
* lower priority than any existing mapping. This method has no effect if a
|
||||
* mapping from the specified or equal {@code DataFlavor} to the specified
|
||||
* {@code String} native already exists.
|
||||
*
|
||||
* @param flav the {@code DataFlavor} key for the mapping
|
||||
* @param nat the {@code String} native value for the mapping
|
||||
* @throws NullPointerException if flav or nat is {@code null}
|
||||
* @see #addFlavorForUnencodedNative
|
||||
* @since 1.4
|
||||
*/
|
||||
@ -862,30 +852,27 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Discards the current mappings for the specified <code>DataFlavor</code>
|
||||
* and all <code>DataFlavor</code>s equal to the specified
|
||||
* <code>DataFlavor</code>, and creates new mappings to the
|
||||
* specified <code>String</code> natives.
|
||||
* Unlike <code>getNativesForFlavor</code>, the mappings will only be
|
||||
* established in one direction, and the natives will not be encoded. To
|
||||
* establish two-way mappings, call <code>setFlavorsForNative</code>
|
||||
* as well. The first native in the array will represent the highest
|
||||
* priority mapping. Subsequent natives will represent mappings of
|
||||
* decreasing priority.
|
||||
* Discards the current mappings for the specified {@code DataFlavor} and
|
||||
* all {@code DataFlavor}s equal to the specified {@code DataFlavor}, and
|
||||
* creates new mappings to the specified {@code String} natives. Unlike
|
||||
* {@code getNativesForFlavor}, the mappings will only be established in one
|
||||
* direction, and the natives will not be encoded. To establish two-way
|
||||
* mappings, call {@code setFlavorsForNative} as well. The first native in
|
||||
* the array will represent the highest priority mapping. Subsequent natives
|
||||
* will represent mappings of decreasing priority.
|
||||
* <p>
|
||||
* If the array contains several elements that reference equal
|
||||
* <code>String</code> natives, this method will establish new mappings
|
||||
* for the first of those elements and ignore the rest of them.
|
||||
* {@code String} natives, this method will establish new mappings for the
|
||||
* first of those elements and ignore the rest of them.
|
||||
* <p>
|
||||
* It is recommended that client code not reset mappings established by the
|
||||
* data transfer subsystem. This method should only be used for
|
||||
* application-level mappings.
|
||||
*
|
||||
* @param flav the <code>DataFlavor</code> key for the mappings
|
||||
* @param natives the <code>String</code> native values for the mappings
|
||||
* @throws NullPointerException if flav or natives is <code>null</code>
|
||||
* or if natives contains <code>null</code> elements
|
||||
*
|
||||
* @param flav the {@code DataFlavor} key for the mappings
|
||||
* @param natives the {@code String} native values for the mappings
|
||||
* @throws NullPointerException if flav or natives is {@code null} or if
|
||||
* natives contains {@code null} elements
|
||||
* @see #setFlavorsForNative
|
||||
* @since 1.4
|
||||
*/
|
||||
@ -903,20 +890,19 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a mapping from a single <code>String</code> native to a single
|
||||
* <code>DataFlavor</code>. Unlike <code>getFlavorsForNative</code>, the
|
||||
* mapping will only be established in one direction, and the native will
|
||||
* not be encoded. To establish a two-way mapping, call
|
||||
* <code>addUnencodedNativeForFlavor</code> as well. The new mapping will
|
||||
* be of lower priority than any existing mapping.
|
||||
* This method has no effect if a mapping from the specified
|
||||
* <code>String</code> native to the specified or equal
|
||||
* <code>DataFlavor</code> already exists.
|
||||
*
|
||||
* @param nat the <code>String</code> native key for the mapping
|
||||
* @param flav the <code>DataFlavor</code> value for the mapping
|
||||
* @throws NullPointerException if nat or flav is <code>null</code>
|
||||
* Adds a mapping from a single {@code String} native to a single
|
||||
* {@code DataFlavor}. Unlike {@code getFlavorsForNative}, the mapping will
|
||||
* only be established in one direction, and the native will not be encoded.
|
||||
* To establish a two-way mapping, call {@code addUnencodedNativeForFlavor}
|
||||
* as well. The new mapping will be of lower priority than any existing
|
||||
* mapping. This method has no effect if a mapping from the specified
|
||||
* {@code String} native to the specified or equal {@code DataFlavor}
|
||||
* already exists.
|
||||
*
|
||||
* @param nat the {@code String} native key for the mapping
|
||||
* @param flav the {@code DataFlavor} value for the mapping
|
||||
* @throws NullPointerException if {@code nat} or {@code flav} is
|
||||
* {@code null}
|
||||
* @see #addUnencodedNativeForFlavor
|
||||
* @since 1.4
|
||||
*/
|
||||
@ -935,29 +921,27 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Discards the current mappings for the specified <code>String</code>
|
||||
* native, and creates new mappings to the specified
|
||||
* <code>DataFlavor</code>s. Unlike <code>getFlavorsForNative</code>, the
|
||||
* mappings will only be established in one direction, and the natives need
|
||||
* not be encoded. To establish two-way mappings, call
|
||||
* <code>setNativesForFlavor</code> as well. The first
|
||||
* <code>DataFlavor</code> in the array will represent the highest priority
|
||||
* mapping. Subsequent <code>DataFlavor</code>s will represent mappings of
|
||||
* Discards the current mappings for the specified {@code String} native,
|
||||
* and creates new mappings to the specified {@code DataFlavor}s. Unlike
|
||||
* {@code getFlavorsForNative}, the mappings will only be established in one
|
||||
* direction, and the natives need not be encoded. To establish two-way
|
||||
* mappings, call {@code setNativesForFlavor} as well. The first
|
||||
* {@code DataFlavor} in the array will represent the highest priority
|
||||
* mapping. Subsequent {@code DataFlavor}s will represent mappings of
|
||||
* decreasing priority.
|
||||
* <p>
|
||||
* If the array contains several elements that reference equal
|
||||
* <code>DataFlavor</code>s, this method will establish new mappings
|
||||
* for the first of those elements and ignore the rest of them.
|
||||
* {@code DataFlavor}s, this method will establish new mappings for the
|
||||
* first of those elements and ignore the rest of them.
|
||||
* <p>
|
||||
* It is recommended that client code not reset mappings established by the
|
||||
* data transfer subsystem. This method should only be used for
|
||||
* application-level mappings.
|
||||
*
|
||||
* @param nat the <code>String</code> native key for the mappings
|
||||
* @param flavors the <code>DataFlavor</code> values for the mappings
|
||||
* @throws NullPointerException if nat or flavors is <code>null</code>
|
||||
* or if flavors contains <code>null</code> elements
|
||||
*
|
||||
* @param nat the {@code String} native key for the mappings
|
||||
* @param flavors the {@code DataFlavor} values for the mappings
|
||||
* @throws NullPointerException if {@code nat} or {@code flavors} is
|
||||
* {@code null} or if {@code flavors} contains {@code null} elements
|
||||
* @see #setNativesForFlavor
|
||||
* @since 1.4
|
||||
*/
|
||||
@ -975,23 +959,22 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a MIME type for use as a <code>String</code> native. The format
|
||||
* of an encoded representation of a MIME type is implementation-dependent.
|
||||
* The only restrictions are:
|
||||
* Encodes a MIME type for use as a {@code String} native. The format of an
|
||||
* encoded representation of a MIME type is implementation-dependent. The
|
||||
* only restrictions are:
|
||||
* <ul>
|
||||
* <li>The encoded representation is <code>null</code> if and only if the
|
||||
* MIME type <code>String</code> is <code>null</code>.</li>
|
||||
* <li>The encoded representations for two non-<code>null</code> MIME type
|
||||
* <code>String</code>s are equal if and only if these <code>String</code>s
|
||||
* are equal according to <code>String.equals(Object)</code>.</li>
|
||||
* <li>The encoded representation is {@code null} if and only if the MIME
|
||||
* type {@code String} is {@code null}</li>
|
||||
* <li>The encoded representations for two non-{@code null} MIME type
|
||||
* {@code String}s are equal if and only if these {@code String}s are
|
||||
* equal according to {@code String.equals(Object)}</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* The reference implementation of this method returns the specified MIME
|
||||
* type <code>String</code> prefixed with <code>JAVA_DATAFLAVOR:</code>.
|
||||
* type {@code String} prefixed with {@code JAVA_DATAFLAVOR:}.
|
||||
*
|
||||
* @param mimeType the MIME type to encode
|
||||
* @return the encoded <code>String</code>, or <code>null</code> if
|
||||
* mimeType is <code>null</code>
|
||||
* @param mimeType the MIME type to encode
|
||||
* @return the encoded {@code String}, or {@code null} if {@code mimeType}
|
||||
* is {@code null}
|
||||
*/
|
||||
public static String encodeJavaMIMEType(String mimeType) {
|
||||
return (mimeType != null)
|
||||
@ -1000,27 +983,26 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a <code>DataFlavor</code> for use as a <code>String</code>
|
||||
* native. The format of an encoded <code>DataFlavor</code> is
|
||||
* implementation-dependent. The only restrictions are:
|
||||
* Encodes a {@code DataFlavor} for use as a {@code String} native. The
|
||||
* format of an encoded {@code DataFlavor} is implementation-dependent. The
|
||||
* only restrictions are:
|
||||
* <ul>
|
||||
* <li>The encoded representation is <code>null</code> if and only if the
|
||||
* specified <code>DataFlavor</code> is <code>null</code> or its MIME type
|
||||
* <code>String</code> is <code>null</code>.</li>
|
||||
* <li>The encoded representations for two non-<code>null</code>
|
||||
* <code>DataFlavor</code>s with non-<code>null</code> MIME type
|
||||
* <code>String</code>s are equal if and only if the MIME type
|
||||
* <code>String</code>s of these <code>DataFlavor</code>s are equal
|
||||
* according to <code>String.equals(Object)</code>.</li>
|
||||
* <li>The encoded representation is {@code null} if and only if the
|
||||
* specified {@code DataFlavor} is {@code null} or its MIME type
|
||||
* {@code String} is {@code null}</li>
|
||||
* <li>The encoded representations for two non-{@code null}
|
||||
* {@code DataFlavor}s with non-{@code null} MIME type {@code String}s
|
||||
* are equal if and only if the MIME type {@code String}s of these
|
||||
* {@code DataFlavor}s are equal according to
|
||||
* {@code String.equals(Object)}</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* The reference implementation of this method returns the MIME type
|
||||
* <code>String</code> of the specified <code>DataFlavor</code> prefixed
|
||||
* with <code>JAVA_DATAFLAVOR:</code>.
|
||||
* {@code String} of the specified {@code DataFlavor} prefixed with
|
||||
* {@code JAVA_DATAFLAVOR:}.
|
||||
*
|
||||
* @param flav the <code>DataFlavor</code> to encode
|
||||
* @return the encoded <code>String</code>, or <code>null</code> if
|
||||
* flav is <code>null</code> or has a <code>null</code> MIME type
|
||||
* @param flav the {@code DataFlavor} to encode
|
||||
* @return the encoded {@code String}, or {@code null} if {@code flav} is
|
||||
* {@code null} or has a {@code null} MIME type
|
||||
*/
|
||||
public static String encodeDataFlavor(DataFlavor flav) {
|
||||
return (flav != null)
|
||||
@ -1029,23 +1011,23 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the specified <code>String</code> is an encoded Java
|
||||
* MIME type.
|
||||
* Returns whether the specified {@code String} is an encoded Java MIME
|
||||
* type.
|
||||
*
|
||||
* @param str the <code>String</code> to test
|
||||
* @return <code>true</code> if the <code>String</code> is encoded;
|
||||
* <code>false</code> otherwise
|
||||
* @param str the {@code String} to test
|
||||
* @return {@code true} if the {@code String} is encoded; {@code false}
|
||||
* otherwise
|
||||
*/
|
||||
public static boolean isJavaMIMEType(String str) {
|
||||
return (str != null && str.startsWith(JavaMIME, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a <code>String</code> native for use as a Java MIME type.
|
||||
* Decodes a {@code String} native for use as a Java MIME type.
|
||||
*
|
||||
* @param nat the <code>String</code> to decode
|
||||
* @return the decoded Java MIME type, or <code>null</code> if nat is not
|
||||
* an encoded <code>String</code> native
|
||||
* @param nat the {@code String} to decode
|
||||
* @return the decoded Java MIME type, or {@code null} if {@code nat} is not
|
||||
* an encoded {@code String} native
|
||||
*/
|
||||
public static String decodeJavaMIMEType(String nat) {
|
||||
return (isJavaMIMEType(nat))
|
||||
@ -1054,14 +1036,13 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a <code>String</code> native for use as a
|
||||
* <code>DataFlavor</code>.
|
||||
* Decodes a {@code String} native for use as a {@code DataFlavor}.
|
||||
*
|
||||
* @param nat the <code>String</code> to decode
|
||||
* @return the decoded <code>DataFlavor</code>, or <code>null</code> if
|
||||
* nat is not an encoded <code>String</code> native
|
||||
* @throws ClassNotFoundException if the class of the data flavor
|
||||
* is not loaded
|
||||
* @param nat the {@code String} to decode
|
||||
* @return the decoded {@code DataFlavor}, or {@code null} if {@code nat} is
|
||||
* not an encoded {@code String} native
|
||||
* @throws ClassNotFoundException if the class of the data flavor is not
|
||||
* loaded
|
||||
*/
|
||||
public static DataFlavor decodeDataFlavor(String nat)
|
||||
throws ClassNotFoundException
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user