This commit is contained in:
J. Duke 2017-07-05 21:39:18 +02:00
commit 6a89b43450
478 changed files with 25347 additions and 5388 deletions

View File

@ -358,3 +358,4 @@ f900d5afd9c83a0df8f36161c27c5e4c86a66f4c jdk-9+111
55b6d550828d1223b364e6ead4a56e56411c56df jdk-9+113 55b6d550828d1223b364e6ead4a56e56411c56df jdk-9+113
1d992540870ff33fe6cc550443388588df9b9e4f jdk-9+114 1d992540870ff33fe6cc550443388588df9b9e4f jdk-9+114
09617ce980b99d49abfd54dacfed353c47e2a115 jdk-9+115 09617ce980b99d49abfd54dacfed353c47e2a115 jdk-9+115
6743a8e0cab7b5f6f4a0575f6664892f0ab740af jdk-9+116

View File

@ -397,6 +397,7 @@ AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK_ARGUMENTS],
ADD_JVM_ARG_IF_OK([-XX:+UseSerialGC],boot_jdk_jvmargs_small,[$JAVA]) ADD_JVM_ARG_IF_OK([-XX:+UseSerialGC],boot_jdk_jvmargs_small,[$JAVA])
ADD_JVM_ARG_IF_OK([-Xms32M],boot_jdk_jvmargs_small,[$JAVA]) ADD_JVM_ARG_IF_OK([-Xms32M],boot_jdk_jvmargs_small,[$JAVA])
ADD_JVM_ARG_IF_OK([-Xmx512M],boot_jdk_jvmargs_small,[$JAVA]) ADD_JVM_ARG_IF_OK([-Xmx512M],boot_jdk_jvmargs_small,[$JAVA])
ADD_JVM_ARG_IF_OK([-XX:TieredStopAtLevel=1],boot_jdk_jvmargs_small,[$JAVA])
AC_MSG_RESULT([$boot_jdk_jvmargs_small]) AC_MSG_RESULT([$boot_jdk_jvmargs_small])

View File

@ -31,7 +31,7 @@
export LEGACY_BUILD_DIR=@OPENJDK_TARGET_OS@-@OPENJDK_TARGET_CPU_LEGACY@ export LEGACY_BUILD_DIR=@OPENJDK_TARGET_OS@-@OPENJDK_TARGET_CPU_LEGACY@
sexport OPENJDK_TARGET_OS="@OPENJDK_TARGET_OS@" export OPENJDK_TARGET_OS="@OPENJDK_TARGET_OS@"
export OPENJDK_TARGET_CPU="@OPENJDK_TARGET_CPU@" export OPENJDK_TARGET_CPU="@OPENJDK_TARGET_CPU@"
export OPENJDK_TARGET_CPU_LIBDIR="@OPENJDK_TARGET_CPU_LIBDIR@" export OPENJDK_TARGET_CPU_LIBDIR="@OPENJDK_TARGET_CPU_LIBDIR@"
export DEBUG_LEVEL="@DEBUG_LEVEL@" export DEBUG_LEVEL="@DEBUG_LEVEL@"

View File

@ -1224,9 +1224,9 @@ with_lcms
with_dxsdk with_dxsdk
with_dxsdk_lib with_dxsdk_lib
with_dxsdk_include with_dxsdk_include
enable_jtreg_failure_handler
enable_new_hotspot_build enable_new_hotspot_build
enable_hotspot_test_in_build enable_hotspot_test_in_build
enable_jtreg_failure_handler
with_num_cores with_num_cores
with_memory_size with_memory_size
with_jobs with_jobs
@ -5070,7 +5070,7 @@ VS_SDK_PLATFORM_NAME_2013=
#CUSTOM_AUTOCONF_INCLUDE #CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks: # Do not change or remove the following line, it is needed for consistency checks:
DATE_WHEN_GENERATED=1460963400 DATE_WHEN_GENERATED=1462204427
############################################################################### ###############################################################################
# #
@ -15492,7 +15492,7 @@ $as_echo "$COMPILE_TYPE" >&6; }
HOTSPOT_TARGET_CPU_DEFINE=PPC32 HOTSPOT_TARGET_CPU_DEFINE=PPC32
elif test "x$OPENJDK_TARGET_CPU" = xs390; then elif test "x$OPENJDK_TARGET_CPU" = xs390; then
HOTSPOT_TARGET_CPU_DEFINE=S390 HOTSPOT_TARGET_CPU_DEFINE=S390
elif test "x$OPENJDK_TARGET_CPU" = ss390x; then elif test "x$OPENJDK_TARGET_CPU" = xs390x; then
HOTSPOT_TARGET_CPU_DEFINE=S390 HOTSPOT_TARGET_CPU_DEFINE=S390
fi fi
@ -15648,7 +15648,7 @@ $as_echo "$COMPILE_TYPE" >&6; }
HOTSPOT_BUILD_CPU_DEFINE=PPC32 HOTSPOT_BUILD_CPU_DEFINE=PPC32
elif test "x$OPENJDK_BUILD_CPU" = xs390; then elif test "x$OPENJDK_BUILD_CPU" = xs390; then
HOTSPOT_BUILD_CPU_DEFINE=S390 HOTSPOT_BUILD_CPU_DEFINE=S390
elif test "x$OPENJDK_BUILD_CPU" = ss390x; then elif test "x$OPENJDK_BUILD_CPU" = xs390x; then
HOTSPOT_BUILD_CPU_DEFINE=S390 HOTSPOT_BUILD_CPU_DEFINE=S390
fi fi
@ -64282,6 +64282,21 @@ $as_echo_n "checking flags for boot jdk java command for small workloads... " >&
fi fi
$ECHO "Check if jvm arg is ok: -XX:TieredStopAtLevel=1" >&5
$ECHO "Command: $JAVA -XX:TieredStopAtLevel=1 -version" >&5
OUTPUT=`$JAVA -XX:TieredStopAtLevel=1 -version 2>&1`
FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
boot_jdk_jvmargs_small="$boot_jdk_jvmargs_small -XX:TieredStopAtLevel=1"
JVM_ARG_OK=true
else
$ECHO "Arg failed:" >&5
$ECHO "$OUTPUT" >&5
JVM_ARG_OK=false
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $boot_jdk_jvmargs_small" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $boot_jdk_jvmargs_small" >&5
$as_echo "$boot_jdk_jvmargs_small" >&6; } $as_echo "$boot_jdk_jvmargs_small" >&6; }

View File

@ -435,7 +435,7 @@ AC_DEFUN([PLATFORM_SETUP_LEGACY_VARS_HELPER],
HOTSPOT_$1_CPU_DEFINE=PPC32 HOTSPOT_$1_CPU_DEFINE=PPC32
elif test "x$OPENJDK_$1_CPU" = xs390; then elif test "x$OPENJDK_$1_CPU" = xs390; then
HOTSPOT_$1_CPU_DEFINE=S390 HOTSPOT_$1_CPU_DEFINE=S390
elif test "x$OPENJDK_$1_CPU" = ss390x; then elif test "x$OPENJDK_$1_CPU" = xs390x; then
HOTSPOT_$1_CPU_DEFINE=S390 HOTSPOT_$1_CPU_DEFINE=S390
fi fi
AC_SUBST(HOTSPOT_$1_CPU_DEFINE) AC_SUBST(HOTSPOT_$1_CPU_DEFINE)

View File

@ -212,14 +212,17 @@ var getJibProfiles = function (input) {
* @returns Common values * @returns Common values
*/ */
var getJibProfilesCommon = function (input) { var getJibProfilesCommon = function (input) {
var common = { var common = {};
dependencies: ["boot_jdk", "gnumake", "jtreg"],
configure_args: ["--with-default-make-target=all", "--enable-jtreg-failure-handler"], common.dependencies = ["boot_jdk", "gnumake", "jtreg"],
configure_args_32bit: ["--with-target-bits=32", "--with-jvm-variants=client,server"], common.default_make_targets = ["product-images", "test-image"],
configure_args_debug: ["--enable-debug"], common.default_make_targets_debug = common.default_make_targets;
configure_args_slowdebug: ["--with-debug-level=slowdebug"], common.default_make_targets_slowdebug = common.default_make_targets;
organization: "jpg.infra.builddeps" common.configure_args = ["--enable-jtreg-failure-handler"],
}; common.configure_args_32bit = ["--with-target-bits=32", "--with-jvm-variants=client,server"],
common.configure_args_debug = ["--enable-debug"],
common.configure_args_slowdebug = ["--with-debug-level=slowdebug"],
common.organization = "jpg.infra.builddeps"
return common; return common;
}; };
@ -242,7 +245,7 @@ var getJibProfilesProfiles = function (input, common) {
target_cpu: "x64", target_cpu: "x64",
dependencies: concat(common.dependencies, "devkit"), dependencies: concat(common.dependencies, "devkit"),
configure_args: concat(common.configure_args, "--with-zlib=system"), configure_args: concat(common.configure_args, "--with-zlib=system"),
make_args: common.make_args default_make_targets: concat(common.default_make_targets, "docs-image")
}, },
"linux-x86": { "linux-x86": {
@ -252,7 +255,7 @@ var getJibProfilesProfiles = function (input, common) {
dependencies: concat(common.dependencies, "devkit"), dependencies: concat(common.dependencies, "devkit"),
configure_args: concat(common.configure_args, common.configure_args_32bit, configure_args: concat(common.configure_args, common.configure_args_32bit,
"--with-zlib=system"), "--with-zlib=system"),
make_args: common.make_args default_make_targets: common.default_make_targets
}, },
"macosx-x64": { "macosx-x64": {
@ -260,7 +263,7 @@ var getJibProfilesProfiles = function (input, common) {
target_cpu: "x64", target_cpu: "x64",
dependencies: concat(common.dependencies, "devkit"), dependencies: concat(common.dependencies, "devkit"),
configure_args: concat(common.configure_args, "--with-zlib=system"), configure_args: concat(common.configure_args, "--with-zlib=system"),
make_args: common.make_args default_make_targets: common.default_make_targets
}, },
"solaris-x64": { "solaris-x64": {
@ -268,7 +271,7 @@ var getJibProfilesProfiles = function (input, common) {
target_cpu: "x64", target_cpu: "x64",
dependencies: concat(common.dependencies, "devkit", "cups"), dependencies: concat(common.dependencies, "devkit", "cups"),
configure_args: concat(common.configure_args, "--with-zlib=system"), configure_args: concat(common.configure_args, "--with-zlib=system"),
make_args: common.make_args default_make_targets: common.default_make_targets
}, },
"solaris-sparcv9": { "solaris-sparcv9": {
@ -276,15 +279,15 @@ var getJibProfilesProfiles = function (input, common) {
target_cpu: "sparcv9", target_cpu: "sparcv9",
dependencies: concat(common.dependencies, "devkit", "cups"), dependencies: concat(common.dependencies, "devkit", "cups"),
configure_args: concat(common.configure_args, "--with-zlib=system"), configure_args: concat(common.configure_args, "--with-zlib=system"),
make_args: common.make_args default_make_targets: common.default_make_targets
}, },
"windows-x64": { "windows-x64": {
target_os: "windows", target_os: "windows",
target_cpu: "x64", target_cpu: "x64",
dependencies: concat(common.dependencies, "devkit", "freetype"), dependencies: concat(common.dependencies, "devkit", "freetype"),
configure_args: common.configure_args, configure_args: concat(common.configure_args),
make_args: common.make_args default_make_targets: common.default_make_targets
}, },
"windows-x86": { "windows-x86": {
@ -293,7 +296,7 @@ var getJibProfilesProfiles = function (input, common) {
build_cpu: "x64", build_cpu: "x64",
dependencies: concat(common.dependencies, "devkit", "freetype"), dependencies: concat(common.dependencies, "devkit", "freetype"),
configure_args: concat(common.configure_args, common.configure_args_32bit), configure_args: concat(common.configure_args, common.configure_args_32bit),
make_args: common.make_args default_make_targets: common.default_make_targets
} }
}; };
profiles = concatObjects(profiles, mainProfiles); profiles = concatObjects(profiles, mainProfiles);
@ -306,14 +309,15 @@ var getJibProfilesProfiles = function (input, common) {
// implementation builds. // implementation builds.
var openOnlyProfiles = generateOpenOnlyProfiles(common, mainProfiles); var openOnlyProfiles = generateOpenOnlyProfiles(common, mainProfiles);
// The open only profiles on linux are used for reference builds and should // The open only profiles on linux are used for reference builds and should
// produce the compact profile images by default. // produce the compact profile images by default. This adds "profiles" as an
// extra default target.
var openOnlyProfilesExtra = { var openOnlyProfilesExtra = {
"linux-x64-open": { "linux-x64-open": {
configure_args: ["--with-default-make-target=all profiles"], default_make_targets: "profiles"
}, },
"linux-x86-open": { "linux-x86-open": {
configure_args: ["--with-default-make-target=all profiles"], default_make_targets: "profiles"
} }
}; };
var openOnlyProfiles = concatObjects(openOnlyProfiles, openOnlyProfilesExtra); var openOnlyProfiles = concatObjects(openOnlyProfiles, openOnlyProfilesExtra);
@ -336,6 +340,7 @@ var getJibProfilesProfiles = function (input, common) {
// Generate the missing platform attributes // Generate the missing platform attributes
profiles = generatePlatformAttributes(profiles); profiles = generatePlatformAttributes(profiles);
profiles = generateDefaultMakeTargetsConfigureArg(common, profiles);
return profiles; return profiles;
}; };
@ -469,6 +474,8 @@ var generateDebugProfiles = function (common, profiles) {
var debugProfile = profile + "-debug"; var debugProfile = profile + "-debug";
newProfiles[debugProfile] = clone(profiles[profile]); newProfiles[debugProfile] = clone(profiles[profile]);
newProfiles[debugProfile].debug_level = "fastdebug"; newProfiles[debugProfile].debug_level = "fastdebug";
newProfiles[debugProfile].default_make_targets
= common.default_make_targets_debug;
newProfiles[debugProfile].labels newProfiles[debugProfile].labels
= concat(newProfiles[debugProfile].labels || [], "debug"), = concat(newProfiles[debugProfile].labels || [], "debug"),
newProfiles[debugProfile].configure_args newProfiles[debugProfile].configure_args
@ -492,6 +499,8 @@ var generateSlowdebugProfiles = function (common, profiles) {
var debugProfile = profile + "-slowdebug"; var debugProfile = profile + "-slowdebug";
newProfiles[debugProfile] = clone(profiles[profile]); newProfiles[debugProfile] = clone(profiles[profile]);
newProfiles[debugProfile].debug_level = "slowdebug"; newProfiles[debugProfile].debug_level = "slowdebug";
newProfiles[debugProfile].default_make_targets
= common.default_make_targets_slowdebug;
newProfiles[debugProfile].labels newProfiles[debugProfile].labels
= concat(newProfiles[debugProfile].labels || [], "slowdebug"), = concat(newProfiles[debugProfile].labels || [], "slowdebug"),
newProfiles[debugProfile].configure_args newProfiles[debugProfile].configure_args
@ -523,6 +532,39 @@ var generateOpenOnlyProfiles = function (common, profiles) {
return newProfiles; return newProfiles;
}; };
/**
* The default_make_targets attribute on a profile is not a real Jib attribute.
* This function rewrites that attribute into the corresponding configure arg.
* Calling this function multiple times on the same profiles object is safe.
*
* @param common Common values
* @param profiles Profiles map to rewrite profiles for
* @returns {{}} New map of profiles with the make targets converted
*/
var generateDefaultMakeTargetsConfigureArg = function (common, profiles) {
var ret = concatObjects(profiles, {});
for (var profile in ret) {
if (ret[profile]["default_make_targets"] != null) {
var targetsString = concat(ret[profile].default_make_targets).join(" ");
// Iterate over all configure args and see if --with-default-make-target
// is already there and change it, otherwise add it.
var found = false;
for (var arg in ret[profile].configure_args) {
if (arg.startsWith("--with-default-make-target")) {
found = true;
arg.replace(/=.*/, "=" + targetsString);
}
}
if (!found) {
ret[profile].configure_args = concat(
ret[profile].configure_args,
"--with-default-make-target=" + targetsString);
}
}
}
return ret;
}
/** /**
* Deep clones an object tree. * Deep clones an object tree.
* *

View File

@ -358,3 +358,4 @@ b75afa17aefe480c23c616a6a2497063312f7189 jdk-9+109
cc30faa2da498c478e89ab062ff160653ca1b170 jdk-9+113 cc30faa2da498c478e89ab062ff160653ca1b170 jdk-9+113
10d175b0368c30f54350fc648adc41b94ce357ee jdk-9+114 10d175b0368c30f54350fc648adc41b94ce357ee jdk-9+114
7bab1b1b36824924b1c657a8419369ba93d198d3 jdk-9+115 7bab1b1b36824924b1c657a8419369ba93d198d3 jdk-9+115
7dfa7377a5e601b8f740741a9a80e04c72dd04d6 jdk-9+116

View File

@ -518,3 +518,4 @@ c558850fac5750d8ca98a45180121980f57cdd28 jdk-9+111
c569f8d89269fb6205b90f727581eb8cc04132f9 jdk-9+113 c569f8d89269fb6205b90f727581eb8cc04132f9 jdk-9+113
b64432bae5271735fd53300b2005b713e98ef411 jdk-9+114 b64432bae5271735fd53300b2005b713e98ef411 jdk-9+114
88dd08d7be0fe7fb9f1914b1628f0aae9bf56e25 jdk-9+115 88dd08d7be0fe7fb9f1914b1628f0aae9bf56e25 jdk-9+115
61a214186dae6811dd989e9165e42f7dbf02acde jdk-9+116

View File

@ -358,3 +358,4 @@ bdbf2342b21bd8ecad1b4e6499a0dfb314952bd7 jdk-9+103
28626780e245fccbfb9bad8e3b05f62357958038 jdk-9+113 28626780e245fccbfb9bad8e3b05f62357958038 jdk-9+113
147114dd0641cd7c9fe6e81642eb993a7b9c6f0b jdk-9+114 147114dd0641cd7c9fe6e81642eb993a7b9c6f0b jdk-9+114
1902a5bda18e794b31fc5f520f5e7d827714b50d jdk-9+115 1902a5bda18e794b31fc5f520f5e7d827714b50d jdk-9+115
9d71d20e614777cd23c1a43b38b5c08a9094d27a jdk-9+116

View File

@ -444,13 +444,15 @@ public class CatalogFeatures {
} }
} else if (index == Feature.FILES.ordinal()) { } else if (index == Feature.FILES.ordinal()) {
try { try {
if (Util.verifyAndGetURI(value, null) == null) { String[] catalogFile = value.split(";[ ]*");
for (String temp : catalogFile) {
if (Util.verifyAndGetURI(temp, null) == null) {
CatalogMessages.reportIAE(new Object[]{value, Feature.FILES.name()}, null); CatalogMessages.reportIAE(new Object[]{value, Feature.FILES.name()}, null);
} }
}
}catch (MalformedURLException | URISyntaxException | IllegalArgumentException ex) { }catch (MalformedURLException | URISyntaxException | IllegalArgumentException ex) {
CatalogMessages.reportIAE(new Object[]{value, Feature.FILES.name()}, ex); CatalogMessages.reportIAE(new Object[]{value, Feature.FILES.name()}, ex);
} }
} }
if (states[index] == null || state.compareTo(states[index]) >= 0) { if (states[index] == null || state.compareTo(states[index]) >= 0) {
values[index] = value; values[index] = value;

View File

@ -91,6 +91,7 @@ public class TestPolicy extends Policy {
permissions.add(new PropertyPermission("line.separator", "read")); permissions.add(new PropertyPermission("line.separator", "read"));
permissions.add(new PropertyPermission("fileStringBuffer", "read")); permissions.add(new PropertyPermission("fileStringBuffer", "read"));
permissions.add(new PropertyPermission("dataproviderthreadcount", "read")); permissions.add(new PropertyPermission("dataproviderthreadcount", "read"));
permissions.add(new RuntimePermission("charsetProvider"));
} }
/* /*

View File

@ -23,6 +23,7 @@
package catalog; package catalog;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Paths;
import javax.xml.catalog.Catalog; import javax.xml.catalog.Catalog;
import javax.xml.catalog.CatalogException; import javax.xml.catalog.CatalogException;
import javax.xml.catalog.CatalogFeatures; import javax.xml.catalog.CatalogFeatures;
@ -34,6 +35,7 @@ import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.SAXParserFactory;
import org.testng.Assert; import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider; import org.testng.annotations.DataProvider;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import org.xml.sax.Attributes; import org.xml.sax.Attributes;
@ -44,10 +46,49 @@ import org.xml.sax.XMLReader;
import org.xml.sax.ext.DefaultHandler2; import org.xml.sax.ext.DefaultHandler2;
/* /*
* @bug 8081248, 8144966, 8146606, 8146237, 8151154, 8150969, 8151162, 8152527 * @bug 8081248, 8144966, 8146606, 8146237, 8151154, 8150969, 8151162, 8152527, 8154220
* @summary Tests basic Catalog functions. * @summary Tests basic Catalog functions.
*/ */
public class CatalogTest { public class CatalogTest {
static final String KEY_FILES = "javax.xml.catalog.files";
public String filepath;
/*
* Initializing fields
*/
@BeforeClass
public void setUpClass() throws Exception {
String file1 = getClass().getResource("first_cat.xml").getFile();
if (System.getProperty("os.name").contains("Windows")) {
filepath = file1.substring(1, file1.lastIndexOf("/") + 1);
} else {
filepath = file1.substring(0, file1.lastIndexOf("/") + 1);
}
}
/*
* @bug 8154220
* Verifies that the file input is validated properly. Valid input includes
* multiple file paths separated by semicolon.
*/
@Test(dataProvider = "hierarchyOfCatFilesData")
public void hierarchyOfCatFiles2(String systemId, String expectedUri) {
String file1 = getClass().getResource("first_cat.xml").getFile();
String file2 = getClass().getResource("second_cat.xml").getFile();
String files = file1 + ";" + file2;
try {
System.setProperty(KEY_FILES, files);
CatalogResolver catalogResolver = CatalogManager.catalogResolver(CatalogFeatures.defaults());
String sysId = catalogResolver.resolveEntity(null, systemId).getSystemId();
Assert.assertEquals(sysId, Paths.get(filepath + expectedUri).toUri().toString().replace("///", "/"), "System ID match not right");
} finally {
System.clearProperty(KEY_FILES);
}
}
/* /*
* @bug 8152527 * @bug 8152527
* This test is the same as the JDK test ResolveEntityTests:testMatch1. * This test is the same as the JDK test ResolveEntityTests:testMatch1.
@ -288,6 +329,19 @@ public class CatalogTest {
} }
} }
/*
DataProvider: used to verify hierarchical catalogs. Refer to JCK test
hierarchyOfCatFiles2.
*/
@DataProvider(name = "hierarchyOfCatFilesData")
Object[][] getHierarchyOfCatFilesData() {
return new Object[][]{
{"http://www.oracle.com/sequence.dtd", "first.dtd"},
{"http://www.oracle.com/sequence_next.dtd", "next.dtd"},
{"http://www.oracle.com/sequence_second.dtd", "second.dtd"}
};
}
/* /*
DataProvider: used to verify CatalogResolver's resolveEntity function. DataProvider: used to verify CatalogResolver's resolveEntity function.
Data columns: Data columns:
@ -300,6 +354,7 @@ public class CatalogTest {
{"rewriteSystem_id.xml", "system", "http://www.sys00test.com/rewrite.dtd", "PUB-404", expected, expected, "Relative rewriteSystem with xml:base at group level failed"}, {"rewriteSystem_id.xml", "system", "http://www.sys00test.com/rewrite.dtd", "PUB-404", expected, expected, "Relative rewriteSystem with xml:base at group level failed"},
}; };
} }
static String id = "http://openjdk.java.net/xml/catalog/dtd/system.dtd"; static String id = "http://openjdk.java.net/xml/catalog/dtd/system.dtd";
/* /*
DataProvider: used to verify how prefer settings affect the result of the DataProvider: used to verify how prefer settings affect the result of the

View File

@ -0,0 +1,6 @@
<catalog prefer="system" xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<system systemId="http://www.oracle.com/sequence.dtd" uri="first.dtd"/>
<nextCatalog catalog="next_cat.xml"/>
</catalog>

View File

@ -0,0 +1,6 @@
<catalog prefer="public" xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<system systemId="http://www.oracle.com/sequence.dtd" uri="next.dtd"/>
<system systemId="http://www.oracle.com/sequence_next.dtd" uri="next.dtd"/>
</catalog>

View File

@ -0,0 +1,7 @@
<catalog prefer="public" xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<system systemId="http://www.oracle.com/sequence.dtd" uri="second.dtd"/>
<system systemId="http://www.oracle.com/sequence_next.dtd" uri="second.dtd"/>
<system systemId="http://www.oracle.com/sequence_second.dtd" uri="second.dtd"/>
</catalog>

View File

@ -358,3 +358,4 @@ b2a69d66dc65ad1d3aeb3bd362cf5bb0deba040e jdk-9+111
68f8be44b6a6b33dfa841ec671c0ba6e4056b372 jdk-9+113 68f8be44b6a6b33dfa841ec671c0ba6e4056b372 jdk-9+113
bb8379287f3736f38c52b2d1418784e2592461d1 jdk-9+114 bb8379287f3736f38c52b2d1418784e2592461d1 jdk-9+114
35225b837d66582037eeadeb471c13235dfd793d jdk-9+115 35225b837d66582037eeadeb471c13235dfd793d jdk-9+115
baeb5edb38939cdb78ae0ac6f4fd368465cbf188 jdk-9+116

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -41,7 +41,7 @@ include GendataPolicyJars.gmk
GENDATA_UNINAME := $(JDK_OUTPUTDIR)/modules/java.base/java/lang/uniName.dat GENDATA_UNINAME := $(JDK_OUTPUTDIR)/modules/java.base/java/lang/uniName.dat
$(GENDATA_UNINAME): $(JDK_TOPDIR)/make/data/unicodedata/UnicodeData.txt $(BUILD_TOOLS_JDK) $(GENDATA_UNINAME): $(JDK_TOPDIR)/make/data/unicodedata/UnicodeData.txt $(BUILD_TOOLS_JDK)
$(MKDIR) -p $(@D) $(call MakeDir, $(@D))
$(TOOL_CHARACTERNAME) $< $@ $(TOOL_CHARACTERNAME) $< $@
TARGETS += $(GENDATA_UNINAME) TARGETS += $(GENDATA_UNINAME)
@ -51,7 +51,7 @@ TARGETS += $(GENDATA_UNINAME)
GENDATA_CURDATA := $(JDK_OUTPUTDIR)/modules/java.base/java/util/currency.data GENDATA_CURDATA := $(JDK_OUTPUTDIR)/modules/java.base/java/util/currency.data
$(GENDATA_CURDATA): $(JDK_TOPDIR)/make/data/currency/CurrencyData.properties $(BUILD_TOOLS_JDK) $(GENDATA_CURDATA): $(JDK_TOPDIR)/make/data/currency/CurrencyData.properties $(BUILD_TOOLS_JDK)
$(MKDIR) -p $(@D) $(call MakeDir, $(@D))
$(RM) $@ $(RM) $@
$(TOOL_GENERATECURRENCYDATA) -o $@.tmp < $< $(TOOL_GENERATECURRENCYDATA) -o $@.tmp < $<
$(MV) $@.tmp $@ $(MV) $@.tmp $@
@ -67,10 +67,10 @@ GENDATA_JAVA_SECURITY := $(SUPPORT_OUTPUTDIR)/modules_conf/java.base/security/ja
# RESTRICTED_PKGS_SRC is optionally set in custom extension for this makefile # RESTRICTED_PKGS_SRC is optionally set in custom extension for this makefile
$(GENDATA_JAVA_SECURITY): $(BUILD_TOOLS) $(GENDATA_JAVA_SECURITY_SRC) $(RESTRICTED_PKGS_SRC) $(GENDATA_JAVA_SECURITY): $(BUILD_TOOLS) $(GENDATA_JAVA_SECURITY_SRC) $(RESTRICTED_PKGS_SRC)
$(ECHO) "Generating java.security" $(call LogInfo, Generating java.security)
$(MKDIR) -p $(@D) $(call MakeDir, $(@D))
$(TOOL_MAKEJAVASECURITY) $(GENDATA_JAVA_SECURITY_SRC) $@ $(OPENJDK_TARGET_OS) \ $(TOOL_MAKEJAVASECURITY) $(GENDATA_JAVA_SECURITY_SRC) $@ $(OPENJDK_TARGET_OS) \
$(OPENJDK_TARGET_CPU_ARCH) $(RESTRICTED_PKGS_SRC) || exit 1 $(OPENJDK_TARGET_CPU_ARCH) $(RESTRICTED_PKGS_SRC)
TARGETS += $(GENDATA_JAVA_SECURITY) TARGETS += $(GENDATA_JAVA_SECURITY)
@ -78,7 +78,7 @@ TARGETS += $(GENDATA_JAVA_SECURITY)
$(SUPPORT_OUTPUTDIR)/modules_libs/java.base/classlist: \ $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/classlist: \
$(JDK_TOPDIR)/make/data/classlist/classlist.$(OPENJDK_TARGET_OS) $(JDK_TOPDIR)/make/data/classlist/classlist.$(OPENJDK_TARGET_OS)
$(MKDIR) -p $(@D) $(call MakeDir, $(@D))
$(RM) $@ $@.tmp $(RM) $@ $@.tmp
$(TOOL_ADDJSUM) $< $@.tmp $(TOOL_ADDJSUM) $< $@.tmp
$(MV) $@.tmp $@ $(MV) $@.tmp $@

View File

@ -0,0 +1,51 @@
#
# Copyright (c) 2016, 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.
#
include LibCommon.gmk
################################################################################
ifeq ($(OPENJDK_TARGET_OS), solaris)
$(eval $(call SetupNativeCompilation, BUILD_LIBEXTNET, \
LIBRARY := extnet, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(JDK_TOPDIR)/src/jdk.net/solaris/native/libextnet, \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/jdk.net, \
MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libextnet/mapfile-vers, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LIBS := -lsocket -lc -ljava, \
OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libextnet, \
))
$(BUILD_LIBEXTNET): $(call FindLib, java.base, java)
TARGETS += $(BUILD_LIBEXTNET)
endif
################################################################################

View File

@ -179,6 +179,7 @@ SUNWprivate_1.1 {
Java_sun_awt_UNIXToolkit_load_1gtk_1icon; Java_sun_awt_UNIXToolkit_load_1gtk_1icon;
Java_sun_awt_UNIXToolkit_nativeSync; Java_sun_awt_UNIXToolkit_nativeSync;
Java_sun_awt_UNIXToolkit_gtkCheckVersionImpl; Java_sun_awt_UNIXToolkit_gtkCheckVersionImpl;
Java_sun_awt_UNIXToolkit_get_1gtk_1version;
Java_java_awt_AWTEvent_initIDs; Java_java_awt_AWTEvent_initIDs;
Java_java_awt_event_InputEvent_initIDs; Java_java_awt_event_InputEvent_initIDs;
Java_java_awt_event_KeyEvent_initIDs; Java_java_awt_event_KeyEvent_initIDs;

View File

@ -0,0 +1,34 @@
#
# Copyright (c) 2016, 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.
#
SUNWprivate_1.1 {
global:
Java_jdk_net_SolarisSocketOptions_init;
Java_jdk_net_SolarisSocketOptions_setFlowOption;
Java_jdk_net_SolarisSocketOptions_getFlowOption;
Java_jdk_net_SolarisSocketOptions_flowSupported;
local:
*;
};

View File

@ -98,10 +98,6 @@ SUNWprivate_1.1 {
Java_sun_net_sdp_SdpSupport_create0; Java_sun_net_sdp_SdpSupport_create0;
Java_sun_net_spi_DefaultProxySelector_init; Java_sun_net_spi_DefaultProxySelector_init;
Java_sun_net_spi_DefaultProxySelector_getSystemProxy; Java_sun_net_spi_DefaultProxySelector_getSystemProxy;
Java_sun_net_ExtendedOptionsImpl_init;
Java_sun_net_ExtendedOptionsImpl_setFlowOption;
Java_sun_net_ExtendedOptionsImpl_getFlowOption;
Java_sun_net_ExtendedOptionsImpl_flowSupported;
NET_AllocSockaddr; NET_AllocSockaddr;
NET_SockaddrToInetAddress; NET_SockaddrToInetAddress;
NET_SockaddrEqualsInetAddress; NET_SockaddrEqualsInetAddress;

View File

@ -3,6 +3,6 @@ build.xml.script.CRC32=f902e8b8
build.xml.stylesheet.CRC32=8064a381@1.75.2.48 build.xml.stylesheet.CRC32=8064a381@1.75.2.48
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=55414227 nbproject/build-impl.xml.data.CRC32=16caf60f
nbproject/build-impl.xml.script.CRC32=c12f9d04 nbproject/build-impl.xml.script.CRC32=c12f9d04
nbproject/build-impl.xml.stylesheet.CRC32=05530350@1.79.1.48 nbproject/build-impl.xml.stylesheet.CRC32=05530350@1.79.1.48

View File

@ -76,4 +76,4 @@ source.encoding=UTF-8
src.src.dir=..\\..\\..\\test\\sanity\\client\\SwingSet\\src src.src.dir=..\\..\\..\\test\\sanity\\client\\SwingSet\\src
src.src2.dir=..\\..\\..\\test\\sanity\\client\\lib\\SwingSet3\\src src.src2.dir=..\\..\\..\\test\\sanity\\client\\lib\\SwingSet3\\src
src.src3.dir=..\\..\\..\\test\\sanity\\client\\lib\\jemmy\\src src.src3.dir=..\\..\\..\\test\\sanity\\client\\lib\\jemmy\\src
src.src4.dir=..\\..\\..\\test\\sanity\\client\\lib\\Jemmy2Ext\\src src.src4.dir=..\\..\\..\\test\\sanity\\client\\lib\\Extensions\\src

View File

@ -6,7 +6,7 @@
<name>SanityTests</name> <name>SanityTests</name>
<source-roots> <source-roots>
<root id="src.src3.dir" name="lib\jemmy\src"/> <root id="src.src3.dir" name="lib\jemmy\src"/>
<root id="src.src4.dir" name="lib\Jemmy2Ext\src"/> <root id="src.src4.dir" name="lib\Extensions\src"/>
<root id="src.src2.dir" name="lib\SwingSet3\src"/> <root id="src.src2.dir" name="lib\SwingSet3\src"/>
<root id="src.src.dir" name="SwingSet\src"/> <root id="src.src.dir" name="SwingSet\src"/>
</source-roots> </source-roots>

View File

@ -54,13 +54,13 @@ class UIProperty extends UIDefault<String> {
return String.format(" d.put(\"%s%s\", \"%s\");\n", return String.format(" d.put(\"%s%s\", \"%s\");\n",
prefix, getName(), getValue()); prefix, getName(), getValue());
case INT: case INT:
return String.format(" d.put(\"%s%s\", new Integer(%s));\n", return String.format(" d.put(\"%s%s\", Integer.valueOf(%s));\n",
prefix, getName(), getValue()); prefix, getName(), getValue());
case FLOAT: case FLOAT:
return String.format(" d.put(\"%s%s\", new Float(%sf));\n", return String.format(" d.put(\"%s%s\", Float.valueOf(%sf));\n",
prefix, getName(), getValue()); prefix, getName(), getValue());
case DOUBLE: case DOUBLE:
return String.format(" d.put(\"%s%s\", new Double(%s));\n", return String.format(" d.put(\"%s%s\", Double.valueOf(%s));\n",
prefix, getName(), getValue()); prefix, getName(), getValue());
case COLOR: case COLOR:
return String.format(" addColor(d, \"%s%s\", %s);\n", return String.format(" addColor(d, \"%s%s\", %s);\n",

View File

@ -52,7 +52,7 @@ public class GenModuleInfoSource {
"Usage: GenModuleInfoSource [option] -o <output file> <module-info-java>\n" + "Usage: GenModuleInfoSource [option] -o <output file> <module-info-java>\n" +
"Options are:\n" + "Options are:\n" +
" -exports <package-name>\n" + " -exports <package-name>\n" +
" -exports <package-name>/<module-name>\n" + " -exports <package-name>[/<module-name>]\n" +
" -uses <service>\n" + " -uses <service>\n" +
" -provides <service>/<provider-impl-classname>\n"; " -provides <service>/<provider-impl-classname>\n";

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1994, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -78,14 +78,8 @@ import jdk.internal.vm.annotation.Stable;
* <p> * <p>
* The Java language provides special support for the string * The Java language provides special support for the string
* concatenation operator (&nbsp;+&nbsp;), and for conversion of * concatenation operator (&nbsp;+&nbsp;), and for conversion of
* other objects to strings. String concatenation is implemented * other objects to strings. For additional information on string
* through the {@code StringBuilder}(or {@code StringBuffer}) * concatenation and conversion, see <i>The Java&trade; Language Specification</i>.
* class and its {@code append} method.
* String conversions are implemented through the method
* {@code toString}, defined by {@code Object} and
* inherited by all classes in Java. For additional information on
* string concatenation and conversion, see Gosling, Joy, and Steele,
* <i>The Java Language Specification</i>.
* *
* <p> Unless otherwise noted, passing a {@code null} argument to a constructor * <p> Unless otherwise noted, passing a {@code null} argument to a constructor
* or method in this class will cause a {@link NullPointerException} to be * or method in this class will cause a {@link NullPointerException} to be
@ -106,6 +100,14 @@ import jdk.internal.vm.annotation.Stable;
* into account. The {@link java.text.Collator} class provides methods for * into account. The {@link java.text.Collator} class provides methods for
* finer-grain, locale-sensitive String comparison. * finer-grain, locale-sensitive String comparison.
* *
* @implNote The implementation of the string concatenation operator is left to
* the discretion of a Java compiler, as long as the compiler ultimately conforms
* to <i>The Java&trade; Language Specification</i>. For example, the {@code javac} compiler
* may implement the operator with {@code StringBuffer}, {@code StringBuilder},
* or {@code java.lang.invoke.StringConcatFactory} depending on the JDK version. The
* implementation of string conversion is typically through the method {@code toString},
* defined by {@code Object} and inherited by all classes in Java.
*
* @author Lee Boynton * @author Lee Boynton
* @author Arthur van Hoff * @author Arthur van Hoff
* @author Martin Buchholz * @author Martin Buchholz
@ -115,6 +117,7 @@ import jdk.internal.vm.annotation.Stable;
* @see java.lang.StringBuilder * @see java.lang.StringBuilder
* @see java.nio.charset.Charset * @see java.nio.charset.Charset
* @since 1.0 * @since 1.0
* @jls 15.18.1 String Concatenation Operator +
*/ */
public final class String public final class String
@ -2977,6 +2980,7 @@ public final class String
* *
* @return a string that has the same contents as this string, but is * @return a string that has the same contents as this string, but is
* guaranteed to be from a pool of unique strings. * guaranteed to be from a pool of unique strings.
* @jls 3.10.5 String Literals
*/ */
public native String intern(); public native String intern();

View File

@ -1155,8 +1155,9 @@ public final class System {
* @param level the log message level. * @param level the log message level.
* @param msg the string message (or a key in the message catalog, if * @param msg the string message (or a key in the message catalog, if
* this logger is a {@link * this logger is a {@link
* LoggerFinder#getLocalizedLogger(java.lang.String, java.util.ResourceBundle, java.lang.Class) * LoggerFinder#getLocalizedLogger(java.lang.String,
* localized logger}); can be {@code null}. * java.util.ResourceBundle, java.lang.reflect.Module) localized logger});
* can be {@code null}.
* *
* @throws NullPointerException if {@code level} is {@code null}. * @throws NullPointerException if {@code level} is {@code null}.
*/ */
@ -1222,8 +1223,9 @@ public final class System {
* @param level the log message level. * @param level the log message level.
* @param msg the string message (or a key in the message catalog, if * @param msg the string message (or a key in the message catalog, if
* this logger is a {@link * this logger is a {@link
* LoggerFinder#getLocalizedLogger(java.lang.String, java.util.ResourceBundle, java.lang.Class) * LoggerFinder#getLocalizedLogger(java.lang.String,
* localized logger}); can be {@code null}. * java.util.ResourceBundle, java.lang.reflect.Module) localized logger});
* can be {@code null}.
* @param thrown a {@code Throwable} associated with the log message; * @param thrown a {@code Throwable} associated with the log message;
* can be {@code null}. * can be {@code null}.
* *
@ -1270,8 +1272,9 @@ public final class System {
* @param format the string message format in {@link * @param format the string message format in {@link
* java.text.MessageFormat} format, (or a key in the message * java.text.MessageFormat} format, (or a key in the message
* catalog, if this logger is a {@link * catalog, if this logger is a {@link
* LoggerFinder#getLocalizedLogger(java.lang.String, java.util.ResourceBundle, java.lang.Class) * LoggerFinder#getLocalizedLogger(java.lang.String,
* localized logger}); can be {@code null}. * java.util.ResourceBundle, java.lang.reflect.Module) localized logger});
* can be {@code null}.
* @param params an optional list of parameters to the message (may be * @param params an optional list of parameters to the message (may be
* none). * none).
* *
@ -1453,30 +1456,30 @@ public final class System {
/** /**
* Returns an instance of {@link Logger Logger} * Returns an instance of {@link Logger Logger}
* for the given {@code caller}. * for the given {@code module}.
* *
* @param name the name of the logger. * @param name the name of the logger.
* @param caller the class for which the logger is being requested. * @param module the module for which the logger is being requested.
* *
* @return a {@link Logger logger} suitable for the given caller's * @return a {@link Logger logger} suitable for use within the given
* use. * module.
* @throws NullPointerException if {@code name} is {@code null} or * @throws NullPointerException if {@code name} is {@code null} or
* {@code caller} is {@code null}. * {@code module} is {@code null}.
* @throws SecurityException if a security manager is present and its * @throws SecurityException if a security manager is present and its
* {@code checkPermission} method doesn't allow the * {@code checkPermission} method doesn't allow the
* {@code RuntimePermission("loggerFinder")}. * {@code RuntimePermission("loggerFinder")}.
*/ */
public abstract Logger getLogger(String name, /* Module */ Class<?> caller); public abstract Logger getLogger(String name, Module module);
/** /**
* Returns a localizable instance of {@link Logger Logger} * Returns a localizable instance of {@link Logger Logger}
* for the given {@code caller}. * for the given {@code module}.
* The returned logger will use the provided resource bundle for * The returned logger will use the provided resource bundle for
* message localization. * message localization.
* *
* @implSpec By default, this method calls {@link * @implSpec By default, this method calls {@link
* #getLogger(java.lang.String, java.lang.Class) * #getLogger(java.lang.String, java.lang.reflect.Module)
* this.getLogger(name, caller)} to obtain a logger, then wraps that * this.getLogger(name, module)} to obtain a logger, then wraps that
* logger in a {@link Logger} instance where all methods that do not * logger in a {@link Logger} instance where all methods that do not
* take a {@link ResourceBundle} as parameter are redirected to one * take a {@link ResourceBundle} as parameter are redirected to one
* which does - passing the given {@code bundle} for * which does - passing the given {@code bundle} for
@ -1499,19 +1502,19 @@ public final class System {
* *
* @param name the name of the logger. * @param name the name of the logger.
* @param bundle a resource bundle; can be {@code null}. * @param bundle a resource bundle; can be {@code null}.
* @param caller the class for which the logger is being requested. * @param module the module for which the logger is being requested.
* @return an instance of {@link Logger Logger} which will use the * @return an instance of {@link Logger Logger} which will use the
* provided resource bundle for message localization. * provided resource bundle for message localization.
* *
* @throws NullPointerException if {@code name} is {@code null} or * @throws NullPointerException if {@code name} is {@code null} or
* {@code caller} is {@code null}. * {@code module} is {@code null}.
* @throws SecurityException if a security manager is present and its * @throws SecurityException if a security manager is present and its
* {@code checkPermission} method doesn't allow the * {@code checkPermission} method doesn't allow the
* {@code RuntimePermission("loggerFinder")}. * {@code RuntimePermission("loggerFinder")}.
*/ */
public Logger getLocalizedLogger(String name, ResourceBundle bundle, public Logger getLocalizedLogger(String name, ResourceBundle bundle,
/* Module */ Class<?> caller) { Module module) {
return new LocalizedLoggerWrapper<>(getLogger(name, caller), bundle); return new LocalizedLoggerWrapper<>(getLogger(name, module), bundle);
} }
/** /**
@ -1558,12 +1561,13 @@ public final class System {
* *
* @implSpec * @implSpec
* Instances returned by this method route messages to loggers * Instances returned by this method route messages to loggers
* obtained by calling {@link LoggerFinder#getLogger(java.lang.String, java.lang.Class) * obtained by calling {@link LoggerFinder#getLogger(java.lang.String,
* LoggerFinder.getLogger(name, caller)}. * java.lang.reflect.Module) LoggerFinder.getLogger(name, module)}, where
* {@code module} is the caller's module.
* *
* @apiNote * @apiNote
* This method may defer calling the {@link * This method may defer calling the {@link
* LoggerFinder#getLogger(java.lang.String, java.lang.Class) * LoggerFinder#getLogger(java.lang.String, java.lang.reflect.Module)
* LoggerFinder.getLogger} method to create an actual logger supplied by * LoggerFinder.getLogger} method to create an actual logger supplied by
* the logging backend, for instance, to allow loggers to be obtained during * the logging backend, for instance, to allow loggers to be obtained during
* the system initialization time. * the system initialization time.
@ -1579,7 +1583,7 @@ public final class System {
public static Logger getLogger(String name) { public static Logger getLogger(String name) {
Objects.requireNonNull(name); Objects.requireNonNull(name);
final Class<?> caller = Reflection.getCallerClass(); final Class<?> caller = Reflection.getCallerClass();
return LazyLoggers.getLogger(name, caller); return LazyLoggers.getLogger(name, caller.getModule());
} }
/** /**
@ -1591,8 +1595,9 @@ public final class System {
* @implSpec * @implSpec
* The returned logger will perform message localization as specified * The returned logger will perform message localization as specified
* by {@link LoggerFinder#getLocalizedLogger(java.lang.String, * by {@link LoggerFinder#getLocalizedLogger(java.lang.String,
* java.util.ResourceBundle, java.lang.Class) * java.util.ResourceBundle, java.lang.reflect.Module)
* LoggerFinder.getLocalizedLogger(name, bundle, caller}. * LoggerFinder.getLocalizedLogger(name, bundle, module}, where
* {@code module} is the caller's module.
* *
* @apiNote * @apiNote
* This method is intended to be used after the system is fully initialized. * This method is intended to be used after the system is fully initialized.
@ -1624,12 +1629,14 @@ public final class System {
// Bootstrap sensitive classes in the JDK do not use resource bundles // Bootstrap sensitive classes in the JDK do not use resource bundles
// when logging. This could be revisited later, if it needs to. // when logging. This could be revisited later, if it needs to.
if (sm != null) { if (sm != null) {
return AccessController.doPrivileged((PrivilegedAction<Logger>) final PrivilegedAction<Logger> pa =
() -> LoggerFinder.accessProvider().getLocalizedLogger(name, rb, caller), () -> LoggerFinder.accessProvider()
null, .getLocalizedLogger(name, rb, caller.getModule());
return AccessController.doPrivileged(pa, null,
LoggerFinder.LOGGERFINDER_PERMISSION); LoggerFinder.LOGGERFINDER_PERMISSION);
} }
return LoggerFinder.accessProvider().getLocalizedLogger(name, rb, caller); return LoggerFinder.accessProvider()
.getLocalizedLogger(name, rb, caller.getModule());
} }
/** /**

View File

@ -25,6 +25,7 @@
package java.lang.invoke; package java.lang.invoke;
import java.lang.reflect.Array;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.util.Arrays; import java.util.Arrays;
@ -1892,7 +1893,8 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
MH_tryFinallyExec = 12, MH_tryFinallyExec = 12,
MH_tryFinallyVoidExec = 13, MH_tryFinallyVoidExec = 13,
MH_decrementCounter = 14, MH_decrementCounter = 14,
MH_LIMIT = 15; MH_Array_newInstance = 15,
MH_LIMIT = 16;
static MethodHandle getConstantHandle(int idx) { static MethodHandle getConstantHandle(int idx) {
MethodHandle handle = HANDLES[idx]; MethodHandle handle = HANDLES[idx];
@ -1965,6 +1967,9 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
case MH_decrementCounter: case MH_decrementCounter:
return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "decrementCounter", return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "decrementCounter",
MethodType.methodType(int.class, int.class)); MethodType.methodType(int.class, int.class));
case MH_Array_newInstance:
return IMPL_LOOKUP.findStatic(Array.class, "newInstance",
MethodType.methodType(Object.class, Class.class, int.class));
} }
} catch (ReflectiveOperationException ex) { } catch (ReflectiveOperationException ex) {
throw newInternalError(ex); throw newInternalError(ex);

View File

@ -25,34 +25,38 @@
package java.lang.invoke; package java.lang.invoke;
import java.lang.reflect.*; import jdk.internal.org.objectweb.asm.ClassWriter;
import java.util.ArrayList; import jdk.internal.org.objectweb.asm.Opcodes;
import java.util.BitSet; import jdk.internal.reflect.CallerSensitive;
import java.util.Iterator; import jdk.internal.reflect.Reflection;
import java.util.List;
import java.util.Arrays;
import java.util.Objects;
import java.security.AccessController;
import java.security.PrivilegedAction;
import sun.invoke.util.ValueConversions; import sun.invoke.util.ValueConversions;
import sun.invoke.util.VerifyAccess; import sun.invoke.util.VerifyAccess;
import sun.invoke.util.Wrapper; import sun.invoke.util.Wrapper;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection;
import sun.reflect.misc.ReflectUtil; import sun.reflect.misc.ReflectUtil;
import sun.security.util.SecurityConstants; import sun.security.util.SecurityConstants;
import java.lang.invoke.LambdaForm.BasicType;
import static java.lang.invoke.MethodHandleImpl.Intrinsic; import java.lang.invoke.LambdaForm.BasicType;
import static java.lang.invoke.MethodHandleNatives.Constants.*; import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ReflectPermission;
import java.nio.ByteOrder;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import jdk.internal.org.objectweb.asm.ClassWriter; import static java.lang.invoke.MethodHandleImpl.Intrinsic;
import jdk.internal.org.objectweb.asm.Opcodes; import static java.lang.invoke.MethodHandleNatives.Constants.*;
import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException; import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
import static java.lang.invoke.MethodType.methodType; import static java.lang.invoke.MethodType.methodType;
@ -741,10 +745,13 @@ public class MethodHandles {
if (name.startsWith("java.lang.invoke.")) if (name.startsWith("java.lang.invoke."))
throw newIllegalArgumentException("illegal lookupClass: "+lookupClass); throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);
// For caller-sensitive MethodHandles.lookup() // For caller-sensitive MethodHandles.lookup() disallow lookup from
// disallow lookup more restricted packages // restricted packages. This a fragile and blunt approach.
// TODO replace with a more formal and less fragile mechanism
// that does not bluntly restrict classes under packages within
// java.base from looking up MethodHandles or VarHandles.
if (allowedModes == ALL_MODES && lookupClass.getClassLoader() == null) { if (allowedModes == ALL_MODES && lookupClass.getClassLoader() == null) {
if (name.startsWith("java.") || if ((name.startsWith("java.") && !name.startsWith("java.util.concurrent.")) ||
(name.startsWith("sun.") && !name.startsWith("sun.invoke."))) { (name.startsWith("sun.") && !name.startsWith("sun.invoke."))) {
throw newIllegalArgumentException("illegal lookupClass: " + lookupClass); throw newIllegalArgumentException("illegal lookupClass: " + lookupClass);
} }
@ -1003,6 +1010,9 @@ assertEquals("[x, y, z]", pb.command().toString());
* @throws NullPointerException if any argument is null * @throws NullPointerException if any argument is null
*/ */
public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException { public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
if (refc.isArray()) {
throw new NoSuchMethodException("no constructor for array class: " + refc.getName());
}
String name = "<init>"; String name = "<init>";
MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type); MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
return getDirectConstructor(refc, ctor); return getDirectConstructor(refc, ctor);
@ -2213,6 +2223,27 @@ return mh1;
static final Lookup PUBLIC_LOOKUP = new Lookup(PUBLIC_LOOKUP_CLASS, Lookup.PUBLIC); static final Lookup PUBLIC_LOOKUP = new Lookup(PUBLIC_LOOKUP_CLASS, Lookup.PUBLIC);
} }
/**
* Produces a method handle constructing arrays of a desired type.
* The return type of the method handle will be the array type.
* The type of its sole argument will be {@code int}, which specifies the size of the array.
* @param arrayClass an array type
* @return a method handle which can create arrays of the given type
* @throws NullPointerException if the argument is {@code null}
* @throws IllegalArgumentException if {@code arrayClass} is not an array type
* @see java.lang.reflect.Array#newInstance(Class, int)
* @since 9
*/
public static
MethodHandle arrayConstructor(Class<?> arrayClass) throws IllegalArgumentException {
if (!arrayClass.isArray()) {
throw newIllegalArgumentException("not an array class: " + arrayClass.getName());
}
MethodHandle ani = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_Array_newInstance).
bindTo(arrayClass.getComponentType());
return ani.asType(ani.type().changeReturnType(arrayClass));
}
/** /**
* Produces a method handle giving read access to elements of an array. * Produces a method handle giving read access to elements of an array.
* The type of the method handle will have a return type of the array's * The type of the method handle will have a return type of the array's
@ -2337,13 +2368,12 @@ return mh1;
* *
* @param viewArrayClass the view array class, with a component type of * @param viewArrayClass the view array class, with a component type of
* type {@code T} * type {@code T}
* @param bigEndian true if the endianness of the view array elements, as * @param byteOrder the endianness of the view array elements, as
* stored in the underlying {@code byte} array, is big endian, otherwise * stored in the underlying {@code byte} array
* little endian
* @return a VarHandle giving access to elements of a {@code byte[]} array * @return a VarHandle giving access to elements of a {@code byte[]} array
* viewed as if elements corresponding to the components type of the view * viewed as if elements corresponding to the components type of the view
* array class * array class
* @throws NullPointerException if viewArrayClass is null * @throws NullPointerException if viewArrayClass or byteOrder is null
* @throws IllegalArgumentException if viewArrayClass is not an array type * @throws IllegalArgumentException if viewArrayClass is not an array type
* @throws UnsupportedOperationException if the component type of * @throws UnsupportedOperationException if the component type of
* viewArrayClass is not supported as a variable type * viewArrayClass is not supported as a variable type
@ -2351,8 +2381,10 @@ return mh1;
*/ */
public static public static
VarHandle byteArrayViewVarHandle(Class<?> viewArrayClass, VarHandle byteArrayViewVarHandle(Class<?> viewArrayClass,
boolean bigEndian) throws IllegalArgumentException { ByteOrder byteOrder) throws IllegalArgumentException {
return VarHandles.byteArrayViewHandle(viewArrayClass, bigEndian); Objects.requireNonNull(byteOrder);
return VarHandles.byteArrayViewHandle(viewArrayClass,
byteOrder == ByteOrder.BIG_ENDIAN);
} }
/** /**
@ -2422,14 +2454,13 @@ return mh1;
* *
* @param viewArrayClass the view array class, with a component type of * @param viewArrayClass the view array class, with a component type of
* type {@code T} * type {@code T}
* @param bigEndian true if the endianness of the view array elements, as * @param byteOrder the endianness of the view array elements, as
* stored in the underlying {@code ByteBuffer}, is big endian, otherwise * stored in the underlying {@code ByteBuffer} (Note this overrides the
* little endian (Note this overrides the endianness of a * endianness of a {@code ByteBuffer})
* {@code ByteBuffer})
* @return a VarHandle giving access to elements of a {@code ByteBuffer} * @return a VarHandle giving access to elements of a {@code ByteBuffer}
* viewed as if elements corresponding to the components type of the view * viewed as if elements corresponding to the components type of the view
* array class * array class
* @throws NullPointerException if viewArrayClass is null * @throws NullPointerException if viewArrayClass or byteOrder is null
* @throws IllegalArgumentException if viewArrayClass is not an array type * @throws IllegalArgumentException if viewArrayClass is not an array type
* @throws UnsupportedOperationException if the component type of * @throws UnsupportedOperationException if the component type of
* viewArrayClass is not supported as a variable type * viewArrayClass is not supported as a variable type
@ -2437,8 +2468,10 @@ return mh1;
*/ */
public static public static
VarHandle byteBufferViewVarHandle(Class<?> viewArrayClass, VarHandle byteBufferViewVarHandle(Class<?> viewArrayClass,
boolean bigEndian) throws IllegalArgumentException { ByteOrder byteOrder) throws IllegalArgumentException {
return VarHandles.makeByteBufferViewHandle(viewArrayClass, bigEndian); Objects.requireNonNull(byteOrder);
return VarHandles.makeByteBufferViewHandle(viewArrayClass,
byteOrder == ByteOrder.BIG_ENDIAN);
} }

View File

@ -123,7 +123,7 @@ public final class StringConcatFactory {
* Concatenation strategy to use. See {@link Strategy} for possible options. * Concatenation strategy to use. See {@link Strategy} for possible options.
* This option is controllable with -Djava.lang.invoke.stringConcat JDK option. * This option is controllable with -Djava.lang.invoke.stringConcat JDK option.
*/ */
private static final Strategy STRATEGY; private static Strategy STRATEGY;
/** /**
* Default strategy to use for concatenation. * Default strategy to use for concatenation.
@ -187,6 +187,16 @@ public final class StringConcatFactory {
private static final ProxyClassesDumper DUMPER; private static final ProxyClassesDumper DUMPER;
static { static {
// In case we need to double-back onto the StringConcatFactory during this
// static initialization, make sure we have the reasonable defaults to complete
// the static initialization properly. After that, actual users would use the
// the proper values we have read from the the properties.
STRATEGY = DEFAULT_STRATEGY;
// CACHE_ENABLE = false; // implied
// CACHE = null; // implied
// DEBUG = false; // implied
// DUMPER = null; // implied
Properties props = GetPropertyAction.getProperties(); Properties props = GetPropertyAction.getProperties();
final String strategy = final String strategy =
props.getProperty("java.lang.invoke.stringConcat"); props.getProperty("java.lang.invoke.stringConcat");

View File

@ -136,6 +136,7 @@ import static java.lang.invoke.MethodHandleStatics.newInternalError;
* consists of the methods * consists of the methods
* {@link #compareAndSet compareAndSet}, * {@link #compareAndSet compareAndSet},
* {@link #weakCompareAndSet weakCompareAndSet}, * {@link #weakCompareAndSet weakCompareAndSet},
* {@link #weakCompareAndSetVolatile weakCompareAndSetVolatile},
* {@link #weakCompareAndSetAcquire weakCompareAndSetAcquire}, * {@link #weakCompareAndSetAcquire weakCompareAndSetAcquire},
* {@link #weakCompareAndSetRelease weakCompareAndSetRelease}, * {@link #weakCompareAndSetRelease weakCompareAndSetRelease},
* {@link #compareAndExchangeAcquire compareAndExchangeAcquire}, * {@link #compareAndExchangeAcquire compareAndExchangeAcquire},
@ -458,7 +459,7 @@ public abstract class VarHandle {
* *
* <p>The symbolic type descriptor at the call site of {@code get} * <p>The symbolic type descriptor at the call site of {@code get}
* must match the access mode type that is the result of calling * must match the access mode type that is the result of calling
* {@code accessModeType(VarHandle.AccessMode.get)} on this VarHandle. * {@code accessModeType(VarHandle.AccessMode.GET)} on this VarHandle.
* *
* <p>This access mode is supported by all VarHandle instances and never * <p>This access mode is supported by all VarHandle instances and never
* throws {@code UnsupportedOperationException}. * throws {@code UnsupportedOperationException}.
@ -488,7 +489,7 @@ public abstract class VarHandle {
* *
* <p>The symbolic type descriptor at the call site of {@code set} * <p>The symbolic type descriptor at the call site of {@code set}
* must match the access mode type that is the result of calling * must match the access mode type that is the result of calling
* {@code accessModeType(VarHandle.AccessMode.set)} on this VarHandle. * {@code accessModeType(VarHandle.AccessMode.SET)} on this VarHandle.
* *
* @param args the signature-polymorphic parameter list of the form * @param args the signature-polymorphic parameter list of the form
* {@code (CT, T newValue)} * {@code (CT, T newValue)}
@ -516,7 +517,8 @@ public abstract class VarHandle {
* *
* <p>The symbolic type descriptor at the call site of {@code getVolatile} * <p>The symbolic type descriptor at the call site of {@code getVolatile}
* must match the access mode type that is the result of calling * must match the access mode type that is the result of calling
* {@code accessModeType(VarHandle.AccessMode.getVolatile)} on this VarHandle. * {@code accessModeType(VarHandle.AccessMode.GET_VOLATILE)} on this
* VarHandle.
* *
* @param args the signature-polymorphic parameter list of the form * @param args the signature-polymorphic parameter list of the form
* {@code (CT)} * {@code (CT)}
@ -544,7 +546,8 @@ public abstract class VarHandle {
* *
* <p>The symbolic type descriptor at the call site of {@code setVolatile} * <p>The symbolic type descriptor at the call site of {@code setVolatile}
* must match the access mode type that is the result of calling * must match the access mode type that is the result of calling
* {@code accessModeType(VarHandle.AccessMode.setVolatile)} on this VarHandle. * {@code accessModeType(VarHandle.AccessMode.SET_VOLATILE)} on this
* VarHandle.
* *
* @apiNote * @apiNote
* Ignoring the many semantic differences from C and C++, this method has * Ignoring the many semantic differences from C and C++, this method has
@ -574,7 +577,8 @@ public abstract class VarHandle {
* *
* <p>The symbolic type descriptor at the call site of {@code getOpaque} * <p>The symbolic type descriptor at the call site of {@code getOpaque}
* must match the access mode type that is the result of calling * must match the access mode type that is the result of calling
* {@code accessModeType(VarHandle.AccessMode.getOpaque)} on this VarHandle. * {@code accessModeType(VarHandle.AccessMode.GET_OPAQUE)} on this
* VarHandle.
* *
* @param args the signature-polymorphic parameter list of the form * @param args the signature-polymorphic parameter list of the form
* {@code (CT)} * {@code (CT)}
@ -603,7 +607,8 @@ public abstract class VarHandle {
* *
* <p>The symbolic type descriptor at the call site of {@code setOpaque} * <p>The symbolic type descriptor at the call site of {@code setOpaque}
* must match the access mode type that is the result of calling * must match the access mode type that is the result of calling
* {@code accessModeType(VarHandle.AccessMode.setOpaque)} on this VarHandle. * {@code accessModeType(VarHandle.AccessMode.SET_OPAQUE)} on this
* VarHandle.
* *
* @param args the signature-polymorphic parameter list of the form * @param args the signature-polymorphic parameter list of the form
* {@code (CT, T newValue)} * {@code (CT, T newValue)}
@ -631,7 +636,8 @@ public abstract class VarHandle {
* *
* <p>The symbolic type descriptor at the call site of {@code getAcquire} * <p>The symbolic type descriptor at the call site of {@code getAcquire}
* must match the access mode type that is the result of calling * must match the access mode type that is the result of calling
* {@code accessModeType(VarHandle.AccessMode.getAcquire)} on this VarHandle. * {@code accessModeType(VarHandle.AccessMode.GET_ACQUIRE)} on this
* VarHandle.
* *
* @apiNote * @apiNote
* Ignoring the many semantic differences from C and C++, this method has * Ignoring the many semantic differences from C and C++, this method has
@ -664,7 +670,8 @@ public abstract class VarHandle {
* *
* <p>The symbolic type descriptor at the call site of {@code setRelease} * <p>The symbolic type descriptor at the call site of {@code setRelease}
* must match the access mode type that is the result of calling * must match the access mode type that is the result of calling
* {@code accessModeType(VarHandle.AccessMode.setRelease)} on this VarHandle. * {@code accessModeType(VarHandle.AccessMode.SET_RELEASE)} on this
* VarHandle.
* *
* @apiNote * @apiNote
* Ignoring the many semantic differences from C and C++, this method has * Ignoring the many semantic differences from C and C++, this method has
@ -700,7 +707,7 @@ public abstract class VarHandle {
* *
* <p>The symbolic type descriptor at the call site of {@code * <p>The symbolic type descriptor at the call site of {@code
* compareAndSet} must match the access mode type that is the result of * compareAndSet} must match the access mode type that is the result of
* calling {@code accessModeType(VarHandle.AccessMode.compareAndSet)} on * calling {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_SET)} on
* this VarHandle. * this VarHandle.
* *
* @param args the signature-polymorphic parameter list of the form * @param args the signature-polymorphic parameter list of the form
@ -734,7 +741,7 @@ public abstract class VarHandle {
* <p>The symbolic type descriptor at the call site of {@code * <p>The symbolic type descriptor at the call site of {@code
* compareAndExchangeVolatile} * compareAndExchangeVolatile}
* must match the access mode type that is the result of calling * must match the access mode type that is the result of calling
* {@code accessModeType(VarHandle.AccessMode.compareAndExchangeVolatile)} * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE)}
* on this VarHandle. * on this VarHandle.
* *
* @param args the signature-polymorphic parameter list of the form * @param args the signature-polymorphic parameter list of the form
@ -769,7 +776,7 @@ public abstract class VarHandle {
* <p>The symbolic type descriptor at the call site of {@code * <p>The symbolic type descriptor at the call site of {@code
* compareAndExchangeAcquire} * compareAndExchangeAcquire}
* must match the access mode type that is the result of calling * must match the access mode type that is the result of calling
* {@code accessModeType(VarHandle.AccessMode.compareAndExchangeAcquire)} on * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE)} on
* this VarHandle. * this VarHandle.
* *
* @param args the signature-polymorphic parameter list of the form * @param args the signature-polymorphic parameter list of the form
@ -804,7 +811,8 @@ public abstract class VarHandle {
* <p>The symbolic type descriptor at the call site of {@code * <p>The symbolic type descriptor at the call site of {@code
* compareAndExchangeRelease} * compareAndExchangeRelease}
* must match the access mode type that is the result of calling * must match the access mode type that is the result of calling
* {@code accessModeType(VarHandle.AccessMode.compareAndExchangeRelease)} on this VarHandle. * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE)}
* on this VarHandle.
* *
* @param args the signature-polymorphic parameter list of the form * @param args the signature-polymorphic parameter list of the form
* {@code (CT, T expectedValue, T newValue)} * {@code (CT, T expectedValue, T newValue)}
@ -836,14 +844,14 @@ public abstract class VarHandle {
* {@link #get}. * {@link #get}.
* *
* <p>This operation may fail spuriously (typically, due to memory * <p>This operation may fail spuriously (typically, due to memory
* contention) even if the current value does match the expected value. * contention) even if the witness value does match the expected value.
* *
* <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}. * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}.
* *
* <p>The symbolic type descriptor at the call site of {@code * <p>The symbolic type descriptor at the call site of {@code
* weakCompareAndSet} must match the access mode type that is the result of * weakCompareAndSet} must match the access mode type that is the result of
* calling {@code accessModeType(VarHandle.AccessMode.weakCompareAndSet)} on * calling {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET)}
* this VarHandle. * on this VarHandle.
* *
* @param args the signature-polymorphic parameter list of the form * @param args the signature-polymorphic parameter list of the form
* {@code (CT, T expectedValue, T newValue)} * {@code (CT, T expectedValue, T newValue)}
@ -865,6 +873,43 @@ public abstract class VarHandle {
@HotSpotIntrinsicCandidate @HotSpotIntrinsicCandidate
boolean weakCompareAndSet(Object... args); boolean weakCompareAndSet(Object... args);
/**
* Possibly atomically sets the value of a variable to the {@code newValue}
* with the memory semantics of {@link #setVolatile} if the variable's
* current value, referred to as the <em>witness value</em>, {@code ==} the
* {@code expectedValue}, as accessed with the memory semantics of
* {@link #getVolatile}.
*
* <p>This operation may fail spuriously (typically, due to memory
* contention) even if the witness value does match the expected value.
*
* <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}.
*
* <p>The symbolic type descriptor at the call site of {@code
* weakCompareAndSetVolatile} must match the access mode type that is the
* result of calling {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE)}
* on this VarHandle.
*
* @param args the signature-polymorphic parameter list of the form
* {@code (CT, T expectedValue, T newValue)}
* , statically represented using varargs.
* @return {@code true} if successful, otherwise {@code false} if the
* witness value was not the same as the {@code expectedValue} or if this
* operation spuriously failed.
* @throws UnsupportedOperationException if the access mode is unsupported
* for this VarHandle.
* @throws WrongMethodTypeException if the access mode type is not
* compatible with the caller's symbolic type descriptor.
* @throws ClassCastException if the access mode type is compatible with the
* caller's symbolic type descriptor, but a reference cast fails.
* @see #setVolatile(Object...)
* @see #getVolatile(Object...)
*/
public final native
@MethodHandle.PolymorphicSignature
@HotSpotIntrinsicCandidate
boolean weakCompareAndSetVolatile(Object... args);
/** /**
* Possibly atomically sets the value of a variable to the {@code newValue} * Possibly atomically sets the value of a variable to the {@code newValue}
* with the semantics of {@link #set} if the variable's current value, * with the semantics of {@link #set} if the variable's current value,
@ -873,14 +918,15 @@ public abstract class VarHandle {
* {@link #getAcquire}. * {@link #getAcquire}.
* *
* <p>This operation may fail spuriously (typically, due to memory * <p>This operation may fail spuriously (typically, due to memory
* contention) even if the current value does match the expected value. * contention) even if the witness value does match the expected value.
* *
* <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}. * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}.
* *
* <p>The symbolic type descriptor at the call site of {@code * <p>The symbolic type descriptor at the call site of {@code
* weakCompareAndSetAcquire} * weakCompareAndSetAcquire}
* must match the access mode type that is the result of calling * must match the access mode type that is the result of calling
* {@code accessModeType(VarHandle.AccessMode.weakCompareAndSetAcquire)} on this VarHandle. * {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE)}
* on this VarHandle.
* *
* @param args the signature-polymorphic parameter list of the form * @param args the signature-polymorphic parameter list of the form
* {@code (CT, T expectedValue, T newValue)} * {@code (CT, T expectedValue, T newValue)}
@ -910,14 +956,15 @@ public abstract class VarHandle {
* {@link #get}. * {@link #get}.
* *
* <p>This operation may fail spuriously (typically, due to memory * <p>This operation may fail spuriously (typically, due to memory
* contention) even if the current value does match the expected value. * contention) even if the witness value does match the expected value.
* *
* <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}. * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}.
* *
* <p>The symbolic type descriptor at the call site of {@code * <p>The symbolic type descriptor at the call site of {@code
* weakCompareAndSetRelease} * weakCompareAndSetRelease}
* must match the access mode type that is the result of calling * must match the access mode type that is the result of calling
* {@code accessModeType(VarHandle.AccessMode.weakCompareAndSetRelease)} on this VarHandle. * {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE)}
* on this VarHandle.
* *
* @param args the signature-polymorphic parameter list of the form * @param args the signature-polymorphic parameter list of the form
* {@code (CT, T expectedValue, T newValue)} * {@code (CT, T expectedValue, T newValue)}
@ -949,7 +996,8 @@ public abstract class VarHandle {
* *
* <p>The symbolic type descriptor at the call site of {@code getAndSet} * <p>The symbolic type descriptor at the call site of {@code getAndSet}
* must match the access mode type that is the result of calling * must match the access mode type that is the result of calling
* {@code accessModeType(VarHandle.AccessMode.getAndSet)} on this VarHandle. * {@code accessModeType(VarHandle.AccessMode.GET_AND_SET)} on this
* VarHandle.
* *
* @param args the signature-polymorphic parameter list of the form * @param args the signature-polymorphic parameter list of the form
* {@code (CT, T newValue)} * {@code (CT, T newValue)}
@ -985,7 +1033,8 @@ public abstract class VarHandle {
* *
* <p>The symbolic type descriptor at the call site of {@code getAndAdd} * <p>The symbolic type descriptor at the call site of {@code getAndAdd}
* must match the access mode type that is the result of calling * must match the access mode type that is the result of calling
* {@code accessModeType(VarHandle.AccessMode.getAndAdd)} on this VarHandle. * {@code accessModeType(VarHandle.AccessMode.GET_AND_ADD)} on this
* VarHandle.
* *
* @param args the signature-polymorphic parameter list of the form * @param args the signature-polymorphic parameter list of the form
* {@code (CT, T value)} * {@code (CT, T value)}
@ -1017,7 +1066,8 @@ public abstract class VarHandle {
* *
* <p>The symbolic type descriptor at the call site of {@code addAndGet} * <p>The symbolic type descriptor at the call site of {@code addAndGet}
* must match the access mode type that is the result of calling * must match the access mode type that is the result of calling
* {@code accessModeType(VarHandle.AccessMode.addAndGet)} on this VarHandle. * {@code accessModeType(VarHandle.AccessMode.ADD_AND_GET)} on this
* VarHandle.
* *
* @param args the signature-polymorphic parameter list of the form * @param args the signature-polymorphic parameter list of the form
* {@code (CT, T value)} * {@code (CT, T value)}
@ -1083,109 +1133,115 @@ public abstract class VarHandle {
* method * method
* {@link VarHandle#get VarHandle.get} * {@link VarHandle#get VarHandle.get}
*/ */
GET("get", AccessType.GET, Object.class), // 0 GET("get", AccessType.GET, Object.class),
/** /**
* The access mode whose access is specified by the corresponding * The access mode whose access is specified by the corresponding
* method * method
* {@link VarHandle#set VarHandle.set} * {@link VarHandle#set VarHandle.set}
*/ */
SET("set", AccessType.SET, void.class), // 1 SET("set", AccessType.SET, void.class),
/** /**
* The access mode whose access is specified by the corresponding * The access mode whose access is specified by the corresponding
* method * method
* {@link VarHandle#getVolatile VarHandle.getVolatile} * {@link VarHandle#getVolatile VarHandle.getVolatile}
*/ */
GET_VOLATILE("getVolatile", AccessType.GET, Object.class), // 2 GET_VOLATILE("getVolatile", AccessType.GET, Object.class),
/** /**
* The access mode whose access is specified by the corresponding * The access mode whose access is specified by the corresponding
* method * method
* {@link VarHandle#setVolatile VarHandle.setVolatile} * {@link VarHandle#setVolatile VarHandle.setVolatile}
*/ */
SET_VOLATILE("setVolatile", AccessType.SET, void.class), // 3 SET_VOLATILE("setVolatile", AccessType.SET, void.class),
/** /**
* The access mode whose access is specified by the corresponding * The access mode whose access is specified by the corresponding
* method * method
* {@link VarHandle#getAcquire VarHandle.getAcquire} * {@link VarHandle#getAcquire VarHandle.getAcquire}
*/ */
GET_ACQUIRE("getAcquire", AccessType.GET, Object.class), // 4 GET_ACQUIRE("getAcquire", AccessType.GET, Object.class),
/** /**
* The access mode whose access is specified by the corresponding * The access mode whose access is specified by the corresponding
* method * method
* {@link VarHandle#setRelease VarHandle.setRelease} * {@link VarHandle#setRelease VarHandle.setRelease}
*/ */
SET_RELEASE("setRelease", AccessType.SET, void.class), // 5 SET_RELEASE("setRelease", AccessType.SET, void.class),
/** /**
* The access mode whose access is specified by the corresponding * The access mode whose access is specified by the corresponding
* method * method
* {@link VarHandle#getOpaque VarHandle.getOpaque} * {@link VarHandle#getOpaque VarHandle.getOpaque}
*/ */
GET_OPAQUE("getOpaque", AccessType.GET, Object.class), // 6 GET_OPAQUE("getOpaque", AccessType.GET, Object.class),
/** /**
* The access mode whose access is specified by the corresponding * The access mode whose access is specified by the corresponding
* method * method
* {@link VarHandle#setOpaque VarHandle.setOpaque} * {@link VarHandle#setOpaque VarHandle.setOpaque}
*/ */
SET_OPAQUE("setOpaque", AccessType.SET, void.class), // 7 SET_OPAQUE("setOpaque", AccessType.SET, void.class),
/** /**
* The access mode whose access is specified by the corresponding * The access mode whose access is specified by the corresponding
* method * method
* {@link VarHandle#compareAndSet VarHandle.compareAndSet} * {@link VarHandle#compareAndSet VarHandle.compareAndSet}
*/ */
COMPARE_AND_SET("compareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class), // 8 COMPARE_AND_SET("compareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class),
/** /**
* The access mode whose access is specified by the corresponding * The access mode whose access is specified by the corresponding
* method * method
* {@link VarHandle#compareAndExchangeVolatile VarHandle.compareAndExchangeVolatile} * {@link VarHandle#compareAndExchangeVolatile VarHandle.compareAndExchangeVolatile}
*/ */
COMPARE_AND_EXCHANGE_VOLATILE("compareAndExchangeVolatile", AccessType.COMPARE_AND_EXCHANGE, Object.class), // 9 COMPARE_AND_EXCHANGE_VOLATILE("compareAndExchangeVolatile", AccessType.COMPARE_AND_EXCHANGE, Object.class),
/** /**
* The access mode whose access is specified by the corresponding * The access mode whose access is specified by the corresponding
* method * method
* {@link VarHandle#compareAndExchangeAcquire VarHandle.compareAndExchangeAcquire} * {@link VarHandle#compareAndExchangeAcquire VarHandle.compareAndExchangeAcquire}
*/ */
COMPARE_AND_EXCHANGE_ACQUIRE("compareAndExchangeAcquire", AccessType.COMPARE_AND_EXCHANGE, Object.class), // 10 COMPARE_AND_EXCHANGE_ACQUIRE("compareAndExchangeAcquire", AccessType.COMPARE_AND_EXCHANGE, Object.class),
/** /**
* The access mode whose access is specified by the corresponding * The access mode whose access is specified by the corresponding
* method * method
* {@link VarHandle#compareAndExchangeRelease VarHandle.compareAndExchangeRelease} * {@link VarHandle#compareAndExchangeRelease VarHandle.compareAndExchangeRelease}
*/ */
COMPARE_AND_EXCHANGE_RELEASE("compareAndExchangeRelease", AccessType.COMPARE_AND_EXCHANGE, Object.class), // 11 COMPARE_AND_EXCHANGE_RELEASE("compareAndExchangeRelease", AccessType.COMPARE_AND_EXCHANGE, Object.class),
/** /**
* The access mode whose access is specified by the corresponding * The access mode whose access is specified by the corresponding
* method * method
* {@link VarHandle#weakCompareAndSet VarHandle.weakCompareAndSet} * {@link VarHandle#weakCompareAndSet VarHandle.weakCompareAndSet}
*/ */
WEAK_COMPARE_AND_SET("weakCompareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class), // 12 WEAK_COMPARE_AND_SET("weakCompareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class),
/**
* The access mode whose access is specified by the corresponding
* method
* {@link VarHandle#weakCompareAndSetVolatile VarHandle.weakCompareAndSetVolatile}
*/
WEAK_COMPARE_AND_SET_VOLATILE("weakCompareAndSetVolatile", AccessType.COMPARE_AND_SWAP, boolean.class),
/** /**
* The access mode whose access is specified by the corresponding * The access mode whose access is specified by the corresponding
* method * method
* {@link VarHandle#weakCompareAndSetAcquire VarHandle.weakCompareAndSetAcquire} * {@link VarHandle#weakCompareAndSetAcquire VarHandle.weakCompareAndSetAcquire}
*/ */
WEAK_COMPARE_AND_SET_ACQUIRE("weakCompareAndSetAcquire", AccessType.COMPARE_AND_SWAP, boolean.class), // 13 WEAK_COMPARE_AND_SET_ACQUIRE("weakCompareAndSetAcquire", AccessType.COMPARE_AND_SWAP, boolean.class),
/** /**
* The access mode whose access is specified by the corresponding * The access mode whose access is specified by the corresponding
* method * method
* {@link VarHandle#weakCompareAndSetRelease VarHandle.weakCompareAndSetRelease} * {@link VarHandle#weakCompareAndSetRelease VarHandle.weakCompareAndSetRelease}
*/ */
WEAK_COMPARE_AND_SET_RELEASE("weakCompareAndSetRelease", AccessType.COMPARE_AND_SWAP, boolean.class), // 14 WEAK_COMPARE_AND_SET_RELEASE("weakCompareAndSetRelease", AccessType.COMPARE_AND_SWAP, boolean.class),
/** /**
* The access mode whose access is specified by the corresponding * The access mode whose access is specified by the corresponding
* method * method
* {@link VarHandle#getAndSet VarHandle.getAndSet} * {@link VarHandle#getAndSet VarHandle.getAndSet}
*/ */
GET_AND_SET("getAndSet", AccessType.GET_AND_UPDATE, Object.class), // 15 GET_AND_SET("getAndSet", AccessType.GET_AND_UPDATE, Object.class),
/** /**
* The access mode whose access is specified by the corresponding * The access mode whose access is specified by the corresponding
* method * method
* {@link VarHandle#getAndAdd VarHandle.getAndAdd} * {@link VarHandle#getAndAdd VarHandle.getAndAdd}
*/ */
GET_AND_ADD("getAndAdd", AccessType.GET_AND_UPDATE, Object.class), // 16 GET_AND_ADD("getAndAdd", AccessType.GET_AND_UPDATE, Object.class),
/** /**
* The access mode whose access is specified by the corresponding * The access mode whose access is specified by the corresponding
* method * method
* {@link VarHandle#addAndGet VarHandle.addAndGet} * {@link VarHandle#addAndGet VarHandle.addAndGet}
*/ */
ADD_AND_GET("addAndGet", AccessType.GET_AND_UPDATE, Object.class), // 17 ADD_AND_GET("addAndGet", AccessType.GET_AND_UPDATE, Object.class),
; ;
static final Map<String, AccessMode> methodNameToAccessMode; static final Map<String, AccessMode> methodNameToAccessMode;

View File

@ -154,6 +154,15 @@ final class VarHandle$Type$s {
{#if[Object]?handle.fieldType.cast(value):value}); {#if[Object]?handle.fieldType.cast(value):value});
} }
@ForceInline
static boolean weakCompareAndSetVolatile(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
// TODO defer to strong form until new Unsafe method is added
return UNSAFE.compareAndSwap$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(expected):expected},
{#if[Object]?handle.fieldType.cast(value):value});
}
@ForceInline @ForceInline
static boolean weakCompareAndSetAcquire(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) { static boolean weakCompareAndSetAcquire(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
return UNSAFE.weakCompareAndSwap$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)), return UNSAFE.weakCompareAndSwap$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
@ -318,6 +327,15 @@ final class VarHandle$Type$s {
{#if[Object]?handle.fieldType.cast(value):value}); {#if[Object]?handle.fieldType.cast(value):value});
} }
@ForceInline
static boolean weakCompareAndSetVolatile(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
// TODO defer to strong form until new Unsafe method is added
return UNSAFE.compareAndSwap$Type$(handle.base,
handle.fieldOffset,
{#if[Object]?handle.fieldType.cast(expected):expected},
{#if[Object]?handle.fieldType.cast(value):value});
}
@ForceInline @ForceInline
static boolean weakCompareAndSetAcquire(FieldStaticReadWrite handle, $type$ expected, $type$ value) { static boolean weakCompareAndSetAcquire(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
return UNSAFE.weakCompareAndSwap$Type$Acquire(handle.base, return UNSAFE.weakCompareAndSwap$Type$Acquire(handle.base,
@ -534,6 +552,20 @@ final class VarHandle$Type$s {
{#if[Object]?handle.componentType.cast(value):value}); {#if[Object]?handle.componentType.cast(value):value});
} }
@ForceInline
static boolean weakCompareAndSetVolatile(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
#if[Object]
Object[] array = (Object[]) handle.arrayType.cast(oarray);
#else[Object]
$type$[] array = ($type$[]) oarray;
#end[Object]
// TODO defer to strong form until new Unsafe method is added
return UNSAFE.compareAndSwap$Type$(array,
(((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
{#if[Object]?handle.componentType.cast(expected):expected},
{#if[Object]?handle.componentType.cast(value):value});
}
@ForceInline @ForceInline
static boolean weakCompareAndSetAcquire(Array handle, Object oarray, int index, $type$ expected, $type$ value) { static boolean weakCompareAndSetAcquire(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
#if[Object] #if[Object]

View File

@ -227,6 +227,16 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
convEndian(handle.be, expected), convEndian(handle.be, value)); convEndian(handle.be, expected), convEndian(handle.be, value));
} }
@ForceInline
static boolean weakCompareAndSetVolatile(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
byte[] ba = (byte[]) oba;
// TODO defer to strong form until new Unsafe method is added
return UNSAFE.compareAndSwap$RawType$(
ba,
address(ba, index(ba, index)),
convEndian(handle.be, expected), convEndian(handle.be, value));
}
@ForceInline @ForceInline
static boolean weakCompareAndSetAcquire(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) { static boolean weakCompareAndSetAcquire(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
byte[] ba = (byte[]) oba; byte[] ba = (byte[]) oba;
@ -443,6 +453,16 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
convEndian(handle.be, expected), convEndian(handle.be, value)); convEndian(handle.be, expected), convEndian(handle.be, value));
} }
@ForceInline
static boolean weakCompareAndSetVolatile(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
ByteBuffer bb = (ByteBuffer) obb;
// TODO defer to strong form until new Unsafe method is added
return UNSAFE.compareAndSwap$RawType$(
UNSAFE.getObject(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
convEndian(handle.be, expected), convEndian(handle.be, value));
}
@ForceInline @ForceInline
static boolean weakCompareAndSetAcquire(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) { static boolean weakCompareAndSetAcquire(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
ByteBuffer bb = (ByteBuffer) obb; ByteBuffer bb = (ByteBuffer) obb;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -4403,6 +4403,35 @@ public class Arrays {
public void sort(Comparator<? super E> c) { public void sort(Comparator<? super E> c) {
Arrays.sort(a, c); Arrays.sort(a, c);
} }
@Override
public Iterator<E> iterator() {
return new ArrayItr<>(a);
}
}
private static class ArrayItr<E> implements Iterator<E> {
private int cursor;
private final E[] a;
ArrayItr(E[] a) {
this.a = a;
}
@Override
public boolean hasNext() {
return cursor < a.length;
}
@Override
public E next() {
int i = cursor;
if (i >= a.length) {
throw new NoSuchElementException();
}
cursor = i + 1;
return a[i];
}
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -58,7 +58,19 @@ package java.util;
* @see java.util.Observer * @see java.util.Observer
* @see java.util.Observer#update(java.util.Observable, java.lang.Object) * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
* @since 1.0 * @since 1.0
*
* @deprecated
* This class and the {@link Observer} interface have been deprecated.
* The event model supported by {@code Observer} and {@code Observable}
* is quite limited, the order of notifications delivered by
* {@code Observable} is unspecified, and state changes are not in
* one-for-one correspondence with notifications.
* For a richer event model, consider using the
* {@link java.beans} package. For reliable and ordered
* messaging among threads, consider using one of the concurrent data
* structures in the {@link java.util.concurrent} package.
*/ */
@Deprecated(since="9")
public class Observable { public class Observable {
private boolean changed = false; private boolean changed = false;
private Vector<Observer> obs; private Vector<Observer> obs;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -31,7 +31,12 @@ package java.util;
* @author Chris Warth * @author Chris Warth
* @see java.util.Observable * @see java.util.Observable
* @since 1.0 * @since 1.0
*
* @deprecated
* This interface has been deprecated. See the {@link Observable}
* class for further information.
*/ */
@Deprecated(since="9")
public interface Observer { public interface Observer {
/** /**
* This method is called whenever the observed object is changed. An * This method is called whenever the observed object is changed. An

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -167,6 +167,19 @@ abstract class DoublePipeline<E_IN>
return Nodes.doubleBuilder(exactSizeIfKnown); return Nodes.doubleBuilder(exactSizeIfKnown);
} }
private <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper, int opFlags) {
return new ReferencePipeline.StatelessOp<Double, U>(this, StreamShape.DOUBLE_VALUE, opFlags) {
@Override
Sink<Double> opWrapSink(int flags, Sink<U> sink) {
return new Sink.ChainedDouble<U>(sink) {
@Override
public void accept(double t) {
downstream.accept(mapper.apply(t));
}
};
}
};
}
// DoubleStream // DoubleStream
@ -184,7 +197,7 @@ abstract class DoublePipeline<E_IN>
@Override @Override
public final Stream<Double> boxed() { public final Stream<Double> boxed() {
return mapToObj(Double::valueOf); return mapToObj(Double::valueOf, 0);
} }
@Override @Override
@ -207,18 +220,7 @@ abstract class DoublePipeline<E_IN>
@Override @Override
public final <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper) { public final <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper) {
Objects.requireNonNull(mapper); Objects.requireNonNull(mapper);
return new ReferencePipeline.StatelessOp<Double, U>(this, StreamShape.DOUBLE_VALUE, return mapToObj(mapper, StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT);
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Double> opWrapSink(int flags, Sink<U> sink) {
return new Sink.ChainedDouble<U>(sink) {
@Override
public void accept(double t) {
downstream.accept(mapper.apply(t));
}
};
}
};
} }
@Override @Override

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -170,6 +170,19 @@ abstract class IntPipeline<E_IN>
return Nodes.intBuilder(exactSizeIfKnown); return Nodes.intBuilder(exactSizeIfKnown);
} }
private <U> Stream<U> mapToObj(IntFunction<? extends U> mapper, int opFlags) {
return new ReferencePipeline.StatelessOp<Integer, U>(this, StreamShape.INT_VALUE, opFlags) {
@Override
Sink<Integer> opWrapSink(int flags, Sink<U> sink) {
return new Sink.ChainedInt<U>(sink) {
@Override
public void accept(int t) {
downstream.accept(mapper.apply(t));
}
};
}
};
}
// IntStream // IntStream
@ -187,8 +200,7 @@ abstract class IntPipeline<E_IN>
@Override @Override
public final LongStream asLongStream() { public final LongStream asLongStream() {
return new LongPipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE, return new LongPipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE, 0) {
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override @Override
Sink<Integer> opWrapSink(int flags, Sink<Long> sink) { Sink<Integer> opWrapSink(int flags, Sink<Long> sink) {
return new Sink.ChainedInt<Long>(sink) { return new Sink.ChainedInt<Long>(sink) {
@ -203,8 +215,7 @@ abstract class IntPipeline<E_IN>
@Override @Override
public final DoubleStream asDoubleStream() { public final DoubleStream asDoubleStream() {
return new DoublePipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE, return new DoublePipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE, 0) {
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override @Override
Sink<Integer> opWrapSink(int flags, Sink<Double> sink) { Sink<Integer> opWrapSink(int flags, Sink<Double> sink) {
return new Sink.ChainedInt<Double>(sink) { return new Sink.ChainedInt<Double>(sink) {
@ -219,7 +230,7 @@ abstract class IntPipeline<E_IN>
@Override @Override
public final Stream<Integer> boxed() { public final Stream<Integer> boxed() {
return mapToObj(Integer::valueOf); return mapToObj(Integer::valueOf, 0);
} }
@Override @Override
@ -242,18 +253,7 @@ abstract class IntPipeline<E_IN>
@Override @Override
public final <U> Stream<U> mapToObj(IntFunction<? extends U> mapper) { public final <U> Stream<U> mapToObj(IntFunction<? extends U> mapper) {
Objects.requireNonNull(mapper); Objects.requireNonNull(mapper);
return new ReferencePipeline.StatelessOp<Integer, U>(this, StreamShape.INT_VALUE, return mapToObj(mapper, StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT);
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Integer> opWrapSink(int flags, Sink<U> sink) {
return new Sink.ChainedInt<U>(sink) {
@Override
public void accept(int t) {
downstream.accept(mapper.apply(t));
}
};
}
};
} }
@Override @Override

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -167,6 +167,19 @@ abstract class LongPipeline<E_IN>
return Nodes.longBuilder(exactSizeIfKnown); return Nodes.longBuilder(exactSizeIfKnown);
} }
private <U> Stream<U> mapToObj(LongFunction<? extends U> mapper, int opFlags) {
return new ReferencePipeline.StatelessOp<Long, U>(this, StreamShape.LONG_VALUE, opFlags) {
@Override
Sink<Long> opWrapSink(int flags, Sink<U> sink) {
return new Sink.ChainedLong<U>(sink) {
@Override
public void accept(long t) {
downstream.accept(mapper.apply(t));
}
};
}
};
}
// LongStream // LongStream
@ -184,8 +197,7 @@ abstract class LongPipeline<E_IN>
@Override @Override
public final DoubleStream asDoubleStream() { public final DoubleStream asDoubleStream() {
return new DoublePipeline.StatelessOp<Long>(this, StreamShape.LONG_VALUE, return new DoublePipeline.StatelessOp<Long>(this, StreamShape.LONG_VALUE, StreamOpFlag.NOT_DISTINCT) {
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override @Override
Sink<Long> opWrapSink(int flags, Sink<Double> sink) { Sink<Long> opWrapSink(int flags, Sink<Double> sink) {
return new Sink.ChainedLong<Double>(sink) { return new Sink.ChainedLong<Double>(sink) {
@ -200,7 +212,7 @@ abstract class LongPipeline<E_IN>
@Override @Override
public final Stream<Long> boxed() { public final Stream<Long> boxed() {
return mapToObj(Long::valueOf); return mapToObj(Long::valueOf, 0);
} }
@Override @Override
@ -223,18 +235,7 @@ abstract class LongPipeline<E_IN>
@Override @Override
public final <U> Stream<U> mapToObj(LongFunction<? extends U> mapper) { public final <U> Stream<U> mapToObj(LongFunction<? extends U> mapper) {
Objects.requireNonNull(mapper); Objects.requireNonNull(mapper);
return new ReferencePipeline.StatelessOp<Long, U>(this, StreamShape.LONG_VALUE, return mapToObj(mapper, StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT);
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Long> opWrapSink(int flags, Sink<U> sink) {
return new Sink.ChainedLong<U>(sink) {
@Override
public void accept(long t) {
downstream.accept(mapper.apply(t));
}
};
}
};
} }
@Override @Override

View File

@ -28,6 +28,7 @@ import java.util.Comparator;
import java.util.Objects; import java.util.Objects;
import java.util.Spliterator; import java.util.Spliterator;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.function.BooleanSupplier; import java.util.function.BooleanSupplier;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -905,6 +906,7 @@ class StreamSpliterators {
// The spliterator to slice // The spliterator to slice
protected final T_SPLITR s; protected final T_SPLITR s;
protected final boolean unlimited; protected final boolean unlimited;
protected final int chunkSize;
private final long skipThreshold; private final long skipThreshold;
private final AtomicLong permits; private final AtomicLong permits;
@ -912,6 +914,8 @@ class StreamSpliterators {
this.s = s; this.s = s;
this.unlimited = limit < 0; this.unlimited = limit < 0;
this.skipThreshold = limit >= 0 ? limit : 0; this.skipThreshold = limit >= 0 ? limit : 0;
this.chunkSize = limit >= 0 ? (int)Math.min(CHUNK_SIZE,
((skip + limit) / AbstractTask.LEAF_TARGET) + 1) : CHUNK_SIZE;
this.permits = new AtomicLong(limit >= 0 ? skip + limit : skip); this.permits = new AtomicLong(limit >= 0 ? skip + limit : skip);
} }
@ -921,6 +925,7 @@ class StreamSpliterators {
this.unlimited = parent.unlimited; this.unlimited = parent.unlimited;
this.permits = parent.permits; this.permits = parent.permits;
this.skipThreshold = parent.skipThreshold; this.skipThreshold = parent.skipThreshold;
this.chunkSize = parent.chunkSize;
} }
/** /**
@ -1029,13 +1034,13 @@ class StreamSpliterators {
PermitStatus permitStatus; PermitStatus permitStatus;
while ((permitStatus = permitStatus()) != PermitStatus.NO_MORE) { while ((permitStatus = permitStatus()) != PermitStatus.NO_MORE) {
if (permitStatus == PermitStatus.MAYBE_MORE) { if (permitStatus == PermitStatus.MAYBE_MORE) {
// Optimistically traverse elements up to a threshold of CHUNK_SIZE // Optimistically traverse elements up to a threshold of chunkSize
if (sb == null) if (sb == null)
sb = new ArrayBuffer.OfRef<>(CHUNK_SIZE); sb = new ArrayBuffer.OfRef<>(chunkSize);
else else
sb.reset(); sb.reset();
long permitsRequested = 0; long permitsRequested = 0;
do { } while (s.tryAdvance(sb) && ++permitsRequested < CHUNK_SIZE); do { } while (s.tryAdvance(sb) && ++permitsRequested < chunkSize);
if (permitsRequested == 0) if (permitsRequested == 0)
return; return;
sb.forEach(action, acquirePermits(permitsRequested)); sb.forEach(action, acquirePermits(permitsRequested));
@ -1102,15 +1107,15 @@ class StreamSpliterators {
PermitStatus permitStatus; PermitStatus permitStatus;
while ((permitStatus = permitStatus()) != PermitStatus.NO_MORE) { while ((permitStatus = permitStatus()) != PermitStatus.NO_MORE) {
if (permitStatus == PermitStatus.MAYBE_MORE) { if (permitStatus == PermitStatus.MAYBE_MORE) {
// Optimistically traverse elements up to a threshold of CHUNK_SIZE // Optimistically traverse elements up to a threshold of chunkSize
if (sb == null) if (sb == null)
sb = bufferCreate(CHUNK_SIZE); sb = bufferCreate(chunkSize);
else else
sb.reset(); sb.reset();
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
T_CONS sbc = (T_CONS) sb; T_CONS sbc = (T_CONS) sb;
long permitsRequested = 0; long permitsRequested = 0;
do { } while (s.tryAdvance(sbc) && ++permitsRequested < CHUNK_SIZE); do { } while (s.tryAdvance(sbc) && ++permitsRequested < chunkSize);
if (permitsRequested == 0) if (permitsRequested == 0)
return; return;
sb.forEach(action, acquirePermits(permitsRequested)); sb.forEach(action, acquirePermits(permitsRequested));

View File

@ -33,6 +33,9 @@ import java.util.function.Function;
import java.lang.System.LoggerFinder; import java.lang.System.LoggerFinder;
import java.lang.System.Logger; import java.lang.System.Logger;
import java.lang.ref.ReferenceQueue; import java.lang.ref.ReferenceQueue;
import java.lang.reflect.Module;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Collection; import java.util.Collection;
import java.util.ResourceBundle; import java.util.ResourceBundle;
@ -129,41 +132,49 @@ public class DefaultLoggerFinder extends LoggerFinder {
return w; return w;
} }
final static SharedLoggers system = new SharedLoggers(); final static SharedLoggers system = new SharedLoggers();
final static SharedLoggers application = new SharedLoggers(); final static SharedLoggers application = new SharedLoggers();
} }
public static boolean isSystem(Module m) {
ClassLoader cl = AccessController.doPrivileged(new PrivilegedAction<>() {
@Override @Override
public final Logger getLogger(String name, /* Module */ Class<?> caller) { public ClassLoader run() {
return m.getClassLoader();
}
});
return cl == null;
}
@Override
public final Logger getLogger(String name, Module module) {
checkPermission(); checkPermission();
return demandLoggerFor(name, caller); return demandLoggerFor(name, module);
} }
@Override @Override
public final Logger getLocalizedLogger(String name, ResourceBundle bundle, public final Logger getLocalizedLogger(String name, ResourceBundle bundle,
/* Module */ Class<?> caller) { Module module) {
return super.getLocalizedLogger(name, bundle, caller); return super.getLocalizedLogger(name, bundle, module);
} }
/** /**
* Returns a {@link Logger logger} suitable for the caller usage. * Returns a {@link Logger logger} suitable for use within the
* given {@code module}.
* *
* @implSpec The default implementation for this method is to return a * @implSpec The default implementation for this method is to return a
* simple logger that will print all messages of INFO level and above * simple logger that will print all messages of INFO level and above
* to the console. That simple logger is not configurable. * to the console. That simple logger is not configurable.
* *
* @param name The name of the logger. * @param name The name of the logger.
* @param caller The class on behalf of which the logger is created. * @param module The module on behalf of which the logger is created.
* @return A {@link Logger logger} suitable for the application usage. * @return A {@link Logger logger} suitable for the application usage.
* @throws SecurityException if the calling code does not have the * @throws SecurityException if the calling code does not have the
* {@code RuntimePermission("loggerFinder")}. * {@code RuntimePermission("loggerFinder")}.
*/ */
protected Logger demandLoggerFor(String name, /* Module */ Class<?> caller) { protected Logger demandLoggerFor(String name, Module module) {
checkPermission(); checkPermission();
if (caller.getClassLoader() == null) { if (isSystem(module)) {
return SharedLoggers.system.get(SimpleConsoleLogger::makeSimpleLogger, name); return SharedLoggers.system.get(SimpleConsoleLogger::makeSimpleLogger, name);
} else { } else {
return SharedLoggers.application.get(SimpleConsoleLogger::makeSimpleLogger, name); return SharedLoggers.application.get(SimpleConsoleLogger::makeSimpleLogger, name);

View File

@ -31,6 +31,7 @@ import java.util.function.BiFunction;
import java.lang.System.LoggerFinder; import java.lang.System.LoggerFinder;
import java.lang.System.Logger; import java.lang.System.Logger;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.lang.reflect.Module;
import java.util.Objects; import java.util.Objects;
import jdk.internal.misc.VM; import jdk.internal.misc.VM;
import sun.util.logging.PlatformLogger; import sun.util.logging.PlatformLogger;
@ -59,15 +60,15 @@ public final class LazyLoggers {
* A factory method to create an SPI logger. * A factory method to create an SPI logger.
* Usually, this will be something like LazyLoggers::getSystemLogger. * Usually, this will be something like LazyLoggers::getSystemLogger.
*/ */
final BiFunction<String, Class<?>, L> loggerSupplier; final BiFunction<String, Module, L> loggerSupplier;
public LazyLoggerFactories(BiFunction<String, Class<?>, L> loggerSupplier) { public LazyLoggerFactories(BiFunction<String, Module, L> loggerSupplier) {
this(Objects.requireNonNull(loggerSupplier), this(Objects.requireNonNull(loggerSupplier),
(Void)null); (Void)null);
} }
private LazyLoggerFactories(BiFunction<String, Class<?>, L> loggerSupplier, private LazyLoggerFactories(BiFunction<String, Module, L> loggerSupplier,
Void unused) { Void unused) {
this.loggerSupplier = loggerSupplier; this.loggerSupplier = loggerSupplier;
} }
@ -107,8 +108,8 @@ public final class LazyLoggers {
// The factories that will be used to create the logger lazyly // The factories that will be used to create the logger lazyly
final LazyLoggerFactories<? extends Logger> factories; final LazyLoggerFactories<? extends Logger> factories;
// We need to pass the actual caller when creating the logger. // We need to pass the actual caller module when creating the logger.
private final WeakReference<Class<?>> callerRef; private final WeakReference<Module> moduleRef;
// The name of the logger that will be created lazyly // The name of the logger that will be created lazyly
final String name; final String name;
@ -121,17 +122,17 @@ public final class LazyLoggers {
private LazyLoggerAccessor(String name, private LazyLoggerAccessor(String name,
LazyLoggerFactories<? extends Logger> factories, LazyLoggerFactories<? extends Logger> factories,
Class<?> caller) { Module module) {
this(Objects.requireNonNull(name), Objects.requireNonNull(factories), this(Objects.requireNonNull(name), Objects.requireNonNull(factories),
Objects.requireNonNull(caller), null); Objects.requireNonNull(module), null);
} }
private LazyLoggerAccessor(String name, private LazyLoggerAccessor(String name,
LazyLoggerFactories<? extends Logger> factories, LazyLoggerFactories<? extends Logger> factories,
Class<?> caller, Void unused) { Module module, Void unused) {
this.name = name; this.name = name;
this.factories = factories; this.factories = factories;
this.callerRef = new WeakReference<Class<?>>(caller); this.moduleRef = new WeakReference<>(module);
} }
/** /**
@ -270,12 +271,12 @@ public final class LazyLoggers {
// Creates the wrapped logger by invoking the SPI. // Creates the wrapped logger by invoking the SPI.
Logger createLogger() { Logger createLogger() {
final Class<?> caller = callerRef.get(); final Module module = moduleRef.get();
if (caller == null) { if (module == null) {
throw new IllegalStateException("The class for which this logger" throw new IllegalStateException("The module for which this logger"
+ " was created has been garbage collected"); + " was created has been garbage collected");
} }
return this.factories.loggerSupplier.apply(name, caller); return this.factories.loggerSupplier.apply(name, module);
} }
/** /**
@ -289,8 +290,8 @@ public final class LazyLoggers {
* @return A new LazyLoggerAccessor. * @return A new LazyLoggerAccessor.
*/ */
public static LazyLoggerAccessor makeAccessor(String name, public static LazyLoggerAccessor makeAccessor(String name,
LazyLoggerFactories<? extends Logger> factories, Class<?> caller) { LazyLoggerFactories<? extends Logger> factories, Module module) {
return new LazyLoggerAccessor(name, factories, caller); return new LazyLoggerAccessor(name, factories, module);
} }
} }
@ -346,11 +347,11 @@ public final class LazyLoggers {
// Avoid using lambda here as lazy loggers could be created early // Avoid using lambda here as lazy loggers could be created early
// in the bootstrap sequence... // in the bootstrap sequence...
private static final BiFunction<String, Class<?>, Logger> loggerSupplier = private static final BiFunction<String, Module, Logger> loggerSupplier =
new BiFunction<>() { new BiFunction<>() {
@Override @Override
public Logger apply(String name, Class<?> caller) { public Logger apply(String name, Module module) {
return LazyLoggers.getLoggerFromFinder(name, caller); return LazyLoggers.getLoggerFromFinder(name, module);
} }
}; };
@ -367,8 +368,8 @@ public final class LazyLoggers {
// logger provider until the VM has finished booting. // logger provider until the VM has finished booting.
// //
private static final class JdkLazyLogger extends LazyLoggerWrapper { private static final class JdkLazyLogger extends LazyLoggerWrapper {
JdkLazyLogger(String name, Class<?> caller) { JdkLazyLogger(String name, Module module) {
this(LazyLoggerAccessor.makeAccessor(name, factories, caller), this(LazyLoggerAccessor.makeAccessor(name, factories, module),
(Void)null); (Void)null);
} }
private JdkLazyLogger(LazyLoggerAccessor holder, Void unused) { private JdkLazyLogger(LazyLoggerAccessor holder, Void unused) {
@ -380,16 +381,16 @@ public final class LazyLoggers {
* Gets a logger from the LoggerFinder. Creates the actual concrete * Gets a logger from the LoggerFinder. Creates the actual concrete
* logger. * logger.
* @param name name of the logger * @param name name of the logger
* @param caller class on behalf of which the logger is created * @param module module on behalf of which the logger is created
* @return The logger returned by the LoggerFinder. * @return The logger returned by the LoggerFinder.
*/ */
static Logger getLoggerFromFinder(String name, Class<?> caller) { static Logger getLoggerFromFinder(String name, Module module) {
final SecurityManager sm = System.getSecurityManager(); final SecurityManager sm = System.getSecurityManager();
if (sm == null) { if (sm == null) {
return accessLoggerFinder().getLogger(name, caller); return accessLoggerFinder().getLogger(name, module);
} else { } else {
return AccessController.doPrivileged((PrivilegedAction<Logger>) return AccessController.doPrivileged((PrivilegedAction<Logger>)
() -> {return accessLoggerFinder().getLogger(name, caller);}, () -> {return accessLoggerFinder().getLogger(name, module);},
null, LOGGERFINDER_PERMISSION); null, LOGGERFINDER_PERMISSION);
} }
} }
@ -398,22 +399,22 @@ public final class LazyLoggers {
* Returns a (possibly lazy) Logger for the caller. * Returns a (possibly lazy) Logger for the caller.
* *
* @param name the logger name * @param name the logger name
* @param caller The class on behalf of which the logger is created. * @param module The module on behalf of which the logger is created.
* If the caller is not loaded from the Boot ClassLoader, * If the module is not loaded from the Boot ClassLoader,
* the LoggerFinder is accessed and the logger returned * the LoggerFinder is accessed and the logger returned
* by {@link LoggerFinder#getLogger(java.lang.String, java.lang.Class)} * by {@link LoggerFinder#getLogger(java.lang.String, java.lang.reflect.Module)}
* is returned to the caller directly. * is returned to the caller directly.
* Otherwise, the logger returned by * Otherwise, the logger returned by
* {@link #getLazyLogger(java.lang.String, java.lang.Class)} * {@link #getLazyLogger(java.lang.String, java.lang.reflect.Module)}
* is returned to the caller. * is returned to the caller.
* *
* @return a (possibly lazy) Logger instance. * @return a (possibly lazy) Logger instance.
*/ */
public static final Logger getLogger(String name, Class<?> caller) { public static final Logger getLogger(String name, Module module) {
if (caller.getClassLoader() == null) { if (DefaultLoggerFinder.isSystem(module)) {
return getLazyLogger(name, caller); return getLazyLogger(name, module);
} else { } else {
return getLoggerFromFinder(name, caller); return getLoggerFromFinder(name, module);
} }
} }
@ -423,10 +424,10 @@ public final class LazyLoggers {
* returned by {@link BootstrapLogger#useLazyLoggers()}. * returned by {@link BootstrapLogger#useLazyLoggers()}.
* *
* @param name the logger name * @param name the logger name
* @param caller the class on behalf of which the logger is created. * @param module the module on behalf of which the logger is created.
* @return a (possibly lazy) Logger instance. * @return a (possibly lazy) Logger instance.
*/ */
public static final Logger getLazyLogger(String name, Class<?> caller) { public static final Logger getLazyLogger(String name, Module module) {
// BootstrapLogger has the logic to determine whether a LazyLogger // BootstrapLogger has the logic to determine whether a LazyLogger
// should be used. Usually, it is worth it only if: // should be used. Usually, it is worth it only if:
@ -438,10 +439,10 @@ public final class LazyLoggers {
// configuration, we're not going to delay the creation of loggers... // configuration, we're not going to delay the creation of loggers...
final boolean useLazyLogger = BootstrapLogger.useLazyLoggers(); final boolean useLazyLogger = BootstrapLogger.useLazyLoggers();
if (useLazyLogger) { if (useLazyLogger) {
return new JdkLazyLogger(name, caller); return new JdkLazyLogger(name, module);
} else { } else {
// Directly invoke the LoggerFinder. // Directly invoke the LoggerFinder.
return getLoggerFromFinder(name, caller); return getLoggerFromFinder(name, module);
} }
} }

View File

@ -1,61 +0,0 @@
/*
* Copyright (c) 2014, 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.net;
import java.net.SocketOption;
/**
* Defines extended socket options, beyond those defined in
* {@link java.net.StandardSocketOptions}. These options may be platform
* specific.
*
* @since 1.8
*/
public final class ExtendedSocketOptions {
private static class ExtSocketOption<T> implements SocketOption<T> {
private final String name;
private final Class<T> type;
ExtSocketOption(String name, Class<T> type) {
this.name = name;
this.type = type;
}
@Override public String name() { return name; }
@Override public Class<T> type() { return type; }
@Override public String toString() { return name; }
}
private ExtendedSocketOptions() {}
/**
* Service level properties. When a security manager is installed,
* setting or getting this option requires a {@link NetworkPermission}
* {@code ("setOption.SO_FLOW_SLA")} or {@code "getOption.SO_FLOW_SLA"}
* respectively.
*/
public static final SocketOption<SocketFlow> SO_FLOW_SLA = new
ExtSocketOption<SocketFlow>("SO_FLOW_SLA", SocketFlow.class);
}

View File

@ -83,8 +83,6 @@ module java.base {
// see JDK-8144062 // see JDK-8144062
exports jdk; exports jdk;
// see JDK-8044773
exports jdk.net;
// the service types defined by the APIs in this module // the service types defined by the APIs in this module
@ -168,6 +166,7 @@ module java.base {
java.sql, java.sql,
java.xml, java.xml,
jdk.charsets, jdk.charsets,
jdk.net,
jdk.scripting.nashorn, jdk.scripting.nashorn,
jdk.unsupported, jdk.unsupported,
jdk.vm.ci; jdk.vm.ci;
@ -194,6 +193,8 @@ module java.base {
jdk.jvmstat; jdk.jvmstat;
exports sun.net to exports sun.net to
java.httpclient; java.httpclient;
exports sun.net.ext to
jdk.net;
exports sun.net.dns to exports sun.net.dns to
java.security.jgss, java.security.jgss,
jdk.naming.dns; jdk.naming.dns;

View File

@ -1,92 +0,0 @@
/*
* Copyright (c) 2014, 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 sun.net;
import java.net.*;
import jdk.net.*;
import java.io.IOException;
import java.io.FileDescriptor;
import java.security.PrivilegedAction;
import java.security.AccessController;
import java.lang.reflect.Field;
import java.util.Set;
import java.util.HashSet;
import java.util.HashMap;
import java.util.Collections;
/**
* Contains the native implementation for extended socket options
* together with some other static utilities
*/
public class ExtendedOptionsImpl {
static {
AccessController.doPrivileged((PrivilegedAction<Void>)() -> {
System.loadLibrary("net");
return null;
});
init();
}
private ExtendedOptionsImpl() {}
public static void checkSetOptionPermission(SocketOption<?> option) {
SecurityManager sm = System.getSecurityManager();
if (sm == null) {
return;
}
String check = "setOption." + option.name();
sm.checkPermission(new NetworkPermission(check));
}
public static void checkGetOptionPermission(SocketOption<?> option) {
SecurityManager sm = System.getSecurityManager();
if (sm == null) {
return;
}
String check = "getOption." + option.name();
sm.checkPermission(new NetworkPermission(check));
}
public static void checkValueType(Object value, Class<?> type) {
if (!type.isAssignableFrom(value.getClass())) {
String s = "Found: " + value.getClass().toString() + " Expected: "
+ type.toString();
throw new IllegalArgumentException(s);
}
}
private static native void init();
/*
* Extension native implementations
*
* SO_FLOW_SLA
*/
public static native void setFlowOption(FileDescriptor fd, SocketFlow f);
public static native void getFlowOption(FileDescriptor fd, SocketFlow f);
public static native boolean flowSupported();
}

View File

@ -0,0 +1,110 @@
/*
* Copyright (c) 2016, 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 sun.net.ext;
import java.io.FileDescriptor;
import java.net.SocketException;
import java.net.SocketOption;
import java.util.Collections;
import java.util.Set;
/**
* Defines the infrastructure to support extended socket options, beyond those
* defined in {@link java.net.StandardSocketOptions}.
*
* Extended socket options are accessed through the jdk.net API, which is in
* the jdk.net module.
*/
public abstract class ExtendedSocketOptions {
private final Set<SocketOption<?>> options;
/** Tells whether or not the option is supported. */
public final boolean isOptionSupported(SocketOption<?> option) {
return options().contains(option);
}
/** Return the, possibly empty, set of extended socket options available. */
public final Set<SocketOption<?>> options() { return options; }
/** Sets the value of a socket option, for the given socket. */
public abstract void setOption(FileDescriptor fd, SocketOption<?> option, Object value)
throws SocketException;
/** Returns the value of a socket option, for the given socket. */
public abstract Object getOption(FileDescriptor fd, SocketOption<?> option)
throws SocketException;
protected ExtendedSocketOptions(Set<SocketOption<?>> options) {
this.options = options;
}
private static volatile ExtendedSocketOptions instance;
public static final ExtendedSocketOptions getInstance() { return instance; }
/** Registers support for extended socket options. Invoked by the jdk.net module. */
public static final void register(ExtendedSocketOptions extOptions) {
if (instance != null)
throw new InternalError("Attempting to reregister extended options");
instance = extOptions;
}
static {
try {
// If the class is present, it will be initialized which
// triggers registration of the extended socket options.
Class<?> c = Class.forName("jdk.net.ExtendedSocketOptions");
} catch (ClassNotFoundException e) {
// the jdk.net module is not present => no extended socket options
instance = new NoExtendedSocketOptions();
}
}
static final class NoExtendedSocketOptions extends ExtendedSocketOptions {
NoExtendedSocketOptions() {
super(Collections.<SocketOption<?>>emptySet());
}
@Override
public void setOption(FileDescriptor fd, SocketOption<?> option, Object value)
throws SocketException
{
throw new UnsupportedOperationException(
"no extended options: " + option.name());
}
@Override
public Object getOption(FileDescriptor fd, SocketOption<?> option)
throws SocketException
{
throw new UnsupportedOperationException(
"no extended options: " + option.name());
}
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,7 +29,6 @@ import java.io.IOException;
import java.nio.channels.*; import java.nio.channels.*;
import java.nio.channels.spi.*; import java.nio.channels.spi.*;
import java.util.*; import java.util.*;
import sun.misc.*;
/** /**

View File

@ -39,7 +39,7 @@ import java.util.Collections;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.concurrent.locks.*; import java.util.concurrent.locks.*;
import sun.net.NetHooks; import sun.net.NetHooks;
import sun.net.ExtendedOptionsImpl; import sun.net.ext.ExtendedSocketOptions;
/** /**
* Base implementation of AsynchronousSocketChannel * Base implementation of AsynchronousSocketChannel
@ -512,9 +512,9 @@ abstract class AsynchronousSocketChannelImpl
set.add(StandardSocketOptions.SO_REUSEPORT); set.add(StandardSocketOptions.SO_REUSEPORT);
} }
set.add(StandardSocketOptions.TCP_NODELAY); set.add(StandardSocketOptions.TCP_NODELAY);
if (ExtendedOptionsImpl.flowSupported()) { ExtendedSocketOptions extendedOptions =
set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA); ExtendedSocketOptions.getInstance();
} set.addAll(extendedOptions.options());
return Collections.unmodifiableSet(set); return Collections.unmodifiableSet(set);
} }
} }

View File

@ -33,7 +33,7 @@ import java.nio.channels.*;
import java.nio.channels.spi.*; import java.nio.channels.spi.*;
import java.util.*; import java.util.*;
import sun.net.ResourceManager; import sun.net.ResourceManager;
import sun.net.ExtendedOptionsImpl; import sun.net.ext.ExtendedSocketOptions;
/** /**
* An implementation of DatagramChannels. * An implementation of DatagramChannels.
@ -306,9 +306,9 @@ class DatagramChannelImpl
set.add(StandardSocketOptions.IP_MULTICAST_IF); set.add(StandardSocketOptions.IP_MULTICAST_IF);
set.add(StandardSocketOptions.IP_MULTICAST_TTL); set.add(StandardSocketOptions.IP_MULTICAST_TTL);
set.add(StandardSocketOptions.IP_MULTICAST_LOOP); set.add(StandardSocketOptions.IP_MULTICAST_LOOP);
if (ExtendedOptionsImpl.flowSupported()) { ExtendedSocketOptions extendedOptions =
set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA); ExtendedSocketOptions.getInstance();
} set.addAll(extendedOptions.options());
return Collections.unmodifiableSet(set); return Collections.unmodifiableSet(set);
} }
} }

View File

@ -27,15 +27,13 @@ package sun.nio.ch;
import java.io.*; import java.io.*;
import java.net.*; import java.net.*;
import jdk.net.*;
import java.nio.channels.*; import java.nio.channels.*;
import java.util.*; import java.util.*;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import sun.net.ExtendedOptionsImpl; import sun.net.ext.ExtendedSocketOptions;
import sun.security.action.GetPropertyAction; import sun.security.action.GetPropertyAction;
public class Net { public class Net {
private Net() { } private Net() { }
@ -281,6 +279,9 @@ public class Net {
// -- Socket options // -- Socket options
static final ExtendedSocketOptions extendedOptions =
ExtendedSocketOptions.getInstance();
static void setSocketOption(FileDescriptor fd, ProtocolFamily family, static void setSocketOption(FileDescriptor fd, ProtocolFamily family,
SocketOption<?> name, Object value) SocketOption<?> name, Object value)
throws IOException throws IOException
@ -291,12 +292,8 @@ public class Net {
// only simple values supported by this method // only simple values supported by this method
Class<?> type = name.type(); Class<?> type = name.type();
if (type == SocketFlow.class) { if (extendedOptions.isOptionSupported(name)) {
SecurityManager sm = System.getSecurityManager(); extendedOptions.setOption(fd, name, value);
if (sm != null) {
sm.checkPermission(new NetworkPermission("setOption.SO_FLOW_SLA"));
}
ExtendedOptionsImpl.setFlowOption(fd, (SocketFlow)value);
return; return;
} }
@ -353,14 +350,8 @@ public class Net {
{ {
Class<?> type = name.type(); Class<?> type = name.type();
if (type == SocketFlow.class) { if (extendedOptions.isOptionSupported(name)) {
SecurityManager sm = System.getSecurityManager(); return extendedOptions.getOption(fd, name);
if (sm != null) {
sm.checkPermission(new NetworkPermission("getOption.SO_FLOW_SLA"));
}
SocketFlow flow = SocketFlow.create();
ExtendedOptionsImpl.getFlowOption(fd, flow);
return flow;
} }
// only simple values supported by this method // only simple values supported by this method

View File

@ -33,8 +33,7 @@ import java.nio.channels.*;
import java.nio.channels.spi.*; import java.nio.channels.spi.*;
import java.util.*; import java.util.*;
import sun.net.NetHooks; import sun.net.NetHooks;
import sun.net.ExtendedOptionsImpl; import sun.net.ext.ExtendedSocketOptions;
/** /**
* An implementation of SocketChannels * An implementation of SocketChannels
@ -242,9 +241,9 @@ class SocketChannelImpl
// additional options required by socket adaptor // additional options required by socket adaptor
set.add(StandardSocketOptions.IP_TOS); set.add(StandardSocketOptions.IP_TOS);
set.add(ExtendedSocketOption.SO_OOBINLINE); set.add(ExtendedSocketOption.SO_OOBINLINE);
if (ExtendedOptionsImpl.flowSupported()) { ExtendedSocketOptions extendedOptions =
set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA); ExtendedSocketOptions.getInstance();
} set.addAll(extendedOptions.options());
return Collections.unmodifiableSet(set); return Collections.unmodifiableSet(set);
} }
} }

View File

@ -1,74 +0,0 @@
/*
* Copyright (c) 2009, 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 sun.security.action;
import java.security.Security;
/**
* A convenience class for retrieving the boolean value of a security property
* as a privileged action.
*
* <p>An instance of this class can be used as the argument of
* <code>AccessController.doPrivileged</code>.
*
* <p>The following code retrieves the boolean value of the security
* property named <code>"prop"</code> as a privileged action:
*
* <pre>
* boolean b = java.security.AccessController.doPrivileged
* (new GetBooleanSecurityPropertyAction("prop")).booleanValue();
* </pre>
*
*/
public class GetBooleanSecurityPropertyAction
implements java.security.PrivilegedAction<Boolean> {
private String theProp;
/**
* Constructor that takes the name of the security property whose boolean
* value needs to be determined.
*
* @param theProp the name of the security property
*/
public GetBooleanSecurityPropertyAction(String theProp) {
this.theProp = theProp;
}
/**
* Determines the boolean value of the security property whose name was
* specified in the constructor.
*
* @return the <code>Boolean</code> value of the security property.
*/
public Boolean run() {
boolean b = false;
try {
String value = Security.getProperty(theProp);
b = (value != null) && value.equalsIgnoreCase("true");
} catch (NullPointerException e) {}
return b;
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -31,12 +31,10 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Set; import java.util.Set;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashSet;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.PublicKey; import java.security.PublicKey;
import java.security.KeyFactory; import java.security.KeyFactory;
import java.security.AlgorithmParameters; import java.security.AlgorithmParameters;
import java.security.NoSuchAlgorithmException;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.X509CRL; import java.security.cert.X509CRL;
@ -48,10 +46,13 @@ import java.security.cert.CertificateException;
import java.security.cert.CertPathValidatorException; import java.security.cert.CertPathValidatorException;
import java.security.cert.CertPathValidatorException.BasicReason; import java.security.cert.CertPathValidatorException.BasicReason;
import java.security.cert.PKIXReason; import java.security.cert.PKIXReason;
import java.io.IOException; import java.security.interfaces.DSAParams;
import java.security.interfaces.*; import java.security.interfaces.DSAPublicKey;
import java.security.spec.*; import java.security.spec.DSAPublicKeySpec;
import sun.security.util.AnchorCertificates;
import sun.security.util.CertConstraintParameters;
import sun.security.util.Debug;
import sun.security.util.DisabledAlgorithmConstraints; import sun.security.util.DisabledAlgorithmConstraints;
import sun.security.x509.X509CertImpl; import sun.security.x509.X509CertImpl;
import sun.security.x509.X509CRLImpl; import sun.security.x509.X509CRLImpl;
@ -69,6 +70,7 @@ import sun.security.x509.AlgorithmId;
* @see PKIXParameters * @see PKIXParameters
*/ */
public final class AlgorithmChecker extends PKIXCertPathChecker { public final class AlgorithmChecker extends PKIXCertPathChecker {
private static final Debug debug = Debug.getInstance("certpath");
private final AlgorithmConstraints constraints; private final AlgorithmConstraints constraints;
private final PublicKey trustedPubKey; private final PublicKey trustedPubKey;
@ -88,6 +90,14 @@ public final class AlgorithmChecker extends PKIXCertPathChecker {
certPathDefaultConstraints = new DisabledAlgorithmConstraints( certPathDefaultConstraints = new DisabledAlgorithmConstraints(
DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS); DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
// If there is no "cacerts" keyword, then disable anchor checking
private static final boolean publicCALimits =
certPathDefaultConstraints.checkProperty("jdkCA");
// If anchor checking enabled, this will be true if the trust anchor
// has a match in the cacerts file
private boolean trustedMatch = false;
/** /**
* Create a new <code>AlgorithmChecker</code> with the algorithm * Create a new <code>AlgorithmChecker</code> with the algorithm
* constraints specified in security property * constraints specified in security property
@ -136,6 +146,11 @@ public final class AlgorithmChecker extends PKIXCertPathChecker {
if (anchor.getTrustedCert() != null) { if (anchor.getTrustedCert() != null) {
this.trustedPubKey = anchor.getTrustedCert().getPublicKey(); this.trustedPubKey = anchor.getTrustedCert().getPublicKey();
// Check for anchor certificate restrictions
trustedMatch = checkFingerprint(anchor.getTrustedCert());
if (trustedMatch && debug != null) {
debug.println("trustedMatch = true");
}
} else { } else {
this.trustedPubKey = anchor.getCAPublicKey(); this.trustedPubKey = anchor.getCAPublicKey();
} }
@ -144,6 +159,19 @@ public final class AlgorithmChecker extends PKIXCertPathChecker {
this.constraints = constraints; this.constraints = constraints;
} }
// Check this 'cert' for restrictions in the AnchorCertificates
// trusted certificates list
private static boolean checkFingerprint(X509Certificate cert) {
if (!publicCALimits) {
return false;
}
if (debug != null) {
debug.println("AlgorithmChecker.contains: " + cert.getSigAlgName());
}
return AnchorCertificates.contains(cert);
}
@Override @Override
public void init(boolean forward) throws CertPathValidatorException { public void init(boolean forward) throws CertPathValidatorException {
// Note that this class does not support forward mode. // Note that this class does not support forward mode.
@ -181,36 +209,8 @@ public final class AlgorithmChecker extends PKIXCertPathChecker {
return; return;
} }
X509CertImpl x509Cert = null;
try {
x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
} catch (CertificateException ce) {
throw new CertPathValidatorException(ce);
}
PublicKey currPubKey = x509Cert.getPublicKey();
String currSigAlg = x509Cert.getSigAlgName();
AlgorithmId algorithmId = null;
try {
algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
} catch (CertificateException ce) {
throw new CertPathValidatorException(ce);
}
AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
// Check the current signature algorithm
if (!constraints.permits(
SIGNATURE_PRIMITIVE_SET,
currSigAlg, currSigAlgParams)) {
throw new CertPathValidatorException(
"Algorithm constraints check failed: " + currSigAlg,
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
// check the key usage and key size // check the key usage and key size
boolean[] keyUsage = x509Cert.getKeyUsage(); boolean[] keyUsage = ((X509Certificate) cert).getKeyUsage();
if (keyUsage != null && keyUsage.length < 9) { if (keyUsage != null && keyUsage.length < 9) {
throw new CertPathValidatorException( throw new CertPathValidatorException(
"incorrect KeyUsage extension", "incorrect KeyUsage extension",
@ -248,28 +248,68 @@ public final class AlgorithmChecker extends PKIXCertPathChecker {
if (primitives.isEmpty()) { if (primitives.isEmpty()) {
throw new CertPathValidatorException( throw new CertPathValidatorException(
"incorrect KeyUsage extension", "incorrect KeyUsage extension bits",
null, null, -1, PKIXReason.INVALID_KEY_USAGE); null, null, -1, PKIXReason.INVALID_KEY_USAGE);
} }
} }
PublicKey currPubKey = cert.getPublicKey();
// Check against DisabledAlgorithmConstraints certpath constraints.
// permits() will throw exception on failure.
certPathDefaultConstraints.permits(primitives,
new CertConstraintParameters((X509Certificate)cert,
trustedMatch));
// new CertConstraintParameters(x509Cert, trustedMatch));
// If there is no previous key, set one and exit
if (prevPubKey == null) {
prevPubKey = currPubKey;
return;
}
X509CertImpl x509Cert;
AlgorithmId algorithmId;
try {
x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
} catch (CertificateException ce) {
throw new CertPathValidatorException(ce);
}
AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
String currSigAlg = x509Cert.getSigAlgName();
// If 'constraints' is not of DisabledAlgorithmConstraints, check all
// everything individually
if (!(constraints instanceof DisabledAlgorithmConstraints)) {
// Check the current signature algorithm
if (!constraints.permits(
SIGNATURE_PRIMITIVE_SET,
currSigAlg, currSigAlgParams)) {
throw new CertPathValidatorException(
"Algorithm constraints check failed on signature " +
"algorithm: " + currSigAlg, null, null, -1,
BasicReason.ALGORITHM_CONSTRAINED);
}
if (!constraints.permits(primitives, currPubKey)) { if (!constraints.permits(primitives, currPubKey)) {
throw new CertPathValidatorException( throw new CertPathValidatorException(
"algorithm constraints check failed", "Algorithm constraints check failed on keysize: " +
sun.security.util.KeyUtil.getKeySize(currPubKey),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
} }
}
// Check with previous cert for signature algorithm and public key // Check with previous cert for signature algorithm and public key
if (prevPubKey != null) { if (prevPubKey != null) {
if (currSigAlg != null) {
if (!constraints.permits( if (!constraints.permits(
SIGNATURE_PRIMITIVE_SET, SIGNATURE_PRIMITIVE_SET,
currSigAlg, prevPubKey, currSigAlgParams)) { currSigAlg, prevPubKey, currSigAlgParams)) {
throw new CertPathValidatorException( throw new CertPathValidatorException(
"Algorithm constraints check failed: " + currSigAlg, "Algorithm constraints check failed on " +
"signature algorithm: " + currSigAlg,
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
} }
}
// Inherit key parameters from previous key // Inherit key parameters from previous key
if (PKIX.isDSAPublicKeyWithoutParams(currPubKey)) { if (PKIX.isDSAPublicKeyWithoutParams(currPubKey)) {
@ -282,7 +322,7 @@ public final class AlgorithmChecker extends PKIXCertPathChecker {
DSAParams params = ((DSAPublicKey)prevPubKey).getParams(); DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
if (params == null) { if (params == null) {
throw new CertPathValidatorException( throw new CertPathValidatorException(
"Key parameters missing"); "Key parameters missing from public key.");
} }
try { try {
@ -330,6 +370,11 @@ public final class AlgorithmChecker extends PKIXCertPathChecker {
// Don't bother to change the trustedPubKey. // Don't bother to change the trustedPubKey.
if (anchor.getTrustedCert() != null) { if (anchor.getTrustedCert() != null) {
prevPubKey = anchor.getTrustedCert().getPublicKey(); prevPubKey = anchor.getTrustedCert().getPublicKey();
// Check for anchor certificate restrictions
trustedMatch = checkFingerprint(anchor.getTrustedCert());
if (trustedMatch && debug != null) {
debug.println("trustedMatch = true");
}
} else { } else {
prevPubKey = anchor.getCAPublicKey(); prevPubKey = anchor.getCAPublicKey();
} }
@ -370,7 +415,8 @@ public final class AlgorithmChecker extends PKIXCertPathChecker {
if (!certPathDefaultConstraints.permits( if (!certPathDefaultConstraints.permits(
SIGNATURE_PRIMITIVE_SET, sigAlgName, key, sigAlgParams)) { SIGNATURE_PRIMITIVE_SET, sigAlgName, key, sigAlgParams)) {
throw new CertPathValidatorException( throw new CertPathValidatorException(
"algorithm check failed: " + sigAlgName + " is disabled", "Algorithm constraints check failed on signature algorithm: " +
sigAlgName + " is disabled",
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
} }
} }

View File

@ -131,8 +131,8 @@ class PKIXMasterCertPathValidator {
} catch (CertPathValidatorException cpve) { } catch (CertPathValidatorException cpve) {
throw new CertPathValidatorException(cpve.getMessage(), throw new CertPathValidatorException(cpve.getMessage(),
cpve.getCause(), cpOriginal, cpSize - (i + 1), (cpve.getCause() != null) ? cpve.getCause() : cpve,
cpve.getReason()); cpOriginal, cpSize - (i + 1), cpve.getReason());
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,7 +29,6 @@ import java.security.AccessController;
import java.security.AlgorithmConstraints; import java.security.AlgorithmConstraints;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.security.Security; import java.security.Security;
import java.util.Map;
import java.util.Set; import java.util.Set;
/** /**
@ -45,8 +44,7 @@ public abstract class AbstractAlgorithmConstraints
} }
// Get algorithm constraints from the specified security property. // Get algorithm constraints from the specified security property.
private static void loadAlgorithmsMap(Map<String, String[]> algorithmsMap, static String[] getAlgorithms(String propertyName) {
String propertyName) {
String property = AccessController.doPrivileged( String property = AccessController.doPrivileged(
(PrivilegedAction<String>) () -> Security.getProperty( (PrivilegedAction<String>) () -> Security.getProperty(
propertyName)); propertyName));
@ -68,18 +66,7 @@ public abstract class AbstractAlgorithmConstraints
if (algorithmsInProperty == null) { if (algorithmsInProperty == null) {
algorithmsInProperty = new String[0]; algorithmsInProperty = new String[0];
} }
algorithmsMap.put(propertyName, algorithmsInProperty); return algorithmsInProperty;
}
static String[] getAlgorithms(Map<String, String[]> algorithmsMap,
String propertyName) {
synchronized (algorithmsMap) {
if (!algorithmsMap.containsKey(propertyName)) {
loadAlgorithmsMap(algorithmsMap, propertyName);
}
return algorithmsMap.get(propertyName);
}
} }
static boolean checkAlgorithm(String[] algorithms, String algorithm, static boolean checkAlgorithm(String[] algorithms, String algorithm,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -40,19 +40,7 @@ public class AlgorithmDecomposer {
private static final Pattern pattern = private static final Pattern pattern =
Pattern.compile("with|and|(?<!padd)in", Pattern.CASE_INSENSITIVE); Pattern.compile("with|and|(?<!padd)in", Pattern.CASE_INSENSITIVE);
/** private static Set<String> decomposeImpl(String algorithm) {
* Decompose the standard algorithm name into sub-elements.
* <p>
* For example, we need to decompose "SHA1WithRSA" into "SHA1" and "RSA"
* so that we can check the "SHA1" and "RSA" algorithm constraints
* separately.
* <p>
* Please override the method if need to support more name pattern.
*/
public Set<String> decompose(String algorithm) {
if (algorithm == null || algorithm.length() == 0) {
return new HashSet<>();
}
// algorithm/mode/padding // algorithm/mode/padding
String[] transTockens = transPattern.split(algorithm); String[] transTockens = transPattern.split(algorithm);
@ -79,6 +67,24 @@ public class AlgorithmDecomposer {
elements.add(token); elements.add(token);
} }
} }
return elements;
}
/**
* Decompose the standard algorithm name into sub-elements.
* <p>
* For example, we need to decompose "SHA1WithRSA" into "SHA1" and "RSA"
* so that we can check the "SHA1" and "RSA" algorithm constraints
* separately.
* <p>
* Please override the method if need to support more name pattern.
*/
public Set<String> decompose(String algorithm) {
if (algorithm == null || algorithm.length() == 0) {
return new HashSet<>();
}
Set<String> elements = decomposeImpl(algorithm);
// In Java standard algorithm name specification, for different // In Java standard algorithm name specification, for different
// purpose, the SHA-1 and SHA-2 algorithm names are different. For // purpose, the SHA-1 and SHA-2 algorithm names are different. For
@ -130,4 +136,40 @@ public class AlgorithmDecomposer {
return elements; return elements;
} }
private static void hasLoop(Set<String> elements, String find, String replace) {
if (elements.contains(find)) {
if (!elements.contains(replace)) {
elements.add(replace);
}
elements.remove(find);
}
}
/*
* This decomposes a standard name into sub-elements with a consistent
* message digest algorithm name to avoid overly complicated checking.
*/
public static Set<String> decomposeOneHash(String algorithm) {
if (algorithm == null || algorithm.length() == 0) {
return new HashSet<>();
}
Set<String> elements = decomposeImpl(algorithm);
hasLoop(elements, "SHA-1", "SHA1");
hasLoop(elements, "SHA-224", "SHA224");
hasLoop(elements, "SHA-256", "SHA256");
hasLoop(elements, "SHA-384", "SHA384");
hasLoop(elements, "SHA-512", "SHA512");
return elements;
}
/*
* The provided message digest algorithm name will return a consistent
* naming scheme.
*/
public static String hashName(String algorithm) {
return algorithm.replace("-", "");
}
} }

View File

@ -0,0 +1,101 @@
/*
* Copyright (c) 2016, 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 sun.security.util;
import java.io.File;
import java.io.FileInputStream;
import java.security.AccessController;
import java.security.KeyStore;
import java.security.PrivilegedAction;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import java.util.HashSet;
import sun.security.x509.X509CertImpl;
/**
* The purpose of this class is to determine the trust anchor certificates is in
* the cacerts file. This is used for PKIX CertPath checking.
*/
public class AnchorCertificates {
private static final Debug debug = Debug.getInstance("certpath");
private static final String HASH = "SHA-256";
private static HashSet<String> certs;
static {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
File f = new File(System.getProperty("java.home"),
"lib/security/cacerts");
KeyStore cacerts;
try {
cacerts = KeyStore.getInstance("JKS");
try (FileInputStream fis = new FileInputStream(f)) {
cacerts.load(fis, "changeit".toCharArray());
certs = new HashSet<>();
Enumeration<String> list = cacerts.aliases();
String alias;
while (list.hasMoreElements()) {
alias = list.nextElement();
// Check if this cert is labeled a trust anchor.
if (alias.contains(" [jdk")) {
X509Certificate cert = (X509Certificate) cacerts
.getCertificate(alias);
certs.add(X509CertImpl.getFingerprint(HASH, cert));
}
}
}
} catch (Exception e) {
if (debug != null) {
debug.println("Error parsing cacerts");
}
e.printStackTrace();
}
return null;
}
});
}
/**
* Checks if a certificate is a trust anchor.
*
* @param cert the certificate to check
* @return true if the certificate is trusted.
*/
public static boolean contains(X509Certificate cert) {
String key = X509CertImpl.getFingerprint(HASH, cert);
boolean result = certs.contains(key);
if (result && debug != null) {
debug.println("AnchorCertificate.contains: matched " +
cert.getSubjectDN());
}
return result;
}
private AnchorCertificates() {}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,43 +23,37 @@
* questions. * questions.
*/ */
#include <jni.h> package sun.security.util;
#include <string.h>
#include "net_util.h" import java.security.cert.X509Certificate;
/* /**
* Class: sun_net_ExtendedOptionsImpl * This class is a wrapper for keeping state and passing objects between PKIX,
* Method: init * AlgorithmChecker, and DisabledAlgorithmConstraints.
* Signature: ()V
*/ */
JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_init public class CertConstraintParameters {
(JNIEnv *env, jclass UNUSED) // A certificate being passed to check against constraints.
{ private final X509Certificate cert;
// This is true if the trust anchor in the certificate chain matches a cert
// in AnchorCertificates
private final boolean trustedMatch;
public CertConstraintParameters(X509Certificate c, boolean match) {
cert = c;
trustedMatch = match;
} }
/* Non Solaris. Functionality is not supported. So, throw UnsupportedOpExc */ public CertConstraintParameters(X509Certificate c) {
this(c, false);
JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setFlowOption
(JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
{
JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
"unsupported socket option");
} }
JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_getFlowOption // Returns if the trust anchor has a match if anchor checking is enabled.
(JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow) public boolean isTrustedMatch() {
{ return trustedMatch;
JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
"unsupported socket option");
} }
static jboolean flowSupported0() { public X509Certificate getCertificate() {
return JNI_FALSE; return cert;
} }
JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_flowSupported
(JNIEnv *env, jclass UNUSED)
{
return JNI_FALSE;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -28,12 +28,14 @@ package sun.security.util;
import java.security.CryptoPrimitive; import java.security.CryptoPrimitive;
import java.security.AlgorithmParameters; import java.security.AlgorithmParameters;
import java.security.Key; import java.security.Key;
import java.util.Locale; import java.security.cert.CertPathValidatorException;
import java.util.Set; import java.security.cert.CertPathValidatorException.BasicReason;
import java.util.Collections; import java.security.cert.X509Certificate;
import java.util.HashSet;
import java.util.Map;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -44,6 +46,7 @@ import java.util.regex.Matcher;
* for the syntax of the disabled algorithm string. * for the syntax of the disabled algorithm string.
*/ */
public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
private static final Debug debug = Debug.getInstance("certpath");
// the known security property, jdk.certpath.disabledAlgorithms // the known security property, jdk.certpath.disabledAlgorithms
public static final String PROPERTY_CERTPATH_DISABLED_ALGS = public static final String PROPERTY_CERTPATH_DISABLED_ALGS =
@ -53,13 +56,8 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
public static final String PROPERTY_TLS_DISABLED_ALGS = public static final String PROPERTY_TLS_DISABLED_ALGS =
"jdk.tls.disabledAlgorithms"; "jdk.tls.disabledAlgorithms";
private static final Map<String, String[]> disabledAlgorithmsMap =
new HashMap<>();
private static final Map<String, KeySizeConstraints> keySizeConstraintsMap =
new HashMap<>();
private final String[] disabledAlgorithms; private final String[] disabledAlgorithms;
private final KeySizeConstraints keySizeConstraints; private final Constraints algorithmConstraints;
/** /**
* Initialize algorithm constraints with the specified security property. * Initialize algorithm constraints with the specified security property.
@ -74,11 +72,14 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
public DisabledAlgorithmConstraints(String propertyName, public DisabledAlgorithmConstraints(String propertyName,
AlgorithmDecomposer decomposer) { AlgorithmDecomposer decomposer) {
super(decomposer); super(decomposer);
disabledAlgorithms = getAlgorithms(disabledAlgorithmsMap, propertyName); disabledAlgorithms = getAlgorithms(propertyName);
keySizeConstraints = getKeySizeConstraints(disabledAlgorithms, algorithmConstraints = new Constraints(disabledAlgorithms);
propertyName);
} }
/*
* This only checks if the algorithm has been completely disabled. If
* there are keysize or other limit, this method allow the algorithm.
*/
@Override @Override
public final boolean permits(Set<CryptoPrimitive> primitives, public final boolean permits(Set<CryptoPrimitive> primitives,
String algorithm, AlgorithmParameters parameters) { String algorithm, AlgorithmParameters parameters) {
@ -91,11 +92,19 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
return checkAlgorithm(disabledAlgorithms, algorithm, decomposer); return checkAlgorithm(disabledAlgorithms, algorithm, decomposer);
} }
/*
* Checks if the key algorithm has been disabled or constraints have been
* placed on the key.
*/
@Override @Override
public final boolean permits(Set<CryptoPrimitive> primitives, Key key) { public final boolean permits(Set<CryptoPrimitive> primitives, Key key) {
return checkConstraints(primitives, "", key, null); return checkConstraints(primitives, "", key, null);
} }
/*
* Checks if the key algorithm has been disabled or if constraints have
* been placed on the key.
*/
@Override @Override
public final boolean permits(Set<CryptoPrimitive> primitives, public final boolean permits(Set<CryptoPrimitive> primitives,
String algorithm, Key key, AlgorithmParameters parameters) { String algorithm, Key key, AlgorithmParameters parameters) {
@ -107,7 +116,39 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
return checkConstraints(primitives, algorithm, key, parameters); return checkConstraints(primitives, algorithm, key, parameters);
} }
// Check algorithm constraints /*
* Check if a x509Certificate object is permitted. Check if all
* algorithms are allowed, certificate constraints, and the
* public key against key constraints.
*
* Uses new style permit() which throws exceptions.
*/
public final void permits(Set<CryptoPrimitive> primitives,
CertConstraintParameters cp) throws CertPathValidatorException {
checkConstraints(primitives, cp);
}
/*
* Check if Certificate object is within the constraints.
* Uses new style permit() which throws exceptions.
*/
public final void permits(Set<CryptoPrimitive> primitives,
X509Certificate cert) throws CertPathValidatorException {
checkConstraints(primitives, new CertConstraintParameters(cert));
}
// Check if a string is contained inside the property
public boolean checkProperty(String param) {
param = param.toLowerCase(Locale.ENGLISH);
for (String block : disabledAlgorithms) {
if (block.toLowerCase(Locale.ENGLISH).indexOf(param) >= 0) {
return true;
}
}
return false;
}
// Check algorithm constraints with key and algorithm
private boolean checkConstraints(Set<CryptoPrimitive> primitives, private boolean checkConstraints(Set<CryptoPrimitive> primitives,
String algorithm, Key key, AlgorithmParameters parameters) { String algorithm, Key key, AlgorithmParameters parameters) {
@ -116,7 +157,7 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
throw new IllegalArgumentException("The key cannot be null"); throw new IllegalArgumentException("The key cannot be null");
} }
// check the target algorithm // check the signature algorithm
if (algorithm != null && algorithm.length() != 0) { if (algorithm != null && algorithm.length() != 0) {
if (!permits(primitives, algorithm, parameters)) { if (!permits(primitives, algorithm, parameters)) {
return false; return false;
@ -129,97 +170,203 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
} }
// check the key constraints // check the key constraints
if (keySizeConstraints.disables(key)) { return algorithmConstraints.permits(key);
return false;
} }
return true; /*
* Check algorithm constraints with Certificate
* Uses new style permit() which throws exceptions.
*/
private void checkConstraints(Set<CryptoPrimitive> primitives,
CertConstraintParameters cp) throws CertPathValidatorException {
X509Certificate cert = cp.getCertificate();
String algorithm = cert.getSigAlgName();
// Check signature algorithm is not disabled
if (!permits(primitives, algorithm, null)) {
throw new CertPathValidatorException(
"Algorithm constraints check failed on disabled "+
"signature algorithm: " + algorithm,
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
} }
private static KeySizeConstraints getKeySizeConstraints( // Check key algorithm is not disabled
String[] disabledAlgorithms, String propertyName) { if (!permits(primitives, cert.getPublicKey().getAlgorithm(), null)) {
synchronized (keySizeConstraintsMap) { throw new CertPathValidatorException(
if(!keySizeConstraintsMap.containsKey(propertyName)) { "Algorithm constraints check failed on disabled "+
// map the key constraints "public key algorithm: " + algorithm,
KeySizeConstraints keySizeConstraints = null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
new KeySizeConstraints(disabledAlgorithms);
keySizeConstraintsMap.put(propertyName, keySizeConstraints);
} }
return keySizeConstraintsMap.get(propertyName); // Check the certificate and key constraints
} algorithmConstraints.permits(cp);
} }
/** /**
* key constraints * Key and Certificate Constraints
*
* The complete disabling of an algorithm is not handled by Constraints or
* Constraint classes. That is addressed with
* permit(Set<CryptoPrimitive>, String, AlgorithmParameters)
*
* When passing a Key to permit(), the boolean return values follow the
* same as the interface class AlgorithmConstraints.permit(). This is to
* maintain compatibility:
* 'true' means the operation is allowed.
* 'false' means it failed the constraints and is disallowed.
*
* When passing CertConstraintParameters through permit(), an exception
* will be thrown on a failure to better identify why the operation was
* disallowed.
*/ */
private static class KeySizeConstraints {
private static final Pattern pattern = Pattern.compile(
"(\\S+)\\s+keySize\\s*(<=|<|==|!=|>|>=)\\s*(\\d+)");
private Map<String, Set<KeySizeConstraint>> constraintsMap = private static class Constraints {
Collections.synchronizedMap( private Map<String, Set<Constraint>> constraintsMap = new HashMap<>();
new HashMap<String, Set<KeySizeConstraint>>()); private static final Pattern keySizePattern = Pattern.compile(
"keySize\\s*(<=|<|==|!=|>|>=)\\s*(\\d+)");
public KeySizeConstraints(String[] restrictions) { public Constraints(String[] constraintArray) {
for (String restriction : restrictions) { for (String constraintEntry : constraintArray) {
if (restriction == null || restriction.isEmpty()) { if (constraintEntry == null || constraintEntry.isEmpty()) {
continue; continue;
} }
Matcher matcher = pattern.matcher(restriction); constraintEntry = constraintEntry.trim();
if (debug != null) {
debug.println("Constraints: " + constraintEntry);
}
// Check if constraint is a complete disabling of an
// algorithm or has conditions.
String algorithm;
String policy;
int space = constraintEntry.indexOf(' ');
if (space > 0) {
algorithm = AlgorithmDecomposer.hashName(
constraintEntry.substring(0, space).
toUpperCase(Locale.ENGLISH));
policy = constraintEntry.substring(space + 1);
} else {
constraintsMap.computeIfAbsent(
constraintEntry.toUpperCase(Locale.ENGLISH),
k -> new HashSet<>());
continue;
}
// Convert constraint conditions into Constraint classes
Constraint c, lastConstraint = null;
// Allow only one jdkCA entry per constraint entry
boolean jdkCALimit = false;
for (String entry : policy.split("&")) {
entry = entry.trim();
Matcher matcher = keySizePattern.matcher(entry);
if (matcher.matches()) { if (matcher.matches()) {
String algorithm = matcher.group(1); if (debug != null) {
debug.println("Constraints set to keySize: " +
entry);
}
c = new KeySizeConstraint(algorithm,
KeySizeConstraint.Operator.of(matcher.group(1)),
Integer.parseInt(matcher.group(2)));
KeySizeConstraint.Operator operator = } else if (entry.equalsIgnoreCase("jdkCA")) {
KeySizeConstraint.Operator.of(matcher.group(2)); if (debug != null) {
int length = Integer.parseInt(matcher.group(3)); debug.println("Constraints set to jdkCA.");
}
if (jdkCALimit) {
throw new IllegalArgumentException("Only one " +
"jdkCA entry allowed in property. " +
"Constraint: " + constraintEntry);
}
c = new jdkCAConstraint(algorithm);
jdkCALimit = true;
} else {
throw new IllegalArgumentException("Error in security" +
" property. Constraint unknown: " + entry);
}
algorithm = algorithm.toLowerCase(Locale.ENGLISH); // Link multiple conditions for a single constraint
// into a linked list.
synchronized (constraintsMap) { if (lastConstraint == null) {
if (!constraintsMap.containsKey(algorithm)) { if (!constraintsMap.containsKey(algorithm)) {
constraintsMap.put(algorithm, constraintsMap.putIfAbsent(algorithm,
new HashSet<KeySizeConstraint>()); new HashSet<>());
} }
constraintsMap.get(algorithm).add(c);
Set<KeySizeConstraint> constraintSet = } else {
constraintsMap.get(algorithm); lastConstraint.nextConstraint = c;
KeySizeConstraint constraint =
new KeySizeConstraint(operator, length);
constraintSet.add(constraint);
} }
lastConstraint = c;
} }
} }
} }
// Does this KeySizeConstraints disable the specified key? // Get applicable constraints based off the signature algorithm
public boolean disables(Key key) { private Set<Constraint> getConstraints(String algorithm) {
String algorithm = key.getAlgorithm().toLowerCase(Locale.ENGLISH); return constraintsMap.get(algorithm);
synchronized (constraintsMap) { }
if (constraintsMap.containsKey(algorithm)) {
Set<KeySizeConstraint> constraintSet = // Check if KeySizeConstraints permit the specified key
constraintsMap.get(algorithm); public boolean permits(Key key) {
for (KeySizeConstraint constraint : constraintSet) { Set<Constraint> set = getConstraints(key.getAlgorithm());
if (constraint.disables(key)) { if (set == null) {
return true; return true;
} }
for (Constraint constraint : set) {
if (!constraint.permits(key)) {
if (debug != null) {
debug.println("keySizeConstraint: failed key " +
"constraint check " + KeyUtil.getKeySize(key));
} }
}
}
return false; return false;
} }
} }
return true;
}
// Check if constraints permit this cert.
public void permits(CertConstraintParameters cp)
throws CertPathValidatorException {
X509Certificate cert = cp.getCertificate();
if (debug != null) {
debug.println("Constraints.permits(): " + cert.getSigAlgName());
}
// Get all signature algorithms to check for constraints
Set<String> algorithms =
AlgorithmDecomposer.decomposeOneHash(cert.getSigAlgName());
if (algorithms == null || algorithms.isEmpty()) {
return;
}
// Attempt to add the public key algorithm to the set
algorithms.add(cert.getPublicKey().getAlgorithm());
// Check all applicable constraints
for (String algorithm : algorithms) {
Set<Constraint> set = getConstraints(algorithm);
if (set == null) {
continue;
}
for (Constraint constraint : set) {
constraint.permits(cp);
}
}
}
}
// Abstract class for algorithm constraint checking
private abstract static class Constraint {
String algorithm;
Constraint nextConstraint = null;
/**
* Key size constraint.
*
* e.g. "keysize <= 1024"
*/
private static class KeySizeConstraint {
// operator // operator
static enum Operator { enum Operator {
EQ, // "==" EQ, // "=="
NE, // "!=" NE, // "!="
LT, // "<" LT, // "<"
@ -243,16 +390,77 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
return GE; return GE;
} }
throw new IllegalArgumentException( throw new IllegalArgumentException("Error in security " +
s + " is not a legal Operator"); "property. " + s + " is not a legal Operator");
} }
} }
/**
* Check if an algorithm constraint permit this key to be used.
* @param key Public key
* @return true if constraints do not match
*/
public boolean permits(Key key) {
return true;
}
/**
* Check if an algorithm constraint is permit this certificate to
* be used.
* @param cp CertificateParameter containing certificate and state info
* @return true if constraints do not match
*/
public abstract void permits(CertConstraintParameters cp)
throws CertPathValidatorException;
}
/*
* This class contains constraints dealing with the certificate chain
* of the certificate.
*/
private static class jdkCAConstraint extends Constraint {
jdkCAConstraint(String algo) {
algorithm = algo;
}
/*
* Check if each constraint fails and check if there is a linked
* constraint Any permitted constraint will exit the linked list
* to allow the operation.
*/
public void permits(CertConstraintParameters cp)
throws CertPathValidatorException {
if (debug != null) {
debug.println("jdkCAConstraints.permits(): " + algorithm);
}
// Return false if the chain has a trust anchor in cacerts
if (cp.isTrustedMatch()) {
if (nextConstraint != null) {
nextConstraint.permits(cp);
return;
}
throw new CertPathValidatorException(
"Algorithm constraints check failed on certificate " +
"anchor limits",
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
}
/*
* This class contains constraints dealing with the key size
* support limits per algorithm. e.g. "keySize <= 1024"
*/
private static class KeySizeConstraint extends Constraint {
private int minSize; // the minimal available key size private int minSize; // the minimal available key size
private int maxSize; // the maximal available key size private int maxSize; // the maximal available key size
private int prohibitedSize = -1; // unavailable key sizes private int prohibitedSize = -1; // unavailable key sizes
public KeySizeConstraint(Operator operator, int length) { public KeySizeConstraint(String algo, Operator operator, int length) {
algorithm = algo;
switch (operator) { switch (operator) {
case EQ: // an unavailable key size case EQ: // an unavailable key size
this.minSize = 0; this.minSize = 0;
@ -286,21 +494,59 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
} }
} }
// Does this key constraint disable the specified key? /*
public boolean disables(Key key) { * If we are passed a certificate, extract the public key and use it.
int size = KeyUtil.getKeySize(key); *
* Check if each constraint fails and check if there is a linked
* constraint Any permitted constraint will exit the linked list
* to allow the operation.
*/
public void permits(CertConstraintParameters cp)
throws CertPathValidatorException {
if (!permitsImpl(cp.getCertificate().getPublicKey())) {
if (nextConstraint != null) {
nextConstraint.permits(cp);
return;
}
throw new CertPathValidatorException(
"Algorithm constraints check failed on keysize limits",
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
// Check if key constraint disable the specified key
// Uses old style permit()
public boolean permits(Key key) {
// If we recursively find a constraint that permits us to use
// this key, return true and skip any other constraint checks.
if (nextConstraint != null && nextConstraint.permits(key)) {
return true;
}
if (debug != null) {
debug.println("KeySizeConstraints.permits(): " + algorithm);
}
return permitsImpl(key);
}
private boolean permitsImpl(Key key) {
// Verify this constraint is for this public key algorithm
if (algorithm.compareToIgnoreCase(key.getAlgorithm()) != 0) {
return true;
}
int size = KeyUtil.getKeySize(key);
if (size == 0) { if (size == 0) {
return true; // we don't allow any key of size 0. return false; // we don't allow any key of size 0.
} else if (size > 0) { } else if (size > 0) {
return ((size < minSize) || (size > maxSize) || return !((size < minSize) || (size > maxSize) ||
(prohibitedSize == size)); (prohibitedSize == size));
} // Otherwise, the key size is not accessible. Conservatively, } // Otherwise, the key size is not accessible. Conservatively,
// please don't disable such keys. // please don't disable such keys.
return false; return true;
}
} }
} }
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -28,8 +28,6 @@ package sun.security.util;
import java.security.AlgorithmParameters; import java.security.AlgorithmParameters;
import java.security.CryptoPrimitive; import java.security.CryptoPrimitive;
import java.security.Key; import java.security.Key;
import java.util.HashMap;
import java.util.Map;
import java.util.Set; import java.util.Set;
import static sun.security.util.AbstractAlgorithmConstraints.getAlgorithms; import static sun.security.util.AbstractAlgorithmConstraints.getAlgorithms;
@ -42,15 +40,12 @@ public class LegacyAlgorithmConstraints extends AbstractAlgorithmConstraints {
public static final String PROPERTY_TLS_LEGACY_ALGS = public static final String PROPERTY_TLS_LEGACY_ALGS =
"jdk.tls.legacyAlgorithms"; "jdk.tls.legacyAlgorithms";
private static final Map<String, String[]> legacyAlgorithmsMap =
new HashMap<>();
private final String[] legacyAlgorithms; private final String[] legacyAlgorithms;
public LegacyAlgorithmConstraints(String propertyName, public LegacyAlgorithmConstraints(String propertyName,
AlgorithmDecomposer decomposer) { AlgorithmDecomposer decomposer) {
super(decomposer); super(decomposer);
legacyAlgorithms = getAlgorithms(legacyAlgorithmsMap, propertyName); legacyAlgorithms = getAlgorithms(propertyName);
} }
@Override @Override

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -1924,17 +1924,18 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
public String getFingerprint(String algorithm) { public String getFingerprint(String algorithm) {
return fingerprints.computeIfAbsent(algorithm, return fingerprints.computeIfAbsent(algorithm,
x -> getCertificateFingerPrint(x)); x -> getFingerprint(x, this));
} }
/** /**
* Gets the requested finger print of the certificate. The result * Gets the requested finger print of the certificate. The result
* only contains 0-9 and A-F. No small case, no colon. * only contains 0-9 and A-F. No small case, no colon.
*/ */
private String getCertificateFingerPrint(String mdAlg) { public static String getFingerprint(String algorithm,
X509Certificate cert) {
try { try {
byte[] encCertInfo = getEncoded(); byte[] encCertInfo = cert.getEncoded();
MessageDigest md = MessageDigest.getInstance(mdAlg); MessageDigest md = MessageDigest.getInstance(algorithm);
byte[] digest = md.digest(encCertInfo); byte[] digest = md.digest(encCertInfo);
StringBuilder sb = new StringBuilder(digest.length * 2); StringBuilder sb = new StringBuilder(digest.length * 2);
for (int i = 0; i < digest.length; i++) { for (int i = 0; i < digest.length; i++) {

View File

@ -286,12 +286,15 @@ public class PlatformLogger {
} }
if (log == null) { if (log == null) {
log = new PlatformLogger(PlatformLogger.Bridge.convert( log = new PlatformLogger(PlatformLogger.Bridge.convert(
// We pass PlatformLogger.class rather than the actual caller // We pass PlatformLogger.class.getModule() (java.base)
// rather than the actual module of the caller
// because we want PlatformLoggers to be system loggers: we // because we want PlatformLoggers to be system loggers: we
// won't need to resolve any resource bundles anyway. // won't need to resolve any resource bundles anyway.
// Note: Many unit tests depend on the fact that // Note: Many unit tests depend on the fact that
// PlatformLogger.getLoggerFromFinder is not caller sensitive. // PlatformLogger.getLoggerFromFinder is not caller
LazyLoggers.getLazyLogger(name, PlatformLogger.class))); // sensitive, and this strategy ensure that the tests
// still pass.
LazyLoggers.getLazyLogger(name, PlatformLogger.class.getModule())));
loggers.put(name, new WeakReference<>(log)); loggers.put(name, new WeakReference<>(log));
} }
return log; return log;

View File

@ -497,13 +497,13 @@ krb5.kdc.bad.policy = tryLast
# " DisabledAlgorithm { , DisabledAlgorithm } " # " DisabledAlgorithm { , DisabledAlgorithm } "
# #
# DisabledAlgorithm: # DisabledAlgorithm:
# AlgorithmName [Constraint] # AlgorithmName [Constraint] { '&' Constraint }
# #
# AlgorithmName: # AlgorithmName:
# (see below) # (see below)
# #
# Constraint: # Constraint:
# KeySizeConstraint # KeySizeConstraint, CertConstraint
# #
# KeySizeConstraint: # KeySizeConstraint:
# keySize Operator DecimalInteger # keySize Operator DecimalInteger
@ -520,6 +520,9 @@ krb5.kdc.bad.policy = tryLast
# DecimalDigit: one of # DecimalDigit: one of
# 1 2 3 4 5 6 7 8 9 0 # 1 2 3 4 5 6 7 8 9 0
# #
# CertConstraint
# jdkCA
#
# The "AlgorithmName" is the standard algorithm name of the disabled # The "AlgorithmName" is the standard algorithm name of the disabled
# algorithm. See "Java Cryptography Architecture Standard Algorithm Name # algorithm. See "Java Cryptography Architecture Standard Algorithm Name
# Documentation" for information about Standard Algorithm Names. Matching # Documentation" for information about Standard Algorithm Names. Matching
@ -542,6 +545,29 @@ krb5.kdc.bad.policy = tryLast
# be disabled. Note that the "KeySizeConstraint" only makes sense to key # be disabled. Note that the "KeySizeConstraint" only makes sense to key
# algorithms. # algorithms.
# #
# "CertConstraint" specifies additional constraints for
# certificates that contain algorithms that are restricted:
#
#   "jdkCA" prohibits the specified algorithm only if the algorithm is used
#     in a certificate chain that terminates at a marked trust anchor in the
#     lib/security/cacerts keystore.  All other chains are not affected.
#     If the jdkCA constraint is not set, then all chains using the
#     specified algorithm are restricted. jdkCA may only be used once in
# a DisabledAlgorithm expression.
#     Example:  To apply this constraint to SHA-1 certificates, include
#     the following:  "SHA1 jdkCA"
#
# When an algorithm must satisfy more than one constraint, it must be
# delimited by an ampersand '&'. For example, to restrict certificates in a
# chain that terminate at a distribution provided trust anchor and contain
# RSA keys that are less than or equal to 1024 bits, add the following
# constraint: "RSA keySize <= 1024 & jdkCA".
#
# All DisabledAlgorithms expressions are processed in the order defined in the
# property. This requires lower keysize constraints to be specified
# before larger keysize constraints of the same algorithm. For example:
# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048".
#
# Note: This property is currently used by Oracle's PKIX implementation. It # Note: This property is currently used by Oracle's PKIX implementation. It
# is not guaranteed to be examined and used by other implementations. # is not guaranteed to be examined and used by other implementations.
# #

View File

@ -27,9 +27,7 @@ package java.net;
import java.io.IOException; import java.io.IOException;
import java.util.Set; import java.util.Set;
import java.util.HashSet; import java.util.HashSet;
import java.util.Collections; import sun.net.ext.ExtendedSocketOptions;
import jdk.net.*;
import static sun.net.ExtendedOptionsImpl.*;
/* /*
* On Unix systems we simply delegate to native methods. * On Unix systems we simply delegate to native methods.
@ -43,8 +41,11 @@ class PlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
init(); init();
} }
static final ExtendedSocketOptions extendedOptions =
ExtendedSocketOptions.getInstance();
protected <T> void setOption(SocketOption<T> name, T value) throws IOException { protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) { if (!extendedOptions.isOptionSupported(name)) {
if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) { if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
super.setOption(name, value); super.setOption(name, value);
} else { } else {
@ -55,21 +56,16 @@ class PlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
} }
} }
} else { } else {
if (!flowSupported()) {
throw new UnsupportedOperationException("unsupported option");
}
if (isClosed()) { if (isClosed()) {
throw new SocketException("Socket closed"); throw new SocketException("Socket closed");
} }
checkSetOptionPermission(name); extendedOptions.setOption(fd, name, value);
checkValueType(value, SocketFlow.class);
setFlowOption(getFileDescriptor(), (SocketFlow)value);
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected <T> T getOption(SocketOption<T> name) throws IOException { protected <T> T getOption(SocketOption<T> name) throws IOException {
if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) { if (!extendedOptions.isOptionSupported(name)) {
if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) { if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
return super.getOption(name); return super.getOption(name);
} else { } else {
@ -79,31 +75,23 @@ class PlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
throw new UnsupportedOperationException("unsupported option"); throw new UnsupportedOperationException("unsupported option");
} }
} }
} } else {
if (!flowSupported()) {
throw new UnsupportedOperationException("unsupported option");
}
if (isClosed()) { if (isClosed()) {
throw new SocketException("Socket closed"); throw new SocketException("Socket closed");
} }
checkGetOptionPermission(name); return (T) extendedOptions.getOption(fd, name);
SocketFlow flow = SocketFlow.create(); }
getFlowOption(getFileDescriptor(), flow);
return (T)flow;
} }
protected Set<SocketOption<?>> supportedOptions() { protected Set<SocketOption<?>> supportedOptions() {
HashSet<SocketOption<?>> options = new HashSet<>( HashSet<SocketOption<?>> options = new HashSet<>(super.supportedOptions());
super.supportedOptions()); options.addAll(extendedOptions.options());
if (flowSupported()) {
options.add(ExtendedSocketOptions.SO_FLOW_SLA);
}
return options; return options;
} }
protected void socketSetOption(int opt, Object val) throws SocketException { protected void socketSetOption(int opt, Object val) throws SocketException {
if (opt == SocketOptions.SO_REUSEPORT && !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) { if (opt == SocketOptions.SO_REUSEPORT &&
!supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
throw new UnsupportedOperationException("unsupported option"); throw new UnsupportedOperationException("unsupported option");
} }
try { try {

View File

@ -28,10 +28,7 @@ import java.io.IOException;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.util.Set; import java.util.Set;
import java.util.HashSet; import java.util.HashSet;
import java.util.Collections; import sun.net.ext.ExtendedSocketOptions;
import jdk.net.*;
import static sun.net.ExtendedOptionsImpl.*;
/* /*
* On Unix systems we simply delegate to native methods. * On Unix systems we simply delegate to native methods.
@ -57,8 +54,11 @@ class PlainSocketImpl extends AbstractPlainSocketImpl
this.fd = fd; this.fd = fd;
} }
static final ExtendedSocketOptions extendedOptions =
ExtendedSocketOptions.getInstance();
protected <T> void setOption(SocketOption<T> name, T value) throws IOException { protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) { if (!extendedOptions.isOptionSupported(name)) {
if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) { if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
super.setOption(name, value); super.setOption(name, value);
} else { } else {
@ -69,21 +69,19 @@ class PlainSocketImpl extends AbstractPlainSocketImpl
} }
} }
} else { } else {
if (getSocket() == null || !flowSupported()) { if (getSocket() == null) {
throw new UnsupportedOperationException("unsupported option"); throw new UnsupportedOperationException("unsupported option");
} }
if (isClosedOrPending()) { if (isClosedOrPending()) {
throw new SocketException("Socket closed"); throw new SocketException("Socket closed");
} }
checkSetOptionPermission(name); extendedOptions.setOption(fd, name, value);
checkValueType(value, SocketFlow.class);
setFlowOption(getFileDescriptor(), (SocketFlow)value);
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected <T> T getOption(SocketOption<T> name) throws IOException { protected <T> T getOption(SocketOption<T> name) throws IOException {
if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) { if (!extendedOptions.isOptionSupported(name)) {
if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) { if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
return super.getOption(name); return super.getOption(name);
} else { } else {
@ -93,31 +91,28 @@ class PlainSocketImpl extends AbstractPlainSocketImpl
throw new UnsupportedOperationException("unsupported option"); throw new UnsupportedOperationException("unsupported option");
} }
} }
} } else {
if (getSocket() == null || !flowSupported()) { if (getSocket() == null) {
throw new UnsupportedOperationException("unsupported option"); throw new UnsupportedOperationException("unsupported option");
} }
if (isClosedOrPending()) { if (isClosedOrPending()) {
throw new SocketException("Socket closed"); throw new SocketException("Socket closed");
} }
checkGetOptionPermission(name); return (T) extendedOptions.getOption(fd, name);
SocketFlow flow = SocketFlow.create(); }
getFlowOption(getFileDescriptor(), flow);
return (T)flow;
} }
protected Set<SocketOption<?>> supportedOptions() { protected Set<SocketOption<?>> supportedOptions() {
HashSet<SocketOption<?>> options = new HashSet<>( HashSet<SocketOption<?>> options = new HashSet<>(super.supportedOptions());
super.supportedOptions()); if (getSocket() != null) {
options.addAll(extendedOptions.options());
if (getSocket() != null && flowSupported()) {
options.add(ExtendedSocketOptions.SO_FLOW_SLA);
} }
return options; return options;
} }
protected void socketSetOption(int opt, boolean b, Object val) throws SocketException { protected void socketSetOption(int opt, boolean b, Object val) throws SocketException {
if (opt == SocketOptions.SO_REUSEPORT && !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) { if (opt == SocketOptions.SO_REUSEPORT &&
!supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
throw new UnsupportedOperationException("unsupported option"); throw new UnsupportedOperationException("unsupported option");
} }
try { try {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,7 +29,6 @@ import java.io.IOException;
import java.nio.channels.*; import java.nio.channels.*;
import java.nio.channels.spi.*; import java.nio.channels.spi.*;
import java.util.*; import java.util.*;
import sun.misc.*;
/** /**

View File

@ -1,344 +0,0 @@
/*
* Copyright (c) 2014, 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.
*/
#include <jni.h>
#include <string.h>
#include "net_util.h"
#include "jdk_net_SocketFlow.h"
static jclass sf_status_class; /* Status enum type */
static jfieldID sf_status;
static jfieldID sf_priority;
static jfieldID sf_bandwidth;
static jfieldID sf_fd_fdID; /* FileDescriptor.fd */
/* References to the literal enum values */
static jobject sfs_NOSTATUS;
static jobject sfs_OK;
static jobject sfs_NOPERMISSION;
static jobject sfs_NOTCONNECTED;
static jobject sfs_NOTSUPPORTED;
static jobject sfs_ALREADYCREATED;
static jobject sfs_INPROGRESS;
static jobject sfs_OTHER;
static jobject getEnumField(JNIEnv *env, char *name);
static void setStatus(JNIEnv *env, jobject obj, int errval);
/* OS specific code is implemented in these three functions */
static jboolean flowSupported0() ;
/*
* Class: sun_net_ExtendedOptionsImpl
* Method: init
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_init
(JNIEnv *env, jclass UNUSED)
{
static int initialized = 0;
jclass c;
/* Global class references */
if (initialized) {
return;
}
c = (*env)->FindClass(env, "jdk/net/SocketFlow$Status");
CHECK_NULL(c);
sf_status_class = (*env)->NewGlobalRef(env, c);
CHECK_NULL(sf_status_class);
/* int "fd" field of java.io.FileDescriptor */
c = (*env)->FindClass(env, "java/io/FileDescriptor");
CHECK_NULL(c);
sf_fd_fdID = (*env)->GetFieldID(env, c, "fd", "I");
CHECK_NULL(sf_fd_fdID);
/* SocketFlow fields */
c = (*env)->FindClass(env, "jdk/net/SocketFlow");
CHECK_NULL(c);
/* status */
sf_status = (*env)->GetFieldID(env, c, "status",
"Ljdk/net/SocketFlow$Status;");
CHECK_NULL(sf_status);
/* priority */
sf_priority = (*env)->GetFieldID(env, c, "priority", "I");
CHECK_NULL(sf_priority);
/* bandwidth */
sf_bandwidth = (*env)->GetFieldID(env, c, "bandwidth", "J");
CHECK_NULL(sf_bandwidth);
/* Initialize the static enum values */
sfs_NOSTATUS = getEnumField(env, "NO_STATUS");
CHECK_NULL(sfs_NOSTATUS);
sfs_OK = getEnumField(env, "OK");
CHECK_NULL(sfs_OK);
sfs_NOPERMISSION = getEnumField(env, "NO_PERMISSION");
CHECK_NULL(sfs_NOPERMISSION);
sfs_NOTCONNECTED = getEnumField(env, "NOT_CONNECTED");
CHECK_NULL(sfs_NOTCONNECTED);
sfs_NOTSUPPORTED = getEnumField(env, "NOT_SUPPORTED");
CHECK_NULL(sfs_NOTSUPPORTED);
sfs_ALREADYCREATED = getEnumField(env, "ALREADY_CREATED");
CHECK_NULL(sfs_ALREADYCREATED);
sfs_INPROGRESS = getEnumField(env, "IN_PROGRESS");
CHECK_NULL(sfs_INPROGRESS);
sfs_OTHER = getEnumField(env, "OTHER");
CHECK_NULL(sfs_OTHER);
initialized = JNI_TRUE;
}
static jobject getEnumField(JNIEnv *env, char *name)
{
jobject f;
jfieldID fID = (*env)->GetStaticFieldID(env, sf_status_class, name,
"Ljdk/net/SocketFlow$Status;");
CHECK_NULL_RETURN(fID, NULL);
f = (*env)->GetStaticObjectField(env, sf_status_class, fID);
CHECK_NULL_RETURN(f, NULL);
f = (*env)->NewGlobalRef(env, f);
CHECK_NULL_RETURN(f, NULL);
return f;
}
/*
* Retrieve the int file-descriptor from a public socket type object.
* Gets impl, then the FileDescriptor from the impl, and then the fd
* from that.
*/
static int getFD(JNIEnv *env, jobject fileDesc) {
return (*env)->GetIntField(env, fileDesc, sf_fd_fdID);
}
/**
* Sets the status field of a SocketFlow to one of the
* canned enum values
*/
static void setStatus (JNIEnv *env, jobject obj, int errval)
{
switch (errval) {
case 0: /* OK */
(*env)->SetObjectField(env, obj, sf_status, sfs_OK);
break;
case EPERM:
(*env)->SetObjectField(env, obj, sf_status, sfs_NOPERMISSION);
break;
case ENOTCONN:
(*env)->SetObjectField(env, obj, sf_status, sfs_NOTCONNECTED);
break;
case EOPNOTSUPP:
(*env)->SetObjectField(env, obj, sf_status, sfs_NOTSUPPORTED);
break;
case EALREADY:
(*env)->SetObjectField(env, obj, sf_status, sfs_ALREADYCREATED);
break;
case EINPROGRESS:
(*env)->SetObjectField(env, obj, sf_status, sfs_INPROGRESS);
break;
default:
(*env)->SetObjectField(env, obj, sf_status, sfs_OTHER);
break;
}
}
#ifdef __solaris__
/*
* Class: sun_net_ExtendedOptionsImpl
* Method: setFlowOption
* Signature: (Ljava/io/FileDescriptor;Ljdk/net/SocketFlow;)V
*/
JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setFlowOption
(JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
{
int fd = getFD(env, fileDesc);
if (fd < 0) {
NET_ERROR(env, JNU_JAVANETPKG "SocketException", "socket closed");
return;
} else {
sock_flow_props_t props;
jlong bandwidth;
int rv;
jint priority = (*env)->GetIntField(env, flow, sf_priority);
memset(&props, 0, sizeof(props));
props.sfp_version = SOCK_FLOW_PROP_VERSION1;
if (priority != jdk_net_SocketFlow_UNSET) {
props.sfp_mask |= SFP_PRIORITY;
props.sfp_priority = priority;
}
bandwidth = (*env)->GetLongField(env, flow, sf_bandwidth);
if (bandwidth > -1) {
props.sfp_mask |= SFP_MAXBW;
props.sfp_maxbw = (uint64_t) bandwidth;
}
rv = setsockopt(fd, SOL_SOCKET, SO_FLOW_SLA, &props, sizeof(props));
if (rv < 0) {
if (errno == ENOPROTOOPT) {
JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
"unsupported socket option");
} else if (errno == EACCES || errno == EPERM) {
NET_ERROR(env, JNU_JAVANETPKG "SocketException",
"Permission denied");
} else {
NET_ERROR(env, JNU_JAVANETPKG "SocketException",
"set option SO_FLOW_SLA failed");
}
return;
}
setStatus(env, flow, props.sfp_status);
}
}
/*
* Class: sun_net_ExtendedOptionsImpl
* Method: getFlowOption
* Signature: (Ljava/io/FileDescriptor;Ljdk/net/SocketFlow;)V
*/
JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_getFlowOption
(JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
{
int fd = getFD(env, fileDesc);
if (fd < 0) {
NET_ERROR(env, JNU_JAVANETPKG "SocketException", "socket closed");
return;
} else {
sock_flow_props_t props;
int status;
socklen_t sz = sizeof(props);
int rv = getsockopt(fd, SOL_SOCKET, SO_FLOW_SLA, &props, &sz);
if (rv < 0) {
if (errno == ENOPROTOOPT) {
JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
"unsupported socket option");
} else if (errno == EACCES || errno == EPERM) {
NET_ERROR(env, JNU_JAVANETPKG "SocketException",
"Permission denied");
} else {
NET_ERROR(env, JNU_JAVANETPKG "SocketException",
"set option SO_FLOW_SLA failed");
}
return;
}
/* first check status to see if flow exists */
status = props.sfp_status;
setStatus(env, flow, status);
if (status == 0) { /* OK */
/* can set the other fields now */
if (props.sfp_mask & SFP_PRIORITY) {
(*env)->SetIntField(env, flow, sf_priority, props.sfp_priority);
}
if (props.sfp_mask & SFP_MAXBW) {
(*env)->SetLongField(env, flow, sf_bandwidth,
(jlong)props.sfp_maxbw);
}
}
}
}
static jboolean flowsupported;
static jboolean flowsupported_set = JNI_FALSE;
static jboolean flowSupported0()
{
/* Do a simple dummy call, and try to figure out from that */
sock_flow_props_t props;
int rv, s;
if (flowsupported_set) {
return flowsupported;
}
s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s < 0) {
flowsupported = JNI_FALSE;
flowsupported_set = JNI_TRUE;
return JNI_FALSE;
}
memset(&props, 0, sizeof(props));
props.sfp_version = SOCK_FLOW_PROP_VERSION1;
props.sfp_mask |= SFP_PRIORITY;
props.sfp_priority = SFP_PRIO_NORMAL;
rv = setsockopt(s, SOL_SOCKET, SO_FLOW_SLA, &props, sizeof(props));
if (rv != 0 && errno == ENOPROTOOPT) {
rv = JNI_FALSE;
} else {
rv = JNI_TRUE;
}
close(s);
flowsupported = rv;
flowsupported_set = JNI_TRUE;
return flowsupported;
}
#else /* __solaris__ */
/* Non Solaris. Functionality is not supported. So, throw UnsupportedOpExc */
JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setFlowOption
(JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
{
JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
"unsupported socket option");
}
JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_getFlowOption
(JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
{
JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
"unsupported socket option");
}
static jboolean flowSupported0() {
return JNI_FALSE;
}
#endif /* __solaris__ */
JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_flowSupported
(JNIEnv *env, jclass UNUSED)
{
return flowSupported0();
}

View File

@ -120,47 +120,6 @@ int getDefaultIPv6Interface(struct in6_addr *target_addr);
#ifdef __solaris__ #ifdef __solaris__
int net_getParam(char *driver, char *param); int net_getParam(char *driver, char *param);
#ifndef SO_FLOW_SLA
#define SO_FLOW_SLA 0x1018
#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
#pragma pack(4)
#endif #endif
/*
* Used with the setsockopt(SO_FLOW_SLA, ...) call to set
* per socket service level properties.
* When the application uses per-socket API, we will enforce the properties
* on both outbound and inbound packets.
*
* For now, only priority and maxbw are supported in SOCK_FLOW_PROP_VERSION1.
*/
typedef struct sock_flow_props_s {
int sfp_version;
uint32_t sfp_mask;
int sfp_priority; /* flow priority */
uint64_t sfp_maxbw; /* bandwidth limit in bps */
int sfp_status; /* flow create status for getsockopt */
} sock_flow_props_t;
#define SOCK_FLOW_PROP_VERSION1 1
/* bit mask values for sfp_mask */
#define SFP_MAXBW 0x00000001 /* Flow Bandwidth Limit */
#define SFP_PRIORITY 0x00000008 /* Flow priority */
/* possible values for sfp_priority */
#define SFP_PRIO_NORMAL 1
#define SFP_PRIO_HIGH 2
#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
#pragma pack()
#endif /* _LONG_LONG_ALIGNMENT */
#endif /* SO_FLOW_SLA */
#endif /* __solaris__ */
JNIEXPORT jboolean JNICALL NET_IsFlowSupported();
#endif /* NET_UTILS_MD_H */ #endif /* NET_UTILS_MD_H */

View File

@ -113,6 +113,10 @@ class WindowsWatchService
// completion key (used to map I/O completion to WatchKey) // completion key (used to map I/O completion to WatchKey)
private int completionKey; private int completionKey;
// flag indicates that ReadDirectoryChangesW failed
// and overlapped I/O operation wasn't started
private boolean errorStartingOverlapped;
WindowsWatchKey(Path dir, WindowsWatchKey(Path dir,
AbstractWatchService watcher, AbstractWatchService watcher,
FileKey fileKey) FileKey fileKey)
@ -175,6 +179,14 @@ class WindowsWatchService
return completionKey; return completionKey;
} }
void setErrorStartingOverlapped(boolean value) {
errorStartingOverlapped = value;
}
boolean isErrorStartingOverlapped() {
return errorStartingOverlapped;
}
// Invalidate the key, assumes that resources have been released // Invalidate the key, assumes that resources have been released
void invalidate() { void invalidate() {
((WindowsWatchService)watcher()).poller.releaseResources(this); ((WindowsWatchService)watcher()).poller.releaseResources(this);
@ -182,6 +194,7 @@ class WindowsWatchService
buffer = null; buffer = null;
countAddress = 0; countAddress = 0;
overlappedAddress = 0; overlappedAddress = 0;
errorStartingOverlapped = false;
} }
@Override @Override
@ -455,12 +468,14 @@ class WindowsWatchService
* resources. * resources.
*/ */
private void releaseResources(WindowsWatchKey key) { private void releaseResources(WindowsWatchKey key) {
if (!key.isErrorStartingOverlapped()) {
try { try {
CancelIo(key.handle()); CancelIo(key.handle());
GetOverlappedResult(key.handle(), key.overlappedAddress()); GetOverlappedResult(key.handle(), key.overlappedAddress());
} catch (WindowsException expected) { } catch (WindowsException expected) {
// expected as I/O operation has been cancelled // expected as I/O operation has been cancelled
} }
}
CloseHandle(key.handle()); CloseHandle(key.handle());
closeAttachedEvent(key.overlappedAddress()); closeAttachedEvent(key.overlappedAddress());
key.buffer().free(); key.buffer().free();
@ -628,6 +643,7 @@ class WindowsWatchService
} catch (WindowsException x) { } catch (WindowsException x) {
// no choice but to cancel key // no choice but to cancel key
criticalError = true; criticalError = true;
key.setErrorStartingOverlapped(true);
} }
} }
if (criticalError) { if (criticalError) {

View File

@ -83,7 +83,7 @@ class _AppMenuBarHandler {
// if we have no foreground frames, then we have to "kick" the menubar // if we have no foreground frames, then we have to "kick" the menubar
final JFrame pingFrame = new JFrame(); final JFrame pingFrame = new JFrame();
pingFrame.getRootPane().putClientProperty("Window.alpha", new Float(0.0f)); pingFrame.getRootPane().putClientProperty("Window.alpha", Float.valueOf(0.0f));
pingFrame.setUndecorated(true); pingFrame.setUndecorated(true);
pingFrame.setVisible(true); pingFrame.setVisible(true);
pingFrame.toFront(); pingFrame.toFront();

View File

@ -58,7 +58,7 @@ class AquaComboBoxPopup extends BasicComboPopup {
updateContents(false); updateContents(false);
// TODO: CPlatformWindow? // TODO: CPlatformWindow?
putClientProperty(CPlatformWindow.WINDOW_FADE_OUT, new Integer(150)); putClientProperty(CPlatformWindow.WINDOW_FADE_OUT, Integer.valueOf(150));
} }
public void updateContents(final boolean remove) { public void updateContents(final boolean remove) {

View File

@ -91,7 +91,7 @@ public class AquaInternalFramePaneUI extends BasicDesktopPaneUI implements Mouse
JComponent getDock() { JComponent getDock() {
if (fDock == null) { if (fDock == null) {
fDock = new Dock(desktop); fDock = new Dock(desktop);
desktop.add(fDock, new Integer(399)); // Just below the DRAG_LAYER desktop.add(fDock, Integer.valueOf(399)); // Just below the DRAG_LAYER
} }
return fDock; return fDock;
} }

View File

@ -416,7 +416,7 @@ public class AquaLookAndFeel extends BasicLookAndFeel {
"Button.select", selected, "Button.select", selected,
"Button.border",(LazyValue) t -> AquaButtonBorder.getDynamicButtonBorder(), "Button.border",(LazyValue) t -> AquaButtonBorder.getDynamicButtonBorder(),
"Button.font", controlFont, "Button.font", controlFont,
"Button.textIconGap", new Integer(4), "Button.textIconGap", Integer.valueOf(4),
"Button.textShiftOffset", zero, // radar 3308129 - aqua doesn't move images when pressed. "Button.textShiftOffset", zero, // radar 3308129 - aqua doesn't move images when pressed.
"Button.focusInputMap", controlFocusInputMap, "Button.focusInputMap", controlFocusInputMap,
"Button.margin", new InsetsUIResource(0, 2, 0, 2), "Button.margin", new InsetsUIResource(0, 2, 0, 2),
@ -635,8 +635,8 @@ public class AquaLookAndFeel extends BasicLookAndFeel {
//"Menu.checkIcon", emptyCheckIcon, // A non-drawing GlyphIcon to make the spacing consistent //"Menu.checkIcon", emptyCheckIcon, // A non-drawing GlyphIcon to make the spacing consistent
"Menu.arrowIcon",(LazyValue) t -> AquaImageFactory.getMenuArrowIcon(), "Menu.arrowIcon",(LazyValue) t -> AquaImageFactory.getMenuArrowIcon(),
"Menu.consumesTabs", Boolean.TRUE, "Menu.consumesTabs", Boolean.TRUE,
"Menu.menuPopupOffsetY", new Integer(1), "Menu.menuPopupOffsetY", Integer.valueOf(1),
"Menu.submenuPopupOffsetY", new Integer(-4), "Menu.submenuPopupOffsetY", Integer.valueOf(-4),
"MenuBar.font", menuFont, "MenuBar.font", menuFont,
"MenuBar.background", menuBackgroundColor, // not a menu item, not selected "MenuBar.background", menuBackgroundColor, // not a menu item, not selected
@ -694,7 +694,7 @@ public class AquaLookAndFeel extends BasicLookAndFeel {
"OptionPane.informationSound", null, // Info and Plain "OptionPane.informationSound", null, // Info and Plain
"OptionPane.questionSound", null, "OptionPane.questionSound", null,
"OptionPane.warningSound", null, "OptionPane.warningSound", null,
"OptionPane.buttonClickThreshhold", new Integer(500), "OptionPane.buttonClickThreshhold", Integer.valueOf(500),
"OptionPane.yesButtonMnemonic", "", "OptionPane.yesButtonMnemonic", "",
"OptionPane.noButtonMnemonic", "", "OptionPane.noButtonMnemonic", "",
"OptionPane.okButtonMnemonic", "", "OptionPane.okButtonMnemonic", "",
@ -717,7 +717,7 @@ public class AquaLookAndFeel extends BasicLookAndFeel {
"PasswordField.caretBlinkRate", textCaretBlinkRate, "PasswordField.caretBlinkRate", textCaretBlinkRate,
"PasswordField.border", textFieldBorder, "PasswordField.border", textFieldBorder,
"PasswordField.margin", zeroInsets, "PasswordField.margin", zeroInsets,
"PasswordField.echoChar", new Character((char)0x25CF), "PasswordField.echoChar", Character.valueOf((char)0x25CF),
"PasswordField.capsLockIconColor", textPasswordFieldCapsLockIconColor, "PasswordField.capsLockIconColor", textPasswordFieldCapsLockIconColor,
"PopupMenu.font", menuFont, "PopupMenu.font", menuFont,
@ -736,7 +736,7 @@ public class AquaLookAndFeel extends BasicLookAndFeel {
"ProgressBar.selectionForeground", black, "ProgressBar.selectionForeground", black,
"ProgressBar.selectionBackground", white, "ProgressBar.selectionBackground", white,
"ProgressBar.border", new BorderUIResource(BorderFactory.createEmptyBorder()), "ProgressBar.border", new BorderUIResource(BorderFactory.createEmptyBorder()),
"ProgressBar.repaintInterval", new Integer(20), "ProgressBar.repaintInterval", Integer.valueOf(20),
"RadioButton.background", controlBackgroundColor, "RadioButton.background", controlBackgroundColor,
"RadioButton.foreground", black, "RadioButton.foreground", black,
@ -772,7 +772,7 @@ public class AquaLookAndFeel extends BasicLookAndFeel {
"ScrollBar.border", null, "ScrollBar.border", null,
"ScrollBar.focusInputMap", aquaKeyBindings.getScrollBarInputMap(), "ScrollBar.focusInputMap", aquaKeyBindings.getScrollBarInputMap(),
"ScrollBar.focusInputMap.RightToLeft", aquaKeyBindings.getScrollBarRightToLeftInputMap(), "ScrollBar.focusInputMap.RightToLeft", aquaKeyBindings.getScrollBarRightToLeftInputMap(),
"ScrollBar.width", new Integer(16), "ScrollBar.width", Integer.valueOf(16),
"ScrollBar.background", white, "ScrollBar.background", white,
"ScrollBar.foreground", black, "ScrollBar.foreground", black,
@ -816,7 +816,7 @@ public class AquaLookAndFeel extends BasicLookAndFeel {
//"SplitPane.shadow", table.get("controlShadow"), //"SplitPane.shadow", table.get("controlShadow"),
"SplitPane.background", panelBackgroundColor, "SplitPane.background", panelBackgroundColor,
"SplitPane.border", scollListBorder, "SplitPane.border", scollListBorder,
"SplitPane.dividerSize", new Integer(9), //$ "SplitPane.dividerSize", Integer.valueOf(9), //$
"SplitPaneDivider.border", null, // AquaSplitPaneDividerUI draws it "SplitPaneDivider.border", null, // AquaSplitPaneDividerUI draws it
"SplitPaneDivider.horizontalGradientVariant",(LazyValue) t -> AquaSplitPaneDividerUI.getHorizontalSplitDividerGradientVariant(), "SplitPaneDivider.horizontalGradientVariant",(LazyValue) t -> AquaSplitPaneDividerUI.getHorizontalSplitDividerGradientVariant(),
@ -833,7 +833,7 @@ public class AquaLookAndFeel extends BasicLookAndFeel {
//"TabbedPane.darkShadow", table.get("controlDkShadow"), //"TabbedPane.darkShadow", table.get("controlDkShadow"),
//"TabbedPane.focus", table.get("controlText"), //"TabbedPane.focus", table.get("controlText"),
"TabbedPane.opaque", useOpaqueComponents, "TabbedPane.opaque", useOpaqueComponents,
"TabbedPane.textIconGap", new Integer(4), "TabbedPane.textIconGap", Integer.valueOf(4),
"TabbedPane.tabInsets", new InsetsUIResource(0, 10, 3, 10), // Label within tab (top, left, bottom, right) "TabbedPane.tabInsets", new InsetsUIResource(0, 10, 3, 10), // Label within tab (top, left, bottom, right)
//"TabbedPane.rightTabInsets", new InsetsUIResource(0, 10, 3, 10), // Label within tab (top, left, bottom, right) //"TabbedPane.rightTabInsets", new InsetsUIResource(0, 10, 3, 10), // Label within tab (top, left, bottom, right)
"TabbedPane.leftTabInsets", new InsetsUIResource(0, 10, 3, 10), // Label within tab "TabbedPane.leftTabInsets", new InsetsUIResource(0, 10, 3, 10), // Label within tab
@ -973,9 +973,9 @@ public class AquaLookAndFeel extends BasicLookAndFeel {
"Tree.selectionBorderColor", selectionBackground, // match the background so it looks like we don't draw anything "Tree.selectionBorderColor", selectionBackground, // match the background so it looks like we don't draw anything
"Tree.editorBorderSelectionColor", null, // The EditTextFrame provides its own border "Tree.editorBorderSelectionColor", null, // The EditTextFrame provides its own border
// "Tree.editorBorder", textFieldBorder, // If you still have Sun bug 4376328 in DefaultTreeCellEditor, it has to have the same insets as TextField.border // "Tree.editorBorder", textFieldBorder, // If you still have Sun bug 4376328 in DefaultTreeCellEditor, it has to have the same insets as TextField.border
"Tree.leftChildIndent", new Integer(7),//$ "Tree.leftChildIndent", Integer.valueOf(7),//$
"Tree.rightChildIndent", new Integer(13),//$ "Tree.rightChildIndent", Integer.valueOf(13),//$
"Tree.rowHeight", new Integer(19),// iconHeight + 3, to match finder - a zero would have the renderer decide, except that leaves the icons touching "Tree.rowHeight", Integer.valueOf(19),// iconHeight + 3, to match finder - a zero would have the renderer decide, except that leaves the icons touching
"Tree.scrollsOnExpand", Boolean.FALSE, "Tree.scrollsOnExpand", Boolean.FALSE,
"Tree.openIcon",(LazyValue) t -> AquaImageFactory.getTreeOpenFolderIcon(), // Open folder icon "Tree.openIcon",(LazyValue) t -> AquaImageFactory.getTreeOpenFolderIcon(), // Open folder icon
"Tree.closedIcon",(LazyValue) t -> AquaImageFactory.getTreeFolderIcon(), // Closed folder icon "Tree.closedIcon",(LazyValue) t -> AquaImageFactory.getTreeFolderIcon(), // Closed folder icon

View File

@ -521,7 +521,7 @@ public class AquaTabbedPaneCopyFromBasicUI extends TabbedPaneUI implements Swing
} }
// [2165820] Mac OS X change: mnemonics need to be triggered with ctrl-option, not just option. // [2165820] Mac OS X change: mnemonics need to be triggered with ctrl-option, not just option.
mnemonicInputMap.put(KeyStroke.getKeyStroke(mnemonic, Event.ALT_MASK | Event.CTRL_MASK), "setSelectedIndex"); mnemonicInputMap.put(KeyStroke.getKeyStroke(mnemonic, Event.ALT_MASK | Event.CTRL_MASK), "setSelectedIndex");
mnemonicToIndexMap.put(new Integer(mnemonic), new Integer(index)); mnemonicToIndexMap.put(Integer.valueOf(mnemonic), Integer.valueOf(index));
} }
/** /**
@ -2084,7 +2084,7 @@ public class AquaTabbedPaneCopyFromBasicUI extends TabbedPaneUI implements Swing
if (mnemonic >= 'a' && mnemonic <= 'z') { if (mnemonic >= 'a' && mnemonic <= 'z') {
mnemonic -= ('a' - 'A'); mnemonic -= ('a' - 'A');
} }
final Integer index = ui.mnemonicToIndexMap.get(new Integer(mnemonic)); final Integer index = ui.mnemonicToIndexMap.get(Integer.valueOf(mnemonic));
if (index != null && pane.isEnabledAt(index.intValue())) { if (index != null && pane.isEnabledAt(index.intValue())) {
pane.setSelectedIndex(index.intValue()); pane.setSelectedIndex(index.intValue());
} }

View File

@ -268,7 +268,7 @@ public class AquaUtilControlSize {
public SizeVariant alterFontSize(final float newSize) { public SizeVariant alterFontSize(final float newSize) {
final float oldSize = fontSize == null ? 0.0f : fontSize.floatValue(); final float oldSize = fontSize == null ? 0.0f : fontSize.floatValue();
fontSize = new Float(newSize + oldSize); fontSize = newSize + oldSize;
return this; return this;
} }

View File

@ -32,8 +32,8 @@ import sun.lwawt.macosx.CPlatformWindow;
import sun.swing.SwingAccessor; import sun.swing.SwingAccessor;
class ScreenPopupFactory extends PopupFactory { class ScreenPopupFactory extends PopupFactory {
static final Float TRANSLUCENT = new Float(248f/255f); static final Float TRANSLUCENT = 248f/255f;
static final Float OPAQUE = new Float(1.0f); static final Float OPAQUE = 1.0f;
boolean fIsActive = true; boolean fIsActive = true;

View File

@ -386,7 +386,7 @@ public final class CStrike extends PhysicalStrike {
if (generalCache == null) { if (generalCache == null) {
return 0L; return 0L;
} }
final Long value = generalCache.get(new Integer(index)); final Long value = generalCache.get(Integer.valueOf(index));
if (value == null) { if (value == null) {
return 0L; return 0L;
} }
@ -415,7 +415,7 @@ public final class CStrike extends PhysicalStrike {
generalCache = new HashMap<Integer, Long>(); generalCache = new HashMap<Integer, Long>();
} }
generalCache.put(new Integer(index), Long.valueOf(value)); generalCache.put(Integer.valueOf(index), Long.valueOf(value));
} }
public synchronized void dispose() { public synchronized void dispose() {
@ -526,7 +526,7 @@ public final class CStrike extends PhysicalStrike {
} }
if (generalCache == null) return 0; if (generalCache == null) return 0;
final Float value = generalCache.get(new Integer(index)); final Float value = generalCache.get(Integer.valueOf(index));
if (value == null) return 0; if (value == null) return 0;
return value.floatValue(); return value.floatValue();
} }
@ -553,7 +553,7 @@ public final class CStrike extends PhysicalStrike {
generalCache = new HashMap<Integer, Float>(); generalCache = new HashMap<Integer, Float>();
} }
generalCache.put(new Integer(index), new Float(value)); generalCache.put(Integer.valueOf(index), Float.valueOf(value));
} }
private static class SparseBitShiftingTwoLayerArray { private static class SparseBitShiftingTwoLayerArray {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -903,7 +903,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
@Override @Override
public boolean requestFocus(Component lightweightChild, boolean temporary, public boolean requestFocus(Component lightweightChild, boolean temporary,
boolean focusedWindowChangeAllowed, long time, boolean focusedWindowChangeAllowed, long time,
CausedFocusEvent.Cause cause) FocusEvent.Cause cause)
{ {
if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) { if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
focusLog.finest("lightweightChild=" + lightweightChild + ", temporary=" + temporary + focusLog.finest("lightweightChild=" + lightweightChild + ", temporary=" + temporary +
@ -1278,7 +1278,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
assert (e.getSource() == target); assert (e.getSource() == target);
if (!target.isFocusOwner() && LWKeyboardFocusManagerPeer.shouldFocusOnClick(target)) { if (!target.isFocusOwner() && LWKeyboardFocusManagerPeer.shouldFocusOnClick(target)) {
LWKeyboardFocusManagerPeer.requestFocusFor(target, CausedFocusEvent.Cause.MOUSE_EVENT); LWKeyboardFocusManagerPeer.requestFocusFor(target, FocusEvent.Cause.MOUSE_EVENT);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -31,8 +31,8 @@ import java.awt.Point;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.Window; import java.awt.Window;
import java.awt.dnd.DropTarget; import java.awt.dnd.DropTarget;
import java.awt.event.FocusEvent;
import sun.awt.CausedFocusEvent;
import sun.awt.LightweightFrame; import sun.awt.LightweightFrame;
import sun.swing.JLightweightFrame; import sun.swing.JLightweightFrame;
import sun.swing.SwingAccessor; import sun.swing.SwingAccessor;
@ -60,7 +60,7 @@ public class LWLightweightFramePeer extends LWWindowPeer {
} }
@Override @Override
public boolean requestWindowFocus(CausedFocusEvent.Cause cause) { public boolean requestWindowFocus(FocusEvent.Cause cause) {
if (!focusAllowedFor()) { if (!focusAllowedFor()) {
return false; return false;
} }

View File

@ -404,6 +404,10 @@ public abstract class LWToolkit extends SunToolkit implements Runnable {
public final PrintJob getPrintJob(Frame frame, String doctitle, public final PrintJob getPrintJob(Frame frame, String doctitle,
JobAttributes jobAttributes, JobAttributes jobAttributes,
PageAttributes pageAttributes) { PageAttributes pageAttributes) {
if (frame == null) {
throw new NullPointerException("frame must not be null");
}
if (GraphicsEnvironment.isHeadless()) { if (GraphicsEnvironment.isHeadless()) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -256,14 +256,14 @@ public class LWWindowPeer
if (!getTarget().isAutoRequestFocus()) { if (!getTarget().isAutoRequestFocus()) {
return; return;
} else { } else {
requestWindowFocus(CausedFocusEvent.Cause.ACTIVATION); requestWindowFocus(FocusEvent.Cause.ACTIVATION);
} }
// Focus the owner in case this window is focused. // Focus the owner in case this window is focused.
} else if (kfmPeer.getCurrentFocusedWindow() == getTarget()) { } else if (kfmPeer.getCurrentFocusedWindow() == getTarget()) {
// Transfer focus to the owner. // Transfer focus to the owner.
LWWindowPeer owner = getOwnerFrameDialog(LWWindowPeer.this); LWWindowPeer owner = getOwnerFrameDialog(LWWindowPeer.this);
if (owner != null) { if (owner != null) {
owner.requestWindowFocus(CausedFocusEvent.Cause.ACTIVATION); owner.requestWindowFocus(FocusEvent.Cause.ACTIVATION);
} }
} }
} }
@ -295,7 +295,7 @@ public class LWWindowPeer
if (f == null) { if (f == null) {
f = DEFAULT_FONT; f = DEFAULT_FONT;
} }
return platformWindow.transformGraphics(new SunGraphics2D(getSurfaceData(), fg, bg, f)); return new SunGraphics2D(getSurfaceData(), fg, bg, f);
} }
@Override @Override
@ -848,7 +848,7 @@ public class LWWindowPeer
// 2. An active but not focused owner frame/dialog is clicked. // 2. An active but not focused owner frame/dialog is clicked.
// The mouse event then will trigger a focus request "in window" to the component, so the window // The mouse event then will trigger a focus request "in window" to the component, so the window
// should gain focus before. // should gain focus before.
requestWindowFocus(CausedFocusEvent.Cause.MOUSE_EVENT); requestWindowFocus(FocusEvent.Cause.MOUSE_EVENT);
mouseDownTarget[targetIdx] = targetPeer; mouseDownTarget[targetIdx] = targetPeer;
} else if (id == MouseEvent.MOUSE_DRAGGED) { } else if (id == MouseEvent.MOUSE_DRAGGED) {
@ -1199,7 +1199,7 @@ public class LWWindowPeer
* Requests platform to set native focus on a frame/dialog. * Requests platform to set native focus on a frame/dialog.
* In case of a simple window, triggers appropriate java focus change. * In case of a simple window, triggers appropriate java focus change.
*/ */
public boolean requestWindowFocus(CausedFocusEvent.Cause cause) { public boolean requestWindowFocus(FocusEvent.Cause cause) {
if (focusLog.isLoggable(PlatformLogger.Level.FINE)) { if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
focusLog.fine("requesting native focus to " + this); focusLog.fine("requesting native focus to " + this);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,8 +26,8 @@
package sun.lwawt; package sun.lwawt;
import java.awt.*; import java.awt.*;
import java.awt.event.FocusEvent;
import sun.awt.CausedFocusEvent;
import sun.java2d.SurfaceData; import sun.java2d.SurfaceData;
// TODO Is it worth to generify this interface, like that: // TODO Is it worth to generify this interface, like that:
@ -114,7 +114,7 @@ public interface PlatformWindow {
public void updateFocusableWindowState(); public void updateFocusableWindowState();
public boolean rejectFocusRequest(CausedFocusEvent.Cause cause); public boolean rejectFocusRequest(FocusEvent.Cause cause);
public boolean requestWindowFocus(); public boolean requestWindowFocus();
@ -130,12 +130,6 @@ public interface PlatformWindow {
*/ */
public void setSizeConstraints(int minW, int minH, int maxW, int maxH); public void setSizeConstraints(int minW, int minH, int maxW, int maxH);
/**
* Transforms the given Graphics object according to the native
* implementation traits (insets, etc.).
*/
public Graphics transformGraphics(Graphics g);
/* /*
* Installs the images for particular window. * Installs the images for particular window.
*/ */

View File

@ -0,0 +1,253 @@
/*
* Copyright (c) 2002, 2016, 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 sun.lwawt.macosx;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
import javax.swing.event.EventListenerList;
/**
* <P>{@code AccessibilityEventMonitor} implements a PropertyChange listener
* on every UI object that implements interface {@code Accessible} in the Java
* Virtual Machine. The events captured by these listeners are made available
* through listeners supported by {@code AccessibilityEventMonitor}.
* With this, all the individual events on each of the UI object
* instances are funneled into one set of PropertyChange listeners.
*
* This code is a subset of com.sun.java.accessibility.util.AccessibilityEventMonitor
* which resides in module jdk.accessibility. Due to modularization the code in
* this package, java.desktop, can not be dependent on code in jdk.accessibility.
*/
class AccessibilityEventMonitor {
/**
* The current list of registered {@link java.beans.PropertyChangeListener
* PropertyChangeListener} classes.
*
* @see #addPropertyChangeListener
*/
private static final EventListenerList listenerList =
new EventListenerList();
/**
* The actual listener that is installed on the component instances.
* This listener calls the other registered listeners when an event
* occurs. By doing things this way, the actual number of listeners
* installed on a component instance is drastically reduced.
*/
private static final AccessibilityEventListener accessibilityListener =
new AccessibilityEventListener();
/**
* Adds the specified listener to receive all PropertyChange events on
* each UI object instance in the Java Virtual Machine as they occur.
* <P>Note: This listener is automatically added to all component
* instances created after this method is called. In addition, it
* is only added to UI object instances that support this listener type.
*
* @param l the listener to add
* @param a the Accessible object to add the PropertyChangeListener to
*/
static void addPropertyChangeListener(PropertyChangeListener l, Accessible a) {
if (listenerList.getListenerCount(PropertyChangeListener.class) == 0) {
accessibilityListener.installListeners(a);
}
listenerList.add(PropertyChangeListener.class, l);
}
/**
* AccessibilityEventListener is the class that does all the work for
* AccessibilityEventMonitor. It is not intended for use by any other
* class except AccessibilityEventMonitor.
*/
private static class AccessibilityEventListener implements PropertyChangeListener {
/**
* Installs PropertyChange listeners to the Accessible object, and its
* children (so long as the object isn't of TRANSIENT state).
*
* @param a the Accessible object to add listeners to
*/
private void installListeners(Accessible a) {
installListeners(a.getAccessibleContext());
}
/**
* Installs PropertyChange listeners to the AccessibleContext object,
* and its * children (so long as the object isn't of TRANSIENT state).
*
* @param ac the AccessibleContext to add listeners to
*/
private void installListeners(AccessibleContext ac) {
if (ac != null) {
AccessibleStateSet states = ac.getAccessibleStateSet();
if (!states.contains(AccessibleState.TRANSIENT)) {
ac.addPropertyChangeListener(this);
/*
* Don't add listeners to transient children. Components
* with transient children should return an AccessibleStateSet
* containing AccessibleState.MANAGES_DESCENDANTS. Components
* may not explicitly return the MANAGES_DESCENDANTS state.
* In this case, don't add listeners to the children of
* lists, tables and trees.
*/
AccessibleStateSet set = ac.getAccessibleStateSet();
if (set.contains(AccessibleState.MANAGES_DESCENDANTS)) {
return;
}
AccessibleRole role = ac.getAccessibleRole();
if ( role == AccessibleRole.LIST ||
role == AccessibleRole.TREE ) {
return;
}
if (role == AccessibleRole.TABLE) {
// handle Oracle tables containing tables
Accessible child = ac.getAccessibleChild(0);
if (child != null) {
AccessibleContext ac2 = child.getAccessibleContext();
if (ac2 != null) {
role = ac2.getAccessibleRole();
if (role != null && role != AccessibleRole.TABLE) {
return;
}
}
}
}
int count = ac.getAccessibleChildrenCount();
for (int i = 0; i < count; i++) {
Accessible child = ac.getAccessibleChild(i);
if (child != null) {
installListeners(child);
}
}
}
}
}
/**
* Removes PropertyChange listeners for the given Accessible object,
* its children (so long as the object isn't of TRANSIENT state).
*
* @param a the Accessible object to remove listeners from
*/
private void removeListeners(Accessible a) {
removeListeners(a.getAccessibleContext());
}
/**
* Removes PropertyChange listeners for the given AccessibleContext
* object, its children (so long as the object isn't of TRANSIENT
* state).
*
* @param a the Accessible object to remove listeners from
*/
private void removeListeners(AccessibleContext ac) {
if (ac != null) {
// Listeners are not added to transient components.
AccessibleStateSet states = ac.getAccessibleStateSet();
if (!states.contains(AccessibleState.TRANSIENT)) {
ac.removePropertyChangeListener(this);
/*
* Listeners are not added to transient children. Components
* with transient children should return an AccessibleStateSet
* containing AccessibleState.MANAGES_DESCENDANTS. Components
* may not explicitly return the MANAGES_DESCENDANTS state.
* In this case, don't remove listeners from the children of
* lists, tables and trees.
*/
if (states.contains(AccessibleState.MANAGES_DESCENDANTS)) {
return;
}
AccessibleRole role = ac.getAccessibleRole();
if ( role == AccessibleRole.LIST ||
role == AccessibleRole.TABLE ||
role == AccessibleRole.TREE ) {
return;
}
int count = ac.getAccessibleChildrenCount();
for (int i = 0; i < count; i++) {
Accessible child = ac.getAccessibleChild(i);
if (child != null) {
removeListeners(child);
}
}
}
}
}
@Override
public void propertyChange(PropertyChangeEvent e) {
// propogate the event
Object[] listeners =
AccessibilityEventMonitor.listenerList.getListenerList();
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==PropertyChangeListener.class) {
((PropertyChangeListener)listeners[i+1]).propertyChange(e);
}
}
// handle childbirth/death
String name = e.getPropertyName();
if (name.compareTo(AccessibleContext.ACCESSIBLE_CHILD_PROPERTY) == 0) {
Object oldValue = e.getOldValue();
Object newValue = e.getNewValue();
if ((oldValue == null) ^ (newValue == null)) { // one null, not both
if (oldValue != null) {
// this Accessible is a child that's going away
if (oldValue instanceof Accessible) {
Accessible a = (Accessible) oldValue;
removeListeners(a.getAccessibleContext());
} else if (oldValue instanceof AccessibleContext) {
removeListeners((AccessibleContext) oldValue);
}
} else if (newValue != null) {
// this Accessible is a child was just born
if (newValue instanceof Accessible) {
Accessible a = (Accessible) newValue;
installListeners(a.getAccessibleContext());
} else if (newValue instanceof AccessibleContext) {
installListeners((AccessibleContext) newValue);
}
}
} else {
System.out.println("ERROR in usage of PropertyChangeEvents for: " + e.toString());
}
}
}
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,20 +26,18 @@
package sun.lwawt.macosx; package sun.lwawt.macosx;
import java.awt.Component; import java.awt.Component;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import javax.accessibility.Accessible; import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext; import javax.accessibility.AccessibleContext;
import javax.swing.JProgressBar; import javax.swing.JProgressBar;
import javax.swing.JSlider; import javax.swing.JSlider;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener; import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.JTextComponent;
import sun.lwawt.macosx.CFRetainedResource;
class CAccessible extends CFRetainedResource implements Accessible { class CAccessible extends CFRetainedResource implements Accessible {
static Field getNativeAXResourceField() { static Field getNativeAXResourceField() {
@ -99,13 +97,10 @@ class CAccessible extends CFRetainedResource implements Accessible {
return accessible.getAccessibleContext(); return accessible.getAccessibleContext();
} }
// currently only supports text components
public void addNotificationListeners(Component c) { public void addNotificationListeners(Component c) {
if (c instanceof JTextComponent) {
JTextComponent tc = (JTextComponent) c;
AXTextChangeNotifier listener = new AXTextChangeNotifier(); AXTextChangeNotifier listener = new AXTextChangeNotifier();
tc.getDocument().addDocumentListener(listener); if (c instanceof Accessible) {
tc.addCaretListener(listener); AccessibilityEventMonitor.addPropertyChangeListener(listener, (Accessible)c);
} }
if (c instanceof JProgressBar) { if (c instanceof JProgressBar) {
JProgressBar pb = (JProgressBar) c; JProgressBar pb = (JProgressBar) c;
@ -117,29 +112,23 @@ class CAccessible extends CFRetainedResource implements Accessible {
} }
private class AXTextChangeNotifier implements DocumentListener, CaretListener { private class AXTextChangeNotifier implements PropertyChangeListener {
@Override
public void changedUpdate(DocumentEvent e) {
if (ptr != 0) valueChanged(ptr);
}
@Override @Override
public void insertUpdate(DocumentEvent e) { public void propertyChange(PropertyChangeEvent e) {
if (ptr != 0) valueChanged(ptr); String name = e.getPropertyName();
if ( ptr != 0 ) {
if (name.compareTo(AccessibleContext.ACCESSIBLE_CARET_PROPERTY) == 0) {
selectionChanged(ptr);
} else if (name.compareTo(AccessibleContext.ACCESSIBLE_TEXT_PROPERTY) == 0 ) {
valueChanged(ptr);
} }
@Override
public void removeUpdate(DocumentEvent e) {
if (ptr != 0) valueChanged(ptr);
} }
@Override
public void caretUpdate(CaretEvent e) {
if (ptr != 0) selectionChanged(ptr);
} }
} }
private class AXProgressChangeNotifier implements ChangeListener { private class AXProgressChangeNotifier implements ChangeListener {
@Override
public void stateChanged(ChangeEvent e) { public void stateChanged(ChangeEvent e) {
if (ptr != 0) valueChanged(ptr); if (ptr != 0) valueChanged(ptr);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,6 +26,7 @@
package sun.lwawt.macosx; package sun.lwawt.macosx;
import java.awt.*; import java.awt.*;
import java.awt.event.FocusEvent.Cause;
import java.awt.peer.*; import java.awt.peer.*;
import java.awt.BufferCapabilities.FlipContents; import java.awt.BufferCapabilities.FlipContents;
import java.awt.event.*; import java.awt.event.*;
@ -34,7 +35,6 @@ import java.security.AccessController;
import java.util.List; import java.util.List;
import java.io.*; import java.io.*;
import sun.awt.CausedFocusEvent.Cause;
import sun.awt.AWTAccessor; import sun.awt.AWTAccessor;
import sun.java2d.pipe.Region; import sun.java2d.pipe.Region;
import sun.security.action.GetBooleanAction; import sun.security.action.GetBooleanAction;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,11 +26,11 @@
package sun.lwawt.macosx; package sun.lwawt.macosx;
import java.awt.*; import java.awt.*;
import sun.awt.CausedFocusEvent; import java.awt.event.FocusEvent;
import sun.java2d.SurfaceData; import sun.java2d.SurfaceData;
import sun.java2d.opengl.CGLLayer; import sun.java2d.opengl.CGLLayer;
import sun.lwawt.LWWindowPeer; import sun.lwawt.LWWindowPeer;
import sun.lwawt.LWWindowPeer.PeerType;
import sun.lwawt.PlatformWindow; import sun.lwawt.PlatformWindow;
import sun.util.logging.PlatformLogger; import sun.util.logging.PlatformLogger;
@ -39,7 +39,8 @@ import sun.util.logging.PlatformLogger;
*/ */
public class CPlatformEmbeddedFrame implements PlatformWindow { public class CPlatformEmbeddedFrame implements PlatformWindow {
private static final PlatformLogger focusLogger = PlatformLogger.getLogger("sun.lwawt.macosx.focus.CPlatformEmbeddedFrame"); private static final PlatformLogger focusLogger = PlatformLogger.getLogger(
"sun.lwawt.macosx.focus.CPlatformEmbeddedFrame");
private CGLLayer windowLayer; private CGLLayer windowLayer;
private LWWindowPeer peer; private LWWindowPeer peer;
@ -133,9 +134,9 @@ public class CPlatformEmbeddedFrame implements PlatformWindow {
public void updateFocusableWindowState() {} public void updateFocusableWindowState() {}
@Override @Override
public boolean rejectFocusRequest(CausedFocusEvent.Cause cause) { public boolean rejectFocusRequest(FocusEvent.Cause cause) {
// Cross-app activation requests are not allowed. // Cross-app activation requests are not allowed.
if (cause != CausedFocusEvent.Cause.MOUSE_EVENT && if (cause != FocusEvent.Cause.MOUSE_EVENT &&
!target.isParentWindowActive()) !target.isParentWindowActive())
{ {
focusLogger.fine("the embedder is inactive, so the request is rejected"); focusLogger.fine("the embedder is inactive, so the request is rejected");
@ -160,11 +161,6 @@ public class CPlatformEmbeddedFrame implements PlatformWindow {
@Override @Override
public void setSizeConstraints(int minW, int minH, int maxW, int maxH) {} public void setSizeConstraints(int minW, int minH, int maxW, int maxH) {}
@Override
public Graphics transformGraphics(Graphics g) {
return g;
}
@Override @Override
public void updateIconImages() {} public void updateIconImages() {}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,7 +27,6 @@ package sun.lwawt.macosx;
import java.awt.Font; import java.awt.Font;
import java.awt.FontMetrics; import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.GraphicsDevice; import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment; import java.awt.GraphicsEnvironment;
import java.awt.Insets; import java.awt.Insets;
@ -37,7 +36,7 @@ import java.awt.Rectangle;
import java.awt.Window; import java.awt.Window;
import sun.awt.CGraphicsDevice; import sun.awt.CGraphicsDevice;
import sun.awt.CGraphicsEnvironment; import sun.awt.CGraphicsEnvironment;
import sun.awt.CausedFocusEvent; import java.awt.event.FocusEvent;
import sun.awt.LightweightFrame; import sun.awt.LightweightFrame;
import sun.java2d.SurfaceData; import sun.java2d.SurfaceData;
import sun.lwawt.LWLightweightFramePeer; import sun.lwawt.LWLightweightFramePeer;
@ -134,7 +133,7 @@ public class CPlatformLWWindow extends CPlatformWindow {
} }
@Override @Override
public boolean rejectFocusRequest(CausedFocusEvent.Cause cause) { public boolean rejectFocusRequest(FocusEvent.Cause cause) {
return false; return false;
} }
@ -152,11 +151,6 @@ public class CPlatformLWWindow extends CPlatformWindow {
public void updateFocusableWindowState() { public void updateFocusableWindowState() {
} }
@Override
public Graphics transformGraphics(Graphics g) {
return null;
}
@Override @Override
public void setAlwaysOnTop(boolean isAlwaysOnTop) { public void setAlwaysOnTop(boolean isAlwaysOnTop) {
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -706,9 +706,9 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
} }
@Override @Override
public boolean rejectFocusRequest(CausedFocusEvent.Cause cause) { public boolean rejectFocusRequest(FocusEvent.Cause cause) {
// Cross-app activation requests are not allowed. // Cross-app activation requests are not allowed.
if (cause != CausedFocusEvent.Cause.MOUSE_EVENT && if (cause != FocusEvent.Cause.MOUSE_EVENT &&
!((LWCToolkit)Toolkit.getDefaultToolkit()).isApplicationActive()) !((LWCToolkit)Toolkit.getDefaultToolkit()).isApplicationActive())
{ {
focusLogger.fine("the app is inactive, so the request is rejected"); focusLogger.fine("the app is inactive, so the request is rejected");
@ -740,12 +740,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
setStyleBits(SHOULD_BECOME_KEY | SHOULD_BECOME_MAIN, isFocusable); // set both bits at once setStyleBits(SHOULD_BECOME_KEY | SHOULD_BECOME_MAIN, isFocusable); // set both bits at once
} }
@Override
public Graphics transformGraphics(Graphics g) {
// is this where we can inject a transform for HiDPI?
return g;
}
@Override @Override
public void setAlwaysOnTop(boolean isAlwaysOnTop) { public void setAlwaysOnTop(boolean isAlwaysOnTop) {
setStyleBits(ALWAYS_ON_TOP, isAlwaysOnTop); setStyleBits(ALWAYS_ON_TOP, isAlwaysOnTop);

View File

@ -99,14 +99,25 @@ public class CTrayIcon extends CFRetainedResource implements TrayIconPeer {
//invocation from the AWTTrayIcon.m //invocation from the AWTTrayIcon.m
public long getPopupMenuModel() { public long getPopupMenuModel() {
PopupMenu newPopup = target.getPopupMenu();
if (popup == newPopup) {
if (popup == null) { if (popup == null) {
PopupMenu popupMenu = target.getPopupMenu(); return 0L;
if (popupMenu != null) { }
popup = popupMenu; } else {
if (newPopup != null) {
if (popup != null) {
popup.removeNotify();
popup = newPopup;
} else {
popup = newPopup;
}
} else { } else {
return 0L; return 0L;
} }
} }
return checkAndCreatePopupPeer().getModel(); return checkAndCreatePopupPeer().getModel();
} }

View File

@ -87,23 +87,22 @@ public class CViewEmbeddedFrame extends EmbeddedFrame {
} }
} }
/* /**
* Initializes the embedded frame bounds and validates a component. * Initializes the embedded frame bounds and validates a component.
* Designed to be called from the main thread * Designed to be called from the main thread. This method should be called
* This method should be called once from the initialization of the SWT_AWT Bridge * once from the initialization of the SWT_AWT Bridge.
*/ */
public void validateWithBounds(final int x, final int y, final int width, final int height) { public void validateWithBounds(final int x, final int y, final int width,
final int height) {
try { try {
LWCToolkit.invokeAndWait(() -> {
final LWWindowPeer peer = AWTAccessor.getComponentAccessor() final LWWindowPeer peer = AWTAccessor.getComponentAccessor()
.getPeer(this); .getPeer(this);
LWCToolkit.invokeAndWait(new Runnable() {
@Override
public void run() {
peer.setBoundsPrivate(0, 0, width, height); peer.setBoundsPrivate(0, 0, width, height);
validate(); validate();
setVisible(true); setVisible(true);
}
}, this); }, this);
} catch (InvocationTargetException ex) {} } catch (InvocationTargetException ex) {
}
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,13 +27,12 @@ package sun.lwawt.macosx;
import java.awt.Font; import java.awt.Font;
import java.awt.FontMetrics; import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.GraphicsDevice; import java.awt.GraphicsDevice;
import java.awt.Insets; import java.awt.Insets;
import java.awt.MenuBar; import java.awt.MenuBar;
import java.awt.Point; import java.awt.Point;
import java.awt.Window; import java.awt.Window;
import sun.awt.CausedFocusEvent.Cause; import java.awt.event.FocusEvent.Cause;
import sun.java2d.SurfaceData; import sun.java2d.SurfaceData;
import sun.lwawt.LWWindowPeer; import sun.lwawt.LWWindowPeer;
import sun.lwawt.PlatformWindow; import sun.lwawt.PlatformWindow;
@ -170,11 +169,6 @@ public class CViewPlatformEmbeddedFrame implements PlatformWindow {
public void setSizeConstraints(int minW, int minH, int maxW, int maxH) { public void setSizeConstraints(int minW, int minH, int maxW, int maxH) {
} }
@Override
public Graphics transformGraphics(Graphics g) {
return g;
}
@Override @Override
public void updateIconImages() { public void updateIconImages() {
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -364,8 +364,8 @@ public final class CWarningWindow extends CPlatformWindow
return null; return null;
} }
return transformGraphics(new SunGraphics2D(sd, SystemColor.windowText, return new SunGraphics2D(sd, SystemColor.windowText, SystemColor.window,
SystemColor.window, ownerWindow.getFont())); ownerWindow.getFont());
} }

View File

@ -378,9 +378,9 @@ public final class LWCToolkit extends LWToolkit {
// These DnD properties must be set, otherwise Swing ends up spewing NPEs // These DnD properties must be set, otherwise Swing ends up spewing NPEs
// all over the place. The values came straight off of MToolkit. // all over the place. The values came straight off of MToolkit.
desktopProperties.put("DnD.Autoscroll.initialDelay", new Integer(50)); desktopProperties.put("DnD.Autoscroll.initialDelay", Integer.valueOf(50));
desktopProperties.put("DnD.Autoscroll.interval", new Integer(50)); desktopProperties.put("DnD.Autoscroll.interval", Integer.valueOf(50));
desktopProperties.put("DnD.Autoscroll.cursorHysteresis", new Integer(5)); desktopProperties.put("DnD.Autoscroll.cursorHysteresis", Integer.valueOf(5));
desktopProperties.put("DnD.isDragImageSupported", Boolean.TRUE); desktopProperties.put("DnD.isDragImageSupported", Boolean.TRUE);

View File

@ -42,7 +42,7 @@ import java.util.List;
* &lt;new class="java.lang.Long"&gt; * &lt;new class="java.lang.Long"&gt;
* &lt;string&gt;10&lt;/string&gt; * &lt;string&gt;10&lt;/string&gt;
* &lt;/new&gt;</pre> * &lt;/new&gt;</pre>
* is equivalent to {@code new Long("10")} in Java code. * is equivalent to {@code Long.valueOf("10")} in Java code.
* <p>The following attributes are supported: * <p>The following attributes are supported:
* <dl> * <dl>
* <dt>class * <dt>class

View File

@ -128,7 +128,7 @@ public class BMPMetadata extends IIOMetadata implements BMPConstants {
addChildNode(root, "BMPVersion", bmpVersion); addChildNode(root, "BMPVersion", bmpVersion);
addChildNode(root, "Width", width); addChildNode(root, "Width", width);
addChildNode(root, "Height", height); addChildNode(root, "Height", height);
addChildNode(root, "BitsPerPixel", new Short(bitsPerPixel)); addChildNode(root, "BitsPerPixel", Short.valueOf(bitsPerPixel));
addChildNode(root, "Compression", compression); addChildNode(root, "Compression", compression);
addChildNode(root, "ImageSize", imageSize); addChildNode(root, "ImageSize", imageSize);
@ -172,12 +172,12 @@ public class BMPMetadata extends IIOMetadata implements BMPConstants {
red = palette[j++] & 0xff; red = palette[j++] & 0xff;
green = palette[j++] & 0xff; green = palette[j++] & 0xff;
blue = palette[j++] & 0xff; blue = palette[j++] & 0xff;
addChildNode(entry, "Red", new Byte((byte)red)); addChildNode(entry, "Red", Byte.valueOf((byte)red));
addChildNode(entry, "Green", new Byte((byte)green)); addChildNode(entry, "Green", Byte.valueOf((byte)green));
addChildNode(entry, "Blue", new Byte((byte)blue)); addChildNode(entry, "Blue", Byte.valueOf((byte)blue));
if (numComps == 4) if (numComps == 4)
addChildNode(entry, "Alpha", addChildNode(entry, "Alpha",
new Byte((byte)(palette[j++] & 0xff))); Byte.valueOf((byte)(palette[j++] & 0xff)));
} }
} }
@ -284,9 +284,9 @@ public class BMPMetadata extends IIOMetadata implements BMPConstants {
private void addXYZPoints(IIOMetadataNode root, String name, double x, double y, double z) { private void addXYZPoints(IIOMetadataNode root, String name, double x, double y, double z) {
IIOMetadataNode node = addChildNode(root, name, null); IIOMetadataNode node = addChildNode(root, name, null);
addChildNode(node, "X", new Double(x)); addChildNode(node, "X", Double.valueOf(x));
addChildNode(node, "Y", new Double(y)); addChildNode(node, "Y", Double.valueOf(y));
addChildNode(node, "Z", new Double(z)); addChildNode(node, "Z", Double.valueOf(z));
} }
private IIOMetadataNode addChildNode(IIOMetadataNode root, private IIOMetadataNode addChildNode(IIOMetadataNode root,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -158,8 +158,8 @@ class GTKEngine {
int widgetType, int state, int shadowType, String detail, int widgetType, int state, int shadowType, String detail,
int x, int y, int width, int height, int synthState, int dir); int x, int y, int width, int height, int synthState, int dir);
private native void native_paint_slider( private native void native_paint_slider(
int widgetType, int state, int shadowType, String detail, int widgetType, int state, int shadowType, String detail, int x,
int x, int y, int width, int height, int orientation); int y, int width, int height, int orientation, boolean hasFocus);
private native void native_paint_vline( private native void native_paint_vline(
int widgetType, int state, String detail, int widgetType, int state, String detail,
int x, int y, int width, int height); int x, int y, int width, int height);
@ -491,6 +491,14 @@ class GTKEngine {
int gtkState = int gtkState =
GTKLookAndFeel.synthStateToGTKStateType(state).ordinal(); GTKLookAndFeel.synthStateToGTKStateType(state).ordinal();
int synthState = context.getComponentState(); int synthState = context.getComponentState();
Container parent = context.getComponent().getParent();
if(GTKLookAndFeel.is3()) {
if (parent != null && parent.getParent() instanceof JComboBox) {
if (parent.getParent().hasFocus()) {
synthState |= SynthConstants.FOCUSED;
}
}
}
int dir = getTextDirection(context); int dir = getTextDirection(context);
int widget = getWidgetType(context.getComponent(), id).ordinal(); int widget = getWidgetType(context.getComponent(), id).ordinal();
native_paint_shadow(widget, gtkState, shadowType.ordinal(), detail, native_paint_shadow(widget, gtkState, shadowType.ordinal(), detail,
@ -498,13 +506,13 @@ class GTKEngine {
} }
public void paintSlider(Graphics g, SynthContext context, public void paintSlider(Graphics g, SynthContext context,
Region id, int state, ShadowType shadowType, String detail, Region id, int state, ShadowType shadowType, String detail, int x,
int x, int y, int w, int h, Orientation orientation) { int y, int w, int h, Orientation orientation, boolean hasFocus) {
state = GTKLookAndFeel.synthStateToGTKStateType(state).ordinal(); state = GTKLookAndFeel.synthStateToGTKStateType(state).ordinal();
int widget = getWidgetType(context.getComponent(), id).ordinal(); int widget = getWidgetType(context.getComponent(), id).ordinal();
native_paint_slider(widget, state, shadowType.ordinal(), detail, native_paint_slider(widget, state, shadowType.ordinal(), detail,
x - x0, y - y0, w, h, orientation.ordinal()); x - x0, y - y0, w, h, orientation.ordinal(), hasFocus);
} }
public void paintVline(Graphics g, SynthContext context, public void paintVline(Graphics g, SynthContext context,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -54,7 +54,8 @@ import sun.swing.SwingUtilities2;
*/ */
@SuppressWarnings("serial") // Superclass not serializable @SuppressWarnings("serial") // Superclass not serializable
public class GTKLookAndFeel extends SynthLookAndFeel { public class GTKLookAndFeel extends SynthLookAndFeel {
private static final boolean IS_22; private static boolean IS_22;
private static boolean IS_3;
/** /**
* Whether or not text is drawn antialiased. This keys off the * Whether or not text is drawn antialiased. This keys off the
@ -107,17 +108,6 @@ public class GTKLookAndFeel extends SynthLookAndFeel {
private static String gtkThemeName = "Default"; private static String gtkThemeName = "Default";
static { static {
// Backup for specifying the version, this isn't currently documented.
// If you pass in anything but 2.2 you got the 2.0 colors/look.
String version = AccessController.doPrivileged(
new GetPropertyAction("swing.gtk.version"));
if (version != null) {
IS_22 = version.equals("2.2");
}
else {
IS_22 = true;
}
String language = Locale.getDefault().getLanguage(); String language = Locale.getDefault().getLanguage();
boolean cjkLocale = boolean cjkLocale =
(Locale.CHINESE.getLanguage().equals(language) || (Locale.CHINESE.getLanguage().equals(language) ||
@ -158,6 +148,10 @@ public class GTKLookAndFeel extends SynthLookAndFeel {
return IS_22; return IS_22;
} }
static boolean is3() {
return IS_3;
}
/** /**
* Maps a swing constant to a GTK constant. * Maps a swing constant to a GTK constant.
*/ */
@ -385,7 +379,7 @@ public class GTKLookAndFeel extends SynthLookAndFeel {
} }
Insets zeroInsets = new InsetsUIResource(0, 0, 0, 0); Insets zeroInsets = new InsetsUIResource(0, 0, 0, 0);
Double defaultCaretAspectRatio = new Double(0.025); Double defaultCaretAspectRatio = Double.valueOf(0.025);
Color caretColor = table.getColor("caretColor"); Color caretColor = table.getColor("caretColor");
Color controlText = table.getColor("controlText"); Color controlText = table.getColor("controlText");
@ -1460,6 +1454,19 @@ public class GTKLookAndFeel extends SynthLookAndFeel {
throw new InternalError("Unable to load native GTK libraries"); throw new InternalError("Unable to load native GTK libraries");
} }
if (UNIXToolkit.getGtkVersion() == UNIXToolkit.GtkVersions.GTK2) {
String version = AccessController.doPrivileged(
new GetPropertyAction("jdk.gtk.version"));
if (version != null) {
IS_22 = version.equals("2.2");
} else {
IS_22 = true;
}
} else if (UNIXToolkit.getGtkVersion() ==
UNIXToolkit.GtkVersions.GTK3) {
IS_3 = true;
}
super.initialize(); super.initialize();
inInitialize = true; inInitialize = true;
loadStyles(); loadStyles();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -576,12 +576,11 @@ class GTKPainter extends SynthPainter {
ShadowType.OUT, "menu", x, y, w, h); ShadowType.OUT, "menu", x, y, w, h);
GTKStyle style = (GTKStyle)context.getStyle(); GTKStyle style = (GTKStyle)context.getStyle();
int xThickness = style.getXThickness(); Insets insets = style.getInsets(context, null);
int yThickness = style.getYThickness();
ENGINE.paintBackground(g, context, id, gtkState, ENGINE.paintBackground(g, context, id, gtkState,
style.getGTKColor(context, gtkState, GTKColorType.BACKGROUND), style.getGTKColor(context, gtkState, GTKColorType.BACKGROUND),
x + xThickness, y + yThickness, x + insets.left, y + insets.top, w - insets.left - insets.right,
w - xThickness - xThickness, h - yThickness - yThickness); h - insets.top - insets.bottom);
ENGINE.finishPainting(); ENGINE.finishPainting();
} }
} }
@ -640,6 +639,34 @@ class GTKPainter extends SynthPainter {
int state = context.getComponentState(); int state = context.getComponentState();
JComponent c = context.getComponent(); JComponent c = context.getComponent();
GTKStyle style = (GTKStyle) context.getStyle();
String detail;
// wide-separators are painted using box not line
if (style.getClassSpecificBoolValue(context,
"wide-separators", false)) {
Insets insets = c.getInsets();
x += insets.left;
y += insets.top;
if (orientation == JSeparator.HORIZONTAL) {
w -= (insets.left + insets.right);
detail = "hseparator";
} else {
h -= (insets.top + insets.bottom);
detail = "vseparator";
}
synchronized (UNIXToolkit.GTK_LOCK) {
if (! ENGINE.paintCachedImage(g, x, y, w, h, id, state,
detail, orientation)) {
ENGINE.startPainting(g, x, y, w, h, id, state,
detail, orientation);
ENGINE.paintBox(g, context, id, state,
ShadowType.ETCHED_OUT, detail, x, y, w, h);
ENGINE.finishPainting();
}
}
return;
}
/* /*
* Note: In theory, the style's x/y thickness values would determine * Note: In theory, the style's x/y thickness values would determine
* the width of the separator content. In practice, however, some * the width of the separator content. In practice, however, some
@ -650,7 +677,6 @@ class GTKPainter extends SynthPainter {
* the w/h values below too much, so that the full thickness of the * the w/h values below too much, so that the full thickness of the
* rendered line will be captured by our image caching code. * rendered line will be captured by our image caching code.
*/ */
String detail;
if (c instanceof JToolBar.Separator) { if (c instanceof JToolBar.Separator) {
/* /*
* GTK renders toolbar separators differently in that an * GTK renders toolbar separators differently in that an
@ -678,7 +704,6 @@ class GTKPainter extends SynthPainter {
float pct = 0.2f; float pct = 0.2f;
JToolBar.Separator sep = (JToolBar.Separator)c; JToolBar.Separator sep = (JToolBar.Separator)c;
Dimension size = sep.getSeparatorSize(); Dimension size = sep.getSeparatorSize();
GTKStyle style = (GTKStyle)context.getStyle();
if (orientation == JSeparator.HORIZONTAL) { if (orientation == JSeparator.HORIZONTAL) {
x += (int)(w * pct); x += (int)(w * pct);
w -= (int)(w * pct * 2); w -= (int)(w * pct * 2);
@ -743,6 +768,15 @@ class GTKPainter extends SynthPainter {
// The ubuntulooks engine paints slider troughs differently depending // The ubuntulooks engine paints slider troughs differently depending
// on the current slider value and its component orientation. // on the current slider value and its component orientation.
JSlider slider = (JSlider)context.getComponent(); JSlider slider = (JSlider)context.getComponent();
if (GTKLookAndFeel.is3()) {
if (slider.getOrientation() == JSlider.VERTICAL) {
y += 1;
h -= 2;
} else {
x += 1;
w -= 2;
}
}
double value = slider.getValue(); double value = slider.getValue();
double min = slider.getMinimum(); double min = slider.getMinimum();
double max = slider.getMaximum(); double max = slider.getMaximum();
@ -776,15 +810,19 @@ class GTKPainter extends SynthPainter {
Region id = context.getRegion(); Region id = context.getRegion();
int gtkState = GTKLookAndFeel.synthStateToGTKState( int gtkState = GTKLookAndFeel.synthStateToGTKState(
id, context.getComponentState()); id, context.getComponentState());
boolean hasFocus = GTKLookAndFeel.is3() &&
((context.getComponentState() & SynthConstants.FOCUSED) != 0);
synchronized (UNIXToolkit.GTK_LOCK) { synchronized (UNIXToolkit.GTK_LOCK) {
if (! ENGINE.paintCachedImage(g, x, y, w, h, id, gtkState, dir)) { if (! ENGINE.paintCachedImage(g, x, y, w, h, id, gtkState, dir,
hasFocus)) {
Orientation orientation = (dir == JSlider.HORIZONTAL ? Orientation orientation = (dir == JSlider.HORIZONTAL ?
Orientation.HORIZONTAL : Orientation.VERTICAL); Orientation.HORIZONTAL : Orientation.VERTICAL);
String detail = (dir == JSlider.HORIZONTAL ? String detail = (dir == JSlider.HORIZONTAL ?
"hscale" : "vscale"); "hscale" : "vscale");
ENGINE.startPainting(g, x, y, w, h, id, gtkState, dir); ENGINE.startPainting(g, x, y, w, h, id, gtkState, dir);
ENGINE.paintSlider(g, context, id, gtkState, ENGINE.paintSlider(g, context, id, gtkState,
ShadowType.OUT, detail, x, y, w, h, orientation); ShadowType.OUT, detail, x, y, w, h, orientation,
hasFocus);
ENGINE.finishPainting(); ENGINE.finishPainting();
} }
} }
@ -963,8 +1001,13 @@ class GTKPainter extends SynthPainter {
int yThickness = style.getYThickness(); int yThickness = style.getYThickness();
ENGINE.startPainting(g, x, y, w, h, id, state); ENGINE.startPainting(g, x, y, w, h, id, state);
if (GTKLookAndFeel.is3()) {
ENGINE.paintBackground(g, context, id, gtkState, null,
x, y, w, h);
}
ENGINE.paintShadow(g, context, id, gtkState, ENGINE.paintShadow(g, context, id, gtkState,
ShadowType.IN, "entry", x, y, w, h); ShadowType.IN, "entry", x, y, w, h);
if (!GTKLookAndFeel.is3()) {
ENGINE.paintFlatBox(g, context, id, ENGINE.paintFlatBox(g, context, id,
gtkState, ShadowType.NONE, "entry_bg", gtkState, ShadowType.NONE, "entry_bg",
x + xThickness, x + xThickness,
@ -972,6 +1015,7 @@ class GTKPainter extends SynthPainter {
w - (2 * xThickness), w - (2 * xThickness),
h - (2 * yThickness), h - (2 * yThickness),
ColorType.TEXT_BACKGROUND); ColorType.TEXT_BACKGROUND);
}
if (focusSize > 0 && (state & SynthConstants.FOCUSED) != 0) { if (focusSize > 0 && (state & SynthConstants.FOCUSED) != 0) {
if (!interiorFocus) { if (!interiorFocus) {
@ -982,14 +1026,14 @@ class GTKPainter extends SynthPainter {
} else { } else {
if (containerParent instanceof JComboBox) { if (containerParent instanceof JComboBox) {
x += (focusSize + 2); x += (focusSize + 2);
y += (focusSize + 1); y += focusSize + (GTKLookAndFeel.is3() ? 3 : 1);
w -= (2 * focusSize + 1); w -= 2 * focusSize + (GTKLookAndFeel.is3() ? 4 : 1);
h -= (2 * focusSize + 2); h -= 2 * focusSize + (GTKLookAndFeel.is3() ? 6 : 2);
} else { } else {
x += focusSize; x += focusSize + (GTKLookAndFeel.is3() ? 2 : 0);
y += focusSize; y += focusSize + (GTKLookAndFeel.is3() ? 2 :0 );
w -= 2 * focusSize; w -= 2 * focusSize + (GTKLookAndFeel.is3() ? 4 : 0);
h -= 2 * focusSize; h -= 2 * focusSize + (GTKLookAndFeel.is3() ? 4 : 0);
} }
} }
ENGINE.paintFocus(g, context, id, gtkState, ENGINE.paintFocus(g, context, id, gtkState,
@ -1138,8 +1182,8 @@ class GTKPainter extends SynthPainter {
Orientation orientation = (dir == JScrollBar.HORIZONTAL ? Orientation orientation = (dir == JScrollBar.HORIZONTAL ?
Orientation.HORIZONTAL : Orientation.VERTICAL); Orientation.HORIZONTAL : Orientation.VERTICAL);
ENGINE.setRangeValue(context, id, value, min, max, visible); ENGINE.setRangeValue(context, id, value, min, max, visible);
ENGINE.paintSlider(g, context, id, gtkState, ENGINE.paintSlider(g, context, id, gtkState, ShadowType.OUT,
ShadowType.OUT, "slider", x, y, w, h, orientation); "slider", x, y, w, h, orientation, false);
ENGINE.finishPainting(); ENGINE.finishPainting();
} }
} }

Some files were not shown because too many files have changed in this diff Show More