# HG changeset patch # User chegar # Date 1513254512 0 # Node ID b6ff245c0db6ffc2a8998fb1157ea6bea7e28d8e # Parent 907bddce488c9017160ae8430110d9bd300d46f3# Parent 651a95f30dfbd825ec9603a28e081102a1de53b0 http-client-branch: merge with default diff -r 907bddce488c -r b6ff245c0db6 .hgtags --- a/.hgtags Mon Dec 11 16:43:11 2017 +0000 +++ b/.hgtags Thu Dec 14 12:28:32 2017 +0000 @@ -459,3 +459,4 @@ a2008587c13fa05fa2dbfcb09fe987576fbedfd1 jdk-10+32 bbd692ad4fa300ecca7939ffbe3b1d5e52a28cc6 jdk-10+33 89deac44e51517841491ba86ff44aa82a5ca96b3 jdk-10+34 +d8c634b016c628622c9abbdc6bf50509e5dedbec jdk-10+35 diff -r 907bddce488c -r b6ff245c0db6 make/MacBundles.gmk --- a/make/MacBundles.gmk Mon Dec 11 16:43:11 2017 +0000 +++ b/make/MacBundles.gmk Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ BUNDLE_ID := $(MACOSX_BUNDLE_ID_BASE).$(VERSION_SHORT) BUNDLE_NAME := $(MACOSX_BUNDLE_NAME_BASE) $(VERSION_SHORT) BUNDLE_INFO := $(MACOSX_BUNDLE_NAME_BASE) $(VERSION_STRING) - BUNDLE_PLATFORM_VERSION := $(VERSION_MAJOR).$(VERSION_MINOR) + BUNDLE_PLATFORM_VERSION := $(VERSION_FEATURE).$(VERSION_INTERIM) BUNDLE_VERSION := $(VERSION_NUMBER) ifeq ($(COMPANY_NAME), N/A) BUNDLE_VENDOR := UNDEFINED diff -r 907bddce488c -r b6ff245c0db6 make/ReleaseFile.gmk --- a/make/ReleaseFile.gmk Mon Dec 11 16:43:11 2017 +0000 +++ b/make/ReleaseFile.gmk Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -48,6 +48,9 @@ $(call info-file-item, "SUN_ARCH_ABI", "$(JDK_ARCH_ABI_PROP_NAME)")) $(call info-file-item, "SOURCE", "$(strip $(SOURCE_REVISION))") $(call info-file-item, "IMPLEMENTOR", "$(COMPANY_NAME)") + $(if $(VENDOR_VERSION_STRING), \ + $(call info-file-item, "IMPLEMENTOR_VERSION", "$(VENDOR_VERSION_STRING)")) + $(call info-file-item, "JAVA_VERSION_DATE", "$(VERSION_DATE)") $(call info-file-item, "OS_NAME", "$(RELEASE_FILE_OS_NAME)") $(call info-file-item, "OS_ARCH", "$(RELEASE_FILE_OS_ARCH)") endef diff -r 907bddce488c -r b6ff245c0db6 make/autoconf/flags.m4 --- a/make/autoconf/flags.m4 Mon Dec 11 16:43:11 2017 +0000 +++ b/make/autoconf/flags.m4 Thu Dec 14 12:28:32 2017 +0000 @@ -313,7 +313,7 @@ -D\"JDK_COMPONENT=\$(PRODUCT_NAME) \$(JDK_RC_PLATFORM_NAME) binary\" \ -D\"JDK_VER=\$(VERSION_NUMBER)\" \ -D\"JDK_COPYRIGHT=Copyright \xA9 $COPYRIGHT_YEAR\" \ - -D\"JDK_NAME=\$(PRODUCT_NAME) \$(JDK_RC_PLATFORM_NAME) \$(VERSION_MAJOR)\" \ + -D\"JDK_NAME=\$(PRODUCT_NAME) \$(JDK_RC_PLATFORM_NAME) \$(VERSION_FEATURE)\" \ -D\"JDK_FVER=\$(subst .,\$(COMMA),\$(VERSION_NUMBER_FOUR_POSITIONS))\"" JVM_RCFLAGS="$JVM_RCFLAGS \ @@ -1166,7 +1166,9 @@ -I${TOPDIR}/src/java.base/$OPENJDK_$1_OS/native/include \ -I${TOPDIR}/src/java.base/$OPENJDK_$1_OS_TYPE/native/include \ -I${TOPDIR}/src/java.base/share/native/libjava \ - -I${TOPDIR}/src/java.base/$OPENJDK_$1_OS_TYPE/native/libjava" + -I${TOPDIR}/src/java.base/$OPENJDK_$1_OS_TYPE/native/libjava \ + -I${TOPDIR}/src/hotspot/share/include \ + -I${TOPDIR}/src/hotspot/os/${HOTSPOT_$1_OS_TYPE}/include" # The shared libraries are compiled using the picflag. $2CFLAGS_JDKLIB="[$]$2COMMON_CCXXFLAGS_JDK \ diff -r 907bddce488c -r b6ff245c0db6 make/autoconf/generated-configure.sh --- a/make/autoconf/generated-configure.sh Mon Dec 11 16:43:11 2017 +0000 +++ b/make/autoconf/generated-configure.sh Thu Dec 14 12:28:32 2017 +0000 @@ -887,6 +887,8 @@ BOOT_JDK JAVA_CHECK JAVAC_CHECK +VENDOR_VERSION_STRING +VERSION_DATE VERSION_IS_GA VERSION_SHORT VERSION_STRING @@ -896,9 +898,9 @@ VERSION_BUILD VERSION_PRE VERSION_PATCH -VERSION_SECURITY -VERSION_MINOR -VERSION_MAJOR +VERSION_UPDATE +VERSION_INTERIM +VERSION_FEATURE MACOSX_BUNDLE_ID_BASE MACOSX_BUNDLE_NAME_BASE HOTSPOT_VM_DISTRO @@ -972,7 +974,6 @@ HOTSPOT_BUILD_OS_TYPE HOTSPOT_BUILD_OS OPENJDK_BUILD_BUNDLE_PLATFORM -OPENJDK_BUILD_OS_EXPORT_DIR OPENJDK_BUILD_CPU_OSARCH OPENJDK_BUILD_CPU_ISADIR OPENJDK_BUILD_CPU_LEGACY_LIB @@ -984,7 +985,6 @@ HOTSPOT_TARGET_OS DEFINE_CROSS_COMPILE_ARCH OPENJDK_TARGET_BUNDLE_PLATFORM -OPENJDK_TARGET_OS_EXPORT_DIR OPENJDK_TARGET_CPU_OSARCH OPENJDK_TARGET_CPU_ISADIR OPENJDK_TARGET_CPU_LEGACY_LIB @@ -1093,6 +1093,7 @@ docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -1143,14 +1144,19 @@ with_update_version with_user_release_suffix with_build_number +with_version_major +with_version_minor +with_version_security with_version_string with_version_pre with_version_opt with_version_build -with_version_major -with_version_minor -with_version_security +with_version_feature +with_version_interim +with_version_update with_version_patch +with_version_date +with_vendor_version_string with_boot_jdk with_build_jdk with_import_modules @@ -1377,6 +1383,7 @@ sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1629,6 +1636,15 @@ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1766,7 +1782,7 @@ for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1919,6 +1935,7 @@ --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -2060,6 +2077,12 @@ compatibility and is ignored --with-build-number Deprecated. Option is kept for backwards compatibility and is ignored + --with-version-major Deprecated. Option is kept for backwards + compatibility and is ignored + --with-version-minor Deprecated. Option is kept for backwards + compatibility and is ignored + --with-version-security Deprecated. Option is kept for backwards + compatibility and is ignored --with-version-string Set version string [calculated] --with-version-pre Set the base part of the version 'PRE' field (pre-release identifier) ['internal'] @@ -2067,14 +2090,17 @@ [..] --with-version-build Set version 'BUILD' field (build number) [not specified] - --with-version-major Set version 'MAJOR' field (first number) [current + --with-version-feature Set version 'FEATURE' field (first number) [current source value] - --with-version-minor Set version 'MINOR' field (second number) [current + --with-version-interim Set version 'INTERIM' field (second number) [current source value] - --with-version-security Set version 'SECURITY' field (third number) [current + --with-version-update Set version 'UPDATE' field (third number) [current source value] --with-version-patch Set version 'PATCH' field (fourth number) [not specified] + --with-version-date Set version date [current source value] + --with-vendor-version-string + Set vendor version string [not specified] --with-boot-jdk path to Boot JDK (used to bootstrap build) [probed] --with-build-jdk path to JDK of same version as is being built[the newly built JDK] @@ -4449,7 +4475,7 @@ # -# Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -5159,7 +5185,7 @@ #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1512479382 +DATE_WHEN_GENERATED=1513206608 ############################################################################### # @@ -16200,13 +16226,6 @@ OPENJDK_TARGET_CPU_JLI="amd64" fi - if test "x$OPENJDK_TARGET_OS" = xmacosx; then - OPENJDK_TARGET_OS_EXPORT_DIR=macosx - else - OPENJDK_TARGET_OS_EXPORT_DIR=${OPENJDK_TARGET_OS_TYPE} - fi - - # The new version string in JDK 9 also defined new naming of OS and ARCH for bundles # Macosx is osx and x86_64 is x64 if test "x$OPENJDK_TARGET_OS" = xmacosx; then @@ -16358,13 +16377,6 @@ OPENJDK_BUILD_CPU_JLI="amd64" fi - if test "x$OPENJDK_BUILD_OS" = xmacosx; then - OPENJDK_BUILD_OS_EXPORT_DIR=macosx - else - OPENJDK_BUILD_OS_EXPORT_DIR=${OPENJDK_BUILD_OS_TYPE} - fi - - # The new version string in JDK 9 also defined new naming of OS and ARCH for bundles # Macosx is osx and x86_64 is x64 if test "x$OPENJDK_BUILD_OS" = xmacosx; then @@ -25004,6 +25016,33 @@ + +# Check whether --with-version-major was given. +if test "${with_version_major+set}" = set; then : + withval=$with_version_major; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Option --with-version-major is deprecated and will be ignored." >&5 +$as_echo "$as_me: WARNING: Option --with-version-major is deprecated and will be ignored." >&2;} +fi + + + + +# Check whether --with-version-minor was given. +if test "${with_version_minor+set}" = set; then : + withval=$with_version_minor; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Option --with-version-minor is deprecated and will be ignored." >&5 +$as_echo "$as_me: WARNING: Option --with-version-minor is deprecated and will be ignored." >&2;} +fi + + + + +# Check whether --with-version-security was given. +if test "${with_version_security+set}" = set; then : + withval=$with_version_security; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Option --with-version-security is deprecated and will be ignored." >&5 +$as_echo "$as_me: WARNING: Option --with-version-security is deprecated and will be ignored." >&2;} +fi + + + # Source the version numbers file . $AUTOCONF_DIR/version-numbers @@ -25032,20 +25071,20 @@ elif test "x$with_version_string" != x; then # Additional [] needed to keep m4 from mangling shell constructs. if [[ $with_version_string =~ ^([0-9]+)(\.([0-9]+))?(\.([0-9]+))?(\.([0-9]+))?(-([a-zA-Z]+))?((\+)([0-9]+)?(-([-a-zA-Z0-9.]+))?)?$ ]] ; then - VERSION_MAJOR=${BASH_REMATCH[1]} - VERSION_MINOR=${BASH_REMATCH[3]} - VERSION_SECURITY=${BASH_REMATCH[5]} + VERSION_FEATURE=${BASH_REMATCH[1]} + VERSION_INTERIM=${BASH_REMATCH[3]} + VERSION_UPDATE=${BASH_REMATCH[5]} VERSION_PATCH=${BASH_REMATCH[7]} VERSION_PRE=${BASH_REMATCH[9]} version_plus_separator=${BASH_REMATCH[11]} VERSION_BUILD=${BASH_REMATCH[12]} VERSION_OPT=${BASH_REMATCH[14]} # Unspecified numerical fields are interpreted as 0. - if test "x$VERSION_MINOR" = x; then - VERSION_MINOR=0 - fi - if test "x$VERSION_SECURITY" = x; then - VERSION_SECURITY=0 + if test "x$VERSION_INTERIM" = x; then + VERSION_INTERIM=0 + fi + if test "x$VERSION_UPDATE" = x; then + VERSION_UPDATE=0 fi if test "x$VERSION_PATCH" = x; then VERSION_PATCH=0 @@ -25174,22 +25213,22 @@ fi -# Check whether --with-version-major was given. -if test "${with_version_major+set}" = set; then : - withval=$with_version_major; with_version_major_present=true -else - with_version_major_present=false -fi - - - if test "x$with_version_major_present" = xtrue; then - if test "x$with_version_major" = xyes; then - as_fn_error $? "--with-version-major must have a value" "$LINENO" 5 +# Check whether --with-version-feature was given. +if test "${with_version_feature+set}" = set; then : + withval=$with_version_feature; with_version_feature_present=true +else + with_version_feature_present=false +fi + + + if test "x$with_version_feature_present" = xtrue; then + if test "x$with_version_feature" = xyes; then + as_fn_error $? "--with-version-feature must have a value" "$LINENO" 5 else # Additional [] needed to keep m4 from mangling shell constructs. - if ! [[ "$with_version_major" =~ ^0*([1-9][0-9]*)|(0)$ ]] ; then - as_fn_error $? "\"$with_version_major\" is not a valid numerical value for VERSION_MAJOR" "$LINENO" 5 + if ! [[ "$with_version_feature" =~ ^0*([1-9][0-9]*)|(0)$ ]] ; then + as_fn_error $? "\"$with_version_feature\" is not a valid numerical value for VERSION_FEATURE" "$LINENO" 5 fi # Extract the version number without leading zeros. cleaned_value=${BASH_REMATCH[1]} @@ -25199,44 +25238,44 @@ fi if test $cleaned_value -gt 255; then - as_fn_error $? "VERSION_MAJOR is given as $with_version_major. This is greater than 255 which is not allowed." "$LINENO" 5 - fi - if test "x$cleaned_value" != "x$with_version_major"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Value for VERSION_MAJOR has been sanitized from '$with_version_major' to '$cleaned_value'" >&5 -$as_echo "$as_me: WARNING: Value for VERSION_MAJOR has been sanitized from '$with_version_major' to '$cleaned_value'" >&2;} - fi - VERSION_MAJOR=$cleaned_value + as_fn_error $? "VERSION_FEATURE is given as $with_version_feature. This is greater than 255 which is not allowed." "$LINENO" 5 + fi + if test "x$cleaned_value" != "x$with_version_feature"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Value for VERSION_FEATURE has been sanitized from '$with_version_feature' to '$cleaned_value'" >&5 +$as_echo "$as_me: WARNING: Value for VERSION_FEATURE has been sanitized from '$with_version_feature' to '$cleaned_value'" >&2;} + fi + VERSION_FEATURE=$cleaned_value fi else if test "x$NO_DEFAULT_VERSION_PARTS" != xtrue; then # Default is to get value from version-numbers - VERSION_MAJOR="$DEFAULT_VERSION_MAJOR" - fi - fi - - -# Check whether --with-version-minor was given. -if test "${with_version_minor+set}" = set; then : - withval=$with_version_minor; with_version_minor_present=true -else - with_version_minor_present=false -fi - - - if test "x$with_version_minor_present" = xtrue; then - if test "x$with_version_minor" = xyes; then - as_fn_error $? "--with-version-minor must have a value" "$LINENO" 5 - elif test "x$with_version_minor" = xno; then + VERSION_FEATURE="$DEFAULT_VERSION_FEATURE" + fi + fi + + +# Check whether --with-version-interim was given. +if test "${with_version_interim+set}" = set; then : + withval=$with_version_interim; with_version_interim_present=true +else + with_version_interim_present=false +fi + + + if test "x$with_version_interim_present" = xtrue; then + if test "x$with_version_interim" = xyes; then + as_fn_error $? "--with-version-interim must have a value" "$LINENO" 5 + elif test "x$with_version_interim" = xno; then # Interpret --without-* as empty string (i.e. 0) instead of the literal "no" - VERSION_MINOR=0 - elif test "x$with_version_minor" = x; then - VERSION_MINOR=0 + VERSION_INTERIM=0 + elif test "x$with_version_interim" = x; then + VERSION_INTERIM=0 else # Additional [] needed to keep m4 from mangling shell constructs. - if ! [[ "$with_version_minor" =~ ^0*([1-9][0-9]*)|(0)$ ]] ; then - as_fn_error $? "\"$with_version_minor\" is not a valid numerical value for VERSION_MINOR" "$LINENO" 5 + if ! [[ "$with_version_interim" =~ ^0*([1-9][0-9]*)|(0)$ ]] ; then + as_fn_error $? "\"$with_version_interim\" is not a valid numerical value for VERSION_INTERIM" "$LINENO" 5 fi # Extract the version number without leading zeros. cleaned_value=${BASH_REMATCH[1]} @@ -25246,44 +25285,44 @@ fi if test $cleaned_value -gt 255; then - as_fn_error $? "VERSION_MINOR is given as $with_version_minor. This is greater than 255 which is not allowed." "$LINENO" 5 - fi - if test "x$cleaned_value" != "x$with_version_minor"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Value for VERSION_MINOR has been sanitized from '$with_version_minor' to '$cleaned_value'" >&5 -$as_echo "$as_me: WARNING: Value for VERSION_MINOR has been sanitized from '$with_version_minor' to '$cleaned_value'" >&2;} - fi - VERSION_MINOR=$cleaned_value + as_fn_error $? "VERSION_INTERIM is given as $with_version_interim. This is greater than 255 which is not allowed." "$LINENO" 5 + fi + if test "x$cleaned_value" != "x$with_version_interim"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Value for VERSION_INTERIM has been sanitized from '$with_version_interim' to '$cleaned_value'" >&5 +$as_echo "$as_me: WARNING: Value for VERSION_INTERIM has been sanitized from '$with_version_interim' to '$cleaned_value'" >&2;} + fi + VERSION_INTERIM=$cleaned_value fi else if test "x$NO_DEFAULT_VERSION_PARTS" != xtrue; then # Default is 0, if unspecified - VERSION_MINOR=$DEFAULT_VERSION_MINOR - fi - fi - - -# Check whether --with-version-security was given. -if test "${with_version_security+set}" = set; then : - withval=$with_version_security; with_version_security_present=true -else - with_version_security_present=false -fi - - - if test "x$with_version_security_present" = xtrue; then - if test "x$with_version_security" = xyes; then - as_fn_error $? "--with-version-security must have a value" "$LINENO" 5 - elif test "x$with_version_security" = xno; then + VERSION_INTERIM=$DEFAULT_VERSION_INTERIM + fi + fi + + +# Check whether --with-version-update was given. +if test "${with_version_update+set}" = set; then : + withval=$with_version_update; with_version_update_present=true +else + with_version_update_present=false +fi + + + if test "x$with_version_update_present" = xtrue; then + if test "x$with_version_update" = xyes; then + as_fn_error $? "--with-version-update must have a value" "$LINENO" 5 + elif test "x$with_version_update" = xno; then # Interpret --without-* as empty string (i.e. 0) instead of the literal "no" - VERSION_SECURITY=0 - elif test "x$with_version_security" = x; then - VERSION_SECURITY=0 + VERSION_UPDATE=0 + elif test "x$with_version_update" = x; then + VERSION_UPDATE=0 else # Additional [] needed to keep m4 from mangling shell constructs. - if ! [[ "$with_version_security" =~ ^0*([1-9][0-9]*)|(0)$ ]] ; then - as_fn_error $? "\"$with_version_security\" is not a valid numerical value for VERSION_SECURITY" "$LINENO" 5 + if ! [[ "$with_version_update" =~ ^0*([1-9][0-9]*)|(0)$ ]] ; then + as_fn_error $? "\"$with_version_update\" is not a valid numerical value for VERSION_UPDATE" "$LINENO" 5 fi # Extract the version number without leading zeros. cleaned_value=${BASH_REMATCH[1]} @@ -25293,19 +25332,19 @@ fi if test $cleaned_value -gt 255; then - as_fn_error $? "VERSION_SECURITY is given as $with_version_security. This is greater than 255 which is not allowed." "$LINENO" 5 - fi - if test "x$cleaned_value" != "x$with_version_security"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Value for VERSION_SECURITY has been sanitized from '$with_version_security' to '$cleaned_value'" >&5 -$as_echo "$as_me: WARNING: Value for VERSION_SECURITY has been sanitized from '$with_version_security' to '$cleaned_value'" >&2;} - fi - VERSION_SECURITY=$cleaned_value + as_fn_error $? "VERSION_UPDATE is given as $with_version_update. This is greater than 255 which is not allowed." "$LINENO" 5 + fi + if test "x$cleaned_value" != "x$with_version_update"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Value for VERSION_UPDATE has been sanitized from '$with_version_update' to '$cleaned_value'" >&5 +$as_echo "$as_me: WARNING: Value for VERSION_UPDATE has been sanitized from '$with_version_update' to '$cleaned_value'" >&2;} + fi + VERSION_UPDATE=$cleaned_value fi else if test "x$NO_DEFAULT_VERSION_PARTS" != xtrue; then # Default is 0, if unspecified - VERSION_SECURITY=$DEFAULT_VERSION_SECURITY + VERSION_UPDATE=$DEFAULT_VERSION_UPDATE fi fi @@ -25366,7 +25405,7 @@ fi # VERSION_NUMBER but always with exactly 4 positions, with 0 for empty positions. - VERSION_NUMBER_FOUR_POSITIONS=$VERSION_MAJOR.$VERSION_MINOR.$VERSION_SECURITY.$VERSION_PATCH + VERSION_NUMBER_FOUR_POSITIONS=$VERSION_FEATURE.$VERSION_INTERIM.$VERSION_UPDATE.$VERSION_PATCH stripped_version_number=$VERSION_NUMBER_FOUR_POSITIONS # Strip trailing zeroes from stripped_version_number @@ -25384,6 +25423,40 @@ # The short version string, just VERSION_NUMBER and PRE, if present. VERSION_SHORT=$VERSION_NUMBER${VERSION_PRE:+-$VERSION_PRE} + # The version date + +# Check whether --with-version-date was given. +if test "${with_version_date+set}" = set; then : + withval=$with_version_date; +fi + + if test "x$with_version_date" = xyes; then + as_fn_error $? "--with-version-date must have a value" "$LINENO" 5 + elif test "x$with_version_date" != x; then + if ! [[ $with_version_date =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] ; then + as_fn_error $? "\"$with_version_date\" is not a valid version date" "$LINENO" 5 + else + VERSION_DATE="$with_version_date" + fi + else + VERSION_DATE="$DEFAULT_VERSION_DATE" + fi + + # The vendor version string, if any + +# Check whether --with-vendor-version-string was given. +if test "${with_vendor_version_string+set}" = set; then : + withval=$with_vendor_version_string; +fi + + if test "x$with_vendor_version_string" = xyes; then + as_fn_error $? "--with-vendor-version-string must have a value" "$LINENO" 5 + elif ! [[ $with_vendor_version_string =~ ^[[:graph:]]*$ ]] ; then + as_fn_error $? "--with--vendor-version-string contains non-graphical characters: $with_vendor_version_string" "$LINENO" 5 + else + VENDOR_VERSION_STRING="$with_vendor_version_string" + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for version string" >&5 $as_echo_n "checking for version string... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $VERSION_STRING" >&5 @@ -25403,6 +25476,8 @@ + + ############################################################################### # # Setup BootJDK, used to bootstrap the build. @@ -50669,7 +50744,7 @@ -D\"JDK_COMPONENT=\$(PRODUCT_NAME) \$(JDK_RC_PLATFORM_NAME) binary\" \ -D\"JDK_VER=\$(VERSION_NUMBER)\" \ -D\"JDK_COPYRIGHT=Copyright \xA9 $COPYRIGHT_YEAR\" \ - -D\"JDK_NAME=\$(PRODUCT_NAME) \$(JDK_RC_PLATFORM_NAME) \$(VERSION_MAJOR)\" \ + -D\"JDK_NAME=\$(PRODUCT_NAME) \$(JDK_RC_PLATFORM_NAME) \$(VERSION_FEATURE)\" \ -D\"JDK_FVER=\$(subst .,\$(COMMA),\$(VERSION_NUMBER_FOUR_POSITIONS))\"" JVM_RCFLAGS="$JVM_RCFLAGS \ @@ -52817,7 +52892,9 @@ -I${TOPDIR}/src/java.base/$OPENJDK_TARGET_OS/native/include \ -I${TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/include \ -I${TOPDIR}/src/java.base/share/native/libjava \ - -I${TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/libjava" + -I${TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/libjava \ + -I${TOPDIR}/src/hotspot/share/include \ + -I${TOPDIR}/src/hotspot/os/${HOTSPOT_TARGET_OS_TYPE}/include" # The shared libraries are compiled using the picflag. CFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK \ @@ -53698,7 +53775,9 @@ -I${TOPDIR}/src/java.base/$OPENJDK_BUILD_OS/native/include \ -I${TOPDIR}/src/java.base/$OPENJDK_BUILD_OS_TYPE/native/include \ -I${TOPDIR}/src/java.base/share/native/libjava \ - -I${TOPDIR}/src/java.base/$OPENJDK_BUILD_OS_TYPE/native/libjava" + -I${TOPDIR}/src/java.base/$OPENJDK_BUILD_OS_TYPE/native/libjava \ + -I${TOPDIR}/src/hotspot/share/include \ + -I${TOPDIR}/src/hotspot/os/${HOTSPOT_BUILD_OS_TYPE}/include" # The shared libraries are compiled using the picflag. OPENJDK_BUILD_CFLAGS_JDKLIB="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK \ diff -r 907bddce488c -r b6ff245c0db6 make/autoconf/jdk-version.m4 --- a/make/autoconf/jdk-version.m4 Mon Dec 11 16:43:11 2017 +0000 +++ b/make/autoconf/jdk-version.m4 Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -62,6 +62,9 @@ BASIC_DEPRECATED_ARG_WITH([update-version]) BASIC_DEPRECATED_ARG_WITH([user-release-suffix]) BASIC_DEPRECATED_ARG_WITH([build-number]) + BASIC_DEPRECATED_ARG_WITH([version-major]) + BASIC_DEPRECATED_ARG_WITH([version-minor]) + BASIC_DEPRECATED_ARG_WITH([version-security]) # Source the version numbers file . $AUTOCONF_DIR/version-numbers @@ -87,20 +90,20 @@ elif test "x$with_version_string" != x; then # Additional [] needed to keep m4 from mangling shell constructs. if [ [[ $with_version_string =~ ^([0-9]+)(\.([0-9]+))?(\.([0-9]+))?(\.([0-9]+))?(-([a-zA-Z]+))?((\+)([0-9]+)?(-([-a-zA-Z0-9.]+))?)?$ ]] ]; then - VERSION_MAJOR=${BASH_REMATCH[[1]]} - VERSION_MINOR=${BASH_REMATCH[[3]]} - VERSION_SECURITY=${BASH_REMATCH[[5]]} + VERSION_FEATURE=${BASH_REMATCH[[1]]} + VERSION_INTERIM=${BASH_REMATCH[[3]]} + VERSION_UPDATE=${BASH_REMATCH[[5]]} VERSION_PATCH=${BASH_REMATCH[[7]]} VERSION_PRE=${BASH_REMATCH[[9]]} version_plus_separator=${BASH_REMATCH[[11]]} VERSION_BUILD=${BASH_REMATCH[[12]]} VERSION_OPT=${BASH_REMATCH[[14]]} # Unspecified numerical fields are interpreted as 0. - if test "x$VERSION_MINOR" = x; then - VERSION_MINOR=0 + if test "x$VERSION_INTERIM" = x; then + VERSION_INTERIM=0 fi - if test "x$VERSION_SECURITY" = x; then - VERSION_SECURITY=0 + if test "x$VERSION_UPDATE" = x; then + VERSION_UPDATE=0 fi if test "x$VERSION_PATCH" = x; then VERSION_PATCH=0 @@ -191,64 +194,64 @@ fi fi - AC_ARG_WITH(version-major, [AS_HELP_STRING([--with-version-major], - [Set version 'MAJOR' field (first number) @<:@current source value@:>@])], - [with_version_major_present=true], [with_version_major_present=false]) + AC_ARG_WITH(version-feature, [AS_HELP_STRING([--with-version-feature], + [Set version 'FEATURE' field (first number) @<:@current source value@:>@])], + [with_version_feature_present=true], [with_version_feature_present=false]) - if test "x$with_version_major_present" = xtrue; then - if test "x$with_version_major" = xyes; then - AC_MSG_ERROR([--with-version-major must have a value]) + if test "x$with_version_feature_present" = xtrue; then + if test "x$with_version_feature" = xyes; then + AC_MSG_ERROR([--with-version-feature must have a value]) else - JDKVER_CHECK_AND_SET_NUMBER(VERSION_MAJOR, $with_version_major) + JDKVER_CHECK_AND_SET_NUMBER(VERSION_FEATURE, $with_version_feature) fi else if test "x$NO_DEFAULT_VERSION_PARTS" != xtrue; then # Default is to get value from version-numbers - VERSION_MAJOR="$DEFAULT_VERSION_MAJOR" + VERSION_FEATURE="$DEFAULT_VERSION_FEATURE" fi fi - AC_ARG_WITH(version-minor, [AS_HELP_STRING([--with-version-minor], - [Set version 'MINOR' field (second number) @<:@current source value@:>@])], - [with_version_minor_present=true], [with_version_minor_present=false]) + AC_ARG_WITH(version-interim, [AS_HELP_STRING([--with-version-interim], + [Set version 'INTERIM' field (second number) @<:@current source value@:>@])], + [with_version_interim_present=true], [with_version_interim_present=false]) - if test "x$with_version_minor_present" = xtrue; then - if test "x$with_version_minor" = xyes; then - AC_MSG_ERROR([--with-version-minor must have a value]) - elif test "x$with_version_minor" = xno; then + if test "x$with_version_interim_present" = xtrue; then + if test "x$with_version_interim" = xyes; then + AC_MSG_ERROR([--with-version-interim must have a value]) + elif test "x$with_version_interim" = xno; then # Interpret --without-* as empty string (i.e. 0) instead of the literal "no" - VERSION_MINOR=0 - elif test "x$with_version_minor" = x; then - VERSION_MINOR=0 + VERSION_INTERIM=0 + elif test "x$with_version_interim" = x; then + VERSION_INTERIM=0 else - JDKVER_CHECK_AND_SET_NUMBER(VERSION_MINOR, $with_version_minor) + JDKVER_CHECK_AND_SET_NUMBER(VERSION_INTERIM, $with_version_interim) fi else if test "x$NO_DEFAULT_VERSION_PARTS" != xtrue; then # Default is 0, if unspecified - VERSION_MINOR=$DEFAULT_VERSION_MINOR + VERSION_INTERIM=$DEFAULT_VERSION_INTERIM fi fi - AC_ARG_WITH(version-security, [AS_HELP_STRING([--with-version-security], - [Set version 'SECURITY' field (third number) @<:@current source value@:>@])], - [with_version_security_present=true], [with_version_security_present=false]) + AC_ARG_WITH(version-update, [AS_HELP_STRING([--with-version-update], + [Set version 'UPDATE' field (third number) @<:@current source value@:>@])], + [with_version_update_present=true], [with_version_update_present=false]) - if test "x$with_version_security_present" = xtrue; then - if test "x$with_version_security" = xyes; then - AC_MSG_ERROR([--with-version-security must have a value]) - elif test "x$with_version_security" = xno; then + if test "x$with_version_update_present" = xtrue; then + if test "x$with_version_update" = xyes; then + AC_MSG_ERROR([--with-version-update must have a value]) + elif test "x$with_version_update" = xno; then # Interpret --without-* as empty string (i.e. 0) instead of the literal "no" - VERSION_SECURITY=0 - elif test "x$with_version_security" = x; then - VERSION_SECURITY=0 + VERSION_UPDATE=0 + elif test "x$with_version_update" = x; then + VERSION_UPDATE=0 else - JDKVER_CHECK_AND_SET_NUMBER(VERSION_SECURITY, $with_version_security) + JDKVER_CHECK_AND_SET_NUMBER(VERSION_UPDATE, $with_version_update) fi else if test "x$NO_DEFAULT_VERSION_PARTS" != xtrue; then # Default is 0, if unspecified - VERSION_SECURITY=$DEFAULT_VERSION_SECURITY + VERSION_UPDATE=$DEFAULT_VERSION_UPDATE fi fi @@ -284,7 +287,7 @@ fi # VERSION_NUMBER but always with exactly 4 positions, with 0 for empty positions. - VERSION_NUMBER_FOUR_POSITIONS=$VERSION_MAJOR.$VERSION_MINOR.$VERSION_SECURITY.$VERSION_PATCH + VERSION_NUMBER_FOUR_POSITIONS=$VERSION_FEATURE.$VERSION_INTERIM.$VERSION_UPDATE.$VERSION_PATCH stripped_version_number=$VERSION_NUMBER_FOUR_POSITIONS # Strip trailing zeroes from stripped_version_number @@ -302,12 +305,38 @@ # The short version string, just VERSION_NUMBER and PRE, if present. VERSION_SHORT=$VERSION_NUMBER${VERSION_PRE:+-$VERSION_PRE} + # The version date + AC_ARG_WITH(version-date, [AS_HELP_STRING([--with-version-date], + [Set version date @<:@current source value@:>@])]) + if test "x$with_version_date" = xyes; then + AC_MSG_ERROR([--with-version-date must have a value]) + elif test "x$with_version_date" != x; then + if [ ! [[ $with_version_date =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] ]; then + AC_MSG_ERROR(["$with_version_date" is not a valid version date]) + else + VERSION_DATE="$with_version_date" + fi + else + VERSION_DATE="$DEFAULT_VERSION_DATE" + fi + + # The vendor version string, if any + AC_ARG_WITH(vendor-version-string, [AS_HELP_STRING([--with-vendor-version-string], + [Set vendor version string @<:@not specified@:>@])]) + if test "x$with_vendor_version_string" = xyes; then + AC_MSG_ERROR([--with-vendor-version-string must have a value]) + elif [ ! [[ $with_vendor_version_string =~ ^[[:graph:]]*$ ]] ]; then + AC_MSG_ERROR([--with--vendor-version-string contains non-graphical characters: $with_vendor_version_string]) + else + VENDOR_VERSION_STRING="$with_vendor_version_string" + fi + AC_MSG_CHECKING([for version string]) AC_MSG_RESULT([$VERSION_STRING]) - AC_SUBST(VERSION_MAJOR) - AC_SUBST(VERSION_MINOR) - AC_SUBST(VERSION_SECURITY) + AC_SUBST(VERSION_FEATURE) + AC_SUBST(VERSION_INTERIM) + AC_SUBST(VERSION_UPDATE) AC_SUBST(VERSION_PATCH) AC_SUBST(VERSION_PRE) AC_SUBST(VERSION_BUILD) @@ -317,4 +346,6 @@ AC_SUBST(VERSION_STRING) AC_SUBST(VERSION_SHORT) AC_SUBST(VERSION_IS_GA) + AC_SUBST(VERSION_DATE) + AC_SUBST(VENDOR_VERSION_STRING) ]) diff -r 907bddce488c -r b6ff245c0db6 make/autoconf/platform.m4 --- a/make/autoconf/platform.m4 Mon Dec 11 16:43:11 2017 +0000 +++ b/make/autoconf/platform.m4 Thu Dec 14 12:28:32 2017 +0000 @@ -388,13 +388,6 @@ OPENJDK_$1_CPU_JLI="amd64" fi - if test "x$OPENJDK_$1_OS" = xmacosx; then - OPENJDK_$1_OS_EXPORT_DIR=macosx - else - OPENJDK_$1_OS_EXPORT_DIR=${OPENJDK_$1_OS_TYPE} - fi - AC_SUBST(OPENJDK_$1_OS_EXPORT_DIR) - # The new version string in JDK 9 also defined new naming of OS and ARCH for bundles # Macosx is osx and x86_64 is x64 if test "x$OPENJDK_$1_OS" = xmacosx; then diff -r 907bddce488c -r b6ff245c0db6 make/autoconf/spec.gmk.in --- a/make/autoconf/spec.gmk.in Mon Dec 11 16:43:11 2017 +0000 +++ b/make/autoconf/spec.gmk.in Thu Dec 14 12:28:32 2017 +0000 @@ -78,7 +78,6 @@ OPENJDK_TARGET_CPU_LEGACY:=@OPENJDK_TARGET_CPU_LEGACY@ OPENJDK_TARGET_CPU_LEGACY_LIB:=@OPENJDK_TARGET_CPU_LEGACY_LIB@ OPENJDK_TARGET_CPU_OSARCH:=@OPENJDK_TARGET_CPU_OSARCH@ -OPENJDK_TARGET_OS_EXPORT_DIR:=@OPENJDK_TARGET_OS_EXPORT_DIR@ HOTSPOT_TARGET_OS := @HOTSPOT_TARGET_OS@ HOTSPOT_TARGET_OS_TYPE := @HOTSPOT_TARGET_OS_TYPE@ @@ -144,10 +143,9 @@ ## Building blocks of the version string # First three version numbers, with well-specified meanings (numerical) -VERSION_MAJOR := @VERSION_MAJOR@ -VERSION_MINOR := @VERSION_MINOR@ -VERSION_SECURITY := @VERSION_SECURITY@ -# Optional fourth element for use by OpenJDK consumers (numerical) +VERSION_FEATURE := @VERSION_FEATURE@ +VERSION_INTERIM := @VERSION_INTERIM@ +VERSION_UPDATE := @VERSION_UPDATE@ VERSION_PATCH := @VERSION_PATCH@ # The pre-release identifier (string) VERSION_PRE := @VERSION_PRE@ @@ -165,17 +163,23 @@ VERSION_STRING := @VERSION_STRING@ # The short version string, without trailing zeroes and just PRE, if present. VERSION_SHORT := @VERSION_SHORT@ -# The Java specification version. It usually equals the major version number. -VERSION_SPECIFICATION := @VERSION_MAJOR@ +# The Java specification version. It usually equals the feature version number. +VERSION_SPECIFICATION := @VERSION_FEATURE@ # A GA version is defined by the PRE string being empty. Rather than testing for # that, this variable defines it with true/false. VERSION_IS_GA := @VERSION_IS_GA@ +# Version date +VERSION_DATE := @VERSION_DATE@ + +# Vendor version string +VENDOR_VERSION_STRING := @VENDOR_VERSION_STRING@ + # Convenience CFLAGS settings for passing version information into native programs. VERSION_CFLAGS := \ - -DVERSION_MAJOR=$(VERSION_MAJOR) \ - -DVERSION_MINOR=$(VERSION_MINOR) \ - -DVERSION_SECURITY=$(VERSION_SECURITY) \ + -DVERSION_FEATURE=$(VERSION_FEATURE) \ + -DVERSION_INTERIM=$(VERSION_INTERIM) \ + -DVERSION_UPDATE=$(VERSION_UPDATE) \ -DVERSION_PATCH=$(VERSION_PATCH) \ -DVERSION_PRE='"$(VERSION_PRE)"' \ -DVERSION_BUILD=$(VERSION_BUILD) \ @@ -184,6 +188,8 @@ -DVERSION_STRING='"$(VERSION_STRING)"' \ -DVERSION_SHORT='"$(VERSION_SHORT)"' \ -DVERSION_SPECIFICATION='"$(VERSION_SPECIFICATION)"' \ + -DVERSION_DATE='"$(VERSION_DATE)"' \ + -DVENDOR_VERSION_STRING='"$(VENDOR_VERSION_STRING)"' \ # # Platform naming variables diff -r 907bddce488c -r b6ff245c0db6 make/autoconf/version-numbers --- a/make/autoconf/version-numbers Mon Dec 11 16:43:11 2017 +0000 +++ b/make/autoconf/version-numbers Thu Dec 14 12:28:32 2017 +0000 @@ -25,10 +25,11 @@ # Default version numbers to use unless overridden by configure -DEFAULT_VERSION_MAJOR=10 -DEFAULT_VERSION_MINOR=0 -DEFAULT_VERSION_SECURITY=0 +DEFAULT_VERSION_FEATURE=10 +DEFAULT_VERSION_INTERIM=0 +DEFAULT_VERSION_UPDATE=0 DEFAULT_VERSION_PATCH=0 +DEFAULT_VERSION_DATE=2018-03-20 LAUNCHER_NAME=openjdk PRODUCT_NAME=OpenJDK diff -r 907bddce488c -r b6ff245c0db6 make/conf/jib-profiles.js --- a/make/conf/jib-profiles.js Mon Dec 11 16:43:11 2017 +0000 +++ b/make/conf/jib-profiles.js Thu Dec 14 12:28:32 2017 +0000 @@ -662,6 +662,16 @@ } }); + // For open profiles, the non-debug jdk bundles, need an "open" prefix on the + // remote bundle names, forming the word "openjdk". See JDK-8188789. + common.main_profile_names.forEach(function (name) { + var openName = name + common.open_suffix; + profiles[openName].artifacts["jdk"].remote = replaceAll( + "\/jdk-", "/openjdk-", + replaceAll("\/\\1", "/open\\1", + profiles[openName].artifacts["jdk"].remote)); + }); + // Profiles used to run tests. Used in JPRT and Mach 5. var testOnlyProfiles = { "run-test-jprt": { @@ -1040,17 +1050,17 @@ * Constructs the numeric version string from reading the * make/autoconf/version-numbers file and removing all trailing ".0". * - * @param major Override major version - * @param minor Override minor version - * @param security Override security version + * @param feature Override feature version + * @param interim Override interim version + * @param update Override update version * @param patch Override patch version * @returns {String} The numeric version string */ -var getVersion = function (major, minor, security, patch) { +var getVersion = function (feature, interim, update, patch) { var version_numbers = getVersionNumbers(); - var version = (major != null ? major : version_numbers.get("DEFAULT_VERSION_MAJOR")) - + "." + (minor != null ? minor : version_numbers.get("DEFAULT_VERSION_MINOR")) - + "." + (security != null ? security : version_numbers.get("DEFAULT_VERSION_SECURITY")) + var version = (feature != null ? feature : version_numbers.get("DEFAULT_VERSION_FEATURE")) + + "." + (interim != null ? interim : version_numbers.get("DEFAULT_VERSION_INTERIM")) + + "." + (update != null ? update : version_numbers.get("DEFAULT_VERSION_UPDATE")) + "." + (patch != null ? patch : version_numbers.get("DEFAULT_VERSION_PATCH")); while (version.match(".*\\.0$")) { version = version.substring(0, version.length - 2); diff -r 907bddce488c -r b6ff245c0db6 make/copy/Copy-java.base.gmk --- a/make/copy/Copy-java.base.gmk Mon Dec 11 16:43:11 2017 +0000 +++ b/make/copy/Copy-java.base.gmk Thu Dec 14 12:28:32 2017 +0000 @@ -28,24 +28,6 @@ $(eval $(call IncludeCustomExtension, copy/Copy-java.base.gmk)) ################################################################################ -# -# Copy exported header files to outputdir. -# -TARGETS += \ - $(INCLUDE_DST_DIR)/jni.h \ - $(INCLUDE_DST_DIR)/jvmticmlr.h \ - $(INCLUDE_DST_DIR)/classfile_constants.h \ - $(INCLUDE_DST_OS_DIR)/jni_md.h \ - # - -$(INCLUDE_DST_DIR)/%.h: $(TOPDIR)/src/java.base/share/native/include/%.h - $(call install-file) - -$(INCLUDE_DST_OS_DIR)/%.h: \ - $(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/include/%.h - $(call install-file) - -################################################################################ ifneq ($(findstring $(OPENJDK_TARGET_OS), windows aix),) diff -r 907bddce488c -r b6ff245c0db6 make/copy/Copy-java.desktop.gmk --- a/make/copy/Copy-java.desktop.gmk Mon Dec 11 16:43:11 2017 +0000 +++ b/make/copy/Copy-java.desktop.gmk Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -29,20 +29,6 @@ ################################################################################ -TARGETS += \ - $(INCLUDE_DST_DIR)/jawt.h \ - $(INCLUDE_DST_OS_DIR)/jawt_md.h \ - # - -$(INCLUDE_DST_DIR)/%.h: $(TOPDIR)/src/java.desktop/share/native/include/%.h - $(call install-file) - -$(INCLUDE_DST_OS_DIR)/%.h: \ - $(TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_EXPORT_DIR)/native/include/%.h - $(call install-file) - -################################################################################ - ifneq ($(FREETYPE_BUNDLE_LIB_PATH), ) # We need to bundle the freetype library, so it will be available at runtime # as well as link time. diff -r 907bddce488c -r b6ff245c0db6 make/copy/Copy-jdk.accessibility.gmk --- a/make/copy/Copy-jdk.accessibility.gmk Mon Dec 11 16:43:11 2017 +0000 +++ b/make/copy/Copy-jdk.accessibility.gmk Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2104, 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,19 +23,7 @@ # questions. # -include CopyCommon.gmk - ################################################################################ +# Include CopyCommon.gmk to get exported header files to be properly copied. -ifeq ($(OPENJDK_TARGET_OS), windows) - TARGETS += $(INCLUDE_DST_OS_DIR)/bridge/AccessBridgeCallbacks.h \ - $(INCLUDE_DST_OS_DIR)/bridge/AccessBridgeCalls.h \ - $(INCLUDE_DST_OS_DIR)/bridge/AccessBridgePackages.h - - $(INCLUDE_DST_OS_DIR)/bridge/%: \ - $(TOPDIR)/src/jdk.accessibility/windows/native/include/bridge/% - $(install-file) - -endif - -################################################################################ +include CopyCommon.gmk diff -r 907bddce488c -r b6ff245c0db6 make/copy/Copy-jdk.jdwp.agent.gmk --- a/make/copy/Copy-jdk.jdwp.agent.gmk Mon Dec 11 16:43:11 2017 +0000 +++ b/make/copy/Copy-jdk.jdwp.agent.gmk Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,13 +23,7 @@ # questions. # -include CopyCommon.gmk - ################################################################################ +# Include CopyCommon.gmk to get exported header files to be properly copied. -TARGETS := $(INCLUDE_DST_DIR)/jdwpTransport.h - -$(INCLUDE_DST_DIR)/%.h: $(TOPDIR)/src/jdk.jdwp.agent/share/native/include/%.h - $(call install-file) - -################################################################################ +include CopyCommon.gmk diff -r 907bddce488c -r b6ff245c0db6 make/copy/CopyCommon.gmk --- a/make/copy/CopyCommon.gmk Mon Dec 11 16:43:11 2017 +0000 +++ b/make/copy/CopyCommon.gmk Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,15 +23,48 @@ # questions. # -INCLUDE_DST_DIR := $(SUPPORT_OUTPUTDIR)/modules_include/$(MODULE) LIB_DST_DIR := $(SUPPORT_OUTPUTDIR)/modules_libs/$(MODULE) CONF_DST_DIR := $(SUPPORT_OUTPUTDIR)/modules_conf/$(MODULE) LEGAL_DST_DIR := $(SUPPORT_OUTPUTDIR)/modules_legal/$(MODULE) -INCLUDE_DST_OS_DIR := $(INCLUDE_DST_DIR)/$(OPENJDK_TARGET_OS) +################################################################################ +# +# Copy exported include headers files to output directory, if present. +# + +INCLUDE_TARGET_DIR := $(SUPPORT_OUTPUTDIR)/modules_include/$(MODULE) +INCLUDE_SOURCE_DIR := $(TOPDIR)/src/$(MODULE)/share/native/include +ifneq ($(wildcard $(INCLUDE_SOURCE_DIR)/*), ) + $(eval $(call SetupCopyFiles, COPY_EXPORTED_INCLUDE, \ + SRC := $(INCLUDE_SOURCE_DIR), \ + DEST := $(INCLUDE_TARGET_DIR), \ + FILES := $(shell $(FIND) $(INCLUDE_SOURCE_DIR) -type f), \ + )) + + TARGETS += $(COPY_EXPORTED_INCLUDE) +endif + +# For historical reasons, the OS include directories have odd names. +INCLUDE_TARGET_OS_SUBDIR := $(OPENJDK_TARGET_OS) ifeq ($(OPENJDK_TARGET_OS), windows) - INCLUDE_DST_OS_DIR := $(INCLUDE_DST_DIR)/win32 + INCLUDE_TARGET_OS_SUBDIR := win32 else ifeq ($(OPENJDK_TARGET_OS), macosx) - INCLUDE_DST_OS_DIR := $(INCLUDE_DST_DIR)/darwin + INCLUDE_TARGET_OS_SUBDIR := darwin +endif + +# Use the most specific of OS and OS_TYPE. +INCLUDE_SOURCE_OS_DIR := $(TOPDIR)/src/$(MODULE)/$(OPENJDK_TARGET_OS)/native/include +ifeq ($(wildcard $(INCLUDE_SOURCE_OS_DIR)/*), ) + INCLUDE_SOURCE_OS_DIR := $(TOPDIR)/src/$(MODULE)/$(OPENJDK_TARGET_OS_TYPE)/native/include endif + +ifneq ($(wildcard $(INCLUDE_SOURCE_OS_DIR)/*), ) + $(eval $(call SetupCopyFiles, COPY_EXPORTED_INCLUDE_OS, \ + SRC := $(INCLUDE_SOURCE_OS_DIR), \ + DEST := $(INCLUDE_TARGET_DIR)/$(INCLUDE_TARGET_OS_SUBDIR), \ + FILES := $(shell $(FIND) $(INCLUDE_SOURCE_OS_DIR) -type f), \ + )) + + TARGETS += $(COPY_EXPORTED_INCLUDE_OS) +endif diff -r 907bddce488c -r b6ff245c0db6 make/gensrc/GensrcMisc.gmk --- a/make/gensrc/GensrcMisc.gmk Mon Dec 11 16:43:11 2017 +0000 +++ b/make/gensrc/GensrcMisc.gmk Thu Dec 14 12:28:32 2017 +0000 @@ -38,7 +38,9 @@ @@VERSION_NUMBER@@ => $(VERSION_NUMBER) ; \ @@VERSION_PRE@@ => $(VERSION_PRE) ; \ @@VERSION_BUILD@@ => $(VERSION_BUILD) ; \ - @@VERSION_OPT@@ => $(VERSION_OPT), \ + @@VERSION_OPT@@ => $(VERSION_OPT) ; \ + @@VERSION_DATE@@ => $(VERSION_DATE) ; \ + @@VENDOR_VERSION_STRING@@ => $(VENDOR_VERSION_STRING), \ )) GENSRC_JAVA_BASE += $(BUILD_VERSION_JAVA) diff -r 907bddce488c -r b6ff245c0db6 make/gensrc/GensrcX11Wrappers.gmk --- a/make/gensrc/GensrcX11Wrappers.gmk Mon Dec 11 16:43:11 2017 +0000 +++ b/make/gensrc/GensrcX11Wrappers.gmk Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -92,8 +92,10 @@ endif SIZER_CFLAGS := \ + -I${TOPDIR}/src/hotspot/share/include \ + -I${TOPDIR}/src/hotspot/os/$(HOTSPOT_TARGET_OS_TYPE)/include \ -I$(TOPDIR)/src/java.base/share/native/include \ - -I$(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_EXPORT_DIR)/native/include \ + -I$(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/include \ -I$(TOPDIR)/src/java.base/share/native/libjava \ -I$(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libjava \ -I$(TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/common/awt \ diff -r 907bddce488c -r b6ff245c0db6 make/hotspot/lib/CompileJvm.gmk --- a/make/hotspot/lib/CompileJvm.gmk Mon Dec 11 16:43:11 2017 +0000 +++ b/make/hotspot/lib/CompileJvm.gmk Thu Dec 14 12:28:32 2017 +0000 @@ -57,9 +57,10 @@ $(patsubst %,-I%,$(filter-out $(JVM_VARIANT_OUTPUTDIR)/gensrc/%, $(JVM_SRC_DIRS))) \ -I$(JVM_VARIANT_OUTPUTDIR)/gensrc \ -I$(TOPDIR)/src/hotspot/share/precompiled \ + -I$(TOPDIR)/src/hotspot/share/include \ + -I$(TOPDIR)/src/hotspot/os/$(HOTSPOT_TARGET_OS_TYPE)/include \ -I$(TOPDIR)/src/java.base/share/native/include \ -I$(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/include \ - -I$(TOPDIR)/src/java.management/share/native/include \ -I$(TOPDIR)/src/java.base/share/native/libjimage \ # diff -r 907bddce488c -r b6ff245c0db6 make/hotspot/lib/CompileLibjsig.gmk --- a/make/hotspot/lib/CompileLibjsig.gmk Mon Dec 11 16:43:11 2017 +0000 +++ b/make/hotspot/lib/CompileLibjsig.gmk Thu Dec 14 12:28:32 2017 +0000 @@ -57,7 +57,7 @@ endif else ifeq ($(OPENJDK_TARGET_OS), solaris) - LIBJSIG_CFLAGS := -m64 -KPIC -mt -I $(TOPDIR)/src/java.base/unix/native/include + LIBJSIG_CFLAGS := -m64 -KPIC -mt -I $(TOPDIR)/src/hotspot/os/$(HOTSPOT_TARGET_OS_TYPE)/include LIBJSIG_LDFLAGS := -m64 -mt -xnolib LIBJSIG_LIBS := $(LIBDL) diff -r 907bddce488c -r b6ff245c0db6 make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java --- a/make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java Mon Dec 11 16:43:11 2017 +0000 +++ b/make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java Thu Dec 14 12:28:32 2017 +0000 @@ -37,6 +37,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; +import java.util.stream.IntStream; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.SAXNotRecognizedException; @@ -52,21 +53,32 @@ static final String LDML_DTD_SYSTEM_ID = "http://www.unicode.org/cldr/dtd/2.0/ldml.dtd"; static final String SPPL_LDML_DTD_SYSTEM_ID = "http://www.unicode.org/cldr/dtd/2.0/ldmlSupplemental.dtd"; + static final String BCP47_LDML_DTD_SYSTEM_ID = "http://www.unicode.org/cldr/dtd/2.0/ldmlBCP47.dtd"; + private static String CLDR_BASE = "../CLDR/21.0.1/"; static String LOCAL_LDML_DTD; static String LOCAL_SPPL_LDML_DTD; + static String LOCAL_BCP47_LDML_DTD; private static String SOURCE_FILE_DIR; private static String SPPL_SOURCE_FILE; private static String NUMBERING_SOURCE_FILE; private static String METAZONES_SOURCE_FILE; private static String LIKELYSUBTAGS_SOURCE_FILE; + private static String TIMEZONE_SOURCE_FILE; static String DESTINATION_DIR = "build/gensrc"; static final String LOCALE_NAME_PREFIX = "locale.displayname."; + static final String LOCALE_SEPARATOR = LOCALE_NAME_PREFIX + "separator"; + static final String LOCALE_KEYTYPE = LOCALE_NAME_PREFIX + "keytype"; + static final String LOCALE_KEY_PREFIX = LOCALE_NAME_PREFIX + "key."; + static final String LOCALE_TYPE_PREFIX = LOCALE_NAME_PREFIX + "type."; + static final String LOCALE_TYPE_PREFIX_CA = LOCALE_TYPE_PREFIX + "ca."; static final String CURRENCY_SYMBOL_PREFIX = "currency.symbol."; static final String CURRENCY_NAME_PREFIX = "currency.displayname."; static final String CALENDAR_NAME_PREFIX = "calendarname."; + static final String CALENDAR_FIRSTDAY_PREFIX = "firstDay."; + static final String CALENDAR_MINDAYS_PREFIX = "minDays."; static final String TIMEZONE_ID_PREFIX = "timezone.id."; static final String ZONE_NAME_PREFIX = "timezone.displayname."; static final String METAZONE_ID_PREFIX = "metazone.id."; @@ -76,6 +88,7 @@ private static LikelySubtagsParseHandler handlerLikelySubtags; static NumberingSystemsParseHandler handlerNumbering; static MetaZonesParseHandler handlerMetaZones; + static TimeZoneParseHandler handlerTimeZone; private static BundleGenerator bundleGenerator; // java.base module related @@ -201,11 +214,13 @@ // Set up path names LOCAL_LDML_DTD = CLDR_BASE + "/dtd/ldml.dtd"; LOCAL_SPPL_LDML_DTD = CLDR_BASE + "/dtd/ldmlSupplemental.dtd"; + LOCAL_BCP47_LDML_DTD = CLDR_BASE + "/dtd/ldmlBCP47.dtd"; SOURCE_FILE_DIR = CLDR_BASE + "/main"; SPPL_SOURCE_FILE = CLDR_BASE + "/supplemental/supplementalData.xml"; LIKELYSUBTAGS_SOURCE_FILE = CLDR_BASE + "/supplemental/likelySubtags.xml"; NUMBERING_SOURCE_FILE = CLDR_BASE + "/supplemental/numberingSystems.xml"; METAZONES_SOURCE_FILE = CLDR_BASE + "/supplemental/metaZones.xml"; + TIMEZONE_SOURCE_FILE = CLDR_BASE + "/bcp47/timezone.xml"; if (BASE_LOCALES.isEmpty()) { setupBaseLocales("en-US"); @@ -215,10 +230,10 @@ // Parse data independent of locales parseSupplemental(); + parseBCP47(); List bundles = readBundleList(); convertBundles(bundles); - convertBundles(addedBundles); } private static void usage() { @@ -314,34 +329,19 @@ } private static final Map> cldrBundles = new HashMap<>(); - // this list will contain additional bundles to be generated for Region dependent Data. - private static List addedBundles = new ArrayList<>(); private static Map> metaInfo = new HashMap<>(); static { // For generating information on supported locales. - metaInfo.put("LocaleNames", new TreeSet<>()); - metaInfo.put("CurrencyNames", new TreeSet<>()); - metaInfo.put("TimeZoneNames", new TreeSet<>()); - metaInfo.put("CalendarData", new TreeSet<>()); - metaInfo.put("FormatData", new TreeSet<>()); metaInfo.put("AvailableLocales", new TreeSet<>()); } - - private static Set calendarDataFields = Set.of("firstDayOfWeek", "minimalDaysInFirstWeek"); - static Map getCLDRBundle(String id) throws Exception { Map bundle = cldrBundles.get(id); if (bundle != null) { return bundle; } - SAXParserFactory factory = SAXParserFactory.newInstance(); - factory.setValidating(true); - SAXParser parser = factory.newSAXParser(); - enableFileAccess(parser); - LDMLParseHandler handler = new LDMLParseHandler(id); File file = new File(SOURCE_FILE_DIR + File.separator + id + ".xml"); if (!file.exists()) { // Skip if the file doesn't exist. @@ -349,14 +349,15 @@ } info("..... main directory ....."); - info("Reading file " + file); - parser.parse(file, handler); + LDMLParseHandler handler = new LDMLParseHandler(id); + parseLDMLFile(file, handler); bundle = handler.getData(); cldrBundles.put(id, bundle); - String country = getCountryCode(id); - if (country != null) { - bundle = handlerSuppl.getData(country); + + if (id.equals("root")) { + // Calendar data (firstDayOfWeek & minDaysInFirstWeek) + bundle = handlerSuppl.getData("root"); if (bundle != null) { //merge two maps into one map Map temp = cldrBundles.remove(id); @@ -379,98 +380,44 @@ // SupplementalData file also provides the "parent" locales which // are othrwise not to be fallen back. Process them here as well. // - info("..... Parsing supplementalData.xml ....."); - SAXParserFactory factorySuppl = SAXParserFactory.newInstance(); - factorySuppl.setValidating(true); - SAXParser parserSuppl = factorySuppl.newSAXParser(); - enableFileAccess(parserSuppl); handlerSuppl = new SupplementDataParseHandler(); - File fileSupply = new File(SPPL_SOURCE_FILE); - parserSuppl.parse(fileSupply, handlerSuppl); + parseLDMLFile(new File(SPPL_SOURCE_FILE), handlerSuppl); Map parentData = handlerSuppl.getData("root"); - parentData.keySet().forEach(key -> { + parentData.keySet().stream() + .filter(key -> key.startsWith(PARENT_LOCALE_PREFIX)) + .forEach(key -> { parentLocalesMap.put(key, new TreeSet( Arrays.asList(((String)parentData.get(key)).split(" ")))); }); // Parse numberingSystems to get digit zero character information. - SAXParserFactory numberingParser = SAXParserFactory.newInstance(); - numberingParser.setValidating(true); - SAXParser parserNumbering = numberingParser.newSAXParser(); - enableFileAccess(parserNumbering); handlerNumbering = new NumberingSystemsParseHandler(); - File fileNumbering = new File(NUMBERING_SOURCE_FILE); - parserNumbering.parse(fileNumbering, handlerNumbering); + parseLDMLFile(new File(NUMBERING_SOURCE_FILE), handlerNumbering); // Parse metaZones to create mappings between Olson tzids and CLDR meta zone names - info("..... Parsing metaZones.xml ....."); - SAXParserFactory metazonesParser = SAXParserFactory.newInstance(); - metazonesParser.setValidating(true); - SAXParser parserMetaZones = metazonesParser.newSAXParser(); - enableFileAccess(parserMetaZones); handlerMetaZones = new MetaZonesParseHandler(); - File fileMetaZones = new File(METAZONES_SOURCE_FILE); - parserMetaZones.parse(fileMetaZones, handlerMetaZones); + parseLDMLFile(new File(METAZONES_SOURCE_FILE), handlerMetaZones); // Parse likelySubtags - info("..... Parsing likelySubtags.xml ....."); - SAXParserFactory likelySubtagsParser = SAXParserFactory.newInstance(); - likelySubtagsParser.setValidating(true); - SAXParser parserLikelySubtags = likelySubtagsParser.newSAXParser(); - enableFileAccess(parserLikelySubtags); handlerLikelySubtags = new LikelySubtagsParseHandler(); - File fileLikelySubtags = new File(LIKELYSUBTAGS_SOURCE_FILE); - parserLikelySubtags.parse(fileLikelySubtags, handlerLikelySubtags); + parseLDMLFile(new File(LIKELYSUBTAGS_SOURCE_FILE), handlerLikelySubtags); } - /** - * This method will check if a new region dependent Bundle needs to be - * generated for this Locale id and targetMap. New Bundle will be generated - * when Locale id has non empty script and country code and targetMap - * contains region dependent data. This method will also remove region - * dependent data from this targetMap after candidate locales check. E.g. It - * will call genRegionDependentBundle() in case of az_Latn_AZ locale and - * remove region dependent data from this targetMap so that az_Latn_AZ - * bundle will not be created. For az_Cyrl_AZ, new Bundle will be generated - * but region dependent data will not be removed from targetMap as its candidate - * locales are [az_Cyrl_AZ, az_Cyrl, root], which does not include az_AZ for - * fallback. - * - */ + // Parsers for data in "bcp47" directory + // + private static void parseBCP47() throws Exception { + // Parse timezone + handlerTimeZone = new TimeZoneParseHandler(); + parseLDMLFile(new File(TIMEZONE_SOURCE_FILE), handlerTimeZone); + } - private static void checkRegionDependentBundle(Map targetMap, String id) { - if ((CLDRConverter.getScript(id) != "") - && (CLDRConverter.getCountryCode(id) != "")) { - Map regionDepDataMap = targetMap - .keySet() - .stream() - .filter(calendarDataFields::contains) - .collect(Collectors.toMap(k -> k, targetMap::get)); - if (!regionDepDataMap.isEmpty()) { - Locale cldrLoc = new Locale(CLDRConverter.getLanguageCode(id), - CLDRConverter.getCountryCode(id)); - genRegionDependentBundle(regionDepDataMap, cldrLoc); - if (checkCandidateLocales(id, cldrLoc)) { - // Remove matchedKeys from this targetMap only if checkCandidateLocales() returns true. - regionDepDataMap.keySet().forEach(targetMap::remove); - } - } - } - } - /** - * This method will generate a new Bundle for region dependent data, - * minimalDaysInFirstWeek and firstDayOfWeek. Newly generated Bundle will be added - * to addedBundles list. - */ - private static void genRegionDependentBundle(Map targetMap, Locale cldrLoc) { - String localeId = cldrLoc.toString(); - StringBuilder sb = getCandLocales(cldrLoc); - if (sb.indexOf(localeId) == -1) { - sb.append(localeId); - } - Bundle bundle = new Bundle(localeId, sb.toString(), null, null); - cldrBundles.put(localeId, targetMap); - addedBundles.add(bundle); + private static void parseLDMLFile(File srcfile, AbstractLDMLHandler handler) throws Exception { + info("..... Parsing " + srcfile.getName() + " ....."); + SAXParserFactory pf = SAXParserFactory.newInstance(); + pf.setValidating(true); + SAXParser parser = pf.newSAXParser(); + enableFileAccess(parser); + parser.parse(srcfile, handler); } private static StringBuilder getCandLocales(Locale cldrLoc) { @@ -491,16 +438,6 @@ return candList; } - /** - * This method will return true, if for a given locale, its language and - * country specific locale will exist in runtime lookup path. E.g. it will - * return true for bs_Latn_BA. - */ - private static boolean checkCandidateLocales(String id, Locale cldrLoc) { - return(getCandidateLocales(Locale.forLanguageTag(id.replaceAll("_", "-"))) - .contains(cldrLoc)); - } - private static void convertBundles(List bundles) throws Exception { // parent locales map. The mappings are put in base metaInfo file // for now. @@ -514,8 +451,6 @@ Map targetMap = bundle.getTargetMap(); - // check if new region DependentBundle needs to be generated for this Locale. - checkRegionDependentBundle(targetMap, bundle.getID()); EnumSet bundleTypes = bundle.getBundleTypes(); if (bundle.isRoot()) { @@ -528,40 +463,30 @@ if (bundleTypes.contains(Bundle.Type.LOCALENAMES)) { Map localeNamesMap = extractLocaleNames(targetMap, bundle.getID()); if (!localeNamesMap.isEmpty() || bundle.isRoot()) { - metaInfo.get("LocaleNames").add(toLanguageTag(bundle.getID())); - addLikelySubtags(metaInfo, "LocaleNames", bundle.getID()); bundleGenerator.generateBundle("util", "LocaleNames", bundle.getJavaID(), true, localeNamesMap, BundleType.OPEN); } } if (bundleTypes.contains(Bundle.Type.CURRENCYNAMES)) { Map currencyNamesMap = extractCurrencyNames(targetMap, bundle.getID(), bundle.getCurrencies()); if (!currencyNamesMap.isEmpty() || bundle.isRoot()) { - metaInfo.get("CurrencyNames").add(toLanguageTag(bundle.getID())); - addLikelySubtags(metaInfo, "CurrencyNames", bundle.getID()); bundleGenerator.generateBundle("util", "CurrencyNames", bundle.getJavaID(), true, currencyNamesMap, BundleType.OPEN); } } if (bundleTypes.contains(Bundle.Type.TIMEZONENAMES)) { Map zoneNamesMap = extractZoneNames(targetMap, bundle.getID()); if (!zoneNamesMap.isEmpty() || bundle.isRoot()) { - metaInfo.get("TimeZoneNames").add(toLanguageTag(bundle.getID())); - addLikelySubtags(metaInfo, "TimeZoneNames", bundle.getID()); bundleGenerator.generateBundle("util", "TimeZoneNames", bundle.getJavaID(), true, zoneNamesMap, BundleType.TIMEZONE); } } if (bundleTypes.contains(Bundle.Type.CALENDARDATA)) { Map calendarDataMap = extractCalendarData(targetMap, bundle.getID()); if (!calendarDataMap.isEmpty() || bundle.isRoot()) { - metaInfo.get("CalendarData").add(toLanguageTag(bundle.getID())); - addLikelySubtags(metaInfo, "CalendarData", bundle.getID()); bundleGenerator.generateBundle("util", "CalendarData", bundle.getJavaID(), true, calendarDataMap, BundleType.PLAIN); } } if (bundleTypes.contains(Bundle.Type.FORMATDATA)) { Map formatDataMap = extractFormatData(targetMap, bundle.getID()); if (!formatDataMap.isEmpty() || bundle.isRoot()) { - metaInfo.get("FormatData").add(toLanguageTag(bundle.getID())); - addLikelySubtags(metaInfo, "FormatData", bundle.getID()); bundleGenerator.generateBundle("text", "FormatData", bundle.getJavaID(), true, formatDataMap, BundleType.PLAIN); } } @@ -570,43 +495,9 @@ metaInfo.get("AvailableLocales").add(toLanguageTag(bundle.getID())); addLikelySubtags(metaInfo, "AvailableLocales", bundle.getID()); } - addCldrImplicitLocales(metaInfo); bundleGenerator.generateMetaInfo(metaInfo); } - /** - * These are the Locales that are implicitly supported by CLDR. - * Adding them explicitly as likelySubtags here, will ensure that - * COMPAT locales do not precede them during ResourceBundle search path. - */ - private static void addCldrImplicitLocales(Map> metaInfo) { - metaInfo.get("LocaleNames").add("zh-Hans-CN"); - metaInfo.get("LocaleNames").add("zh-Hans-SG"); - metaInfo.get("LocaleNames").add("zh-Hant-HK"); - metaInfo.get("LocaleNames").add("zh-Hant-MO"); - metaInfo.get("LocaleNames").add("zh-Hant-TW"); - metaInfo.get("CurrencyNames").add("zh-Hans-CN"); - metaInfo.get("CurrencyNames").add("zh-Hans-SG"); - metaInfo.get("CurrencyNames").add("zh-Hant-HK"); - metaInfo.get("CurrencyNames").add("zh-Hant-MO"); - metaInfo.get("CurrencyNames").add("zh-Hant-TW"); - metaInfo.get("TimeZoneNames").add("zh-Hans-CN"); - metaInfo.get("TimeZoneNames").add("zh-Hans-SG"); - metaInfo.get("TimeZoneNames").add("zh-Hant-HK"); - metaInfo.get("TimeZoneNames").add("zh-Hant-MO"); - metaInfo.get("TimeZoneNames").add("zh-Hant-TW"); - metaInfo.get("TimeZoneNames").add("zh-HK"); - metaInfo.get("CalendarData").add("zh-Hans-CN"); - metaInfo.get("CalendarData").add("zh-Hans-SG"); - metaInfo.get("CalendarData").add("zh-Hant-HK"); - metaInfo.get("CalendarData").add("zh-Hant-MO"); - metaInfo.get("CalendarData").add("zh-Hant-TW"); - metaInfo.get("FormatData").add("zh-Hans-CN"); - metaInfo.get("FormatData").add("zh-Hans-SG"); - metaInfo.get("FormatData").add("zh-Hant-HK"); - metaInfo.get("FormatData").add("zh-Hant-MO"); - metaInfo.get("FormatData").add("zh-Hant-TW"); - } static final Map aliases = new HashMap<>(); /** @@ -656,14 +547,6 @@ return Locale.forLanguageTag(id.replaceAll("_", "-")).getCountry(); } - /* - * Returns the script portion of the given id. - * If id is "root", "" is returned. - */ - static String getScript(String id) { - return "root".equals(id) ? "" : Locale.forLanguageTag(id.replaceAll("_", "-")).getScript(); - } - private static class KeyComparator implements Comparator { static KeyComparator INSTANCE = new KeyComparator(); @@ -695,9 +578,25 @@ Map localeNames = new TreeMap<>(KeyComparator.INSTANCE); for (String key : map.keySet()) { if (key.startsWith(LOCALE_NAME_PREFIX)) { - localeNames.put(key.substring(LOCALE_NAME_PREFIX.length()), map.get(key)); + switch (key) { + case LOCALE_SEPARATOR: + localeNames.put("ListCompositionPattern", map.get(key)); + break; + case LOCALE_KEYTYPE: + localeNames.put("ListKeyTypePattern", map.get(key)); + break; + default: + localeNames.put(key.substring(LOCALE_NAME_PREFIX.length()), map.get(key)); + break; + } } } + + if (id.equals("root")) { + // Add display name pattern, which is not in CLDR + localeNames.put("DisplayNamePattern", "{0,choice,0#|1#{1}|2#{1} ({2})}"); + } + return localeNames; } @@ -778,10 +677,30 @@ return names; } + /** + * Extracts the language independent calendar data. Each of the two keys, + * "firstDayOfWeek" and "minimalDaysInFirstWeek" has a string value consists of + * one or multiple occurrences of: + * i: rg1 rg2 ... rgn; + * where "i" is the data for the following regions (delimited by a space) after + * ":", and ends with a ";". + */ private static Map extractCalendarData(Map map, String id) { Map calendarData = new LinkedHashMap<>(); - copyIfPresent(map, "firstDayOfWeek", calendarData); - copyIfPresent(map, "minimalDaysInFirstWeek", calendarData); + if (id.equals("root")) { + calendarData.put("firstDayOfWeek", + IntStream.range(1, 8) + .mapToObj(String::valueOf) + .filter(d -> map.keySet().contains(CALENDAR_FIRSTDAY_PREFIX + d)) + .map(d -> d + ": " + map.get(CALENDAR_FIRSTDAY_PREFIX + d)) + .collect(Collectors.joining(";"))); + calendarData.put("minimalDaysInFirstWeek", + IntStream.range(0, 7) + .mapToObj(String::valueOf) + .filter(d -> map.keySet().contains(CALENDAR_MINDAYS_PREFIX + d)) + .map(d -> d + ": " + map.get(CALENDAR_MINDAYS_PREFIX + d)) + .collect(Collectors.joining(";"))); + } return calendarData; } @@ -844,17 +763,19 @@ for (String key : map.keySet()) { // Copy available calendar names - if (key.startsWith(CLDRConverter.CALENDAR_NAME_PREFIX)) { - String type = key.substring(CLDRConverter.CALENDAR_NAME_PREFIX.length()); + if (key.startsWith(CLDRConverter.LOCALE_TYPE_PREFIX_CA)) { + String type = key.substring(CLDRConverter.LOCALE_TYPE_PREFIX_CA.length()); for (CalendarType calendarType : CalendarType.values()) { if (calendarType == CalendarType.GENERIC) { continue; } if (type.equals(calendarType.lname())) { Object value = map.get(key); - formatData.put(key, value); - String ukey = CLDRConverter.CALENDAR_NAME_PREFIX + calendarType.uname(); - if (!key.equals(ukey)) { + String dataKey = key.replace(LOCALE_TYPE_PREFIX_CA, + CALENDAR_NAME_PREFIX); + formatData.put(dataKey, value); + String ukey = CALENDAR_NAME_PREFIX + calendarType.uname(); + if (!dataKey.equals(ukey)) { formatData.put(ukey, value); } } @@ -874,6 +795,18 @@ copyIfPresent(map, "NumberElements", formatData); } copyIfPresent(map, "NumberPatterns", formatData); + + // put extra number elements for available scripts into formatData, if it is "root" + if (id.equals("root")) { + handlerNumbering.keySet().stream() + .filter(k -> !numberingScripts.contains(k)) + .forEach(k -> { + String[] ne = (String[])map.get("latn.NumberElements"); + String[] neNew = Arrays.copyOf(ne, ne.length); + neNew[4] = handlerNumbering.get(k).substring(0, 1); + formatData.put(k + ".NumberElements", neNew); + }); + } return formatData; } diff -r 907bddce488c -r b6ff245c0db6 make/jdk/src/classes/build/tools/cldrconverter/LDMLParseHandler.java --- a/make/jdk/src/classes/build/tools/cldrconverter/LDMLParseHandler.java Mon Dec 11 16:43:11 2017 +0000 +++ b/make/jdk/src/classes/build/tools/cldrconverter/LDMLParseHandler.java Thu Dec 14 12:28:32 2017 +0000 @@ -76,12 +76,16 @@ // ignore this element - it has language and territory elements that aren't locale data pushIgnoredContainer(qName); break; - case "type": - if ("calendar".equals(attributes.getValue("key"))) { - pushStringEntry(qName, attributes, CLDRConverter.CALENDAR_NAME_PREFIX + attributes.getValue("type")); - } else { - pushIgnoredContainer(qName); - } + + // for LocaleNames + // copy string + case "localeSeparator": + pushStringEntry(qName, attributes, + CLDRConverter.LOCALE_SEPARATOR); + break; + case "localeKeyTypePattern": + pushStringEntry(qName, attributes, + CLDRConverter.LOCALE_KEYTYPE); break; case "language": @@ -96,6 +100,24 @@ attributes.getValue("type")); break; + case "key": + // for LocaleNames + // copy string + pushStringEntry(qName, attributes, + CLDRConverter.LOCALE_KEY_PREFIX + + convertOldKeyName(attributes.getValue("type"))); + break; + + case "type": + // for LocaleNames/CalendarNames + // copy string + pushStringEntry(qName, attributes, + CLDRConverter.LOCALE_TYPE_PREFIX + + convertOldKeyName(attributes.getValue("key")) + "." + + attributes.getValue("type")); + + break; + // // Currency information // @@ -515,26 +537,10 @@ currentNumberingSystem = script + "."; String digits = CLDRConverter.handlerNumbering.get(script); if (digits == null) { - throw new InternalError("null digits for " + script); - } - if (Character.isSurrogate(digits.charAt(0))) { - // DecimalFormatSymbols doesn't support supplementary characters as digit zero. pushIgnoredContainer(qName); break; } - // in case digits are in the reversed order, reverse back the order. - if (digits.charAt(0) > digits.charAt(digits.length() - 1)) { - StringBuilder sb = new StringBuilder(digits); - digits = sb.reverse().toString(); - } - // Check if the order is sequential. - char c0 = digits.charAt(0); - for (int i = 1; i < digits.length(); i++) { - if (digits.charAt(i) != c0 + i) { - pushIgnoredContainer(qName); - break symbols; - } - } + @SuppressWarnings("unchecked") List numberingScripts = (List) get("numberingScripts"); if (numberingScripts == null) { @@ -924,17 +930,35 @@ } } } else if (currentContainer instanceof Entry) { - Entry entry = (Entry) currentContainer; - Object value = entry.getValue(); - if (value != null) { - String key = entry.getKey(); - // Tweak for MonthNames for the root locale, Needed for - // SimpleDateFormat.format()/parse() roundtrip. - if (id.equals("root") && key.startsWith("MonthNames")) { - value = new DateFormatSymbols(Locale.US).getShortMonths(); - } - put(entry.getKey(), value); + Entry entry = (Entry) currentContainer; + Object value = entry.getValue(); + if (value != null) { + String key = entry.getKey(); + // Tweak for MonthNames for the root locale, Needed for + // SimpleDateFormat.format()/parse() roundtrip. + if (id.equals("root") && key.startsWith("MonthNames")) { + value = new DateFormatSymbols(Locale.US).getShortMonths(); } + put(entry.getKey(), value); } } } + + public String convertOldKeyName(String key) { + // Explicitly obtained from "alias" attribute in each "key" element. + switch (key) { + case "calendar": + return "ca"; + case "currency": + return "cu"; + case "collation": + return "co"; + case "numbers": + return "nu"; + case "timezone": + return "tz"; + default: + return key; + } + } +} diff -r 907bddce488c -r b6ff245c0db6 make/jdk/src/classes/build/tools/cldrconverter/NumberingSystemsParseHandler.java --- a/make/jdk/src/classes/build/tools/cldrconverter/NumberingSystemsParseHandler.java Mon Dec 11 16:43:11 2017 +0000 +++ b/make/jdk/src/classes/build/tools/cldrconverter/NumberingSystemsParseHandler.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,9 +54,32 @@ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { switch (qName) { case "numberingSystem": - if ("numeric".equals(attributes.getValue("type"))) { - // eg, - put(attributes.getValue("id"), attributes.getValue("digits")); + numberingSystem: { + if ("numeric".equals(attributes.getValue("type"))) { + // eg, + String script = attributes.getValue("id"); + String digits = attributes.getValue("digits"); + + if (Character.isSurrogate(digits.charAt(0))) { + // DecimalFormatSymbols doesn't support supplementary characters as digit zero. + break numberingSystem; + } + // in case digits are in the reversed order, reverse back the order. + if (digits.charAt(0) > digits.charAt(digits.length() - 1)) { + StringBuilder sb = new StringBuilder(digits); + digits = sb.reverse().toString(); + } + // Check if the order is sequential. + char c0 = digits.charAt(0); + for (int i = 1; i < digits.length(); i++) { + if (digits.charAt(i) != c0 + i) { + break numberingSystem; + } + } + + // script/digits are acceptable. + put(script, digits); + } } pushIgnoredContainer(qName); break; diff -r 907bddce488c -r b6ff245c0db6 make/jdk/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java --- a/make/jdk/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java Mon Dec 11 16:43:11 2017 +0000 +++ b/make/jdk/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -256,20 +256,21 @@ CLDRConverter.info("Generating file " + file); try (PrintWriter out = new PrintWriter(file, "us-ascii")) { - out.println(CopyrightHeaders.getOpenJDKCopyright()); + out.printf(CopyrightHeaders.getOpenJDKCopyright()); - out.println((CLDRConverter.isBaseModule ? "package sun.util.cldr;\n\n" : + out.printf((CLDRConverter.isBaseModule ? "package sun.util.cldr;\n\n" : "package sun.util.resources.cldr.provider;\n\n") + "import java.util.HashMap;\n" + "import java.util.Locale;\n" + "import java.util.Map;\n" - + "import sun.util.locale.provider.LocaleProviderAdapter;\n" - + "import sun.util.locale.provider.LocaleDataMetaInfo;\n"); + + "import sun.util.locale.provider.LocaleDataMetaInfo;\n" + + "import sun.util.locale.provider.LocaleProviderAdapter;\n\n"); out.printf("public class %s implements LocaleDataMetaInfo {\n", className); - out.println(" private static final Map resourceNameToLocales = new HashMap<>();\n" + - (CLDRConverter.isBaseModule ? - " private static final Map parentLocalesMap = new HashMap<>();\n\n" : "\n") + - " static {\n"); + out.printf(" private static final Map resourceNameToLocales = new HashMap<>();\n" + + (CLDRConverter.isBaseModule ? + " private static final Map parentLocalesMap = new HashMap<>();\n\n" : + "\n") + + " static {\n"); for (String key : metaInfo.keySet()) { if (key.startsWith(CLDRConverter.PARENT_LOCALE_PREFIX)) { @@ -296,30 +297,50 @@ } out.printf("\n });\n"); } else { - out.printf(" resourceNameToLocales.put(\"%s\",\n", key); - out.printf(" \"%s\");\n", - toLocaleList(key.equals("FormatData") ? metaInfo.get("AvailableLocales") : - metaInfo.get(key), false)); + if ("AvailableLocales".equals(key)) { + out.printf(" resourceNameToLocales.put(\"%s\",\n", key); + out.printf(" \"%s\");\n", toLocaleList(metaInfo.get(key), false)); + } } } - out.println(" }\n\n"); + + out.printf(" }\n\n"); + + // end of static initializer block. - out.println(" @Override\n" + + // Short TZ names for delayed initialization + if (CLDRConverter.isBaseModule) { + out.printf(" private static class TZShortIDMapHolder {\n"); + out.printf(" static final Map tzShortIDMap = new HashMap<>();\n"); + out.printf(" static {\n"); + CLDRConverter.handlerTimeZone.getData().entrySet().stream() + .forEach(e -> { + out.printf(" tzShortIDMap.put(\"%s\", \"%s\");\n", e.getKey(), + ((String)e.getValue())); + }); + out.printf(" }\n }\n\n"); + } + + out.printf(" @Override\n" + " public LocaleProviderAdapter.Type getType() {\n" + " return LocaleProviderAdapter.Type.CLDR;\n" + " }\n\n"); - out.println(" @Override\n" + + out.printf(" @Override\n" + " public String availableLanguageTags(String category) {\n" + " return resourceNameToLocales.getOrDefault(category, \"\");\n" + " }\n\n"); if (CLDRConverter.isBaseModule) { + out.printf(" @Override\n" + + " public Map tzShortIDs() {\n" + + " return TZShortIDMapHolder.tzShortIDMap;\n" + + " }\n\n"); out.printf(" public Map parentLocales() {\n" + " return parentLocalesMap;\n" + " }\n}"); } else { - out.println("}"); + out.printf("}"); } } } diff -r 907bddce488c -r b6ff245c0db6 make/jdk/src/classes/build/tools/cldrconverter/SupplementDataParseHandler.java --- a/make/jdk/src/classes/build/tools/cldrconverter/SupplementDataParseHandler.java Mon Dec 11 16:43:11 2017 +0000 +++ b/make/jdk/src/classes/build/tools/cldrconverter/SupplementDataParseHandler.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -84,53 +84,18 @@ values.put(CLDRConverter.PARENT_LOCALE_PREFIX+key, parentLocalesMap.get(key)); }); - } else { - String countryData = getWeekData(id, JAVA_FIRSTDAY, firstDayMap); - if (countryData != null) { - values.put(JAVA_FIRSTDAY, countryData); - } - String minDaysData = getWeekData(id, JAVA_MINDAY, minDaysMap); - if (minDaysData != null) { - values.put(JAVA_MINDAY, minDaysData); - } + firstDayMap.keySet().forEach(key -> { + values.put(CLDRConverter.CALENDAR_FIRSTDAY_PREFIX+firstDayMap.get(key), + key); + }); + minDaysMap.keySet().forEach(key -> { + values.put(CLDRConverter.CALENDAR_MINDAYS_PREFIX+minDaysMap.get(key), + key); + }); } return values.isEmpty() ? null : values; } - /** - * It returns either firstDay or minDays in the JRE format for the country. - * - * @param country territory code of the requested data - * @param jreDataName JAVA_FIRSTDAY or JAVA_MINDAY - * @param dataMap firstDayMap or minDaysMap - * @return the value for the given jreDataName, or null if requested value - * (firstDay/minDays) is not available although that is highly unlikely - * because of the default value for the world (001). - */ - String getWeekData(String country, final String jreDataName, final Map dataMap) { - String countryValue = null; - String defaultWorldValue = null; - for (String key : dataMap.keySet()) { - if (key.contains(country)) { - if (jreDataName.equals(JAVA_FIRSTDAY)) { - countryValue = DAY_OF_WEEK_MAP.get((String) dataMap.get(key)); - } else if (jreDataName.equals(JAVA_MINDAY)) { - countryValue = (String) dataMap.get(key); - } - if (countryValue != null) { - return countryValue; - } - } else if (key.contains(WORLD)) { - if (jreDataName.equals(JAVA_FIRSTDAY)) { - defaultWorldValue = DAY_OF_WEEK_MAP.get((String) dataMap.get(key)); - } else if (jreDataName.equals(JAVA_MINDAY)) { - defaultWorldValue = (String) dataMap.get(key); - } - } - } - return defaultWorldValue; - } - @Override public InputSource resolveEntity(String publicID, String systemID) throws IOException, SAXException { // avoid HTTP traffic to unicode.org @@ -152,7 +117,33 @@ switch (qName) { case "firstDay": if (!isIgnored(attributes)) { - firstDayMap.put(attributes.getValue("territories"), attributes.getValue("day")); + String fd; + + switch (attributes.getValue("day")) { + case "sun": + fd = "1"; + break; + default: + case "mon": + fd = "2"; + break; + case "tue": + fd = "3"; + break; + case "wed": + fd = "4"; + break; + case "thu": + fd = "5"; + break; + case "fri": + fd = "6"; + break; + case "sat": + fd = "7"; + break; + } + firstDayMap.put(attributes.getValue("territories"), fd); } break; case "minDays": diff -r 907bddce488c -r b6ff245c0db6 make/jdk/src/classes/build/tools/cldrconverter/TimeZoneParseHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/jdk/src/classes/build/tools/cldrconverter/TimeZoneParseHandler.java Thu Dec 14 12:28:32 2017 +0000 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package build.tools.cldrconverter; + +import java.io.File; +import java.io.IOException; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * Handles parsing of timezone.xml and produces a map from short timezone IDs to + * tz database IDs. + */ + +class TimeZoneParseHandler extends AbstractLDMLHandler { + + @Override + public InputSource resolveEntity(String publicID, String systemID) throws IOException, SAXException { + // avoid HTTP traffic to unicode.org + if (systemID.startsWith(CLDRConverter.BCP47_LDML_DTD_SYSTEM_ID)) { + return new InputSource((new File(CLDRConverter.LOCAL_BCP47_LDML_DTD)).toURI().toString()); + } + return null; + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + switch (qName) { + case "type": + if (!isIgnored(attributes) && !attributes.getValue("deprecated").equals("true")) { + put(attributes.getValue("name"), attributes.getValue("alias")); + } + break; + default: + // treat anything else as a container + pushContainer(qName, attributes); + break; + } + } +} diff -r 907bddce488c -r b6ff245c0db6 make/jprt.properties --- a/make/jprt.properties Mon Dec 11 16:43:11 2017 +0000 +++ b/make/jprt.properties Thu Dec 14 12:28:32 2017 +0000 @@ -177,6 +177,7 @@ # Not all test targets need the test image jprt.test.bundle.targets=\ + ${my.make.rule.test.targets.svc}, \ ${my.make.rule.test.targets.hotspot.reg}, \ ${my.make.rule.test.targets.hotspot.gtest} \ ${my.make.rule.test.targets.nativesanity} \ diff -r 907bddce488c -r b6ff245c0db6 make/lib/Awt2dLibraries.gmk --- a/make/lib/Awt2dLibraries.gmk Mon Dec 11 16:43:11 2017 +0000 +++ b/make/lib/Awt2dLibraries.gmk Thu Dec 14 12:28:32 2017 +0000 @@ -681,7 +681,7 @@ DISABLED_WARNINGS_CXX_solstudio := \ truncwarn wvarhidenmem wvarhidemem wbadlkginit identexpected \ hidevf w_novirtualdescr arrowrtn2, \ - DISABLED_WARNINGS_microsoft := 4267 4244 4018 4090 4996 4146 4334 4819, \ + DISABLED_WARNINGS_microsoft := 4267 4244 4018 4090 4996 4146 4334 4819 4101, \ MAPFILE := $(BUILD_LIBFONTMANAGER_MAPFILE), \ LDFLAGS := $(subst -Wl$(COMMA)-z$(COMMA)defs,,$(LDFLAGS_JDKLIB)) $(LDFLAGS_CXX_JDK) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ diff -r 907bddce488c -r b6ff245c0db6 make/lib/Lib-java.management.gmk --- a/make/lib/Lib-java.management.gmk Mon Dec 11 16:43:11 2017 +0000 +++ b/make/lib/Lib-java.management.gmk Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -30,8 +30,8 @@ ################################################################################ -LIBMANAGEMENT_SRC += $(TOPDIR)/src/java.management/share/native/libmanagement -LIBMANAGEMENT_CFLAGS := -I$(TOPDIR)/src/java.management/share/native/include \ +LIBMANAGEMENT_SRC += $(TOPDIR)/src/java.management/share/native/libmanagement +LIBMANAGEMENT_CFLAGS := -I$(TOPDIR)/src/hotspot/share/include \ $(addprefix -I,$(LIBMANAGEMENT_SRC)) \ -I$(SUPPORT_OUTPUTDIR)/headers/java.management \ $(LIBJAVA_HEADER_FLAGS) \ diff -r 907bddce488c -r b6ff245c0db6 make/mapfiles/libjava/mapfile-vers --- a/make/mapfiles/libjava/mapfile-vers Mon Dec 11 16:43:11 2017 +0000 +++ b/make/mapfiles/libjava/mapfile-vers Thu Dec 14 12:28:32 2017 +0000 @@ -74,7 +74,7 @@ JNU_ThrowStringIndexOutOfBoundsException; JNU_ToString; - Java_java_io_FileDescriptor_close; + Java_java_io_FileDescriptor_close0; Java_java_io_FileDescriptor_initIDs; Java_java_io_FileDescriptor_sync; Java_java_io_FileDescriptor_getAppend; diff -r 907bddce488c -r b6ff245c0db6 make/nashorn/build.xml --- a/make/nashorn/build.xml Mon Dec 11 16:43:11 2017 +0000 +++ b/make/nashorn/build.xml Thu Dec 14 12:28:32 2017 +0000 @@ -265,7 +265,7 @@ - + diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp --- a/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -36,6 +36,7 @@ #include "gc/shared/cardTableModRefBS.hpp" #include "nativeInst_ppc.hpp" #include "oops/objArrayKlass.hpp" +#include "runtime/safepointMechanism.inline.hpp" #include "runtime/sharedRuntime.hpp" #define __ _masm-> @@ -1314,11 +1315,10 @@ __ pop_frame(); } - if (LoadPollAddressFromThread) { - // TODO: PPC port __ ld(polling_page, in_bytes(JavaThread::poll_address_offset()), R16_thread); - Unimplemented(); + if (SafepointMechanism::uses_thread_local_poll()) { + __ ld(polling_page, in_bytes(Thread::polling_page_offset()), R16_thread); } else { - __ load_const_optimized(polling_page, (long)(address) os::get_polling_page(), R0); // TODO: PPC port: get_standard_polling_page() + __ load_const_optimized(polling_page, (long)(address) os::get_polling_page(), R0); } // Restore return pc relative to callers' sp. @@ -1341,26 +1341,18 @@ int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) { - - if (LoadPollAddressFromThread) { - const Register poll_addr = tmp->as_register(); - // TODO: PPC port __ ld(poll_addr, in_bytes(JavaThread::poll_address_offset()), R16_thread); - Unimplemented(); - __ relocate(relocInfo::poll_type); // XXX - guarantee(info != NULL, "Shouldn't be NULL"); - int offset = __ offset(); - add_debug_info_for_branch(info); - __ load_from_polling_page(poll_addr); - return offset; + const Register poll_addr = tmp->as_register(); + if (SafepointMechanism::uses_thread_local_poll()) { + __ ld(poll_addr, in_bytes(Thread::polling_page_offset()), R16_thread); + } else { + __ load_const_optimized(poll_addr, (intptr_t)os::get_polling_page(), R0); } - - __ load_const_optimized(tmp->as_register(), (intptr_t)os::get_polling_page(), R0); // TODO: PPC port: get_standard_polling_page() if (info != NULL) { add_debug_info_for_branch(info); } int offset = __ offset(); __ relocate(relocInfo::poll_type); - __ load_from_polling_page(tmp->as_register()); + __ load_from_polling_page(poll_addr); return offset; } diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp --- a/src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp Thu Dec 14 12:28:32 2017 +0000 @@ -54,4 +54,6 @@ #define SUPPORT_RESERVED_STACK_AREA +#define THREAD_LOCAL_POLL + #endif // CPU_PPC_VM_GLOBALDEFINITIONS_PPC_HPP diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/ppc/globals_ppc.hpp --- a/src/hotspot/cpu/ppc/globals_ppc.hpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/ppc/globals_ppc.hpp Thu Dec 14 12:28:32 2017 +0000 @@ -83,7 +83,7 @@ // 2x unrolled loop is shorter with more than 9 HeapWords. define_pd_global(intx, InitArrayShortSize, 9*BytesPerLong); -define_pd_global(bool, ThreadLocalHandshakes, false); +define_pd_global(bool, ThreadLocalHandshakes, true); // Platform dependent flag handling: flags only defined on this platform. #define ARCH_FLAGS(develop, \ @@ -95,12 +95,6 @@ constraint, \ writeable) \ \ - /* Load poll address from thread. This is used to implement per-thread */ \ - /* safepoints on platforms != IA64. */ \ - product(bool, LoadPollAddressFromThread, false, \ - "Load polling page address from thread object (required for " \ - "per-thread safepoints on platforms != IA64)") \ - \ product(uintx, PowerArchitecturePPC64, 0, \ "CPU Version: x for PowerX. Currently recognizes Power5 to " \ "Power8. Default is 0. Newer CPUs will be recognized as Power8.") \ diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/ppc/interp_masm_ppc.hpp --- a/src/hotspot/cpu/ppc/interp_masm_ppc.hpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/ppc/interp_masm_ppc.hpp Thu Dec 14 12:28:32 2017 +0000 @@ -57,10 +57,10 @@ static const Address d_tmp; // dispatch routines - void dispatch_next(TosState state, int step = 0); + void dispatch_next(TosState state, int step = 0, bool generate_poll = false); void dispatch_via (TosState state, address* table); void load_dispatch_table(Register dst, address* table); - void dispatch_Lbyte_code(TosState state, Register bytecode, address* table, bool verify = false); + void dispatch_Lbyte_code(TosState state, Register bytecode, address* table, bool generate_poll = false); // Called by shared interpreter generator. void dispatch_prolog(TosState state, int step = 0); diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp --- a/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -29,6 +29,7 @@ #include "interp_masm_ppc.hpp" #include "interpreter/interpreterRuntime.hpp" #include "prims/jvmtiThreadState.hpp" +#include "runtime/safepointMechanism.hpp" #include "runtime/sharedRuntime.hpp" #ifdef PRODUCT @@ -53,7 +54,7 @@ } } -void InterpreterMacroAssembler::dispatch_next(TosState state, int bcp_incr) { +void InterpreterMacroAssembler::dispatch_next(TosState state, int bcp_incr, bool generate_poll) { Register bytecode = R12_scratch2; if (bcp_incr != 0) { lbzu(bytecode, bcp_incr, R14_bcp); @@ -61,7 +62,7 @@ lbz(bytecode, 0, R14_bcp); } - dispatch_Lbyte_code(state, bytecode, Interpreter::dispatch_table(state)); + dispatch_Lbyte_code(state, bytecode, Interpreter::dispatch_table(state), generate_poll); } void InterpreterMacroAssembler::dispatch_via(TosState state, address* table) { @@ -203,16 +204,26 @@ } void InterpreterMacroAssembler::dispatch_Lbyte_code(TosState state, Register bytecode, - address* table, bool verify) { - if (verify) { - unimplemented("dispatch_Lbyte_code: verify"); // See Sparc Implementation to implement this - } - + address* table, bool generate_poll) { assert_different_registers(bytecode, R11_scratch1); // Calc dispatch table address. load_dispatch_table(R11_scratch1, table); + if (SafepointMechanism::uses_thread_local_poll() && generate_poll) { + address *sfpt_tbl = Interpreter::safept_table(state); + if (table != sfpt_tbl) { + Label dispatch; + ld(R0, in_bytes(Thread::polling_page_offset()), R16_thread); + // Armed page has poll_bit set, if poll bit is cleared just continue. + andi_(R0, R0, SafepointMechanism::poll_bit()); + beq(CCR0, dispatch); + load_dispatch_table(R11_scratch1, sfpt_tbl); + align(32, 16); + bind(dispatch); + } + } + sldi(R12_scratch2, bytecode, LogBytesPerWord); ldx(R11_scratch1, R11_scratch1, R12_scratch2); diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/ppc/macroAssembler_ppc.cpp --- a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -37,6 +37,8 @@ #include "runtime/interfaceSupport.hpp" #include "runtime/objectMonitor.hpp" #include "runtime/os.hpp" +#include "runtime/safepoint.hpp" +#include "runtime/safepointMechanism.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/stubRoutines.hpp" #include "utilities/macros.hpp" @@ -3019,6 +3021,18 @@ stwx(R0, tmp1, tmp2); } +void MacroAssembler::safepoint_poll(Label& slow_path, Register temp_reg) { + if (SafepointMechanism::uses_thread_local_poll()) { + ld(temp_reg, in_bytes(Thread::polling_page_offset()), R16_thread); + // Armed page has poll_bit set. + andi_(temp_reg, temp_reg, SafepointMechanism::poll_bit()); + } else { + lwz(temp_reg, (RegisterOrConstant)(intptr_t)SafepointSynchronize::address_of_state()); + cmpwi(CCR0, temp_reg, SafepointSynchronize::_not_synchronized); + } + bne(CCR0, slow_path); +} + // GC barrier helper macros diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/ppc/macroAssembler_ppc.hpp --- a/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp Thu Dec 14 12:28:32 2017 +0000 @@ -647,6 +647,9 @@ // Support for serializing memory accesses between threads void serialize_memory(Register thread, Register tmp1, Register tmp2); + // Check if safepoint requested and if so branch + void safepoint_poll(Label& slow_path, Register temp_reg); + // GC barrier support. void card_write_barrier_post(Register Rstore_addr, Register Rnew_val, Register Rtmp); void card_table_write(jbyte* byte_map_base, Register Rtmp, Register Robj); diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/ppc/ppc.ad --- a/src/hotspot/cpu/ppc/ppc.ad Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/ppc/ppc.ad Thu Dec 14 12:28:32 2017 +0000 @@ -1577,11 +1577,10 @@ } if (method_needs_polling) { - if (LoadPollAddressFromThread) { - // TODO: PPC port __ ld(polling_page, in_bytes(JavaThread::poll_address_offset()), R16_thread); - Unimplemented(); + if (SafepointMechanism::uses_thread_local_poll()) { + __ ld(polling_page, in_bytes(JavaThread::polling_page_offset()), R16_thread); } else { - __ load_const_optimized(polling_page, (long)(address) os::get_polling_page()); // TODO: PPC port: get_standard_polling_page() + __ load_const_optimized(polling_page, (long)(address) os::get_polling_page()); } } @@ -14147,7 +14146,6 @@ instruct safePoint_poll(iRegPdst poll) %{ match(SafePoint poll); - predicate(LoadPollAddressFromThread); // It caused problems to add the effect that r0 is killed, but this // effect no longer needs to be mentioned, since r0 is not contained @@ -14159,24 +14157,6 @@ ins_pipe(pipe_class_default); %} -// Safepoint without per-thread support. Load address of page to poll -// as constant. -// Rscratch2RegP is R12. -// LoadConPollAddr node is added in pd_post_matching_hook(). It must be -// a seperate node so that the oop map is at the right location. -instruct safePoint_poll_conPollAddr(rscratch2RegP poll) %{ - match(SafePoint poll); - predicate(!LoadPollAddressFromThread); - - // It caused problems to add the effect that r0 is killed, but this - // effect no longer needs to be mentioned, since r0 is not contained - // in a reg_class. - - format %{ "LD R0, #0, R12 \t// Safepoint poll for GC" %} - ins_encode( enc_poll(0x0, poll) ); - ins_pipe(pipe_class_default); -%} - // ============================================================================ // Call Instructions diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp --- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -214,6 +214,7 @@ // StackFrameStream construction (needed for deoptimization; see // compiledVFrame::create_stack_value). // If return_pc_adjustment != 0 adjust the return pc by return_pc_adjustment. + // Updated return pc is returned in R31 (if not return_pc_is_pre_saved). int i; int offset; @@ -233,16 +234,17 @@ BLOCK_COMMENT("push_frame_reg_args_and_save_live_registers {"); - // Save r31 in the last slot of the not yet pushed frame so that we - // can use it as scratch reg. - __ std(R31, -reg_size, R1_SP); + // Save some registers in the last slots of the not yet pushed frame so that we + // can use them as scratch regs. + __ std(R31, - reg_size, R1_SP); + __ std(R30, -2*reg_size, R1_SP); assert(-reg_size == register_save_offset - frame_size_in_bytes + ((regstosave_num-1)*reg_size), "consistency check"); // save the flags // Do the save_LR_CR by hand and adjust the return pc if requested. - __ mfcr(R31); - __ std(R31, _abi(cr), R1_SP); + __ mfcr(R30); + __ std(R30, _abi(cr), R1_SP); switch (return_pc_location) { case return_pc_is_lr: __ mflr(R31); break; case return_pc_is_pre_saved: assert(return_pc_adjustment == 0, "unsupported"); break; @@ -257,7 +259,7 @@ } // push a new frame - __ push_frame(frame_size_in_bytes, R31); + __ push_frame(frame_size_in_bytes, R30); // save all registers (ints and floats) offset = register_save_offset; @@ -267,7 +269,7 @@ switch (reg_type) { case RegisterSaver::int_reg: { - if (reg_num != 31) { // We spilled R31 right at the beginning. + if (reg_num < 30) { // We spilled R30-31 right at the beginning. __ std(as_Register(reg_num), offset, R1_SP); } break; @@ -278,8 +280,8 @@ } case RegisterSaver::special_reg: { if (reg_num == SR_CTR_SpecialRegisterEnumValue) { - __ mfctr(R31); - __ std(R31, offset, R1_SP); + __ mfctr(R30); + __ std(R30, offset, R1_SP); } else { Unimplemented(); } @@ -2364,23 +2366,14 @@ Register sync_state = r_temp_5; Register suspend_flags = r_temp_6; - __ load_const(sync_state_addr, SafepointSynchronize::address_of_state(), /*temp*/ sync_state); - - // TODO: PPC port assert(4 == SafepointSynchronize::sz_state(), "unexpected field size"); - __ lwz(sync_state, 0, sync_state_addr); - + // No synchronization in progress nor yet synchronized + // (cmp-br-isync on one path, release (same as acquire on PPC64) on the other path). + __ safepoint_poll(sync, sync_state); + + // Not suspended. // TODO: PPC port assert(4 == Thread::sz_suspend_flags(), "unexpected field size"); __ lwz(suspend_flags, thread_(suspend_flags)); - - __ acquire(); - - Label do_safepoint; - // No synchronization in progress nor yet synchronized. - __ cmpwi(CCR0, sync_state, SafepointSynchronize::_not_synchronized); - // Not suspended. __ cmpwi(CCR1, suspend_flags, 0); - - __ bne(CCR0, sync); __ beq(CCR1, no_block); // Block. Save any potential method result value before the operation and @@ -2388,6 +2381,7 @@ // lets us share the oopMap we used when we went native rather than create // a distinct one for this pc. __ bind(sync); + __ isync(); address entry_point = is_critical_native ? CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans_and_transition) @@ -2410,7 +2404,7 @@ // Transition from _thread_in_native_trans to _thread_in_Java. __ li(R0, _thread_in_Java); - __ release(); + __ lwsync(); // Acquire safepoint and suspend state, release thread state. // TODO: PPC port assert(4 == JavaThread::sz_thread_state(), "unexpected field size"); __ stw(R0, thread_(thread_state)); __ bind(after_transition); @@ -3093,7 +3087,7 @@ return_pc_location = RegisterSaver::return_pc_is_thread_saved_exception_pc; } - // Save registers, fpu state, and flags. + // Save registers, fpu state, and flags. Set R31 = return pc. map = RegisterSaver::push_frame_reg_args_and_save_live_registers(masm, &frame_size_in_bytes, /*generate_oop_map=*/ true, @@ -3142,6 +3136,19 @@ // No exception case. __ BIND(noException); + if (SafepointMechanism::uses_thread_local_poll() && !cause_return) { + Label no_adjust; + // If our stashed return pc was modified by the runtime we avoid touching it + __ ld(R0, frame_size_in_bytes + _abi(lr), R1_SP); + __ cmpd(CCR0, R0, R31); + __ bne(CCR0, no_adjust); + + // Adjust return pc forward to step over the safepoint poll instruction + __ addi(R31, R31, 4); + __ std(R31, frame_size_in_bytes + _abi(lr), R1_SP); + + __ bind(no_adjust); + } // Normal exit, restore registers and exit. RegisterSaver::restore_live_registers_and_pop_frame(masm, diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp --- a/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -1535,23 +1535,17 @@ // Acquire isn't strictly necessary here because of the fence, but // sync_state is declared to be volatile, so we do it anyway // (cmp-br-isync on one path, release (same as acquire on PPC64) on the other path). - int sync_state_offs = __ load_const_optimized(sync_state_addr, SafepointSynchronize::address_of_state(), /*temp*/R0, true); - // TODO PPC port assert(4 == SafepointSynchronize::sz_state(), "unexpected field size"); - __ lwz(sync_state, sync_state_offs, sync_state_addr); + Label do_safepoint, sync_check_done; + // No synchronization in progress nor yet synchronized. + __ safepoint_poll(do_safepoint, sync_state); + // Not suspended. // TODO PPC port assert(4 == Thread::sz_suspend_flags(), "unexpected field size"); __ lwz(suspend_flags, thread_(suspend_flags)); + __ cmpwi(CCR1, suspend_flags, 0); + __ beq(CCR1, sync_check_done); - Label sync_check_done; - Label do_safepoint; - // No synchronization in progress nor yet synchronized. - __ cmpwi(CCR0, sync_state, SafepointSynchronize::_not_synchronized); - // Not suspended. - __ cmpwi(CCR1, suspend_flags, 0); - - __ bne(CCR0, do_safepoint); - __ beq(CCR1, sync_check_done); __ bind(do_safepoint); __ isync(); // Block. We do the call directly and leave the current @@ -1592,7 +1586,7 @@ // we don't want the current thread to continue until all our prior memory // accesses (including the new thread state) are visible to other threads. __ li(R0/*thread_state*/, _thread_in_Java); - __ release(); + __ lwsync(); // Acquire safepoint and suspend state, release thread state. __ stw(R0/*thread_state*/, thread_(thread_state)); if (CheckJNICalls) { @@ -1858,10 +1852,7 @@ // Safepoint check const Register sync_state = R11_scratch1; - int sync_state_offs = __ load_const_optimized(sync_state, SafepointSynchronize::address_of_state(), /*temp*/R0, true); - __ lwz(sync_state, sync_state_offs, sync_state); - __ cmpwi(CCR0, sync_state, SafepointSynchronize::_not_synchronized); - __ bne(CCR0, slow_path); + __ safepoint_poll(slow_path, sync_state); // We don't generate local frame and don't align stack because // we not even call stub code (we generate the code inline) @@ -1918,10 +1909,7 @@ // Safepoint check const Register sync_state = R11_scratch1; - int sync_state_offs = __ load_const_optimized(sync_state, SafepointSynchronize::address_of_state(), /*temp*/R0, true); - __ lwz(sync_state, sync_state_offs, sync_state); - __ cmpwi(CCR0, sync_state, SafepointSynchronize::_not_synchronized); - __ bne(CCR0, slow_path); + __ safepoint_poll(slow_path, sync_state); // We don't generate local frame and don't align stack because // we not even call stub code (we generate the code inline) diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/ppc/templateTable_ppc_64.cpp --- a/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -1630,7 +1630,7 @@ // Push returnAddress for "ret" on stack. __ push_ptr(R17_tos); // And away we go! - __ dispatch_next(vtos); + __ dispatch_next(vtos, 0 ,true); return; } @@ -1643,7 +1643,6 @@ const bool increment_invocation_counter_for_backward_branches = UseCompiler && UseLoopCounter; if (increment_invocation_counter_for_backward_branches) { Label Lforward; - __ dispatch_prolog(vtos); // Check branch direction. __ cmpdi(CCR0, Rdisp, 0); @@ -1744,11 +1743,8 @@ } __ bind(Lforward); - __ dispatch_epilog(vtos); - - } else { - __ dispatch_next(vtos); } + __ dispatch_next(vtos, 0, true); } // Helper function for if_cmp* methods below. @@ -1829,7 +1825,7 @@ __ ld(R11_scratch1, in_bytes(Method::const_offset()), R19_method); __ add(R11_scratch1, R17_tos, R11_scratch1); __ addi(R14_bcp, R11_scratch1, in_bytes(ConstMethod::codes_offset())); - __ dispatch_next(vtos); + __ dispatch_next(vtos, 0, true); } void TemplateTable::wide_ret() { @@ -1846,7 +1842,7 @@ __ ld(Rscratch1, in_bytes(Method::const_offset()), R19_method); __ addi(Rscratch2, R17_tos, in_bytes(ConstMethod::codes_offset())); __ add(R14_bcp, Rscratch1, Rscratch2); - __ dispatch_next(vtos); + __ dispatch_next(vtos, 0, true); } void TemplateTable::tableswitch() { @@ -1896,7 +1892,7 @@ __ bind(Ldispatch); __ add(R14_bcp, Roffset, R14_bcp); - __ dispatch_next(vtos); + __ dispatch_next(vtos, 0, true); } void TemplateTable::lookupswitch() { @@ -1960,7 +1956,7 @@ __ bind(Lcontinue_execution); __ add(R14_bcp, Roffset, R14_bcp); - __ dispatch_next(vtos); + __ dispatch_next(vtos, 0, true); } // Table switch using binary search (value/offset pairs are ordered). @@ -2093,7 +2089,7 @@ __ extsw(Rj, Rj); __ add(R14_bcp, Rj, R14_bcp); - __ dispatch_next(vtos); + __ dispatch_next(vtos, 0 , true); } void TemplateTable::_return(TosState state) { @@ -2124,6 +2120,17 @@ __ bind(Lskip_register_finalizer); } + if (SafepointMechanism::uses_thread_local_poll() && _desc->bytecode() != Bytecodes::_return_register_finalizer) { + Label no_safepoint; + __ ld(R11_scratch1, in_bytes(Thread::polling_page_offset()), R16_thread); + __ andi_(R11_scratch1, R11_scratch1, SafepointMechanism::poll_bit()); + __ beq(CCR0, no_safepoint); + __ push(state); + __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)); + __ pop(state); + __ bind(no_safepoint); + } + // Move the result value into the correct register and remove memory stack frame. __ remove_activation(state, /* throw_monitor_exception */ true); // Restoration of lr done by remove_activation. diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/s390/assembler_s390.hpp --- a/src/hotspot/cpu/s390/assembler_s390.hpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/s390/assembler_s390.hpp Thu Dec 14 12:28:32 2017 +0000 @@ -1459,6 +1459,10 @@ bcondLogNotZero = bcondLogNotZero_Carry | bcondLogNotZero_NoCarry, bcondLogCarry = bcondLogZero_Carry | bcondLogNotZero_Carry, bcondLogBorrow = /* bcondLogZero_Borrow | */ bcondLogNotZero_Borrow, + // Vector compare instructions + bcondVAlltrue = 8, // All vector elements evaluate true + bcondVMixed = 4, // Some vector elements evaluate true, some false + bcondVAllfalse = 1, // All vector elements evaluate false // string search instructions bcondFound = 4, bcondNotFound = 2, @@ -3022,6 +3026,12 @@ inline void z_btrue( Label& L); inline void z_bfalse(Label& L); + inline void z_bvat(Label& L); // all true + inline void z_bvnt(Label& L); // not all true (mixed or all false) + inline void z_bvmix(Label& L); // mixed true and false + inline void z_bvaf(Label& L); // not all false (mixed or all true) + inline void z_bvnf(Label& L); // all false + inline void z_brno( Label& L); diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/s390/assembler_s390.inline.hpp --- a/src/hotspot/cpu/s390/assembler_s390.inline.hpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/s390/assembler_s390.inline.hpp Thu Dec 14 12:28:32 2017 +0000 @@ -1315,23 +1315,28 @@ inline void Assembler::z_exrl(Register r1, Label& L) { z_exrl(r1, target(L)); } // z10 inline void Assembler::z_larl(Register r1, Label& L) { z_larl(r1, target(L)); } -inline void Assembler::z_bru( Label& L) { z_brc(bcondAlways,target(L)); } -inline void Assembler::z_brul( Label& L) { z_brcl(bcondAlways,target(L)); } -inline void Assembler::z_brul( address a) { z_brcl(bcondAlways,a); } -inline void Assembler::z_brh( Label& L) { z_brc(bcondHigh,target(L)); } -inline void Assembler::z_brl( Label& L) { z_brc(bcondLow,target(L)); } -inline void Assembler::z_bre( Label& L) { z_brc(bcondEqual,target(L)); } -inline void Assembler::z_brnh( Label& L) { z_brc(bcondNotHigh,target(L)); } -inline void Assembler::z_brnl( Label& L) { z_brc(bcondNotLow,target(L)); } -inline void Assembler::z_brne( Label& L) { z_brc(bcondNotEqual,target(L)); } -inline void Assembler::z_brz( Label& L) { z_brc(bcondZero,target(L)); } -inline void Assembler::z_brnz( Label& L) { z_brc(bcondNotZero,target(L)); } -inline void Assembler::z_braz( Label& L) { z_brc(bcondAllZero,target(L)); } -inline void Assembler::z_brnaz( Label& L) { z_brc(bcondNotAllZero,target(L)); } +inline void Assembler::z_bru( Label& L) { z_brc(bcondAlways, target(L)); } +inline void Assembler::z_brul( Label& L) { z_brcl(bcondAlways, target(L)); } +inline void Assembler::z_brul( address a) { z_brcl(bcondAlways,a ); } +inline void Assembler::z_brh( Label& L) { z_brc(bcondHigh, target(L)); } +inline void Assembler::z_brl( Label& L) { z_brc(bcondLow, target(L)); } +inline void Assembler::z_bre( Label& L) { z_brc(bcondEqual, target(L)); } +inline void Assembler::z_brnh( Label& L) { z_brc(bcondNotHigh, target(L)); } +inline void Assembler::z_brnl( Label& L) { z_brc(bcondNotLow, target(L)); } +inline void Assembler::z_brne( Label& L) { z_brc(bcondNotEqual, target(L)); } +inline void Assembler::z_brz( Label& L) { z_brc(bcondZero, target(L)); } +inline void Assembler::z_brnz( Label& L) { z_brc(bcondNotZero, target(L)); } +inline void Assembler::z_braz( Label& L) { z_brc(bcondAllZero, target(L)); } +inline void Assembler::z_brnaz( Label& L) { z_brc(bcondNotAllZero, target(L)); } inline void Assembler::z_brnp( Label& L) { z_brc( bcondNotPositive, target( L)); } -inline void Assembler::z_btrue( Label& L) { z_brc(bcondAllOne,target(L)); } -inline void Assembler::z_bfalse(Label& L) { z_brc(bcondAllZero,target(L)); } -inline void Assembler::z_brno( Label& L) { z_brc(bcondNotOrdered,target(L)); } +inline void Assembler::z_btrue( Label& L) { z_brc(bcondAllOne, target(L)); } +inline void Assembler::z_bfalse(Label& L) { z_brc(bcondAllZero, target(L)); } +inline void Assembler::z_bvat( Label& L) { z_brc(bcondVAlltrue, target(L)); } +inline void Assembler::z_bvnt( Label& L) { z_brc((Assembler::branch_condition)(bcondVMixed | bcondVAllfalse), target(L)); } +inline void Assembler::z_bvmix( Label& L) { z_brc(bcondVMixed, target(L)); } +inline void Assembler::z_bvaf( Label& L) { z_brc(bcondVAllfalse, target(L)); } +inline void Assembler::z_bvnf( Label& L) { z_brc((Assembler::branch_condition)(bcondVMixed | bcondVAlltrue), target(L)); } +inline void Assembler::z_brno( Label& L) { z_brc(bcondNotOrdered, target(L)); } inline void Assembler::z_brc( branch_condition m, Label& L) { z_brc(m, target(L)); } inline void Assembler::z_brcl(branch_condition m, Label& L) { z_brcl(m, target(L)); } diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp --- a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -36,6 +36,7 @@ #include "gc/shared/cardTableModRefBS.hpp" #include "nativeInst_s390.hpp" #include "oops/objArrayKlass.hpp" +#include "runtime/safepointMechanism.inline.hpp" #include "runtime/sharedRuntime.hpp" #include "vmreg_s390.inline.hpp" @@ -1135,8 +1136,12 @@ (result->is_single_fpu() && result->as_float_reg() == Z_F0) || (result->is_double_fpu() && result->as_double_reg() == Z_F0), "convention"); - AddressLiteral pp(os::get_polling_page()); - __ load_const_optimized(Z_R1_scratch, pp); + if (SafepointMechanism::uses_thread_local_poll()) { + __ z_lg(Z_R1_scratch, Address(Z_thread, Thread::polling_page_offset())); + } else { + AddressLiteral pp(os::get_polling_page()); + __ load_const_optimized(Z_R1_scratch, pp); + } // Pop the frame before the safepoint code. __ pop_frame_restore_retPC(initial_frame_size_in_bytes()); @@ -1154,13 +1159,18 @@ } int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) { - AddressLiteral pp(os::get_polling_page()); - __ load_const_optimized(tmp->as_register_lo(), pp); + const Register poll_addr = tmp->as_register_lo(); + if (SafepointMechanism::uses_thread_local_poll()) { + __ z_lg(poll_addr, Address(Z_thread, Thread::polling_page_offset())); + } else { + AddressLiteral pp(os::get_polling_page()); + __ load_const_optimized(poll_addr, pp); + } guarantee(info != NULL, "Shouldn't be NULL"); add_debug_info_for_branch(info); int offset = __ offset(); __ relocate(relocInfo::poll_type); - __ load_from_polling_page(tmp->as_register_lo()); + __ load_from_polling_page(poll_addr); return offset; } diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/s390/globalDefinitions_s390.hpp --- a/src/hotspot/cpu/s390/globalDefinitions_s390.hpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/s390/globalDefinitions_s390.hpp Thu Dec 14 12:28:32 2017 +0000 @@ -54,4 +54,6 @@ #define SUPPORT_RESERVED_STACK_AREA +#define THREAD_LOCAL_POLL + #endif // CPU_S390_VM_GLOBALDEFINITIONS_S390_HPP diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/s390/globals_s390.hpp --- a/src/hotspot/cpu/s390/globals_s390.hpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/s390/globals_s390.hpp Thu Dec 14 12:28:32 2017 +0000 @@ -85,7 +85,7 @@ // 8146801 (Short Array Allocation): No performance work done here yet. define_pd_global(intx, InitArrayShortSize, 1*BytesPerLong); -define_pd_global(bool, ThreadLocalHandshakes, false); +define_pd_global(bool, ThreadLocalHandshakes, true); #define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct, range, constraint, writeable) \ \ diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/s390/interp_masm_s390.cpp --- a/src/hotspot/cpu/s390/interp_masm_s390.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/s390/interp_masm_s390.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -36,6 +36,7 @@ #include "prims/jvmtiThreadState.hpp" #include "runtime/basicLock.hpp" #include "runtime/biasedLocking.hpp" +#include "runtime/safepointMechanism.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/thread.inline.hpp" @@ -74,16 +75,16 @@ dispatch_next(state, step); } -void InterpreterMacroAssembler::dispatch_next(TosState state, int bcp_incr) { +void InterpreterMacroAssembler::dispatch_next(TosState state, int bcp_incr, bool generate_poll) { z_llgc(Z_bytecode, bcp_incr, Z_R0, Z_bcp); // Load next bytecode. add2reg(Z_bcp, bcp_incr); // Advance bcp. Add2reg produces optimal code. - dispatch_base(state, Interpreter::dispatch_table(state)); + dispatch_base(state, Interpreter::dispatch_table(state), generate_poll); } // Common code to dispatch and dispatch_only. // Dispatch value in Lbyte_code and increment Lbcp. -void InterpreterMacroAssembler::dispatch_base(TosState state, address* table) { +void InterpreterMacroAssembler::dispatch_base(TosState state, address* table, bool generate_poll) { verify_FPU(1, state); #ifdef ASSERT @@ -109,7 +110,20 @@ verify_oop(Z_tos, state); // Dispatch table to use. - load_absolute_address(Z_tmp_1, (address) table); // Z_tmp_1 = table; + load_absolute_address(Z_tmp_1, (address)table); // Z_tmp_1 = table; + + if (SafepointMechanism::uses_thread_local_poll() && generate_poll) { + address *sfpt_tbl = Interpreter::safept_table(state); + if (table != sfpt_tbl) { + Label dispatch; + const Address poll_byte_addr(Z_thread, in_bytes(Thread::polling_page_offset()) + 7 /* Big Endian */); + // Armed page has poll_bit set, if poll bit is cleared just continue. + z_tm(poll_byte_addr, SafepointMechanism::poll_bit()); + z_braz(dispatch); + load_absolute_address(Z_tmp_1, (address)sfpt_tbl); // Z_tmp_1 = table; + bind(dispatch); + } + } // 0 <= Z_bytecode < 256 => Use a 32 bit shift, because it is shorter than sllg. // Z_bytecode must have been loaded zero-extended for this approach to be correct. @@ -119,8 +133,8 @@ z_br(Z_tmp_1); } -void InterpreterMacroAssembler::dispatch_only(TosState state) { - dispatch_base(state, Interpreter::dispatch_table(state)); +void InterpreterMacroAssembler::dispatch_only(TosState state, bool generate_poll) { + dispatch_base(state, Interpreter::dispatch_table(state), generate_poll); } void InterpreterMacroAssembler::dispatch_only_normal(TosState state) { diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/s390/interp_masm_s390.hpp --- a/src/hotspot/cpu/s390/interp_masm_s390.hpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/s390/interp_masm_s390.hpp Thu Dec 14 12:28:32 2017 +0000 @@ -49,7 +49,7 @@ bool check_exceptions); // Base routine for all dispatches. - void dispatch_base(TosState state, address* table); + void dispatch_base(TosState state, address* table, bool generate_poll = false); public: InterpreterMacroAssembler(CodeBuffer* c) @@ -78,11 +78,11 @@ // dispatch routines void dispatch_prolog(TosState state, int step = 0); void dispatch_epilog(TosState state, int step = 0); - void dispatch_only(TosState state); + void dispatch_only(TosState state, bool generate_poll = false); // Dispatch normal table via Z_bytecode (assume Z_bytecode is loaded already). void dispatch_only_normal(TosState state); void dispatch_normal(TosState state); - void dispatch_next(TosState state, int step = 0); + void dispatch_next(TosState state, int step = 0, bool generate_poll = false); void dispatch_next_noverify_oop(TosState state, int step = 0); void dispatch_via(TosState state, address* table); diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/s390/macroAssembler_s390.cpp --- a/src/hotspot/cpu/s390/macroAssembler_s390.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/s390/macroAssembler_s390.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -43,6 +43,8 @@ #include "runtime/interfaceSupport.hpp" #include "runtime/objectMonitor.hpp" #include "runtime/os.hpp" +#include "runtime/safepoint.hpp" +#include "runtime/safepointMechanism.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/stubRoutines.hpp" #include "utilities/events.hpp" @@ -2019,6 +2021,15 @@ return here + offset; } +void MacroAssembler::instr_size(Register size, Register pc) { + // Extract 2 most significant bits of current instruction. + z_llgc(size, Address(pc)); + z_srl(size, 6); + // Compute (x+3)&6 which translates 0->2, 1->4, 2->4, 3->6. + z_ahi(size, 3); + z_nill(size, 6); +} + // Resize_frame with SP(new) = SP(old) - [offset]. void MacroAssembler::resize_frame_sub(Register offset, Register fp, bool load_fp) { @@ -2705,6 +2716,19 @@ z_st(Z_R0, 0, tmp2, tmp1); } +void MacroAssembler::safepoint_poll(Label& slow_path, Register temp_reg) { + if (SafepointMechanism::uses_thread_local_poll()) { + const Address poll_byte_addr(Z_thread, in_bytes(Thread::polling_page_offset()) + 7 /* Big Endian */); + // Armed page has poll_bit set. + z_tm(poll_byte_addr, SafepointMechanism::poll_bit()); + z_brnaz(slow_path); + } else { + load_const_optimized(temp_reg, SafepointSynchronize::address_of_state()); + z_cli(/*SafepointSynchronize::sz_state()*/4-1, temp_reg, SafepointSynchronize::_not_synchronized); + z_brne(slow_path); + } +} + // Don't rely on register locking, always use Z_R1 as scratch register instead. void MacroAssembler::bang_stack_with_offset(int offset) { // Stack grows down, caller passes positive offset. @@ -4914,13 +4938,14 @@ // The result is the number of characters copied before the first incompatible character was found. // If precise is true, the processing stops exactly at this point. Otherwise, the result may be off // by a few bytes. The result always indicates the number of copied characters. +// When used as a character index, the returned value points to the first incompatible character. // // Note: Does not behave exactly like package private StringUTF16 compress java implementation in case of failure: // - Different number of characters may have been written to dead array (if precise is false). // - Returns a number incompatible character found. // re-process data from current iteration in break handler. //---< pack & store characters >--- @@ -5094,24 +5119,28 @@ z_tmll(Rcnt, min_cnt-1); z_brnaz(ScalarShortcut); // if all bits zero, there is nothing left to do for scalar loop. // Rix == 0 in all cases. + z_sllg(Z_R1, Rcnt, 1); // # src bytes already processed. Only lower 32 bits are valid! + // Z_R1 contents must be treated as unsigned operand! For huge strings, + // (Rcnt >= 2**30), the value may spill into the sign bit by sllg. z_lgfr(result, Rcnt); // all characters processed. - z_sgfr(Rdst, Rcnt); // restore ptr - z_sgfr(Rsrc, Rcnt); // restore ptr, double the element count for Rsrc restore - z_sgfr(Rsrc, Rcnt); + z_slgfr(Rdst, Rcnt); // restore ptr + z_slgfr(Rsrc, Z_R1); // restore ptr, double the element count for Rsrc restore z_bru(AllDone); bind(UnrolledBreak); z_lgfr(Z_R0, Rcnt); // # chars processed in total after unrolled loop z_nilf(Z_R0, ~(min_cnt-1)); - z_sll(Rix, log_min_cnt); // # chars processed so far in UnrolledLoop, excl. current iteration. - z_sr(Z_R0, Rix); // correct # chars processed in total. + z_sll(Rix, log_min_cnt); // # chars not yet processed in UnrolledLoop (due to break), broken iteration not included. + z_sr(Z_R0, Rix); // fix # chars processed OK so far. if (!precise) { z_lgfr(result, Z_R0); + z_sllg(Z_R1, Z_R0, 1); // # src bytes already processed. Only lower 32 bits are valid! + // Z_R1 contents must be treated as unsigned operand! For huge strings, + // (Rcnt >= 2**30), the value may spill into the sign bit by sllg. z_aghi(result, min_cnt/2); // min_cnt/2 characters have already been written // but ptrs were not updated yet. - z_sgfr(Rdst, Z_R0); // restore ptr - z_sgfr(Rsrc, Z_R0); // restore ptr, double the element count for Rsrc restore - z_sgfr(Rsrc, Z_R0); + z_slgfr(Rdst, Z_R0); // restore ptr + z_slgfr(Rsrc, Z_R1); // restore ptr, double the element count for Rsrc restore z_bru(AllDone); } bind(UnrolledDone); @@ -5165,7 +5194,7 @@ z_sr(Rix, Z_R0); } z_lgfr(result, Rcnt); // # processed characters (if all runs ok). - z_brz(ScalarDone); + z_brz(ScalarDone); // uses CC from Rix calculation bind(ScalarLoop); z_llh(Z_R1, 0, Z_R0, Rsrc); @@ -6452,27 +6481,6 @@ Assembler::z_brc(Assembler::bcondOverflow /* CC==3 (iterate) */, retry); } -void MacroAssembler::generate_safepoint_check(Label& slow_path, Register scratch, bool may_relocate) { - if (scratch == noreg) scratch = Z_R1; - address Astate = SafepointSynchronize::address_of_state(); - BLOCK_COMMENT("safepoint check:"); - - if (may_relocate) { - ptrdiff_t total_distance = Astate - this->pc(); - if (RelAddr::is_in_range_of_RelAddr32(total_distance)) { - RelocationHolder rspec = external_word_Relocation::spec(Astate); - (this)->relocate(rspec, relocInfo::pcrel_addr_format); - load_absolute_address(scratch, Astate); - } else { - load_const_optimized(scratch, Astate); - } - } else { - load_absolute_address(scratch, Astate); - } - z_cli(/*SafepointSynchronize::sz_state()*/4-1, scratch, SafepointSynchronize::_not_synchronized); - z_brne(slow_path); -} - void MacroAssembler::generate_type_profiling(const Register Rdata, const Register Rreceiver_klass, diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/s390/macroAssembler_s390.hpp --- a/src/hotspot/cpu/s390/macroAssembler_s390.hpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/s390/macroAssembler_s390.hpp Thu Dec 14 12:28:32 2017 +0000 @@ -260,8 +260,6 @@ // // Constants, loading constants, TOC support // - // Safepoint check factored out. - void generate_safepoint_check(Label& slow_path, Register scratch = noreg, bool may_relocate = true); // Load generic address: d <- base(a) + index(a) + disp(a). inline void load_address(Register d, const Address &a); @@ -443,6 +441,9 @@ // Get current PC + offset. Offset given in bytes, must be even! address get_PC(Register result, int64_t offset); + // Get size of instruction at pc (which must point to valid code). + void instr_size(Register size, Register pc); + // Accessing, and in particular modifying, a stack location is only safe if // the stack pointer (Z_SP) is set such that the accessed stack location is // in the reserved range. @@ -641,6 +642,9 @@ // Support for serializing memory accesses between threads. void serialize_memory(Register thread, Register tmp1, Register tmp2); + // Check if safepoint requested and if so branch + void safepoint_poll(Label& slow_path, Register temp_reg); + // Stack overflow checking void bang_stack_with_offset(int offset); diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/s390/s390.ad --- a/src/hotspot/cpu/s390/s390.ad Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/s390/s390.ad Thu Dec 14 12:28:32 2017 +0000 @@ -919,8 +919,12 @@ // Touch the polling page. if (need_polling) { - AddressLiteral pp(os::get_polling_page()); - __ load_const_optimized(Z_R1_scratch, pp); + if (SafepointMechanism::uses_thread_local_poll()) { + __ z_lg(Z_R1_scratch, Address(Z_thread, Thread::polling_page_offset())); + } else { + AddressLiteral pp(os::get_polling_page()); + __ load_const_optimized(Z_R1_scratch, pp); + } // We need to mark the code position where the load from the safepoint // polling page was emitted as relocInfo::poll_return_type here. __ relocate(relocInfo::poll_return_type); diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/s390/sharedRuntime_s390.cpp --- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -2165,7 +2165,7 @@ __ serialize_memory(Z_thread, Z_R1, Z_R2); } } - __ generate_safepoint_check(sync, Z_R1, true); + __ safepoint_poll(sync, Z_R1); __ load_and_test_int(Z_R0, Address(Z_thread, JavaThread::suspend_flags_offset())); __ z_bre(no_block); @@ -3190,12 +3190,18 @@ bool cause_return = (poll_type == POLL_AT_RETURN); // Make room for return address (or push it again) - if (!cause_return) + if (!cause_return) { __ z_lg(Z_R14, Address(Z_thread, JavaThread::saved_exception_pc_offset())); + } // Save registers, fpu state, and flags map = RegisterSaver::save_live_registers(masm, RegisterSaver::all_registers); + if (SafepointMechanism::uses_thread_local_poll() && !cause_return) { + // Keep a copy of the return pc to detect if it gets modified. + __ z_lgr(Z_R6, Z_R14); + } + // The following is basically a call_VM. However, we need the precise // address of the call in order to generate an oopmap. Hence, we do all the // work outselves. @@ -3231,6 +3237,21 @@ // No exception case __ bind(noException); + if (SafepointMechanism::uses_thread_local_poll() && !cause_return) { + Label no_adjust; + // If our stashed return pc was modified by the runtime we avoid touching it + const int offset_of_return_pc = _z_abi16(return_pc) + RegisterSaver::live_reg_frame_size(RegisterSaver::all_registers); + __ z_cg(Z_R6, offset_of_return_pc, Z_SP); + __ z_brne(no_adjust); + + // Adjust return pc forward to step over the safepoint poll instruction + __ instr_size(Z_R1_scratch, Z_R6); + __ z_agr(Z_R6, Z_R1_scratch); + __ z_stg(Z_R6, offset_of_return_pc, Z_SP); + + __ bind(no_adjust); + } + // Normal exit, restore registers and exit. RegisterSaver::restore_live_registers(masm, RegisterSaver::all_registers); diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp --- a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -1633,7 +1633,7 @@ // Check for safepoint operation in progress and/or pending suspend requests. { Label Continue, do_safepoint; - __ generate_safepoint_check(do_safepoint, Z_R1, true); + __ safepoint_poll(do_safepoint, Z_R1); // Check for suspend. __ load_and_test_int(Z_R0/*suspend_flags*/, thread_(suspend_flags)); __ z_bre(Continue); // 0 -> no flag set -> not suspended @@ -1937,7 +1937,7 @@ Label slow_path; // If we need a safepoint check, generate full interpreter entry. - __ generate_safepoint_check(slow_path, Z_R1, false); + __ safepoint_poll(slow_path, Z_R1); BLOCK_COMMENT("CRC32_update {"); @@ -1990,7 +1990,7 @@ Label slow_path; // If we need a safepoint check, generate full interpreter entry. - __ generate_safepoint_check(slow_path, Z_R1, false); + __ safepoint_poll(slow_path, Z_R1); // We don't generate local frame and don't align stack because // we call stub code and there is no safepoint on this path. diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/s390/templateTable_s390.cpp --- a/src/hotspot/cpu/s390/templateTable_s390.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/s390/templateTable_s390.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -1853,7 +1853,7 @@ // Push return address for "ret" on stack. __ push_ptr(Z_tos); // And away we go! - __ dispatch_next(vtos); + __ dispatch_next(vtos, 0 , true); return; } @@ -1961,7 +1961,7 @@ // Z_tos: Return bci for jsr's, unused otherwise. // Z_bytecode: target bytecode // Z_bcp: target bcp - __ dispatch_only(vtos); + __ dispatch_only(vtos, true); // Out-of-line code runtime calls. if (UseLoopCounter) { @@ -2072,7 +2072,7 @@ __ get_method(Z_tos); __ mem2reg_opt(Z_R1_scratch, Address(Z_tos, Method::const_offset())); __ load_address(Z_bcp, Address(Z_R1_scratch, Z_tmp_1, ConstMethod::codes_offset())); - __ dispatch_next(vtos); + __ dispatch_next(vtos, 0 , true); } void TemplateTable::wide_ret() { @@ -2085,7 +2085,7 @@ __ get_method(Z_tos); __ mem2reg_opt(Z_R1_scratch, Address(Z_tos, Method::const_offset())); __ load_address(Z_bcp, Address(Z_R1_scratch, Z_tmp_1, ConstMethod::codes_offset())); - __ dispatch_next(vtos); + __ dispatch_next(vtos, 0, true); } void TemplateTable::tableswitch () { @@ -2129,7 +2129,7 @@ // Load next bytecode. __ z_llgc(Z_bytecode, Address(Z_bcp, index)); __ z_agr(Z_bcp, index); // Advance bcp. - __ dispatch_only(vtos); + __ dispatch_only(vtos, true); // Handle default. __ bind(default_case); @@ -2193,7 +2193,7 @@ // Load next bytecode. __ z_llgc(Z_bytecode, Address(Z_bcp, offset, 0)); __ z_agr(Z_bcp, offset); // Advance bcp. - __ dispatch_only(vtos); + __ dispatch_only(vtos, true); } @@ -2302,7 +2302,7 @@ // Load next bytecode. __ z_llgc(Z_bytecode, Address(Z_bcp, j)); __ z_agr(Z_bcp, j); // Advance bcp. - __ dispatch_only(vtos); + __ dispatch_only(vtos, true); // default case -> j = default offset __ bind(default_case); @@ -2312,7 +2312,7 @@ // Load next bytecode. __ z_llgc(Z_bytecode, Address(Z_bcp, j)); __ z_agr(Z_bcp, j); // Advance bcp. - __ dispatch_only(vtos); + __ dispatch_only(vtos, true); } void TemplateTable::_return(TosState state) { @@ -2333,6 +2333,17 @@ __ bind(skip_register_finalizer); } + if (SafepointMechanism::uses_thread_local_poll() && _desc->bytecode() != Bytecodes::_return_register_finalizer) { + Label no_safepoint; + const Address poll_byte_addr(Z_thread, in_bytes(Thread::polling_page_offset()) + 7 /* Big Endian */); + __ z_tm(poll_byte_addr, SafepointMechanism::poll_bit()); + __ z_braz(no_safepoint); + __ push(state); + __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)); + __ pop(state); + __ bind(no_safepoint); + } + if (state == itos) { // Narrow result if state is itos but result type is smaller. // Need to narrow in the return bytecode rather than in generate_return_entry diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/sparc/stubGenerator_sparc.cpp --- a/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -5157,8 +5157,8 @@ const Register gxp = G1; // Need to use global registers across RWs. const Register gyp = G2; const Register gzp = G3; - const Register offs = G4; - const Register disp = G5; + const Register disp = G4; + const Register offs = G5; __ mov(xptr, gxp); __ mov(yptr, gyp); @@ -5569,8 +5569,8 @@ // for (int i = xn; i >= 0; i--) __ bind(L_loop_i); - __ cmp_and_br_short(xpc, xp,// i >= 0 - Assembler::less, Assembler::pn, L_exit_loop_i); + __ cmp_and_brx_short(xpc, xp,// i >= 0 + Assembler::lessUnsigned, Assembler::pn, L_exit_loop_i); __ lduw(xpc, 0, rt); // u64 x = xp[i] __ lduw(xpc, 4, rx); // ... __ sllx(rt, 32, rt); @@ -5598,8 +5598,8 @@ __ bind(L_loop_j); - __ cmp_and_br_short(ypc, yp,// j >= 0 - Assembler::less, Assembler::pn, L_exit); + __ cmp_and_brx_short(ypc, yp,// j >= 0 + Assembler::lessUnsigned, Assembler::pn, L_exit); __ clr(rc); // u64 c = 0 __ lduw(ypc, 0, rt); // u64 y = yp[j] (= *ypc) __ lduw(ypc, 4, ry); // ... @@ -5615,8 +5615,8 @@ __ bind(L_loop_i2); - __ cmp_and_br_short(xpc, xp,// i >= 0 - Assembler::less, Assembler::pn, L_exit_loop_i2); + __ cmp_and_brx_short(xpc, xp,// i >= 0 + Assembler::lessUnsigned, Assembler::pn, L_exit_loop_i2); __ lduw(xpc, 0, rt); // u64 x = xp[i] (= *xpc) __ lduw(xpc, 4, rx); // ... __ sllx(rt, 32, rt); diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/x86/assembler_x86.cpp --- a/src/hotspot/cpu/x86/assembler_x86.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/x86/assembler_x86.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -7449,6 +7449,27 @@ emit_int8((unsigned char)(0xF0 & src2_enc<<4)); } +void Assembler::cmpps(XMMRegister dst, XMMRegister nds, XMMRegister src, int cop, int vector_len) { + assert(VM_Version::supports_avx(), ""); + assert(!VM_Version::supports_evex(), ""); + InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false); + int encode = simd_prefix_and_encode(dst, nds, src, VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes); + emit_int8((unsigned char)0xC2); + emit_int8((unsigned char)(0xC0 | encode)); + emit_int8((unsigned char)(0xF & cop)); +} + +void Assembler::blendvps(XMMRegister dst, XMMRegister nds, XMMRegister src1, XMMRegister src2, int vector_len) { + assert(VM_Version::supports_avx(), ""); + assert(!VM_Version::supports_evex(), ""); + InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false); + int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src1->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); + emit_int8((unsigned char)0x4A); + emit_int8((unsigned char)(0xC0 | encode)); + int src2_enc = src2->encoding(); + emit_int8((unsigned char)(0xF0 & src2_enc<<4)); +} + void Assembler::vpblendd(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8, int vector_len) { assert(VM_Version::supports_avx2(), ""); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false); diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/x86/assembler_x86.hpp --- a/src/hotspot/cpu/x86/assembler_x86.hpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/x86/assembler_x86.hpp Thu Dec 14 12:28:32 2017 +0000 @@ -2114,9 +2114,11 @@ // runtime code and native libraries. void vzeroupper(); - // AVX support for vectorized conditional move (double). The following two instructions used only coupled. + // AVX support for vectorized conditional move (float/double). The following two instructions used only coupled. void cmppd(XMMRegister dst, XMMRegister nds, XMMRegister src, int cop, int vector_len); void blendvpd(XMMRegister dst, XMMRegister nds, XMMRegister src1, XMMRegister src2, int vector_len); + void cmpps(XMMRegister dst, XMMRegister nds, XMMRegister src, int cop, int vector_len); + void blendvps(XMMRegister dst, XMMRegister nds, XMMRegister src1, XMMRegister src2, int vector_len); void vpblendd(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8, int vector_len); protected: diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/cpu/x86/x86.ad --- a/src/hotspot/cpu/x86/x86.ad Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/cpu/x86/x86.ad Thu Dec 14 12:28:32 2017 +0000 @@ -1263,6 +1263,7 @@ if (!VM_Version::supports_cx8()) ret_value = false; break; + case Op_CMoveVF: case Op_CMoveVD: if (UseAVX < 1 || UseAVX > 2) ret_value = false; @@ -1304,6 +1305,9 @@ if ((vlen == 32) && (VM_Version::supports_avx512bw() == false)) ret_value = false; break; + case Op_CMoveVF: + if (vlen != 8) + ret_value = false; case Op_CMoveVD: if (vlen != 4) ret_value = false; @@ -8170,6 +8174,22 @@ ins_pipe( pipe_slow ); %} +instruct vcmov8F_reg(vecY dst, vecY src1, vecY src2, immI8 cop, cmpOp_vcmppd copnd) %{ + predicate(UseAVX > 0 && UseAVX < 3 && n->as_Vector()->length() == 8); + match(Set dst (CMoveVF (Binary copnd cop) (Binary src1 src2))); + effect(TEMP dst, USE src1, USE src2); + format %{ "cmpps.$copnd $dst, $src1, $src2 ! vcmovevf, cond=$cop\n\t" + "blendvps $dst,$src1,$src2,$dst ! vcmovevf\n\t" + %} + ins_encode %{ + int vector_len = 1; + int cond = (Assembler::Condition)($copnd$$cmpcode); + __ cmpps($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, cond, vector_len); + __ blendvps($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, $dst$$XMMRegister, vector_len); + %} + ins_pipe( pipe_slow ); +%} + instruct vcmov4D_reg(vecY dst, vecY src1, vecY src2, immI8 cop, cmpOp_vcmppd copnd) %{ predicate(UseAVX > 0 && UseAVX < 3 && n->as_Vector()->length() == 4); match(Set dst (CMoveVD (Binary copnd cop) (Binary src1 src2))); diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/os/posix/include/jvm_md.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/os/posix/include/jvm_md.h Thu Dec 14 12:28:32 2017 +0000 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 1997, 2012, 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. + */ + +#ifndef _JAVASOFT_JVM_MD_H_ +#define _JAVASOFT_JVM_MD_H_ + +/* + * This file is currently collecting system-specific dregs for the + * JNI conversion, which should be sorted out later. + */ + +#include /* For DIR */ +#include /* For MAXPATHLEN */ +#include /* For F_OK, R_OK, W_OK */ +#include /* For ptrdiff_t */ +#include /* For uintptr_t */ + +#define JNI_ONLOAD_SYMBOLS {"JNI_OnLoad"} +#define JNI_ONUNLOAD_SYMBOLS {"JNI_OnUnload"} +#define JVM_ONLOAD_SYMBOLS {"JVM_OnLoad"} +#define AGENT_ONLOAD_SYMBOLS {"Agent_OnLoad"} +#define AGENT_ONUNLOAD_SYMBOLS {"Agent_OnUnload"} +#define AGENT_ONATTACH_SYMBOLS {"Agent_OnAttach"} + +#define JNI_LIB_PREFIX "lib" +#ifdef __APPLE__ +#define JNI_LIB_SUFFIX ".dylib" +#define VERSIONED_JNI_LIB_NAME(NAME, VERSION) JNI_LIB_PREFIX NAME "." VERSION JNI_LIB_SUFFIX +#else +#define JNI_LIB_SUFFIX ".so" +#define VERSIONED_JNI_LIB_NAME(NAME, VERSION) JNI_LIB_PREFIX NAME JNI_LIB_SUFFIX "." VERSION +#endif +#define JNI_LIB_NAME(NAME) JNI_LIB_PREFIX NAME JNI_LIB_SUFFIX + +#if defined(AIX) || defined(SOLARIS) +#define JVM_MAXPATHLEN MAXPATHLEN +#else +// Hack: MAXPATHLEN is 4095 on some Linux and 4096 on others. This may +// cause problems if JVM and the rest of JDK are built on different +// Linux releases. Here we define JVM_MAXPATHLEN to be MAXPATHLEN + 1, +// so buffers declared in VM are always >= 4096. +#define JVM_MAXPATHLEN MAXPATHLEN + 1 +#endif + +#define JVM_R_OK R_OK +#define JVM_W_OK W_OK +#define JVM_X_OK X_OK +#define JVM_F_OK F_OK + +/* + * File I/O + */ + +#include +#include +#include +#include +#include + +/* Signals */ + +#include // for socklen_t + +#define JVM_SIGINT SIGINT +#define JVM_SIGTERM SIGTERM + +#define BREAK_SIGNAL SIGQUIT /* Thread dumping support. */ +#ifdef SOLARIS +#define ASYNC_SIGNAL SIGJVM2 /* Event-based suspend/resume support */ +#endif // SOLARIS +#define SHUTDOWN1_SIGNAL SIGHUP /* Shutdown Hooks support. */ +#define SHUTDOWN2_SIGNAL SIGINT +#define SHUTDOWN3_SIGNAL SIGTERM + +/* With 1.4.1 libjsig added versioning: used in os_solaris.cpp and jsig.c */ +#define JSIG_VERSION_1_4_1 0x30140100 + +#endif /* !_JAVASOFT_JVM_MD_H_ */ diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/os/posix/os_posix.cpp --- a/src/hotspot/os/posix/os_posix.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/os/posix/os_posix.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -243,8 +243,9 @@ assert(fd != -1, "File descriptor is not valid"); // allocate space for the file - if (util_posix_fallocate(fd, 0, (off_t)size) != 0) { - vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory.")); + int ret = util_posix_fallocate(fd, 0, (off_t)size); + if (ret != 0) { + vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory. error(%d)", ret)); return NULL; } @@ -256,12 +257,13 @@ char* addr = (char*)mmap(base, size, prot, flags, fd, 0); if (addr == MAP_FAILED) { + warning("Failed mmap to file. (%s)", os::strerror(errno)); return NULL; } if (base != NULL && addr != base) { if (!os::release_memory(addr, size)) { warning("Could not release memory on unsuccessful file mapping"); - } + } return NULL; } return addr; diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/os/windows/include/jvm_md.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/os/windows/include/jvm_md.h Thu Dec 14 12:28:32 2017 +0000 @@ -0,0 +1,102 @@ +/* + * Copyright (c) 1997, 2008, 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. + */ + +#ifndef _JAVASOFT_JVM_MD_H_ +#define _JAVASOFT_JVM_MD_H_ + +/* + * This file is currently collecting system-specific dregs for the + * JNI conversion, which should be sorted out later. + */ + +#include +#include +#include + +#include "jni.h" + +typedef int socklen_t; + +#define JNI_ONLOAD_SYMBOLS {"_JNI_OnLoad@8", "JNI_OnLoad"} +#define JNI_ONUNLOAD_SYMBOLS {"_JNI_OnUnload@8", "JNI_OnUnload"} +#define JVM_ONLOAD_SYMBOLS {"_JVM_OnLoad@12", "JVM_OnLoad"} +#define AGENT_ONLOAD_SYMBOLS {"_Agent_OnLoad@12", "Agent_OnLoad"} +#define AGENT_ONUNLOAD_SYMBOLS {"_Agent_OnUnload@4", "Agent_OnUnload"} +#define AGENT_ONATTACH_SYMBOLS {"_Agent_OnAttach@12", "Agent_OnAttach"} + +#define JNI_LIB_PREFIX "" +#define JNI_LIB_SUFFIX ".dll" + +struct dirent { + char d_name[MAX_PATH]; +}; + +typedef struct { + struct dirent dirent; + char *path; + HANDLE handle; + WIN32_FIND_DATA find_data; +} DIR; + +#include /* For uintptr_t */ +#include + +#define JVM_MAXPATHLEN _MAX_PATH + +#define JVM_R_OK 4 +#define JVM_W_OK 2 +#define JVM_X_OK 1 +#define JVM_F_OK 0 + +#ifdef __cplusplus +extern "C" { +#endif + +JNIEXPORT void * JNICALL +JVM_GetThreadInterruptEvent(); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +/* + * File I/O + */ + +#include +#include +#include +#include +#include + +/* Signals */ + +#define JVM_SIGINT SIGINT +#define JVM_SIGTERM SIGTERM + +#define SHUTDOWN1_SIGNAL SIGINT /* Shutdown Hooks support. */ +#define SHUTDOWN2_SIGNAL SIGTERM + +#endif /* !_JAVASOFT_JVM_MD_H_ */ diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/adlc/formssel.cpp --- a/src/hotspot/share/adlc/formssel.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/adlc/formssel.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -4164,7 +4164,7 @@ "AddVB","AddVS","AddVI","AddVL","AddVF","AddVD", "SubVB","SubVS","SubVI","SubVL","SubVF","SubVD", "MulVS","MulVI","MulVL","MulVF","MulVD", - "CMoveVD", + "CMoveVD", "CMoveVF", "DivVF","DivVD", "AbsVF","AbsVD", "NegVF","NegVD", diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/c1/c1_GraphBuilder.cpp --- a/src/hotspot/share/c1/c1_GraphBuilder.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/c1/c1_GraphBuilder.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -1439,6 +1439,9 @@ } if (needs_check) { + // Not a trivial method because C2 can do better with inlined check. + compilation()->set_would_profile(true); + // Perform the registration of finalizable objects. ValueStack* state_before = copy_state_for_exception(); load_local(objectType, 0); @@ -3556,6 +3559,9 @@ } bool GraphBuilder::try_inline_intrinsics(ciMethod* callee, bool ignore_return) { + // Not a trivial method because C2 may do intrinsics better. + compilation()->set_would_profile(true); + // For calling is_intrinsic_available we need to transition to // the '_thread_in_vm' state because is_intrinsic_available() // accesses critical VM-internal data. diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/ci/ciEnv.cpp --- a/src/hotspot/share/ci/ciEnv.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/ci/ciEnv.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -899,64 +899,18 @@ void ciEnv::validate_compile_task_dependencies(ciMethod* target) { if (failing()) return; // no need for further checks - // First, check non-klass dependencies as we might return early and - // not check klass dependencies if the system dictionary - // modification counter hasn't changed (see below). - for (Dependencies::DepStream deps(dependencies()); deps.next(); ) { - if (deps.is_klass_type()) continue; // skip klass dependencies - Klass* witness = deps.check_dependency(); - if (witness != NULL) { - if (deps.type() == Dependencies::call_site_target_value) { - _inc_decompile_count_on_failure = false; - record_failure("call site target change"); - } else { - record_failure("invalid non-klass dependency"); - } - return; + bool counter_changed = system_dictionary_modification_counter_changed(); + Dependencies::DepType result = dependencies()->validate_dependencies(_task, counter_changed); + if (result != Dependencies::end_marker) { + if (result == Dependencies::call_site_target_value) { + _inc_decompile_count_on_failure = false; + record_failure("call site target change"); + } else if (Dependencies::is_klass_type(result)) { + record_failure("invalid non-klass dependency"); + } else { + record_failure("concurrent class loading"); } } - - // Klass dependencies must be checked when the system dictionary - // changes. If logging is enabled all violated dependences will be - // recorded in the log. In debug mode check dependencies even if - // the system dictionary hasn't changed to verify that no invalid - // dependencies were inserted. Any violated dependences in this - // case are dumped to the tty. - bool counter_changed = system_dictionary_modification_counter_changed(); - - bool verify_deps = trueInDebug; - if (!counter_changed && !verify_deps) return; - - int klass_violations = 0; - for (Dependencies::DepStream deps(dependencies()); deps.next(); ) { - if (!deps.is_klass_type()) continue; // skip non-klass dependencies - Klass* witness = deps.check_dependency(); - if (witness != NULL) { - klass_violations++; - if (!counter_changed) { - // Dependence failed but counter didn't change. Log a message - // describing what failed and allow the assert at the end to - // trigger. - deps.print_dependency(witness); - } else if (xtty == NULL) { - // If we're not logging then a single violation is sufficient, - // otherwise we want to log all the dependences which were - // violated. - break; - } - } - } - - if (klass_violations != 0) { -#ifdef ASSERT - if (!counter_changed && !PrintCompilation) { - // Print out the compile task that failed - _task->print_tty(); - } -#endif - assert(counter_changed, "failed dependencies, but counter didn't change"); - record_failure("concurrent class loading"); - } } // ------------------------------------------------------------------ diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/code/dependencies.cpp --- a/src/hotspot/share/code/dependencies.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/code/dependencies.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -30,6 +30,8 @@ #include "classfile/javaClasses.inline.hpp" #include "code/dependencies.hpp" #include "compiler/compileLog.hpp" +#include "compiler/compileBroker.hpp" +#include "compiler/compileTask.hpp" #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" #include "oops/objArrayKlass.hpp" @@ -620,6 +622,72 @@ guarantee(FIRST_TYPE <= dept && dept < TYPE_LIMIT, "invalid dependency type: %d", (int) dept); } +Dependencies::DepType Dependencies::validate_dependencies(CompileTask* task, bool counter_changed, char** failure_detail) { + // First, check non-klass dependencies as we might return early and + // not check klass dependencies if the system dictionary + // modification counter hasn't changed (see below). + for (Dependencies::DepStream deps(this); deps.next(); ) { + if (deps.is_klass_type()) continue; // skip klass dependencies + Klass* witness = deps.check_dependency(); + if (witness != NULL) { + return deps.type(); + } + } + + // Klass dependencies must be checked when the system dictionary + // changes. If logging is enabled all violated dependences will be + // recorded in the log. In debug mode check dependencies even if + // the system dictionary hasn't changed to verify that no invalid + // dependencies were inserted. Any violated dependences in this + // case are dumped to the tty. + if (!counter_changed && !trueInDebug) { + return end_marker; + } + + int klass_violations = 0; + DepType result = end_marker; + for (Dependencies::DepStream deps(this); deps.next(); ) { + if (!deps.is_klass_type()) continue; // skip non-klass dependencies + Klass* witness = deps.check_dependency(); + if (witness != NULL) { + if (klass_violations == 0) { + result = deps.type(); + if (failure_detail != NULL && klass_violations == 0) { + // Use a fixed size buffer to prevent the string stream from + // resizing in the context of an inner resource mark. + char* buffer = NEW_RESOURCE_ARRAY(char, O_BUFLEN); + stringStream st(buffer, O_BUFLEN); + deps.print_dependency(witness, true, &st); + *failure_detail = st.as_string(); + } + } + klass_violations++; + if (!counter_changed) { + // Dependence failed but counter didn't change. Log a message + // describing what failed and allow the assert at the end to + // trigger. + deps.print_dependency(witness); + } else if (xtty == NULL) { + // If we're not logging then a single violation is sufficient, + // otherwise we want to log all the dependences which were + // violated. + break; + } + } + } + + if (klass_violations != 0) { +#ifdef ASSERT + if (task != NULL && !counter_changed && !PrintCompilation) { + // Print out the compile task that failed + task->print_tty(); + } +#endif + assert(counter_changed, "failed dependencies, but counter didn't change"); + } + return result; +} + // for the sake of the compiler log, print out current dependencies: void Dependencies::log_all_dependencies() { if (log() == NULL) return; diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/code/dependencies.hpp --- a/src/hotspot/share/code/dependencies.hpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/code/dependencies.hpp Thu Dec 14 12:28:32 2017 +0000 @@ -457,6 +457,8 @@ void copy_to(nmethod* nm); + DepType validate_dependencies(CompileTask* task, bool counter_changed, char** failure_detail = NULL); + void log_all_dependencies(); void log_dependency(DepType dept, GrowableArray* args) { diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/gc/g1/g1Arguments.cpp --- a/src/hotspot/share/gc/g1/g1Arguments.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/gc/g1/g1Arguments.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -98,9 +98,9 @@ // Enable loop strip mining to offer better pause time guarantees if (FLAG_IS_DEFAULT(UseCountedLoopSafepoints)) { FLAG_SET_DEFAULT(UseCountedLoopSafepoints, true); - } - if (UseCountedLoopSafepoints && FLAG_IS_DEFAULT(LoopStripMiningIter)) { - FLAG_SET_DEFAULT(LoopStripMiningIter, 1000); + if (FLAG_IS_DEFAULT(LoopStripMiningIter)) { + FLAG_SET_DEFAULT(LoopStripMiningIter, 1000); + } } #endif } diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/include/jmm.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/include/jmm.h Thu Dec 14 12:28:32 2017 +0000 @@ -0,0 +1,345 @@ +/* + * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +#ifndef _JAVA_JMM_H_ +#define _JAVA_JMM_H_ + +/* + * This is a private interface used by JDK for JVM monitoring + * and management. + * + * Bump the version number when either of the following happens: + * + * 1. There is a change in functions in JmmInterface. + * + * 2. There is a change in the contract between VM and Java classes. + */ + +#include "jni.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + JMM_VERSION_1 = 0x20010000, + JMM_VERSION_1_0 = 0x20010000, + JMM_VERSION_1_1 = 0x20010100, // JDK 6 + JMM_VERSION_1_2 = 0x20010200, // JDK 7 + JMM_VERSION_1_2_1 = 0x20010201, // JDK 7 GA + JMM_VERSION_1_2_2 = 0x20010202, + JMM_VERSION_2 = 0x20020000, // JDK 10 + JMM_VERSION = 0x20020000 +}; + +typedef struct { + unsigned int isLowMemoryDetectionSupported : 1; + unsigned int isCompilationTimeMonitoringSupported : 1; + unsigned int isThreadContentionMonitoringSupported : 1; + unsigned int isCurrentThreadCpuTimeSupported : 1; + unsigned int isOtherThreadCpuTimeSupported : 1; + unsigned int isObjectMonitorUsageSupported : 1; + unsigned int isSynchronizerUsageSupported : 1; + unsigned int isThreadAllocatedMemorySupported : 1; + unsigned int isRemoteDiagnosticCommandsSupported : 1; + unsigned int : 22; +} jmmOptionalSupport; + +typedef enum { + JMM_CLASS_LOADED_COUNT = 1, /* Total number of loaded classes */ + JMM_CLASS_UNLOADED_COUNT = 2, /* Total number of unloaded classes */ + JMM_THREAD_TOTAL_COUNT = 3, /* Total number of threads that have been started */ + JMM_THREAD_LIVE_COUNT = 4, /* Current number of live threads */ + JMM_THREAD_PEAK_COUNT = 5, /* Peak number of live threads */ + JMM_THREAD_DAEMON_COUNT = 6, /* Current number of daemon threads */ + JMM_JVM_INIT_DONE_TIME_MS = 7, /* Time when the JVM finished initialization */ + JMM_COMPILE_TOTAL_TIME_MS = 8, /* Total accumulated time spent in compilation */ + JMM_GC_TIME_MS = 9, /* Total accumulated time spent in collection */ + JMM_GC_COUNT = 10, /* Total number of collections */ + JMM_JVM_UPTIME_MS = 11, /* The JVM uptime in milliseconds */ + + JMM_INTERNAL_ATTRIBUTE_INDEX = 100, + JMM_CLASS_LOADED_BYTES = 101, /* Number of bytes loaded instance classes */ + JMM_CLASS_UNLOADED_BYTES = 102, /* Number of bytes unloaded instance classes */ + JMM_TOTAL_CLASSLOAD_TIME_MS = 103, /* Accumulated VM class loader time (TraceClassLoadingTime) */ + JMM_VM_GLOBAL_COUNT = 104, /* Number of VM internal flags */ + JMM_SAFEPOINT_COUNT = 105, /* Total number of safepoints */ + JMM_TOTAL_SAFEPOINTSYNC_TIME_MS = 106, /* Accumulated time spent getting to safepoints */ + JMM_TOTAL_STOPPED_TIME_MS = 107, /* Accumulated time spent at safepoints */ + JMM_TOTAL_APP_TIME_MS = 108, /* Accumulated time spent in Java application */ + JMM_VM_THREAD_COUNT = 109, /* Current number of VM internal threads */ + JMM_CLASS_INIT_TOTAL_COUNT = 110, /* Number of classes for which initializers were run */ + JMM_CLASS_INIT_TOTAL_TIME_MS = 111, /* Accumulated time spent in class initializers */ + JMM_METHOD_DATA_SIZE_BYTES = 112, /* Size of method data in memory */ + JMM_CLASS_VERIFY_TOTAL_TIME_MS = 113, /* Accumulated time spent in class verifier */ + JMM_SHARED_CLASS_LOADED_COUNT = 114, /* Number of shared classes loaded */ + JMM_SHARED_CLASS_UNLOADED_COUNT = 115, /* Number of shared classes unloaded */ + JMM_SHARED_CLASS_LOADED_BYTES = 116, /* Number of bytes loaded shared classes */ + JMM_SHARED_CLASS_UNLOADED_BYTES = 117, /* Number of bytes unloaded shared classes */ + + JMM_OS_ATTRIBUTE_INDEX = 200, + JMM_OS_PROCESS_ID = 201, /* Process id of the JVM */ + JMM_OS_MEM_TOTAL_PHYSICAL_BYTES = 202, /* Physical memory size */ + + JMM_GC_EXT_ATTRIBUTE_INFO_SIZE = 401 /* the size of the GC specific attributes for a given GC memory manager */ +} jmmLongAttribute; + +typedef enum { + JMM_VERBOSE_GC = 21, + JMM_VERBOSE_CLASS = 22, + JMM_THREAD_CONTENTION_MONITORING = 23, + JMM_THREAD_CPU_TIME = 24, + JMM_THREAD_ALLOCATED_MEMORY = 25 +} jmmBoolAttribute; + + +enum { + JMM_THREAD_STATE_FLAG_SUSPENDED = 0x00100000, + JMM_THREAD_STATE_FLAG_NATIVE = 0x00400000 +}; + +#define JMM_THREAD_STATE_FLAG_MASK 0xFFF00000 + +typedef enum { + JMM_STAT_PEAK_THREAD_COUNT = 801, + JMM_STAT_THREAD_CONTENTION_COUNT = 802, + JMM_STAT_THREAD_CONTENTION_TIME = 803, + JMM_STAT_THREAD_CONTENTION_STAT = 804, + JMM_STAT_PEAK_POOL_USAGE = 805, + JMM_STAT_GC_STAT = 806 +} jmmStatisticType; + +typedef enum { + JMM_USAGE_THRESHOLD_HIGH = 901, + JMM_USAGE_THRESHOLD_LOW = 902, + JMM_COLLECTION_USAGE_THRESHOLD_HIGH = 903, + JMM_COLLECTION_USAGE_THRESHOLD_LOW = 904 +} jmmThresholdType; + +/* Should match what is allowed in globals.hpp */ +typedef enum { + JMM_VMGLOBAL_TYPE_UNKNOWN = 0, + JMM_VMGLOBAL_TYPE_JBOOLEAN = 1, + JMM_VMGLOBAL_TYPE_JSTRING = 2, + JMM_VMGLOBAL_TYPE_JLONG = 3, + JMM_VMGLOBAL_TYPE_JDOUBLE = 4 +} jmmVMGlobalType; + +typedef enum { + JMM_VMGLOBAL_ORIGIN_DEFAULT = 1, /* Default value */ + JMM_VMGLOBAL_ORIGIN_COMMAND_LINE = 2, /* Set at command line (or JNI invocation) */ + JMM_VMGLOBAL_ORIGIN_MANAGEMENT = 3, /* Set via management interface */ + JMM_VMGLOBAL_ORIGIN_ENVIRON_VAR = 4, /* Set via environment variables */ + JMM_VMGLOBAL_ORIGIN_CONFIG_FILE = 5, /* Set via config file (such as .hotspotrc) */ + JMM_VMGLOBAL_ORIGIN_ERGONOMIC = 6, /* Set via ergonomic */ + JMM_VMGLOBAL_ORIGIN_ATTACH_ON_DEMAND = 7, /* Set via attach */ + JMM_VMGLOBAL_ORIGIN_OTHER = 99 /* Set via some other mechanism */ +} jmmVMGlobalOrigin; + +typedef struct { + jstring name; + jvalue value; + jmmVMGlobalType type; /* Data type */ + jmmVMGlobalOrigin origin; /* Default or non-default value */ + unsigned int writeable : 1; /* dynamically writeable */ + unsigned int external : 1; /* external supported interface */ + unsigned int reserved : 30; + void *reserved1; + void *reserved2; +} jmmVMGlobal; + +typedef struct { + const char* name; + char type; + const char* description; +} jmmExtAttributeInfo; + +/* Caller has to set the following fields before calling GetLastGCStat + * o usage_before_gc - array of MemoryUsage objects + * o usage_after_gc - array of MemoryUsage objects + * o gc_ext_attribute_values_size - size of gc_ext_atttribute_values array + * o gc_ext_attribtue_values - array of jvalues + */ +typedef struct { + jlong gc_index; /* Index of the collections */ + jlong start_time; /* Start time of the GC */ + jlong end_time; /* End time of the GC */ + jobjectArray usage_before_gc; /* Memory usage array before GC */ + jobjectArray usage_after_gc; /* Memory usage array after GC */ + jint gc_ext_attribute_values_size; /* set by the caller of GetGCStat */ + jvalue* gc_ext_attribute_values; /* Array of jvalue for GC extension attributes */ + jint num_gc_ext_attributes; /* number of GC extension attribute values s are filled */ + /* -1 indicates gc_ext_attribute_values is not big enough */ +} jmmGCStat; + +typedef struct { + const char* name; /* Name of the diagnostic command */ + const char* description; /* Short description */ + const char* impact; /* Impact on the JVM */ + const char* permission_class; /* Class name of the required permission if any */ + const char* permission_name; /* Permission name of the required permission if any */ + const char* permission_action; /* Action name of the required permission if any*/ + int num_arguments; /* Number of supported options or arguments */ + jboolean enabled; /* True if the diagnostic command can be invoked, false otherwise*/ +} dcmdInfo; + +typedef struct { + const char* name; /* Option/Argument name*/ + const char* description; /* Short description */ + const char* type; /* Type: STRING, BOOLEAN, etc. */ + const char* default_string; /* Default value in a parsable string */ + jboolean mandatory; /* True if the option/argument is mandatory */ + jboolean option; /* True if it is an option, false if it is an argument */ + /* (see diagnosticFramework.hpp for option/argument definitions) */ + jboolean multiple; /* True is the option can be specified several time */ + int position; /* Expected position for this argument (this field is */ + /* meaningless for options) */ +} dcmdArgInfo; + +typedef struct jmmInterface_1_ { + void* reserved1; + void* reserved2; + + jint (JNICALL *GetVersion) (JNIEnv *env); + + jint (JNICALL *GetOptionalSupport) (JNIEnv *env, + jmmOptionalSupport* support_ptr); + + jint (JNICALL *GetThreadInfo) (JNIEnv *env, + jlongArray ids, + jint maxDepth, + jobjectArray infoArray); + + jobjectArray (JNICALL *GetMemoryPools) (JNIEnv* env, jobject mgr); + + jobjectArray (JNICALL *GetMemoryManagers) (JNIEnv* env, jobject pool); + + jobject (JNICALL *GetMemoryPoolUsage) (JNIEnv* env, jobject pool); + jobject (JNICALL *GetPeakMemoryPoolUsage) (JNIEnv* env, jobject pool); + + void (JNICALL *GetThreadAllocatedMemory) + (JNIEnv *env, + jlongArray ids, + jlongArray sizeArray); + + jobject (JNICALL *GetMemoryUsage) (JNIEnv* env, jboolean heap); + + jlong (JNICALL *GetLongAttribute) (JNIEnv *env, jobject obj, jmmLongAttribute att); + jboolean (JNICALL *GetBoolAttribute) (JNIEnv *env, jmmBoolAttribute att); + jboolean (JNICALL *SetBoolAttribute) (JNIEnv *env, jmmBoolAttribute att, jboolean flag); + + jint (JNICALL *GetLongAttributes) (JNIEnv *env, + jobject obj, + jmmLongAttribute* atts, + jint count, + jlong* result); + + jobjectArray (JNICALL *FindCircularBlockedThreads) (JNIEnv *env); + + // Not used in JDK 6 or JDK 7 + jlong (JNICALL *GetThreadCpuTime) (JNIEnv *env, jlong thread_id); + + jobjectArray (JNICALL *GetVMGlobalNames) (JNIEnv *env); + jint (JNICALL *GetVMGlobals) (JNIEnv *env, + jobjectArray names, + jmmVMGlobal *globals, + jint count); + + jint (JNICALL *GetInternalThreadTimes) (JNIEnv *env, + jobjectArray names, + jlongArray times); + + jboolean (JNICALL *ResetStatistic) (JNIEnv *env, + jvalue obj, + jmmStatisticType type); + + void (JNICALL *SetPoolSensor) (JNIEnv *env, + jobject pool, + jmmThresholdType type, + jobject sensor); + + jlong (JNICALL *SetPoolThreshold) (JNIEnv *env, + jobject pool, + jmmThresholdType type, + jlong threshold); + jobject (JNICALL *GetPoolCollectionUsage) (JNIEnv* env, jobject pool); + + jint (JNICALL *GetGCExtAttributeInfo) (JNIEnv *env, + jobject mgr, + jmmExtAttributeInfo *ext_info, + jint count); + void (JNICALL *GetLastGCStat) (JNIEnv *env, + jobject mgr, + jmmGCStat *gc_stat); + + jlong (JNICALL *GetThreadCpuTimeWithKind) + (JNIEnv *env, + jlong thread_id, + jboolean user_sys_cpu_time); + void (JNICALL *GetThreadCpuTimesWithKind) + (JNIEnv *env, + jlongArray ids, + jlongArray timeArray, + jboolean user_sys_cpu_time); + + jint (JNICALL *DumpHeap0) (JNIEnv *env, + jstring outputfile, + jboolean live); + jobjectArray (JNICALL *FindDeadlocks) (JNIEnv *env, + jboolean object_monitors_only); + void (JNICALL *SetVMGlobal) (JNIEnv *env, + jstring flag_name, + jvalue new_value); + void* reserved6; + jobjectArray (JNICALL *DumpThreads) (JNIEnv *env, + jlongArray ids, + jboolean lockedMonitors, + jboolean lockedSynchronizers, + jint maxDepth); + void (JNICALL *SetGCNotificationEnabled) (JNIEnv *env, + jobject mgr, + jboolean enabled); + jobjectArray (JNICALL *GetDiagnosticCommands) (JNIEnv *env); + void (JNICALL *GetDiagnosticCommandInfo) + (JNIEnv *env, + jobjectArray cmds, + dcmdInfo *infoArray); + void (JNICALL *GetDiagnosticCommandArgumentsInfo) + (JNIEnv *env, + jstring commandName, + dcmdArgInfo *infoArray); + jstring (JNICALL *ExecuteDiagnosticCommand) + (JNIEnv *env, + jstring command); + void (JNICALL *SetDiagnosticFrameworkNotificationEnabled) + (JNIEnv *env, + jboolean enabled); +} JmmInterface; + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* !_JAVA_JMM_H_ */ diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/include/jvm.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/include/jvm.h Thu Dec 14 12:28:32 2017 +0000 @@ -0,0 +1,1328 @@ +/* + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +#ifndef _JAVASOFT_JVM_H_ +#define _JAVASOFT_JVM_H_ + +#include + +#include "jni.h" +#include "jvm_md.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This file contains additional functions exported from the VM. + * These functions are complementary to the standard JNI support. + * There are three parts to this file: + * + * First, this file contains the VM-related functions needed by native + * libraries in the standard Java API. For example, the java.lang.Object + * class needs VM-level functions that wait for and notify monitors. + * + * Second, this file contains the functions and constant definitions + * needed by the byte code verifier and class file format checker. + * These functions allow the verifier and format checker to be written + * in a VM-independent way. + * + * Third, this file contains various I/O and network operations needed + * by the standard Java I/O and network APIs. + */ + +/* + * Bump the version number when either of the following happens: + * + * 1. There is a change in JVM_* functions. + * + * 2. There is a change in the contract between VM and Java classes. + * For example, if the VM relies on a new private field in Thread + * class. + */ + +#define JVM_INTERFACE_VERSION 5 + +JNIEXPORT jint JNICALL +JVM_GetInterfaceVersion(void); + +/************************************************************************* + PART 1: Functions for Native Libraries + ************************************************************************/ +/* + * java.lang.Object + */ +JNIEXPORT jint JNICALL +JVM_IHashCode(JNIEnv *env, jobject obj); + +JNIEXPORT void JNICALL +JVM_MonitorWait(JNIEnv *env, jobject obj, jlong ms); + +JNIEXPORT void JNICALL +JVM_MonitorNotify(JNIEnv *env, jobject obj); + +JNIEXPORT void JNICALL +JVM_MonitorNotifyAll(JNIEnv *env, jobject obj); + +JNIEXPORT jobject JNICALL +JVM_Clone(JNIEnv *env, jobject obj); + +/* + * java.lang.String + */ +JNIEXPORT jstring JNICALL +JVM_InternString(JNIEnv *env, jstring str); + +/* + * java.lang.System + */ +JNIEXPORT jlong JNICALL +JVM_CurrentTimeMillis(JNIEnv *env, jclass ignored); + +JNIEXPORT jlong JNICALL +JVM_NanoTime(JNIEnv *env, jclass ignored); + +JNIEXPORT jlong JNICALL +JVM_GetNanoTimeAdjustment(JNIEnv *env, jclass ignored, jlong offset_secs); + +JNIEXPORT void JNICALL +JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos, + jobject dst, jint dst_pos, jint length); + +JNIEXPORT jobject JNICALL +JVM_InitProperties(JNIEnv *env, jobject p); + + +/* + * java.lang.Runtime + */ +JNIEXPORT void JNICALL +JVM_Halt(jint code); + +JNIEXPORT void JNICALL +JVM_GC(void); + +/* Returns the number of real-time milliseconds that have elapsed since the + * least-recently-inspected heap object was last inspected by the garbage + * collector. + * + * For simple stop-the-world collectors this value is just the time + * since the most recent collection. For generational collectors it is the + * time since the oldest generation was most recently collected. Other + * collectors are free to return a pessimistic estimate of the elapsed time, or + * simply the time since the last full collection was performed. + * + * Note that in the presence of reference objects, a given object that is no + * longer strongly reachable may have to be inspected multiple times before it + * can be reclaimed. + */ +JNIEXPORT jlong JNICALL +JVM_MaxObjectInspectionAge(void); + +JNIEXPORT jlong JNICALL +JVM_TotalMemory(void); + +JNIEXPORT jlong JNICALL +JVM_FreeMemory(void); + +JNIEXPORT jlong JNICALL +JVM_MaxMemory(void); + +JNIEXPORT jint JNICALL +JVM_ActiveProcessorCount(void); + +JNIEXPORT void * JNICALL +JVM_LoadLibrary(const char *name); + +JNIEXPORT void JNICALL +JVM_UnloadLibrary(void * handle); + +JNIEXPORT void * JNICALL +JVM_FindLibraryEntry(void *handle, const char *name); + +JNIEXPORT jboolean JNICALL +JVM_IsSupportedJNIVersion(jint version); + +JNIEXPORT jobjectArray JNICALL +JVM_GetVmArguments(JNIEnv *env); + + +/* + * java.lang.Throwable + */ +JNIEXPORT void JNICALL +JVM_FillInStackTrace(JNIEnv *env, jobject throwable); + +/* + * java.lang.StackTraceElement + */ +JNIEXPORT void JNICALL +JVM_InitStackTraceElementArray(JNIEnv *env, jobjectArray elements, jobject throwable); + +JNIEXPORT void JNICALL +JVM_InitStackTraceElement(JNIEnv* env, jobject element, jobject stackFrameInfo); + +/* + * java.lang.StackWalker + */ +enum { + JVM_STACKWALK_FILL_CLASS_REFS_ONLY = 0x2, + JVM_STACKWALK_GET_CALLER_CLASS = 0x04, + JVM_STACKWALK_SHOW_HIDDEN_FRAMES = 0x20, + JVM_STACKWALK_FILL_LIVE_STACK_FRAMES = 0x100 +}; + +JNIEXPORT jobject JNICALL +JVM_CallStackWalk(JNIEnv *env, jobject stackStream, jlong mode, + jint skip_frames, jint frame_count, jint start_index, + jobjectArray frames); + +JNIEXPORT jint JNICALL +JVM_MoreStackWalk(JNIEnv *env, jobject stackStream, jlong mode, jlong anchor, + jint frame_count, jint start_index, + jobjectArray frames); + +/* + * java.lang.Thread + */ +JNIEXPORT void JNICALL +JVM_StartThread(JNIEnv *env, jobject thread); + +JNIEXPORT void JNICALL +JVM_StopThread(JNIEnv *env, jobject thread, jobject exception); + +JNIEXPORT jboolean JNICALL +JVM_IsThreadAlive(JNIEnv *env, jobject thread); + +JNIEXPORT void JNICALL +JVM_SuspendThread(JNIEnv *env, jobject thread); + +JNIEXPORT void JNICALL +JVM_ResumeThread(JNIEnv *env, jobject thread); + +JNIEXPORT void JNICALL +JVM_SetThreadPriority(JNIEnv *env, jobject thread, jint prio); + +JNIEXPORT void JNICALL +JVM_Yield(JNIEnv *env, jclass threadClass); + +JNIEXPORT void JNICALL +JVM_Sleep(JNIEnv *env, jclass threadClass, jlong millis); + +JNIEXPORT jobject JNICALL +JVM_CurrentThread(JNIEnv *env, jclass threadClass); + +JNIEXPORT jint JNICALL +JVM_CountStackFrames(JNIEnv *env, jobject thread); + +JNIEXPORT void JNICALL +JVM_Interrupt(JNIEnv *env, jobject thread); + +JNIEXPORT jboolean JNICALL +JVM_IsInterrupted(JNIEnv *env, jobject thread, jboolean clearInterrupted); + +JNIEXPORT jboolean JNICALL +JVM_HoldsLock(JNIEnv *env, jclass threadClass, jobject obj); + +JNIEXPORT void JNICALL +JVM_DumpAllStacks(JNIEnv *env, jclass unused); + +JNIEXPORT jobjectArray JNICALL +JVM_GetAllThreads(JNIEnv *env, jclass dummy); + +JNIEXPORT void JNICALL +JVM_SetNativeThreadName(JNIEnv *env, jobject jthread, jstring name); + +/* getStackTrace() and getAllStackTraces() method */ +JNIEXPORT jobjectArray JNICALL +JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threads); + +/* + * java.lang.SecurityManager + */ +JNIEXPORT jobjectArray JNICALL +JVM_GetClassContext(JNIEnv *env); + +/* + * java.lang.Package + */ +JNIEXPORT jstring JNICALL +JVM_GetSystemPackage(JNIEnv *env, jstring name); + +JNIEXPORT jobjectArray JNICALL +JVM_GetSystemPackages(JNIEnv *env); + +/* + * java.lang.ref.Reference + */ +JNIEXPORT jobject JNICALL +JVM_GetAndClearReferencePendingList(JNIEnv *env); + +JNIEXPORT jboolean JNICALL +JVM_HasReferencePendingList(JNIEnv *env); + +JNIEXPORT void JNICALL +JVM_WaitForReferencePendingList(JNIEnv *env); + +/* + * java.io.ObjectInputStream + */ +JNIEXPORT jobject JNICALL +JVM_LatestUserDefinedLoader(JNIEnv *env); + +/* + * java.lang.reflect.Array + */ +JNIEXPORT jint JNICALL +JVM_GetArrayLength(JNIEnv *env, jobject arr); + +JNIEXPORT jobject JNICALL +JVM_GetArrayElement(JNIEnv *env, jobject arr, jint index); + +JNIEXPORT jvalue JNICALL +JVM_GetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jint wCode); + +JNIEXPORT void JNICALL +JVM_SetArrayElement(JNIEnv *env, jobject arr, jint index, jobject val); + +JNIEXPORT void JNICALL +JVM_SetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jvalue v, + unsigned char vCode); + +JNIEXPORT jobject JNICALL +JVM_NewArray(JNIEnv *env, jclass eltClass, jint length); + +JNIEXPORT jobject JNICALL +JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim); + +/* + * java.lang.Class and java.lang.ClassLoader + */ + +#define JVM_CALLER_DEPTH -1 + +/* + * Returns the immediate caller class of the native method invoking + * JVM_GetCallerClass. The Method.invoke and other frames due to + * reflection machinery are skipped. + * + * The depth parameter must be -1 (JVM_DEPTH). The caller is expected + * to be marked with sun.reflect.CallerSensitive. The JVM will throw + * an error if it is not marked propertly. + */ +JNIEXPORT jclass JNICALL +JVM_GetCallerClass(JNIEnv *env, int depth); + + +/* + * Find primitive classes + * utf: class name + */ +JNIEXPORT jclass JNICALL +JVM_FindPrimitiveClass(JNIEnv *env, const char *utf); + + +/* + * Find a class from a boot class loader. Returns NULL if class not found. + */ +JNIEXPORT jclass JNICALL +JVM_FindClassFromBootLoader(JNIEnv *env, const char *name); + +/* + * Find a class from a given class loader. Throws ClassNotFoundException. + * name: name of class + * init: whether initialization is done + * loader: class loader to look up the class. This may not be the same as the caller's + * class loader. + * caller: initiating class. The initiating class may be null when a security + * manager is not installed. + */ +JNIEXPORT jclass JNICALL +JVM_FindClassFromCaller(JNIEnv *env, const char *name, jboolean init, + jobject loader, jclass caller); + +/* + * Find a class from a given class. + */ +JNIEXPORT jclass JNICALL +JVM_FindClassFromClass(JNIEnv *env, const char *name, jboolean init, + jclass from); + +/* Find a loaded class cached by the VM */ +JNIEXPORT jclass JNICALL +JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name); + +/* Define a class */ +JNIEXPORT jclass JNICALL +JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, + jsize len, jobject pd); + +/* Define a class with a source (added in JDK1.5) */ +JNIEXPORT jclass JNICALL +JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader, + const jbyte *buf, jsize len, jobject pd, + const char *source); + +/* + * Module support funcions + */ + +/* + * Define a module with the specified packages and bind the module to the + * given class loader. + * module: module to define + * is_open: specifies if module is open (currently ignored) + * version: the module version + * location: the module location + * packages: list of packages in the module + * num_packages: number of packages in the module + */ +JNIEXPORT void JNICALL +JVM_DefineModule(JNIEnv *env, jobject module, jboolean is_open, jstring version, + jstring location, const char* const* packages, jsize num_packages); + +/* + * Set the boot loader's unnamed module. + * module: boot loader's unnamed module + */ +JNIEXPORT void JNICALL +JVM_SetBootLoaderUnnamedModule(JNIEnv *env, jobject module); + +/* + * Do a qualified export of a package. + * from_module: module containing the package to export + * package: name of the package to export + * to_module: module to export the package to + */ +JNIEXPORT void JNICALL +JVM_AddModuleExports(JNIEnv *env, jobject from_module, const char* package, jobject to_module); + +/* + * Do an export of a package to all unnamed modules. + * from_module: module containing the package to export + * package: name of the package to export to all unnamed modules + */ +JNIEXPORT void JNICALL +JVM_AddModuleExportsToAllUnnamed(JNIEnv *env, jobject from_module, const char* package); + +/* + * Do an unqualified export of a package. + * from_module: module containing the package to export + * package: name of the package to export + */ +JNIEXPORT void JNICALL +JVM_AddModuleExportsToAll(JNIEnv *env, jobject from_module, const char* package); + +/* + * Add a module to the list of modules that a given module can read. + * from_module: module requesting read access + * source_module: module that from_module wants to read + */ +JNIEXPORT void JNICALL +JVM_AddReadsModule(JNIEnv *env, jobject from_module, jobject source_module); + +/* + * Reflection support functions + */ + +JNIEXPORT jstring JNICALL +JVM_GetClassName(JNIEnv *env, jclass cls); + +JNIEXPORT jobjectArray JNICALL +JVM_GetClassInterfaces(JNIEnv *env, jclass cls); + +JNIEXPORT jboolean JNICALL +JVM_IsInterface(JNIEnv *env, jclass cls); + +JNIEXPORT jobjectArray JNICALL +JVM_GetClassSigners(JNIEnv *env, jclass cls); + +JNIEXPORT void JNICALL +JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers); + +JNIEXPORT jobject JNICALL +JVM_GetProtectionDomain(JNIEnv *env, jclass cls); + +JNIEXPORT jboolean JNICALL +JVM_IsArrayClass(JNIEnv *env, jclass cls); + +JNIEXPORT jboolean JNICALL +JVM_IsPrimitiveClass(JNIEnv *env, jclass cls); + +JNIEXPORT jint JNICALL +JVM_GetClassModifiers(JNIEnv *env, jclass cls); + +JNIEXPORT jobjectArray JNICALL +JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass); + +JNIEXPORT jclass JNICALL +JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass); + +JNIEXPORT jstring JNICALL +JVM_GetSimpleBinaryName(JNIEnv *env, jclass ofClass); + +/* Generics support (JDK 1.5) */ +JNIEXPORT jstring JNICALL +JVM_GetClassSignature(JNIEnv *env, jclass cls); + +/* Annotations support (JDK 1.5) */ +JNIEXPORT jbyteArray JNICALL +JVM_GetClassAnnotations(JNIEnv *env, jclass cls); + +/* Type use annotations support (JDK 1.8) */ + +JNIEXPORT jbyteArray JNICALL +JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls); + +JNIEXPORT jbyteArray JNICALL +JVM_GetFieldTypeAnnotations(JNIEnv *env, jobject field); + +JNIEXPORT jbyteArray JNICALL +JVM_GetMethodTypeAnnotations(JNIEnv *env, jobject method); + +/* + * New (JDK 1.4) reflection implementation + */ + +JNIEXPORT jobjectArray JNICALL +JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly); + +JNIEXPORT jobjectArray JNICALL +JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, jboolean publicOnly); + +JNIEXPORT jobjectArray JNICALL +JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly); + +/* Differs from JVM_GetClassModifiers in treatment of inner classes. + This returns the access flags for the class as specified in the + class file rather than searching the InnerClasses attribute (if + present) to find the source-level access flags. Only the values of + the low 13 bits (i.e., a mask of 0x1FFF) are guaranteed to be + valid. */ +JNIEXPORT jint JNICALL +JVM_GetClassAccessFlags(JNIEnv *env, jclass cls); + +/* The following two reflection routines are still needed due to startup time issues */ +/* + * java.lang.reflect.Method + */ +JNIEXPORT jobject JNICALL +JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jobjectArray args0); + +/* + * java.lang.reflect.Constructor + */ +JNIEXPORT jobject JNICALL +JVM_NewInstanceFromConstructor(JNIEnv *env, jobject c, jobjectArray args0); + +/* + * Constant pool access; currently used to implement reflective access to annotations (JDK 1.5) + */ + +JNIEXPORT jobject JNICALL +JVM_GetClassConstantPool(JNIEnv *env, jclass cls); + +JNIEXPORT jint JNICALL JVM_ConstantPoolGetSize +(JNIEnv *env, jobject unused, jobject jcpool); + +JNIEXPORT jclass JNICALL JVM_ConstantPoolGetClassAt +(JNIEnv *env, jobject unused, jobject jcpool, jint index); + +JNIEXPORT jclass JNICALL JVM_ConstantPoolGetClassAtIfLoaded +(JNIEnv *env, jobject unused, jobject jcpool, jint index); + +JNIEXPORT jint JNICALL JVM_ConstantPoolGetClassRefIndexAt +(JNIEnv *env, jobject obj, jobject unused, jint index); + +JNIEXPORT jobject JNICALL JVM_ConstantPoolGetMethodAt +(JNIEnv *env, jobject unused, jobject jcpool, jint index); + +JNIEXPORT jobject JNICALL JVM_ConstantPoolGetMethodAtIfLoaded +(JNIEnv *env, jobject unused, jobject jcpool, jint index); + +JNIEXPORT jobject JNICALL JVM_ConstantPoolGetFieldAt +(JNIEnv *env, jobject unused, jobject jcpool, jint index); + +JNIEXPORT jobject JNICALL JVM_ConstantPoolGetFieldAtIfLoaded +(JNIEnv *env, jobject unused, jobject jcpool, jint index); + +JNIEXPORT jobjectArray JNICALL JVM_ConstantPoolGetMemberRefInfoAt +(JNIEnv *env, jobject unused, jobject jcpool, jint index); + +JNIEXPORT jint JNICALL JVM_ConstantPoolGetNameAndTypeRefIndexAt +(JNIEnv *env, jobject obj, jobject unused, jint index); + +JNIEXPORT jobjectArray JNICALL JVM_ConstantPoolGetNameAndTypeRefInfoAt +(JNIEnv *env, jobject obj, jobject unused, jint index); + +JNIEXPORT jint JNICALL JVM_ConstantPoolGetIntAt +(JNIEnv *env, jobject unused, jobject jcpool, jint index); + +JNIEXPORT jlong JNICALL JVM_ConstantPoolGetLongAt +(JNIEnv *env, jobject unused, jobject jcpool, jint index); + +JNIEXPORT jfloat JNICALL JVM_ConstantPoolGetFloatAt +(JNIEnv *env, jobject unused, jobject jcpool, jint index); + +JNIEXPORT jdouble JNICALL JVM_ConstantPoolGetDoubleAt +(JNIEnv *env, jobject unused, jobject jcpool, jint index); + +JNIEXPORT jstring JNICALL JVM_ConstantPoolGetStringAt +(JNIEnv *env, jobject unused, jobject jcpool, jint index); + +JNIEXPORT jstring JNICALL JVM_ConstantPoolGetUTF8At +(JNIEnv *env, jobject unused, jobject jcpool, jint index); + +JNIEXPORT jbyte JNICALL JVM_ConstantPoolGetTagAt +(JNIEnv *env, jobject unused, jobject jcpool, jint index); + +/* + * Parameter reflection + */ + +JNIEXPORT jobjectArray JNICALL +JVM_GetMethodParameters(JNIEnv *env, jobject method); + +/* + * java.security.* + */ + +JNIEXPORT jobject JNICALL +JVM_DoPrivileged(JNIEnv *env, jclass cls, + jobject action, jobject context, jboolean wrapException); + +JNIEXPORT jobject JNICALL +JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls); + +JNIEXPORT jobject JNICALL +JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls); + +/* + * Signal support, used to implement the shutdown sequence. Every VM must + * support JVM_SIGINT and JVM_SIGTERM, raising the former for user interrupts + * (^C) and the latter for external termination (kill, system shutdown, etc.). + * Other platform-dependent signal values may also be supported. + */ + +JNIEXPORT void * JNICALL +JVM_RegisterSignal(jint sig, void *handler); + +JNIEXPORT jboolean JNICALL +JVM_RaiseSignal(jint sig); + +JNIEXPORT jint JNICALL +JVM_FindSignal(const char *name); + +/* + * Retrieve the assertion directives for the specified class. + */ +JNIEXPORT jboolean JNICALL +JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls); + +/* + * Retrieve the assertion directives from the VM. + */ +JNIEXPORT jobject JNICALL +JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused); + +/* + * java.util.concurrent.atomic.AtomicLong + */ +JNIEXPORT jboolean JNICALL +JVM_SupportsCX8(void); + +/* + * com.sun.dtrace.jsdt support + */ + +#define JVM_TRACING_DTRACE_VERSION 1 + +/* + * Structure to pass one probe description to JVM + */ +typedef struct { + jmethodID method; + jstring function; + jstring name; + void* reserved[4]; // for future use +} JVM_DTraceProbe; + +/** + * Encapsulates the stability ratings for a DTrace provider field + */ +typedef struct { + jint nameStability; + jint dataStability; + jint dependencyClass; +} JVM_DTraceInterfaceAttributes; + +/* + * Structure to pass one provider description to JVM + */ +typedef struct { + jstring name; + JVM_DTraceProbe* probes; + jint probe_count; + JVM_DTraceInterfaceAttributes providerAttributes; + JVM_DTraceInterfaceAttributes moduleAttributes; + JVM_DTraceInterfaceAttributes functionAttributes; + JVM_DTraceInterfaceAttributes nameAttributes; + JVM_DTraceInterfaceAttributes argsAttributes; + void* reserved[4]; // for future use +} JVM_DTraceProvider; + +/* + * Get the version number the JVM was built with + */ +JNIEXPORT jint JNICALL +JVM_DTraceGetVersion(JNIEnv* env); + +/* + * Register new probe with given signature, return global handle + * + * The version passed in is the version that the library code was + * built with. + */ +JNIEXPORT jlong JNICALL +JVM_DTraceActivate(JNIEnv* env, jint version, jstring module_name, + jint providers_count, JVM_DTraceProvider* providers); + +/* + * Check JSDT probe + */ +JNIEXPORT jboolean JNICALL +JVM_DTraceIsProbeEnabled(JNIEnv* env, jmethodID method); + +/* + * Destroy custom DOF + */ +JNIEXPORT void JNICALL +JVM_DTraceDispose(JNIEnv* env, jlong activation_handle); + +/* + * Check to see if DTrace is supported by OS + */ +JNIEXPORT jboolean JNICALL +JVM_DTraceIsSupported(JNIEnv* env); + +/************************************************************************* + PART 2: Support for the Verifier and Class File Format Checker + ************************************************************************/ +/* + * Return the class name in UTF format. The result is valid + * until JVM_ReleaseUTf is called. + * + * The caller must treat the string as a constant and not modify it + * in any way. + */ +JNIEXPORT const char * JNICALL +JVM_GetClassNameUTF(JNIEnv *env, jclass cb); + +/* + * Returns the constant pool types in the buffer provided by "types." + */ +JNIEXPORT void JNICALL +JVM_GetClassCPTypes(JNIEnv *env, jclass cb, unsigned char *types); + +/* + * Returns the number of Constant Pool entries. + */ +JNIEXPORT jint JNICALL +JVM_GetClassCPEntriesCount(JNIEnv *env, jclass cb); + +/* + * Returns the number of *declared* fields or methods. + */ +JNIEXPORT jint JNICALL +JVM_GetClassFieldsCount(JNIEnv *env, jclass cb); + +JNIEXPORT jint JNICALL +JVM_GetClassMethodsCount(JNIEnv *env, jclass cb); + +/* + * Returns the CP indexes of exceptions raised by a given method. + * Places the result in the given buffer. + * + * The method is identified by method_index. + */ +JNIEXPORT void JNICALL +JVM_GetMethodIxExceptionIndexes(JNIEnv *env, jclass cb, jint method_index, + unsigned short *exceptions); +/* + * Returns the number of exceptions raised by a given method. + * The method is identified by method_index. + */ +JNIEXPORT jint JNICALL +JVM_GetMethodIxExceptionsCount(JNIEnv *env, jclass cb, jint method_index); + +/* + * Returns the byte code sequence of a given method. + * Places the result in the given buffer. + * + * The method is identified by method_index. + */ +JNIEXPORT void JNICALL +JVM_GetMethodIxByteCode(JNIEnv *env, jclass cb, jint method_index, + unsigned char *code); + +/* + * Returns the length of the byte code sequence of a given method. + * The method is identified by method_index. + */ +JNIEXPORT jint JNICALL +JVM_GetMethodIxByteCodeLength(JNIEnv *env, jclass cb, jint method_index); + +/* + * A structure used to a capture exception table entry in a Java method. + */ +typedef struct { + jint start_pc; + jint end_pc; + jint handler_pc; + jint catchType; +} JVM_ExceptionTableEntryType; + +/* + * Returns the exception table entry at entry_index of a given method. + * Places the result in the given buffer. + * + * The method is identified by method_index. + */ +JNIEXPORT void JNICALL +JVM_GetMethodIxExceptionTableEntry(JNIEnv *env, jclass cb, jint method_index, + jint entry_index, + JVM_ExceptionTableEntryType *entry); + +/* + * Returns the length of the exception table of a given method. + * The method is identified by method_index. + */ +JNIEXPORT jint JNICALL +JVM_GetMethodIxExceptionTableLength(JNIEnv *env, jclass cb, int index); + +/* + * Returns the modifiers of a given field. + * The field is identified by field_index. + */ +JNIEXPORT jint JNICALL +JVM_GetFieldIxModifiers(JNIEnv *env, jclass cb, int index); + +/* + * Returns the modifiers of a given method. + * The method is identified by method_index. + */ +JNIEXPORT jint JNICALL +JVM_GetMethodIxModifiers(JNIEnv *env, jclass cb, int index); + +/* + * Returns the number of local variables of a given method. + * The method is identified by method_index. + */ +JNIEXPORT jint JNICALL +JVM_GetMethodIxLocalsCount(JNIEnv *env, jclass cb, int index); + +/* + * Returns the number of arguments (including this pointer) of a given method. + * The method is identified by method_index. + */ +JNIEXPORT jint JNICALL +JVM_GetMethodIxArgsSize(JNIEnv *env, jclass cb, int index); + +/* + * Returns the maximum amount of stack (in words) used by a given method. + * The method is identified by method_index. + */ +JNIEXPORT jint JNICALL +JVM_GetMethodIxMaxStack(JNIEnv *env, jclass cb, int index); + +/* + * Is a given method a constructor. + * The method is identified by method_index. + */ +JNIEXPORT jboolean JNICALL +JVM_IsConstructorIx(JNIEnv *env, jclass cb, int index); + +/* + * Is the given method generated by the VM. + * The method is identified by method_index. + */ +JNIEXPORT jboolean JNICALL +JVM_IsVMGeneratedMethodIx(JNIEnv *env, jclass cb, int index); + +/* + * Returns the name of a given method in UTF format. + * The result remains valid until JVM_ReleaseUTF is called. + * + * The caller must treat the string as a constant and not modify it + * in any way. + */ +JNIEXPORT const char * JNICALL +JVM_GetMethodIxNameUTF(JNIEnv *env, jclass cb, jint index); + +/* + * Returns the signature of a given method in UTF format. + * The result remains valid until JVM_ReleaseUTF is called. + * + * The caller must treat the string as a constant and not modify it + * in any way. + */ +JNIEXPORT const char * JNICALL +JVM_GetMethodIxSignatureUTF(JNIEnv *env, jclass cb, jint index); + +/* + * Returns the name of the field referred to at a given constant pool + * index. + * + * The result is in UTF format and remains valid until JVM_ReleaseUTF + * is called. + * + * The caller must treat the string as a constant and not modify it + * in any way. + */ +JNIEXPORT const char * JNICALL +JVM_GetCPFieldNameUTF(JNIEnv *env, jclass cb, jint index); + +/* + * Returns the name of the method referred to at a given constant pool + * index. + * + * The result is in UTF format and remains valid until JVM_ReleaseUTF + * is called. + * + * The caller must treat the string as a constant and not modify it + * in any way. + */ +JNIEXPORT const char * JNICALL +JVM_GetCPMethodNameUTF(JNIEnv *env, jclass cb, jint index); + +/* + * Returns the signature of the method referred to at a given constant pool + * index. + * + * The result is in UTF format and remains valid until JVM_ReleaseUTF + * is called. + * + * The caller must treat the string as a constant and not modify it + * in any way. + */ +JNIEXPORT const char * JNICALL +JVM_GetCPMethodSignatureUTF(JNIEnv *env, jclass cb, jint index); + +/* + * Returns the signature of the field referred to at a given constant pool + * index. + * + * The result is in UTF format and remains valid until JVM_ReleaseUTF + * is called. + * + * The caller must treat the string as a constant and not modify it + * in any way. + */ +JNIEXPORT const char * JNICALL +JVM_GetCPFieldSignatureUTF(JNIEnv *env, jclass cb, jint index); + +/* + * Returns the class name referred to at a given constant pool index. + * + * The result is in UTF format and remains valid until JVM_ReleaseUTF + * is called. + * + * The caller must treat the string as a constant and not modify it + * in any way. + */ +JNIEXPORT const char * JNICALL +JVM_GetCPClassNameUTF(JNIEnv *env, jclass cb, jint index); + +/* + * Returns the class name referred to at a given constant pool index. + * + * The constant pool entry must refer to a CONSTANT_Fieldref. + * + * The result is in UTF format and remains valid until JVM_ReleaseUTF + * is called. + * + * The caller must treat the string as a constant and not modify it + * in any way. + */ +JNIEXPORT const char * JNICALL +JVM_GetCPFieldClassNameUTF(JNIEnv *env, jclass cb, jint index); + +/* + * Returns the class name referred to at a given constant pool index. + * + * The constant pool entry must refer to CONSTANT_Methodref or + * CONSTANT_InterfaceMethodref. + * + * The result is in UTF format and remains valid until JVM_ReleaseUTF + * is called. + * + * The caller must treat the string as a constant and not modify it + * in any way. + */ +JNIEXPORT const char * JNICALL +JVM_GetCPMethodClassNameUTF(JNIEnv *env, jclass cb, jint index); + +/* + * Returns the modifiers of a field in calledClass. The field is + * referred to in class cb at constant pool entry index. + * + * The caller must treat the string as a constant and not modify it + * in any way. + * + * Returns -1 if the field does not exist in calledClass. + */ +JNIEXPORT jint JNICALL +JVM_GetCPFieldModifiers(JNIEnv *env, jclass cb, int index, jclass calledClass); + +/* + * Returns the modifiers of a method in calledClass. The method is + * referred to in class cb at constant pool entry index. + * + * Returns -1 if the method does not exist in calledClass. + */ +JNIEXPORT jint JNICALL +JVM_GetCPMethodModifiers(JNIEnv *env, jclass cb, int index, jclass calledClass); + +/* + * Releases the UTF string obtained from the VM. + */ +JNIEXPORT void JNICALL +JVM_ReleaseUTF(const char *utf); + +/* + * Compare if two classes are in the same package. + */ +JNIEXPORT jboolean JNICALL +JVM_IsSameClassPackage(JNIEnv *env, jclass class1, jclass class2); + +/* Get classfile constants */ +#include "classfile_constants.h" + +/* + * A function defined by the byte-code verifier and called by the VM. + * This is not a function implemented in the VM. + * + * Returns JNI_FALSE if verification fails. A detailed error message + * will be places in msg_buf, whose length is specified by buf_len. + */ +typedef jboolean (*verifier_fn_t)(JNIEnv *env, + jclass cb, + char * msg_buf, + jint buf_len); + + +/* + * Support for a VM-independent class format checker. + */ +typedef struct { + unsigned long code; /* byte code */ + unsigned long excs; /* exceptions */ + unsigned long etab; /* catch table */ + unsigned long lnum; /* line number */ + unsigned long lvar; /* local vars */ +} method_size_info; + +typedef struct { + unsigned int constants; /* constant pool */ + unsigned int fields; + unsigned int methods; + unsigned int interfaces; + unsigned int fields2; /* number of static 2-word fields */ + unsigned int innerclasses; /* # of records in InnerClasses attr */ + + method_size_info clinit; /* memory used in clinit */ + method_size_info main; /* used everywhere else */ +} class_size_info; + +/* + * Functions defined in libjava.so to perform string conversions. + * + */ + +typedef jstring (*to_java_string_fn_t)(JNIEnv *env, char *str); + +typedef char *(*to_c_string_fn_t)(JNIEnv *env, jstring s, jboolean *b); + +/* This is the function defined in libjava.so that performs class + * format checks. This functions fills in size information about + * the class file and returns: + * + * 0: good + * -1: out of memory + * -2: bad format + * -3: unsupported version + * -4: bad class name + */ + +typedef jint (*check_format_fn_t)(char *class_name, + unsigned char *data, + unsigned int data_size, + class_size_info *class_size, + char *message_buffer, + jint buffer_length, + jboolean measure_only, + jboolean check_relaxed); + +#define JVM_RECOGNIZED_CLASS_MODIFIERS (JVM_ACC_PUBLIC | \ + JVM_ACC_FINAL | \ + JVM_ACC_SUPER | \ + JVM_ACC_INTERFACE | \ + JVM_ACC_ABSTRACT | \ + JVM_ACC_ANNOTATION | \ + JVM_ACC_ENUM | \ + JVM_ACC_SYNTHETIC) + +#define JVM_RECOGNIZED_FIELD_MODIFIERS (JVM_ACC_PUBLIC | \ + JVM_ACC_PRIVATE | \ + JVM_ACC_PROTECTED | \ + JVM_ACC_STATIC | \ + JVM_ACC_FINAL | \ + JVM_ACC_VOLATILE | \ + JVM_ACC_TRANSIENT | \ + JVM_ACC_ENUM | \ + JVM_ACC_SYNTHETIC) + +#define JVM_RECOGNIZED_METHOD_MODIFIERS (JVM_ACC_PUBLIC | \ + JVM_ACC_PRIVATE | \ + JVM_ACC_PROTECTED | \ + JVM_ACC_STATIC | \ + JVM_ACC_FINAL | \ + JVM_ACC_SYNCHRONIZED | \ + JVM_ACC_BRIDGE | \ + JVM_ACC_VARARGS | \ + JVM_ACC_NATIVE | \ + JVM_ACC_ABSTRACT | \ + JVM_ACC_STRICT | \ + JVM_ACC_SYNTHETIC) + +/* + * This is the function defined in libjava.so to perform path + * canonicalization. VM call this function before opening jar files + * to load system classes. + * + */ + +typedef int (*canonicalize_fn_t)(JNIEnv *env, char *orig, char *out, int len); + +/************************************************************************* + PART 3: I/O and Network Support + ************************************************************************/ + +/* + * Convert a pathname into native format. This function does syntactic + * cleanup, such as removing redundant separator characters. It modifies + * the given pathname string in place. + */ +JNIEXPORT char * JNICALL +JVM_NativePath(char *); + +/* + * The standard printing functions supported by the Java VM. (Should they + * be renamed to JVM_* in the future? + */ + +/* jio_snprintf() and jio_vsnprintf() behave like snprintf(3) and vsnprintf(3), + * respectively, with the following differences: + * - The string written to str is always zero-terminated, also in case of + * truncation (count is too small to hold the result string), unless count + * is 0. In case of truncation count-1 characters are written and '\0' + * appendend. + * - If count is too small to hold the whole string, -1 is returned across + * all platforms. */ + +JNIEXPORT int +jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args); + +JNIEXPORT int +jio_snprintf(char *str, size_t count, const char *fmt, ...); + +JNIEXPORT int +jio_fprintf(FILE *, const char *fmt, ...); + +JNIEXPORT int +jio_vfprintf(FILE *, const char *fmt, va_list args); + + +JNIEXPORT void * JNICALL +JVM_RawMonitorCreate(void); + +JNIEXPORT void JNICALL +JVM_RawMonitorDestroy(void *mon); + +JNIEXPORT jint JNICALL +JVM_RawMonitorEnter(void *mon); + +JNIEXPORT void JNICALL +JVM_RawMonitorExit(void *mon); + +/* + * java.lang.management support + */ +JNIEXPORT void* JNICALL +JVM_GetManagement(jint version); + +/* + * com.sun.tools.attach.VirtualMachine support + * + * Initialize the agent properties with the properties maintained in the VM. + */ +JNIEXPORT jobject JNICALL +JVM_InitAgentProperties(JNIEnv *env, jobject agent_props); + +JNIEXPORT jstring JNICALL +JVM_GetTemporaryDirectory(JNIEnv *env); + +/* Generics reflection support. + * + * Returns information about the given class's EnclosingMethod + * attribute, if present, or null if the class had no enclosing + * method. + * + * If non-null, the returned array contains three elements. Element 0 + * is the java.lang.Class of which the enclosing method is a member, + * and elements 1 and 2 are the java.lang.Strings for the enclosing + * method's name and descriptor, respectively. + */ +JNIEXPORT jobjectArray JNICALL +JVM_GetEnclosingMethodInfo(JNIEnv* env, jclass ofClass); + +/* ========================================================================= + * The following defines a private JVM interface that the JDK can query + * for the JVM version and capabilities. sun.misc.Version defines + * the methods for getting the VM version and its capabilities. + * + * When a new bit is added, the following should be updated to provide + * access to the new capability: + * HS: JVM_GetVersionInfo and Abstract_VM_Version class + * SDK: Version class + * + * Similary, a private JDK interface JDK_GetVersionInfo0 is defined for + * JVM to query for the JDK version and capabilities. + * + * When a new bit is added, the following should be updated to provide + * access to the new capability: + * HS: JDK_Version class + * SDK: JDK_GetVersionInfo0 + * + * ========================================================================== + */ +typedef struct { + unsigned int jvm_version; /* Encoded $VNUM as specified by JEP-223 */ + unsigned int patch_version : 8; /* JEP-223 patch version */ + unsigned int reserved3 : 8; + unsigned int reserved1 : 16; + unsigned int reserved2; + + /* The following bits represents JVM supports that JDK has dependency on. + * JDK can use these bits to determine which JVM version + * and support it has to maintain runtime compatibility. + * + * When a new bit is added in a minor or update release, make sure + * the new bit is also added in the main/baseline. + */ + unsigned int is_attach_supported : 1; + unsigned int : 31; + unsigned int : 32; + unsigned int : 32; +} jvm_version_info; + +#define JVM_VERSION_MAJOR(version) ((version & 0xFF000000) >> 24) +#define JVM_VERSION_MINOR(version) ((version & 0x00FF0000) >> 16) +#define JVM_VERSION_SECURITY(version) ((version & 0x0000FF00) >> 8) +#define JVM_VERSION_BUILD(version) ((version & 0x000000FF)) + +JNIEXPORT void JNICALL +JVM_GetVersionInfo(JNIEnv* env, jvm_version_info* info, size_t info_size); + +typedef struct { + unsigned int jdk_version; /* Encoded $VNUM as specified by JEP-223 */ + unsigned int patch_version : 8; /* JEP-223 patch version */ + unsigned int reserved3 : 8; + unsigned int reserved1 : 16; + unsigned int reserved2; + + /* The following bits represents new JDK supports that VM has dependency on. + * VM implementation can use these bits to determine which JDK version + * and support it has to maintain runtime compatibility. + * + * When a new bit is added in a minor or update release, make sure + * the new bit is also added in the main/baseline. + */ + unsigned int thread_park_blocker : 1; + unsigned int post_vm_init_hook_enabled : 1; + unsigned int pending_list_uses_discovered_field : 1; + unsigned int : 29; + unsigned int : 32; + unsigned int : 32; +} jdk_version_info; + +#define JDK_VERSION_MAJOR(version) ((version & 0xFF000000) >> 24) +#define JDK_VERSION_MINOR(version) ((version & 0x00FF0000) >> 16) +#define JDK_VERSION_SECURITY(version) ((version & 0x0000FF00) >> 8) +#define JDK_VERSION_BUILD(version) ((version & 0x000000FF)) + +/* + * This is the function JDK_GetVersionInfo0 defined in libjava.so + * that is dynamically looked up by JVM. + */ +typedef void (*jdk_version_info_fn_t)(jdk_version_info* info, size_t info_size); + +/* + * This structure is used by the launcher to get the default thread + * stack size from the VM using JNI_GetDefaultJavaVMInitArgs() with a + * version of 1.1. As it is not supported otherwise, it has been removed + * from jni.h + */ +typedef struct JDK1_1InitArgs { + jint version; + + char **properties; + jint checkSource; + jint nativeStackSize; + jint javaStackSize; + jint minHeapSize; + jint maxHeapSize; + jint verifyMode; + char *classpath; + + jint (JNICALL *vfprintf)(FILE *fp, const char *format, va_list args); + void (JNICALL *exit)(jint code); + void (JNICALL *abort)(void); + + jint enableClassGC; + jint enableVerboseGC; + jint disableAsyncGC; + jint verbose; + jboolean debugging; + jint debugPort; +} JDK1_1InitArgs; + + +#ifdef __cplusplus +} /* extern "C" */ + +#endif /* __cplusplus */ + +#endif /* !_JAVASOFT_JVM_H_ */ diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/jvmci/jvmciEnv.cpp --- a/src/hotspot/share/jvmci/jvmciEnv.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/jvmci/jvmciEnv.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -410,8 +410,8 @@ // ------------------------------------------------------------------ // Check for changes to the system dictionary during compilation // class loads, evolution, breakpoints -JVMCIEnv::CodeInstallResult JVMCIEnv::check_for_system_dictionary_modification(Dependencies* dependencies, Handle compiled_code, - JVMCIEnv* env, char** failure_detail) { +JVMCIEnv::CodeInstallResult JVMCIEnv::validate_compile_task_dependencies(Dependencies* dependencies, Handle compiled_code, + JVMCIEnv* env, char** failure_detail) { // If JVMTI capabilities were enabled during compile, the compilation is invalidated. if (env != NULL) { if (!env->_jvmti_can_hotswap_or_post_breakpoint && JvmtiExport::can_hotswap_or_post_breakpoint()) { @@ -422,37 +422,20 @@ // Dependencies must be checked when the system dictionary changes // or if we don't know whether it has changed (i.e., env == NULL). - // In debug mode, always check dependencies. - bool counter_changed = env != NULL && env->_system_dictionary_modification_counter != SystemDictionary::number_of_modifications(); - bool verify_deps = env == NULL || trueInDebug || JavaAssertions::enabled(SystemDictionary::HotSpotInstalledCode_klass()->name()->as_C_string(), true); - if (!counter_changed && !verify_deps) { + bool counter_changed = env == NULL || env->_system_dictionary_modification_counter != SystemDictionary::number_of_modifications(); + CompileTask* task = env == NULL ? NULL : env->task(); + Dependencies::DepType result = dependencies->validate_dependencies(task, counter_changed, failure_detail); + if (result == Dependencies::end_marker) { return JVMCIEnv::ok; } - for (Dependencies::DepStream deps(dependencies); deps.next(); ) { - Klass* witness = deps.check_dependency(); - if (witness != NULL) { - // Use a fixed size buffer to prevent the string stream from - // resizing in the context of an inner resource mark. - char* buffer = NEW_RESOURCE_ARRAY(char, O_BUFLEN); - stringStream st(buffer, O_BUFLEN); - deps.print_dependency(witness, true, &st); - *failure_detail = st.as_string(); - if (env == NULL || counter_changed || deps.type() == Dependencies::evol_method) { - return JVMCIEnv::dependencies_failed; - } else { - // The dependencies were invalid at the time of installation - // without any intervening modification of the system - // dictionary. That means they were invalidly constructed. - return JVMCIEnv::dependencies_invalid; - } - } - if (LogCompilation) { - deps.log_dependency(); - } + if (!Dependencies::is_klass_type(result) || counter_changed) { + return JVMCIEnv::dependencies_failed; } - - return JVMCIEnv::ok; + // The dependencies were invalid at the time of installation + // without any intervening modification of the system + // dictionary. That means they were invalidly constructed. + return JVMCIEnv::dependencies_invalid; } // ------------------------------------------------------------------ @@ -492,8 +475,15 @@ // Encode the dependencies now, so we can check them right away. dependencies->encode_content_bytes(); + // Record the dependencies for the current compile in the log + if (LogCompilation) { + for (Dependencies::DepStream deps(dependencies); deps.next(); ) { + deps.log_dependency(); + } + } + // Check for {class loads, evolution, breakpoints} during compilation - result = check_for_system_dictionary_modification(dependencies, compiled_code, env, &failure_detail); + result = validate_compile_task_dependencies(dependencies, compiled_code, env, &failure_detail); if (result != JVMCIEnv::ok) { // While not a true deoptimization, it is a preemptive decompile. MethodData* mdp = method()->method_data(); diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/jvmci/jvmciEnv.hpp --- a/src/hotspot/share/jvmci/jvmciEnv.hpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/jvmci/jvmciEnv.hpp Thu Dec 14 12:28:32 2017 +0000 @@ -138,8 +138,8 @@ // Helper routine for determining the validity of a compilation // with respect to concurrent class loading. - static JVMCIEnv::CodeInstallResult check_for_system_dictionary_modification(Dependencies* target, Handle compiled_code, - JVMCIEnv* env, char** failure_detail); + static JVMCIEnv::CodeInstallResult validate_compile_task_dependencies(Dependencies* target, Handle compiled_code, + JVMCIEnv* env, char** failure_detail); public: CompileTask* task() { return _task; } diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/opto/c2_globals.hpp --- a/src/hotspot/share/opto/c2_globals.hpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/opto/c2_globals.hpp Thu Dec 14 12:28:32 2017 +0000 @@ -195,6 +195,9 @@ product(bool, UseSubwordForMaxVector, true, \ "Use Subword Analysis to set maximum vector size") \ \ + product(bool, UseVectorCmov, false, \ + "Use Vectorized Cmov") \ + \ develop(intx, UnrollLimitForProfileCheck, 1, \ "Don't use profile_trip_cnt() to restrict unrolling until " \ "unrolling would push the number of unrolled iterations above " \ diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/opto/classes.hpp --- a/src/hotspot/share/opto/classes.hpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/opto/classes.hpp Thu Dec 14 12:28:32 2017 +0000 @@ -66,6 +66,7 @@ macro(CMoveD) macro(CMoveVD) macro(CMoveF) +macro(CMoveVF) macro(CMoveI) macro(CMoveL) macro(CMoveP) diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/opto/loopopts.cpp --- a/src/hotspot/share/opto/loopopts.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/opto/loopopts.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -528,13 +528,12 @@ BasicType bt = phi->type()->basic_type(); switch (bt) { case T_DOUBLE: + case T_FLOAT: if (C->use_cmove()) { continue; //TODO: maybe we want to add some cost } - case T_FLOAT: { cost += Matcher::float_cmove_cost(); // Could be very expensive break; - } case T_LONG: { cost += Matcher::long_cmove_cost(); // May encodes as 2 CMOV's } @@ -613,8 +612,9 @@ } // Check for highly predictable branch. No point in CMOV'ing if // we are going to predict accurately all the time. - if (C->use_cmove() && cmp_op == Op_CmpD) ;//keep going - else if (iff->_prob < infrequent_prob || + if (C->use_cmove() && (cmp_op == Op_CmpF || cmp_op == Op_CmpD)) { + //keep going + } else if (iff->_prob < infrequent_prob || iff->_prob > (1.0f - infrequent_prob)) return NULL; diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/opto/matcher.cpp --- a/src/hotspot/share/opto/matcher.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/opto/matcher.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -2267,6 +2267,7 @@ case Op_CMoveL: case Op_CMoveN: case Op_CMoveP: + case Op_CMoveVF: case Op_CMoveVD: { // Restructure into a binary tree for Matching. It's possible that // we could move this code up next to the graph reshaping for IfNodes diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/opto/superword.cpp --- a/src/hotspot/share/opto/superword.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/opto/superword.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -58,7 +58,7 @@ _mem_slice_tail(arena(), 8, 0, NULL), // memory slice tails _node_info(arena(), 8, 0, SWNodeInfo::initial), // info needed per node _clone_map(phase->C->clone_map()), // map of nodes created in cloning - _cmovev_kit(_arena, this), // map to facilitate CMoveVD creation + _cmovev_kit(_arena, this), // map to facilitate CMoveV creation _align_to_ref(NULL), // memory reference to align vectors to _disjoint_ptrs(arena(), 8, 0, OrderedPair::initial), // runtime disambiguated pointer pairs _dg(_arena), // dependence graph @@ -511,8 +511,7 @@ combine_packs(); construct_my_pack_map(); - - if (_do_vector_loop) { + if (UseVectorCmov) { merge_packs_to_cmovd(); } @@ -1249,8 +1248,8 @@ //------------------------------data_size--------------------------- int SuperWord::data_size(Node* s) { - Node* use = NULL; //test if the node is a candidate for CMoveVD optimization, then return the size of CMov - if (_do_vector_loop) { + Node* use = NULL; //test if the node is a candidate for CMoveV optimization, then return the size of CMov + if (UseVectorCmov) { use = _cmovev_kit.is_Bool_candidate(s); if (use != NULL) { return data_size(use); @@ -1260,6 +1259,7 @@ return data_size(use); } } + int bsize = type2aelembytes(velt_basic_type(s)); assert(bsize != 0, "valid size"); return bsize; @@ -1718,6 +1718,9 @@ if (!cmovd->is_CMove()) { return NULL; } + if (cmovd->Opcode() != Op_CMoveF && cmovd->Opcode() != Op_CMoveD) { + return NULL; + } if (pack(cmovd) != NULL) { // already in the cmov pack return NULL; } @@ -2377,7 +2380,13 @@ } BasicType bt = velt_basic_type(n); const TypeVect* vt = TypeVect::make(bt, vlen); - vn = new CMoveVDNode(cc, src1, src2, vt); + assert(bt == T_FLOAT || bt == T_DOUBLE, "Only vectorization for FP cmovs is supported"); + if (bt == T_FLOAT) { + vn = new CMoveVFNode(cc, src1, src2, vt); + } else { + assert(bt == T_DOUBLE, "Expected double"); + vn = new CMoveVDNode(cc, src1, src2, vt); + } NOT_PRODUCT(if(is_trace_cmov()) {tty->print("SWPointer::output: created new CMove node %d: ", vn->_idx); vn->dump();}) } else if (opc == Op_FmaD || opc == Op_FmaF) { // Promote operands to vector diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/opto/vectornode.cpp --- a/src/hotspot/share/opto/vectornode.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/opto/vectornode.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -92,6 +92,9 @@ case Op_FmaF: assert(bt == T_FLOAT, "must be"); return Op_FmaVF; + case Op_CMoveF: + assert(bt == T_FLOAT, "must be"); + return Op_CMoveVF; case Op_CMoveD: assert(bt == T_DOUBLE, "must be"); return Op_CMoveVD; diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/opto/vectornode.hpp --- a/src/hotspot/share/opto/vectornode.hpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/opto/vectornode.hpp Thu Dec 14 12:28:32 2017 +0000 @@ -277,8 +277,16 @@ virtual int Opcode() const; }; +//------------------------------CMoveVFNode-------------------------------------- +// Vector float conditional move +class CMoveVFNode : public VectorNode { +public: + CMoveVFNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {} + virtual int Opcode() const; +}; + //------------------------------CMoveVDNode-------------------------------------- -// Vector multiply double +// Vector double conditional move class CMoveVDNode : public VectorNode { public: CMoveVDNode(Node* in1, Node* in2, Node* in3, const TypeVect* vt) : VectorNode(in1, in2, in3, vt) {} diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/prims/nativeLookup.cpp --- a/src/hotspot/share/prims/nativeLookup.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/prims/nativeLookup.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -224,7 +224,13 @@ st.print_raw(long_name); if (os_style) os::print_jni_name_suffix_on(&st, args_size); char* jni_name = st.as_string(); - return (address)os::dll_lookup(dll, jni_name); + address critical_entry = (address)os::dll_lookup(dll, jni_name); + // Close the handle to avoid keeping the library alive if the native method holder is unloaded. + // This is fine because the library is still kept alive by JNI (see JVM_LoadLibrary). As soon + // as the holder class and the library are unloaded (see JVM_UnloadLibrary), the native wrapper + // that calls 'critical_entry' becomes unreachable and is unloaded as well. + os::dll_unload(dll); + return critical_entry; } } @@ -245,7 +251,6 @@ + (method->is_static() ? 1 : 0) // class for static methods + method->size_of_parameters(); // actual parameters - // 1) Try JNI short style entry = lookup_style(method, pure_name, "", args_size, true, in_base_library, CHECK_NULL); if (entry != NULL) return entry; diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/runtime/java.cpp --- a/src/hotspot/share/runtime/java.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/runtime/java.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -357,7 +357,7 @@ MemTracker::final_report(tty); } - Threads::log_smr_statistics(); + ThreadsSMRSupport::log_smr_statistics(); } #else // PRODUCT MODE STATISTICS @@ -399,7 +399,7 @@ Method::print_touched_methods(tty); } - Threads::log_smr_statistics(); + ThreadsSMRSupport::log_smr_statistics(); } #endif diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/runtime/thread.cpp --- a/src/hotspot/share/runtime/thread.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/runtime/thread.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -107,7 +107,6 @@ #include "utilities/events.hpp" #include "utilities/macros.hpp" #include "utilities/preserveException.hpp" -#include "utilities/resourceHash.hpp" #include "utilities/vmError.hpp" #if INCLUDE_ALL_GCS #include "gc/cms/concurrentMarkSweepThread.hpp" @@ -207,7 +206,7 @@ void JavaThread::smr_delete() { if (_on_thread_list) { - Threads::smr_delete(this); + ThreadsSMRSupport::smr_delete(this); } else { delete this; } @@ -419,7 +418,7 @@ assert(!thread->is_Java_thread() || Thread::current() == thread || !((JavaThread *) thread)->on_thread_list() || SafepointSynchronize::is_at_safepoint() || - Threads::is_a_protected_JavaThread_with_lock((JavaThread *) thread), + ThreadsSMRSupport::is_a_protected_JavaThread_with_lock((JavaThread *) thread), "possibility of dangling Thread pointer"); } #endif @@ -3443,103 +3442,15 @@ // would like. We are actively migrating Threads_lock uses to other // mechanisms in order to reduce Threads_lock contention. -JavaThread* Threads::_thread_list = NULL; -int Threads::_number_of_threads = 0; -int Threads::_number_of_non_daemon_threads = 0; -int Threads::_return_code = 0; -int Threads::_thread_claim_parity = 0; -size_t JavaThread::_stack_size_at_create = 0; -// Safe Memory Reclamation (SMR) support: -Monitor* Threads::_smr_delete_lock = - new Monitor(Monitor::special, "smr_delete_lock", - false /* allow_vm_block */, - Monitor::_safepoint_check_never); -// The '_cnt', '_max' and '_times" fields are enabled via -// -XX:+EnableThreadSMRStatistics: - -// # of parallel threads in _smr_delete_lock->wait(). -// Impl note: Hard to imagine > 64K waiting threads so this could be 16-bit, -// but there is no nice 16-bit _FORMAT support. -uint Threads::_smr_delete_lock_wait_cnt = 0; - -// Max # of parallel threads in _smr_delete_lock->wait(). -// Impl note: See _smr_delete_lock_wait_cnt note. -uint Threads::_smr_delete_lock_wait_max = 0; - -// Flag to indicate when an _smr_delete_lock->notify() is needed. -// Impl note: See _smr_delete_lock_wait_cnt note. -volatile uint Threads::_smr_delete_notify = 0; - -// # of threads deleted over VM lifetime. -// Impl note: Atomically incremented over VM lifetime so use unsigned for more -// range. Unsigned 64-bit would be more future proof, but 64-bit atomic inc -// isn't available everywhere (or is it?). -volatile uint Threads::_smr_deleted_thread_cnt = 0; - -// Max time in millis to delete a thread. -// Impl note: 16-bit might be too small on an overloaded machine. Use -// unsigned since this is a time value. Set via Atomic::cmpxchg() in a -// loop for correctness. -volatile uint Threads::_smr_deleted_thread_time_max = 0; - -// Cumulative time in millis to delete threads. -// Impl note: Atomically added to over VM lifetime so use unsigned for more -// range. Unsigned 64-bit would be more future proof, but 64-bit atomic inc -// isn't available everywhere (or is it?). -volatile uint Threads::_smr_deleted_thread_times = 0; - -ThreadsList* volatile Threads::_smr_java_thread_list = new ThreadsList(0); - -// # of ThreadsLists allocated over VM lifetime. -// Impl note: We allocate a new ThreadsList for every thread create and -// every thread delete so we need a bigger type than the -// _smr_deleted_thread_cnt field. -uint64_t Threads::_smr_java_thread_list_alloc_cnt = 1; - -// # of ThreadsLists freed over VM lifetime. -// Impl note: See _smr_java_thread_list_alloc_cnt note. -uint64_t Threads::_smr_java_thread_list_free_cnt = 0; - -// Max size ThreadsList allocated. -// Impl note: Max # of threads alive at one time should fit in unsigned 32-bit. -uint Threads::_smr_java_thread_list_max = 0; - -// Max # of nested ThreadsLists for a thread. -// Impl note: Hard to imagine > 64K nested ThreadsLists so this could be -// 16-bit, but there is no nice 16-bit _FORMAT support. -uint Threads::_smr_nested_thread_list_max = 0; - -// # of ThreadsListHandles deleted over VM lifetime. -// Impl note: Atomically incremented over VM lifetime so use unsigned for -// more range. There will be fewer ThreadsListHandles than threads so -// unsigned 32-bit should be fine. -volatile uint Threads::_smr_tlh_cnt = 0; - -// Max time in millis to delete a ThreadsListHandle. -// Impl note: 16-bit might be too small on an overloaded machine. Use -// unsigned since this is a time value. Set via Atomic::cmpxchg() in a -// loop for correctness. -volatile uint Threads::_smr_tlh_time_max = 0; - -// Cumulative time in millis to delete ThreadsListHandles. -// Impl note: Atomically added to over VM lifetime so use unsigned for more -// range. Unsigned 64-bit would be more future proof, but 64-bit atomic inc -// isn't available everywhere (or is it?). -volatile uint Threads::_smr_tlh_times = 0; - -ThreadsList* Threads::_smr_to_delete_list = NULL; - -// # of parallel ThreadsLists on the to-delete list. -// Impl note: Hard to imagine > 64K ThreadsLists needing to be deleted so -// this could be 16-bit, but there is no nice 16-bit _FORMAT support. -uint Threads::_smr_to_delete_list_cnt = 0; - -// Max # of parallel ThreadsLists on the to-delete list. -// Impl note: See _smr_to_delete_list_cnt note. -uint Threads::_smr_to_delete_list_max = 0; +JavaThread* Threads::_thread_list = NULL; +int Threads::_number_of_threads = 0; +int Threads::_number_of_non_daemon_threads = 0; +int Threads::_return_code = 0; +int Threads::_thread_claim_parity = 0; +size_t JavaThread::_stack_size_at_create = 0; #ifdef ASSERT -bool Threads::_vm_complete = false; +bool Threads::_vm_complete = false; #endif static inline void *prefetch_and_load_ptr(void **addr, intx prefetch_interval) { @@ -3561,12 +3472,8 @@ MACRO_current_p++, \ X = (JavaThread*)prefetch_and_load_ptr((void**)MACRO_current_p, (intx)MACRO_scan_interval)) -inline ThreadsList* Threads::get_smr_java_thread_list() { - return (ThreadsList*)OrderAccess::load_acquire(&_smr_java_thread_list); -} - // All JavaThreads -#define ALL_JAVA_THREADS(X) DO_JAVA_THREADS(get_smr_java_thread_list(), X) +#define ALL_JAVA_THREADS(X) DO_JAVA_THREADS(ThreadsSMRSupport::get_smr_java_thread_list(), X) // All JavaThreads + all non-JavaThreads (i.e., every thread in the system) void Threads::threads_do(ThreadClosure* tc) { @@ -3667,240 +3574,6 @@ vmSymbols::void_method_signature(), CHECK); } -// Safe Memory Reclamation (SMR) support: -// - -// Acquire a stable ThreadsList. -// -ThreadsList *Threads::acquire_stable_list(Thread *self, bool is_ThreadsListSetter) { - assert(self != NULL, "sanity check"); - // acquire_stable_list_nested_path() will grab the Threads_lock - // so let's make sure the ThreadsListHandle is in a safe place. - // ThreadsListSetter cannot make this check on this code path. - debug_only(if (!is_ThreadsListSetter && StrictSafepointChecks) self->check_for_valid_safepoint_state(/* potential_vm_operation */ false);) - - if (self->get_threads_hazard_ptr() == NULL) { - // The typical case is first. - return acquire_stable_list_fast_path(self); - } - - // The nested case is rare. - return acquire_stable_list_nested_path(self); -} - -// Fast path (and lock free) way to acquire a stable ThreadsList. -// -ThreadsList *Threads::acquire_stable_list_fast_path(Thread *self) { - assert(self != NULL, "sanity check"); - assert(self->get_threads_hazard_ptr() == NULL, "sanity check"); - assert(self->get_nested_threads_hazard_ptr() == NULL, - "cannot have a nested hazard ptr with a NULL regular hazard ptr"); - - ThreadsList* threads; - - // Stable recording of a hazard ptr for SMR. This code does not use - // locks so its use of the _smr_java_thread_list & _threads_hazard_ptr - // fields is racy relative to code that uses those fields with locks. - // OrderAccess and Atomic functions are used to deal with those races. - // - while (true) { - threads = get_smr_java_thread_list(); - - // Publish a tagged hazard ptr to denote that the hazard ptr is not - // yet verified as being stable. Due to the fence after the hazard - // ptr write, it will be sequentially consistent w.r.t. the - // sequentially consistent writes of the ThreadsList, even on - // non-multiple copy atomic machines where stores can be observed - // in different order from different observer threads. - ThreadsList* unverified_threads = Thread::tag_hazard_ptr(threads); - self->set_threads_hazard_ptr(unverified_threads); - - // If _smr_java_thread_list has changed, we have lost a race with - // Threads::add() or Threads::remove() and have to try again. - if (get_smr_java_thread_list() != threads) { - continue; - } - - // We try to remove the tag which will verify the hazard ptr as - // being stable. This exchange can race with a scanning thread - // which might invalidate the tagged hazard ptr to keep it from - // being followed to access JavaThread ptrs. If we lose the race, - // we simply retry. If we win the race, then the stable hazard - // ptr is officially published. - if (self->cmpxchg_threads_hazard_ptr(threads, unverified_threads) == unverified_threads) { - break; - } - } - - // A stable hazard ptr has been published letting other threads know - // that the ThreadsList and the JavaThreads reachable from this list - // are protected and hence they should not be deleted until everyone - // agrees it is safe to do so. - - return threads; -} - -// Acquire a nested stable ThreadsList; this is rare so it uses -// Threads_lock. -// -ThreadsList *Threads::acquire_stable_list_nested_path(Thread *self) { - assert(self != NULL, "sanity check"); - assert(self->get_threads_hazard_ptr() != NULL, - "cannot have a NULL regular hazard ptr when acquiring a nested hazard ptr"); - - // The thread already has a hazard ptr (ThreadsList ref) so we need - // to create a nested ThreadsListHandle with the current ThreadsList - // since it might be different than our current hazard ptr. The need - // for a nested ThreadsListHandle is rare so we do this while holding - // the Threads_lock so we don't race with the scanning code; the code - // is so much simpler this way. - - NestedThreadsList* node; - { - // Only grab the Threads_lock if we don't already own it. - MutexLockerEx ml(Threads_lock->owned_by_self() ? NULL : Threads_lock); - node = new NestedThreadsList(get_smr_java_thread_list()); - // We insert at the front of the list to match up with the delete - // in release_stable_list(). - node->set_next(self->get_nested_threads_hazard_ptr()); - self->set_nested_threads_hazard_ptr(node); - if (EnableThreadSMRStatistics) { - self->inc_nested_threads_hazard_ptr_cnt(); - if (self->nested_threads_hazard_ptr_cnt() > _smr_nested_thread_list_max) { - _smr_nested_thread_list_max = self->nested_threads_hazard_ptr_cnt(); - } - } - } - log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::acquire_stable_list: add NestedThreadsList node containing ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(node->t_list())); - - return node->t_list(); -} - -inline void Threads::add_smr_deleted_thread_times(uint add_value) { - Atomic::add(add_value, &_smr_deleted_thread_times); -} - -inline void Threads::inc_smr_deleted_thread_cnt() { - Atomic::inc(&_smr_deleted_thread_cnt); -} - -// Release a stable ThreadsList. -// -void Threads::release_stable_list(Thread *self) { - assert(self != NULL, "sanity check"); - // release_stable_list_nested_path() will grab the Threads_lock - // so let's make sure the ThreadsListHandle is in a safe place. - debug_only(if (StrictSafepointChecks) self->check_for_valid_safepoint_state(/* potential_vm_operation */ false);) - - if (self->get_nested_threads_hazard_ptr() == NULL) { - // The typical case is first. - release_stable_list_fast_path(self); - return; - } - - // The nested case is rare. - release_stable_list_nested_path(self); -} - -// Fast path way to release a stable ThreadsList. The release portion -// is lock-free, but the wake up portion is not. -// -void Threads::release_stable_list_fast_path(Thread *self) { - assert(self != NULL, "sanity check"); - assert(self->get_threads_hazard_ptr() != NULL, "sanity check"); - assert(self->get_nested_threads_hazard_ptr() == NULL, - "cannot have a nested hazard ptr when releasing a regular hazard ptr"); - - // After releasing the hazard ptr, other threads may go ahead and - // free up some memory temporarily used by a ThreadsList snapshot. - self->set_threads_hazard_ptr(NULL); - - // We use double-check locking to reduce traffic on the system - // wide smr_delete_lock. - if (Threads::smr_delete_notify()) { - // An exiting thread might be waiting in smr_delete(); we need to - // check with smr_delete_lock to be sure. - release_stable_list_wake_up((char *) "regular hazard ptr"); - } -} - -// Release a nested stable ThreadsList; this is rare so it uses -// Threads_lock. -// -void Threads::release_stable_list_nested_path(Thread *self) { - assert(self != NULL, "sanity check"); - assert(self->get_nested_threads_hazard_ptr() != NULL, "sanity check"); - assert(self->get_threads_hazard_ptr() != NULL, - "must have a regular hazard ptr to have nested hazard ptrs"); - - // We have a nested ThreadsListHandle so we have to release it first. - // The need for a nested ThreadsListHandle is rare so we do this while - // holding the Threads_lock so we don't race with the scanning code; - // the code is so much simpler this way. - - NestedThreadsList *node; - { - // Only grab the Threads_lock if we don't already own it. - MutexLockerEx ml(Threads_lock->owned_by_self() ? NULL : Threads_lock); - // We remove from the front of the list to match up with the insert - // in acquire_stable_list(). - node = self->get_nested_threads_hazard_ptr(); - self->set_nested_threads_hazard_ptr(node->next()); - if (EnableThreadSMRStatistics) { - self->dec_nested_threads_hazard_ptr_cnt(); - } - } - - // An exiting thread might be waiting in smr_delete(); we need to - // check with smr_delete_lock to be sure. - release_stable_list_wake_up((char *) "nested hazard ptr"); - - log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::release_stable_list: delete NestedThreadsList node containing ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(node->t_list())); - - delete node; -} - -// Wake up portion of the release stable ThreadsList protocol; -// uses the smr_delete_lock(). -// -void Threads::release_stable_list_wake_up(char *log_str) { - assert(log_str != NULL, "sanity check"); - - // Note: smr_delete_lock is held in smr_delete() for the entire - // hazard ptr search so that we do not lose this notify() if - // the exiting thread has to wait. That code path also holds - // Threads_lock (which was grabbed before smr_delete_lock) so that - // threads_do() can be called. This means the system can't start a - // safepoint which means this thread can't take too long to get to - // a safepoint because of being blocked on smr_delete_lock. - // - MonitorLockerEx ml(Threads::smr_delete_lock(), Monitor::_no_safepoint_check_flag); - if (Threads::smr_delete_notify()) { - // Notify any exiting JavaThreads that are waiting in smr_delete() - // that we've released a ThreadsList. - ml.notify_all(); - log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::release_stable_list notified %s", os::current_thread_id(), log_str); - } -} - -inline void Threads::update_smr_deleted_thread_time_max(uint new_value) { - while (true) { - uint cur_value = _smr_deleted_thread_time_max; - if (new_value <= cur_value) { - // No need to update max value so we're done. - break; - } - if (Atomic::cmpxchg(new_value, &_smr_deleted_thread_time_max, cur_value) == cur_value) { - // Updated max value so we're done. Otherwise try it all again. - break; - } - } -} - -inline ThreadsList* Threads::xchg_smr_java_thread_list(ThreadsList* new_list) { - return (ThreadsList*)Atomic::xchg(new_list, &_smr_java_thread_list); -} - void Threads::initialize_java_lang_classes(JavaThread* main_thread, TRAPS) { TraceTime timer("Initialize java.lang classes", TRACETIME_LOG(Info, startuptime)); @@ -4666,501 +4339,6 @@ return JNI_FALSE; } -// Hash table of pointers found by a scan. Used for collecting hazard -// pointers (ThreadsList references). Also used for collecting JavaThreads -// that are indirectly referenced by hazard ptrs. An instance of this -// class only contains one type of pointer. -// -class ThreadScanHashtable : public CHeapObj { - private: - static bool ptr_equals(void * const& s1, void * const& s2) { - return s1 == s2; - } - - static unsigned int ptr_hash(void * const& s1) { - // 2654435761 = 2^32 * Phi (golden ratio) - return (unsigned int)(((uint32_t)(uintptr_t)s1) * 2654435761u); - } - - int _table_size; - // ResourceHashtable SIZE is specified at compile time so our - // dynamic _table_size is unused for now; 1031 is the first prime - // after 1024. - typedef ResourceHashtable PtrTable; - PtrTable * _ptrs; - - public: - // ResourceHashtable is passed to various functions and populated in - // different places so we allocate it using C_HEAP to make it immune - // from any ResourceMarks that happen to be in the code paths. - ThreadScanHashtable(int table_size) : _table_size(table_size), _ptrs(new (ResourceObj::C_HEAP, mtThread) PtrTable()) {} - - ~ThreadScanHashtable() { delete _ptrs; } - - bool has_entry(void *pointer) { - int *val_ptr = _ptrs->get(pointer); - return val_ptr != NULL && *val_ptr == 1; - } - - void add_entry(void *pointer) { - _ptrs->put(pointer, 1); - } -}; - -// Closure to gather JavaThreads indirectly referenced by hazard ptrs -// (ThreadsList references) into a hash table. This closure handles part 2 -// of the dance - adding all the JavaThreads referenced by the hazard -// pointer (ThreadsList reference) to the hash table. -// -class AddThreadHazardPointerThreadClosure : public ThreadClosure { - private: - ThreadScanHashtable *_table; - - public: - AddThreadHazardPointerThreadClosure(ThreadScanHashtable *table) : _table(table) {} - - virtual void do_thread(Thread *thread) { - if (!_table->has_entry((void*)thread)) { - // The same JavaThread might be on more than one ThreadsList or - // more than one thread might be using the same ThreadsList. In - // either case, we only need a single entry for a JavaThread. - _table->add_entry((void*)thread); - } - } -}; - -// Closure to gather JavaThreads indirectly referenced by hazard ptrs -// (ThreadsList references) into a hash table. This closure handles part 1 -// of the dance - hazard ptr chain walking and dispatch to another -// closure. -// -class ScanHazardPtrGatherProtectedThreadsClosure : public ThreadClosure { - private: - ThreadScanHashtable *_table; - public: - ScanHazardPtrGatherProtectedThreadsClosure(ThreadScanHashtable *table) : _table(table) {} - - virtual void do_thread(Thread *thread) { - assert_locked_or_safepoint(Threads_lock); - - if (thread == NULL) return; - - // This code races with Threads::acquire_stable_list() which is - // lock-free so we have to handle some special situations. - // - ThreadsList *current_list = NULL; - while (true) { - current_list = thread->get_threads_hazard_ptr(); - // No hazard ptr so nothing more to do. - if (current_list == NULL) { - assert(thread->get_nested_threads_hazard_ptr() == NULL, - "cannot have a nested hazard ptr with a NULL regular hazard ptr"); - return; - } - - // If the hazard ptr is verified as stable (since it is not tagged), - // then it is safe to use. - if (!Thread::is_hazard_ptr_tagged(current_list)) break; - - // The hazard ptr is tagged as not yet verified as being stable - // so we are racing with acquire_stable_list(). This exchange - // attempts to invalidate the hazard ptr. If we win the race, - // then we can ignore this unstable hazard ptr and the other - // thread will retry the attempt to publish a stable hazard ptr. - // If we lose the race, then we retry our attempt to look at the - // hazard ptr. - if (thread->cmpxchg_threads_hazard_ptr(NULL, current_list) == current_list) return; - } - - // The current JavaThread has a hazard ptr (ThreadsList reference) - // which might be _smr_java_thread_list or it might be an older - // ThreadsList that has been removed but not freed. In either case, - // the hazard ptr is protecting all the JavaThreads on that - // ThreadsList. - AddThreadHazardPointerThreadClosure add_cl(_table); - current_list->threads_do(&add_cl); - - // Any NestedThreadsLists are also protecting JavaThreads so - // gather those also; the ThreadsLists may be different. - for (NestedThreadsList* node = thread->get_nested_threads_hazard_ptr(); - node != NULL; node = node->next()) { - node->t_list()->threads_do(&add_cl); - } - } -}; - -// Closure to print JavaThreads that have a hazard ptr (ThreadsList -// reference) that contains an indirect reference to a specific JavaThread. -// -class ScanHazardPtrPrintMatchingThreadsClosure : public ThreadClosure { - private: - JavaThread *_thread; - public: - ScanHazardPtrPrintMatchingThreadsClosure(JavaThread *thread) : _thread(thread) {} - - virtual void do_thread(Thread *thread) { - assert_locked_or_safepoint(Threads_lock); - - if (thread == NULL) return; - ThreadsList *current_list = thread->get_threads_hazard_ptr(); - if (current_list == NULL) { - assert(thread->get_nested_threads_hazard_ptr() == NULL, - "cannot have a nested hazard ptr with a NULL regular hazard ptr"); - return; - } - // If the hazard ptr is unverified, then ignore it. - if (Thread::is_hazard_ptr_tagged(current_list)) return; - - // The current JavaThread has a hazard ptr (ThreadsList reference) - // which might be _smr_java_thread_list or it might be an older - // ThreadsList that has been removed but not freed. In either case, - // the hazard ptr is protecting all the JavaThreads on that - // ThreadsList, but we only care about matching a specific JavaThread. - DO_JAVA_THREADS(current_list, p) { - if (p == _thread) { - log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::smr_delete: thread1=" INTPTR_FORMAT " has a hazard pointer for thread2=" INTPTR_FORMAT, os::current_thread_id(), p2i(thread), p2i(_thread)); - break; - } - } - - // Any NestedThreadsLists are also protecting JavaThreads so - // check those also; the ThreadsLists may be different. - for (NestedThreadsList* node = thread->get_nested_threads_hazard_ptr(); - node != NULL; node = node->next()) { - DO_JAVA_THREADS(node->t_list(), p) { - if (p == _thread) { - log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::smr_delete: thread1=" INTPTR_FORMAT " has a nested hazard pointer for thread2=" INTPTR_FORMAT, os::current_thread_id(), p2i(thread), p2i(_thread)); - return; - } - } - } - } -}; - -// Return true if the specified JavaThread is protected by a hazard -// pointer (ThreadsList reference). Otherwise, returns false. -// -bool Threads::is_a_protected_JavaThread(JavaThread *thread) { - assert_locked_or_safepoint(Threads_lock); - - // Hash table size should be first power of two higher than twice - // the length of the Threads list. - int hash_table_size = MIN2(_number_of_threads, 32) << 1; - hash_table_size--; - hash_table_size |= hash_table_size >> 1; - hash_table_size |= hash_table_size >> 2; - hash_table_size |= hash_table_size >> 4; - hash_table_size |= hash_table_size >> 8; - hash_table_size |= hash_table_size >> 16; - hash_table_size++; - - // Gather a hash table of the JavaThreads indirectly referenced by - // hazard ptrs. - ThreadScanHashtable *scan_table = new ThreadScanHashtable(hash_table_size); - ScanHazardPtrGatherProtectedThreadsClosure scan_cl(scan_table); - Threads::threads_do(&scan_cl); - - bool thread_is_protected = false; - if (scan_table->has_entry((void*)thread)) { - thread_is_protected = true; - } - delete scan_table; - return thread_is_protected; -} - -// Safely delete a JavaThread when it is no longer in use by a -// ThreadsListHandle. -// -void Threads::smr_delete(JavaThread *thread) { - assert(!Threads_lock->owned_by_self(), "sanity"); - - bool has_logged_once = false; - elapsedTimer timer; - if (EnableThreadSMRStatistics) { - timer.start(); - } - - while (true) { - { - // No safepoint check because this JavaThread is not on the - // Threads list. - MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag); - // Cannot use a MonitorLockerEx helper here because we have - // to drop the Threads_lock first if we wait. - Threads::smr_delete_lock()->lock_without_safepoint_check(); - // Set the smr_delete_notify flag after we grab smr_delete_lock - // and before we scan hazard ptrs because we're doing - // double-check locking in release_stable_list(). - Threads::set_smr_delete_notify(); - - if (!is_a_protected_JavaThread(thread)) { - // This is the common case. - Threads::clear_smr_delete_notify(); - Threads::smr_delete_lock()->unlock(); - break; - } - if (!has_logged_once) { - has_logged_once = true; - log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::smr_delete: thread=" INTPTR_FORMAT " is not deleted.", os::current_thread_id(), p2i(thread)); - if (log_is_enabled(Debug, os, thread)) { - ScanHazardPtrPrintMatchingThreadsClosure scan_cl(thread); - Threads::threads_do(&scan_cl); - } - } - } // We have to drop the Threads_lock to wait or delete the thread - - if (EnableThreadSMRStatistics) { - _smr_delete_lock_wait_cnt++; - if (_smr_delete_lock_wait_cnt > _smr_delete_lock_wait_max) { - _smr_delete_lock_wait_max = _smr_delete_lock_wait_cnt; - } - } - // Wait for a release_stable_list() call before we check again. No - // safepoint check, no timeout, and not as suspend equivalent flag - // because this JavaThread is not on the Threads list. - Threads::smr_delete_lock()->wait(Mutex::_no_safepoint_check_flag, 0, - !Mutex::_as_suspend_equivalent_flag); - if (EnableThreadSMRStatistics) { - _smr_delete_lock_wait_cnt--; - } - - Threads::clear_smr_delete_notify(); - Threads::smr_delete_lock()->unlock(); - // Retry the whole scenario. - } - - if (ThreadLocalHandshakes) { - // The thread is about to be deleted so cancel any handshake. - thread->cancel_handshake(); - } - - delete thread; - if (EnableThreadSMRStatistics) { - timer.stop(); - uint millis = (uint)timer.milliseconds(); - Threads::inc_smr_deleted_thread_cnt(); - Threads::add_smr_deleted_thread_times(millis); - Threads::update_smr_deleted_thread_time_max(millis); - } - - log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::smr_delete: thread=" INTPTR_FORMAT " is deleted.", os::current_thread_id(), p2i(thread)); -} - -bool Threads::smr_delete_notify() { - // Use load_acquire() in order to see any updates to _smr_delete_notify - // earlier than when smr_delete_lock is grabbed. - return (OrderAccess::load_acquire(&_smr_delete_notify) != 0); -} - -// set_smr_delete_notify() and clear_smr_delete_notify() are called -// under the protection of the smr_delete_lock, but we also use an -// Atomic operation to ensure the memory update is seen earlier than -// when the smr_delete_lock is dropped. -// -void Threads::set_smr_delete_notify() { - Atomic::inc(&_smr_delete_notify); -} - -void Threads::clear_smr_delete_notify() { - Atomic::dec(&_smr_delete_notify); -} - -// Closure to gather hazard ptrs (ThreadsList references) into a hash table. -// -class ScanHazardPtrGatherThreadsListClosure : public ThreadClosure { - private: - ThreadScanHashtable *_table; - public: - ScanHazardPtrGatherThreadsListClosure(ThreadScanHashtable *table) : _table(table) {} - - virtual void do_thread(Thread* thread) { - assert_locked_or_safepoint(Threads_lock); - - if (thread == NULL) return; - ThreadsList *threads = thread->get_threads_hazard_ptr(); - if (threads == NULL) { - assert(thread->get_nested_threads_hazard_ptr() == NULL, - "cannot have a nested hazard ptr with a NULL regular hazard ptr"); - return; - } - // In this closure we always ignore the tag that might mark this - // hazard ptr as not yet verified. If we happen to catch an - // unverified hazard ptr that is subsequently discarded (not - // published), then the only side effect is that we might keep a - // to-be-deleted ThreadsList alive a little longer. - threads = Thread::untag_hazard_ptr(threads); - if (!_table->has_entry((void*)threads)) { - _table->add_entry((void*)threads); - } - - // Any NestedThreadsLists are also protecting JavaThreads so - // gather those also; the ThreadsLists may be different. - for (NestedThreadsList* node = thread->get_nested_threads_hazard_ptr(); - node != NULL; node = node->next()) { - threads = node->t_list(); - if (!_table->has_entry((void*)threads)) { - _table->add_entry((void*)threads); - } - } - } -}; - -// Safely free a ThreadsList after a Threads::add() or Threads::remove(). -// The specified ThreadsList may not get deleted during this call if it -// is still in-use (referenced by a hazard ptr). Other ThreadsLists -// in the chain may get deleted by this call if they are no longer in-use. -void Threads::smr_free_list(ThreadsList* threads) { - assert_locked_or_safepoint(Threads_lock); - - threads->set_next_list(_smr_to_delete_list); - _smr_to_delete_list = threads; - if (EnableThreadSMRStatistics) { - _smr_to_delete_list_cnt++; - if (_smr_to_delete_list_cnt > _smr_to_delete_list_max) { - _smr_to_delete_list_max = _smr_to_delete_list_cnt; - } - } - - // Hash table size should be first power of two higher than twice the length of the ThreadsList - int hash_table_size = MIN2(_number_of_threads, 32) << 1; - hash_table_size--; - hash_table_size |= hash_table_size >> 1; - hash_table_size |= hash_table_size >> 2; - hash_table_size |= hash_table_size >> 4; - hash_table_size |= hash_table_size >> 8; - hash_table_size |= hash_table_size >> 16; - hash_table_size++; - - // Gather a hash table of the current hazard ptrs: - ThreadScanHashtable *scan_table = new ThreadScanHashtable(hash_table_size); - ScanHazardPtrGatherThreadsListClosure scan_cl(scan_table); - Threads::threads_do(&scan_cl); - - // Walk through the linked list of pending freeable ThreadsLists - // and free the ones that are not referenced from hazard ptrs. - ThreadsList* current = _smr_to_delete_list; - ThreadsList* prev = NULL; - ThreadsList* next = NULL; - bool threads_is_freed = false; - while (current != NULL) { - next = current->next_list(); - if (!scan_table->has_entry((void*)current)) { - // This ThreadsList is not referenced by a hazard ptr. - if (prev != NULL) { - prev->set_next_list(next); - } - if (_smr_to_delete_list == current) { - _smr_to_delete_list = next; - } - - log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::smr_free_list: threads=" INTPTR_FORMAT " is freed.", os::current_thread_id(), p2i(current)); - if (current == threads) threads_is_freed = true; - delete current; - if (EnableThreadSMRStatistics) { - _smr_java_thread_list_free_cnt++; - _smr_to_delete_list_cnt--; - } - } else { - prev = current; - } - current = next; - } - - if (!threads_is_freed) { - // Only report "is not freed" on the original call to - // smr_free_list() for this ThreadsList. - log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::smr_free_list: threads=" INTPTR_FORMAT " is not freed.", os::current_thread_id(), p2i(threads)); - } - - delete scan_table; -} - -// Remove a JavaThread from a ThreadsList. The returned ThreadsList is a -// new copy of the specified ThreadsList with the specified JavaThread -// removed. -ThreadsList *ThreadsList::remove_thread(ThreadsList* list, JavaThread* java_thread) { - assert(list->_length > 0, "sanity"); - - uint i = 0; - DO_JAVA_THREADS(list, current) { - if (current == java_thread) { - break; - } - i++; - } - assert(i < list->_length, "did not find JavaThread on the list"); - const uint index = i; - const uint new_length = list->_length - 1; - const uint head_length = index; - const uint tail_length = (new_length >= index) ? (new_length - index) : 0; - ThreadsList *const new_list = new ThreadsList(new_length); - - if (head_length > 0) { - Copy::disjoint_words((HeapWord*)list->_threads, (HeapWord*)new_list->_threads, head_length); - } - if (tail_length > 0) { - Copy::disjoint_words((HeapWord*)list->_threads + index + 1, (HeapWord*)new_list->_threads + index, tail_length); - } - - return new_list; -} - -// Add a JavaThread to a ThreadsList. The returned ThreadsList is a -// new copy of the specified ThreadsList with the specified JavaThread -// appended to the end. -ThreadsList *ThreadsList::add_thread(ThreadsList *list, JavaThread *java_thread) { - const uint index = list->_length; - const uint new_length = index + 1; - const uint head_length = index; - ThreadsList *const new_list = new ThreadsList(new_length); - - if (head_length > 0) { - Copy::disjoint_words((HeapWord*)list->_threads, (HeapWord*)new_list->_threads, head_length); - } - *(JavaThread**)(new_list->_threads + index) = java_thread; - - return new_list; -} - -int ThreadsList::find_index_of_JavaThread(JavaThread *target) { - if (target == NULL) { - return -1; - } - for (uint i = 0; i < length(); i++) { - if (target == thread_at(i)) { - return (int)i; - } - } - return -1; -} - -JavaThread* ThreadsList::find_JavaThread_from_java_tid(jlong java_tid) const { - DO_JAVA_THREADS(this, thread) { - oop tobj = thread->threadObj(); - // Ignore the thread if it hasn't run yet, has exited - // or is starting to exit. - if (tobj != NULL && !thread->is_exiting() && - java_tid == java_lang_Thread::thread_id(tobj)) { - // found a match - return thread; - } - } - return NULL; -} - -bool ThreadsList::includes(const JavaThread * const p) const { - if (p == NULL) { - return false; - } - DO_JAVA_THREADS(this, q) { - if (q == p) { - return true; - } - } - return false; -} void Threads::add(JavaThread* p, bool force_daemon) { // The threads lock must be owned at this point @@ -5189,18 +4367,7 @@ ThreadService::add_thread(p, daemon); // Maintain fast thread list - ThreadsList *new_list = ThreadsList::add_thread(get_smr_java_thread_list(), p); - if (EnableThreadSMRStatistics) { - _smr_java_thread_list_alloc_cnt++; - if (new_list->length() > _smr_java_thread_list_max) { - _smr_java_thread_list_max = new_list->length(); - } - } - // Initial _smr_java_thread_list will not generate a "Threads::add" mesg. - log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::add: new ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(new_list)); - - ThreadsList *old_list = xchg_smr_java_thread_list(new_list); - smr_free_list(old_list); + ThreadsSMRSupport::add_thread(p); // Possible GC point. Events::log(p, "Thread added: " INTPTR_FORMAT, p2i(p)); @@ -5215,20 +4382,10 @@ // that we do not remove thread without safepoint code notice { MutexLocker ml(Threads_lock); - assert(get_smr_java_thread_list()->includes(p), "p must be present"); + assert(ThreadsSMRSupport::get_smr_java_thread_list()->includes(p), "p must be present"); // Maintain fast thread list - ThreadsList *new_list = ThreadsList::remove_thread(get_smr_java_thread_list(), p); - if (EnableThreadSMRStatistics) { - _smr_java_thread_list_alloc_cnt++; - // This list is smaller so no need to check for a "longest" update. - } - - // Final _smr_java_thread_list will not generate a "Threads::remove" mesg. - log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::remove: new ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(new_list)); - - ThreadsList *old_list = xchg_smr_java_thread_list(new_list); - smr_free_list(old_list); + ThreadsSMRSupport::remove_thread(p); JavaThread* current = _thread_list; JavaThread* prev = NULL; @@ -5453,7 +4610,7 @@ } #endif // INCLUDE_SERVICES - print_smr_info_on(st); + ThreadsSMRSupport::print_smr_info_on(st); st->cr(); ALL_JAVA_THREADS(p) { @@ -5486,101 +4643,6 @@ st->flush(); } -// Log Threads class SMR info. -void Threads::log_smr_statistics() { - LogTarget(Info, thread, smr) log; - if (log.is_enabled()) { - LogStream out(log); - print_smr_info_on(&out); - } -} - -// Print Threads class SMR info. -void Threads::print_smr_info_on(outputStream* st) { - // Only grab the Threads_lock if we don't already own it - // and if we are not reporting an error. - MutexLockerEx ml((Threads_lock->owned_by_self() || VMError::is_error_reported()) ? NULL : Threads_lock); - - st->print_cr("Threads class SMR info:"); - st->print_cr("_smr_java_thread_list=" INTPTR_FORMAT ", length=%u, " - "elements={", p2i(_smr_java_thread_list), - _smr_java_thread_list->length()); - print_smr_info_elements_on(st, _smr_java_thread_list); - st->print_cr("}"); - if (_smr_to_delete_list != NULL) { - st->print_cr("_smr_to_delete_list=" INTPTR_FORMAT ", length=%u, " - "elements={", p2i(_smr_to_delete_list), - _smr_to_delete_list->length()); - print_smr_info_elements_on(st, _smr_to_delete_list); - st->print_cr("}"); - for (ThreadsList *t_list = _smr_to_delete_list->next_list(); - t_list != NULL; t_list = t_list->next_list()) { - st->print("next-> " INTPTR_FORMAT ", length=%u, " - "elements={", p2i(t_list), t_list->length()); - print_smr_info_elements_on(st, t_list); - st->print_cr("}"); - } - } - if (!EnableThreadSMRStatistics) { - return; - } - st->print_cr("_smr_java_thread_list_alloc_cnt=" UINT64_FORMAT "," - "_smr_java_thread_list_free_cnt=" UINT64_FORMAT "," - "_smr_java_thread_list_max=%u, " - "_smr_nested_thread_list_max=%u", - _smr_java_thread_list_alloc_cnt, - _smr_java_thread_list_free_cnt, - _smr_java_thread_list_max, - _smr_nested_thread_list_max); - if (_smr_tlh_cnt > 0) { - st->print_cr("_smr_tlh_cnt=%u" - ", _smr_tlh_times=%u" - ", avg_smr_tlh_time=%0.2f" - ", _smr_tlh_time_max=%u", - _smr_tlh_cnt, _smr_tlh_times, - ((double) _smr_tlh_times / _smr_tlh_cnt), - _smr_tlh_time_max); - } - if (_smr_deleted_thread_cnt > 0) { - st->print_cr("_smr_deleted_thread_cnt=%u" - ", _smr_deleted_thread_times=%u" - ", avg_smr_deleted_thread_time=%0.2f" - ", _smr_deleted_thread_time_max=%u", - _smr_deleted_thread_cnt, _smr_deleted_thread_times, - ((double) _smr_deleted_thread_times / _smr_deleted_thread_cnt), - _smr_deleted_thread_time_max); - } - st->print_cr("_smr_delete_lock_wait_cnt=%u, _smr_delete_lock_wait_max=%u", - _smr_delete_lock_wait_cnt, _smr_delete_lock_wait_max); - st->print_cr("_smr_to_delete_list_cnt=%u, _smr_to_delete_list_max=%u", - _smr_to_delete_list_cnt, _smr_to_delete_list_max); -} - -// Print ThreadsList elements (4 per line). -void Threads::print_smr_info_elements_on(outputStream* st, - ThreadsList* t_list) { - uint cnt = 0; - JavaThreadIterator jti(t_list); - for (JavaThread *jt = jti.first(); jt != NULL; jt = jti.next()) { - st->print(INTPTR_FORMAT, p2i(jt)); - if (cnt < t_list->length() - 1) { - // Separate with comma or comma-space except for the last one. - if (((cnt + 1) % 4) == 0) { - // Four INTPTR_FORMAT fit on an 80 column line so end the - // current line with just a comma. - st->print_cr(","); - } else { - // Not the last one on the current line so use comma-space: - st->print(", "); - } - } else { - // Last one so just end the current line. - st->cr(); - } - cnt++; - } -} - void Threads::print_on_error(Thread* this_thread, outputStream* st, Thread* current, char* buf, int buflen, bool* found_current) { if (this_thread != NULL) { @@ -5617,7 +4679,7 @@ // memory (even in resource area), it might deadlock the error handler. void Threads::print_on_error(outputStream* st, Thread* current, char* buf, int buflen) { - print_smr_info_on(st); + ThreadsSMRSupport::print_smr_info_on(st); st->cr(); bool found_current = false; diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/runtime/thread.hpp --- a/src/hotspot/share/runtime/thread.hpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/runtime/thread.hpp Thu Dec 14 12:28:32 2017 +0000 @@ -58,6 +58,7 @@ class ThreadSafepointState; class ThreadsList; +class ThreadsSMRSupport; class NestedThreadsList; class JvmtiThreadState; @@ -103,7 +104,6 @@ // - WatcherThread class Thread: public ThreadShadow { - friend class Threads; friend class VMStructs; friend class JVMCIVMStructs; private: @@ -121,12 +121,14 @@ protected: // Support for forcing alignment of thread objects for biased locking void* _real_malloc_address; + // JavaThread lifecycle support: - friend class ScanHazardPtrGatherProtectedThreadsClosure; - friend class ScanHazardPtrGatherThreadsListClosure; - friend class ScanHazardPtrPrintMatchingThreadsClosure; - friend class ThreadsListHandle; - friend class ThreadsListSetter; + friend class ScanHazardPtrGatherProtectedThreadsClosure; // for cmpxchg_threads_hazard_ptr(), get_threads_hazard_ptr(), is_hazard_ptr_tagged() access + friend class ScanHazardPtrGatherThreadsListClosure; // for get_nested_threads_hazard_ptr(), get_threads_hazard_ptr(), untag_hazard_ptr() access + friend class ScanHazardPtrPrintMatchingThreadsClosure; // for get_threads_hazard_ptr(), is_hazard_ptr_tagged() access + friend class ThreadsListSetter; // for get_threads_hazard_ptr() access + friend class ThreadsSMRSupport; // for get_threads_hazard_ptr() access + ThreadsList* volatile _threads_hazard_ptr; ThreadsList* cmpxchg_threads_hazard_ptr(ThreadsList* exchange_value, ThreadsList* compare_value); ThreadsList* get_threads_hazard_ptr(); @@ -2126,62 +2128,18 @@ class Threads: AllStatic { friend class VMStructs; private: - // Safe Memory Reclamation (SMR) support: - // The coordination between Threads::release_stable_list() and - // Threads::smr_delete() uses the smr_delete_lock in order to - // reduce the traffic on the Threads_lock. - static Monitor* _smr_delete_lock; - // The '_cnt', '_max' and '_times" fields are enabled via - // -XX:+EnableThreadSMRStatistics (see thread.cpp for a - // description about each field): - static uint _smr_delete_lock_wait_cnt; - static uint _smr_delete_lock_wait_max; - // The smr_delete_notify flag is used for proper double-check - // locking in order to reduce the traffic on the smr_delete_lock. - static volatile uint _smr_delete_notify; - static volatile uint _smr_deleted_thread_cnt; - static volatile uint _smr_deleted_thread_time_max; - static volatile uint _smr_deleted_thread_times; - static ThreadsList* volatile _smr_java_thread_list; - static uint64_t _smr_java_thread_list_alloc_cnt; - static uint64_t _smr_java_thread_list_free_cnt; - static uint _smr_java_thread_list_max; - static uint _smr_nested_thread_list_max; - static volatile uint _smr_tlh_cnt; - static volatile uint _smr_tlh_time_max; - static volatile uint _smr_tlh_times; - static ThreadsList* _smr_to_delete_list; - static uint _smr_to_delete_list_cnt; - static uint _smr_to_delete_list_max; - - static JavaThread* _thread_list; - static int _number_of_threads; - static int _number_of_non_daemon_threads; - static int _return_code; - static int _thread_claim_parity; + static JavaThread* _thread_list; + static int _number_of_threads; + static int _number_of_non_daemon_threads; + static int _return_code; + static int _thread_claim_parity; #ifdef ASSERT - static bool _vm_complete; + static bool _vm_complete; #endif static void initialize_java_lang_classes(JavaThread* main_thread, TRAPS); static void initialize_jsr292_core_classes(TRAPS); - static ThreadsList *acquire_stable_list_fast_path(Thread *self); - static ThreadsList *acquire_stable_list_nested_path(Thread *self); - static void add_smr_deleted_thread_times(uint add_value); - static void clear_smr_delete_notify(); - static ThreadsList* get_smr_java_thread_list(); - static void inc_smr_deleted_thread_cnt(); - static void release_stable_list_fast_path(Thread *self); - static void release_stable_list_nested_path(Thread *self); - static void release_stable_list_wake_up(char *log_str); - static void set_smr_delete_notify(); - static Monitor* smr_delete_lock() { return _smr_delete_lock; } - static bool smr_delete_notify(); - static void smr_free_list(ThreadsList* threads); - static void update_smr_deleted_thread_time_max(uint new_value); - static ThreadsList* xchg_smr_java_thread_list(ThreadsList* new_list); - public: // Thread management // force_daemon is a concession to JNI, where we may need to add a @@ -2191,19 +2149,6 @@ static void threads_do(ThreadClosure* tc); static void possibly_parallel_threads_do(bool is_par, ThreadClosure* tc); - // SMR support: - static ThreadsList *acquire_stable_list(Thread *self, bool is_ThreadsListSetter); - static void release_stable_list(Thread *self); - static bool is_a_protected_JavaThread(JavaThread *thread); - static bool is_a_protected_JavaThread_with_lock(JavaThread *thread) { - MutexLockerEx ml(Threads_lock->owned_by_self() ? NULL : Threads_lock); - return is_a_protected_JavaThread(thread); - } - static void smr_delete(JavaThread *thread); - static void inc_smr_tlh_cnt(); - static void update_smr_tlh_time_max(uint new_value); - static void add_smr_tlh_times(uint add_value); - // Initializes the vm and creates the vm thread static jint create_vm(JavaVMInitArgs* args, bool* canTryAgain); static void convert_vm_init_libraries_to_agents(); @@ -2264,10 +2209,7 @@ // Verification static void verify(); - static void log_smr_statistics(); static void print_on(outputStream* st, bool print_stacks, bool internal_format, bool print_concurrent_locks); - static void print_smr_info_on(outputStream* st); - static void print_smr_info_elements_on(outputStream* st, ThreadsList* t_list); static void print(bool print_stacks, bool internal_format) { // this function is only used by debug.cpp print_on(tty, print_stacks, internal_format, false /* no concurrent lock printed */); diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/runtime/thread.inline.hpp --- a/src/hotspot/share/runtime/thread.inline.hpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/runtime/thread.inline.hpp Thu Dec 14 12:28:32 2017 +0000 @@ -28,7 +28,6 @@ #include "runtime/atomic.hpp" #include "runtime/os.inline.hpp" #include "runtime/thread.hpp" -#include "runtime/threadSMR.hpp" inline void Thread::set_suspend_flag(SuspendFlags f) { assert(sizeof(jint) == sizeof(_suspend_flags), "size mismatch"); @@ -212,26 +211,4 @@ OrderAccess::release_store((volatile jint *) &_terminated, (jint) _thread_terminated); } -inline void Threads::add_smr_tlh_times(uint add_value) { - Atomic::add(add_value, &_smr_tlh_times); -} - -inline void Threads::inc_smr_tlh_cnt() { - Atomic::inc(&_smr_tlh_cnt); -} - -inline void Threads::update_smr_tlh_time_max(uint new_value) { - while (true) { - uint cur_value = _smr_tlh_time_max; - if (new_value <= cur_value) { - // No need to update max value so we're done. - break; - } - if (Atomic::cmpxchg(new_value, &_smr_tlh_time_max, cur_value) == cur_value) { - // Updated max value so we're done. Otherwise try it all again. - break; - } - } -} - #endif // SHARE_VM_RUNTIME_THREAD_INLINE_HPP diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/runtime/threadSMR.cpp --- a/src/hotspot/share/runtime/threadSMR.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/runtime/threadSMR.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -23,10 +23,357 @@ */ #include "precompiled.hpp" +#include "logging/logStream.hpp" #include "memory/allocation.inline.hpp" #include "runtime/thread.inline.hpp" -#include "runtime/threadSMR.hpp" +#include "runtime/threadSMR.inline.hpp" #include "services/threadService.hpp" +#include "utilities/globalDefinitions.hpp" +#include "utilities/resourceHash.hpp" + +Monitor* ThreadsSMRSupport::_smr_delete_lock = + new Monitor(Monitor::special, "smr_delete_lock", + false /* allow_vm_block */, + Monitor::_safepoint_check_never); +// The '_cnt', '_max' and '_times" fields are enabled via +// -XX:+EnableThreadSMRStatistics: + +// # of parallel threads in _smr_delete_lock->wait(). +// Impl note: Hard to imagine > 64K waiting threads so this could be 16-bit, +// but there is no nice 16-bit _FORMAT support. +uint ThreadsSMRSupport::_smr_delete_lock_wait_cnt = 0; + +// Max # of parallel threads in _smr_delete_lock->wait(). +// Impl note: See _smr_delete_lock_wait_cnt note. +uint ThreadsSMRSupport::_smr_delete_lock_wait_max = 0; + +// Flag to indicate when an _smr_delete_lock->notify() is needed. +// Impl note: See _smr_delete_lock_wait_cnt note. +volatile uint ThreadsSMRSupport::_smr_delete_notify = 0; + +// # of threads deleted over VM lifetime. +// Impl note: Atomically incremented over VM lifetime so use unsigned for more +// range. Unsigned 64-bit would be more future proof, but 64-bit atomic inc +// isn't available everywhere (or is it?). +volatile uint ThreadsSMRSupport::_smr_deleted_thread_cnt = 0; + +// Max time in millis to delete a thread. +// Impl note: 16-bit might be too small on an overloaded machine. Use +// unsigned since this is a time value. Set via Atomic::cmpxchg() in a +// loop for correctness. +volatile uint ThreadsSMRSupport::_smr_deleted_thread_time_max = 0; + +// Cumulative time in millis to delete threads. +// Impl note: Atomically added to over VM lifetime so use unsigned for more +// range. Unsigned 64-bit would be more future proof, but 64-bit atomic inc +// isn't available everywhere (or is it?). +volatile uint ThreadsSMRSupport::_smr_deleted_thread_times = 0; + +ThreadsList* volatile ThreadsSMRSupport::_smr_java_thread_list = new ThreadsList(0); + +// # of ThreadsLists allocated over VM lifetime. +// Impl note: We allocate a new ThreadsList for every thread create and +// every thread delete so we need a bigger type than the +// _smr_deleted_thread_cnt field. +uint64_t ThreadsSMRSupport::_smr_java_thread_list_alloc_cnt = 1; + +// # of ThreadsLists freed over VM lifetime. +// Impl note: See _smr_java_thread_list_alloc_cnt note. +uint64_t ThreadsSMRSupport::_smr_java_thread_list_free_cnt = 0; + +// Max size ThreadsList allocated. +// Impl note: Max # of threads alive at one time should fit in unsigned 32-bit. +uint ThreadsSMRSupport::_smr_java_thread_list_max = 0; + +// Max # of nested ThreadsLists for a thread. +// Impl note: Hard to imagine > 64K nested ThreadsLists so this could be +// 16-bit, but there is no nice 16-bit _FORMAT support. +uint ThreadsSMRSupport::_smr_nested_thread_list_max = 0; + +// # of ThreadsListHandles deleted over VM lifetime. +// Impl note: Atomically incremented over VM lifetime so use unsigned for +// more range. There will be fewer ThreadsListHandles than threads so +// unsigned 32-bit should be fine. +volatile uint ThreadsSMRSupport::_smr_tlh_cnt = 0; + +// Max time in millis to delete a ThreadsListHandle. +// Impl note: 16-bit might be too small on an overloaded machine. Use +// unsigned since this is a time value. Set via Atomic::cmpxchg() in a +// loop for correctness. +volatile uint ThreadsSMRSupport::_smr_tlh_time_max = 0; + +// Cumulative time in millis to delete ThreadsListHandles. +// Impl note: Atomically added to over VM lifetime so use unsigned for more +// range. Unsigned 64-bit would be more future proof, but 64-bit atomic inc +// isn't available everywhere (or is it?). +volatile uint ThreadsSMRSupport::_smr_tlh_times = 0; + +ThreadsList* ThreadsSMRSupport::_smr_to_delete_list = NULL; + +// # of parallel ThreadsLists on the to-delete list. +// Impl note: Hard to imagine > 64K ThreadsLists needing to be deleted so +// this could be 16-bit, but there is no nice 16-bit _FORMAT support. +uint ThreadsSMRSupport::_smr_to_delete_list_cnt = 0; + +// Max # of parallel ThreadsLists on the to-delete list. +// Impl note: See _smr_to_delete_list_cnt note. +uint ThreadsSMRSupport::_smr_to_delete_list_max = 0; + + +// 'inline' functions first so the definitions are before first use: + +inline void ThreadsSMRSupport::add_smr_deleted_thread_times(uint add_value) { + Atomic::add(add_value, &_smr_deleted_thread_times); +} + +inline void ThreadsSMRSupport::inc_smr_deleted_thread_cnt() { + Atomic::inc(&_smr_deleted_thread_cnt); +} + +inline void ThreadsSMRSupport::inc_smr_java_thread_list_alloc_cnt() { + _smr_java_thread_list_alloc_cnt++; +} + +inline void ThreadsSMRSupport::update_smr_deleted_thread_time_max(uint new_value) { + while (true) { + uint cur_value = _smr_deleted_thread_time_max; + if (new_value <= cur_value) { + // No need to update max value so we're done. + break; + } + if (Atomic::cmpxchg(new_value, &_smr_deleted_thread_time_max, cur_value) == cur_value) { + // Updated max value so we're done. Otherwise try it all again. + break; + } + } +} + +inline void ThreadsSMRSupport::update_smr_java_thread_list_max(uint new_value) { + if (new_value > _smr_java_thread_list_max) { + _smr_java_thread_list_max = new_value; + } +} + +inline ThreadsList* ThreadsSMRSupport::xchg_smr_java_thread_list(ThreadsList* new_list) { + return (ThreadsList*)Atomic::xchg(new_list, &_smr_java_thread_list); +} + + +// Hash table of pointers found by a scan. Used for collecting hazard +// pointers (ThreadsList references). Also used for collecting JavaThreads +// that are indirectly referenced by hazard ptrs. An instance of this +// class only contains one type of pointer. +// +class ThreadScanHashtable : public CHeapObj { + private: + static bool ptr_equals(void * const& s1, void * const& s2) { + return s1 == s2; + } + + static unsigned int ptr_hash(void * const& s1) { + // 2654435761 = 2^32 * Phi (golden ratio) + return (unsigned int)(((uint32_t)(uintptr_t)s1) * 2654435761u); + } + + int _table_size; + // ResourceHashtable SIZE is specified at compile time so our + // dynamic _table_size is unused for now; 1031 is the first prime + // after 1024. + typedef ResourceHashtable PtrTable; + PtrTable * _ptrs; + + public: + // ResourceHashtable is passed to various functions and populated in + // different places so we allocate it using C_HEAP to make it immune + // from any ResourceMarks that happen to be in the code paths. + ThreadScanHashtable(int table_size) : _table_size(table_size), _ptrs(new (ResourceObj::C_HEAP, mtThread) PtrTable()) {} + + ~ThreadScanHashtable() { delete _ptrs; } + + bool has_entry(void *pointer) { + int *val_ptr = _ptrs->get(pointer); + return val_ptr != NULL && *val_ptr == 1; + } + + void add_entry(void *pointer) { + _ptrs->put(pointer, 1); + } +}; + +// Closure to gather JavaThreads indirectly referenced by hazard ptrs +// (ThreadsList references) into a hash table. This closure handles part 2 +// of the dance - adding all the JavaThreads referenced by the hazard +// pointer (ThreadsList reference) to the hash table. +// +class AddThreadHazardPointerThreadClosure : public ThreadClosure { + private: + ThreadScanHashtable *_table; + + public: + AddThreadHazardPointerThreadClosure(ThreadScanHashtable *table) : _table(table) {} + + virtual void do_thread(Thread *thread) { + if (!_table->has_entry((void*)thread)) { + // The same JavaThread might be on more than one ThreadsList or + // more than one thread might be using the same ThreadsList. In + // either case, we only need a single entry for a JavaThread. + _table->add_entry((void*)thread); + } + } +}; + +// Closure to gather JavaThreads indirectly referenced by hazard ptrs +// (ThreadsList references) into a hash table. This closure handles part 1 +// of the dance - hazard ptr chain walking and dispatch to another +// closure. +// +class ScanHazardPtrGatherProtectedThreadsClosure : public ThreadClosure { + private: + ThreadScanHashtable *_table; + public: + ScanHazardPtrGatherProtectedThreadsClosure(ThreadScanHashtable *table) : _table(table) {} + + virtual void do_thread(Thread *thread) { + assert_locked_or_safepoint(Threads_lock); + + if (thread == NULL) return; + + // This code races with ThreadsSMRSupport::acquire_stable_list() which + // is lock-free so we have to handle some special situations. + // + ThreadsList *current_list = NULL; + while (true) { + current_list = thread->get_threads_hazard_ptr(); + // No hazard ptr so nothing more to do. + if (current_list == NULL) { + assert(thread->get_nested_threads_hazard_ptr() == NULL, + "cannot have a nested hazard ptr with a NULL regular hazard ptr"); + return; + } + + // If the hazard ptr is verified as stable (since it is not tagged), + // then it is safe to use. + if (!Thread::is_hazard_ptr_tagged(current_list)) break; + + // The hazard ptr is tagged as not yet verified as being stable + // so we are racing with acquire_stable_list(). This exchange + // attempts to invalidate the hazard ptr. If we win the race, + // then we can ignore this unstable hazard ptr and the other + // thread will retry the attempt to publish a stable hazard ptr. + // If we lose the race, then we retry our attempt to look at the + // hazard ptr. + if (thread->cmpxchg_threads_hazard_ptr(NULL, current_list) == current_list) return; + } + + // The current JavaThread has a hazard ptr (ThreadsList reference) + // which might be _smr_java_thread_list or it might be an older + // ThreadsList that has been removed but not freed. In either case, + // the hazard ptr is protecting all the JavaThreads on that + // ThreadsList. + AddThreadHazardPointerThreadClosure add_cl(_table); + current_list->threads_do(&add_cl); + + // Any NestedThreadsLists are also protecting JavaThreads so + // gather those also; the ThreadsLists may be different. + for (NestedThreadsList* node = thread->get_nested_threads_hazard_ptr(); + node != NULL; node = node->next()) { + node->t_list()->threads_do(&add_cl); + } + } +}; + +// Closure to gather hazard ptrs (ThreadsList references) into a hash table. +// +class ScanHazardPtrGatherThreadsListClosure : public ThreadClosure { + private: + ThreadScanHashtable *_table; + public: + ScanHazardPtrGatherThreadsListClosure(ThreadScanHashtable *table) : _table(table) {} + + virtual void do_thread(Thread* thread) { + assert_locked_or_safepoint(Threads_lock); + + if (thread == NULL) return; + ThreadsList *threads = thread->get_threads_hazard_ptr(); + if (threads == NULL) { + assert(thread->get_nested_threads_hazard_ptr() == NULL, + "cannot have a nested hazard ptr with a NULL regular hazard ptr"); + return; + } + // In this closure we always ignore the tag that might mark this + // hazard ptr as not yet verified. If we happen to catch an + // unverified hazard ptr that is subsequently discarded (not + // published), then the only side effect is that we might keep a + // to-be-deleted ThreadsList alive a little longer. + threads = Thread::untag_hazard_ptr(threads); + if (!_table->has_entry((void*)threads)) { + _table->add_entry((void*)threads); + } + + // Any NestedThreadsLists are also protecting JavaThreads so + // gather those also; the ThreadsLists may be different. + for (NestedThreadsList* node = thread->get_nested_threads_hazard_ptr(); + node != NULL; node = node->next()) { + threads = node->t_list(); + if (!_table->has_entry((void*)threads)) { + _table->add_entry((void*)threads); + } + } + } +}; + +// Closure to print JavaThreads that have a hazard ptr (ThreadsList +// reference) that contains an indirect reference to a specific JavaThread. +// +class ScanHazardPtrPrintMatchingThreadsClosure : public ThreadClosure { + private: + JavaThread *_thread; + public: + ScanHazardPtrPrintMatchingThreadsClosure(JavaThread *thread) : _thread(thread) {} + + virtual void do_thread(Thread *thread) { + assert_locked_or_safepoint(Threads_lock); + + if (thread == NULL) return; + ThreadsList *current_list = thread->get_threads_hazard_ptr(); + if (current_list == NULL) { + assert(thread->get_nested_threads_hazard_ptr() == NULL, + "cannot have a nested hazard ptr with a NULL regular hazard ptr"); + return; + } + // If the hazard ptr is unverified, then ignore it. + if (Thread::is_hazard_ptr_tagged(current_list)) return; + + // The current JavaThread has a hazard ptr (ThreadsList reference) + // which might be _smr_java_thread_list or it might be an older + // ThreadsList that has been removed but not freed. In either case, + // the hazard ptr is protecting all the JavaThreads on that + // ThreadsList, but we only care about matching a specific JavaThread. + JavaThreadIterator jti(current_list); + for (JavaThread *p = jti.first(); p != NULL; p = jti.next()) { + if (p == _thread) { + log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::smr_delete: thread1=" INTPTR_FORMAT " has a hazard pointer for thread2=" INTPTR_FORMAT, os::current_thread_id(), p2i(thread), p2i(_thread)); + break; + } + } + + // Any NestedThreadsLists are also protecting JavaThreads so + // check those also; the ThreadsLists may be different. + for (NestedThreadsList* node = thread->get_nested_threads_hazard_ptr(); + node != NULL; node = node->next()) { + JavaThreadIterator jti(node->t_list()); + for (JavaThread *p = jti.first(); p != NULL; p = jti.next()) { + if (p == _thread) { + log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::smr_delete: thread1=" INTPTR_FORMAT " has a nested hazard pointer for thread2=" INTPTR_FORMAT, os::current_thread_id(), p2i(thread), p2i(_thread)); + return; + } + } + } + } +}; + // 'entries + 1' so we always have at least one entry. ThreadsList::ThreadsList(int entries) : _length(entries), _threads(NEW_C_HEAP_ARRAY(JavaThread*, entries + 1, mtThread)), _next_list(NULL) { @@ -37,20 +384,87 @@ FREE_C_HEAP_ARRAY(JavaThread*, _threads); } -ThreadsListSetter::~ThreadsListSetter() { - if (_target_needs_release) { - // The hazard ptr in the target needs to be released. - Threads::release_stable_list(_target); +// Add a JavaThread to a ThreadsList. The returned ThreadsList is a +// new copy of the specified ThreadsList with the specified JavaThread +// appended to the end. +ThreadsList *ThreadsList::add_thread(ThreadsList *list, JavaThread *java_thread) { + const uint index = list->_length; + const uint new_length = index + 1; + const uint head_length = index; + ThreadsList *const new_list = new ThreadsList(new_length); + + if (head_length > 0) { + Copy::disjoint_words((HeapWord*)list->_threads, (HeapWord*)new_list->_threads, head_length); } + *(JavaThread**)(new_list->_threads + index) = java_thread; + + return new_list; +} + +int ThreadsList::find_index_of_JavaThread(JavaThread *target) { + if (target == NULL) { + return -1; + } + for (uint i = 0; i < length(); i++) { + if (target == thread_at(i)) { + return (int)i; + } + } + return -1; } -void ThreadsListSetter::set() { - assert(_target->get_threads_hazard_ptr() == NULL, "hazard ptr should not already be set"); - (void) Threads::acquire_stable_list(_target, /* is_ThreadsListSetter */ true); - _target_needs_release = true; +JavaThread* ThreadsList::find_JavaThread_from_java_tid(jlong java_tid) const { + for (uint i = 0; i < length(); i++) { + JavaThread* thread = thread_at(i); + oop tobj = thread->threadObj(); + // Ignore the thread if it hasn't run yet, has exited + // or is starting to exit. + if (tobj != NULL && !thread->is_exiting() && + java_tid == java_lang_Thread::thread_id(tobj)) { + // found a match + return thread; + } + } + return NULL; } -ThreadsListHandle::ThreadsListHandle(Thread *self) : _list(Threads::acquire_stable_list(self, /* is_ThreadsListSetter */ false)), _self(self) { +bool ThreadsList::includes(const JavaThread * const p) const { + if (p == NULL) { + return false; + } + for (uint i = 0; i < length(); i++) { + if (thread_at(i) == p) { + return true; + } + } + return false; +} + +// Remove a JavaThread from a ThreadsList. The returned ThreadsList is a +// new copy of the specified ThreadsList with the specified JavaThread +// removed. +ThreadsList *ThreadsList::remove_thread(ThreadsList* list, JavaThread* java_thread) { + assert(list->_length > 0, "sanity"); + + uint i = (uint)list->find_index_of_JavaThread(java_thread); + assert(i < list->_length, "did not find JavaThread on the list"); + const uint index = i; + const uint new_length = list->_length - 1; + const uint head_length = index; + const uint tail_length = (new_length >= index) ? (new_length - index) : 0; + ThreadsList *const new_list = new ThreadsList(new_length); + + if (head_length > 0) { + Copy::disjoint_words((HeapWord*)list->_threads, (HeapWord*)new_list->_threads, head_length); + } + if (tail_length > 0) { + Copy::disjoint_words((HeapWord*)list->_threads + index + 1, (HeapWord*)new_list->_threads + index, tail_length); + } + + return new_list; +} + +ThreadsListHandle::ThreadsListHandle(Thread *self) : _list(ThreadsSMRSupport::acquire_stable_list(self, /* is_ThreadsListSetter */ false)), _self(self) { assert(self == Thread::current(), "sanity check"); if (EnableThreadSMRStatistics) { _timer.start(); @@ -58,13 +472,11 @@ } ThreadsListHandle::~ThreadsListHandle() { - Threads::release_stable_list(_self); + ThreadsSMRSupport::release_stable_list(_self); if (EnableThreadSMRStatistics) { _timer.stop(); uint millis = (uint)_timer.milliseconds(); - Threads::inc_smr_tlh_cnt(); - Threads::add_smr_tlh_times(millis); - Threads::update_smr_tlh_time_max(millis); + ThreadsSMRSupport::update_smr_tlh_stats(millis); } } @@ -119,3 +531,546 @@ *jt_pp = java_thread; return true; } + +ThreadsListSetter::~ThreadsListSetter() { + if (_target_needs_release) { + // The hazard ptr in the target needs to be released. + ThreadsSMRSupport::release_stable_list(_target); + } +} + +void ThreadsListSetter::set() { + assert(_target->get_threads_hazard_ptr() == NULL, "hazard ptr should not already be set"); + (void) ThreadsSMRSupport::acquire_stable_list(_target, /* is_ThreadsListSetter */ true); + _target_needs_release = true; +} + +// Acquire a stable ThreadsList. +// +ThreadsList *ThreadsSMRSupport::acquire_stable_list(Thread *self, bool is_ThreadsListSetter) { + assert(self != NULL, "sanity check"); + // acquire_stable_list_nested_path() will grab the Threads_lock + // so let's make sure the ThreadsListHandle is in a safe place. + // ThreadsListSetter cannot make this check on this code path. + debug_only(if (!is_ThreadsListSetter && StrictSafepointChecks) self->check_for_valid_safepoint_state(/* potential_vm_operation */ false);) + + if (self->get_threads_hazard_ptr() == NULL) { + // The typical case is first. + return acquire_stable_list_fast_path(self); + } + + // The nested case is rare. + return acquire_stable_list_nested_path(self); +} + +// Fast path (and lock free) way to acquire a stable ThreadsList. +// +ThreadsList *ThreadsSMRSupport::acquire_stable_list_fast_path(Thread *self) { + assert(self != NULL, "sanity check"); + assert(self->get_threads_hazard_ptr() == NULL, "sanity check"); + assert(self->get_nested_threads_hazard_ptr() == NULL, + "cannot have a nested hazard ptr with a NULL regular hazard ptr"); + + ThreadsList* threads; + + // Stable recording of a hazard ptr for SMR. This code does not use + // locks so its use of the _smr_java_thread_list & _threads_hazard_ptr + // fields is racy relative to code that uses those fields with locks. + // OrderAccess and Atomic functions are used to deal with those races. + // + while (true) { + threads = get_smr_java_thread_list(); + + // Publish a tagged hazard ptr to denote that the hazard ptr is not + // yet verified as being stable. Due to the fence after the hazard + // ptr write, it will be sequentially consistent w.r.t. the + // sequentially consistent writes of the ThreadsList, even on + // non-multiple copy atomic machines where stores can be observed + // in different order from different observer threads. + ThreadsList* unverified_threads = Thread::tag_hazard_ptr(threads); + self->set_threads_hazard_ptr(unverified_threads); + + // If _smr_java_thread_list has changed, we have lost a race with + // Threads::add() or Threads::remove() and have to try again. + if (get_smr_java_thread_list() != threads) { + continue; + } + + // We try to remove the tag which will verify the hazard ptr as + // being stable. This exchange can race with a scanning thread + // which might invalidate the tagged hazard ptr to keep it from + // being followed to access JavaThread ptrs. If we lose the race, + // we simply retry. If we win the race, then the stable hazard + // ptr is officially published. + if (self->cmpxchg_threads_hazard_ptr(threads, unverified_threads) == unverified_threads) { + break; + } + } + + // A stable hazard ptr has been published letting other threads know + // that the ThreadsList and the JavaThreads reachable from this list + // are protected and hence they should not be deleted until everyone + // agrees it is safe to do so. + + return threads; +} + +// Acquire a nested stable ThreadsList; this is rare so it uses +// Threads_lock. +// +ThreadsList *ThreadsSMRSupport::acquire_stable_list_nested_path(Thread *self) { + assert(self != NULL, "sanity check"); + assert(self->get_threads_hazard_ptr() != NULL, + "cannot have a NULL regular hazard ptr when acquiring a nested hazard ptr"); + + // The thread already has a hazard ptr (ThreadsList ref) so we need + // to create a nested ThreadsListHandle with the current ThreadsList + // since it might be different than our current hazard ptr. The need + // for a nested ThreadsListHandle is rare so we do this while holding + // the Threads_lock so we don't race with the scanning code; the code + // is so much simpler this way. + + NestedThreadsList* node; + { + // Only grab the Threads_lock if we don't already own it. + MutexLockerEx ml(Threads_lock->owned_by_self() ? NULL : Threads_lock); + node = new NestedThreadsList(get_smr_java_thread_list()); + // We insert at the front of the list to match up with the delete + // in release_stable_list(). + node->set_next(self->get_nested_threads_hazard_ptr()); + self->set_nested_threads_hazard_ptr(node); + if (EnableThreadSMRStatistics) { + self->inc_nested_threads_hazard_ptr_cnt(); + if (self->nested_threads_hazard_ptr_cnt() > _smr_nested_thread_list_max) { + _smr_nested_thread_list_max = self->nested_threads_hazard_ptr_cnt(); + } + } + } + log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::acquire_stable_list: add NestedThreadsList node containing ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(node->t_list())); + + return node->t_list(); +} + +void ThreadsSMRSupport::add_thread(JavaThread *thread){ + ThreadsList *new_list = ThreadsList::add_thread(ThreadsSMRSupport::get_smr_java_thread_list(), thread); + if (EnableThreadSMRStatistics) { + ThreadsSMRSupport::inc_smr_java_thread_list_alloc_cnt(); + ThreadsSMRSupport::update_smr_java_thread_list_max(new_list->length()); + } + // Initial _smr_java_thread_list will not generate a "Threads::add" mesg. + log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::add: new ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(new_list)); + + ThreadsList *old_list = ThreadsSMRSupport::xchg_smr_java_thread_list(new_list); + ThreadsSMRSupport::smr_free_list(old_list); +} + +// set_smr_delete_notify() and clear_smr_delete_notify() are called +// under the protection of the smr_delete_lock, but we also use an +// Atomic operation to ensure the memory update is seen earlier than +// when the smr_delete_lock is dropped. +// +void ThreadsSMRSupport::clear_smr_delete_notify() { + Atomic::dec(&_smr_delete_notify); +} + +// Return true if the specified JavaThread is protected by a hazard +// pointer (ThreadsList reference). Otherwise, returns false. +// +bool ThreadsSMRSupport::is_a_protected_JavaThread(JavaThread *thread) { + assert_locked_or_safepoint(Threads_lock); + + // Hash table size should be first power of two higher than twice + // the length of the Threads list. + int hash_table_size = MIN2((int)get_smr_java_thread_list()->length(), 32) << 1; + hash_table_size--; + hash_table_size |= hash_table_size >> 1; + hash_table_size |= hash_table_size >> 2; + hash_table_size |= hash_table_size >> 4; + hash_table_size |= hash_table_size >> 8; + hash_table_size |= hash_table_size >> 16; + hash_table_size++; + + // Gather a hash table of the JavaThreads indirectly referenced by + // hazard ptrs. + ThreadScanHashtable *scan_table = new ThreadScanHashtable(hash_table_size); + ScanHazardPtrGatherProtectedThreadsClosure scan_cl(scan_table); + Threads::threads_do(&scan_cl); + + bool thread_is_protected = false; + if (scan_table->has_entry((void*)thread)) { + thread_is_protected = true; + } + delete scan_table; + return thread_is_protected; +} + +// Release a stable ThreadsList. +// +void ThreadsSMRSupport::release_stable_list(Thread *self) { + assert(self != NULL, "sanity check"); + // release_stable_list_nested_path() will grab the Threads_lock + // so let's make sure the ThreadsListHandle is in a safe place. + debug_only(if (StrictSafepointChecks) self->check_for_valid_safepoint_state(/* potential_vm_operation */ false);) + + if (self->get_nested_threads_hazard_ptr() == NULL) { + // The typical case is first. + release_stable_list_fast_path(self); + return; + } + + // The nested case is rare. + release_stable_list_nested_path(self); +} + +// Fast path way to release a stable ThreadsList. The release portion +// is lock-free, but the wake up portion is not. +// +void ThreadsSMRSupport::release_stable_list_fast_path(Thread *self) { + assert(self != NULL, "sanity check"); + assert(self->get_threads_hazard_ptr() != NULL, "sanity check"); + assert(self->get_nested_threads_hazard_ptr() == NULL, + "cannot have a nested hazard ptr when releasing a regular hazard ptr"); + + // After releasing the hazard ptr, other threads may go ahead and + // free up some memory temporarily used by a ThreadsList snapshot. + self->set_threads_hazard_ptr(NULL); + + // We use double-check locking to reduce traffic on the system + // wide smr_delete_lock. + if (ThreadsSMRSupport::smr_delete_notify()) { + // An exiting thread might be waiting in smr_delete(); we need to + // check with smr_delete_lock to be sure. + release_stable_list_wake_up((char *) "regular hazard ptr"); + } +} + +// Release a nested stable ThreadsList; this is rare so it uses +// Threads_lock. +// +void ThreadsSMRSupport::release_stable_list_nested_path(Thread *self) { + assert(self != NULL, "sanity check"); + assert(self->get_nested_threads_hazard_ptr() != NULL, "sanity check"); + assert(self->get_threads_hazard_ptr() != NULL, + "must have a regular hazard ptr to have nested hazard ptrs"); + + // We have a nested ThreadsListHandle so we have to release it first. + // The need for a nested ThreadsListHandle is rare so we do this while + // holding the Threads_lock so we don't race with the scanning code; + // the code is so much simpler this way. + + NestedThreadsList *node; + { + // Only grab the Threads_lock if we don't already own it. + MutexLockerEx ml(Threads_lock->owned_by_self() ? NULL : Threads_lock); + // We remove from the front of the list to match up with the insert + // in acquire_stable_list(). + node = self->get_nested_threads_hazard_ptr(); + self->set_nested_threads_hazard_ptr(node->next()); + if (EnableThreadSMRStatistics) { + self->dec_nested_threads_hazard_ptr_cnt(); + } + } + + // An exiting thread might be waiting in smr_delete(); we need to + // check with smr_delete_lock to be sure. + release_stable_list_wake_up((char *) "nested hazard ptr"); + + log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::release_stable_list: delete NestedThreadsList node containing ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(node->t_list())); + + delete node; +} + +// Wake up portion of the release stable ThreadsList protocol; +// uses the smr_delete_lock(). +// +void ThreadsSMRSupport::release_stable_list_wake_up(char *log_str) { + assert(log_str != NULL, "sanity check"); + + // Note: smr_delete_lock is held in smr_delete() for the entire + // hazard ptr search so that we do not lose this notify() if + // the exiting thread has to wait. That code path also holds + // Threads_lock (which was grabbed before smr_delete_lock) so that + // threads_do() can be called. This means the system can't start a + // safepoint which means this thread can't take too long to get to + // a safepoint because of being blocked on smr_delete_lock. + // + MonitorLockerEx ml(ThreadsSMRSupport::smr_delete_lock(), Monitor::_no_safepoint_check_flag); + if (ThreadsSMRSupport::smr_delete_notify()) { + // Notify any exiting JavaThreads that are waiting in smr_delete() + // that we've released a ThreadsList. + ml.notify_all(); + log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::release_stable_list notified %s", os::current_thread_id(), log_str); + } +} + +void ThreadsSMRSupport::remove_thread(JavaThread *thread) { + ThreadsList *new_list = ThreadsList::remove_thread(ThreadsSMRSupport::get_smr_java_thread_list(), thread); + if (EnableThreadSMRStatistics) { + ThreadsSMRSupport::inc_smr_java_thread_list_alloc_cnt(); + // This list is smaller so no need to check for a "longest" update. + } + + // Final _smr_java_thread_list will not generate a "Threads::remove" mesg. + log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::remove: new ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(new_list)); + + ThreadsList *old_list = ThreadsSMRSupport::xchg_smr_java_thread_list(new_list); + ThreadsSMRSupport::smr_free_list(old_list); +} + +// See note for clear_smr_delete_notify(). +// +void ThreadsSMRSupport::set_smr_delete_notify() { + Atomic::inc(&_smr_delete_notify); +} + +// Safely delete a JavaThread when it is no longer in use by a +// ThreadsListHandle. +// +void ThreadsSMRSupport::smr_delete(JavaThread *thread) { + assert(!Threads_lock->owned_by_self(), "sanity"); + + bool has_logged_once = false; + elapsedTimer timer; + if (EnableThreadSMRStatistics) { + timer.start(); + } + + while (true) { + { + // No safepoint check because this JavaThread is not on the + // Threads list. + MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag); + // Cannot use a MonitorLockerEx helper here because we have + // to drop the Threads_lock first if we wait. + ThreadsSMRSupport::smr_delete_lock()->lock_without_safepoint_check(); + // Set the smr_delete_notify flag after we grab smr_delete_lock + // and before we scan hazard ptrs because we're doing + // double-check locking in release_stable_list(). + ThreadsSMRSupport::set_smr_delete_notify(); + + if (!is_a_protected_JavaThread(thread)) { + // This is the common case. + ThreadsSMRSupport::clear_smr_delete_notify(); + ThreadsSMRSupport::smr_delete_lock()->unlock(); + break; + } + if (!has_logged_once) { + has_logged_once = true; + log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::smr_delete: thread=" INTPTR_FORMAT " is not deleted.", os::current_thread_id(), p2i(thread)); + if (log_is_enabled(Debug, os, thread)) { + ScanHazardPtrPrintMatchingThreadsClosure scan_cl(thread); + Threads::threads_do(&scan_cl); + } + } + } // We have to drop the Threads_lock to wait or delete the thread + + if (EnableThreadSMRStatistics) { + _smr_delete_lock_wait_cnt++; + if (_smr_delete_lock_wait_cnt > _smr_delete_lock_wait_max) { + _smr_delete_lock_wait_max = _smr_delete_lock_wait_cnt; + } + } + // Wait for a release_stable_list() call before we check again. No + // safepoint check, no timeout, and not as suspend equivalent flag + // because this JavaThread is not on the Threads list. + ThreadsSMRSupport::smr_delete_lock()->wait(Mutex::_no_safepoint_check_flag, 0, + !Mutex::_as_suspend_equivalent_flag); + if (EnableThreadSMRStatistics) { + _smr_delete_lock_wait_cnt--; + } + + ThreadsSMRSupport::clear_smr_delete_notify(); + ThreadsSMRSupport::smr_delete_lock()->unlock(); + // Retry the whole scenario. + } + + if (ThreadLocalHandshakes) { + // The thread is about to be deleted so cancel any handshake. + thread->cancel_handshake(); + } + + delete thread; + if (EnableThreadSMRStatistics) { + timer.stop(); + uint millis = (uint)timer.milliseconds(); + ThreadsSMRSupport::inc_smr_deleted_thread_cnt(); + ThreadsSMRSupport::add_smr_deleted_thread_times(millis); + ThreadsSMRSupport::update_smr_deleted_thread_time_max(millis); + } + + log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::smr_delete: thread=" INTPTR_FORMAT " is deleted.", os::current_thread_id(), p2i(thread)); +} + +bool ThreadsSMRSupport::smr_delete_notify() { + // Use load_acquire() in order to see any updates to _smr_delete_notify + // earlier than when smr_delete_lock is grabbed. + return (OrderAccess::load_acquire(&_smr_delete_notify) != 0); +} + +// Safely free a ThreadsList after a Threads::add() or Threads::remove(). +// The specified ThreadsList may not get deleted during this call if it +// is still in-use (referenced by a hazard ptr). Other ThreadsLists +// in the chain may get deleted by this call if they are no longer in-use. +void ThreadsSMRSupport::smr_free_list(ThreadsList* threads) { + assert_locked_or_safepoint(Threads_lock); + + threads->set_next_list(_smr_to_delete_list); + _smr_to_delete_list = threads; + if (EnableThreadSMRStatistics) { + _smr_to_delete_list_cnt++; + if (_smr_to_delete_list_cnt > _smr_to_delete_list_max) { + _smr_to_delete_list_max = _smr_to_delete_list_cnt; + } + } + + // Hash table size should be first power of two higher than twice the length of the ThreadsList + int hash_table_size = MIN2((int)get_smr_java_thread_list()->length(), 32) << 1; + hash_table_size--; + hash_table_size |= hash_table_size >> 1; + hash_table_size |= hash_table_size >> 2; + hash_table_size |= hash_table_size >> 4; + hash_table_size |= hash_table_size >> 8; + hash_table_size |= hash_table_size >> 16; + hash_table_size++; + + // Gather a hash table of the current hazard ptrs: + ThreadScanHashtable *scan_table = new ThreadScanHashtable(hash_table_size); + ScanHazardPtrGatherThreadsListClosure scan_cl(scan_table); + Threads::threads_do(&scan_cl); + + // Walk through the linked list of pending freeable ThreadsLists + // and free the ones that are not referenced from hazard ptrs. + ThreadsList* current = _smr_to_delete_list; + ThreadsList* prev = NULL; + ThreadsList* next = NULL; + bool threads_is_freed = false; + while (current != NULL) { + next = current->next_list(); + if (!scan_table->has_entry((void*)current)) { + // This ThreadsList is not referenced by a hazard ptr. + if (prev != NULL) { + prev->set_next_list(next); + } + if (_smr_to_delete_list == current) { + _smr_to_delete_list = next; + } + + log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::smr_free_list: threads=" INTPTR_FORMAT " is freed.", os::current_thread_id(), p2i(current)); + if (current == threads) threads_is_freed = true; + delete current; + if (EnableThreadSMRStatistics) { + _smr_java_thread_list_free_cnt++; + _smr_to_delete_list_cnt--; + } + } else { + prev = current; + } + current = next; + } + + if (!threads_is_freed) { + // Only report "is not freed" on the original call to + // smr_free_list() for this ThreadsList. + log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::smr_free_list: threads=" INTPTR_FORMAT " is not freed.", os::current_thread_id(), p2i(threads)); + } + + delete scan_table; +} + + +// Debug, logging, and printing stuff at the end: + +// Log Threads class SMR info. +void ThreadsSMRSupport::log_smr_statistics() { + LogTarget(Info, thread, smr) log; + if (log.is_enabled()) { + LogStream out(log); + print_smr_info_on(&out); + } +} + +// Print Threads class SMR info. +void ThreadsSMRSupport::print_smr_info_on(outputStream* st) { + // Only grab the Threads_lock if we don't already own it + // and if we are not reporting an error. + MutexLockerEx ml((Threads_lock->owned_by_self() || VMError::is_error_reported()) ? NULL : Threads_lock); + + st->print_cr("Threads class SMR info:"); + st->print_cr("_smr_java_thread_list=" INTPTR_FORMAT ", length=%u, " + "elements={", p2i(_smr_java_thread_list), + _smr_java_thread_list->length()); + print_smr_info_elements_on(st, _smr_java_thread_list); + st->print_cr("}"); + if (_smr_to_delete_list != NULL) { + st->print_cr("_smr_to_delete_list=" INTPTR_FORMAT ", length=%u, " + "elements={", p2i(_smr_to_delete_list), + _smr_to_delete_list->length()); + print_smr_info_elements_on(st, _smr_to_delete_list); + st->print_cr("}"); + for (ThreadsList *t_list = _smr_to_delete_list->next_list(); + t_list != NULL; t_list = t_list->next_list()) { + st->print("next-> " INTPTR_FORMAT ", length=%u, " + "elements={", p2i(t_list), t_list->length()); + print_smr_info_elements_on(st, t_list); + st->print_cr("}"); + } + } + if (!EnableThreadSMRStatistics) { + return; + } + st->print_cr("_smr_java_thread_list_alloc_cnt=" UINT64_FORMAT "," + "_smr_java_thread_list_free_cnt=" UINT64_FORMAT "," + "_smr_java_thread_list_max=%u, " + "_smr_nested_thread_list_max=%u", + _smr_java_thread_list_alloc_cnt, + _smr_java_thread_list_free_cnt, + _smr_java_thread_list_max, + _smr_nested_thread_list_max); + if (_smr_tlh_cnt > 0) { + st->print_cr("_smr_tlh_cnt=%u" + ", _smr_tlh_times=%u" + ", avg_smr_tlh_time=%0.2f" + ", _smr_tlh_time_max=%u", + _smr_tlh_cnt, _smr_tlh_times, + ((double) _smr_tlh_times / _smr_tlh_cnt), + _smr_tlh_time_max); + } + if (_smr_deleted_thread_cnt > 0) { + st->print_cr("_smr_deleted_thread_cnt=%u" + ", _smr_deleted_thread_times=%u" + ", avg_smr_deleted_thread_time=%0.2f" + ", _smr_deleted_thread_time_max=%u", + _smr_deleted_thread_cnt, _smr_deleted_thread_times, + ((double) _smr_deleted_thread_times / _smr_deleted_thread_cnt), + _smr_deleted_thread_time_max); + } + st->print_cr("_smr_delete_lock_wait_cnt=%u, _smr_delete_lock_wait_max=%u", + _smr_delete_lock_wait_cnt, _smr_delete_lock_wait_max); + st->print_cr("_smr_to_delete_list_cnt=%u, _smr_to_delete_list_max=%u", + _smr_to_delete_list_cnt, _smr_to_delete_list_max); +} + +// Print ThreadsList elements (4 per line). +void ThreadsSMRSupport::print_smr_info_elements_on(outputStream* st, + ThreadsList* t_list) { + uint cnt = 0; + JavaThreadIterator jti(t_list); + for (JavaThread *jt = jti.first(); jt != NULL; jt = jti.next()) { + st->print(INTPTR_FORMAT, p2i(jt)); + if (cnt < t_list->length() - 1) { + // Separate with comma or comma-space except for the last one. + if (((cnt + 1) % 4) == 0) { + // Four INTPTR_FORMAT fit on an 80 column line so end the + // current line with just a comma. + st->print_cr(","); + } else { + // Not the last one on the current line so use comma-space: + st->print(", "); + } + } else { + // Last one so just end the current line. + st->cr(); + } + cnt++; + } +} diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/runtime/threadSMR.hpp --- a/src/hotspot/share/runtime/threadSMR.hpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/runtime/threadSMR.hpp Thu Dec 14 12:28:32 2017 +0000 @@ -77,11 +77,77 @@ // longer protected by a ThreadsListHandle. +// SMR Support for the Threads class. +// +class ThreadsSMRSupport : AllStatic { + // The coordination between ThreadsSMRSupport::release_stable_list() and + // ThreadsSMRSupport::smr_delete() uses the smr_delete_lock in order to + // reduce the traffic on the Threads_lock. + static Monitor* _smr_delete_lock; + // The '_cnt', '_max' and '_times" fields are enabled via + // -XX:+EnableThreadSMRStatistics (see thread.cpp for a + // description about each field): + static uint _smr_delete_lock_wait_cnt; + static uint _smr_delete_lock_wait_max; + // The smr_delete_notify flag is used for proper double-check + // locking in order to reduce the traffic on the smr_delete_lock. + static volatile uint _smr_delete_notify; + static volatile uint _smr_deleted_thread_cnt; + static volatile uint _smr_deleted_thread_time_max; + static volatile uint _smr_deleted_thread_times; + static ThreadsList* volatile _smr_java_thread_list; + static uint64_t _smr_java_thread_list_alloc_cnt; + static uint64_t _smr_java_thread_list_free_cnt; + static uint _smr_java_thread_list_max; + static uint _smr_nested_thread_list_max; + static volatile uint _smr_tlh_cnt; + static volatile uint _smr_tlh_time_max; + static volatile uint _smr_tlh_times; + static ThreadsList* _smr_to_delete_list; + static uint _smr_to_delete_list_cnt; + static uint _smr_to_delete_list_max; + + static ThreadsList *acquire_stable_list_fast_path(Thread *self); + static ThreadsList *acquire_stable_list_nested_path(Thread *self); + static void add_smr_deleted_thread_times(uint add_value); + static void add_smr_tlh_times(uint add_value); + static void clear_smr_delete_notify(); + static void inc_smr_deleted_thread_cnt(); + static void inc_smr_java_thread_list_alloc_cnt(); + static void inc_smr_tlh_cnt(); + static bool is_a_protected_JavaThread(JavaThread *thread); + static void release_stable_list_fast_path(Thread *self); + static void release_stable_list_nested_path(Thread *self); + static void release_stable_list_wake_up(char *log_str); + static void set_smr_delete_notify(); + static Monitor* smr_delete_lock() { return _smr_delete_lock; } + static bool smr_delete_notify(); + static void smr_free_list(ThreadsList* threads); + static void update_smr_deleted_thread_time_max(uint new_value); + static void update_smr_java_thread_list_max(uint new_value); + static void update_smr_tlh_time_max(uint new_value); + static ThreadsList* xchg_smr_java_thread_list(ThreadsList* new_list); + + public: + static ThreadsList *acquire_stable_list(Thread *self, bool is_ThreadsListSetter); + static void add_thread(JavaThread *thread); + static ThreadsList* get_smr_java_thread_list(); + static bool is_a_protected_JavaThread_with_lock(JavaThread *thread); + static void release_stable_list(Thread *self); + static void remove_thread(JavaThread *thread); + static void smr_delete(JavaThread *thread); + static void update_smr_tlh_stats(uint millis); + + // Logging and printing support: + static void log_smr_statistics(); + static void print_smr_info_elements_on(outputStream* st, ThreadsList* t_list); + static void print_smr_info_on(outputStream* st); +}; + // A fast list of JavaThreads. // class ThreadsList : public CHeapObj { - friend class ScanHazardPtrGatherProtectedThreadsClosure; - friend class Threads; + friend class ThreadsSMRSupport; // for next_list(), set_next_list() access const uint _length; ThreadsList* _next_list; @@ -93,6 +159,9 @@ ThreadsList *next_list() const { return _next_list; } void set_next_list(ThreadsList *list) { _next_list = list; } + static ThreadsList* add_thread(ThreadsList* list, JavaThread* java_thread); + static ThreadsList* remove_thread(ThreadsList* list, JavaThread* java_thread); + public: ThreadsList(int entries); ~ThreadsList(); @@ -110,9 +179,6 @@ int find_index_of_JavaThread(JavaThread* target); JavaThread* find_JavaThread_from_java_tid(jlong java_tid) const; bool includes(const JavaThread * const p) const; - - static ThreadsList* add_thread(ThreadsList* list, JavaThread* java_thread); - static ThreadsList* remove_thread(ThreadsList* list, JavaThread* java_thread); }; // Linked list of ThreadsLists to support nested ThreadsListHandles. diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/runtime/threadSMR.inline.hpp --- a/src/hotspot/share/runtime/threadSMR.inline.hpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/runtime/threadSMR.inline.hpp Thu Dec 14 12:28:32 2017 +0000 @@ -52,6 +52,32 @@ } } +// These three inlines are private to ThreadsSMRSupport, but +// they are called by public inline update_smr_tlh_stats() below: + +inline void ThreadsSMRSupport::add_smr_tlh_times(uint add_value) { + Atomic::add(add_value, &_smr_tlh_times); +} + +inline void ThreadsSMRSupport::inc_smr_tlh_cnt() { + Atomic::inc(&_smr_tlh_cnt); +} + +inline void ThreadsSMRSupport::update_smr_tlh_time_max(uint new_value) { + while (true) { + uint cur_value = _smr_tlh_time_max; + if (new_value <= cur_value) { + // No need to update max value so we're done. + break; + } + if (Atomic::cmpxchg(new_value, &_smr_tlh_time_max, cur_value) == cur_value) { + // Updated max value so we're done. Otherwise try it all again. + break; + } + } +} + + inline ThreadsList* ThreadsListSetter::list() { ThreadsList *ret = _target->get_threads_hazard_ptr(); assert(ret != NULL, "hazard ptr should be set"); @@ -59,4 +85,19 @@ return ret; } +inline ThreadsList* ThreadsSMRSupport::get_smr_java_thread_list() { + return (ThreadsList*)OrderAccess::load_acquire(&_smr_java_thread_list); +} + +inline bool ThreadsSMRSupport::is_a_protected_JavaThread_with_lock(JavaThread *thread) { + MutexLockerEx ml(Threads_lock->owned_by_self() ? NULL : Threads_lock); + return is_a_protected_JavaThread(thread); +} + +inline void ThreadsSMRSupport::update_smr_tlh_stats(uint millis) { + ThreadsSMRSupport::inc_smr_tlh_cnt(); + ThreadsSMRSupport::add_smr_tlh_times(millis); + ThreadsSMRSupport::update_smr_tlh_time_max(millis); +} + #endif // SHARE_VM_RUNTIME_THREADSMR_INLINE_HPP diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/runtime/vmStructs.cpp --- a/src/hotspot/share/runtime/vmStructs.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/runtime/vmStructs.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -1991,6 +1991,7 @@ declare_c2_type(MulVDNode, VectorNode) \ declare_c2_type(FmaVDNode, VectorNode) \ declare_c2_type(FmaVFNode, VectorNode) \ + declare_c2_type(CMoveVFNode, VectorNode) \ declare_c2_type(CMoveVDNode, VectorNode) \ declare_c2_type(MulReductionVDNode, ReductionNode) \ declare_c2_type(DivVFNode, VectorNode) \ diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/runtime/vm_operations.hpp --- a/src/hotspot/share/runtime/vm_operations.hpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/runtime/vm_operations.hpp Thu Dec 14 12:28:32 2017 +0000 @@ -29,6 +29,7 @@ #include "memory/allocation.hpp" #include "oops/oop.hpp" #include "runtime/thread.hpp" +#include "runtime/threadSMR.hpp" #include "code/codeCache.hpp" // The following classes are used for operations diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/runtime/vm_version.cpp --- a/src/hotspot/share/runtime/vm_version.cpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/runtime/vm_version.cpp Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,14 +48,14 @@ #error HOTSPOT_VERSION_STRING must be defined #endif -#ifndef VERSION_MAJOR - #error VERSION_MAJOR must be defined +#ifndef VERSION_FEATURE + #error VERSION_FEATURE must be defined #endif -#ifndef VERSION_MINOR - #error VERSION_MINOR must be defined +#ifndef VERSION_INTERIM + #error VERSION_INTERIM must be defined #endif -#ifndef VERSION_SECURITY - #error VERSION_SECURITY must be defined +#ifndef VERSION_UPDATE + #error VERSION_UPDATE must be defined #endif #ifndef VERSION_PATCH #error VERSION_PATCH must be defined @@ -76,9 +76,9 @@ // HOTSPOT_VERSION_STRING equals the JDK VERSION_STRING (unless overridden // in a standalone build). -int Abstract_VM_Version::_vm_major_version = VERSION_MAJOR; -int Abstract_VM_Version::_vm_minor_version = VERSION_MINOR; -int Abstract_VM_Version::_vm_security_version = VERSION_SECURITY; +int Abstract_VM_Version::_vm_major_version = VERSION_FEATURE; +int Abstract_VM_Version::_vm_minor_version = VERSION_INTERIM; +int Abstract_VM_Version::_vm_security_version = VERSION_UPDATE; int Abstract_VM_Version::_vm_patch_version = VERSION_PATCH; int Abstract_VM_Version::_vm_build_number = VERSION_BUILD; unsigned int Abstract_VM_Version::_parallel_worker_threads = 0; diff -r 907bddce488c -r b6ff245c0db6 src/hotspot/share/services/threadService.hpp --- a/src/hotspot/share/services/threadService.hpp Mon Dec 11 16:43:11 2017 +0000 +++ b/src/hotspot/share/services/threadService.hpp Thu Dec 14 12:28:32 2017 +0000 @@ -33,6 +33,7 @@ #include "runtime/objectMonitor.inline.hpp" #include "runtime/perfData.hpp" #include "runtime/thread.hpp" +#include "runtime/threadSMR.hpp" #include "services/management.hpp" #include "services/serviceUtil.hpp" diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java --- a/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -769,6 +769,8 @@ "com.sun.crypto.provider.TlsMasterSecretGenerator"); put("Alg.Alias.KeyGenerator.SunTls12MasterSecret", "SunTlsMasterSecret"); + put("Alg.Alias.KeyGenerator.SunTlsExtendedMasterSecret", + "SunTlsMasterSecret"); put("KeyGenerator.SunTlsKeyMaterial", "com.sun.crypto.provider.TlsKeyMaterialGenerator"); diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/com/sun/crypto/provider/TlsMasterSecretGenerator.java --- a/src/java.base/share/classes/com/sun/crypto/provider/TlsMasterSecretGenerator.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/com/sun/crypto/provider/TlsMasterSecretGenerator.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -102,21 +102,32 @@ try { byte[] master; - byte[] clientRandom = spec.getClientRandom(); - byte[] serverRandom = spec.getServerRandom(); - if (protocolVersion >= 0x0301) { - byte[] seed = concat(clientRandom, serverRandom); + byte[] label; + byte[] seed; + byte[] extendedMasterSecretSessionHash = + spec.getExtendedMasterSecretSessionHash(); + if (extendedMasterSecretSessionHash.length != 0) { + label = LABEL_EXTENDED_MASTER_SECRET; + seed = extendedMasterSecretSessionHash; + } else { + byte[] clientRandom = spec.getClientRandom(); + byte[] serverRandom = spec.getServerRandom(); + label = LABEL_MASTER_SECRET; + seed = concat(clientRandom, serverRandom); + } master = ((protocolVersion >= 0x0303) ? - doTLS12PRF(premaster, LABEL_MASTER_SECRET, seed, 48, - spec.getPRFHashAlg(), spec.getPRFHashLength(), - spec.getPRFBlockSize()) : - doTLS10PRF(premaster, LABEL_MASTER_SECRET, seed, 48)); + doTLS12PRF(premaster, label, seed, 48, + spec.getPRFHashAlg(), spec.getPRFHashLength(), + spec.getPRFBlockSize()) : + doTLS10PRF(premaster, label, seed, 48)); } else { master = new byte[48]; MessageDigest md5 = MessageDigest.getInstance("MD5"); MessageDigest sha = MessageDigest.getInstance("SHA"); + byte[] clientRandom = spec.getClientRandom(); + byte[] serverRandom = spec.getServerRandom(); byte[] tmp = new byte[20]; for (int i = 0; i < 3; i++) { sha.update(SSL3_CONST[i]); @@ -175,5 +186,5 @@ } } +} -} diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java --- a/src/java.base/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,6 +55,11 @@ static final byte[] LABEL_MASTER_SECRET = // "master secret" { 109, 97, 115, 116, 101, 114, 32, 115, 101, 99, 114, 101, 116 }; + static final byte[] LABEL_EXTENDED_MASTER_SECRET = + // "extended master secret" + { 101, 120, 116, 101, 110, 100, 101, 100, 32, 109, 97, 115, 116, + 101, 114, 32, 115, 101, 99, 114, 101, 116 }; + static final byte[] LABEL_KEY_EXPANSION = // "key expansion" { 107, 101, 121, 32, 101, 120, 112, 97, 110, 115, 105, 111, 110 }; diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/io/ByteArrayOutputStream.java --- a/src/java.base/share/classes/java/io/ByteArrayOutputStream.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/io/ByteArrayOutputStream.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ package java.io; +import java.nio.charset.Charset; import java.util.Arrays; /** @@ -223,14 +224,27 @@ /** * Converts the buffer's contents into a string by decoding the bytes using - * the named {@link java.nio.charset.Charset charset}. The length of the new - * {@code String} is a function of the charset, and hence may not be equal - * to the length of the byte array. + * the named {@link java.nio.charset.Charset charset}. + * + *

This method is equivalent to {@code #toString(charset)} that takes a + * {@link java.nio.charset.Charset charset}. + * + *

An invocation of this method of the form * - *

This method always replaces malformed-input and unmappable-character - * sequences with this charset's default replacement string. The {@link - * java.nio.charset.CharsetDecoder} class should be used when more control - * over the decoding process is required. + *

 {@code
+     *      ByteArrayOutputStream b = ...
+     *      b.toString("UTF-8")
+     *      }
+     * 
+ * + * behaves in exactly the same way as the expression + * + *
 {@code
+     *      ByteArrayOutputStream b = ...
+     *      b.toString(StandardCharsets.UTF_8)
+     *      }
+     * 
+ * * * @param charsetName the name of a supported * {@link java.nio.charset.Charset charset} @@ -246,6 +260,26 @@ } /** + * Converts the buffer's contents into a string by decoding the bytes using + * the specified {@link java.nio.charset.Charset charset}. The length of the new + * {@code String} is a function of the charset, and hence may not be equal + * to the length of the byte array. + * + *

This method always replaces malformed-input and unmappable-character + * sequences with the charset's default replacement string. The {@link + * java.nio.charset.CharsetDecoder} class should be used when more control + * over the decoding process is required. + * + * @param charset the {@linkplain java.nio.charset.Charset charset} + * to be used to decode the {@code bytes} + * @return String decoded from the buffer's contents. + * @since 10 + */ + public synchronized String toString(Charset charset) { + return new String(buf, 0, count, charset); + } + + /** * Creates a newly allocated string. Its size is the current size of * the output stream and the valid contents of the buffer have been * copied into it. Each character c in the resulting string is @@ -257,9 +291,10 @@ * * @deprecated This method does not properly convert bytes into characters. * As of JDK 1.1, the preferred way to do this is via the - * {@code toString(String enc)} method, which takes an encoding-name - * argument, or the {@code toString()} method, which uses the - * platform's default character encoding. + * {@link #toString(String charsetName)} or {@link #toString(Charset charset)} + * method, which takes an encoding-name or charset argument, + * or the {@code toString()} method, which uses the platform's default + * character encoding. * * @param hibyte the high byte of each resulting Unicode character. * @return the current contents of the output stream, as a string. diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/io/FileInputStream.java --- a/src/java.base/share/classes/java/io/FileInputStream.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/io/FileInputStream.java Thu Dec 14 12:28:32 2017 +0000 @@ -25,6 +25,7 @@ package java.io; +import java.lang.reflect.Method; import java.nio.channels.FileChannel; import sun.nio.ch.FileChannelImpl; @@ -38,6 +39,22 @@ * such as image data. For reading streams of characters, consider using * FileReader. * + * @apiNote + * To release resources used by this stream {@link #close} should be called + * directly or by try-with-resources. Subclasses are responsible for the cleanup + * of resources acquired by the subclass. + * Subclasses that override {@link #finalize} in order to perform cleanup + * should be modified to use alternative cleanup mechanisms such as + * {@link java.lang.ref.Cleaner} and remove the overriding {@code finalize} method. + * + * @implSpec + * If this FileInputStream has been subclassed and the {@link #close} + * method has been overridden, the {@link #close} method will be + * called when the FileInputStream is unreachable. + * Otherwise, it is implementation specific how the resource cleanup described in + * {@link #close} is performed. + + * * @author Arthur van Hoff * @see java.io.File * @see java.io.FileDescriptor @@ -63,6 +80,8 @@ private volatile boolean closed; + private final AltFinalizer altFinalizer; + /** * Creates a FileInputStream by * opening a connection to an actual file, @@ -137,6 +156,10 @@ fd.attach(this); path = name; open(name); + altFinalizer = AltFinalizer.get(this); + if (altFinalizer == null) { + fd.registerCleanup(); // open set the fd, register the cleanup + } } /** @@ -173,6 +196,7 @@ } fd = fdObj; path = null; + altFinalizer = null; /* * FileDescriptor is being shared by streams. @@ -316,6 +340,14 @@ *

If this stream has an associated channel then the channel is closed * as well. * + * @apiNote + * Overriding {@link #close} to perform cleanup actions is reliable + * only when called directly or when called by try-with-resources. + * Do not depend on finalization to invoke {@code close}; + * finalization is not reliable and is deprecated. + * If cleanup of native resources is needed, other mechanisms such as + * {@linkplain java.lang.ref.Cleaner} should be used. + * * @exception IOException if an I/O error occurs. * * @revised 1.4 @@ -404,16 +436,27 @@ private static native void initIDs(); - static { initIDs(); } /** - * Ensures that the close method of this file input stream is + * Ensures that the {@link #close} method of this file input stream is * called when there are no more references to it. + * The {@link #finalize} method does not call {@link #close} directly. * - * @deprecated The {@code finalize} method has been deprecated. + * @apiNote + * To release resources used by this stream {@link #close} should be called + * directly or by try-with-resources. + * + * @implSpec + * If this FileInputStream has been subclassed and the {@link #close} + * method has been overridden, the {@link #close} method will be + * called when the FileInputStream is unreachable. + * Otherwise, it is implementation specific how the resource cleanup described in + * {@link #close} is performed. + * + * @deprecated The {@code finalize} method has been deprecated and will be removed. * Subclasses that override {@code finalize} in order to perform cleanup * should be modified to use alternative cleanup mechanisms and * to remove the overriding {@code finalize} method. @@ -425,15 +468,57 @@ * @exception IOException if an I/O error occurs. * @see java.io.FileInputStream#close() */ - @Deprecated(since="9") + @Deprecated(since="9", forRemoval = true) protected void finalize() throws IOException { - if ((fd != null) && (fd != FileDescriptor.in)) { - /* if fd is shared, the references in FileDescriptor - * will ensure that finalizer is only called when - * safe to do so. All references using the fd have - * become unreachable. We can call close() - */ - close(); + } + + /** + * Class to call {@code FileInputStream.close} when finalized. + * If finalization of the stream is needed, an instance is created + * in its constructor(s). When the set of instances + * related to the stream is unreachable, the AltFinalizer performs + * the needed call to the stream's {@code close} method. + */ + static class AltFinalizer { + private final FileInputStream fis; + + /* + * Returns a finalizer object if the FIS needs a finalizer; otherwise null. + * If the FIS has a close method; it needs an AltFinalizer. + */ + static AltFinalizer get(FileInputStream fis) { + Class clazz = fis.getClass(); + while (clazz != FileInputStream.class) { + try { + clazz.getDeclaredMethod("close"); + return new AltFinalizer(fis); + } catch (NoSuchMethodException nsme) { + // ignore + } + clazz = clazz.getSuperclass(); + } + return null; + } + + private AltFinalizer(FileInputStream fis) { + this.fis = fis; + } + + @Override + @SuppressWarnings("deprecation") + protected final void finalize() { + try { + if ((fis.fd != null) && (fis.fd != FileDescriptor.in)) { + /* if fd is shared, the references in FileDescriptor + * will ensure that finalizer is only called when + * safe to do so. All references using the fd have + * become unreachable. We can call close() + */ + fis.close(); + } + } catch (IOException ioe) { + // ignore + } } } } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/io/FileOutputStream.java --- a/src/java.base/share/classes/java/io/FileOutputStream.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/io/FileOutputStream.java Thu Dec 14 12:28:32 2017 +0000 @@ -25,6 +25,7 @@ package java.io; +import java.lang.reflect.Method; import java.nio.channels.FileChannel; import jdk.internal.misc.SharedSecrets; import jdk.internal.misc.JavaIOFileDescriptorAccess; @@ -44,6 +45,21 @@ * such as image data. For writing streams of characters, consider using * FileWriter. * + * @apiNote + * To release resources used by this stream {@link #close} should be called + * directly or by try-with-resources. Subclasses are responsible for the cleanup + * of resources acquired by the subclass. + * Subclasses that override {@link #finalize} in order to perform cleanup + * should be modified to use alternative cleanup mechanisms such as + * {@link java.lang.ref.Cleaner} and remove the overriding {@code finalize} method. + * + * @implSpec + * If this FileOutputStream has been subclassed and the {@link #close} + * method has been overridden, the {@link #close} method will be + * called when the FileInputStream is unreachable. + * Otherwise, it is implementation specific how the resource cleanup described in + * {@link #close} is performed. + * * @author Arthur van Hoff * @see java.io.File * @see java.io.FileDescriptor @@ -80,6 +96,8 @@ private volatile boolean closed; + private final AltFinalizer altFinalizer; + /** * Creates a file output stream to write to the file with the * specified name. A new FileDescriptor object is @@ -218,6 +236,10 @@ this.path = name; open(name, append); + altFinalizer = AltFinalizer.get(this); + if (altFinalizer == null) { + fd.registerCleanup(); // open set the fd, register the cleanup + } } /** @@ -253,6 +275,7 @@ } this.fd = fdObj; this.path = null; + this.altFinalizer = null; fd.attach(this); } @@ -340,6 +363,14 @@ *

If this stream has an associated channel then the channel is closed * as well. * + * @apiNote + * Overriding {@link #close} to perform cleanup actions is reliable + * only when called directly or when called by try-with-resources. + * Do not depend on finalization to invoke {@code close}; + * finalization is not reliable and is deprecated. + * If cleanup of native resources is needed, other mechanisms such as + * {@linkplain java.lang.ref.Cleaner} should be used. + * * @exception IOException if an I/O error occurs. * * @revised 1.4 @@ -429,34 +460,35 @@ /** * Cleans up the connection to the file, and ensures that the - * close method of this file output stream is + * {@link #close} method of this file output stream is * called when there are no more references to this stream. + * The {@link #finalize} method does not call {@link #close} directly. + * + * @apiNote + * To release resources used by this stream {@link #close} should be called + * directly or by try-with-resources. * - * @deprecated The {@code finalize} method has been deprecated. - * Subclasses that override {@code finalize} in order to perform cleanup - * should be modified to use alternative cleanup mechanisms and - * to remove the overriding {@code finalize} method. - * When overriding the {@code finalize} method, its implementation must explicitly - * ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}. - * See the specification for {@link Object#finalize()} for further - * information about migration options. + * @implSpec + * If this FileOutputStream has been subclassed and the {@link #close} + * method has been overridden, the {@link #close} method will be + * called when the FileOutputStream is unreachable. + * Otherwise, it is implementation specific how the resource cleanup described in + * {@link #close} is performed. + * + * @deprecated The {@code finalize} method has been deprecated and will be removed. + * Subclasses that override {@code finalize} in order to perform cleanup + * should be modified to use alternative cleanup mechanisms and + * to remove the overriding {@code finalize} method. + * When overriding the {@code finalize} method, its implementation must explicitly + * ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}. + * See the specification for {@link Object#finalize()} for further + * information about migration options. + * * @exception IOException if an I/O error occurs. * @see java.io.FileInputStream#close() */ - @Deprecated(since="9") + @Deprecated(since="9", forRemoval = true) protected void finalize() throws IOException { - if (fd != null) { - if (fd == FileDescriptor.out || fd == FileDescriptor.err) { - flush(); - } else { - /* if fd is shared, the references in FileDescriptor - * will ensure that finalizer is only called when - * safe to do so. All references using the fd have - * become unreachable. We can call close() - */ - close(); - } - } } private static native void initIDs(); @@ -465,4 +497,59 @@ initIDs(); } + /** + * Class to call {@code FileOutputStream.close} when finalized. + * If finalization of the stream is needed, an instance is created + * in its constructor(s). When the set of instances + * related to the stream is unreachable, the AltFinalizer performs + * the needed call to the stream's {@code close} method. + */ + static class AltFinalizer { + private final FileOutputStream fos; + + /* + * Returns a finalizer object if the FOS needs a finalizer; otherwise null. + * If the FOS has a close method; it needs an AltFinalizer. + */ + static AltFinalizer get(FileOutputStream fos) { + Class clazz = fos.getClass(); + while (clazz != FileOutputStream.class) { + try { + clazz.getDeclaredMethod("close"); + return new AltFinalizer(fos); + } catch (NoSuchMethodException nsme) { + // ignore + } + clazz = clazz.getSuperclass(); + } + return null; + } + + private AltFinalizer(FileOutputStream fos) { + this.fos = fos; + } + + @Override + @SuppressWarnings("deprecation") + protected final void finalize() { + try { + if (fos.fd != null) { + if (fos.fd == FileDescriptor.out || fos.fd == FileDescriptor.err) { + // Subclass may override flush; otherwise it is no-op + fos.flush(); + } else { + /* if fd is shared, the references in FileDescriptor + * will ensure that finalizer is only called when + * safe to do so. All references using the fd have + * become unreachable. We can call close() + */ + fos.close(); + } + } + } catch (IOException ioe) { + // ignore + } + } + } + } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/io/PrintStream.java --- a/src/java.base/share/classes/java/io/PrintStream.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/io/PrintStream.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,10 +45,16 @@ * ({@code '\n'}) is written. * *

All characters printed by a {@code PrintStream} are converted into - * bytes using the platform's default character encoding. + * bytes using the given encoding or charset, or platform's default character + * encoding if not specified. * The {@link PrintWriter} class should be used in situations that require * writing characters rather than bytes. * + *

This class always replaces malformed and unmappable character sequences with + * the charset's default replacement string. + * The {@linkplain java.nio.charset.CharsetEncoder} class should be used when more + * control over the encoding process is required. + * * @author Frank Yellin * @author Mark Reinhold * @since 1.0 @@ -105,22 +111,13 @@ this.textOut = new BufferedWriter(charOut); } - private PrintStream(boolean autoFlush, OutputStream out, Charset charset) { - super(out); - this.autoFlush = autoFlush; - this.charOut = new OutputStreamWriter(this, charset); - this.textOut = new BufferedWriter(charOut); - } - /* Variant of the private constructor so that the given charset name * can be verified before evaluating the OutputStream argument. Used * by constructors creating a FileOutputStream that also take a * charset name. */ - private PrintStream(boolean autoFlush, Charset charset, OutputStream out) - throws UnsupportedEncodingException - { - this(autoFlush, out, charset); + private PrintStream(boolean autoFlush, Charset charset, OutputStream out) { + this(out, autoFlush, charset); } /** @@ -172,9 +169,30 @@ public PrintStream(OutputStream out, boolean autoFlush, String encoding) throws UnsupportedEncodingException { - this(autoFlush, - requireNonNull(out, "Null output stream"), - toCharset(encoding)); + this(requireNonNull(out, "Null output stream"), autoFlush, toCharset(encoding)); + } + + /** + * Creates a new print stream, with the specified OutputStream, automatic line + * flushing and charset. This convenience constructor creates the necessary + * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter}, + * which will encode characters using the provided charset. + * + * @param out The output stream to which values and objects will be + * printed + * @param autoFlush A boolean; if true, the output buffer will be flushed + * whenever a byte array is written, one of the + * {@code println} methods is invoked, or a newline + * character or byte ({@code '\n'}) is written + * @param charset A {@linkplain java.nio.charset.Charset charset} + * + * @since 10 + */ + public PrintStream(OutputStream out, boolean autoFlush, Charset charset) { + super(out); + this.autoFlush = autoFlush; + this.charOut = new OutputStreamWriter(this, charset); + this.textOut = new BufferedWriter(charOut); } /** @@ -250,6 +268,36 @@ /** * Creates a new print stream, without automatic line flushing, with the + * specified file name and charset. This convenience constructor creates + * the necessary intermediate {@link java.io.OutputStreamWriter + * OutputStreamWriter}, which will encode characters using the provided + * charset. + * + * @param fileName + * The name of the file to use as the destination of this print + * stream. If the file exists, then it will be truncated to + * zero size; otherwise, a new file will be created. The output + * will be written to the file and is buffered. + * + * @param charset + * A {@linkplain java.nio.charset.Charset charset} + * + * @throws IOException + * if an I/O error occurs while opening or creating the file + * + * @throws SecurityException + * If a security manager is present and {@link + * SecurityManager#checkWrite checkWrite(fileName)} denies write + * access to the file + * + * @since 10 + */ + public PrintStream(String fileName, Charset charset) throws IOException { + this(false, requireNonNull(charset, "charset"), new FileOutputStream(fileName)); + } + + /** + * Creates a new print stream, without automatic line flushing, with the * specified file. This convenience constructor creates the necessary * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter}, * which will encode characters using the {@linkplain @@ -319,6 +367,37 @@ this(false, toCharset(csn), new FileOutputStream(file)); } + + /** + * Creates a new print stream, without automatic line flushing, with the + * specified file and charset. This convenience constructor creates + * the necessary intermediate {@link java.io.OutputStreamWriter + * OutputStreamWriter}, which will encode characters using the provided + * charset. + * + * @param file + * The file to use as the destination of this print stream. If the + * file exists, then it will be truncated to zero size; otherwise, + * a new file will be created. The output will be written to the + * file and is buffered. + * + * @param charset + * A {@linkplain java.nio.charset.Charset charset} + * + * @throws IOException + * if an I/O error occurs while opening or creating the file + * + * @throws SecurityException + * If a security manager is present and {@link + * SecurityManager#checkWrite checkWrite(file.getPath())} + * denies write access to the file + * + * @since 10 + */ + public PrintStream(File file, Charset charset) throws IOException { + this(false, requireNonNull(charset, "charset"), new FileOutputStream(file)); + } + /** Check to make sure that the stream has not been closed */ private void ensureOpen() throws IOException { if (out == null) diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/io/PrintWriter.java --- a/src/java.base/share/classes/java/io/PrintWriter.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/io/PrintWriter.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,6 +48,11 @@ * constructors may. The client may inquire as to whether any errors have * occurred by invoking {@link #checkError checkError()}. * + *

This class always replaces malformed and unmappable character sequences with + * the charset's default replacement string. + * The {@linkplain java.nio.charset.CharsetEncoder} class should be used when more + * control over the encoding process is required. + * * @author Frank Yellin * @author Mark Reinhold * @since 1.1 @@ -137,7 +142,26 @@ * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream) */ public PrintWriter(OutputStream out, boolean autoFlush) { - this(new BufferedWriter(new OutputStreamWriter(out)), autoFlush); + this(out, autoFlush, Charset.defaultCharset()); + } + + /** + * Creates a new PrintWriter from an existing OutputStream. This + * convenience constructor creates the necessary intermediate + * OutputStreamWriter, which will convert characters into bytes using the + * specified charset. + * + * @param out An output stream + * @param autoFlush A boolean; if true, the {@code println}, + * {@code printf}, or {@code format} methods will + * flush the output buffer + * @param charset + * A {@linkplain java.nio.charset.Charset charset} + * + * @since 10 + */ + public PrintWriter(OutputStream out, boolean autoFlush, Charset charset) { + this(new BufferedWriter(new OutputStreamWriter(out, charset)), autoFlush); // save print stream for error propagation if (out instanceof java.io.PrintStream) { @@ -226,6 +250,36 @@ /** * Creates a new PrintWriter, without automatic line flushing, with the + * specified file name and charset. This convenience constructor creates + * the necessary intermediate {@link java.io.OutputStreamWriter + * OutputStreamWriter}, which will encode characters using the provided + * charset. + * + * @param fileName + * The name of the file to use as the destination of this writer. + * If the file exists then it will be truncated to zero size; + * otherwise, a new file will be created. The output will be + * written to the file and is buffered. + * + * @param charset + * A {@linkplain java.nio.charset.Charset charset} + * + * @throws IOException + * if an I/O error occurs while opening or creating the file + * + * @throws SecurityException + * If a security manager is present and {@link + * SecurityManager#checkWrite checkWrite(fileName)} denies write + * access to the file + * + * @since 10 + */ + public PrintWriter(String fileName, Charset charset) throws IOException { + this(Objects.requireNonNull(charset, "charset"), new File(fileName)); + } + + /** + * Creates a new PrintWriter, without automatic line flushing, with the * specified file. This convenience constructor creates the necessary * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter}, * which will encode characters using the {@linkplain @@ -295,6 +349,36 @@ this(toCharset(csn), file); } + /** + * Creates a new PrintWriter, without automatic line flushing, with the + * specified file and charset. This convenience constructor creates the + * necessary intermediate {@link java.io.OutputStreamWriter + * OutputStreamWriter}, which will encode characters using the provided + * charset. + * + * @param file + * The file to use as the destination of this writer. If the file + * exists then it will be truncated to zero size; otherwise, a new + * file will be created. The output will be written to the file + * and is buffered. + * + * @param charset + * A {@linkplain java.nio.charset.Charset charset} + * + * @throws IOException + * if an I/O error occurs while opening or creating the file + * + * @throws SecurityException + * If a security manager is present and {@link + * SecurityManager#checkWrite checkWrite(file.getPath())} + * denies write access to the file + * + * @since 10 + */ + public PrintWriter(File file, Charset charset) throws IOException { + this(Objects.requireNonNull(charset, "charset"), file); + } + /** Checks to make sure that the stream has not been closed */ private void ensureOpen() throws IOException { if (out == null) diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/io/RandomAccessFile.java --- a/src/java.base/share/classes/java/io/RandomAccessFile.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/io/RandomAccessFile.java Thu Dec 14 12:28:32 2017 +0000 @@ -257,6 +257,7 @@ fd.attach(this); path = name; open(name, imode); + fd.registerCleanup(); // open sets the fd, register the cleanup } /** diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/lang/ClassLoader.java --- a/src/java.base/share/classes/java/lang/ClassLoader.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/lang/ClassLoader.java Thu Dec 14 12:28:32 2017 +0000 @@ -38,6 +38,7 @@ import java.security.PrivilegedAction; import java.security.ProtectionDomain; import java.security.cert.Certificate; +import java.util.ArrayDeque; import java.util.Arrays; import java.util.Collections; import java.util.Deque; @@ -45,7 +46,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; -import java.util.LinkedList; import java.util.Map; import java.util.NoSuchElementException; import java.util.Objects; @@ -2496,7 +2496,7 @@ } // native libraries being loaded - static Deque nativeLibraryContext = new LinkedList<>(); + static Deque nativeLibraryContext = new ArrayDeque<>(8); /* * The run() method will be invoked when this class loader becomes diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/lang/ModuleLayer.java --- a/src/java.base/share/classes/java/lang/ModuleLayer.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/lang/ModuleLayer.java Thu Dec 14 12:28:32 2017 +0000 @@ -845,9 +845,8 @@ return layers() .skip(1) // skip this layer - .map(l -> l.nameToModule) - .filter(map -> map.containsKey(name)) - .map(map -> map.get(name)) + .map(l -> l.nameToModule.get(name)) + .filter(Objects::nonNull) .findAny(); } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/lang/Runtime.java --- a/src/java.base/share/classes/java/lang/Runtime.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/lang/Runtime.java Thu Dec 14 12:28:32 2017 +0000 @@ -877,62 +877,6 @@ } /** - * Creates a localized version of an input stream. This method takes - * an {@code InputStream} and returns an {@code InputStream} - * equivalent to the argument in all respects except that it is - * localized: as characters in the local character set are read from - * the stream, they are automatically converted from the local - * character set to Unicode. - *

- * If the argument is already a localized stream, it may be returned - * as the result. - * - * @param in InputStream to localize - * @return a localized input stream - * @see java.io.InputStream - * @see java.io.BufferedReader#BufferedReader(java.io.Reader) - * @see java.io.InputStreamReader#InputStreamReader(java.io.InputStream) - * @deprecated As of JDK 1.1, the preferred way to translate a byte - * stream in the local encoding into a character stream in Unicode is via - * the {@code InputStreamReader} and {@code BufferedReader} - * classes. - * This method is subject to removal in a future version of Java SE. - */ - @Deprecated(since="1.1", forRemoval=true) - public InputStream getLocalizedInputStream(InputStream in) { - return in; - } - - /** - * Creates a localized version of an output stream. This method - * takes an {@code OutputStream} and returns an - * {@code OutputStream} equivalent to the argument in all respects - * except that it is localized: as Unicode characters are written to - * the stream, they are automatically converted to the local - * character set. - *

- * If the argument is already a localized stream, it may be returned - * as the result. - * - * @deprecated As of JDK 1.1, the preferred way to translate a - * Unicode character stream into a byte stream in the local encoding is via - * the {@code OutputStreamWriter}, {@code BufferedWriter}, and - * {@code PrintWriter} classes. - * This method is subject to removal in a future version of Java SE. - * - * @param out OutputStream to localize - * @return a localized output stream - * @see java.io.OutputStream - * @see java.io.BufferedWriter#BufferedWriter(java.io.Writer) - * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream) - * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream) - */ - @Deprecated(since="1.1", forRemoval=true) - public OutputStream getLocalizedOutputStream(OutputStream out) { - return out; - } - - /** * Returns the version of the Java Runtime Environment as a {@link Version}. * * @return the {@link Version} of the Java Runtime Environment @@ -955,81 +899,68 @@ * *

Version numbers

* - *

A version number, {@code $VNUM}, is a non-empty sequence - * of elements separated by period characters (U+002E). An element is - * either zero, or an unsigned integer numeral without leading zeros. The - * final element in a version number must not be zero. The format is: - *

+ *

A version number, {@code $VNUM}, is a non-empty sequence of + * elements separated by period characters (U+002E). An element is either + * zero, or an unsigned integer numeral without leading zeros. The final + * element in a version number must not be zero. When an element is + * incremented, all subsequent elements are removed. The format is:

* *
-     *     [1-9][0-9]*((\.0)*\.[1-9][0-9]*)*
+     * [1-9][0-9]*((\.0)*\.[1-9][0-9]*)*
      * 
* - *

The sequence may be of arbitrary length but the first three - * elements are assigned specific meanings, as follows:

+ *

The sequence may be of arbitrary length but the first four elements + * are assigned specific meanings, as follows:

* *
-     *     $MAJOR.$MINOR.$SECURITY
+     * $FEATURE.$INTERIM.$UPDATE.$PATCH
      * 
* *
    * - *
  • {@code $MAJOR} --- The major version - * number, incremented for a major release that contains significant new - * features as specified in a new edition of the Java SE Platform - * Specification, e.g., JSR 337 for - * Java SE 8. Features may be removed in a major release, given - * advance notice at least one major release ahead of time, and - * incompatible changes may be made when justified. The {@code $MAJOR} - * version number of JDK 8 is {@code 8}; the {@code $MAJOR} version - * number of JDK 9 is {@code 9}. When {@code $MAJOR} is incremented, - * all subsequent elements are removed.

  • + *
  • {@code $FEATURE} — The + * feature-release counter, incremented for every feature release + * regardless of release content. Features may be added in a feature + * release; they may also be removed, if advance notice was given at least + * one feature release ahead of time. Incompatible changes may be made + * when justified.

  • * - *
  • {@code $MINOR} --- The minor version - * number, incremented for a minor update release that may contain - * compatible bug fixes, revisions to standard APIs mandated by a - * Maintenance Release - * of the relevant Platform Specification, and implementation features - * outside the scope of that Specification such as new JDK-specific APIs, - * additional service providers, new garbage collectors, and ports to new - * hardware architectures.

  • + *
  • {@code $INTERIM} — The + * interim-release counter, incremented for non-feature releases that + * contain compatible bug fixes and enhancements but no incompatible + * changes, no feature removals, and no changes to standard APIs. + *

  • * - *
  • {@code $SECURITY} --- The security - * level, incremented for a security update release that contains critical - * fixes including those necessary to improve security. {@code $SECURITY} - * is not reset when {@code $MINOR} is incremented. A - * higher value of {@code $SECURITY} for a given {@code $MAJOR} value, - * therefore, always indicates a more secure release, regardless of the - * value of {@code $MINOR}.

  • + *
  • {@code $UPDATE} — The update-release + * counter, incremented for compatible update releases that fix security + * issues, regressions, and bugs in newer features.

  • + * + *
  • {@code $PATCH} — The emergency + * patch-release counter, incremented only when it's necessary to produce + * an emergency release to fix a critical issue.

  • * *
* - *

The fourth and later elements of a version number are free for use - * by downstream consumers of this code base. Such a consumer may, - * e.g., use the fourth element to identify patch releases which - * contain a small number of critical non-security fixes in addition to - * the security fixes in the corresponding security release.

+ *

The fifth and later elements of a version number are free for use by + * platform implementors, to identify implementor-specific patch + * releases.

* - *

The version number does not include trailing zero elements; - * i.e., {@code $SECURITY} is omitted if it has the value zero, - * and {@code $MINOR} is omitted if both {@code $MINOR} and {@code - * $SECURITY} have the value zero.

+ *

A version number never has trailing zero elements. If an element + * and all those that follow it logically have the value zero then all of + * them are omitted.

* *

The sequence of numerals in a version number is compared to another * such sequence in numerical, pointwise fashion; e.g., {@code - * 9.9.1} is less than {@code 9.10.3}. If one sequence is shorter than - * another then the missing elements of the shorter sequence are - * considered to be less than the corresponding elements of the longer - * sequence; e.g., {@code 9.1.2} is less than {@code 9.1.2.1}. - *

+ * 10.0.4} is less than {@code 10.1.2}. If one sequence is shorter than + * another then the missing elements of the shorter sequence are considered + * to be less than the corresponding elements of the longer sequence; + * e.g., {@code 10.0.2} is less than {@code 10.0.2.1}.

* *

Version strings

* - *

A version string, {@code $VSTR}, consists of a version - * number {@code $VNUM}, as described above, optionally followed by - * pre-release and build information, in one of the following formats: - *

+ *

A version string, {@code $VSTR}, is a version number {@code + * $VNUM}, as described above, optionally followed by pre-release and build + * information, in one of the following formats:

* *
      *     $VNUM(-$PRE)?\+$BUILD(-$OPT)?
@@ -1042,19 +973,19 @@
      * 
    * *
  • {@code $PRE}, matching {@code ([a-zA-Z0-9]+)} - * --- A pre-release identifier. Typically {@code ea}, for a - * potentially unstable early-access release under active development, - * or {@code internal}, for an internal developer build.

  • + * — A pre-release identifier. Typically {@code ea}, for a + * potentially unstable early-access release under active development, or + * {@code internal}, for an internal developer build.

    * *
  • {@code $BUILD}, matching {@code - * (0|[1-9][0-9]*)} --- The build number, incremented for each promoted + * (0|[1-9][0-9]*)} — The build number, incremented for each promoted * build. {@code $BUILD} is reset to {@code 1} when any portion of {@code * $VNUM} is incremented.

  • * - *
  • {@code $OPT}, matching {@code - * ([-a-zA-Z0-9.]+)} --- Additional build information, if desired. In - * the case of an {@code internal} build this will often contain the date - * and time of the build.

  • + *
  • {@code $OPT}, matching {@code ([-a-zA-Z0-9.]+)} + * — Additional build information, if desired. In the case of an + * {@code internal} build this will often contain the date and time of the + * build.

  • * *
* @@ -1138,7 +1069,7 @@ throw new NullPointerException(); // Shortcut to avoid initializing VersionPattern when creating - // major version constants during startup + // feature-version constants during startup if (isSimpleNumber(s)) { return new Version(List.of(Integer.parseInt(s)), Optional.empty(), Optional.empty(), Optional.empty()); @@ -1195,43 +1126,114 @@ } /** - * Returns the major version number. + * Returns the value of the feature element of + * the version number. * - * @return The major version number + * @return The value of the feature element + * + * @since 10 */ - public int major() { + public int feature() { return version.get(0); } /** - * Returns the minor version number or zero if it - * was not set. + * Returns the value of the interim element of + * the version number, or zero if it is absent. * - * @return The minor version number or zero if it was not set + * @return The value of the interim element, or zero + * + * @since 10 */ - public int minor() { + public int interim() { return (version.size() > 1 ? version.get(1) : 0); } /** - * Returns the security version number or zero - * if it was not set. + * Returns the value of the update element of the + * version number, or zero if it is absent. * - * @return The security version number or zero if it was not set + * @return The value of the update element, or zero + * + * @since 10 */ - public int security() { + public int update() { return (version.size() > 2 ? version.get(2) : 0); } /** - * Returns an unmodifiable {@link java.util.List List} of the - * integer numerals contained in the version - * number. The {@code List} always contains at least one - * element corresponding to the major version - * number. + * Returns the value of the patch element of the + * version number, or zero if it is absent. + * + * @return The value of the patch element, or zero + * + * @since 10 + */ + public int patch() { + return (version.size() > 3 ? version.get(3) : 0); + } + + /** + * Returns the value of the major element of the version number. + * + * @deprecated As of Java SE 10, the first element of a version + * number is not the major-release number but the feature-release + * counter, incremented for every time-based release. Use the {@link + * #feature()} method in preference to this method. For compatibility, + * this method returns the value of the feature + * element. + * + * @return The value of the feature element + */ + @Deprecated(since = "10") + public int major() { + return feature(); + } + + /** + * Returns the value of the minor element of the version number, or + * zero if it is absent. * - * @return An unmodifiable list of the integer numerals - * contained in the version number + * @deprecated As of Java SE 10, the second element of a version + * number is not the minor-release number but the interim-release + * counter, incremented for every interim release. Use the {@link + * #interim()} method in preference to this method. For compatibility, + * this method returns the value of the interim + * element, or zero if it is absent. + * + * @return The value of the interim element, or zero + */ + @Deprecated(since = "10") + public int minor() { + return interim(); + } + + /** + * Returns the value of the security element of the version number, or + * zero if it is absent. + * + * @deprecated As of Java SE 10, the third element of a version + * number is not the security level but the update-release counter, + * incremented for every update release. Use the {@link #update()} + * method in preference to this method. For compatibility, this method + * returns the value of the update element, or + * zero if it is absent. + * + * @return The value of the update element, or zero + */ + @Deprecated(since = "10") + public int security() { + return update(); + } + + /** + * Returns an unmodifiable {@link java.util.List List} of the integers + * represented in the version number. The {@code + * List} always contains at least one element corresponding to the feature version number. + * + * @return An unmodifiable list of the integers + * represented in the version number */ public List version() { return version; diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/lang/String.java --- a/src/java.base/share/classes/java/lang/String.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/lang/String.java Thu Dec 14 12:28:32 2017 +0000 @@ -3046,6 +3046,10 @@ return COMPACT_STRINGS ? coder : UTF16; } + byte[] value() { + return value; + } + private boolean isLatin1() { return COMPACT_STRINGS && coder == LATIN1; } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/lang/StringCoding.java --- a/src/java.base/share/classes/java/lang/StringCoding.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/lang/StringCoding.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,6 +47,11 @@ import static java.lang.String.LATIN1; import static java.lang.String.UTF16; import static java.lang.String.COMPACT_STRINGS; +import static java.lang.Character.isSurrogate; +import static java.lang.Character.highSurrogate; +import static java.lang.Character.lowSurrogate; +import static java.lang.Character.isSupplementaryCodePoint; +import static java.lang.StringUTF16.putChar; /** * Utility class for string encoding and decoding. @@ -66,8 +71,6 @@ private static final Charset US_ASCII = sun.nio.cs.US_ASCII.INSTANCE; private static final Charset UTF_8 = sun.nio.cs.UTF_8.INSTANCE; - private static boolean warnUnsupportedCharset = true; - private static T deref(ThreadLocal> tl) { SoftReference sr = tl.get(); if (sr == null) @@ -80,7 +83,6 @@ } // Trim the given byte array to the given length - // private static byte[] safeTrim(byte[] ba, int len, boolean isTrusted) { if (len == ba.length && (isTrusted || System.getSecurityManager() == null)) return ba; @@ -105,17 +107,6 @@ return null; } - private static void warnUnsupportedCharset(String csn) { - if (warnUnsupportedCharset) { - // Use err(String) rather than the Logging API or System.err - // since this method may be called during VM initialization - // before either is available. - err("WARNING: Default charset " + csn + - " not supported, using ISO-8859-1 instead\n"); - warnUnsupportedCharset = false; - } - } - static class Result { byte[] value; byte coder; @@ -224,19 +215,6 @@ } } - private static class StringDecoder8859_1 extends StringDecoder { - StringDecoder8859_1(Charset cs, String rcn) { - super(cs, rcn); - } - Result decode(byte[] ba, int off, int len) { - if (COMPACT_STRINGS) { - return result.with(Arrays.copyOfRange(ba, off, off + len), LATIN1); - } else { - return result.with(StringLatin1.inflate(ba, off, len), UTF16); - } - } - } - static Result decode(String charsetName, byte[] ba, int off, int len) throws UnsupportedEncodingException { @@ -249,12 +227,15 @@ Charset cs = lookupCharset(csn); if (cs != null) { if (cs == UTF_8) { - sd = new StringDecoderUTF8(cs, csn); - } else if (cs == ISO_8859_1) { - sd = new StringDecoder8859_1(cs, csn); - } else { - sd = new StringDecoder(cs, csn); + return decodeUTF8(ba, off, len, true); + } + if (cs == ISO_8859_1) { + return decodeLatin1(ba, off, len); } + if (cs == US_ASCII) { + return decodeASCII(ba, off, len); + } + sd = new StringDecoder(cs, csn); } } catch (IllegalCharsetNameException x) {} if (sd == null) @@ -265,6 +246,16 @@ } static Result decode(Charset cs, byte[] ba, int off, int len) { + if (cs == UTF_8) { + return decodeUTF8(ba, off, len, true); + } + if (cs == ISO_8859_1) { + return decodeLatin1(ba, off, len); + } + if (cs == US_ASCII) { + return decodeASCII(ba, off, len); + } + // (1)We never cache the "external" cs, the only benefit of creating // an additional StringDe/Encoder object to wrap it is to share the // de/encode() method. These SD/E objects are short-lived, the young-gen @@ -280,39 +271,29 @@ // check (... && (isTrusted || SM == null || getClassLoader0())) in trim // but it then can be argued that the SM is null when the operation // is started... - if (cs == UTF_8) { - return StringDecoderUTF8.decode(ba, off, len, new Result()); - } CharsetDecoder cd = cs.newDecoder(); // ascii fastpath - if (cs == ISO_8859_1 || ((cd instanceof ArrayDecoder) && - ((ArrayDecoder)cd).isASCIICompatible() && - !hasNegatives(ba, off, len))) { - if (COMPACT_STRINGS) { - return new Result().with(Arrays.copyOfRange(ba, off, off + len), - LATIN1); - } else { - return new Result().with(StringLatin1.inflate(ba, off, len), UTF16); - } + if ((cd instanceof ArrayDecoder) && + ((ArrayDecoder)cd).isASCIICompatible() && !hasNegatives(ba, off, len)) { + return decodeLatin1(ba, off, len); } int en = scale(len, cd.maxCharsPerByte()); if (len == 0) { return new Result().with(); } - if (cs.getClass().getClassLoader0() != null && - System.getSecurityManager() != null) { - ba = Arrays.copyOfRange(ba, off, off + len); - off = 0; - } cd.onMalformedInput(CodingErrorAction.REPLACE) .onUnmappableCharacter(CodingErrorAction.REPLACE) .reset(); - char[] ca = new char[en]; if (cd instanceof ArrayDecoder) { int clen = ((ArrayDecoder)cd).decode(ba, off, len, ca); return new Result().with(ca, 0, clen); } + if (cs.getClass().getClassLoader0() != null && + System.getSecurityManager() != null) { + ba = Arrays.copyOfRange(ba, off, off + len); + off = 0; + } ByteBuffer bb = ByteBuffer.wrap(ba, off, len); CharBuffer cb = CharBuffer.wrap(ca); try { @@ -331,24 +312,22 @@ } static Result decode(byte[] ba, int off, int len) { - String csn = Charset.defaultCharset().name(); - try { - // use charset name decode() variant which provides caching. - return decode(csn, ba, off, len); - } catch (UnsupportedEncodingException x) { - warnUnsupportedCharset(csn); + Charset cs = Charset.defaultCharset(); + if (cs == UTF_8) { + return decodeUTF8(ba, off, len, true); + } + if (cs == ISO_8859_1) { + return decodeLatin1(ba, off, len); } - try { - return decode("ISO-8859-1", ba, off, len); - } catch (UnsupportedEncodingException x) { - // If this code is hit during VM initialization, err(String) is - // the only way we will be able to get any kind of error message. - err("ISO-8859-1 charset not available: " + x.toString() + "\n"); - // If we can not find ISO-8859-1 (a required encoding) then things - // are seriously wrong with the installation. - System.exit(1); - return null; + if (cs == US_ASCII) { + return decodeASCII(ba, off, len); } + StringDecoder sd = deref(decoder); + if (sd == null || !cs.name().equals(sd.cs.name())) { + sd = new StringDecoder(cs, cs.name()); + set(decoder, sd); + } + return sd.decode(ba, off, len); } // -- Encoding -- @@ -393,9 +372,6 @@ return ba; } if (ce instanceof ArrayEncoder) { - if (!isTrusted) { - val = Arrays.copyOf(val, val.length); - } int blen = (coder == LATIN1 ) ? ((ArrayEncoder)ce).encodeFromLatin1(val, 0, len, ba) : ((ArrayEncoder)ce).encodeFromUTF16(val, 0, len, ba); if (blen != -1) { @@ -423,49 +399,140 @@ } } - @HotSpotIntrinsicCandidate - private static int implEncodeISOArray(byte[] sa, int sp, - byte[] da, int dp, int len) { - int i = 0; - for (; i < len; i++) { - char c = StringUTF16.getChar(sa, sp++); - if (c > '\u00FF') - break; - da[dp++] = (byte)c; + static byte[] encode(String charsetName, byte coder, byte[] val) + throws UnsupportedEncodingException + { + StringEncoder se = deref(encoder); + String csn = (charsetName == null) ? "ISO-8859-1" : charsetName; + if ((se == null) || !(csn.equals(se.requestedCharsetName()) + || csn.equals(se.charsetName()))) { + se = null; + try { + Charset cs = lookupCharset(csn); + if (cs != null) { + if (cs == UTF_8) { + return encodeUTF8(coder, val, true); + } + if (cs == ISO_8859_1) { + return encode8859_1(coder, val); + } + if (cs == US_ASCII) { + return encodeASCII(coder, val); + } + se = new StringEncoder(cs, csn); + } + } catch (IllegalCharsetNameException x) {} + if (se == null) { + throw new UnsupportedEncodingException (csn); + } + set(encoder, se); } - return i; + return se.encode(coder, val); } - static byte[] encode8859_1(byte coder, byte[] val) { - if (coder == LATIN1) { + static byte[] encode(Charset cs, byte coder, byte[] val) { + if (cs == UTF_8) { + return encodeUTF8(coder, val, true); + } + if (cs == ISO_8859_1) { + return encode8859_1(coder, val); + } + if (cs == US_ASCII) { + return encodeASCII(coder, val); + } + CharsetEncoder ce = cs.newEncoder(); + // fastpath for ascii compatible + if (coder == LATIN1 && (((ce instanceof ArrayEncoder) && + ((ArrayEncoder)ce).isASCIICompatible() && + !hasNegatives(val, 0, val.length)))) { return Arrays.copyOf(val, val.length); } - int len = val.length >> 1; - byte[] dst = new byte[len]; - int dp = 0; - int sp = 0; - int sl = len; - while (sp < sl) { - int ret = implEncodeISOArray(val, sp, dst, dp, len); - sp = sp + ret; - dp = dp + ret; - if (ret != len) { - char c = StringUTF16.getChar(val, sp++); - if (Character.isHighSurrogate(c) && sp < sl && - Character.isLowSurrogate(StringUTF16.getChar(val, sp))) { - sp++; - } - dst[dp++] = '?'; - len = sl - sp; + int len = val.length >> coder; // assume LATIN1=0/UTF16=1; + int en = scale(len, ce.maxBytesPerChar()); + byte[] ba = new byte[en]; + if (len == 0) { + return ba; + } + ce.onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE) + .reset(); + if (ce instanceof ArrayEncoder) { + int blen = (coder == LATIN1 ) ? ((ArrayEncoder)ce).encodeFromLatin1(val, 0, len, ba) + : ((ArrayEncoder)ce).encodeFromUTF16(val, 0, len, ba); + if (blen != -1) { + return safeTrim(ba, blen, true); } } - if (dp == dst.length) { - return dst; + boolean isTrusted = cs.getClass().getClassLoader0() == null || + System.getSecurityManager() == null; + char[] ca = (coder == LATIN1 ) ? StringLatin1.toChars(val) + : StringUTF16.toChars(val); + ByteBuffer bb = ByteBuffer.wrap(ba); + CharBuffer cb = CharBuffer.wrap(ca, 0, len); + try { + CoderResult cr = ce.encode(cb, bb, true); + if (!cr.isUnderflow()) + cr.throwException(); + cr = ce.flush(bb); + if (!cr.isUnderflow()) + cr.throwException(); + } catch (CharacterCodingException x) { + throw new Error(x); } - return Arrays.copyOf(dst, dp); + return safeTrim(ba, bb.position(), isTrusted); } - static byte[] encodeASCII(byte coder, byte[] val) { + static byte[] encode(byte coder, byte[] val) { + Charset cs = Charset.defaultCharset(); + if (cs == UTF_8) { + return encodeUTF8(coder, val, true); + } + if (cs == ISO_8859_1) { + return encode8859_1(coder, val); + } + if (cs == US_ASCII) { + return encodeASCII(coder, val); + } + StringEncoder se = deref(encoder); + if (se == null || !cs.name().equals(se.cs.name())) { + se = new StringEncoder(cs, cs.name()); + set(encoder, se); + } + return se.encode(coder, val); + } + + /** + * Print a message directly to stderr, bypassing all character conversion + * methods. + * @param msg message to print + */ + private static native void err(String msg); + + /* The cached Result for each thread */ + private static final ThreadLocal + resultCached = new ThreadLocal<>() { + protected StringCoding.Result initialValue() { + return new StringCoding.Result(); + }}; + + ////////////////////////// ascii ////////////////////////////// + + private static Result decodeASCII(byte[] ba, int off, int len) { + Result result = resultCached.get(); + if (COMPACT_STRINGS && !hasNegatives(ba, off, len)) { + return result.with(Arrays.copyOfRange(ba, off, off + len), + LATIN1); + } + byte[] dst = new byte[len<<1]; + int dp = 0; + while (dp < len) { + int b = ba[off++]; + putChar(dst, dp++, (b >= 0) ? (char)b : repl); + } + return result.with(dst, UTF16); + } + + private static byte[] encodeASCII(byte coder, byte[] val) { if (coder == LATIN1) { byte[] dst = new byte[val.length]; for (int i = 0; i < val.length; i++) { @@ -498,59 +565,51 @@ return Arrays.copyOf(dst, dp); } - static byte[] encodeUTF8(byte coder, byte[] val) { - int dp = 0; - byte[] dst; + ////////////////////////// latin1/8859_1 /////////////////////////// + + private static Result decodeLatin1(byte[] ba, int off, int len) { + Result result = resultCached.get(); + if (COMPACT_STRINGS) { + return result.with(Arrays.copyOfRange(ba, off, off + len), LATIN1); + } else { + return result.with(StringLatin1.inflate(ba, off, len), UTF16); + } + } + + @HotSpotIntrinsicCandidate + private static int implEncodeISOArray(byte[] sa, int sp, + byte[] da, int dp, int len) { + int i = 0; + for (; i < len; i++) { + char c = StringUTF16.getChar(sa, sp++); + if (c > '\u00FF') + break; + da[dp++] = (byte)c; + } + return i; + } + + private static byte[] encode8859_1(byte coder, byte[] val) { if (coder == LATIN1) { - dst = new byte[val.length << 1]; - for (int sp = 0; sp < val.length; sp++) { - byte c = val[sp]; - if (c < 0) { - dst[dp++] = (byte)(0xc0 | ((c & 0xff) >> 6)); - dst[dp++] = (byte)(0x80 | (c & 0x3f)); - } else { - dst[dp++] = c; + return Arrays.copyOf(val, val.length); + } + int len = val.length >> 1; + byte[] dst = new byte[len]; + int dp = 0; + int sp = 0; + int sl = len; + while (sp < sl) { + int ret = implEncodeISOArray(val, sp, dst, dp, len); + sp = sp + ret; + dp = dp + ret; + if (ret != len) { + char c = StringUTF16.getChar(val, sp++); + if (Character.isHighSurrogate(c) && sp < sl && + Character.isLowSurrogate(StringUTF16.getChar(val, sp))) { + sp++; } - } - } else { - int sp = 0; - int sl = val.length >> 1; - dst = new byte[sl * 3]; - char c; - while (sp < sl && (c = StringUTF16.getChar(val, sp)) < '\u0080') { - // ascii fast loop; - dst[dp++] = (byte)c; - sp++; - } - while (sp < sl) { - c = StringUTF16.getChar(val, sp++); - if (c < 0x80) { - dst[dp++] = (byte)c; - } else if (c < 0x800) { - dst[dp++] = (byte)(0xc0 | (c >> 6)); - dst[dp++] = (byte)(0x80 | (c & 0x3f)); - } else if (Character.isSurrogate(c)) { - int uc = -1; - char c2; - if (Character.isHighSurrogate(c) && sp < sl && - Character.isLowSurrogate(c2 = StringUTF16.getChar(val, sp))) { - uc = Character.toCodePoint(c, c2); - } - if (uc < 0) { - dst[dp++] = '?'; - } else { - dst[dp++] = (byte)(0xf0 | ((uc >> 18))); - dst[dp++] = (byte)(0x80 | ((uc >> 12) & 0x3f)); - dst[dp++] = (byte)(0x80 | ((uc >> 6) & 0x3f)); - dst[dp++] = (byte)(0x80 | (uc & 0x3f)); - sp++; // 2 chars - } - } else { - // 3 bytes, 16 bits - dst[dp++] = (byte)(0xe0 | ((c >> 12))); - dst[dp++] = (byte)(0x80 | ((c >> 6) & 0x3f)); - dst[dp++] = (byte)(0x80 | (c & 0x3f)); - } + dst[dp++] = '?'; + len = sl - sp; } } if (dp == dst.length) { @@ -559,113 +618,333 @@ return Arrays.copyOf(dst, dp); } - static byte[] encode(String charsetName, byte coder, byte[] val) - throws UnsupportedEncodingException - { - StringEncoder se = deref(encoder); - String csn = (charsetName == null) ? "ISO-8859-1" : charsetName; - if ((se == null) || !(csn.equals(se.requestedCharsetName()) - || csn.equals(se.charsetName()))) { - se = null; - try { - Charset cs = lookupCharset(csn); - if (cs != null) { - if (cs == UTF_8) { - return encodeUTF8(coder, val); - } else if (cs == ISO_8859_1) { - return encode8859_1(coder, val); - } else if (cs == US_ASCII) { - return encodeASCII(coder, val); - } - se = new StringEncoder(cs, csn); - } - } catch (IllegalCharsetNameException x) {} - if (se == null) { - throw new UnsupportedEncodingException (csn); - } - set(encoder, se); + //////////////////////////////// utf8 //////////////////////////////////// + + private static boolean isNotContinuation(int b) { + return (b & 0xc0) != 0x80; + } + + private static boolean isMalformed3(int b1, int b2, int b3) { + return (b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) || + (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80; + } + + private static boolean isMalformed3_2(int b1, int b2) { + return (b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) || + (b2 & 0xc0) != 0x80; + } + + private static boolean isMalformed4(int b2, int b3, int b4) { + return (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80 || + (b4 & 0xc0) != 0x80; + } + + private static boolean isMalformed4_2(int b1, int b2) { + return (b1 == 0xf0 && (b2 < 0x90 || b2 > 0xbf)) || + (b1 == 0xf4 && (b2 & 0xf0) != 0x80) || + (b2 & 0xc0) != 0x80; + } + + private static boolean isMalformed4_3(int b3) { + return (b3 & 0xc0) != 0x80; + } + + // for nb == 3/4 + private static int malformedN(byte[] src, int sp, int nb) { + if (nb == 3) { + int b1 = src[sp++]; + int b2 = src[sp++]; // no need to lookup b3 + return ((b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) || + isNotContinuation(b2)) ? 1 : 2; + } else if (nb == 4) { // we don't care the speed here + int b1 = src[sp++] & 0xff; + int b2 = src[sp++] & 0xff; + if (b1 > 0xf4 || + (b1 == 0xf0 && (b2 < 0x90 || b2 > 0xbf)) || + (b1 == 0xf4 && (b2 & 0xf0) != 0x80) || + isNotContinuation(b2)) + return 1; + if (isNotContinuation(src[sp++])) + return 2; + return 3; } - return se.encode(coder, val); + assert false; + return -1; + } + + private static void throwMalformed(int off, int nb) { + throw new IllegalArgumentException("malformed input off : " + off + + ", length : " + nb); + } + + private static char repl = '\ufffd'; + + private static Result decodeUTF8(byte[] src, int sp, int len, boolean doReplace) { + // ascii-bais, which has a relative impact to the non-ascii-only bytes + if (COMPACT_STRINGS && !hasNegatives(src, sp, len)) + return resultCached.get().with(Arrays.copyOfRange(src, sp, sp + len), + LATIN1); + return decodeUTF8_0(src, sp, len, doReplace); } - static byte[] encode(Charset cs, byte coder, byte[] val) { - if (cs == UTF_8) { - return encodeUTF8(coder, val); - } else if (cs == ISO_8859_1) { - return encode8859_1(coder, val); - } else if (cs == US_ASCII) { - return encodeASCII(coder, val); - } - CharsetEncoder ce = cs.newEncoder(); - // fastpath for ascii compatible - if (coder == LATIN1 && (((ce instanceof ArrayEncoder) && - ((ArrayEncoder)ce).isASCIICompatible() && - !hasNegatives(val, 0, val.length)))) { - return Arrays.copyOf(val, val.length); - } - int len = val.length >> coder; // assume LATIN1=0/UTF16=1; - int en = scale(len, ce.maxBytesPerChar()); - byte[] ba = new byte[en]; - if (len == 0) { - return ba; - } - boolean isTrusted = cs.getClass().getClassLoader0() == null || - System.getSecurityManager() == null; - ce.onMalformedInput(CodingErrorAction.REPLACE) - .onUnmappableCharacter(CodingErrorAction.REPLACE) - .reset(); - if (ce instanceof ArrayEncoder) { - if (!isTrusted) { - val = Arrays.copyOf(val, val.length); + private static Result decodeUTF8_0(byte[] src, int sp, int len, boolean doReplace) { + Result ret = resultCached.get(); + + int sl = sp + len; + int dp = 0; + byte[] dst = new byte[len]; + + if (COMPACT_STRINGS) { + while (sp < sl) { + int b1 = src[sp]; + if (b1 >= 0) { + dst[dp++] = (byte)b1; + sp++; + continue; + } + if ((b1 == (byte)0xc2 || b1 == (byte)0xc3) && + sp + 1 < sl) { + int b2 = src[sp + 1]; + if (!isNotContinuation(b2)) { + dst[dp++] = (byte)(((b1 << 6) ^ b2)^ + (((byte) 0xC0 << 6) ^ + ((byte) 0x80 << 0))); + sp += 2; + continue; + } + } + // anything not a latin1, including the repl + // we have to go with the utf16 + break; } - int blen = (coder == LATIN1 ) ? ((ArrayEncoder)ce).encodeFromLatin1(val, 0, len, ba) - : ((ArrayEncoder)ce).encodeFromUTF16(val, 0, len, ba); - if (blen != -1) { - return safeTrim(ba, blen, isTrusted); + if (sp == sl) { + if (dp != dst.length) { + dst = Arrays.copyOf(dst, dp); + } + return ret.with(dst, LATIN1); } } - char[] ca = (coder == LATIN1 ) ? StringLatin1.toChars(val) - : StringUTF16.toChars(val); - ByteBuffer bb = ByteBuffer.wrap(ba); - CharBuffer cb = CharBuffer.wrap(ca, 0, len); - try { - CoderResult cr = ce.encode(cb, bb, true); - if (!cr.isUnderflow()) - cr.throwException(); - cr = ce.flush(bb); - if (!cr.isUnderflow()) - cr.throwException(); - } catch (CharacterCodingException x) { - throw new Error(x); + if (dp == 0) { + dst = new byte[len << 1]; + } else { + byte[] buf = new byte[len << 1]; + StringLatin1.inflate(dst, 0, buf, 0, dp); + dst = buf; } - return safeTrim(ba, bb.position(), isTrusted); + while (sp < sl) { + int b1 = src[sp++]; + if (b1 >= 0) { + putChar(dst, dp++, (char) b1); + } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) { + if (sp < sl) { + int b2 = src[sp++]; + if (isNotContinuation(b2)) { + if (!doReplace) { + throwMalformed(sp - 1, 1); + } + putChar(dst, dp++, repl); + sp--; + } else { + putChar(dst, dp++, (char)(((b1 << 6) ^ b2)^ + (((byte) 0xC0 << 6) ^ + ((byte) 0x80 << 0)))); + } + continue; + } + if (!doReplace) { + throwMalformed(sp, 1); // underflow() + } + putChar(dst, dp++, repl); + break; + } else if ((b1 >> 4) == -2) { + if (sp + 1 < sl) { + int b2 = src[sp++]; + int b3 = src[sp++]; + if (isMalformed3(b1, b2, b3)) { + if (!doReplace) { + throwMalformed(sp - 3, 3); + } + putChar(dst, dp++, repl); + sp -= 3; + sp += malformedN(src, sp, 3); + } else { + char c = (char)((b1 << 12) ^ + (b2 << 6) ^ + (b3 ^ + (((byte) 0xE0 << 12) ^ + ((byte) 0x80 << 6) ^ + ((byte) 0x80 << 0)))); + if (isSurrogate(c)) { + if (!doReplace) { + throwMalformed(sp - 3, 3); + } + putChar(dst, dp++, repl); + } else { + putChar(dst, dp++, c); + } + } + continue; + } + if (sp < sl && isMalformed3_2(b1, src[sp])) { + if (!doReplace) { + throwMalformed(sp - 1, 2); + } + putChar(dst, dp++, repl); + continue; + } + if (!doReplace){ + throwMalformed(sp, 1); + } + putChar(dst, dp++, repl); + break; + } else if ((b1 >> 3) == -2) { + if (sp + 2 < sl) { + int b2 = src[sp++]; + int b3 = src[sp++]; + int b4 = src[sp++]; + int uc = ((b1 << 18) ^ + (b2 << 12) ^ + (b3 << 6) ^ + (b4 ^ + (((byte) 0xF0 << 18) ^ + ((byte) 0x80 << 12) ^ + ((byte) 0x80 << 6) ^ + ((byte) 0x80 << 0)))); + if (isMalformed4(b2, b3, b4) || + !isSupplementaryCodePoint(uc)) { // shortest form check + if (!doReplace) { + throwMalformed(sp - 4, 4); + } + putChar(dst, dp++, repl); + sp -= 4; + sp += malformedN(src, sp, 4); + } else { + putChar(dst, dp++, highSurrogate(uc)); + putChar(dst, dp++, lowSurrogate(uc)); + } + continue; + } + b1 &= 0xff; + if (b1 > 0xf4 || + sp < sl && isMalformed4_2(b1, src[sp] & 0xff)) { + if (!doReplace) { + throwMalformed(sp - 1, 1); // or 2 + } + putChar(dst, dp++, repl); + continue; + } + if (!doReplace) { + throwMalformed(sp - 1, 1); + } + sp++; + putChar(dst, dp++, repl); + if (sp < sl && isMalformed4_3(src[sp])) { + continue; + } + break; + } else { + if (!doReplace) { + throwMalformed(sp - 1, 1); + } + putChar(dst, dp++, repl); + } + } + if (dp != len) { + dst = Arrays.copyOf(dst, dp << 1); + } + return ret.with(dst, UTF16); } - static byte[] encode(byte coder, byte[] val) { - String csn = Charset.defaultCharset().name(); - try { - // use charset name encode() variant which provides caching. - return encode(csn, coder, val); - } catch (UnsupportedEncodingException x) { - warnUnsupportedCharset(csn); + private static byte[] encodeUTF8(byte coder, byte[] val, boolean doReplace) { + if (coder == UTF16) + return encodeUTF8_UTF16(val, doReplace); + + if (!hasNegatives(val, 0, val.length)) + return Arrays.copyOf(val, val.length); + + int dp = 0; + byte[] dst = new byte[val.length << 1]; + for (int sp = 0; sp < val.length; sp++) { + byte c = val[sp]; + if (c < 0) { + dst[dp++] = (byte)(0xc0 | ((c & 0xff) >> 6)); + dst[dp++] = (byte)(0x80 | (c & 0x3f)); + } else { + dst[dp++] = c; + } } - try { - return encode("ISO-8859-1", coder, val); - } catch (UnsupportedEncodingException x) { - // If this code is hit during VM initialization, err(String) is - // the only way we will be able to get any kind of error message. - err("ISO-8859-1 charset not available: " + x.toString() + "\n"); - // If we can not find ISO-8859-1 (a required encoding) then things - // are seriously wrong with the installation. - System.exit(1); - return null; - } + if (dp == dst.length) + return dst; + return Arrays.copyOf(dst, dp); } - /** - * Print a message directly to stderr, bypassing all character conversion - * methods. - * @param msg message to print + private static byte[] encodeUTF8_UTF16(byte[] val, boolean doReplace) { + int dp = 0; + int sp = 0; + int sl = val.length >> 1; + byte[] dst = new byte[sl * 3]; + char c; + while (sp < sl && (c = StringUTF16.getChar(val, sp)) < '\u0080') { + // ascii fast loop; + dst[dp++] = (byte)c; + sp++; + } + while (sp < sl) { + c = StringUTF16.getChar(val, sp++); + if (c < 0x80) { + dst[dp++] = (byte)c; + } else if (c < 0x800) { + dst[dp++] = (byte)(0xc0 | (c >> 6)); + dst[dp++] = (byte)(0x80 | (c & 0x3f)); + } else if (Character.isSurrogate(c)) { + int uc = -1; + char c2; + if (Character.isHighSurrogate(c) && sp < sl && + Character.isLowSurrogate(c2 = StringUTF16.getChar(val, sp))) { + uc = Character.toCodePoint(c, c2); + } + if (uc < 0) { + if (doReplace) { + dst[dp++] = '?'; + } else { + throwMalformed(sp - 1, 1); // or 2, does not matter here + } + } else { + dst[dp++] = (byte)(0xf0 | ((uc >> 18))); + dst[dp++] = (byte)(0x80 | ((uc >> 12) & 0x3f)); + dst[dp++] = (byte)(0x80 | ((uc >> 6) & 0x3f)); + dst[dp++] = (byte)(0x80 | (uc & 0x3f)); + sp++; // 2 chars + } + } else { + // 3 bytes, 16 bits + dst[dp++] = (byte)(0xe0 | ((c >> 12))); + dst[dp++] = (byte)(0x80 | ((c >> 6) & 0x3f)); + dst[dp++] = (byte)(0x80 | (c & 0x3f)); + } + } + if (dp == dst.length) { + return dst; + } + return Arrays.copyOf(dst, dp); + } + + ////////////////////// for j.u.z.ZipCoder ////////////////////////// + + /* + * Throws iae, instead of replacing, if malformed or unmappble. */ - private static native void err(String msg); + static String newStringUTF8NoRepl(byte[] src, int off, int len) { + if (COMPACT_STRINGS && !hasNegatives(src, off, len)) + return new String(Arrays.copyOfRange(src, off, off + len), LATIN1); + Result ret = decodeUTF8_0(src, off, len, false); + return new String(ret.value, ret.coder); + } + + /* + * Throws iae, instead of replacing, if unmappble. + */ + static byte[] getBytesUTF8NoRepl(String s) { + return encodeUTF8(s.coder(), s.value(), false); + } } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/lang/StringDecoderUTF8.java --- a/src/java.base/share/classes/java/lang/StringDecoderUTF8.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,235 +0,0 @@ -/* - * Copyright (c) 2015, 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 java.lang; - -import java.nio.charset.Charset; -import java.util.Arrays; - -import static java.lang.String.LATIN1; -import static java.lang.String.UTF16; -import static java.lang.String.COMPACT_STRINGS; -import static java.lang.Character.isSurrogate; -import static java.lang.Character.highSurrogate; -import static java.lang.Character.lowSurrogate; -import static java.lang.Character.isSupplementaryCodePoint; -import static java.lang.StringUTF16.putChar; - -class StringDecoderUTF8 extends StringCoding.StringDecoder { - - StringDecoderUTF8(Charset cs, String rcn) { - super(cs, rcn); - } - - private static boolean isNotContinuation(int b) { - return (b & 0xc0) != 0x80; - } - - private static boolean isMalformed3(int b1, int b2, int b3) { - return (b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) || - (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80; - } - - private static boolean isMalformed3_2(int b1, int b2) { - return (b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) || - (b2 & 0xc0) != 0x80; - } - - private static boolean isMalformed4(int b2, int b3, int b4) { - return (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80 || - (b4 & 0xc0) != 0x80; - } - - private static boolean isMalformed4_2(int b1, int b2) { - return (b1 == 0xf0 && (b2 < 0x90 || b2 > 0xbf)) || - (b1 == 0xf4 && (b2 & 0xf0) != 0x80) || - (b2 & 0xc0) != 0x80; - } - - private static boolean isMalformed4_3(int b3) { - return (b3 & 0xc0) != 0x80; - } - - // for nb == 3/4 - private static int malformedN(byte[] src, int sp, int nb) { - if (nb == 3) { - int b1 = src[sp++]; - int b2 = src[sp++]; // no need to lookup b3 - return ((b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) || - isNotContinuation(b2)) ? 1 : 2; - } else if (nb == 4) { // we don't care the speed here - int b1 = src[sp++] & 0xff; - int b2 = src[sp++] & 0xff; - if (b1 > 0xf4 || - (b1 == 0xf0 && (b2 < 0x90 || b2 > 0xbf)) || - (b1 == 0xf4 && (b2 & 0xf0) != 0x80) || - isNotContinuation(b2)) - return 1; - if (isNotContinuation(src[sp++])) - return 2; - return 3; - } - assert false; - return -1; - } - - private static char repl = '\ufffd'; - - StringCoding.Result decode(byte[] src, int sp, int len) { - return decode(src, sp, len, result); - } - - static StringCoding.Result decode(byte[] src, int sp, int len, - StringCoding.Result ret) { - int sl = sp + len; - byte[] dst = new byte[len]; - int dp = 0; - if (COMPACT_STRINGS) { // Latin1 only loop - while (sp < sl) { - int b1 = src[sp]; - if (b1 >= 0) { - dst[dp++] = (byte)b1; - sp++; - continue; - } - if ((b1 == (byte)0xc2 || b1 == (byte)0xc3) && - sp + 1 < sl) { - int b2 = src[sp + 1]; - if (!isNotContinuation(b2)) { - dst[dp++] = (byte)(((b1 << 6) ^ b2)^ - (((byte) 0xC0 << 6) ^ - ((byte) 0x80 << 0))); - sp += 2; - continue; - } - } - // anything not a latin1, including the repl - // we have to go with the utf16 - break; - } - if (sp == sl) { - if (dp != dst.length) { - dst = Arrays.copyOf(dst, dp); - } - return ret.with(dst, LATIN1); - } - } - if (dp == 0) { - dst = new byte[len << 1]; - } else { - byte[] buf = new byte[len << 1]; - StringLatin1.inflate(dst, 0, buf, 0, dp); - dst = buf; - } - while (sp < sl) { - int b1 = src[sp++]; - if (b1 >= 0) { - putChar(dst, dp++, (char) b1); - } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) { - if (sp < sl) { - int b2 = src[sp++]; - if (isNotContinuation(b2)) { - putChar(dst, dp++, repl); - sp--; - } else { - putChar(dst, dp++, (char)(((b1 << 6) ^ b2)^ - (((byte) 0xC0 << 6) ^ - ((byte) 0x80 << 0)))); - } - continue; - } - putChar(dst, dp++, repl); - break; - } else if ((b1 >> 4) == -2) { - if (sp + 1 < sl) { - int b2 = src[sp++]; - int b3 = src[sp++]; - if (isMalformed3(b1, b2, b3)) { - putChar(dst, dp++, repl); - sp -= 3; - sp += malformedN(src, sp, 3); - } else { - char c = (char)((b1 << 12) ^ - (b2 << 6) ^ - (b3 ^ - (((byte) 0xE0 << 12) ^ - ((byte) 0x80 << 6) ^ - ((byte) 0x80 << 0)))); - putChar(dst, dp++, isSurrogate(c) ? repl : c); - } - continue; - } - if (sp < sl && isMalformed3_2(b1, src[sp])) { - putChar(dst, dp++, repl); - continue; - } - putChar(dst, dp++, repl); - break; - } else if ((b1 >> 3) == -2) { - if (sp + 2 < sl) { - int b2 = src[sp++]; - int b3 = src[sp++]; - int b4 = src[sp++]; - int uc = ((b1 << 18) ^ - (b2 << 12) ^ - (b3 << 6) ^ - (b4 ^ - (((byte) 0xF0 << 18) ^ - ((byte) 0x80 << 12) ^ - ((byte) 0x80 << 6) ^ - ((byte) 0x80 << 0)))); - if (isMalformed4(b2, b3, b4) || - !isSupplementaryCodePoint(uc)) { // shortest form check - putChar(dst, dp++, repl); - sp -= 4; - sp += malformedN(src, sp, 4); - } else { - putChar(dst, dp++, highSurrogate(uc)); - putChar(dst, dp++, lowSurrogate(uc)); - } - continue; - } - b1 &= 0xff; - if (b1 > 0xf4 || - sp < sl && isMalformed4_2(b1, src[sp] & 0xff)) { - putChar(dst, dp++, repl); - continue; - } - sp++; - putChar(dst, dp++, repl); - if (sp < sl && isMalformed4_3(src[sp])) { - continue; - } - break; - } else { - putChar(dst, dp++, repl); - } - } - if (dp != len) { - dst = Arrays.copyOf(dst, dp << 1); - } - return ret.with(dst, UTF16); - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/lang/System.java --- a/src/java.base/share/classes/java/lang/System.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/lang/System.java Thu Dec 14 12:28:32 2017 +0000 @@ -550,8 +550,10 @@ * System properties. The following properties are guaranteed to be defined: *
*
java.version
Java version number + *
java.version.date
Java version date *
java.vendor
Java vendor specific string *
java.vendor.url
Java vendor URL + *
java.vendor.version
Java vendor version *
java.home
Java installation directory *
java.class.version
Java class version number *
java.class.path
Java classpath @@ -591,12 +593,18 @@ * * * java.version - * Java Runtime Environment version which may be interpreted + * Java Runtime Environment version, which may be interpreted * as a {@link Runtime.Version} + * java.version.date + * Java Runtime Environment version date, in ISO-8601 YYYY-MM-DD + * format, which may be interpreted as a {@link + * java.time.LocalDate} * java.vendor * Java Runtime Environment vendor * java.vendor.url * Java vendor URL + * java.vendor.version + * Java vendor version * java.home * Java installation directory * java.vm.specification.version @@ -2184,6 +2192,15 @@ public Stream layers(ClassLoader loader) { return ModuleLayer.layers(loader); } + + public String newStringUTF8NoRepl(byte[] bytes, int off, int len) { + return StringCoding.newStringUTF8NoRepl(bytes, off, len); + } + + public byte[] getBytesUTF8NoRepl(String s) { + return StringCoding.getBytesUTF8NoRepl(s); + } + }); } } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/lang/VersionProps.java.template --- a/src/java.base/share/classes/java/lang/VersionProps.java.template Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/lang/VersionProps.java.template Thu Dec 14 12:28:32 2017 +0000 @@ -32,13 +32,15 @@ class VersionProps { - private static final String launcher_name = "@@LAUNCHER_NAME@@"; private static final String java_version = "@@VERSION_SHORT@@"; + private static final String java_version_date = + "@@VERSION_DATE@@"; + private static final String java_runtime_name = "@@RUNTIME_NAME@@"; @@ -57,14 +59,27 @@ private static final String VERSION_OPT = "@@VERSION_OPT@@"; + private static final boolean isLTS = + "@@VERSION_OPT@@".startsWith("LTS"); + + private static final String VENDOR_VERSION_STRING = + "@@VENDOR_VERSION_STRING@@"; + + private static final String vendor_version = + (VENDOR_VERSION_STRING.length() > 0 + ? " " + VENDOR_VERSION_STRING : ""); + static { init(); } public static void init() { System.setProperty("java.version", java_version); + System.setProperty("java.version.date", java_version_date); System.setProperty("java.runtime.version", java_runtime_version); System.setProperty("java.runtime.name", java_runtime_name); + if (VENDOR_VERSION_STRING.length() > 0) + System.setProperty("java.vendor.version", VENDOR_VERSION_STRING); } private static int parseVersionNumber(String version, int prevIndex, int index) { @@ -162,31 +177,36 @@ /* First line: platform version. */ if (err) { - ps.println(launcher_name + " version \"" + java_version + "\""); + ps.println(launcher_name + " version \"" + java_version + "\"" + + " " + java_version_date + + (isLTS ? " LTS" : "")); } else { /* Use a format more in line with GNU conventions */ - ps.println(launcher_name + " " + java_version); + ps.println(launcher_name + " " + java_version + + " " + java_version_date + + (isLTS ? " LTS" : "")); } /* Second line: runtime version (ie, libraries). */ String jdk_debug_level = System.getProperty("jdk.debug", "release"); - /* Debug level is not printed for "release" builds */ if ("release".equals(jdk_debug_level)) { + /* Do not show debug level "release" builds */ jdk_debug_level = ""; } else { jdk_debug_level = jdk_debug_level + " "; } - ps.print(java_runtime_name + " (" + jdk_debug_level + "build " + java_runtime_version); - - ps.println(')'); + ps.println(java_runtime_name + vendor_version + + " (" + jdk_debug_level + "build " + java_runtime_version + ")"); /* Third line: JVM information. */ String java_vm_name = System.getProperty("java.vm.name"); String java_vm_version = System.getProperty("java.vm.version"); String java_vm_info = System.getProperty("java.vm.info"); - ps.println(java_vm_name + " (" + jdk_debug_level + "build " + java_vm_version + ", " + - java_vm_info + ")"); + ps.println(java_vm_name + vendor_version + + " (" + jdk_debug_level + "build " + java_vm_version + ", " + + java_vm_info + ")"); + } } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/lang/invoke/MethodType.java --- a/src/java.base/share/classes/java/lang/invoke/MethodType.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/lang/invoke/MethodType.java Thu Dec 14 12:28:32 2017 +0000 @@ -105,23 +105,10 @@ private @Stable String methodDescriptor; // cache for toMethodDescriptorString /** - * Check the given parameters for validity and store them into the final fields. + * Constructor that performs no copying or validation. + * Should only be called from the factory method makeImpl */ - private MethodType(Class rtype, Class[] ptypes, boolean trusted) { - checkRtype(rtype); - checkPtypes(ptypes); - this.rtype = rtype; - // defensively copy the array passed in by the user - this.ptypes = trusted ? ptypes : Arrays.copyOf(ptypes, ptypes.length); - } - - /** - * Construct a temporary unchecked instance of MethodType for use only as a key to the intern table. - * Does not check the given parameters for validity, and must discarded (if untrusted) or checked - * (if trusted) after it has been used as a searching key. - * The parameters are reversed for this constructor, so that it is not accidentally used. - */ - private MethodType(Class[] ptypes, Class rtype) { + private MethodType(Class rtype, Class[] ptypes) { this.rtype = rtype; this.ptypes = ptypes; } @@ -308,18 +295,21 @@ if (ptypes.length == 0) { ptypes = NO_PTYPES; trusted = true; } - MethodType primordialMT = new MethodType(ptypes, rtype); + MethodType primordialMT = new MethodType(rtype, ptypes); MethodType mt = internTable.get(primordialMT); if (mt != null) return mt; // promote the object to the Real Thing, and reprobe + MethodType.checkRtype(rtype); if (trusted) { - MethodType.checkRtype(rtype); MethodType.checkPtypes(ptypes); mt = primordialMT; } else { - mt = new MethodType(rtype, ptypes, false); + // Make defensive copy then validate + ptypes = Arrays.copyOf(ptypes, ptypes.length); + MethodType.checkPtypes(ptypes); + mt = new MethodType(rtype, ptypes); } mt.form = MethodTypeForm.findForm(mt); return internTable.add(mt); diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/lang/module/Configuration.java --- a/src/java.base/share/classes/java/lang/module/Configuration.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/lang/module/Configuration.java Thu Dec 14 12:28:32 2017 +0000 @@ -543,9 +543,8 @@ if (!parents.isEmpty()) { return configurations() .skip(1) // skip this configuration - .map(cf -> cf.nameToModule) - .filter(map -> map.containsKey(name)) - .map(map -> map.get(name)) + .map(cf -> cf.nameToModule.get(name)) + .filter(Objects::nonNull) .findFirst(); } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/lang/module/ModuleDescriptor.java --- a/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java Thu Dec 14 12:28:32 2017 +0000 @@ -39,6 +39,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -2603,7 +2604,8 @@ * Returns a string containing the given set of modifiers and label. */ private static String toString(Set mods, String what) { - return (Stream.concat(mods.stream().map(e -> e.toString().toLowerCase()), + return (Stream.concat(mods.stream().map(e -> e.toString() + .toLowerCase(Locale.ROOT)), Stream.of(what))) .collect(Collectors.joining(" ")); } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/net/SocketInputStream.java --- a/src/java.base/share/classes/java/net/SocketInputStream.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/net/SocketInputStream.java Thu Dec 14 12:28:32 2017 +0000 @@ -283,7 +283,7 @@ /** * Overrides finalize, the fd is closed by the Socket. */ - @SuppressWarnings("deprecation") + @SuppressWarnings({"deprecation", "removal"}) protected void finalize() {} /** diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/net/SocketOutputStream.java --- a/src/java.base/share/classes/java/net/SocketOutputStream.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/net/SocketOutputStream.java Thu Dec 14 12:28:32 2017 +0000 @@ -175,7 +175,7 @@ /** * Overrides finalize, the fd is closed by the Socket. */ - @SuppressWarnings("deprecation") + @SuppressWarnings({"deprecation", "removal"}) protected void finalize() {} /** diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/net/URLClassLoader.java --- a/src/java.base/share/classes/java/net/URLClassLoader.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/net/URLClassLoader.java Thu Dec 14 12:28:32 2017 +0000 @@ -658,8 +658,8 @@ * * @param name the resource name * @exception IOException if an I/O exception occurs - * @return an {@code Enumeration} of {@code URL}s - * If the loader is closed, the Enumeration will be empty. + * @return An {@code Enumeration} of {@code URL}s. + * If the loader is closed, the Enumeration contains no elements. */ public Enumeration findResources(final String name) throws IOException diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/net/URLDecoder.java --- a/src/java.base/share/classes/java/net/URLDecoder.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/net/URLDecoder.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,10 @@ package java.net; import java.io.*; +import java.nio.charset.Charset; +import java.nio.charset.IllegalCharsetNameException; +import java.nio.charset.UnsupportedCharsetException; +import java.util.Objects; /** * Utility class for HTML form decoding. This class contains static methods @@ -108,7 +112,43 @@ /** * Decodes an {@code application/x-www-form-urlencoded} string using * a specific encoding scheme. - * The supplied encoding is used to determine + * + *

+ * This method behaves the same as {@linkplain decode(String s, Charset charset)} + * except that it will {@linkplain java.nio.charset.Charset#forName look up the charset} + * using the given encoding name. + * + * @implNote This implementation will throw an {@link java.lang.IllegalArgumentException} + * when illegal strings are encountered. + * + * @param s the {@code String} to decode + * @param enc The name of a supported + * character + * encoding. + * @return the newly decoded {@code String} + * @throws UnsupportedEncodingException + * If character encoding needs to be consulted, but + * named character encoding is not supported + * @see URLEncoder#encode(java.lang.String, java.lang.String) + * @since 1.4 + */ + public static String decode(String s, String enc) throws UnsupportedEncodingException { + if (enc.length() == 0) { + throw new UnsupportedEncodingException ("URLDecoder: empty string enc parameter"); + } + + try { + Charset charset = Charset.forName(enc); + return decode(s, charset); + } catch (IllegalCharsetNameException | UnsupportedCharsetException e) { + throw new UnsupportedEncodingException(enc); + } + } + + /** + * Decodes an {@code application/x-www-form-urlencoded} string using + * a specific {@linkplain java.nio.charset.Charset Charset}. + * The supplied charset is used to determine * what characters are represented by any consecutive sequences of the * form "{@code %xy}". *

@@ -118,29 +158,25 @@ * UTF-8 should be used. Not doing so may introduce * incompatibilities. * + * @implNote This implementation will throw an {@link java.lang.IllegalArgumentException} + * when illegal strings are encountered. + * * @param s the {@code String} to decode - * @param enc The name of a supported - * character - * encoding. + * @param charset the given charset * @return the newly decoded {@code String} - * @exception UnsupportedEncodingException - * If character encoding needs to be consulted, but - * named character encoding is not supported - * @see URLEncoder#encode(java.lang.String, java.lang.String) - * @since 1.4 + * @throws NullPointerException if {@code s} or {@code charset} is {@code null} + * @throws IllegalArgumentException if the implementation encounters illegal + * characters + * @see URLEncoder#encode(java.lang.String, java.nio.charset.Charset) + * @since 10 */ - public static String decode(String s, String enc) - throws UnsupportedEncodingException{ - + public static String decode(String s, Charset charset) { + Objects.requireNonNull(charset, "Charset"); boolean needToChange = false; int numChars = s.length(); StringBuilder sb = new StringBuilder(numChars > 500 ? numChars / 2 : numChars); int i = 0; - if (enc.length() == 0) { - throw new UnsupportedEncodingException ("URLDecoder: empty string enc parameter"); - } - char c; byte[] bytes = null; while (i < numChars) { @@ -173,7 +209,9 @@ (c=='%')) { int v = Integer.parseInt(s, i + 1, i + 3, 16); if (v < 0) - throw new IllegalArgumentException("URLDecoder: Illegal hex characters in escape (%) pattern - negative value"); + throw new IllegalArgumentException( + "URLDecoder: Illegal hex characters in escape " + + "(%) pattern - negative value"); bytes[pos++] = (byte) v; i+= 3; if (i < numChars) @@ -187,7 +225,7 @@ throw new IllegalArgumentException( "URLDecoder: Incomplete trailing escape (%) pattern"); - sb.append(new String(bytes, 0, pos, enc)); + sb.append(new String(bytes, 0, pos, charset)); } catch (NumberFormatException e) { throw new IllegalArgumentException( "URLDecoder: Illegal hex characters in escape (%) pattern - " diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/net/URLEncoder.java --- a/src/java.base/share/classes/java/net/URLEncoder.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/net/URLEncoder.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,7 @@ import java.nio.charset.IllegalCharsetNameException; import java.nio.charset.UnsupportedCharsetException ; import java.util.BitSet; +import java.util.Objects; import sun.security.action.GetPropertyAction; /** @@ -168,45 +169,61 @@ /** * Translates a string into {@code application/x-www-form-urlencoded} - * format using a specific encoding scheme. This method uses the - * supplied encoding scheme to obtain the bytes for unsafe - * characters. + * format using a specific encoding scheme. *

- * Note: The - * World Wide Web Consortium Recommendation states that - * UTF-8 should be used. Not doing so may introduce - * incompatibilities. + * This method behaves the same as {@linkplain encode(String s, Charset charset)} + * except that it will {@linkplain java.nio.charset.Charset#forName look up the charset} + * using the given encoding name. * * @param s {@code String} to be translated. * @param enc The name of a supported * character * encoding. * @return the translated {@code String}. - * @exception UnsupportedEncodingException + * @throws UnsupportedEncodingException * If the named encoding is not supported * @see URLDecoder#decode(java.lang.String, java.lang.String) * @since 1.4 */ public static String encode(String s, String enc) throws UnsupportedEncodingException { + if (enc == null) { + throw new NullPointerException("charsetName"); + } + + try { + Charset charset = Charset.forName(enc); + return encode(s, charset); + } catch (IllegalCharsetNameException | UnsupportedCharsetException e) { + throw new UnsupportedEncodingException(enc); + } + } + + /** + * Translates a string into {@code application/x-www-form-urlencoded} + * format using a specific {@linkplain java.nio.charset.Charset Charset}. + * This method uses the supplied charset to obtain the bytes for unsafe + * characters. + *

+ * Note: The + * World Wide Web Consortium Recommendation states that + * UTF-8 should be used. Not doing so may introduce incompatibilities. + * + * @param s {@code String} to be translated. + * @param charset the given charset + * @return the translated {@code String}. + * @throws NullPointerException if {@code s} or {@code charset} is {@code null}. + * @see URLDecoder#decode(java.lang.String, java.nio.charset.Charset) + * @since 10 + */ + public static String encode(String s, Charset charset) { + Objects.requireNonNull(charset, "charset"); boolean needToChange = false; StringBuilder out = new StringBuilder(s.length()); - Charset charset; CharArrayWriter charArrayWriter = new CharArrayWriter(); - if (enc == null) - throw new NullPointerException("charsetName"); - - try { - charset = Charset.forName(enc); - } catch (IllegalCharsetNameException e) { - throw new UnsupportedEncodingException(enc); - } catch (UnsupportedCharsetException e) { - throw new UnsupportedEncodingException(enc); - } - for (int i = 0; i < s.length();) { int c = (int) s.charAt(i); //System.out.println("Examining character: " + c); diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/net/URLStreamHandler.java --- a/src/java.base/share/classes/java/net/URLStreamHandler.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/net/URLStreamHandler.java Thu Dec 14 12:28:32 2017 +0000 @@ -480,39 +480,14 @@ * @return a string representation of the {@code URL} argument. */ protected String toExternalForm(URL u) { - - // pre-compute length of StringBuffer - int len = u.getProtocol().length() + 1; - if (u.getAuthority() != null && u.getAuthority().length() > 0) - len += 2 + u.getAuthority().length(); - if (u.getPath() != null) { - len += u.getPath().length(); - } - if (u.getQuery() != null) { - len += 1 + u.getQuery().length(); - } - if (u.getRef() != null) - len += 1 + u.getRef().length(); - - StringBuilder result = new StringBuilder(len); - result.append(u.getProtocol()); - result.append(":"); - if (u.getAuthority() != null && u.getAuthority().length() > 0) { - result.append("//"); - result.append(u.getAuthority()); - } - if (u.getPath() != null) { - result.append(u.getPath()); - } - if (u.getQuery() != null) { - result.append('?'); - result.append(u.getQuery()); - } - if (u.getRef() != null) { - result.append("#"); - result.append(u.getRef()); - } - return result.toString(); + String s; + return u.getProtocol() + + ':' + + (((s = u.getAuthority()) != null && s.length() > 0) + ? "//" + s : "") + + (((s = u.getPath()) != null) ? s : "") + + (((s = u.getQuery()) != null) ? '?' + s : "") + + (((s = u.getRef()) != null) ? '#' + s : ""); } /** diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/nio/channels/Channels.java --- a/src/java.base/share/classes/java/nio/channels/Channels.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/nio/channels/Channels.java Thu Dec 14 12:28:32 2017 +0000 @@ -527,7 +527,7 @@ * behaves in exactly the same way as the expression * *

 {@code
-     *     Channels.newReader(ch, Charset.forName(csName).newDecoder(), -1)
+     *     Channels.newReader(ch, Charset.forName(csName))
      * } 
* * @param ch @@ -550,6 +550,38 @@ } /** + * Constructs a reader that decodes bytes from the given channel according + * to the given charset. + * + *

An invocation of this method of the form + * + *

 {@code
+     *     Channels.newReader(ch, charset)
+     * } 
+ * + * behaves in exactly the same way as the expression + * + *
 {@code
+     *     Channels.newReader(ch, Charset.forName(csName).newDecoder(), -1)
+     * } 
+ * + *

The reader's default action for malformed-input and unmappable-character + * errors is to {@linkplain java.nio.charset.CodingErrorAction#REPORT report} + * them. When more control over the error handling is required, the constructor + * that takes a {@linkplain java.nio.charset.CharsetDecoder} should be used. + * + * @param ch The channel from which bytes will be read + * + * @param charset The charset to be used + * + * @return A new reader + */ + public static Reader newReader(ReadableByteChannel ch, Charset charset) { + Objects.requireNonNull(charset, "charset"); + return newReader(ch, charset.newDecoder(), -1); + } + + /** * Constructs a writer that encodes characters using the given encoder and * writes the resulting bytes to the given channel. * @@ -595,7 +627,7 @@ * behaves in exactly the same way as the expression * *

 {@code
-     *     Channels.newWriter(ch, Charset.forName(csName).newEncoder(), -1)
+     *     Channels.newWriter(ch, Charset.forName(csName))
      * } 
* * @param ch @@ -616,4 +648,38 @@ Objects.requireNonNull(csName, "csName"); return newWriter(ch, Charset.forName(csName).newEncoder(), -1); } + + /** + * Constructs a writer that encodes characters according to the given + * charset and writes the resulting bytes to the given channel. + * + *

An invocation of this method of the form + * + *

 {@code
+     *     Channels.newWriter(ch, charset)
+     * } 
+ * + * behaves in exactly the same way as the expression + * + *
 {@code
+     *     Channels.newWriter(ch, Charset.forName(csName).newEncoder(), -1)
+     * } 
+ * + *

The writer's default action for malformed-input and unmappable-character + * errors is to {@linkplain java.nio.charset.CodingErrorAction#REPORT report} + * them. When more control over the error handling is required, the constructor + * that takes a {@linkplain java.nio.charset.CharsetEncoder} should be used. + * + * @param ch + * The channel to which bytes will be written + * + * @param charset + * The charset to be used + * + * @return A new writer + */ + public static Writer newWriter(WritableByteChannel ch, Charset charset) { + Objects.requireNonNull(charset, "charset"); + return newWriter(ch, charset.newEncoder(), -1); } +} diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/security/ProtectionDomain.java --- a/src/java.base/share/classes/java/security/ProtectionDomain.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/security/ProtectionDomain.java Thu Dec 14 12:28:32 2017 +0000 @@ -25,15 +25,13 @@ package java.security; -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.SoftReference; -import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.Collections; import java.util.Enumeration; import java.util.List; +import java.util.Map; import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; +import java.util.WeakHashMap; import jdk.internal.misc.JavaSecurityAccess; import jdk.internal.misc.JavaSecurityProtectionDomainAccess; import static jdk.internal.misc.JavaSecurityProtectionDomainAccess.ProtectionDomainCache; @@ -115,23 +113,10 @@ } static { - // setup SharedSecrets to allow access to doIntersectionPrivilege - // methods and ProtectionDomain cache + // Set up JavaSecurityAccess in SharedSecrets SharedSecrets.setJavaSecurityAccess(new JavaSecurityAccessImpl()); - SharedSecrets.setJavaSecurityProtectionDomainAccess( - new JavaSecurityProtectionDomainAccess() { - @Override - public ProtectionDomainCache getProtectionDomainCache() { - return new PDCache(); - } - }); } - /** - * Used for storing ProtectionDomains as keys in a Map. - */ - static final class Key {} - /* CodeSource */ private CodeSource codesource ; @@ -571,117 +556,27 @@ } /** - * A cache of ProtectionDomains and their Permissions. - * - * This class stores ProtectionDomains as weak keys in a ConcurrentHashMap - * with additional support for checking and removing weak keys that are no - * longer in use. There can be cases where the permission collection may - * have a chain of strong references back to the ProtectionDomain, which - * ordinarily would prevent the entry from being removed from the map. To - * address that, we wrap the permission collection in a SoftReference so - * that it can be reclaimed by the garbage collector due to memory demand. + * Used for storing ProtectionDomains as keys in a Map. */ - private static class PDCache implements ProtectionDomainCache { - private final ConcurrentHashMap> - pdMap = new ConcurrentHashMap<>(); - private final ReferenceQueue queue = new ReferenceQueue<>(); - - @Override - public void put(ProtectionDomain pd, PermissionCollection pc) { - processQueue(queue, pdMap); - WeakProtectionDomainKey weakPd = - new WeakProtectionDomainKey(pd, queue); - pdMap.put(weakPd, new SoftReference<>(pc)); - } - - @Override - public PermissionCollection get(ProtectionDomain pd) { - processQueue(queue, pdMap); - WeakProtectionDomainKey weakPd = new WeakProtectionDomainKey(pd); - SoftReference sr = pdMap.get(weakPd); - return (sr == null) ? null : sr.get(); - } - - /** - * Removes weak keys from the map that have been enqueued - * on the reference queue and are no longer in use. - */ - private static void processQueue(ReferenceQueue queue, - ConcurrentHashMap, ?> pdMap) { - Reference ref; - while ((ref = queue.poll()) != null) { - pdMap.remove(ref); - } - } - } - - /** - * A weak key for a ProtectionDomain. - */ - private static class WeakProtectionDomainKey extends WeakReference { - /** - * Saved value of the referent's identity hash code, to maintain - * a consistent hash code after the referent has been cleared - */ - private final int hash; + final class Key {} - /** - * A key representing a null ProtectionDomain. - */ - private static final Key NULL_KEY = new Key(); - - /** - * Create a new WeakProtectionDomain with the specified domain and - * registered with a queue. - */ - WeakProtectionDomainKey(ProtectionDomain pd, ReferenceQueue rq) { - this((pd == null ? NULL_KEY : pd.key), rq); - } - - WeakProtectionDomainKey(ProtectionDomain pd) { - this(pd == null ? NULL_KEY : pd.key); - } - - private WeakProtectionDomainKey(Key key, ReferenceQueue rq) { - super(key, rq); - hash = key.hashCode(); - } - - private WeakProtectionDomainKey(Key key) { - super(key); - hash = key.hashCode(); - } - - /** - * Returns the identity hash code of the original referent. - */ - @Override - public int hashCode() { - return hash; - } - - /** - * Returns true if the given object is an identical - * WeakProtectionDomainKey instance, or, if this object's referent - * has not been cleared and the given object is another - * WeakProtectionDomainKey instance with an identical non-null - * referent as this one. - */ - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - - if (obj instanceof WeakProtectionDomainKey) { - Object referent = get(); - return (referent != null) && - (referent == ((WeakProtectionDomainKey)obj).get()); - } else { - return false; - } - } + static { + SharedSecrets.setJavaSecurityProtectionDomainAccess( + new JavaSecurityProtectionDomainAccess() { + public ProtectionDomainCache getProtectionDomainCache() { + return new ProtectionDomainCache() { + private final Map map = + Collections.synchronizedMap + (new WeakHashMap()); + public void put(ProtectionDomain pd, + PermissionCollection pc) { + map.put((pd == null ? null : pd.key), pc); + } + public PermissionCollection get(ProtectionDomain pd) { + return pd == null ? map.get(null) : map.get(pd.key); + } + }; + } + }); } } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/text/DateFormat.java --- a/src/java.base/share/classes/java/text/DateFormat.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/text/DateFormat.java Thu Dec 14 12:28:32 2017 +0000 @@ -97,6 +97,13 @@ * DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, Locale.FRANCE); * }

*
+ * + *

If the specified locale contains "ca" (calendar), "rg" (region override), + * and/or "tz" (timezone) Unicode + * extensions, the calendar, the country and/or the time zone for formatting + * are overridden. If both "ca" and "rg" are specified, the calendar from the "ca" + * extension supersedes the implicit one from the "rg" extension. + * *

You can use a DateFormat to parse also. *

*
{@code
diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/text/DateFormatSymbols.java
--- a/src/java.base/share/classes/java/text/DateFormatSymbols.java	Mon Dec 11 16:43:11 2017 +0000
+++ b/src/java.base/share/classes/java/text/DateFormatSymbols.java	Thu Dec 14 12:28:32 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -49,6 +49,7 @@
 import java.util.ResourceBundle;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import sun.util.locale.provider.CalendarDataUtility;
 import sun.util.locale.provider.LocaleProviderAdapter;
 import sun.util.locale.provider.LocaleServiceProviderPool;
 import sun.util.locale.provider.ResourceBundleBasedAdapter;
@@ -82,6 +83,10 @@
  * 
*
* + *

If the locale contains "rg" (region override) + * Unicode extension, + * the symbols are overridden for the designated region. + * *

* DateFormatSymbols objects are cloneable. When you obtain * a DateFormatSymbols object, feel free to modify the @@ -716,15 +721,18 @@ } dfs = new DateFormatSymbols(false); + // check for region override + Locale override = CalendarDataUtility.findRegionOverride(locale); + // Initialize the fields from the ResourceBundle for locale. LocaleProviderAdapter adapter - = LocaleProviderAdapter.getAdapter(DateFormatSymbolsProvider.class, locale); + = LocaleProviderAdapter.getAdapter(DateFormatSymbolsProvider.class, override); // Avoid any potential recursions if (!(adapter instanceof ResourceBundleBasedAdapter)) { adapter = LocaleProviderAdapter.getResourceBundleBased(); } ResourceBundle resource - = ((ResourceBundleBasedAdapter)adapter).getLocaleData().getDateFormatData(locale); + = ((ResourceBundleBasedAdapter)adapter).getLocaleData().getDateFormatData(override); dfs.locale = locale; // JRE and CLDR use different keys diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/text/DecimalFormatSymbols.java --- a/src/java.base/share/classes/java/text/DecimalFormatSymbols.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/text/DecimalFormatSymbols.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,6 +44,7 @@ import java.text.spi.DecimalFormatSymbolsProvider; import java.util.Currency; import java.util.Locale; +import sun.util.locale.provider.CalendarDataUtility; import sun.util.locale.provider.LocaleProviderAdapter; import sun.util.locale.provider.LocaleServiceProviderPool; import sun.util.locale.provider.ResourceBundleBasedAdapter; @@ -56,6 +57,10 @@ * of these symbols, you can get the DecimalFormatSymbols object from * your DecimalFormat and modify it. * + *

If the locale contains "rg" (region override) + * Unicode extension, + * the symbols are overridden for the designated region. + * * @see java.util.Locale * @see DecimalFormat * @author Mark Davis @@ -609,13 +614,18 @@ private void initialize( Locale locale ) { this.locale = locale; + // check for region override + Locale override = locale.getUnicodeLocaleType("nu") == null ? + CalendarDataUtility.findRegionOverride(locale) : + locale; + // get resource bundle data - LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(DecimalFormatSymbolsProvider.class, locale); + LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(DecimalFormatSymbolsProvider.class, override); // Avoid potential recursions if (!(adapter instanceof ResourceBundleBasedAdapter)) { adapter = LocaleProviderAdapter.getResourceBundleBased(); } - Object[] data = adapter.getLocaleResources(locale).getDecimalFormatSymbolsData(); + Object[] data = adapter.getLocaleResources(override).getDecimalFormatSymbolsData(); String[] numberElements = (String[]) data[0]; decimalSeparator = numberElements[0].charAt(0); diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/text/NumberFormat.java --- a/src/java.base/share/classes/java/text/NumberFormat.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/text/NumberFormat.java Thu Dec 14 12:28:32 2017 +0000 @@ -96,7 +96,14 @@ * NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH); * } * - * You can also use a NumberFormat to parse numbers: + * + *

If the locale contains "nu" (numbers) and/or "rg" (region override) + * Unicode extensions, + * the decimal digits, and/or the country used for formatting are overridden. + * If both "nu" and "rg" are specified, the decimal digits from the "nu" + * extension supersedes the implicit one from the "rg" extension. + * + *

You can also use a {@code NumberFormat} to parse numbers: *

*
{@code
  * myNumber = nf.parse(myString);
diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/text/SimpleDateFormat.java
--- a/src/java.base/share/classes/java/text/SimpleDateFormat.java	Mon Dec 11 16:43:11 2017 +0000
+++ b/src/java.base/share/classes/java/text/SimpleDateFormat.java	Thu Dec 14 12:28:32 2017 +0000
@@ -672,7 +672,7 @@
             // However, the calendar should use the current default TimeZone.
             // If this is not contained in the locale zone strings, then the zone
             // will be formatted using generic GMT+/-H:MM nomenclature.
-            calendar = Calendar.getInstance(TimeZone.getDefault(), loc);
+            calendar = Calendar.getInstance(loc);
         }
     }
 
diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/time/format/DateTimeFormatter.java
--- a/src/java.base/share/classes/java/time/format/DateTimeFormatter.java	Mon Dec 11 16:43:11 2017 +0000
+++ b/src/java.base/share/classes/java/time/format/DateTimeFormatter.java	Thu Dec 14 12:28:32 2017 +0000
@@ -97,6 +97,7 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import sun.util.locale.provider.TimeZoneNameUtility;
 
 /**
  * Formatter for printing and parsing date-time objects.
@@ -548,7 +549,7 @@
      * For example, {@code d MMM uuuu} will format 2011-12-03 as '3 Dec 2011'.
      * 

* The formatter will use the {@link Locale#getDefault(Locale.Category) default FORMAT locale}. - * This can be changed using {@link DateTimeFormatter#withLocale(Locale)} on the returned formatter + * This can be changed using {@link DateTimeFormatter#withLocale(Locale)} on the returned formatter. * Alternatively use the {@link #ofPattern(String, Locale)} variant of this method. *

* The returned formatter has no override chronology or zone. @@ -572,7 +573,7 @@ * For example, {@code d MMM uuuu} will format 2011-12-03 as '3 Dec 2011'. *

* The formatter will use the specified locale. - * This can be changed using {@link DateTimeFormatter#withLocale(Locale)} on the returned formatter + * This can be changed using {@link DateTimeFormatter#withLocale(Locale)} on the returned formatter. *

* The returned formatter has no override chronology or zone. * It uses {@link ResolverStyle#SMART SMART} resolver style. @@ -1443,10 +1444,17 @@ * This is used to lookup any part of the formatter needing specific * localization, such as the text or localized pattern. *

+ * The locale is stored as passed in, without further processing. + * If the locale has + * Unicode extensions, they may be used later in text + * processing. To set the chronology, time-zone and decimal style from + * unicode extensions, see {@link #localizedBy localizedBy()}. + *

* This instance is immutable and unaffected by this method call. * * @param locale the new locale, not null * @return a formatter based on this formatter with the requested locale, not null + * @see #localizedBy(Locale) */ public DateTimeFormatter withLocale(Locale locale) { if (this.locale.equals(locale)) { @@ -1455,6 +1463,52 @@ return new DateTimeFormatter(printerParser, locale, decimalStyle, resolverStyle, resolverFields, chrono, zone); } + /** + * Returns a copy of this formatter with localized values of the locale, + * calendar, region, decimal style and/or timezone, that supercede values in + * this formatter. + *

+ * This is used to lookup any part of the formatter needing specific + * localization, such as the text or localized pattern. If the locale contains the + * "ca" (calendar), "nu" (numbering system), "rg" (region override), and/or + * "tz" (timezone) + * Unicode extensions, + * the chronology, numbering system and/or the zone are overridden. If both "ca" + * and "rg" are specified, the chronology from the "ca" extension supersedes the + * implicit one from the "rg" extension. Same is true for the "nu" extension. + *

+ * Unlike the {@link #withLocale withLocale} method, the call to this method may + * produce a different formatter depending on the order of method chaining with + * other withXXXX() methods. + *

+ * This instance is immutable and unaffected by this method call. + * + * @param locale the locale, not null + * @return a formatter based on this formatter with localized values of + * the calendar, decimal style and/or timezone, that supercede values in this + * formatter. + * @see #withLocale(Locale) + * @since 10 + */ + public DateTimeFormatter localizedBy(Locale locale) { + if (this.locale.equals(locale)) { + return this; + } + + // Check for decimalStyle/chronology/timezone in locale object + Chronology c = locale.getUnicodeLocaleType("ca") != null ? + Chronology.ofLocale(locale) : chrono; + DecimalStyle ds = locale.getUnicodeLocaleType("nu") != null ? + DecimalStyle.of(locale) : decimalStyle; + String tzType = locale.getUnicodeLocaleType("tz"); + ZoneId z = tzType != null ? + TimeZoneNameUtility.convertLDMLShortID(tzType) + .map(ZoneId::of) + .orElse(zone) : + zone; + return new DateTimeFormatter(printerParser, locale, ds, resolverStyle, resolverFields, c, z); + } + //----------------------------------------------------------------------- /** * Gets the DecimalStyle to be used during formatting. diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java --- a/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -120,6 +120,7 @@ import java.util.concurrent.ConcurrentMap; import sun.text.spi.JavaTimeDateTimePatternProvider; +import sun.util.locale.provider.CalendarDataUtility; import sun.util.locale.provider.LocaleProviderAdapter; import sun.util.locale.provider.LocaleResources; import sun.util.locale.provider.TimeZoneNameUtility; @@ -198,6 +199,10 @@ * Gets the formatting pattern for date and time styles for a locale and chronology. * The locale and chronology are used to lookup the locale specific format * for the requested dateStyle and/or timeStyle. + *

+ * If the locale contains the "rg" (region override) + * Unicode extensions, + * the formatting pattern is overridden with the one appropriate for the region. * * @param dateStyle the FormatStyle for the date, null for time-only pattern * @param timeStyle the FormatStyle for the time, null for date-only pattern @@ -216,7 +221,8 @@ LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(JavaTimeDateTimePatternProvider.class, locale); JavaTimeDateTimePatternProvider provider = adapter.getJavaTimeDateTimePatternProvider(); String pattern = provider.getJavaTimeDateTimePattern(convertStyle(timeStyle), - convertStyle(dateStyle), chrono.getCalendarType(), locale); + convertStyle(dateStyle), chrono.getCalendarType(), + CalendarDataUtility.findRegionOverride(locale)); return pattern; } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/time/format/DateTimeTextProvider.java --- a/src/java.base/share/classes/java/time/format/DateTimeTextProvider.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/time/format/DateTimeTextProvider.java Thu Dec 14 12:28:32 2017 +0000 @@ -510,7 +510,8 @@ @SuppressWarnings("unchecked") static T getLocalizedResource(String key, Locale locale) { LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased() - .getLocaleResources(locale); + .getLocaleResources( + CalendarDataUtility.findRegionOverride(locale)); ResourceBundle rb = lr.getJavaTimeFormatData(); return rb.containsKey(key) ? (T) rb.getObject(key) : null; } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/time/format/DecimalStyle.java --- a/src/java.base/share/classes/java/time/format/DecimalStyle.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/time/format/DecimalStyle.java Thu Dec 14 12:28:32 2017 +0000 @@ -147,6 +147,11 @@ * Obtains the DecimalStyle for the specified locale. *

* This method provides access to locale sensitive decimal style symbols. + * If the locale contains "nu" (Numbering System) and/or "rg" + * (Region Override) + * Unicode extensions, returned instance will reflect the values specified with + * those extensions. If both "nu" and "rg" are specified, the value from + * the "nu" extension supersedes the implicit one from the "rg" extension. * * @param locale the locale, not null * @return the decimal style, not null diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/time/temporal/ChronoField.java --- a/src/java.base/share/classes/java/time/temporal/ChronoField.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/time/temporal/ChronoField.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -79,6 +79,7 @@ import java.util.Locale; import java.util.Objects; import java.util.ResourceBundle; +import sun.util.locale.provider.CalendarDataUtility; import sun.util.locale.provider.LocaleProviderAdapter; import sun.util.locale.provider.LocaleResources; @@ -632,7 +633,9 @@ } LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased() - .getLocaleResources(locale); + .getLocaleResources( + CalendarDataUtility + .findRegionOverride(locale)); ResourceBundle rb = lr.getJavaTimeFormatData(); String key = "field." + displayNameKey; return rb.containsKey(key) ? rb.getString(key) : name; diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/time/temporal/IsoFields.java --- a/src/java.base/share/classes/java/time/temporal/IsoFields.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/time/temporal/IsoFields.java Thu Dec 14 12:28:32 2017 +0000 @@ -81,6 +81,7 @@ import java.util.Objects; import java.util.ResourceBundle; +import sun.util.locale.provider.CalendarDataUtility; import sun.util.locale.provider.LocaleProviderAdapter; import sun.util.locale.provider.LocaleResources; @@ -430,7 +431,9 @@ public String getDisplayName(Locale locale) { Objects.requireNonNull(locale, "locale"); LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased() - .getLocaleResources(locale); + .getLocaleResources( + CalendarDataUtility + .findRegionOverride(locale)); ResourceBundle rb = lr.getJavaTimeFormatData(); return rb.containsKey("field.week") ? rb.getString("field.week") : toString(); } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/time/temporal/WeekFields.java --- a/src/java.base/share/classes/java/time/temporal/WeekFields.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/time/temporal/WeekFields.java Thu Dec 14 12:28:32 2017 +0000 @@ -286,13 +286,17 @@ * Obtains an instance of {@code WeekFields} appropriate for a locale. *

* This will look up appropriate values from the provider of localization data. + * If the locale contains "fw" (First day of week) and/or "rg" + * (Region Override) + * Unicode extensions, returned instance will reflect the values specified with + * those extensions. If both "fw" and "rg" are specified, the value from + * the "fw" extension supersedes the implicit one from the "rg" extension. * * @param locale the locale to use, not null * @return the week-definition, not null */ public static WeekFields of(Locale locale) { Objects.requireNonNull(locale, "locale"); - locale = new Locale(locale.getLanguage(), locale.getCountry()); // elminate variants int calDow = CalendarDataUtility.retrieveFirstDayOfWeek(locale); DayOfWeek dow = DayOfWeek.SUNDAY.plus(calDow - 1); @@ -1041,7 +1045,8 @@ Objects.requireNonNull(locale, "locale"); if (rangeUnit == YEARS) { // only have values for week-of-year LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased() - .getLocaleResources(locale); + .getLocaleResources( + CalendarDataUtility.findRegionOverride(locale)); ResourceBundle rb = lr.getJavaTimeFormatData(); return rb.containsKey("field.week") ? rb.getString("field.week") : name; } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/Calendar.java --- a/src/java.base/share/classes/java/util/Calendar.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/Calendar.java Thu Dec 14 12:28:32 2017 +0000 @@ -58,6 +58,7 @@ import sun.util.calendar.ZoneInfo; import sun.util.locale.provider.CalendarDataUtility; import sun.util.locale.provider.LocaleProviderAdapter; +import sun.util.locale.provider.TimeZoneNameUtility; import sun.util.spi.CalendarProvider; /** @@ -128,9 +129,14 @@ * * Calendar defines a locale-specific seven day week using two * parameters: the first day of the week and the minimal days in first week - * (from 1 to 7). These numbers are taken from the locale resource data when a - * Calendar is constructed. They may also be specified explicitly - * through the methods for setting their values. + * (from 1 to 7). These numbers are taken from the locale resource data or the + * locale itself when a {@code Calendar} is constructed. If the designated + * locale contains "fw" and/or "rg" + * Unicode extensions, the first day of the week will be obtained according to + * those extensions. If both "fw" and "rg" are specified, the value from the "fw" + * extension supersedes the implicit one from the "rg" extension. + * They may also be specified explicitly through the methods for setting their + * values. * *

When setting or getting the WEEK_OF_MONTH or * WEEK_OF_YEAR fields, Calendar must determine the @@ -1444,6 +1450,11 @@ * *

The default values are used for locale and time zone if these * parameters haven't been given explicitly. + *

+ * If the locale contains the time zone with "tz" + * Unicode extension, + * and time zone hasn't been given explicitly, time zone in the locale + * is used. * *

Any out of range field values are either normalized in lenient * mode or detected as an invalid value in non-lenient mode. @@ -1463,7 +1474,7 @@ locale = Locale.getDefault(); } if (zone == null) { - zone = TimeZone.getDefault(); + zone = defaultTimeZone(locale); } Calendar cal; if (type == null) { @@ -1605,12 +1616,17 @@ * Calendar returned is based on the current time * in the default time zone with the default * {@link Locale.Category#FORMAT FORMAT} locale. + *

+ * If the locale contains the time zone with "tz" + * Unicode extension, + * that time zone is used instead. * * @return a Calendar. */ public static Calendar getInstance() { - return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT)); + Locale aLocale = Locale.getDefault(Locale.Category.FORMAT); + return createCalendar(defaultTimeZone(aLocale), aLocale); } /** @@ -1631,13 +1647,17 @@ * Gets a calendar using the default time zone and specified locale. * The Calendar returned is based on the current time * in the default time zone with the given locale. + *

+ * If the locale contains the time zone with "tz" + * Unicode extension, + * that time zone is used instead. * * @param aLocale the locale for the week data * @return a Calendar. */ public static Calendar getInstance(Locale aLocale) { - return createCalendar(TimeZone.getDefault(), aLocale); + return createCalendar(defaultTimeZone(aLocale), aLocale); } /** @@ -1655,6 +1675,16 @@ return createCalendar(zone, aLocale); } + private static TimeZone defaultTimeZone(Locale l) { + TimeZone defaultTZ = TimeZone.getDefault(); + String shortTZID = l.getUnicodeLocaleType("tz"); + return shortTZID != null ? + TimeZoneNameUtility.convertLDMLShortID(shortTZID) + .map(TimeZone::getTimeZone) + .orElse(defaultTZ) : + defaultTZ; + } + private static Calendar createCalendar(TimeZone zone, Locale aLocale) { diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/Collections.java --- a/src/java.base/share/classes/java/util/Collections.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/Collections.java Thu Dec 14 12:28:32 2017 +0000 @@ -24,9 +24,10 @@ */ package java.util; -import java.io.Serializable; + +import java.io.IOException; import java.io.ObjectOutputStream; -import java.io.IOException; +import java.io.Serializable; import java.lang.reflect.Array; import java.util.function.BiConsumer; import java.util.function.BiFunction; @@ -5164,14 +5165,19 @@ * specified comparator. * @since 1.5 */ + @SuppressWarnings("unchecked") public static Comparator reverseOrder(Comparator cmp) { - if (cmp == null) - return reverseOrder(); - - if (cmp instanceof ReverseComparator2) - return ((ReverseComparator2)cmp).cmp; - - return new ReverseComparator2<>(cmp); + if (cmp == null) { + return (Comparator) ReverseComparator.REVERSE_ORDER; + } else if (cmp == ReverseComparator.REVERSE_ORDER) { + return (Comparator) Comparators.NaturalOrderComparator.INSTANCE; + } else if (cmp == Comparators.NaturalOrderComparator.INSTANCE) { + return (Comparator) ReverseComparator.REVERSE_ORDER; + } else if (cmp instanceof ReverseComparator2) { + return ((ReverseComparator2) cmp).cmp; + } else { + return new ReverseComparator2<>(cmp); + } } /** diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/Currency.java --- a/src/java.base/share/classes/java/util/Currency.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/Currency.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.File; -import java.io.FileInputStream; import java.io.FileReader; import java.io.InputStream; import java.io.IOException; @@ -42,6 +41,7 @@ import java.util.regex.Pattern; import java.util.regex.Matcher; import java.util.spi.CurrencyNameProvider; +import sun.util.locale.provider.CalendarDataUtility; import sun.util.locale.provider.LocaleServiceProviderPool; import sun.util.logging.PlatformLogger; @@ -348,6 +348,13 @@ * until December 31, 2001, and the Euro from January 1, 2002, local time * of the respective countries. *

+ * If the specified {@code locale} contains "cu" and/or "rg" + * Unicode extensions, + * the instance returned from this method reflects + * the values specified with those extensions. If both "cu" and "rg" are + * specified, the currency from the "cu" extension supersedes the implicit one + * from the "rg" extension. + *

* The method returns null for territories that don't * have a currency, such as Antarctica. * @@ -361,12 +368,19 @@ * is not a supported ISO 3166 country code. */ public static Currency getInstance(Locale locale) { - String country = locale.getCountry(); - if (country == null) { - throw new NullPointerException(); + // check for locale overrides + String override = locale.getUnicodeLocaleType("cu"); + if (override != null) { + try { + return getInstance(override.toUpperCase(Locale.ROOT)); + } catch (IllegalArgumentException iae) { + // override currency is invalid. Fall through. + } } - if (country.length() != 2) { + String country = CalendarDataUtility.findRegionOverride(locale).getCountry(); + + if (country == null || !country.matches("^[a-zA-Z]{2}$")) { throw new IllegalArgumentException(); } @@ -482,6 +496,12 @@ * locale is the US, while for other locales it may be "US$". If no * symbol can be determined, the ISO 4217 currency code is returned. *

+ * If the default {@link Locale.Category#DISPLAY DISPLAY} locale + * contains "rg" (region override) + * Unicode extension, + * the symbol returned from this method reflects + * the value specified with that extension. + *

* This is equivalent to calling * {@link #getSymbol(Locale) * getSymbol(Locale.getDefault(Locale.Category.DISPLAY))}. @@ -498,6 +518,11 @@ * For example, for the US Dollar, the symbol is "$" if the specified * locale is the US, while for other locales it may be "US$". If no * symbol can be determined, the ISO 4217 currency code is returned. + *

+ * If the specified {@code locale} contains "rg" (region override) + * Unicode extension, + * the symbol returned from this method reflects + * the value specified with that extension. * * @param locale the locale for which a display name for this currency is * needed @@ -507,6 +532,7 @@ public String getSymbol(Locale locale) { LocaleServiceProviderPool pool = LocaleServiceProviderPool.getPool(CurrencyNameProvider.class); + locale = CalendarDataUtility.findRegionOverride(locale); String symbol = pool.getLocalizedObject( CurrencyNameGetter.INSTANCE, locale, currencyCode, SYMBOL); diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/EnumSet.java --- a/src/java.base/share/classes/java/util/EnumSet.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/EnumSet.java Thu Dec 14 12:28:32 2017 +0000 @@ -75,7 +75,6 @@ * @author Josh Bloch * @since 1.5 * @see EnumMap - * @serial exclude */ @SuppressWarnings("serial") // No serialVersionUID due to usage of // serial proxy pattern @@ -85,12 +84,12 @@ /** * The class of all the elements of this set. */ - final Class elementType; + final transient Class elementType; /** - * All of the values comprising T. (Cached for performance.) + * All of the values comprising E. (Cached for performance.) */ - final Enum[] universe; + final transient Enum[] universe; EnumSet(ClasselementType, Enum[] universe) { this.elementType = elementType; @@ -416,7 +415,7 @@ * * @serial include */ - private static class SerializationProxy > + private static class SerializationProxy> implements java.io.Serializable { @@ -441,10 +440,18 @@ elements = set.toArray(ZERO_LENGTH_ENUM_ARRAY); } - // instead of cast to E, we should perhaps use elementType.cast() - // to avoid injection of forged stream, but it will slow the implementation + /** + * Returns an {@code EnumSet} object with initial state + * held by this proxy. + * + * @return a {@code EnumSet} object with initial state + * held by this proxy + */ @SuppressWarnings("unchecked") private Object readResolve() { + // instead of cast to E, we should perhaps use elementType.cast() + // to avoid injection of forged stream, but it will slow the + // implementation EnumSet result = EnumSet.noneOf(elementType); for (Enum e : elements) result.add((E)e); @@ -454,13 +461,24 @@ private static final long serialVersionUID = 362491234563181265L; } + /** + * Returns a + * + * SerializationProxy + * representing the state of this instance. + * + * @return a {@link SerializationProxy} + * representing the state of this instance + */ Object writeReplace() { return new SerializationProxy<>(this); } - // readObject method for the serialization proxy pattern - // See Effective Java, Second Ed., Item 78. - private void readObject(java.io.ObjectInputStream stream) + /** + * @param s the stream + * @throws java.io.InvalidObjectException always + */ + private void readObject(java.io.ObjectInputStream s) throws java.io.InvalidObjectException { throw new java.io.InvalidObjectException("Proxy required"); } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/Formatter.java --- a/src/java.base/share/classes/java/util/Formatter.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/Formatter.java Thu Dec 14 12:28:32 2017 +0000 @@ -2137,6 +2137,39 @@ } /** + * Constructs a new formatter with the specified file name, charset, and + * locale. + * + * @param fileName + * The name of the file to use as the destination of this + * formatter. If the file exists then it will be truncated to + * zero size; otherwise, a new file will be created. The output + * will be written to the file and is buffered. + * + * @param charset + * A {@linkplain java.nio.charset.Charset charset} + * + * @param l + * The {@linkplain java.util.Locale locale} to apply during + * formatting. If {@code l} is {@code null} then no localization + * is applied. + * + * @throws IOException + * if an I/O error occurs while opening or creating the file + * + * @throws SecurityException + * If a security manager is present and {@link + * SecurityManager#checkWrite checkWrite(fileName)} denies write + * access to the file + * + * @throws NullPointerException + * if {@code fileName} or {@code charset} is {@code null}. + */ + public Formatter(String fileName, Charset charset, Locale l) throws IOException { + this(Objects.requireNonNull(charset, "charset"), l, new File(fileName)); + } + + /** * Constructs a new formatter with the specified file. * *

The charset used is the {@linkplain @@ -2248,6 +2281,40 @@ } /** + * Constructs a new formatter with the specified file, charset, and + * locale. + * + * @param file + * The file to use as the destination of this formatter. If the + * file exists then it will be truncated to zero size; otherwise, + * a new file will be created. The output will be written to the + * file and is buffered. + * + * @param charset + * A {@linkplain java.nio.charset.Charset charset} + * + * @param l + * The {@linkplain java.util.Locale locale} to apply during + * formatting. If {@code l} is {@code null} then no localization + * is applied. + * + * @throws IOException + * if an I/O error occurs while opening or creating the file + * + * @throws SecurityException + * If a security manager is present and {@link + * SecurityManager#checkWrite checkWrite(file.getPath())} denies + * write access to the file + * + * @throws NullPointerException + * if {@code file} or {@code charset} is {@code null}. + */ + public Formatter(File file, Charset charset, Locale l) throws IOException { + this(Objects.requireNonNull(charset, "charset"), l, file); + } + + + /** * Constructs a new formatter with the specified print stream. * *

The locale used is the {@linkplain @@ -2340,6 +2407,29 @@ this(l, new BufferedWriter(new OutputStreamWriter(os, csn))); } + /** + * Constructs a new formatter with the specified output stream, charset, + * and locale. + * + * @param os + * The output stream to use as the destination of this formatter. + * The output will be buffered. + * + * @param charset + * A {@linkplain java.nio.charset.Charset charset} + * + * @param l + * The {@linkplain java.util.Locale locale} to apply during + * formatting. If {@code l} is {@code null} then no localization + * is applied. + * + * @throws NullPointerException + * if {@code os} or {@code charset} is {@code null}. + */ + public Formatter(OutputStream os, Charset charset, Locale l) { + this(l, new BufferedWriter(new OutputStreamWriter(os, charset))); + } + private static char getZero(Locale l) { if ((l != null) && !l.equals(Locale.US)) { DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(l); diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/Locale.java --- a/src/java.base/share/classes/java/util/Locale.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/Locale.java Thu Dec 14 12:28:32 2017 +0000 @@ -48,6 +48,7 @@ import java.text.MessageFormat; import java.util.concurrent.ConcurrentHashMap; import java.util.spi.LocaleNameProvider; +import java.util.stream.Collectors; import sun.security.action.GetPropertyAction; import sun.util.locale.BaseLocale; @@ -62,6 +63,7 @@ import sun.util.locale.provider.LocaleProviderAdapter; import sun.util.locale.provider.LocaleResources; import sun.util.locale.provider.LocaleServiceProviderPool; +import sun.util.locale.provider.TimeZoneNameUtility; /** * A Locale object represents a specific geographical, political, @@ -665,10 +667,12 @@ /** * Display types for retrieving localized names from the name providers. */ - private static final int DISPLAY_LANGUAGE = 0; - private static final int DISPLAY_COUNTRY = 1; - private static final int DISPLAY_VARIANT = 2; - private static final int DISPLAY_SCRIPT = 3; + private static final int DISPLAY_LANGUAGE = 0; + private static final int DISPLAY_COUNTRY = 1; + private static final int DISPLAY_VARIANT = 2; + private static final int DISPLAY_SCRIPT = 3; + private static final int DISPLAY_UEXT_KEY = 4; + private static final int DISPLAY_UEXT_TYPE = 5; /** * Private constructor used by getInstance method @@ -942,11 +946,14 @@ variant = props.getProperty("user.variant", ""); } - return getInstance(language, script, country, variant, null); + return getInstance(language, script, country, variant, + getDefaultExtensions(props.getProperty("user.extensions", "")) + .orElse(null)); } private static Locale initDefault(Locale.Category category) { Properties props = GetPropertyAction.privilegedGetProperties(); + return getInstance( props.getProperty(category.languageKey, defaultLocale.getLanguage()), @@ -956,7 +963,22 @@ defaultLocale.getCountry()), props.getProperty(category.variantKey, defaultLocale.getVariant()), - null); + getDefaultExtensions(props.getProperty(category.extensionsKey, "")) + .orElse(defaultLocale.getLocaleExtensions())); + } + + private static Optional getDefaultExtensions(String extensionsProp) { + LocaleExtensions exts = null; + + try { + exts = new InternalLocaleBuilder() + .setExtensions(extensionsProp) + .getLocaleExtensions(); + } catch (LocaleSyntaxException e) { + // just ignore this incorrect property + } + + return Optional.ofNullable(exts); } /** @@ -1771,7 +1793,7 @@ * @exception NullPointerException if inLocale is null */ public String getDisplayLanguage(Locale inLocale) { - return getDisplayString(baseLocale.getLanguage(), inLocale, DISPLAY_LANGUAGE); + return getDisplayString(baseLocale.getLanguage(), null, inLocale, DISPLAY_LANGUAGE); } /** @@ -1801,7 +1823,7 @@ * @since 1.7 */ public String getDisplayScript(Locale inLocale) { - return getDisplayString(baseLocale.getScript(), inLocale, DISPLAY_SCRIPT); + return getDisplayString(baseLocale.getScript(), null, inLocale, DISPLAY_SCRIPT); } /** @@ -1844,29 +1866,24 @@ * @exception NullPointerException if inLocale is null */ public String getDisplayCountry(Locale inLocale) { - return getDisplayString(baseLocale.getRegion(), inLocale, DISPLAY_COUNTRY); + return getDisplayString(baseLocale.getRegion(), null, inLocale, DISPLAY_COUNTRY); } - private String getDisplayString(String code, Locale inLocale, int type) { - if (code.length() == 0) { + private String getDisplayString(String code, String cat, Locale inLocale, int type) { + Objects.requireNonNull(inLocale); + Objects.requireNonNull(code); + + if (code.isEmpty()) { return ""; } - if (inLocale == null) { - throw new NullPointerException(); - } - LocaleServiceProviderPool pool = LocaleServiceProviderPool.getPool(LocaleNameProvider.class); - String key = (type == DISPLAY_VARIANT ? "%%"+code : code); + String rbKey = (type == DISPLAY_VARIANT ? "%%"+code : code); String result = pool.getLocalizedObject( LocaleNameGetter.INSTANCE, - inLocale, key, type, code); - if (result != null) { - return result; - } - - return code; + inLocale, rbKey, type, code, cat); + return result != null ? result : code; } /** @@ -1894,29 +1911,31 @@ if (baseLocale.getVariant().length() == 0) return ""; - LocaleResources lr = LocaleProviderAdapter.forJRE().getLocaleResources(inLocale); + LocaleResources lr = LocaleProviderAdapter + .getResourceBundleBased() + .getLocaleResources(inLocale); String names[] = getDisplayVariantArray(inLocale); // Get the localized patterns for formatting a list, and use // them to format the list. return formatList(names, - lr.getLocaleName("ListPattern"), lr.getLocaleName("ListCompositionPattern")); } /** * Returns a name for the locale that is appropriate for display to the * user. This will be the values returned by getDisplayLanguage(), - * getDisplayScript(), getDisplayCountry(), and getDisplayVariant() assembled - * into a single string. The non-empty values are used in order, - * with the second and subsequent names in parentheses. For example: + * getDisplayScript(), getDisplayCountry(), getDisplayVariant() and + * optional Unicode extensions + * assembled into a single string. The non-empty values are used in order, with + * the second and subsequent names in parentheses. For example: *

- * language (script, country, variant)
- * language (country)
- * language (variant)
- * script (country)
- * country
+ * language (script, country, variant(, extension)*)
+ * language (country(, extension)*)
+ * language (variant(, extension)*)
+ * script (country(, extension)*)
+ * country (extension)*
*
* depending on which fields are specified in the locale. If the * language, script, country, and variant fields are all empty, @@ -1931,16 +1950,17 @@ /** * Returns a name for the locale that is appropriate for display * to the user. This will be the values returned by - * getDisplayLanguage(), getDisplayScript(),getDisplayCountry(), - * and getDisplayVariant() assembled into a single string. - * The non-empty values are used in order, - * with the second and subsequent names in parentheses. For example: + * getDisplayLanguage(), getDisplayScript(),getDisplayCountry() + * getDisplayVariant(), and optional + * Unicode extensions assembled into a single string. The non-empty + * values are used in order, with the second and subsequent names in + * parentheses. For example: *
- * language (script, country, variant)
- * language (country)
- * language (variant)
- * script (country)
- * country
+ * language (script, country, variant(, extension)*)
+ * language (country(, extension)*)
+ * language (variant(, extension)*)
+ * script (country(, extension)*)
+ * country (extension)*
*
* depending on which fields are specified in the locale. If the * language, script, country, and variant fields are all empty, @@ -1951,7 +1971,9 @@ * @throws NullPointerException if inLocale is null */ public String getDisplayName(Locale inLocale) { - LocaleResources lr = LocaleProviderAdapter.forJRE().getLocaleResources(inLocale); + LocaleResources lr = LocaleProviderAdapter + .getResourceBundleBased() + .getLocaleResources(inLocale); String languageName = getDisplayLanguage(inLocale); String scriptName = getDisplayScript(inLocale); @@ -1960,7 +1982,6 @@ // Get the localized patterns for formatting a display name. String displayNamePattern = lr.getLocaleName("DisplayNamePattern"); - String listPattern = lr.getLocaleName("ListPattern"); String listCompositionPattern = lr.getLocaleName("ListCompositionPattern"); // The display name consists of a main name, followed by qualifiers. @@ -1977,7 +1998,7 @@ if (variantNames.length == 0) { return ""; } else { - return formatList(variantNames, listPattern, listCompositionPattern); + return formatList(variantNames, listCompositionPattern); } } ArrayList names = new ArrayList<>(4); @@ -1994,6 +2015,16 @@ names.addAll(Arrays.asList(variantNames)); } + // add Unicode extensions + if (localeExtensions != null) { + localeExtensions.getUnicodeLocaleAttributes().stream() + .map(key -> getDisplayString(key, null, inLocale, DISPLAY_UEXT_KEY)) + .forEach(names::add); + localeExtensions.getUnicodeLocaleKeys().stream() + .map(key -> getDisplayKeyTypeExtensionString(key, lr, inLocale)) + .forEach(names::add); + } + // The first one in the main name mainName = names.get(0); @@ -2014,7 +2045,7 @@ // list case, but this is more efficient, and we want it to be // efficient since all the language-only locales will not have any // qualifiers. - qualifierNames.length != 0 ? formatList(qualifierNames, listPattern, listCompositionPattern) : null + qualifierNames.length != 0 ? formatList(qualifierNames, listCompositionPattern) : null }; if (displayNamePattern != null) { @@ -2121,74 +2152,78 @@ // For each variant token, lookup the display name. If // not found, use the variant name itself. for (int i=0; i 3) { - MessageFormat format = new MessageFormat(listCompositionPattern); - stringList = composeList(format, stringList); + if (pattern == null) { + return Arrays.stream(stringList).collect(Collectors.joining(",")); } - // Rebuild the argument list with the list length as the first element - Object[] args = new Object[stringList.length + 1]; - System.arraycopy(stringList, 0, args, 1, stringList.length); - args[0] = stringList.length; - - // Format it using the pattern in the resource - MessageFormat format = new MessageFormat(listPattern); - return format.format(args); - } - - /** - * Given a list of strings, return a list shortened to three elements. - * Shorten it by applying the given format to the first two elements - * recursively. - * @param format a format which takes two arguments - * @param list a list of strings - * @return if the list is three elements or shorter, the same list; - * otherwise, a new list of three elements. - */ - private static String[] composeList(MessageFormat format, String[] list) { - if (list.length <= 3) return list; - - // Use the given format to compose the first two elements into one - String[] listItems = { list[0], list[1] }; - String newItem = format.format(listItems); - - // Form a new list one element shorter - String[] newList = new String[list.length-1]; - System.arraycopy(list, 2, newList, 1, newList.length-1); - newList[0] = newItem; - - // Recurse - return composeList(format, newList); + switch (stringList.length) { + case 0: + return ""; + case 1: + return stringList[0]; + default: + return Arrays.stream(stringList).reduce("", + (s1, s2) -> { + if (s1.equals("")) { + return s2; + } + if (s2.equals("")) { + return s1; + } + return MessageFormat.format(pattern, s1, s2); + }); + } } // Duplicate of sun.util.locale.UnicodeLocaleExtension.isKey in order to @@ -2345,9 +2380,10 @@ Locale locale, String key, Object... params) { - assert params.length == 2; + assert params.length == 3; int type = (Integer)params[0]; String code = (String)params[1]; + String cat = (String)params[2]; switch(type) { case DISPLAY_LANGUAGE: @@ -2358,6 +2394,10 @@ return localeNameProvider.getDisplayVariant(code, locale); case DISPLAY_SCRIPT: return localeNameProvider.getDisplayScript(code, locale); + case DISPLAY_UEXT_KEY: + return localeNameProvider.getDisplayUnicodeExtensionKey(code, locale); + case DISPLAY_UEXT_TYPE: + return localeNameProvider.getDisplayUnicodeExtensionType(code, cat, locale); default: assert false; // shouldn't happen } @@ -2384,7 +2424,8 @@ DISPLAY("user.language.display", "user.script.display", "user.country.display", - "user.variant.display"), + "user.variant.display", + "user.extensions.display"), /** * Category used to represent the default locale for @@ -2393,19 +2434,23 @@ FORMAT("user.language.format", "user.script.format", "user.country.format", - "user.variant.format"); + "user.variant.format", + "user.extensions.format"); - Category(String languageKey, String scriptKey, String countryKey, String variantKey) { + Category(String languageKey, String scriptKey, String countryKey, + String variantKey, String extensionsKey) { this.languageKey = languageKey; this.scriptKey = scriptKey; this.countryKey = countryKey; this.variantKey = variantKey; + this.extensionsKey = extensionsKey; } final String languageKey; final String scriptKey; final String countryKey; final String variantKey; + final String extensionsKey; } /** diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/Optional.java --- a/src/java.base/share/classes/java/util/Optional.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/Optional.java Thu Dec 14 12:28:32 2017 +0000 @@ -32,8 +32,9 @@ /** * A container object which may or may not contain a non-{@code null} value. - * If a value is present, {@code isPresent()} returns {@code true} and - * {@code get()} returns the value. + * If a value is present, {@code isPresent()} returns {@code true}. If no + * value is present, the object is considered empty and + * {@code isPresent()} returns {@code false}. * *

Additional methods that depend on the presence or absence of a contained * value are provided, such as {@link #orElse(Object) orElse()} @@ -137,14 +138,10 @@ * {@code NoSuchElementException}. * * @apiNote - * The methods {@link #orElse(Object) orElse} and - * {@link #orElseGet(Supplier) orElseGet} - * are generally preferable to this method, as they return a substitute - * value if the value is absent, instead of throwing an exception. + * The preferred alternative to this method is {@link #orElseThrow()}. * * @return the non-{@code null} value described by this {@code Optional} * @throws NoSuchElementException if no value is present - * @see Optional#isPresent() */ public T get() { if (value == null) { @@ -362,6 +359,21 @@ } /** + * If a value is present, returns the value, otherwise throws + * {@code NoSuchElementException}. + * + * @return the non-{@code null} value described by this {@code Optional} + * @throws NoSuchElementException if no value is present + * @since 10 + */ + public T orElseThrow() { + if (value == null) { + throw new NoSuchElementException("No value present"); + } + return value; + } + + /** * If a value is present, returns the value, otherwise throws an exception * produced by the exception supplying function. * diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/OptionalDouble.java --- a/src/java.base/share/classes/java/util/OptionalDouble.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/OptionalDouble.java Thu Dec 14 12:28:32 2017 +0000 @@ -30,9 +30,10 @@ import java.util.stream.DoubleStream; /** - * A container object which may or may not contain a {@code double} value. If a - * value is present, {@code isPresent()} returns {@code true} and - * {@code getAsDouble()} returns the value. + * A container object which may or may not contain a {@code double} value. + * If a value is present, {@code isPresent()} returns {@code true}. If no + * value is present, the object is considered empty and + * {@code isPresent()} returns {@code false}. * *

Additional methods that depend on the presence or absence of a contained * value are provided, such as {@link #orElse(double) orElse()} @@ -117,14 +118,10 @@ * {@code NoSuchElementException}. * * @apiNote - * The methods {@link #orElse(double) orElse} and - * {@link #orElseGet(DoubleSupplier) orElseGet} - * are generally preferable to this method, as they return a substitute - * value if the value is absent, instead of throwing an exception. + * The preferred alternative to this method is {@link #orElseThrow()}. * * @return the value described by this {@code OptionalDouble} * @throws NoSuchElementException if no value is present - * @see OptionalDouble#isPresent() */ public double getAsDouble() { if (!isPresent) { @@ -226,6 +223,21 @@ } /** + * If a value is present, returns the value, otherwise throws + * {@code NoSuchElementException}. + * + * @return the value described by this {@code OptionalDouble} + * @throws NoSuchElementException if no value is present + * @since 10 + */ + public double orElseThrow() { + if (!isPresent) { + throw new NoSuchElementException("No value present"); + } + return value; + } + + /** * If a value is present, returns the value, otherwise throws an exception * produced by the exception supplying function. * diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/OptionalInt.java --- a/src/java.base/share/classes/java/util/OptionalInt.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/OptionalInt.java Thu Dec 14 12:28:32 2017 +0000 @@ -30,9 +30,10 @@ import java.util.stream.IntStream; /** - * A container object which may or may not contain an {@code int} value. If a - * value is present, {@code isPresent()} returns {@code true} and - * {@code getAsInt()} returns the value. + * A container object which may or may not contain an {@code int} value. + * If a value is present, {@code isPresent()} returns {@code true}. If no + * value is present, the object is considered empty and + * {@code isPresent()} returns {@code false}. * *

Additional methods that depend on the presence or absence of a contained * value are provided, such as {@link #orElse(int) orElse()} @@ -117,14 +118,10 @@ * {@code NoSuchElementException}. * * @apiNote - * The methods {@link #orElse(int) orElse} and - * {@link #orElseGet(IntSupplier) orElseGet} - * are generally preferable to this method, as they return a substitute - * value if the value is absent, instead of throwing an exception. + * The preferred alternative to this method is {@link #orElseThrow()}. * * @return the value described by this {@code OptionalInt} * @throws NoSuchElementException if no value is present - * @see OptionalInt#isPresent() */ public int getAsInt() { if (!isPresent) { @@ -225,6 +222,21 @@ } /** + * If a value is present, returns the value, otherwise throws + * {@code NoSuchElementException}. + * + * @return the value described by this {@code OptionalInt} + * @throws NoSuchElementException if no value is present + * @since 10 + */ + public int orElseThrow() { + if (!isPresent) { + throw new NoSuchElementException("No value present"); + } + return value; + } + + /** * If a value is present, returns the value, otherwise throws an exception * produced by the exception supplying function. * diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/OptionalLong.java --- a/src/java.base/share/classes/java/util/OptionalLong.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/OptionalLong.java Thu Dec 14 12:28:32 2017 +0000 @@ -30,9 +30,10 @@ import java.util.stream.LongStream; /** - * A container object which may or may not contain a {@code long} value. If a - * value is present, {@code isPresent()} returns {@code true} and - * {@code getAsLong()} returns the value. + * A container object which may or may not contain a {@code long} value. + * If a value is present, {@code isPresent()} returns {@code true}. If no + * value is present, the object is considered empty and + * {@code isPresent()} returns {@code false}. * *

Additional methods that depend on the presence or absence of a contained * value are provided, such as {@link #orElse(long) orElse()} @@ -117,14 +118,10 @@ * {@code NoSuchElementException}. * * @apiNote - * The methods {@link #orElse(long) orElse} and - * {@link #orElseGet(LongSupplier) orElseGet} - * are generally preferable to this method, as they return a substitute - * value if the value is absent, instead of throwing an exception. + * The preferred alternative to this method is {@link #orElseThrow()}. * * @return the value described by this {@code OptionalLong} * @throws NoSuchElementException if no value is present - * @see OptionalLong#isPresent() */ public long getAsLong() { if (!isPresent) { @@ -225,6 +222,21 @@ } /** + * If a value is present, returns the value, otherwise throws + * {@code NoSuchElementException}. + * + * @return the value described by this {@code OptionalLong} + * @throws NoSuchElementException if no value is present + * @since 10 + */ + public long orElseThrow() { + if (!isPresent) { + throw new NoSuchElementException("No value present"); + } + return value; + } + + /** * If a value is present, returns the value, otherwise throws an exception * produced by the exception supplying function. * diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/Properties.java --- a/src/java.base/share/classes/java/util/Properties.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/Properties.java Thu Dec 14 12:28:32 2017 +0000 @@ -37,6 +37,10 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.StreamCorruptedException; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.nio.charset.IllegalCharsetNameException; +import java.nio.charset.UnsupportedCharsetException; import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiConsumer; import java.util.function.BiFunction; @@ -997,6 +1001,11 @@ * *

The specified stream remains open after this method returns. * + *

This method behaves the same as + * {@linkplain #storeToXML(OutputStream os, String comment, Charset charset)} + * except that it will {@linkplain java.nio.charset.Charset#forName look up the charset} + * using the given encoding name. + * * @param os the output stream on which to emit the XML document. * @param comment a description of the property list, or {@code null} * if no comment is desired. @@ -1011,20 +1020,67 @@ * @throws NullPointerException if {@code os} is {@code null}, * or if {@code encoding} is {@code null}. * @throws ClassCastException if this {@code Properties} object - * contains any keys or values that are not - * {@code Strings}. + * contains any keys or values that are not {@code Strings}. * @see #loadFromXML(InputStream) * @see Character * Encoding in Entities * @since 1.5 */ public void storeToXML(OutputStream os, String comment, String encoding) - throws IOException - { + throws IOException { Objects.requireNonNull(os); Objects.requireNonNull(encoding); + + try { + Charset charset = Charset.forName(encoding); + storeToXML(os, comment, charset); + } catch (IllegalCharsetNameException | UnsupportedCharsetException e) { + throw new UnsupportedEncodingException(encoding); + } + } + + /** + * Emits an XML document representing all of the properties contained + * in this table, using the specified encoding. + * + *

The XML document will have the following DOCTYPE declaration: + *

+     * <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
+     * 
+ * + *

If the specified comment is {@code null} then no comment + * will be stored in the document. + * + *

An implementation is required to support writing of XML documents + * that use the "{@code UTF-8}" or "{@code UTF-16}" encoding. An + * implementation may support additional encodings. + * + *

Unmappable characters for the specified charset will be encoded as + * numeric character references. + * + *

The specified stream remains open after this method returns. + * + * @param os the output stream on which to emit the XML document. + * @param comment a description of the property list, or {@code null} + * if no comment is desired. + * @param charset the charset + * + * @throws IOException if writing to the specified output stream + * results in an {@code IOException}. + * @throws NullPointerException if {@code os} or {@code charset} is {@code null}. + * @throws ClassCastException if this {@code Properties} object + * contains any keys or values that are not {@code Strings}. + * @see #loadFromXML(InputStream) + * @see Character + * Encoding in Entities + * @since 10 + */ + public void storeToXML(OutputStream os, String comment, Charset charset) + throws IOException { + Objects.requireNonNull(os, "OutputStream"); + Objects.requireNonNull(charset, "Charset"); PropertiesDefaultHandler handler = new PropertiesDefaultHandler(); - handler.store(this, os, comment, encoding); + handler.store(this, os, comment, charset); } /** diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/Scanner.java --- a/src/java.base/share/classes/java/util/Scanner.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/Scanner.java Thu Dec 14 12:28:32 2017 +0000 @@ -33,10 +33,13 @@ import java.nio.file.Path; import java.nio.file.Files; import java.text.*; +import java.text.spi.NumberFormatProvider; import java.util.function.Consumer; import java.util.regex.*; import java.util.stream.Stream; import java.util.stream.StreamSupport; +import sun.util.locale.provider.LocaleProviderAdapter; +import sun.util.locale.provider.ResourceBundleBasedAdapter; /** * A simple text scanner which can parse primitive types and strings using @@ -575,7 +578,21 @@ * does not exist */ public Scanner(InputStream source, String charsetName) { - this(makeReadable(Objects.requireNonNull(source, "source"), toCharset(charsetName)), + this(source, toCharset(charsetName)); + } + + /** + * Constructs a new {@code Scanner} that produces values scanned + * from the specified input stream. Bytes from the stream are converted + * into characters using the specified charset. + * + * @param source an input stream to be scanned + * @param charset the charset used to convert bytes from the file + * into characters to be scanned + * @since 10 + */ + public Scanner(InputStream source, Charset charset) { + this(makeReadable(Objects.requireNonNull(source, "source"), charset), WHITESPACE_PATTERN); } @@ -594,7 +611,18 @@ } } + /* + * This method is added so that null-check on charset can be performed before + * creating InputStream as an existing test required it. + */ + private static Readable makeReadable(Path source, Charset charset) + throws IOException { + Objects.requireNonNull(charset, "charset"); + return makeReadable(Files.newInputStream(source), charset); + } + private static Readable makeReadable(InputStream source, Charset charset) { + Objects.requireNonNull(charset, "charset"); return new InputStreamReader(source, charset); } @@ -629,6 +657,22 @@ this(Objects.requireNonNull(source), toDecoder(charsetName)); } + /** + * Constructs a new {@code Scanner} that produces values scanned + * from the specified file. Bytes from the file are converted into + * characters using the specified charset. + * + * @param source A file to be scanned + * @param charset The charset used to convert bytes from the file + * into characters to be scanned + * @throws IOException + * if an I/O error occurs opening the source + * @since 10 + */ + public Scanner(File source, Charset charset) throws IOException { + this(Objects.requireNonNull(source), charset.newDecoder()); + } + private Scanner(File source, CharsetDecoder dec) throws FileNotFoundException { @@ -649,6 +693,12 @@ return Channels.newReader(source, dec, -1); } + private static Readable makeReadable(ReadableByteChannel source, + Charset charset) { + Objects.requireNonNull(charset, "charset"); + return Channels.newReader(source, charset); + } + /** * Constructs a new {@code Scanner} that produces values scanned * from the specified file. Bytes from the file are converted into @@ -688,8 +738,22 @@ this(Objects.requireNonNull(source), toCharset(charsetName)); } - private Scanner(Path source, Charset charset) throws IOException { - this(makeReadable(Files.newInputStream(source), charset)); + /** + * Constructs a new {@code Scanner} that produces values scanned + * from the specified file. Bytes from the file are converted into + * characters using the specified charset. + * + * @param source + * the path to the file to be scanned + * @param charset + * the charset used to convert bytes from the file + * into characters to be scanned + * @throws IOException + * if an I/O error occurs opening the source + * @since 10 + */ + public Scanner(Path source, Charset charset) throws IOException { + this(makeReadable(source, charset)); } /** @@ -735,6 +799,21 @@ WHITESPACE_PATTERN); } + /** + * Constructs a new {@code Scanner} that produces values scanned + * from the specified channel. Bytes from the source are converted into + * characters using the specified charset. + * + * @param source a channel to scan + * @param charset the encoding type used to convert bytes from the + * channel into characters to be scanned + * @since 10 + */ + public Scanner(ReadableByteChannel source, Charset charset) { + this(makeReadable(Objects.requireNonNull(source, "source"), charset), + WHITESPACE_PATTERN); + } + // Private primitives used to support scanning private void saveState() { @@ -1186,9 +1265,27 @@ modCount++; this.locale = locale; - DecimalFormat df = - (DecimalFormat)NumberFormat.getNumberInstance(locale); + + DecimalFormat df = null; + NumberFormat nf = NumberFormat.getNumberInstance(locale); DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(locale); + if (nf instanceof DecimalFormat) { + df = (DecimalFormat) nf; + } else { + + // In case where NumberFormat.getNumberInstance() returns + // other instance (non DecimalFormat) based on the provider + // used and java.text.spi.NumberFormatProvider implementations, + // DecimalFormat constructor is used to obtain the instance + LocaleProviderAdapter adapter = LocaleProviderAdapter + .getAdapter(NumberFormatProvider.class, locale); + if (!(adapter instanceof ResourceBundleBasedAdapter)) { + adapter = LocaleProviderAdapter.getResourceBundleBased(); + } + String[] all = adapter.getLocaleResources(locale) + .getNumberPatterns(); + df = new DecimalFormat(all[0], dfs); + } // These must be literalized to avoid collision with regex // metacharacters such as dot or parenthesis diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/SimpleTimeZone.java --- a/src/java.base/share/classes/java/util/SimpleTimeZone.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/SimpleTimeZone.java Thu Dec 14 12:28:32 2017 +0000 @@ -548,12 +548,11 @@ computeOffset: if (useDaylight) { - synchronized (this) { - if (cacheStart != 0) { - if (date >= cacheStart && date < cacheEnd) { - offset += dstSavings; - break computeOffset; - } + Cache cache = this.cache; + if (cache != null) { + if (date >= cache.start && date < cache.end) { + offset += dstSavings; + break computeOffset; } } BaseCalendar cal = date >= GregorianCalendar.DEFAULT_GREGORIAN_CUTOVER ? @@ -671,14 +670,13 @@ } private int getOffset(BaseCalendar cal, BaseCalendar.Date cdate, int year, long time) { - synchronized (this) { - if (cacheStart != 0) { - if (time >= cacheStart && time < cacheEnd) { - return rawOffset + dstSavings; - } - if (year == cacheYear) { - return rawOffset; - } + Cache cache = this.cache; + if (cache != null) { + if (time >= cache.start && time < cache.end) { + return rawOffset + dstSavings; + } + if (year == cache.year) { + return rawOffset; } } @@ -689,11 +687,7 @@ if (time >= start && time < end) { offset += dstSavings; } - synchronized (this) { - cacheYear = year; - cacheStart = start; - cacheEnd = end; - } + this.cache = new Cache(year, start, end); } else { if (time < end) { // TODO: support Gregorian cutover. The previous year @@ -711,12 +705,7 @@ } } if (start <= end) { - synchronized (this) { - // The start and end transitions are in multiple years. - cacheYear = (long) startYear - 1; - cacheStart = start; - cacheEnd = end; - } + this.cache = new Cache((long) startYear - 1, start, end); } } return offset; @@ -876,7 +865,7 @@ * Generates the hash code for the SimpleDateFormat object. * @return the hash code for this object */ - public synchronized int hashCode() + public int hashCode() { return startMonth ^ startDay ^ startDayOfWeek ^ startTime ^ endMonth ^ endDay ^ endDayOfWeek ^ endTime ^ rawOffset; @@ -1201,19 +1190,27 @@ /** * Cache values representing a single period of daylight saving - * time. When the cache values are valid, cacheStart is the start - * time (inclusive) of daylight saving time and cacheEnd is the - * end time (exclusive). + * time. Cache.start is the start time (inclusive) of daylight + * saving time and Cache.end is the end time (exclusive). * - * cacheYear has a year value if both cacheStart and cacheEnd are - * in the same year. cacheYear is set to startYear - 1 if - * cacheStart and cacheEnd are in different years. cacheStart is 0 - * if the cache values are void. cacheYear is a long to support - * Integer.MIN_VALUE - 1 (JCK requirement). + * Cache.year has a year value if both Cache.start and Cache.end are + * in the same year. Cache.year is set to startYear - 1 if + * Cache.start and Cache.end are in different years. + * Cache.year is a long to support Integer.MIN_VALUE - 1 (JCK requirement). */ - private transient long cacheYear; - private transient long cacheStart; - private transient long cacheEnd; + private static final class Cache { + final long year; + final long start; + final long end; + + Cache(long year, long start, long end) { + this.year = year; + this.start = start; + this.end = end; + } + } + + private transient volatile Cache cache; /** * Constants specifying values of startMode and endMode. @@ -1282,9 +1279,8 @@ // Maximum number of rules. private static final int MAX_RULE_NUM = 6; - private synchronized void invalidateCache() { - cacheYear = startYear - 1; - cacheStart = cacheEnd = 0; + private void invalidateCache() { + cache = null; } //---------------------------------------------------------------------- diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/concurrent/CountedCompleter.java --- a/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java Thu Dec 14 12:28:32 2017 +0000 @@ -735,7 +735,7 @@ CountedCompleter a = this, s = a; while (a.onExceptionalCompletion(ex, s) && (a = (s = a).completer) != null && a.status >= 0 && - a.recordExceptionalCompletion(ex) == EXCEPTIONAL) + isExceptionalStatus(a.recordExceptionalCompletion(ex))) ; } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java --- a/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java Thu Dec 14 12:28:32 2017 +0000 @@ -219,52 +219,59 @@ * methods in a way that flows well in javadocs. */ - /* + /** * The status field holds run control status bits packed into a - * single int to minimize footprint and to ensure atomicity (via - * CAS). Status is initially zero, and takes on nonnegative - * values until completed, upon which status (anded with - * DONE_MASK) holds value NORMAL, CANCELLED, or EXCEPTIONAL. Tasks - * undergoing blocking waits by other threads have the SIGNAL bit - * set. Completion of a stolen task with SIGNAL set awakens any - * waiters via notifyAll. Even though suboptimal for some - * purposes, we use basic builtin wait/notify to take advantage of - * "monitor inflation" in JVMs that we would otherwise need to - * emulate to avoid adding further per-task bookkeeping overhead. - * We want these monitors to be "fat", i.e., not use biasing or - * thin-lock techniques, so use some odd coding idioms that tend - * to avoid them, mainly by arranging that every synchronized - * block performs a wait, notifyAll or both. + * single int to ensure atomicity. Status is initially zero, and + * takes on nonnegative values until completed, upon which it + * holds (sign bit) DONE, possibly with ABNORMAL (cancelled or + * exceptional) and THROWN (in which case an exception has been + * stored). Tasks with dependent blocked waiting joiners have the + * SIGNAL bit set. Completion of a task with SIGNAL set awakens + * any waiters via notifyAll. (Waiters also help signal others + * upon completion.) * * These control bits occupy only (some of) the upper half (16 * bits) of status field. The lower bits are used for user-defined * tags. */ + volatile int status; // accessed directly by pool and workers - /** The run status of this task */ - volatile int status; // accessed directly by pool and workers - static final int DONE_MASK = 0xf0000000; // mask out non-completion bits - static final int NORMAL = 0xf0000000; // must be negative - static final int CANCELLED = 0xc0000000; // must be < NORMAL - static final int EXCEPTIONAL = 0x80000000; // must be < CANCELLED - static final int SIGNAL = 0x00010000; // must be >= 1 << 16 - static final int SMASK = 0x0000ffff; // short bits for tags + private static final int DONE = 1 << 31; // must be negative + private static final int ABNORMAL = 1 << 18; // set atomically with DONE + private static final int THROWN = 1 << 17; // set atomically with ABNORMAL + private static final int SIGNAL = 1 << 16; // true if joiner waiting + private static final int SMASK = 0xffff; // short bits for tags + + static boolean isExceptionalStatus(int s) { // needed by subclasses + return (s & THROWN) != 0; + } /** - * Marks completion and wakes up threads waiting to join this - * task. + * Sets DONE status and wakes up threads waiting to join this task. * - * @param completion one of NORMAL, CANCELLED, EXCEPTIONAL - * @return completion status on exit + * @return status on exit */ - private int setCompletion(int completion) { - for (int s;;) { + private int setDone() { + int s; + if (((s = (int)STATUS.getAndBitwiseOr(this, DONE)) & SIGNAL) != 0) + synchronized (this) { notifyAll(); } + return s | DONE; + } + + /** + * Marks cancelled or exceptional completion unless already done. + * + * @param completion must be DONE | ABNORMAL, ORed with THROWN if exceptional + * @return status on exit + */ + private int abnormalCompletion(int completion) { + for (int s, ns;;) { if ((s = status) < 0) return s; - if (STATUS.compareAndSet(this, s, s | completion)) { - if ((s >>> 16) != 0) + else if (STATUS.weakCompareAndSet(this, s, ns = s | completion)) { + if ((s & SIGNAL) != 0) synchronized (this) { notifyAll(); } - return completion; + return ns; } } } @@ -282,10 +289,11 @@ try { completed = exec(); } catch (Throwable rex) { - return setExceptionalCompletion(rex); + completed = false; + s = setExceptionalCompletion(rex); } if (completed) - s = setCompletion(NORMAL); + s = setDone(); } return s; } @@ -297,9 +305,7 @@ * @param timeout using Object.wait conventions. */ final void internalWait(long timeout) { - int s; - if ((s = status) >= 0 && // force completer to issue notify - STATUS.compareAndSet(this, s, s | SIGNAL)) { + if ((int)STATUS.getAndBitwiseOr(this, SIGNAL) >= 0) { synchronized (this) { if (status >= 0) try { wait(timeout); } catch (InterruptedException ie) { } @@ -314,27 +320,24 @@ * @return status upon completion */ private int externalAwaitDone() { - int s = ((this instanceof CountedCompleter) ? // try helping - ForkJoinPool.common.externalHelpComplete( - (CountedCompleter)this, 0) : - ForkJoinPool.common.tryExternalUnpush(this) ? doExec() : 0); - if (s >= 0 && (s = status) >= 0) { + int s = tryExternalHelp(); + if (s >= 0 && (s = (int)STATUS.getAndBitwiseOr(this, SIGNAL)) >= 0) { boolean interrupted = false; - do { - if (STATUS.compareAndSet(this, s, s | SIGNAL)) { - synchronized (this) { - if (status >= 0) { - try { - wait(0L); - } catch (InterruptedException ie) { - interrupted = true; - } + synchronized (this) { + for (;;) { + if ((s = status) >= 0) { + try { + wait(0L); + } catch (InterruptedException ie) { + interrupted = true; } - else - notifyAll(); + } + else { + notifyAll(); + break; } } - } while ((s = status) >= 0); + } if (interrupted) Thread.currentThread().interrupt(); } @@ -345,30 +348,40 @@ * Blocks a non-worker-thread until completion or interruption. */ private int externalInterruptibleAwaitDone() throws InterruptedException { - int s; - if (Thread.interrupted()) - throw new InterruptedException(); - if ((s = status) >= 0 && - (s = ((this instanceof CountedCompleter) ? - ForkJoinPool.common.externalHelpComplete( - (CountedCompleter)this, 0) : - ForkJoinPool.common.tryExternalUnpush(this) ? doExec() : - 0)) >= 0) { - while ((s = status) >= 0) { - if (STATUS.compareAndSet(this, s, s | SIGNAL)) { - synchronized (this) { - if (status >= 0) - wait(0L); - else - notifyAll(); + int s = tryExternalHelp(); + if (s >= 0 && (s = (int)STATUS.getAndBitwiseOr(this, SIGNAL)) >= 0) { + synchronized (this) { + for (;;) { + if ((s = status) >= 0) + wait(0L); + else { + notifyAll(); + break; } } } } + else if (Thread.interrupted()) + throw new InterruptedException(); return s; } /** + * Tries to help with tasks allowed for external callers. + * + * @return current status + */ + private int tryExternalHelp() { + int s; + return ((s = status) < 0 ? s: + (this instanceof CountedCompleter) ? + ForkJoinPool.common.externalHelpComplete( + (CountedCompleter)this, 0) : + ForkJoinPool.common.tryExternalUnpush(this) ? + doExec() : 0); + } + + /** * Implementation for join, get, quietlyJoin. Directly handles * only cases of already-completed, external wait, and * unfork+exec. Others are relayed to ForkJoinPool.awaitJoin. @@ -475,7 +488,7 @@ } finally { lock.unlock(); } - s = setCompletion(EXCEPTIONAL); + s = abnormalCompletion(DONE | ABNORMAL | THROWN); } return s; } @@ -487,7 +500,7 @@ */ private int setExceptionalCompletion(Throwable ex) { int s = recordExceptionalCompletion(ex); - if ((s & DONE_MASK) == EXCEPTIONAL) + if ((s & THROWN) != 0) internalPropagateException(ex); return s; } @@ -662,10 +675,8 @@ * Throws exception, if any, associated with the given status. */ private void reportException(int s) { - if (s == CANCELLED) - throw new CancellationException(); - if (s == EXCEPTIONAL) - rethrow(getThrowableException()); + rethrow((s & THROWN) != 0 ? getThrowableException() : + new CancellationException()); } // public methods @@ -707,7 +718,7 @@ */ public final V join() { int s; - if ((s = doJoin() & DONE_MASK) != NORMAL) + if (((s = doJoin()) & ABNORMAL) != 0) reportException(s); return getRawResult(); } @@ -722,7 +733,7 @@ */ public final V invoke() { int s; - if ((s = doInvoke() & DONE_MASK) != NORMAL) + if (((s = doInvoke()) & ABNORMAL) != 0) reportException(s); return getRawResult(); } @@ -747,9 +758,9 @@ public static void invokeAll(ForkJoinTask t1, ForkJoinTask t2) { int s1, s2; t2.fork(); - if ((s1 = t1.doInvoke() & DONE_MASK) != NORMAL) + if (((s1 = t1.doInvoke()) & ABNORMAL) != 0) t1.reportException(s1); - if ((s2 = t2.doJoin() & DONE_MASK) != NORMAL) + if (((s2 = t2.doJoin()) & ABNORMAL) != 0) t2.reportException(s2); } @@ -779,7 +790,7 @@ } else if (i != 0) t.fork(); - else if (t.doInvoke() < NORMAL && ex == null) + else if ((t.doInvoke() & ABNORMAL) != 0 && ex == null) ex = t.getException(); } for (int i = 1; i <= last; ++i) { @@ -787,7 +798,7 @@ if (t != null) { if (ex != null) t.cancel(false); - else if (t.doJoin() < NORMAL) + else if ((t.doJoin() & ABNORMAL) != 0) ex = t.getException(); } } @@ -831,7 +842,7 @@ } else if (i != 0) t.fork(); - else if (t.doInvoke() < NORMAL && ex == null) + else if ((t.doInvoke() & ABNORMAL) != 0 && ex == null) ex = t.getException(); } for (int i = 1; i <= last; ++i) { @@ -839,7 +850,7 @@ if (t != null) { if (ex != null) t.cancel(false); - else if (t.doJoin() < NORMAL) + else if ((t.doJoin() & ABNORMAL) != 0) ex = t.getException(); } } @@ -876,7 +887,8 @@ * @return {@code true} if this task is now cancelled */ public boolean cancel(boolean mayInterruptIfRunning) { - return (setCompletion(CANCELLED) & DONE_MASK) == CANCELLED; + int s = abnormalCompletion(DONE | ABNORMAL); + return (s & (ABNORMAL | THROWN)) == ABNORMAL; } public final boolean isDone() { @@ -884,7 +896,7 @@ } public final boolean isCancelled() { - return (status & DONE_MASK) == CANCELLED; + return (status & (ABNORMAL | THROWN)) == ABNORMAL; } /** @@ -893,7 +905,7 @@ * @return {@code true} if this task threw an exception or was cancelled */ public final boolean isCompletedAbnormally() { - return status < NORMAL; + return (status & ABNORMAL) != 0; } /** @@ -904,7 +916,7 @@ * exception and was not cancelled */ public final boolean isCompletedNormally() { - return (status & DONE_MASK) == NORMAL; + return (status & (DONE | ABNORMAL)) == DONE; } /** @@ -915,9 +927,9 @@ * @return the exception, or {@code null} if none */ public final Throwable getException() { - int s = status & DONE_MASK; - return ((s >= NORMAL) ? null : - (s == CANCELLED) ? new CancellationException() : + int s = status; + return ((s & ABNORMAL) == 0 ? null : + (s & THROWN) == 0 ? new CancellationException() : getThrowableException()); } @@ -961,7 +973,7 @@ setExceptionalCompletion(rex); return; } - setCompletion(NORMAL); + setDone(); } /** @@ -973,7 +985,7 @@ * @since 1.8 */ public final void quietlyComplete() { - setCompletion(NORMAL); + setDone(); } /** @@ -990,11 +1002,12 @@ public final V get() throws InterruptedException, ExecutionException { int s = (Thread.currentThread() instanceof ForkJoinWorkerThread) ? doJoin() : externalInterruptibleAwaitDone(); - if ((s &= DONE_MASK) == CANCELLED) + if ((s & THROWN) != 0) + throw new ExecutionException(getThrowableException()); + else if ((s & ABNORMAL) != 0) throw new CancellationException(); - if (s == EXCEPTIONAL) - throw new ExecutionException(getThrowableException()); - return getRawResult(); + else + return getRawResult(); } /** @@ -1034,7 +1047,7 @@ while ((s = status) >= 0 && (ns = deadline - System.nanoTime()) > 0L) { if ((ms = TimeUnit.NANOSECONDS.toMillis(ns)) > 0L && - STATUS.compareAndSet(this, s, s | SIGNAL)) { + (s = (int)STATUS.getAndBitwiseOr(this, SIGNAL)) >= 0) { synchronized (this) { if (status >= 0) wait(ms); // OK to throw InterruptedException @@ -1046,15 +1059,13 @@ } } if (s >= 0) - s = status; - if ((s &= DONE_MASK) != NORMAL) { - if (s == CANCELLED) - throw new CancellationException(); - if (s != EXCEPTIONAL) - throw new TimeoutException(); + throw new TimeoutException(); + else if ((s & THROWN) != 0) throw new ExecutionException(getThrowableException()); - } - return getRawResult(); + else if ((s & ABNORMAL) != 0) + throw new CancellationException(); + else + return getRawResult(); } /** @@ -1110,7 +1121,7 @@ * setRawResult(null)}. */ public void reinitialize() { - if ((status & DONE_MASK) == EXCEPTIONAL) + if ((status & THROWN) != 0) clearExceptionalCompletion(); else status = 0; @@ -1327,8 +1338,8 @@ */ public final short setForkJoinTaskTag(short newValue) { for (int s;;) { - if (STATUS.compareAndSet(this, s = status, - (s & ~SMASK) | (newValue & SMASK))) + if (STATUS.weakCompareAndSet(this, s = status, + (s & ~SMASK) | (newValue & SMASK))) return (short)s; } } @@ -1351,8 +1362,8 @@ for (int s;;) { if ((short)(s = status) != expect) return false; - if (STATUS.compareAndSet(this, s, - (s & ~SMASK) | (update & SMASK))) + if (STATUS.weakCompareAndSet(this, s, + (s & ~SMASK) | (update & SMASK))) return true; } } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java --- a/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java Thu Dec 14 12:28:32 2017 +0000 @@ -1252,18 +1252,20 @@ head = h += taken; d = subtractDemand(taken); } - else if ((empty = (t == h)) && (c & COMPLETE) != 0) { - closeOnComplete(s); // end of stream - break; - } else if ((d = demand) == 0L && (c & REQS) != 0) weakCasCtl(c, c & ~REQS); // exhausted demand else if (d != 0L && (c & REQS) == 0) weakCasCtl(c, c | REQS); // new demand - else if (t == (t = tail) && (empty || d == 0L)) { - int bit = ((c & ACTIVE) != 0) ? ACTIVE : RUN; - if (weakCasCtl(c, c & ~bit) && bit == RUN) - break; // un-keep-alive or exit + else if (t == (t = tail)) { // stability check + if ((empty = (t == h)) && (c & COMPLETE) != 0) { + closeOnComplete(s); // end of stream + break; + } + else if (empty || d == 0L) { + int bit = ((c & ACTIVE) != 0) ? ACTIVE : RUN; + if (weakCasCtl(c, c & ~bit) && bit == RUN) + break; // un-keep-alive or exit + } } } } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java --- a/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java Thu Dec 14 12:28:32 2017 +0000 @@ -105,20 +105,20 @@ * @param x the value */ public void accumulate(double x) { - Cell[] as; long b, v, r; int m; Cell a; - if ((as = cells) != null + Cell[] cs; long b, v, r; int m; Cell c; + if ((cs = cells) != null || ((r = doubleToRawLongBits (function.applyAsDouble(longBitsToDouble(b = base), x))) != b && !casBase(b, r))) { boolean uncontended = true; - if (as == null - || (m = as.length - 1) < 0 - || (a = as[getProbe() & m]) == null + if (cs == null + || (m = cs.length - 1) < 0 + || (c = cs[getProbe() & m]) == null || !(uncontended = ((r = doubleToRawLongBits (function.applyAsDouble - (longBitsToDouble(v = a.value), x))) == v) - || a.cas(v, r))) + (longBitsToDouble(v = c.value), x))) == v) + || c.cas(v, r))) doubleAccumulate(x, function, uncontended); } } @@ -133,13 +133,13 @@ * @return the current value */ public double get() { - Cell[] as = cells; + Cell[] cs = cells; double result = longBitsToDouble(base); - if (as != null) { - for (Cell a : as) - if (a != null) + if (cs != null) { + for (Cell c : cs) + if (c != null) result = function.applyAsDouble - (result, longBitsToDouble(a.value)); + (result, longBitsToDouble(c.value)); } return result; } @@ -153,12 +153,12 @@ * updating. */ public void reset() { - Cell[] as = cells; + Cell[] cs = cells; base = identity; - if (as != null) { - for (Cell a : as) - if (a != null) - a.reset(identity); + if (cs != null) { + for (Cell c : cs) + if (c != null) + c.reset(identity); } } @@ -173,14 +173,12 @@ * @return the value before reset */ public double getThenReset() { - Cell[] as = cells; - double result = longBitsToDouble(base); - base = identity; - if (as != null) { - for (Cell a : as) { - if (a != null) { - double v = longBitsToDouble(a.value); - a.reset(identity); + Cell[] cs = cells; + double result = longBitsToDouble(getAndSetBase(identity)); + if (cs != null) { + for (Cell c : cs) { + if (c != null) { + double v = longBitsToDouble(c.getAndSet(identity)); result = function.applyAsDouble(result, v); } } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/concurrent/atomic/DoubleAdder.java --- a/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAdder.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAdder.java Thu Dec 14 12:28:32 2017 +0000 @@ -87,15 +87,15 @@ * @param x the value to add */ public void add(double x) { - Cell[] as; long b, v; int m; Cell a; - if ((as = cells) != null || + Cell[] cs; long b, v; int m; Cell c; + if ((cs = cells) != null || !casBase(b = base, Double.doubleToRawLongBits (Double.longBitsToDouble(b) + x))) { boolean uncontended = true; - if (as == null || (m = as.length - 1) < 0 || - (a = as[getProbe() & m]) == null || - !(uncontended = a.cas(v = a.value, + if (cs == null || (m = cs.length - 1) < 0 || + (c = cs[getProbe() & m]) == null || + !(uncontended = c.cas(v = c.value, Double.doubleToRawLongBits (Double.longBitsToDouble(v) + x)))) doubleAccumulate(x, null, uncontended); @@ -115,12 +115,12 @@ * @return the sum */ public double sum() { - Cell[] as = cells; + Cell[] cs = cells; double sum = Double.longBitsToDouble(base); - if (as != null) { - for (Cell a : as) - if (a != null) - sum += Double.longBitsToDouble(a.value); + if (cs != null) { + for (Cell c : cs) + if (c != null) + sum += Double.longBitsToDouble(c.value); } return sum; } @@ -133,12 +133,12 @@ * known that no threads are concurrently updating. */ public void reset() { - Cell[] as = cells; + Cell[] cs = cells; base = 0L; // relies on fact that double 0 must have same rep as long - if (as != null) { - for (Cell a : as) - if (a != null) - a.reset(); + if (cs != null) { + for (Cell c : cs) + if (c != null) + c.reset(); } } @@ -153,16 +153,12 @@ * @return the sum */ public double sumThenReset() { - Cell[] as = cells; - double sum = Double.longBitsToDouble(base); - base = 0L; - if (as != null) { - for (Cell a : as) { - if (a != null) { - long v = a.value; - a.reset(); - sum += Double.longBitsToDouble(v); - } + Cell[] cs = cells; + double sum = Double.longBitsToDouble(getAndSetBase(0L)); + if (cs != null) { + for (Cell c : cs) { + if (c != null) + sum += Double.longBitsToDouble(c.getAndSet(0L)); } } return sum; diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java --- a/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java Thu Dec 14 12:28:32 2017 +0000 @@ -103,17 +103,17 @@ * @param x the value */ public void accumulate(long x) { - Cell[] as; long b, v, r; int m; Cell a; - if ((as = cells) != null + Cell[] cs; long b, v, r; int m; Cell c; + if ((cs = cells) != null || ((r = function.applyAsLong(b = base, x)) != b && !casBase(b, r))) { boolean uncontended = true; - if (as == null - || (m = as.length - 1) < 0 - || (a = as[getProbe() & m]) == null + if (cs == null + || (m = cs.length - 1) < 0 + || (c = cs[getProbe() & m]) == null || !(uncontended = - (r = function.applyAsLong(v = a.value, x)) == v - || a.cas(v, r))) + (r = function.applyAsLong(v = c.value, x)) == v + || c.cas(v, r))) longAccumulate(x, function, uncontended); } } @@ -128,12 +128,12 @@ * @return the current value */ public long get() { - Cell[] as = cells; + Cell[] cs = cells; long result = base; - if (as != null) { - for (Cell a : as) - if (a != null) - result = function.applyAsLong(result, a.value); + if (cs != null) { + for (Cell c : cs) + if (c != null) + result = function.applyAsLong(result, c.value); } return result; } @@ -147,12 +147,12 @@ * updating. */ public void reset() { - Cell[] as = cells; + Cell[] cs = cells; base = identity; - if (as != null) { - for (Cell a : as) - if (a != null) - a.reset(identity); + if (cs != null) { + for (Cell c : cs) + if (c != null) + c.reset(identity); } } @@ -167,14 +167,12 @@ * @return the value before reset */ public long getThenReset() { - Cell[] as = cells; - long result = base; - base = identity; - if (as != null) { - for (Cell a : as) { - if (a != null) { - long v = a.value; - a.reset(identity); + Cell[] cs = cells; + long result = getAndSetBase(identity); + if (cs != null) { + for (Cell c : cs) { + if (c != null) { + long v = c.getAndSet(identity); result = function.applyAsLong(result, v); } } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/concurrent/atomic/LongAdder.java --- a/src/java.base/share/classes/java/util/concurrent/atomic/LongAdder.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/concurrent/atomic/LongAdder.java Thu Dec 14 12:28:32 2017 +0000 @@ -83,12 +83,12 @@ * @param x the value to add */ public void add(long x) { - Cell[] as; long b, v; int m; Cell a; - if ((as = cells) != null || !casBase(b = base, b + x)) { + Cell[] cs; long b, v; int m; Cell c; + if ((cs = cells) != null || !casBase(b = base, b + x)) { boolean uncontended = true; - if (as == null || (m = as.length - 1) < 0 || - (a = as[getProbe() & m]) == null || - !(uncontended = a.cas(v = a.value, v + x))) + if (cs == null || (m = cs.length - 1) < 0 || + (c = cs[getProbe() & m]) == null || + !(uncontended = c.cas(v = c.value, v + x))) longAccumulate(x, null, uncontended); } } @@ -117,12 +117,12 @@ * @return the sum */ public long sum() { - Cell[] as = cells; + Cell[] cs = cells; long sum = base; - if (as != null) { - for (Cell a : as) - if (a != null) - sum += a.value; + if (cs != null) { + for (Cell c : cs) + if (c != null) + sum += c.value; } return sum; } @@ -135,12 +135,12 @@ * known that no threads are concurrently updating. */ public void reset() { - Cell[] as = cells; + Cell[] cs = cells; base = 0L; - if (as != null) { - for (Cell a : as) - if (a != null) - a.reset(); + if (cs != null) { + for (Cell c : cs) + if (c != null) + c.reset(); } } @@ -155,15 +155,12 @@ * @return the sum */ public long sumThenReset() { - Cell[] as = cells; - long sum = base; - base = 0L; - if (as != null) { - for (Cell a : as) { - if (a != null) { - sum += a.value; - a.reset(); - } + Cell[] cs = cells; + long sum = getAndSetBase(0L); + if (cs != null) { + for (Cell c : cs) { + if (c != null) + sum += c.getAndSet(0L); } } return sum; diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java --- a/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java Thu Dec 14 12:28:32 2017 +0000 @@ -133,6 +133,9 @@ final void reset(long identity) { VALUE.setVolatile(this, identity); } + final long getAndSet(long val) { + return (long)VALUE.getAndSet(this, val); + } // VarHandle mechanics private static final VarHandle VALUE; @@ -178,6 +181,10 @@ return BASE.compareAndSet(this, cmp, val); } + final long getAndSetBase(long val) { + return (long)BASE.getAndSet(this, val); + } + /** * CASes the cellsBusy field from 0 to 1 to acquire lock. */ @@ -228,9 +235,9 @@ } boolean collide = false; // True if last slot nonempty done: for (;;) { - Cell[] as; Cell a; int n; long v; - if ((as = cells) != null && (n = as.length) > 0) { - if ((a = as[(n - 1) & h]) == null) { + Cell[] cs; Cell c; int n; long v; + if ((cs = cells) != null && (n = cs.length) > 0) { + if ((c = cs[(n - 1) & h]) == null) { if (cellsBusy == 0) { // Try to attach new Cell Cell r = new Cell(x); // Optimistically create if (cellsBusy == 0 && casCellsBusy()) { @@ -252,17 +259,17 @@ } else if (!wasUncontended) // CAS already known to fail wasUncontended = true; // Continue after rehash - else if (a.cas(v = a.value, + else if (c.cas(v = c.value, (fn == null) ? v + x : fn.applyAsLong(v, x))) break; - else if (n >= NCPU || cells != as) + else if (n >= NCPU || cells != cs) collide = false; // At max size or stale else if (!collide) collide = true; else if (cellsBusy == 0 && casCellsBusy()) { try { - if (cells == as) // Expand table unless stale - cells = Arrays.copyOf(as, n << 1); + if (cells == cs) // Expand table unless stale + cells = Arrays.copyOf(cs, n << 1); } finally { cellsBusy = 0; } @@ -271,9 +278,9 @@ } h = advanceProbe(h); } - else if (cellsBusy == 0 && cells == as && casCellsBusy()) { + else if (cellsBusy == 0 && cells == cs && casCellsBusy()) { try { // Initialize table - if (cells == as) { + if (cells == cs) { Cell[] rs = new Cell[2]; rs[h & 1] = new Cell(x); cells = rs; @@ -312,9 +319,9 @@ } boolean collide = false; // True if last slot nonempty done: for (;;) { - Cell[] as; Cell a; int n; long v; - if ((as = cells) != null && (n = as.length) > 0) { - if ((a = as[(n - 1) & h]) == null) { + Cell[] cs; Cell c; int n; long v; + if ((cs = cells) != null && (n = cs.length) > 0) { + if ((c = cs[(n - 1) & h]) == null) { if (cellsBusy == 0) { // Try to attach new Cell Cell r = new Cell(Double.doubleToRawLongBits(x)); if (cellsBusy == 0 && casCellsBusy()) { @@ -336,16 +343,16 @@ } else if (!wasUncontended) // CAS already known to fail wasUncontended = true; // Continue after rehash - else if (a.cas(v = a.value, apply(fn, v, x))) + else if (c.cas(v = c.value, apply(fn, v, x))) break; - else if (n >= NCPU || cells != as) + else if (n >= NCPU || cells != cs) collide = false; // At max size or stale else if (!collide) collide = true; else if (cellsBusy == 0 && casCellsBusy()) { try { - if (cells == as) // Expand table unless stale - cells = Arrays.copyOf(as, n << 1); + if (cells == cs) // Expand table unless stale + cells = Arrays.copyOf(cs, n << 1); } finally { cellsBusy = 0; } @@ -354,9 +361,9 @@ } h = advanceProbe(h); } - else if (cellsBusy == 0 && cells == as && casCellsBusy()) { + else if (cellsBusy == 0 && cells == cs && casCellsBusy()) { try { // Initialize table - if (cells == as) { + if (cells == cs) { Cell[] rs = new Cell[2]; rs[h & 1] = new Cell(Double.doubleToRawLongBits(x)); cells = rs; diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/jar/JarFile.java --- a/src/java.base/share/classes/java/util/jar/JarFile.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/jar/JarFile.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -112,9 +112,9 @@ *

  • * {@code jdk.util.jar.version} can be assigned a value that is the * {@code String} representation of a non-negative integer - * {@code <= Runtime.version().major()}. The value is used to set the effective + * {@code <= Runtime.version().feature()}. The value is used to set the effective * runtime version to something other than the default value obtained by - * evaluating {@code Runtime.version().major()}. The effective runtime version + * evaluating {@code Runtime.version().feature()}. The effective runtime version * is the version that the {@link JarFile#JarFile(File, boolean, int, Runtime.Version)} * constructor uses when the value of the last argument is * {@code JarFile.runtimeVersion()}. @@ -143,7 +143,7 @@ public class JarFile extends ZipFile { private final static Runtime.Version BASE_VERSION; - private final static int BASE_VERSION_MAJOR; + private final static int BASE_VERSION_FEATURE; private final static Runtime.Version RUNTIME_VERSION; private final static boolean MULTI_RELEASE_ENABLED; private final static boolean MULTI_RELEASE_FORCED; @@ -153,7 +153,7 @@ private boolean jvInitialized; private boolean verify; private final Runtime.Version version; // current version - private final int versionMajor; // version.major() + private final int versionFeature; // version.feature() private boolean isMultiRelease; // is jar multi-release? // indicates if Class-Path attribute present @@ -170,14 +170,14 @@ JUZFA = jdk.internal.misc.SharedSecrets.getJavaUtilZipFileAccess(); // multi-release jar file versions >= 9 BASE_VERSION = Runtime.Version.parse(Integer.toString(8)); - BASE_VERSION_MAJOR = BASE_VERSION.major(); + BASE_VERSION_FEATURE = BASE_VERSION.feature(); String jarVersion = GetPropertyAction.privilegedGetProperty("jdk.util.jar.version"); - int runtimeVersion = Runtime.version().major(); + int runtimeVersion = Runtime.version().feature(); if (jarVersion != null) { int jarVer = Integer.parseInt(jarVersion); runtimeVersion = (jarVer > runtimeVersion) ? runtimeVersion - : Math.max(jarVer, BASE_VERSION_MAJOR); + : Math.max(jarVer, BASE_VERSION_FEATURE); } RUNTIME_VERSION = Runtime.Version.parse(Integer.toString(runtimeVersion)); String enableMultiRelease = GetPropertyAction @@ -224,10 +224,10 @@ * Returns the version that represents the effective runtime versioned * configuration of a multi-release jar file. *

    - * By default the major version number of the returned {@code Version} will - * be equal to the major version number of {@code Runtime.version()}. + * By default the feature version number of the returned {@code Version} will + * be equal to the feature version number of {@code Runtime.version()}. * However, if the {@code jdk.util.jar.version} property is set, the - * returned {@code Version} is derived from that property and major version + * returned {@code Version} is derived from that property and feature version * numbers may not be equal. * * @return the version that represents the runtime versioned configuration @@ -322,7 +322,7 @@ *

    * The canonical form derived from the version parameter is * {@code Runtime.Version.parse(Integer.toString(n))} where {@code n} is - * {@code Math.max(version.major(), JarFile.baseVersion().major())}. + * {@code Math.max(version.feature(), JarFile.baseVersion().feature())}. * * @param file the jar file to be opened for reading * @param verify whether or not to verify the jar file if @@ -341,17 +341,17 @@ super(file, mode); this.verify = verify; Objects.requireNonNull(version); - if (MULTI_RELEASE_FORCED || version.major() == RUNTIME_VERSION.major()) { + if (MULTI_RELEASE_FORCED || version.feature() == RUNTIME_VERSION.feature()) { // This deals with the common case where the value from JarFile.runtimeVersion() is passed this.version = RUNTIME_VERSION; - } else if (version.major() <= BASE_VERSION_MAJOR) { + } else if (version.feature() <= BASE_VERSION_FEATURE) { // This also deals with the common case where the value from JarFile.baseVersion() is passed this.version = BASE_VERSION; } else { // Canonicalize - this.version = Runtime.Version.parse(Integer.toString(version.major())); + this.version = Runtime.Version.parse(Integer.toString(version.feature())); } - this.versionMajor = this.version.major(); + this.versionFeature = this.version.feature(); } /** @@ -579,7 +579,7 @@ // filter out dir META-INF/versions/ and META-INF/versions/*/ // and any entry with version > 'version' if (index == -1 || index == (name.length() - 1) || - Integer.parseInt(name, off, index, 10) > versionMajor) { + Integer.parseInt(name, off, index, 10) > versionFeature) { return null; } } catch (NumberFormatException x) { @@ -592,11 +592,11 @@ } private JarEntry getVersionedEntry(String name, JarEntry je) { - if (BASE_VERSION_MAJOR < versionMajor) { + if (BASE_VERSION_FEATURE < versionFeature) { if (!name.startsWith(META_INF)) { // search for versioned entry - int v = versionMajor; - while (v > BASE_VERSION_MAJOR) { + int v = versionFeature; + while (v > BASE_VERSION_FEATURE) { JarFileEntry vje = getEntry0(META_INF_VERSIONS + v + "/" + name); if (vje != null) { return vje.withBasename(name); @@ -673,7 +673,7 @@ } JarFileEntry realEntry() { - if (isMultiRelease() && versionMajor != BASE_VERSION_MAJOR) { + if (isMultiRelease() && versionFeature != BASE_VERSION_FEATURE) { String entryName = super.getName(); return entryName == basename || entryName.equals(basename) ? this : new JarFileEntry(entryName, this); diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/spi/LocaleNameProvider.java --- a/src/java.base/share/classes/java/util/spi/LocaleNameProvider.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/spi/LocaleNameProvider.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package java.util.spi; import java.util.Locale; +import java.util.Objects; /** * An abstract class for service providers that @@ -141,4 +142,54 @@ * @see java.util.Locale#getDisplayVariant(java.util.Locale) */ public abstract String getDisplayVariant(String variant, Locale locale); + + /** + * Returns a localized name for the given + * Unicode extension key, + * and the given locale that is appropriate for display to the user. + * If the name returned cannot be localized according to {@code locale}, + * this method returns null. + * @implSpec the default implementation returns {@code null}. + * @param key the Unicode Extension key, not null. + * @param locale the desired locale, not null. + * @return the name of the given key string for the specified locale, + * or null if it's not available. + * @exception NullPointerException if {@code key} or {@code locale} is null + * @exception IllegalArgumentException if {@code locale} isn't + * one of the locales returned from + * {@link java.util.spi.LocaleServiceProvider#getAvailableLocales() + * getAvailableLocales()}. + * @since 10 + */ + public String getDisplayUnicodeExtensionKey(String key, Locale locale) { + Objects.requireNonNull(key); + Objects.requireNonNull(locale); + return null; + } + + /** + * Returns a localized name for the given + * Unicode extension type, + * and the given locale that is appropriate for display to the user. + * If the name returned cannot be localized according to {@code locale}, + * this method returns null. + * @implSpec the default implementation returns {@code null}. + * @param type the Unicode Extension type, not null. + * @param key the Unicode Extension key for this {@code type}, not null. + * @param locale the desired locale, not null. + * @return the name of the given type string for the specified locale, + * or null if it's not available. + * @exception NullPointerException if {@code key}, {@code type} or {@code locale} is null + * @exception IllegalArgumentException if {@code locale} isn't + * one of the locales returned from + * {@link java.util.spi.LocaleServiceProvider#getAvailableLocales() + * getAvailableLocales()}. + * @since 10 + */ + public String getDisplayUnicodeExtensionType(String type, String key, Locale locale) { + Objects.requireNonNull(type); + Objects.requireNonNull(key); + Objects.requireNonNull(locale); + return null; + } } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/zip/Deflater.java --- a/src/java.base/share/classes/java/util/zip/Deflater.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/zip/Deflater.java Thu Dec 14 12:28:32 2017 +0000 @@ -67,12 +67,26 @@ * } *

  • * + * @apiNote + * To release resources used by this {@code Deflater}, the {@link #end()} method + * should be called explicitly. Subclasses are responsible for the cleanup of resources + * acquired by the subclass. Subclasses that override {@link #finalize()} in order + * to perform cleanup should be modified to use alternative cleanup mechanisms such + * as {@link java.lang.ref.Cleaner} and remove the overriding {@code finalize} method. + * + * @implSpec + * If this {@code Deflater} has been subclassed and the {@code end} method has been + * overridden, the {@code end} method will be called by the finalization when the + * deflater is unreachable. But the subclasses should not depend on this specific + * implementation; the finalization is not reliable and the {@code finalize} method + * is deprecated to be removed. + * * @see Inflater * @author David Connelly * @since 1.1 */ -public -class Deflater { + +public class Deflater { private final ZStreamRef zsRef; private byte[] buf = new byte[0]; @@ -169,7 +183,9 @@ public Deflater(int level, boolean nowrap) { this.level = level; this.strategy = DEFAULT_STRATEGY; - this.zsRef = new ZStreamRef(init(level, DEFAULT_STRATEGY, nowrap)); + this.zsRef = ZStreamRef.get(this, + () -> init(level, DEFAULT_STRATEGY, nowrap), + Deflater::end); } /** @@ -534,38 +550,32 @@ /** * Closes the compressor and discards any unprocessed input. + * * This method should be called when the compressor is no longer - * being used, but will also be called automatically by the - * finalize() method. Once this method is called, the behavior - * of the Deflater object is undefined. + * being used. Once this method is called, the behavior of the + * Deflater object is undefined. */ public void end() { synchronized (zsRef) { - long addr = zsRef.address(); - zsRef.clear(); - if (addr != 0) { - end(addr); - buf = null; - } + zsRef.clean(); + buf = null; } } /** * Closes the compressor when garbage is collected. * - * @deprecated The {@code finalize} method has been deprecated. - * Subclasses that override {@code finalize} in order to perform cleanup - * should be modified to use alternative cleanup mechanisms and - * to remove the overriding {@code finalize} method. - * When overriding the {@code finalize} method, its implementation must explicitly - * ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}. - * See the specification for {@link Object#finalize()} for further - * information about migration options. + * @deprecated The {@code finalize} method has been deprecated and will be + * removed. It is implemented as a no-op. Subclasses that override + * {@code finalize} in order to perform cleanup should be modified to use + * alternative cleanup mechanisms and to remove the overriding {@code finalize} + * method. The recommended cleanup for compressor is to explicitly call + * {@code end} method when it is no longer in use. If the {@code end} is + * not invoked explicitly the resource of the compressor will be released + * when the instance becomes unreachable. */ - @Deprecated(since="9") - protected void finalize() { - end(); - } + @Deprecated(since="9", forRemoval=true) + protected void finalize() {} private void ensureOpen() { assert Thread.holdsLock(zsRef); diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/zip/Inflater.java --- a/src/java.base/share/classes/java/util/zip/Inflater.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/zip/Inflater.java Thu Dec 14 12:28:32 2017 +0000 @@ -66,13 +66,27 @@ * } * * + * @apiNote + * To release resources used by this {@code Inflater}, the {@link #end()} method + * should be called explicitly. Subclasses are responsible for the cleanup of resources + * acquired by the subclass. Subclasses that override {@link #finalize()} in order + * to perform cleanup should be modified to use alternative cleanup mechanisms such + * as {@link java.lang.ref.Cleaner} and remove the overriding {@code finalize} method. + * + * @implSpec + * If this {@code Inflater} has been subclassed and the {@code end} method has been + * overridden, the {@code end} method will be called by the finalization when the + * inflater is unreachable. But the subclasses should not depend on this specific + * implementation; the finalization is not reliable and the {@code finalize} method + * is deprecated to be removed. + * * @see Deflater * @author David Connelly * @since 1.1 * */ -public -class Inflater { + +public class Inflater { private final ZStreamRef zsRef; private byte[] buf = defaultBuf; @@ -101,7 +115,7 @@ * @param nowrap if true then support GZIP compatible compression */ public Inflater(boolean nowrap) { - zsRef = new ZStreamRef(init(nowrap)); + this.zsRef = ZStreamRef.get(this, () -> init(nowrap), Inflater::end); } /** @@ -361,38 +375,37 @@ /** * Closes the decompressor and discards any unprocessed input. + * * This method should be called when the decompressor is no longer - * being used, but will also be called automatically by the finalize() - * method. Once this method is called, the behavior of the Inflater - * object is undefined. + * being used. Once this method is called, the behavior of the + * Inflater object is undefined. */ public void end() { synchronized (zsRef) { - long addr = zsRef.address(); - zsRef.clear(); - if (addr != 0) { - end(addr); - buf = null; - } + zsRef.clean(); + buf = null; } } /** * Closes the decompressor when garbage is collected. * - * @deprecated The {@code finalize} method has been deprecated. - * Subclasses that override {@code finalize} in order to perform cleanup - * should be modified to use alternative cleanup mechanisms and - * to remove the overriding {@code finalize} method. - * When overriding the {@code finalize} method, its implementation must explicitly - * ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}. - * See the specification for {@link Object#finalize()} for further - * information about migration options. + * @implSpec + * If this {@code Inflater} has been subclassed and the {@code end} method + * has been overridden, the {@code end} method will be called when the + * inflater is unreachable. + * + * @deprecated The {@code finalize} method has been deprecated and will be + * removed. It is implemented as a no-op. Subclasses that override + * {@code finalize} in order to perform cleanup should be modified to use + * alternative cleanup mechanisms and remove the overriding {@code finalize} + * method. The recommended cleanup for compressor is to explicitly call + * {@code end} method when it is no longer in use. If the {@code end} is + * not invoked explicitly the resource of the compressor will be released + * when the instance becomes unreachable, */ - @Deprecated(since="9") - protected void finalize() { - end(); - } + @Deprecated(since="9", forRemoval=true) + protected void finalize() {} private void ensureOpen () { assert Thread.holdsLock(zsRef); diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/zip/ZStreamRef.java --- a/src/java.base/share/classes/java/util/zip/ZStreamRef.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/zip/ZStreamRef.java Thu Dec 14 12:28:32 2017 +0000 @@ -25,22 +25,89 @@ package java.util.zip; -/** - * A reference to the native zlib's z_stream structure. - */ +import java.util.function.LongConsumer; +import java.util.function.LongSupplier; +import java.lang.ref.Cleaner.Cleanable; +import jdk.internal.ref.CleanerFactory; -class ZStreamRef { +/** + * A reference to the native zlib's z_stream structure. It also + * serves as the "cleaner" to clean up the native resource when + * the deflater or infalter is ended, closed or cleaned. + */ +class ZStreamRef implements Runnable { - private volatile long address; - ZStreamRef (long address) { - this.address = address; + private LongConsumer end; + private long address; + private final Cleanable cleanable; + + private ZStreamRef (Object owner, LongSupplier addr, LongConsumer end) { + this.cleanable = CleanerFactory.cleaner().register(owner, this); + this.end = end; + this.address = addr.getAsLong(); } long address() { return address; } - void clear() { + void clean() { + cleanable.clean(); + } + + public synchronized void run() { + long addr = address; address = 0; + if (addr != 0) { + end.accept(addr); + } + } + + private ZStreamRef (LongSupplier addr, LongConsumer end) { + this.cleanable = null; + this.end = end; + this.address = addr.getAsLong(); + } + + /* + * If {@code Inflater/Deflater} has been subclassed and the {@code end} method + * is overridden, uses {@code finalizer} mechanism for resource cleanup. So + * {@code end} method can be called when the {@code Inflater/Deflater} is + * unreachable. This mechanism will be removed when the {@code finalize} method + * is removed from {@code Inflater/Deflater}. + */ + static ZStreamRef get(Object owner, LongSupplier addr, LongConsumer end) { + Class clz = owner.getClass(); + while (clz != Deflater.class && clz != Inflater.class) { + try { + clz.getDeclaredMethod("end"); + return new FinalizableZStreamRef(owner, addr, end); + } catch (NoSuchMethodException nsme) {} + clz = clz.getSuperclass(); + } + return new ZStreamRef(owner, addr, end); + } + + private static class FinalizableZStreamRef extends ZStreamRef { + final Object owner; + + FinalizableZStreamRef (Object owner, LongSupplier addr, LongConsumer end) { + super(addr, end); + this.owner = owner; + } + + @Override + void clean() { + run(); + } + + @Override + @SuppressWarnings("deprecation") + protected void finalize() { + if (owner instanceof Inflater) + ((Inflater)owner).end(); + else + ((Deflater)owner).end(); + } } } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/zip/ZipCoder.java --- a/src/java.base/share/classes/java/util/zip/ZipCoder.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/zip/ZipCoder.java Thu Dec 14 12:28:32 2017 +0000 @@ -28,72 +28,60 @@ import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; -import java.nio.charset.CoderResult; +import java.nio.charset.CharacterCodingException; import java.nio.charset.CodingErrorAction; -import java.util.Arrays; -import sun.nio.cs.ArrayDecoder; -import sun.nio.cs.ArrayEncoder; + +import static java.nio.charset.StandardCharsets.UTF_8; /** * Utility class for zipfile name and comment decoding and encoding */ -final class ZipCoder { +class ZipCoder { + + private static final jdk.internal.misc.JavaLangAccess JLA = + jdk.internal.misc.SharedSecrets.getJavaLangAccess(); + + static final class UTF8 extends ZipCoder { + + UTF8(Charset utf8) { + super(utf8); + } - private static boolean isASCII(byte[] ba, int off, int len) { - for (int i = off; i < off + len; i++) { - if (ba[i] < 0) - return false; + @Override + boolean isUTF8() { + return true; } - return true; + + @Override + String toString(byte[] ba, int off, int length) { + return JLA.newStringUTF8NoRepl(ba, off, length); + } + + @Override + byte[] getBytes(String s) { + return JLA.getBytesUTF8NoRepl(s); + } } - private static boolean hasReplaceChar(byte[] ba) { - for (int i = 0; i < ba.length; i++) { - if (ba[i] == (byte)'?') - return true; - } - return false; + // UTF_8.ArrayEn/Decoder is stateless, so make it singleton. + private static ZipCoder utf8 = new UTF8(UTF_8); + + public static ZipCoder get(Charset charset) { + if (charset == UTF_8) + return utf8; + return new ZipCoder(charset); } String toString(byte[] ba, int off, int length) { - - // fastpath for UTF-8 cs and ascii only name, leverage the - // compact string impl to avoid the unnecessary char[] copy/ - // paste. A temporary workaround before we have better approach, - // such as a String constructor that throws exception for - // malformed and/or unmappable characters, instead of silently - // replacing with repl char - if (isUTF8 && isASCII(ba, off, length)) { - return new String(ba, off, length, cs); - } + try { + return decoder().decode(ByteBuffer.wrap(ba, off, length)).toString(); - CharsetDecoder cd = decoder().reset(); - int len = (int)(length * cd.maxCharsPerByte()); - char[] ca = new char[len]; - if (len == 0) - return new String(ca); - // UTF-8 only for now. Other ArrayDeocder only handles - // CodingErrorAction.REPLACE mode. ZipCoder uses - // REPORT mode. - if (isUTF8 && cd instanceof ArrayDecoder) { - int clen = ((ArrayDecoder)cd).decode(ba, off, length, ca); - if (clen == -1) // malformed - throw new IllegalArgumentException("MALFORMED"); - return new String(ca, 0, clen); + } catch (CharacterCodingException x) { + throw new IllegalArgumentException(x); } - ByteBuffer bb = ByteBuffer.wrap(ba, off, length); - CharBuffer cb = CharBuffer.wrap(ca); - CoderResult cr = cd.decode(bb, cb, true); - if (!cr.isUnderflow()) - throw new IllegalArgumentException(cr.toString()); - cr = cd.flush(cb); - if (!cr.isUnderflow()) - throw new IllegalArgumentException(cr.toString()); - return new String(ca, 0, cb.position()); } String toString(byte[] ba, int length) { @@ -105,84 +93,47 @@ } byte[] getBytes(String s) { - if (isUTF8) { - // fastpath for UTF8. should only occur when the string - // has malformed surrogates. A postscan should still be - // faster and use less memory. - byte[] ba = s.getBytes(cs); - if (!hasReplaceChar(ba)) { - return ba; + try { + ByteBuffer bb = encoder().encode(CharBuffer.wrap(s)); + int pos = bb.position(); + int limit = bb.limit(); + if (bb.hasArray() && pos == 0 && limit == bb.capacity()) { + return bb.array(); } + byte[] bytes = new byte[bb.limit() - bb.position()]; + bb.get(bytes); + return bytes; + } catch (CharacterCodingException x) { + throw new IllegalArgumentException(x); } - CharsetEncoder ce = encoder().reset(); - char[] ca = s.toCharArray(); - int len = (int)(ca.length * ce.maxBytesPerChar()); - byte[] ba = new byte[len]; - if (len == 0) - return ba; - // UTF-8 only for now. Other ArrayDeocder only handles - // CodingErrorAction.REPLACE mode. - if (isUTF8 && ce instanceof ArrayEncoder) { - int blen = ((ArrayEncoder)ce).encode(ca, 0, ca.length, ba); - if (blen == -1) // malformed - throw new IllegalArgumentException("MALFORMED"); - return Arrays.copyOf(ba, blen); - } - ByteBuffer bb = ByteBuffer.wrap(ba); - CharBuffer cb = CharBuffer.wrap(ca); - CoderResult cr = ce.encode(cb, bb, true); - if (!cr.isUnderflow()) - throw new IllegalArgumentException(cr.toString()); - cr = ce.flush(bb); - if (!cr.isUnderflow()) - throw new IllegalArgumentException(cr.toString()); - if (bb.position() == ba.length) // defensive copy? - return ba; - else - return Arrays.copyOf(ba, bb.position()); } // assume invoked only if "this" is not utf8 byte[] getBytesUTF8(String s) { - if (isUTF8) - return getBytes(s); - if (utf8 == null) - utf8 = new ZipCoder(StandardCharsets.UTF_8); return utf8.getBytes(s); } String toStringUTF8(byte[] ba, int len) { - return toStringUTF8(ba, 0, len); + return utf8.toString(ba, 0, len); } String toStringUTF8(byte[] ba, int off, int len) { - if (isUTF8) - return toString(ba, off, len); - if (utf8 == null) - utf8 = new ZipCoder(StandardCharsets.UTF_8); return utf8.toString(ba, off, len); } boolean isUTF8() { - return isUTF8; + return false; } private Charset cs; private CharsetDecoder dec; private CharsetEncoder enc; - private boolean isUTF8; - private ZipCoder utf8; private ZipCoder(Charset cs) { this.cs = cs; - this.isUTF8 = cs.name().equals(StandardCharsets.UTF_8.name()); } - static ZipCoder get(Charset charset) { - return new ZipCoder(charset); - } - - private CharsetDecoder decoder() { + protected CharsetDecoder decoder() { if (dec == null) { dec = cs.newDecoder() .onMalformedInput(CodingErrorAction.REPORT) @@ -191,7 +142,7 @@ return dec; } - private CharsetEncoder encoder() { + protected CharsetEncoder encoder() { if (enc == null) { enc = cs.newEncoder() .onMalformedInput(CodingErrorAction.REPORT) diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/java/util/zip/ZipFile.java --- a/src/java.base/share/classes/java/util/zip/ZipFile.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/java/util/zip/ZipFile.java Thu Dec 14 12:28:32 2017 +0000 @@ -31,22 +31,24 @@ import java.io.EOFException; import java.io.File; import java.io.RandomAccessFile; +import java.io.UncheckedIOException; +import java.lang.ref.Cleaner.Cleanable; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.attribute.BasicFileAttributes; -import java.nio.file.Path; import java.nio.file.Files; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Deque; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; -import java.util.Map; import java.util.Objects; import java.util.NoSuchElementException; +import java.util.Set; import java.util.Spliterator; import java.util.Spliterators; import java.util.WeakHashMap; @@ -61,8 +63,8 @@ import jdk.internal.misc.SharedSecrets; import jdk.internal.misc.VM; import jdk.internal.perf.PerfCounter; +import jdk.internal.ref.CleanerFactory; -import static java.util.zip.ZipConstants.*; import static java.util.zip.ZipConstants64.*; import static java.util.zip.ZipUtils.*; @@ -73,6 +75,21 @@ * or method in this class will cause a {@link NullPointerException} to be * thrown. * + * @apiNote + * To release resources used by this {@code ZipFile}, the {@link #close()} method + * should be called explicitly or by try-with-resources. Subclasses are responsible + * for the cleanup of resources acquired by the subclass. Subclasses that override + * {@link #finalize()} in order to perform cleanup should be modified to use alternative + * cleanup mechanisms such as {@link java.lang.ref.Cleaner} and remove the overriding + * {@code finalize} method. + * + * @implSpec + * If this {@code ZipFile} has been subclassed and the {@code close} method has + * been overridden, the {@code close} method will be called by the finalization + * when {@code ZipFile} is unreachable. But the subclasses should not depend on + * this specific implementation; the finalization is not reliable and the + * {@code finalize} method is deprecated to be removed. + * * @author David Connelly * @since 1.1 */ @@ -81,9 +98,15 @@ private final String name; // zip file name private volatile boolean closeRequested; - private Source zsrc; private ZipCoder zc; + // The "resource" used by this zip file that needs to be + // cleaned after use. + // a) the input streams that need to be closed + // b) the list of cached Inflater objects + // c) the "native" source of this zip file. + private final CleanableResource res; + private static final int STORED = ZipEntry.STORED; private static final int DEFLATED = ZipEntry.DEFLATED; @@ -214,10 +237,13 @@ } } Objects.requireNonNull(charset, "charset"); + this.zc = ZipCoder.get(charset); this.name = name; long t0 = System.nanoTime(); - this.zsrc = Source.get(file, (mode & OPEN_DELETE) != 0); + + this.res = CleanableResource.get(this, file, mode); + PerfCounter.getZipFileOpenTime().addElapsedTimeFrom(t0); PerfCounter.getZipFileCount().increment(); } @@ -284,10 +310,10 @@ public String getComment() { synchronized (this) { ensureOpen(); - if (zsrc.comment == null) { + if (res.zsrc.comment == null) { return null; } - return zc.toString(zsrc.comment); + return zc.toString(res.zsrc.comment); } } @@ -318,7 +344,7 @@ synchronized (this) { ensureOpen(); byte[] bname = zc.getBytes(name); - int pos = zsrc.getEntryPos(bname, true); + int pos = res.zsrc.getEntryPos(bname, true); if (pos != -1) { return getZipEntry(name, bname, pos, func); } @@ -326,10 +352,6 @@ return null; } - // The outstanding inputstreams that need to be closed, - // mapped to the inflater objects they use. - private final Map streams = new WeakHashMap<>(); - /** * Returns an input stream for reading the contents of the specified * zip file entry. @@ -348,6 +370,8 @@ Objects.requireNonNull(entry, "entry"); int pos = -1; ZipFileInputStream in = null; + Source zsrc = res.zsrc; + Set istreams = res.istreams; synchronized (this) { ensureOpen(); if (Objects.equals(lastEntryName, entry.name)) { @@ -363,8 +387,8 @@ in = new ZipFileInputStream(zsrc.cen, pos); switch (CENHOW(zsrc.cen, pos)) { case STORED: - synchronized (streams) { - streams.put(in, null); + synchronized (istreams) { + istreams.add(in); } return in; case DEFLATED: @@ -377,10 +401,9 @@ if (size <= 0) { size = 4096; } - Inflater inf = getInflater(); - InputStream is = new ZipFileInflaterInputStream(in, inf, (int)size); - synchronized (streams) { - streams.put(is, inf); + InputStream is = new ZipFileInflaterInputStream(in, res, (int)size); + synchronized (istreams) { + istreams.add(is); } return is; default: @@ -392,25 +415,30 @@ private class ZipFileInflaterInputStream extends InflaterInputStream { private volatile boolean closeRequested; private boolean eof = false; + private final Cleanable cleanable; - ZipFileInflaterInputStream(ZipFileInputStream zfin, Inflater inf, - int size) { + ZipFileInflaterInputStream(ZipFileInputStream zfin, + CleanableResource res, int size) { + this(zfin, res, res.getInflater(), size); + } + + private ZipFileInflaterInputStream(ZipFileInputStream zfin, + CleanableResource res, + Inflater inf, int size) { super(zfin, inf, size); - } + this.cleanable = CleanerFactory.cleaner().register(this, + () -> res.releaseInflater(inf)); + } public void close() throws IOException { if (closeRequested) return; closeRequested = true; - super.close(); - Inflater inf; - synchronized (streams) { - inf = streams.remove(this); + synchronized (res.istreams) { + res.istreams.remove(this); } - if (inf != null) { - releaseInflater(inf); - } + cleanable.clean(); } // Override fill() method to provide an extra "dummy" byte @@ -436,44 +464,8 @@ return (avail > (long) Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) avail); } - - @SuppressWarnings("deprecation") - protected void finalize() throws Throwable { - close(); - } } - /* - * Gets an inflater from the list of available inflaters or allocates - * a new one. - */ - private Inflater getInflater() { - Inflater inf; - synchronized (inflaterCache) { - while ((inf = inflaterCache.poll()) != null) { - if (!inf.ended()) { - return inf; - } - } - } - return new Inflater(true); - } - - /* - * Releases the specified inflater to the list of available inflaters. - */ - private void releaseInflater(Inflater inf) { - if (!inf.ended()) { - inf.reset(); - synchronized (inflaterCache) { - inflaterCache.add(inf); - } - } - } - - // List of available Inflater objects for decompression - private final Deque inflaterCache = new ArrayDeque<>(); - /** * Returns the path name of the ZIP file. * @return the path name of the ZIP file @@ -518,7 +510,7 @@ throw new NoSuchElementException(); } // each "entry" has 3 ints in table entries - return (T)getZipEntry(null, null, zsrc.getEntryPos(i++ * 3), gen); + return (T)getZipEntry(null, null, res.zsrc.getEntryPos(i++ * 3), gen); } } @@ -536,14 +528,14 @@ public Enumeration entries() { synchronized (this) { ensureOpen(); - return new ZipEntryIterator(zsrc.total, ZipEntry::new); + return new ZipEntryIterator(res.zsrc.total, ZipEntry::new); } } private Enumeration entries(Function func) { synchronized (this) { ensureOpen(); - return new ZipEntryIterator(zsrc.total, func); + return new ZipEntryIterator(res.zsrc.total, func); } } @@ -568,7 +560,7 @@ if (index >= 0 && index < fence) { synchronized (ZipFile.this) { ensureOpen(); - action.accept(gen.apply(zsrc.getEntryPos(index++ * 3))); + action.accept(gen.apply(res.zsrc.getEntryPos(index++ * 3))); } return true; } @@ -589,13 +581,13 @@ public Stream stream() { synchronized (this) { ensureOpen(); - return StreamSupport.stream(new EntrySpliterator<>(0, zsrc.total, + return StreamSupport.stream(new EntrySpliterator<>(0, res.zsrc.total, pos -> getZipEntry(null, null, pos, ZipEntry::new)), false); } } private String getEntryName(int pos) { - byte[] cen = zsrc.cen; + byte[] cen = res.zsrc.cen; int nlen = CENNAM(cen, pos); int clen = CENCOM(cen, pos); int flag = CENFLG(cen, pos); @@ -620,7 +612,7 @@ synchronized (this) { ensureOpen(); return StreamSupport.stream( - new EntrySpliterator<>(0, zsrc.total, this::getEntryName), false); + new EntrySpliterator<>(0, res.zsrc.total, this::getEntryName), false); } } @@ -638,7 +630,7 @@ private Stream stream(Function func) { synchronized (this) { ensureOpen(); - return StreamSupport.stream(new EntrySpliterator<>(0, zsrc.total, + return StreamSupport.stream(new EntrySpliterator<>(0, res.zsrc.total, pos -> (JarEntry)getZipEntry(null, null, pos, func)), false); } } @@ -649,7 +641,7 @@ /* Checks ensureOpen() before invoke this method */ private ZipEntry getZipEntry(String name, byte[] bname, int pos, Function func) { - byte[] cen = zsrc.cen; + byte[] cen = res.zsrc.cen; int nlen = CENNAM(cen, pos); int elen = CENEXT(cen, pos); int clen = CENCOM(cen, pos); @@ -698,12 +690,170 @@ public int size() { synchronized (this) { ensureOpen(); - return zsrc.total; + return res.zsrc.total; + } + } + + private static class CleanableResource implements Runnable { + // The outstanding inputstreams that need to be closed + final Set istreams; + + // List of cached Inflater objects for decompression + Deque inflaterCache; + + final Cleanable cleanable; + + Source zsrc; + + CleanableResource(ZipFile zf, File file, int mode) throws IOException { + this.cleanable = CleanerFactory.cleaner().register(zf, this); + this.istreams = Collections.newSetFromMap(new WeakHashMap<>()); + this.inflaterCache = new ArrayDeque<>(); + this.zsrc = Source.get(file, (mode & OPEN_DELETE) != 0); + } + + void clean() { + cleanable.clean(); + } + + /* + * Gets an inflater from the list of available inflaters or allocates + * a new one. + */ + Inflater getInflater() { + Inflater inf; + synchronized (inflaterCache) { + if ((inf = inflaterCache.poll()) != null) { + return inf; + } + } + return new Inflater(true); + } + + /* + * Releases the specified inflater to the list of available inflaters. + */ + void releaseInflater(Inflater inf) { + Deque inflaters = this.inflaterCache; + if (inflaters != null) { + synchronized (inflaters) { + // double checked! + if (inflaters == this.inflaterCache) { + inf.reset(); + inflaters.add(inf); + return; + } + } + } + // inflaters cache already closed - just end it. + inf.end(); + } + + public void run() { + IOException ioe = null; + + // Release cached inflaters and close the cache first + Deque inflaters = this.inflaterCache; + if (inflaters != null) { + synchronized (inflaters) { + // no need to double-check as only one thread gets a + // chance to execute run() (Cleaner guarantee)... + Inflater inf; + while ((inf = inflaters.poll()) != null) { + inf.end(); + } + // close inflaters cache + this.inflaterCache = null; + } + } + + // Close streams, release their inflaters + if (istreams != null) { + synchronized (istreams) { + if (!istreams.isEmpty()) { + InputStream[] copy = istreams.toArray(new InputStream[0]); + istreams.clear(); + for (InputStream is : copy) { + try { + is.close(); + } catch (IOException e) { + if (ioe == null) ioe = e; + else ioe.addSuppressed(e); + } + } + } + } + } + + // Release zip src + if (zsrc != null) { + synchronized (zsrc) { + try { + Source.release(zsrc); + zsrc = null; + } catch (IOException e) { + if (ioe == null) ioe = e; + else ioe.addSuppressed(e); + } + } + } + if (ioe != null) { + throw new UncheckedIOException(ioe); + } + } + + CleanableResource(File file, int mode) + throws IOException { + this.cleanable = null; + this.istreams = Collections.newSetFromMap(new WeakHashMap<>()); + this.inflaterCache = new ArrayDeque<>(); + this.zsrc = Source.get(file, (mode & OPEN_DELETE) != 0); + } + + /* + * If {@code ZipFile} has been subclassed and the {@code close} method is + * overridden, uses the {@code finalizer} mechanism for resource cleanup. + * So {@code close} method can be called when the the {@code ZipFile} is + * unreachable. This mechanism will be removed when {@code finalize} method + * is removed from {@code ZipFile}. + */ + static CleanableResource get(ZipFile zf, File file, int mode) + throws IOException { + Class clz = zf.getClass(); + while (clz != ZipFile.class) { + try { + clz.getDeclaredMethod("close"); + return new FinalizableResource(zf, file, mode); + } catch (NoSuchMethodException nsme) {} + clz = clz.getSuperclass(); + } + return new CleanableResource(zf, file, mode); + } + + static class FinalizableResource extends CleanableResource { + ZipFile zf; + FinalizableResource(ZipFile zf, File file, int mode) + throws IOException { + super(file, mode); + this.zf = zf; + } + + @Override + void clean() { + run(); + } + + @Override + @SuppressWarnings("deprecation") + protected void finalize() throws IOException { + zf.close(); + } } } /** * Closes the ZIP file. + * *

    Closing this ZIP file will close all of the input streams * previously returned by invocations of the {@link #getInputStream * getInputStream} method. @@ -717,31 +867,12 @@ closeRequested = true; synchronized (this) { - // Close streams, release their inflaters - synchronized (streams) { - if (!streams.isEmpty()) { - Map copy = new HashMap<>(streams); - streams.clear(); - for (Map.Entry e : copy.entrySet()) { - e.getKey().close(); - Inflater inf = e.getValue(); - if (inf != null) { - inf.end(); - } - } - } - } - // Release cached inflaters - synchronized (inflaterCache) { - Inflater inf; - while ((inf = inflaterCache.poll()) != null) { - inf.end(); - } - } - // Release zip src - if (zsrc != null) { - Source.close(zsrc); - zsrc = null; + // Close streams, release their inflaters, release cached inflaters + // and release zip source + try { + res.clean(); + } catch (UncheckedIOException ioe) { + throw ioe.getCause(); } } } @@ -750,34 +881,26 @@ * Ensures that the system resources held by this ZipFile object are * released when there are no more references to it. * - *

    - * Since the time when GC would invoke this method is undetermined, - * it is strongly recommended that applications invoke the {@code close} - * method as soon they have finished accessing this {@code ZipFile}. - * This will prevent holding up system resources for an undetermined - * length of time. + * @deprecated The {@code finalize} method has been deprecated and will be + * removed. It is implemented as a no-op. Subclasses that override + * {@code finalize} in order to perform cleanup should be modified to + * use alternative cleanup mechanisms and to remove the overriding + * {@code finalize} method. The recommended cleanup for ZipFile object + * is to explicitly invoke {@code close} method when it is no longer in + * use, or use try-with-resources. If the {@code close} is not invoked + * explicitly the resources held by this object will be released when + * the instance becomes unreachable. * - * @deprecated The {@code finalize} method has been deprecated. - * Subclasses that override {@code finalize} in order to perform cleanup - * should be modified to use alternative cleanup mechanisms and - * to remove the overriding {@code finalize} method. - * When overriding the {@code finalize} method, its implementation must explicitly - * ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}. - * See the specification for {@link Object#finalize()} for further - * information about migration options. * @throws IOException if an I/O error has occurred - * @see java.util.zip.ZipFile#close() */ - @Deprecated(since="9") - protected void finalize() throws IOException { - close(); - } + @Deprecated(since="9", forRemoval=true) + protected void finalize() throws IOException {} private void ensureOpen() { if (closeRequested) { throw new IllegalStateException("zip file closed"); } - if (zsrc == null) { + if (res.zsrc == null) { throw new IllegalStateException("The object is not initialized."); } } @@ -798,7 +921,7 @@ protected long rem; // number of remaining bytes within entry protected long size; // uncompressed size of this entry - ZipFileInputStream(byte[] cen, int cenpos) throws IOException { + ZipFileInputStream(byte[] cen, int cenpos) { rem = CENSIZ(cen, cenpos); size = CENLEN(cen, cenpos); pos = CENOFF(cen, cenpos); @@ -808,10 +931,10 @@ checkZIP64(cen, cenpos); } // negative for lazy initialization, see getDataOffset(); - pos = - (pos + ZipFile.this.zsrc.locpos); + pos = - (pos + ZipFile.this.res.zsrc.locpos); } - private void checkZIP64(byte[] cen, int cenpos) throws IOException { + private void checkZIP64(byte[] cen, int cenpos) { int off = cenpos + CENHDR + CENNAM(cen, cenpos); int end = off + CENEXT(cen, cenpos); while (off + 4 < end) { @@ -857,7 +980,7 @@ if (pos <= 0) { byte[] loc = new byte[LOCHDR]; pos = -pos; - int len = ZipFile.this.zsrc.readFullyAt(loc, 0, loc.length, pos); + int len = ZipFile.this.res.zsrc.readFullyAt(loc, 0, loc.length, pos); if (len != LOCHDR) { throw new ZipException("ZipFile error reading zip file"); } @@ -882,7 +1005,7 @@ if (len <= 0) { return 0; } - len = ZipFile.this.zsrc.readAt(b, off, len, pos); + len = ZipFile.this.res.zsrc.readAt(b, off, len, pos); if (len > 0) { pos += len; rem -= len; @@ -932,15 +1055,11 @@ } closeRequested = true; rem = 0; - synchronized (streams) { - streams.remove(this); + synchronized (res.istreams) { + res.istreams.remove(this); } } - @SuppressWarnings("deprecation") - protected void finalize() { - close(); - } } /** @@ -952,6 +1071,7 @@ private String[] getMetaInfEntryNames() { synchronized (this) { ensureOpen(); + Source zsrc = res.zsrc; if (zsrc.metanames == null) { return null; } @@ -972,7 +1092,7 @@ new JavaUtilZipFileAccess() { @Override public boolean startsWithLocHeader(ZipFile zip) { - return zip.zsrc.startsWithLoc; + return zip.res.zsrc.startsWithLoc; } @Override public String[] getMetaInfEntryNames(ZipFile zip) { @@ -1080,7 +1200,7 @@ private static final HashMap files = new HashMap<>(); - public static Source get(File file, boolean toDelete) throws IOException { + static Source get(File file, boolean toDelete) throws IOException { Key key = new Key(file, Files.readAttributes(file.toPath(), BasicFileAttributes.class)); Source src = null; @@ -1105,9 +1225,9 @@ } } - private static void close(Source src) throws IOException { + static void release(Source src) throws IOException { synchronized (files) { - if (--src.refs == 0) { + if (src != null && --src.refs == 0) { files.remove(src.key); src.close(); } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/jdk/internal/misc/JavaIOFileDescriptorAccess.java --- a/src/java.base/share/classes/jdk/internal/misc/JavaIOFileDescriptorAccess.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/jdk/internal/misc/JavaIOFileDescriptorAccess.java Thu Dec 14 12:28:32 2017 +0000 @@ -25,6 +25,7 @@ package jdk.internal.misc; import java.io.FileDescriptor; +import java.io.IOException; /* * @author Chris Hegarty @@ -35,7 +36,8 @@ public int get(FileDescriptor fdo); public void setAppend(FileDescriptor fdo, boolean append); public boolean getAppend(FileDescriptor fdo); - public void close(FileDescriptor fdo); + public void close(FileDescriptor fdo) throws IOException; + public void registerCleanup(FileDescriptor fdo); // Only valid on Windows public void setHandle(FileDescriptor fdo, long handle); diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java --- a/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java Thu Dec 14 12:28:32 2017 +0000 @@ -254,4 +254,23 @@ * given class loader. */ Stream layers(ClassLoader loader); + + /** + * Returns a new string by decoding from the given utf8 bytes array. + * + * @param off the index of the first byte to decode + * @param len the number of bytes to decode + * @return the newly created string + * @throws IllegalArgumentException for malformed or unmappable bytes. + */ + String newStringUTF8NoRepl(byte[] bytes, int off, int len); + + /** + * Encode the given string into a sequence of bytes using utf8. + * + * @param s the string to encode + * @return the encoded bytes in utf8 + * @throws IllegalArgumentException for malformed surrogates + */ + byte[] getBytesUTF8NoRepl(String s); } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/jdk/internal/module/ModuleInfo.java --- a/src/java.base/share/classes/jdk/internal/module/ModuleInfo.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/jdk/internal/module/ModuleInfo.java Thu Dec 14 12:28:32 2017 +0000 @@ -63,6 +63,9 @@ public final class ModuleInfo { + private final int JAVA_MIN_SUPPORTED_VERSION = 53; + private final int JAVA_MAX_SUPPORTED_VERSION = 54; + private static final JavaLangModuleAccess JLMA = SharedSecrets.getJavaLangModuleAccess(); @@ -188,8 +191,10 @@ int minor_version = in.readUnsignedShort(); int major_version = in.readUnsignedShort(); - if (major_version < 53) { - throw invalidModuleDescriptor("Must be >= 53.0"); + if (major_version < JAVA_MIN_SUPPORTED_VERSION || + major_version > JAVA_MAX_SUPPORTED_VERSION) { + throw invalidModuleDescriptor("Unsupported major.minor version " + + major_version + "." + minor_version); } ConstantPool cpool = new ConstantPool(in); @@ -245,7 +250,7 @@ switch (attribute_name) { case MODULE : - builder = readModuleAttribute(in, cpool); + builder = readModuleAttribute(in, cpool, major_version); break; case MODULE_PACKAGES : @@ -334,7 +339,7 @@ * Reads the Module attribute, returning the ModuleDescriptor.Builder to * build the corresponding ModuleDescriptor. */ - private Builder readModuleAttribute(DataInput in, ConstantPool cpool) + private Builder readModuleAttribute(DataInput in, ConstantPool cpool, int major) throws IOException { // module_name @@ -390,8 +395,21 @@ JLMA.requires(builder, mods, dn, vs); } - if (dn.equals("java.base")) + if (dn.equals("java.base")) { + if (major >= 54 + && (mods.contains(Requires.Modifier.TRANSITIVE) + || mods.contains(Requires.Modifier.STATIC))) { + String flagName; + if (mods.contains(Requires.Modifier.TRANSITIVE)) { + flagName = "ACC_TRANSITIVE"; + } else { + flagName = "ACC_STATIC_PHASE"; + } + throw invalidModuleDescriptor("The requires entry for java.base" + + " has " + flagName + " set"); + } requiresJavaBase = true; + } } if (mn.equals("java.base")) { if (requires_count > 0) { diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/jdk/internal/module/ModuleInfoWriter.java --- a/src/java.base/share/classes/jdk/internal/module/ModuleInfoWriter.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/jdk/internal/module/ModuleInfoWriter.java Thu Dec 14 12:28:32 2017 +0000 @@ -80,7 +80,7 @@ */ private static byte[] toModuleInfo(ModuleDescriptor md, ModuleTarget target) { ClassWriter cw = new ClassWriter(0); - cw.visit(Opcodes.V9, ACC_MODULE, "module-info", null, null, null); + cw.visit(Opcodes.V10, ACC_MODULE, "module-info", null, null, null); int moduleFlags = md.modifiers().stream() .map(MODULE_MODS_TO_FLAGS::get) diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/jdk/internal/util/xml/PropertiesDefaultHandler.java --- a/src/java.base/share/classes/jdk/internal/util/xml/PropertiesDefaultHandler.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/jdk/internal/util/xml/PropertiesDefaultHandler.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package jdk.internal.util.xml; import java.io.*; +import java.nio.charset.Charset; import java.util.InvalidPropertiesFormatException; import java.util.Map.Entry; import java.util.Properties; @@ -94,11 +95,11 @@ */ } - public void store(Properties props, OutputStream os, String comment, String encoding) + public void store(Properties props, OutputStream os, String comment, Charset charset) throws IOException { try { - XMLStreamWriter writer = new XMLStreamWriterImpl(os, encoding); + XMLStreamWriter writer = new XMLStreamWriterImpl(os, charset); writer.writeStartDocument(); writer.writeDTD(PROPS_DTD_DECL); writer.writeStartElement(ELEMENT_ROOT); diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/jdk/internal/util/xml/XMLStreamWriter.java --- a/src/java.base/share/classes/jdk/internal/util/xml/XMLStreamWriter.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/jdk/internal/util/xml/XMLStreamWriter.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,9 @@ package jdk.internal.util.xml; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; + /** * Basic XMLStreamWriter for writing simple XML files such as those * defined in java.util.Properties @@ -38,6 +41,7 @@ //Defaults the XML version to 1.0, and the encoding to utf-8 public static final String DEFAULT_XML_VERSION = "1.0"; public static final String DEFAULT_ENCODING = "UTF-8"; + public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; /** * Writes a start tag to the output. All writeStartElement methods diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/jdk/internal/util/xml/impl/XMLStreamWriterImpl.java --- a/src/java.base/share/classes/jdk/internal/util/xml/impl/XMLStreamWriterImpl.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/jdk/internal/util/xml/impl/XMLStreamWriterImpl.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,7 +66,7 @@ private int _state = 0; private Element _currentEle; private XMLWriter _writer; - private String _encoding; + private Charset _charset; /** * This flag can be used to turn escaping off for content. It does * not apply to attribute content. @@ -79,26 +79,23 @@ System.getProperty("line.separator").toCharArray(); public XMLStreamWriterImpl(OutputStream os) throws XMLStreamException { - this(os, XMLStreamWriter.DEFAULT_ENCODING); + this(os, XMLStreamWriter.DEFAULT_CHARSET); } - public XMLStreamWriterImpl(OutputStream os, String encoding) + public XMLStreamWriterImpl(OutputStream os, Charset cs) throws XMLStreamException { - Charset cs = null; - if (encoding == null) { - _encoding = XMLStreamWriter.DEFAULT_ENCODING; + if (cs == null) { + _charset = XMLStreamWriter.DEFAULT_CHARSET; } else { try { - cs = getCharset(encoding); + _charset = checkCharset(cs); } catch (UnsupportedEncodingException e) { throw new XMLStreamException(e); } - - this._encoding = encoding; } - _writer = new XMLWriter(os, encoding, cs); + _writer = new XMLWriter(os, null, _charset); } /** @@ -108,7 +105,7 @@ * @throws XMLStreamException */ public void writeStartDocument() throws XMLStreamException { - writeStartDocument(_encoding, XMLStreamWriter.DEFAULT_XML_VERSION); + writeStartDocument(_charset.name(), XMLStreamWriter.DEFAULT_XML_VERSION); } /** @@ -118,7 +115,7 @@ * @throws XMLStreamException */ public void writeStartDocument(String version) throws XMLStreamException { - writeStartDocument(_encoding, version, null); + writeStartDocument(_charset.name(), version, null); } /** @@ -155,7 +152,7 @@ _state = STATE_XML_DECL; String enc = encoding; if (enc == null) { - enc = _encoding; + enc = _charset.name(); } else { //check if the encoding is supported try { @@ -564,6 +561,20 @@ return cs; } + /** + * Checks for charset support. + * @param charset the specified charset + * @return the charset + * @throws UnsupportedEncodingException if the charset is not supported + */ + private Charset checkCharset(Charset charset) throws UnsupportedEncodingException { + if (charset.name().equalsIgnoreCase("UTF-32")) { + throw new UnsupportedEncodingException("The basic XMLWriter does " + + "not support " + charset.name()); + } + return charset; + } + /* * Start of Internal classes. * diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/launcher/LauncherHelper.java --- a/src/java.base/share/classes/sun/launcher/LauncherHelper.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/launcher/LauncherHelper.java Thu Dec 14 12:28:32 2017 +0000 @@ -268,7 +268,7 @@ Locale locale = Locale.getDefault(); ostream.println(LOCALE_SETTINGS); ostream.println(INDENT + "default locale = " + - locale.getDisplayLanguage()); + locale.getDisplayName()); ostream.println(INDENT + "default display locale = " + Locale.getDefault(Category.DISPLAY).getDisplayName()); ostream.println(INDENT + "default format locale = " + diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java --- a/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java Thu Dec 14 12:28:32 2017 +0000 @@ -27,6 +27,7 @@ import java.io.FileDescriptor; import java.io.IOException; +import java.io.UncheckedIOException; import java.lang.ref.Cleaner.Cleanable; import java.nio.ByteBuffer; import java.nio.MappedByteBuffer; @@ -109,7 +110,12 @@ } public void run() { - fdAccess.close(fd); + try { + fdAccess.close(fd); + } catch (IOException ioe) { + // Rethrow as unchecked so the exception can be propagated as needed + throw new UncheckedIOException("close", ioe); + } } } @@ -188,7 +194,11 @@ } else if (closer != null) { // Perform the cleaning action so it is not redone when // this channel becomes phantom reachable. - closer.clean(); + try { + closer.clean(); + } catch (UncheckedIOException uioe) { + throw uioe.getCause(); + } } else { fdAccess.close(fd); } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java --- a/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java Thu Dec 14 12:28:32 2017 +0000 @@ -63,8 +63,8 @@ return new Encoder(this); } - private static class Decoder extends CharsetDecoder - implements ArrayDecoder { + private static class Decoder extends CharsetDecoder { + private Decoder(Charset cs) { super(cs, 1.0f, 1.0f); } @@ -124,23 +124,10 @@ else return decodeBufferLoop(src, dst); } - - public int decode(byte[] src, int sp, int len, char[] dst) { - if (len > dst.length) - len = dst.length; - int dp = 0; - while (dp < len) - dst[dp++] = (char)(src[sp++] & 0xff); - return dp; - } - - public boolean isASCIICompatible() { - return true; - } } - private static class Encoder extends CharsetEncoder - implements ArrayEncoder { + private static class Encoder extends CharsetEncoder { + private Encoder(Charset cs) { super(cs, 1.0f, 1.0f); } @@ -271,39 +258,5 @@ else return encodeBufferLoop(src, dst); } - - private byte repl = (byte)'?'; - protected void implReplaceWith(byte[] newReplacement) { - repl = newReplacement[0]; - } - - public int encode(char[] src, int sp, int len, byte[] dst) { - int dp = 0; - int slen = Math.min(len, dst.length); - int sl = sp + slen; - while (sp < sl) { - int ret = encodeISOArray(src, sp, dst, dp, slen); - sp = sp + ret; - dp = dp + ret; - if (ret != slen) { - char c = src[sp++]; - if (Character.isHighSurrogate(c) && sp < sl && - Character.isLowSurrogate(src[sp])) { - if (len > dst.length) { - sl++; - len--; - } - sp++; - } - dst[dp++] = repl; - slen = Math.min((sl - sp), (dst.length - dp)); - } - } - return dp; - } - - public boolean isASCIICompatible() { - return true; - } } } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/nio/cs/US_ASCII.java --- a/src/java.base/share/classes/sun/nio/cs/US_ASCII.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/nio/cs/US_ASCII.java Thu Dec 14 12:28:32 2017 +0000 @@ -58,8 +58,7 @@ return new Encoder(this); } - private static class Decoder extends CharsetDecoder - implements ArrayDecoder { + private static class Decoder extends CharsetDecoder { private Decoder(Charset cs) { super(cs, 1.0f, 1.0f); @@ -128,32 +127,9 @@ else return decodeBufferLoop(src, dst); } - - private char repl = '\uFFFD'; - protected void implReplaceWith(String newReplacement) { - repl = newReplacement.charAt(0); - } - - public int decode(byte[] src, int sp, int len, char[] dst) { - int dp = 0; - len = Math.min(len, dst.length); - while (dp < len) { - byte b = src[sp++]; - if (b >= 0) - dst[dp++] = (char)b; - else - dst[dp++] = repl; - } - return dp; - } - - public boolean isASCIICompatible() { - return true; - } } - private static class Encoder extends CharsetEncoder - implements ArrayEncoder { + private static class Encoder extends CharsetEncoder { private Encoder(Charset cs) { super(cs, 1.0f, 1.0f); @@ -237,36 +213,5 @@ return encodeBufferLoop(src, dst); } - private byte repl = (byte)'?'; - protected void implReplaceWith(byte[] newReplacement) { - repl = newReplacement[0]; - } - - public int encode(char[] src, int sp, int len, byte[] dst) { - int dp = 0; - int sl = sp + Math.min(len, dst.length); - while (sp < sl) { - char c = src[sp++]; - if (c < 0x80) { - dst[dp++] = (byte)c; - continue; - } - if (Character.isHighSurrogate(c) && sp < sl && - Character.isLowSurrogate(src[sp])) { - if (len > dst.length) { - sl++; - len--; - } - sp++; - } - dst[dp++] = repl; - } - return dp; - } - - public boolean isASCIICompatible() { - return true; - } } - } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/nio/cs/UTF_8.java --- a/src/java.base/share/classes/sun/nio/cs/UTF_8.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/nio/cs/UTF_8.java Thu Dec 14 12:28:32 2017 +0000 @@ -80,8 +80,8 @@ dst.position(dp - dst.arrayOffset()); } - private static class Decoder extends CharsetDecoder - implements ArrayDecoder { + private static class Decoder extends CharsetDecoder { + private Decoder(Charset cs) { super(cs, 1.0f, 1.0f); } @@ -423,142 +423,9 @@ bb.position(sp); return bb; } - - // returns -1 if there is/are malformed byte(s) and the - // "action" for malformed input is not REPLACE. - public int decode(byte[] sa, int sp, int len, char[] da) { - final int sl = sp + len; - int dp = 0; - int dlASCII = Math.min(len, da.length); - ByteBuffer bb = null; // only necessary if malformed - - // ASCII only optimized loop - while (dp < dlASCII && sa[sp] >= 0) - da[dp++] = (char) sa[sp++]; - - while (sp < sl) { - int b1 = sa[sp++]; - if (b1 >= 0) { - // 1 byte, 7 bits: 0xxxxxxx - da[dp++] = (char) b1; - } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) { - // 2 bytes, 11 bits: 110xxxxx 10xxxxxx - if (sp < sl) { - int b2 = sa[sp++]; - if (isNotContinuation(b2)) { - if (malformedInputAction() != CodingErrorAction.REPLACE) - return -1; - da[dp++] = replacement().charAt(0); - sp--; // malformedN(bb, 2) always returns 1 - } else { - da[dp++] = (char) (((b1 << 6) ^ b2)^ - (((byte) 0xC0 << 6) ^ - ((byte) 0x80 << 0))); - } - continue; - } - if (malformedInputAction() != CodingErrorAction.REPLACE) - return -1; - da[dp++] = replacement().charAt(0); - return dp; - } else if ((b1 >> 4) == -2) { - // 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx - if (sp + 1 < sl) { - int b2 = sa[sp++]; - int b3 = sa[sp++]; - if (isMalformed3(b1, b2, b3)) { - if (malformedInputAction() != CodingErrorAction.REPLACE) - return -1; - da[dp++] = replacement().charAt(0); - sp -= 3; - bb = getByteBuffer(bb, sa, sp); - sp += malformedN(bb, 3).length(); - } else { - char c = (char)((b1 << 12) ^ - (b2 << 6) ^ - (b3 ^ - (((byte) 0xE0 << 12) ^ - ((byte) 0x80 << 6) ^ - ((byte) 0x80 << 0)))); - if (Character.isSurrogate(c)) { - if (malformedInputAction() != CodingErrorAction.REPLACE) - return -1; - da[dp++] = replacement().charAt(0); - } else { - da[dp++] = c; - } - } - continue; - } - if (malformedInputAction() != CodingErrorAction.REPLACE) - return -1; - if (sp < sl && isMalformed3_2(b1, sa[sp])) { - da[dp++] = replacement().charAt(0); - continue; - - } - da[dp++] = replacement().charAt(0); - return dp; - } else if ((b1 >> 3) == -2) { - // 4 bytes, 21 bits: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - if (sp + 2 < sl) { - int b2 = sa[sp++]; - int b3 = sa[sp++]; - int b4 = sa[sp++]; - int uc = ((b1 << 18) ^ - (b2 << 12) ^ - (b3 << 6) ^ - (b4 ^ - (((byte) 0xF0 << 18) ^ - ((byte) 0x80 << 12) ^ - ((byte) 0x80 << 6) ^ - ((byte) 0x80 << 0)))); - if (isMalformed4(b2, b3, b4) || - // shortest form check - !Character.isSupplementaryCodePoint(uc)) { - if (malformedInputAction() != CodingErrorAction.REPLACE) - return -1; - da[dp++] = replacement().charAt(0); - sp -= 4; - bb = getByteBuffer(bb, sa, sp); - sp += malformedN(bb, 4).length(); - } else { - da[dp++] = Character.highSurrogate(uc); - da[dp++] = Character.lowSurrogate(uc); - } - continue; - } - if (malformedInputAction() != CodingErrorAction.REPLACE) - return -1; - b1 &= 0xff; - if (b1 > 0xf4 || - sp < sl && isMalformed4_2(b1, sa[sp] & 0xff)) { - da[dp++] = replacement().charAt(0); - continue; - } - sp++; - if (sp < sl && isMalformed4_3(sa[sp])) { - da[dp++] = replacement().charAt(0); - continue; - } - da[dp++] = replacement().charAt(0); - return dp; - } else { - if (malformedInputAction() != CodingErrorAction.REPLACE) - return -1; - da[dp++] = replacement().charAt(0); - } - } - return dp; - } - - public boolean isASCIICompatible() { - return true; - } } - private static final class Encoder extends CharsetEncoder - implements ArrayEncoder { + private static final class Encoder extends CharsetEncoder { private Encoder(Charset cs) { super(cs, 1.1f, 3.0f); @@ -699,58 +566,5 @@ return encodeBufferLoop(src, dst); } - private byte repl = (byte)'?'; - protected void implReplaceWith(byte[] newReplacement) { - repl = newReplacement[0]; - } - - // returns -1 if there is malformed char(s) and the - // "action" for malformed input is not REPLACE. - public int encode(char[] sa, int sp, int len, byte[] da) { - int sl = sp + len; - int dp = 0; - int dlASCII = dp + Math.min(len, da.length); - - // ASCII only optimized loop - while (dp < dlASCII && sa[sp] < '\u0080') - da[dp++] = (byte) sa[sp++]; - - while (sp < sl) { - char c = sa[sp++]; - if (c < 0x80) { - // Have at most seven bits - da[dp++] = (byte)c; - } else if (c < 0x800) { - // 2 bytes, 11 bits - da[dp++] = (byte)(0xc0 | (c >> 6)); - da[dp++] = (byte)(0x80 | (c & 0x3f)); - } else if (Character.isSurrogate(c)) { - if (sgp == null) - sgp = new Surrogate.Parser(); - int uc = sgp.parse(c, sa, sp - 1, sl); - if (uc < 0) { - if (malformedInputAction() != CodingErrorAction.REPLACE) - return -1; - da[dp++] = repl; - } else { - da[dp++] = (byte)(0xf0 | ((uc >> 18))); - da[dp++] = (byte)(0x80 | ((uc >> 12) & 0x3f)); - da[dp++] = (byte)(0x80 | ((uc >> 6) & 0x3f)); - da[dp++] = (byte)(0x80 | (uc & 0x3f)); - sp++; // 2 chars - } - } else { - // 3 bytes, 16 bits - da[dp++] = (byte)(0xe0 | ((c >> 12))); - da[dp++] = (byte)(0x80 | ((c >> 6) & 0x3f)); - da[dp++] = (byte)(0x80 | (c & 0x3f)); - } - } - return dp; - } - - public boolean isASCIICompatible() { - return true; - } } } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/security/internal/spec/TlsMasterSecretParameterSpec.java --- a/src/java.base/share/classes/sun/security/internal/spec/TlsMasterSecretParameterSpec.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/security/internal/spec/TlsMasterSecretParameterSpec.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,6 +48,7 @@ private final SecretKey premasterSecret; private final int majorVersion, minorVersion; private final byte[] clientRandom, serverRandom; + private final byte[] extendedMasterSecretSessionHash; private final String prfHashAlg; private final int prfHashLength; private final int prfBlockSize; @@ -80,6 +81,50 @@ int majorVersion, int minorVersion, byte[] clientRandom, byte[] serverRandom, String prfHashAlg, int prfHashLength, int prfBlockSize) { + this(premasterSecret, majorVersion, minorVersion, + clientRandom, serverRandom, + new byte[0], + prfHashAlg, prfHashLength, prfBlockSize); + } + + /** + * Constructs a new TlsMasterSecretParameterSpec. + * + *

    The getAlgorithm() method of premasterSecret + * should return "TlsRsaPremasterSecret" if the key exchange + * algorithm was RSA and "TlsPremasterSecret" otherwise. + * + * @param premasterSecret the premaster secret + * @param majorVersion the major number of the protocol version + * @param minorVersion the minor number of the protocol version + * @param extendedMasterSecretSessionHash the session hash for + * Extended Master Secret + * @param prfHashAlg the name of the TLS PRF hash algorithm to use. + * Used only for TLS 1.2+. TLS1.1 and earlier use a fixed PRF. + * @param prfHashLength the output length of the TLS PRF hash algorithm. + * Used only for TLS 1.2+. + * @param prfBlockSize the input block size of the TLS PRF hash algorithm. + * Used only for TLS 1.2+. + * + * @throws NullPointerException if premasterSecret is null + * @throws IllegalArgumentException if minorVersion or majorVersion are + * negative or larger than 255 + */ + public TlsMasterSecretParameterSpec(SecretKey premasterSecret, + int majorVersion, int minorVersion, + byte[] extendedMasterSecretSessionHash, + String prfHashAlg, int prfHashLength, int prfBlockSize) { + this(premasterSecret, majorVersion, minorVersion, + new byte[0], new byte[0], + extendedMasterSecretSessionHash, + prfHashAlg, prfHashLength, prfBlockSize); + } + + private TlsMasterSecretParameterSpec(SecretKey premasterSecret, + int majorVersion, int minorVersion, + byte[] clientRandom, byte[] serverRandom, + byte[] extendedMasterSecretSessionHash, + String prfHashAlg, int prfHashLength, int prfBlockSize) { if (premasterSecret == null) { throw new NullPointerException("premasterSecret must not be null"); } @@ -88,6 +133,9 @@ this.minorVersion = checkVersion(minorVersion); this.clientRandom = clientRandom.clone(); this.serverRandom = serverRandom.clone(); + this.extendedMasterSecretSessionHash = + (extendedMasterSecretSessionHash != null ? + extendedMasterSecretSessionHash.clone() : new byte[0]); this.prfHashAlg = prfHashAlg; this.prfHashLength = prfHashLength; this.prfBlockSize = prfBlockSize; @@ -147,6 +195,17 @@ } /** + * Returns a copy of the Extended Master Secret session hash. + * + * @return a copy of the Extended Master Secret session hash, or an empty + * array if no extended master secret session hash was provided + * at instantiation time + */ + public byte[] getExtendedMasterSecretSessionHash() { + return extendedMasterSecretSessionHash.clone(); + } + + /** * Obtains the PRF hash algorithm to use in the PRF calculation. * * @return the hash algorithm. diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/security/ssl/ClientHandshaker.java --- a/src/java.base/share/classes/sun/security/ssl/ClientHandshaker.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/security/ssl/ClientHandshaker.java Thu Dec 14 12:28:32 2017 +0000 @@ -655,7 +655,8 @@ // validate subject identity ClientKeyExchangeService p = - ClientKeyExchangeService.find(sessionSuite.keyExchange.name); + ClientKeyExchangeService.find( + sessionSuite.keyExchange.name); if (p != null) { Principal localPrincipal = session.getLocalPrincipal(); @@ -663,8 +664,9 @@ if (debug != null && Debug.isOn("session")) System.out.println("Subject identity is same"); } else { - throw new SSLProtocolException("Server resumed" + - " session with wrong subject identity or no subject"); + throw new SSLProtocolException( + "Server resumed session with " + + "wrong subject identity or no subject"); } } @@ -707,6 +709,54 @@ } // Otherwise, using the value negotiated during the original // session initiation + // check the "extended_master_secret" extension + ExtendedMasterSecretExtension extendedMasterSecretExt = + (ExtendedMasterSecretExtension)mesg.extensions.get( + ExtensionType.EXT_EXTENDED_MASTER_SECRET); + if (extendedMasterSecretExt != null) { + // Is it the expected server extension? + if (!useExtendedMasterSecret || + !mesgVersion.useTLS10PlusSpec() || !requestedToUseEMS) { + fatalSE(Alerts.alert_unsupported_extension, + "Server sent the extended_master_secret " + + "extension improperly"); + } + + // For abbreviated handshake, if the original session did not use + // the "extended_master_secret" extension but the new ServerHello + // contains the extension, the client MUST abort the handshake. + if (resumingSession && (session != null) && + !session.getUseExtendedMasterSecret()) { + fatalSE(Alerts.alert_unsupported_extension, + "Server sent an unexpected extended_master_secret " + + "extension on session resumption"); + } + } else { + if (useExtendedMasterSecret && !allowLegacyMasterSecret) { + // For full handshake, if a client receives a ServerHello + // without the extension, it SHOULD abort the handshake if + // it does not wish to interoperate with legacy servers. + fatalSE(Alerts.alert_handshake_failure, + "Extended Master Secret extension is required"); + } + + if (resumingSession && (session != null)) { + if (session.getUseExtendedMasterSecret()) { + // For abbreviated handshake, if the original session used + // the "extended_master_secret" extension but the new + // ServerHello does not contain the extension, the client + // MUST abort the handshake. + fatalSE(Alerts.alert_handshake_failure, + "Missing Extended Master Secret extension " + + "on session resumption"); + } else if (useExtendedMasterSecret && !allowLegacyResumption) { + // Unlikely, abbreviated handshake should be discarded. + fatalSE(Alerts.alert_handshake_failure, + "Extended Master Secret extension is required"); + } + } + } + // check the ALPN extension ALPNExtension serverHelloALPN = (ALPNExtension) mesg.extensions.get(ExtensionType.EXT_ALPN); @@ -777,7 +827,8 @@ && (type != ExtensionType.EXT_ALPN) && (type != ExtensionType.EXT_RENEGOTIATION_INFO) && (type != ExtensionType.EXT_STATUS_REQUEST) - && (type != ExtensionType.EXT_STATUS_REQUEST_V2)) { + && (type != ExtensionType.EXT_STATUS_REQUEST_V2) + && (type != ExtensionType.EXT_EXTENDED_MASTER_SECRET)) { // Note: Better to check client requested extensions rather // than all supported extensions. fatalSE(Alerts.alert_unsupported_extension, @@ -788,7 +839,8 @@ // Create a new session, we need to do the full handshake session = new SSLSessionImpl(protocolVersion, cipherSuite, getLocalSupportedSignAlgs(), - mesg.sessionId, getHostSE(), getPortSE()); + mesg.sessionId, getHostSE(), getPortSE(), + (extendedMasterSecretExt != null)); session.setRequestedServerNames(requestedServerNames); session.setNegotiatedMaxFragSize(requestedMFLength); session.setMaximumPacketSize(maximumPacketSize); @@ -1430,6 +1482,44 @@ session = null; } + if ((session != null) && useExtendedMasterSecret) { + boolean isTLS10Plus = sessionVersion.useTLS10PlusSpec(); + if (isTLS10Plus && !session.getUseExtendedMasterSecret()) { + if (!allowLegacyResumption) { + // perform full handshake instead + // + // The client SHOULD NOT offer an abbreviated handshake + // to resume a session that does not use an extended + // master secret. Instead, it SHOULD offer a full + // handshake. + session = null; + } + } + + if ((session != null) && !allowUnsafeServerCertChange) { + // It is fine to move on with abbreviate handshake if + // endpoint identification is enabled. + String identityAlg = getEndpointIdentificationAlgorithmSE(); + if ((identityAlg == null || identityAlg.length() == 0)) { + if (isTLS10Plus) { + if (!session.getUseExtendedMasterSecret()) { + // perform full handshake instead + session = null; + } // Otherwise, use extended master secret. + } else { + // The extended master secret extension does not + // apply to SSL 3.0. Perform a full handshake + // instead. + // + // Note that the useExtendedMasterSecret is + // extended to protect SSL 3.0 connections, + // by discarding abbreviate handshake. + session = null; + } + } + } + } + if (session != null) { if (debug != null) { if (Debug.isOn("handshake") || Debug.isOn("session")) { @@ -1539,6 +1629,14 @@ clientHelloMessage.addSignatureAlgorithmsExtension(localSignAlgs); } + // add Extended Master Secret extension + if (useExtendedMasterSecret && maxProtocolVersion.useTLS10PlusSpec()) { + if ((session == null) || session.getUseExtendedMasterSecret()) { + clientHelloMessage.addExtendedMasterSecretExtension(); + requestedToUseEMS = true; + } + } + // add server_name extension if (enableSNIExtension) { if (session != null) { @@ -1647,10 +1745,14 @@ // Allow server certificate change in client side during renegotiation // after a session-resumption abbreviated initial handshake? // - // DO NOT need to check allowUnsafeServerCertChange here. We only + // DO NOT need to check allowUnsafeServerCertChange here. We only // reserve server certificates when allowUnsafeServerCertChange is // flase. - if (reservedServerCerts != null) { + // + // Allow server certificate change if it is negotiated to use the + // extended master secret. + if ((reservedServerCerts != null) && + !session.getUseExtendedMasterSecret()) { // It is not necessary to check the certificate update if endpoint // identification is enabled. String identityAlg = getEndpointIdentificationAlgorithmSE(); diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/security/ssl/ExtendedMasterSecretExtension.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/java.base/share/classes/sun/security/ssl/ExtendedMasterSecretExtension.java Thu Dec 14 12:28:32 2017 +0000 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2017, Red Hat, Inc. and/or its affiliates. + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.security.ssl; + +import java.io.IOException; +import javax.net.ssl.SSLProtocolException; + +/** + * Extended Master Secret TLS extension (TLS 1.0+). This extension + * defines how to calculate the TLS connection master secret and + * mitigates some types of man-in-the-middle attacks. + * + * See further information in + * RFC 7627. + * + * @author Martin Balao (mbalao@redhat.com) + */ +final class ExtendedMasterSecretExtension extends HelloExtension { + ExtendedMasterSecretExtension() { + super(ExtensionType.EXT_EXTENDED_MASTER_SECRET); + } + + ExtendedMasterSecretExtension(HandshakeInStream s, + int len) throws IOException { + super(ExtensionType.EXT_EXTENDED_MASTER_SECRET); + + if (len != 0) { + throw new SSLProtocolException("Invalid " + type + " extension"); + } + } + + @Override + int length() { + return 4; // 4: extension type and length fields + } + + @Override + void send(HandshakeOutStream s) throws IOException { + s.putInt16(type.id); // ExtensionType extension_type; + s.putInt16(0); // extension_data length + } + + @Override + public String toString() { + return "Extension " + type; + } +} + diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/security/ssl/ExtensionType.java --- a/src/java.base/share/classes/sun/security/ssl/ExtensionType.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/security/ssl/ExtensionType.java Thu Dec 14 12:28:32 2017 +0000 @@ -43,7 +43,7 @@ return name; } - static List knownExtensions = new ArrayList<>(15); + static List knownExtensions = new ArrayList<>(16); static ExtensionType get(int id) { for (ExtensionType ext : knownExtensions) { @@ -105,6 +105,10 @@ static final ExtensionType EXT_STATUS_REQUEST_V2 = e(0x0011, "status_request_v2"); // IANA registry value: 17 + // extensions defined in RFC 7627 + static final ExtensionType EXT_EXTENDED_MASTER_SECRET = + e(0x0017, "extended_master_secret"); // IANA registry value: 23 + // extensions defined in RFC 5746 static final ExtensionType EXT_RENEGOTIATION_INFO = e(0xff01, "renegotiation_info"); // IANA registry value: 65281 diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java --- a/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java Thu Dec 14 12:28:32 2017 +0000 @@ -389,6 +389,10 @@ extensions.add(signatureAlgorithm); } + void addExtendedMasterSecretExtension() { + extensions.add(new ExtendedMasterSecretExtension()); + } + void addMFLExtension(int maximumPacketSize) { HelloExtension maxFragmentLength = new MaxFragmentLengthExtension(maximumPacketSize); @@ -1441,7 +1445,7 @@ } else { sig = getSignature(privateKey.getAlgorithm()); } - sig.initSign(privateKey); // where is the SecureRandom? + sig.initSign(privateKey, sr); updateSignature(sig, clntNonce, svrNonce); signatureBytes = sig.sign(); diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/security/ssl/Handshaker.java --- a/src/java.base/share/classes/sun/security/ssl/Handshaker.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/security/ssl/Handshaker.java Thu Dec 14 12:28:32 2017 +0000 @@ -30,12 +30,6 @@ import java.util.*; import java.security.*; import java.nio.ByteBuffer; -import java.security.NoSuchAlgorithmException; -import java.security.AccessController; -import java.security.AlgorithmConstraints; -import java.security.AccessControlContext; -import java.security.PrivilegedExceptionAction; -import java.security.PrivilegedActionException; import java.util.function.BiFunction; import javax.crypto.*; @@ -225,6 +219,20 @@ Debug.getBooleanProperty( "jdk.tls.rejectClientInitiatedRenegotiation", false); + // To switch off the extended_master_secret extension. + static final boolean useExtendedMasterSecret; + + // Allow session resumption without Extended Master Secret extension. + static final boolean allowLegacyResumption = + Debug.getBooleanProperty("jdk.tls.allowLegacyResumption", true); + + // Allow full handshake without Extended Master Secret extension. + static final boolean allowLegacyMasterSecret = + Debug.getBooleanProperty("jdk.tls.allowLegacyMasterSecret", true); + + // Is it requested to use extended master secret extension? + boolean requestedToUseEMS = false; + // need to dispose the object when it is invalidated boolean invalidated; @@ -233,6 +241,24 @@ */ final boolean isDTLS; + // Is the extended_master_secret extension supported? + static { + boolean supportExtendedMasterSecret = true; + try { + KeyGenerator kg = + JsseJce.getKeyGenerator("SunTlsExtendedMasterSecret"); + } catch (NoSuchAlgorithmException nae) { + supportExtendedMasterSecret = false; + } + + if (supportExtendedMasterSecret) { + useExtendedMasterSecret = Debug.getBooleanProperty( + "jdk.tls.useExtendedMasterSecret", true); + } else { + useExtendedMasterSecret = false; + } + } + Handshaker(SSLSocketImpl c, SSLContextImpl context, ProtocolList enabledProtocols, boolean needCertVerify, boolean isClient, ProtocolVersion activeProtocolVersion, @@ -243,7 +269,7 @@ init(context, enabledProtocols, needCertVerify, isClient, activeProtocolVersion, isInitialHandshake, secureRenegotiation, clientVerifyData, serverVerifyData); - } + } Handshaker(SSLEngineImpl engine, SSLContextImpl context, ProtocolList enabledProtocols, boolean needCertVerify, @@ -1226,6 +1252,7 @@ * SHA1 hashes are of (different) constant strings, the pre-master * secret, and the nonces provided by the client and the server. */ + @SuppressWarnings("deprecation") private SecretKey calculateMasterSecret(SecretKey preMasterSecret, ProtocolVersion requestedVersion) { @@ -1276,11 +1303,37 @@ int prfHashLength = prf.getPRFHashLength(); int prfBlockSize = prf.getPRFBlockSize(); - @SuppressWarnings("deprecation") - TlsMasterSecretParameterSpec spec = new TlsMasterSecretParameterSpec( - preMasterSecret, (majorVersion & 0xFF), (minorVersion & 0xFF), - clnt_random.random_bytes, svr_random.random_bytes, - prfHashAlg, prfHashLength, prfBlockSize); + TlsMasterSecretParameterSpec spec; + if (session.getUseExtendedMasterSecret()) { + // reset to use the extended master secret algorithm + masterAlg = "SunTlsExtendedMasterSecret"; + + byte[] sessionHash = null; + if (protocolVersion.useTLS12PlusSpec()) { + sessionHash = handshakeHash.getFinishedHash(); + } else { + // TLS 1.0/1.1, DTLS 1.0 + sessionHash = new byte[36]; + try { + handshakeHash.getMD5Clone().digest(sessionHash, 0, 16); + handshakeHash.getSHAClone().digest(sessionHash, 16, 20); + } catch (DigestException de) { + throw new ProviderException(de); + } + } + + spec = new TlsMasterSecretParameterSpec( + preMasterSecret, + (majorVersion & 0xFF), (minorVersion & 0xFF), + sessionHash, + prfHashAlg, prfHashLength, prfBlockSize); + } else { + spec = new TlsMasterSecretParameterSpec( + preMasterSecret, + (majorVersion & 0xFF), (minorVersion & 0xFF), + clnt_random.random_bytes, svr_random.random_bytes, + prfHashAlg, prfHashLength, prfBlockSize); + } try { KeyGenerator kg = JsseJce.getKeyGenerator(masterAlg); diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/security/ssl/HelloExtensions.java --- a/src/java.base/share/classes/sun/security/ssl/HelloExtensions.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/security/ssl/HelloExtensions.java Thu Dec 14 12:28:32 2017 +0000 @@ -93,6 +93,8 @@ extension = new CertStatusReqExtension(s, extlen); } else if (extType == ExtensionType.EXT_STATUS_REQUEST_V2) { extension = new CertStatusReqListV2Extension(s, extlen); + } else if (extType == ExtensionType.EXT_EXTENDED_MASTER_SECRET) { + extension = new ExtendedMasterSecretExtension(s, extlen); } else { extension = new UnknownExtension(s, extlen, extType); } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java --- a/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -91,6 +91,7 @@ private byte compressionMethod; private CipherSuite cipherSuite; private SecretKey masterSecret; + private final boolean useExtendedMasterSecret; /* * Information not part of the SSLv3 protocol spec, but used @@ -148,7 +149,7 @@ */ private SSLSessionImpl() { this(ProtocolVersion.NONE, CipherSuite.C_NULL, null, - new SessionId(false, null), null, -1); + new SessionId(false, null), null, -1, false); } /* @@ -158,9 +159,11 @@ */ SSLSessionImpl(ProtocolVersion protocolVersion, CipherSuite cipherSuite, Collection algorithms, - SecureRandom generator, String host, int port) { + SecureRandom generator, String host, int port, + boolean useExtendedMasterSecret) { this(protocolVersion, cipherSuite, algorithms, - new SessionId(defaultRejoinable, generator), host, port); + new SessionId(defaultRejoinable, generator), host, port, + useExtendedMasterSecret); } /* @@ -168,7 +171,8 @@ */ SSLSessionImpl(ProtocolVersion protocolVersion, CipherSuite cipherSuite, Collection algorithms, - SessionId id, String host, int port) { + SessionId id, String host, int port, + boolean useExtendedMasterSecret) { this.protocolVersion = protocolVersion; sessionId = id; peerCerts = null; @@ -182,6 +186,7 @@ SignatureAndHashAlgorithm.getAlgorithmNames(algorithms); negotiatedMaxFragLen = -1; statusResponses = null; + this.useExtendedMasterSecret = useExtendedMasterSecret; if (debug != null && Debug.isOn("session")) { System.out.println("%% Initialized: " + this); @@ -203,6 +208,10 @@ return masterSecret; } + boolean getUseExtendedMasterSecret() { + return useExtendedMasterSecret; + } + void setPeerCertificates(X509Certificate[] peer) { if (peerCerts == null) { peerCerts = peer; diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java --- a/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java Thu Dec 14 12:28:32 2017 +0000 @@ -529,6 +529,27 @@ } } + // check out the "extended_master_secret" extension + if (useExtendedMasterSecret) { + ExtendedMasterSecretExtension extendedMasterSecretExtension = + (ExtendedMasterSecretExtension)mesg.extensions.get( + ExtensionType.EXT_EXTENDED_MASTER_SECRET); + if (extendedMasterSecretExtension != null) { + requestedToUseEMS = true; + } else if (mesg.protocolVersion.useTLS10PlusSpec()) { + if (!allowLegacyMasterSecret) { + // For full handshake, if the server receives a ClientHello + // without the extension, it SHOULD abort the handshake if + // it does not wish to interoperate with legacy clients. + // + // As if extended master extension is required for full + // handshake, it MUST be used in abbreviated handshake too. + fatalSE(Alerts.alert_handshake_failure, + "Extended Master Secret extension is required"); + } + } + } + // check the ALPN extension ALPNExtension clientHelloALPN = (ALPNExtension) mesg.extensions.get(ExtensionType.EXT_ALPN); @@ -592,8 +613,42 @@ if (resumingSession) { ProtocolVersion oldVersion = previous.getProtocolVersion(); // cannot resume session with different version - if (oldVersion != protocolVersion) { + if (oldVersion != mesg.protocolVersion) { + resumingSession = false; + } + } + + if (resumingSession && useExtendedMasterSecret) { + if (requestedToUseEMS && + !previous.getUseExtendedMasterSecret()) { + // For abbreviated handshake request, If the original + // session did not use the "extended_master_secret" + // extension but the new ClientHello contains the + // extension, then the server MUST NOT perform the + // abbreviated handshake. Instead, it SHOULD continue + // with a full handshake. resumingSession = false; + } else if (!requestedToUseEMS && + previous.getUseExtendedMasterSecret()) { + // For abbreviated handshake request, if the original + // session used the "extended_master_secret" extension + // but the new ClientHello does not contain it, the + // server MUST abort the abbreviated handshake. + fatalSE(Alerts.alert_handshake_failure, + "Missing Extended Master Secret extension " + + "on session resumption"); + } else if (!requestedToUseEMS && + !previous.getUseExtendedMasterSecret()) { + // For abbreviated handshake request, if neither the + // original session nor the new ClientHello uses the + // extension, the server SHOULD abort the handshake. + if (!allowLegacyResumption) { + fatalSE(Alerts.alert_handshake_failure, + "Missing Extended Master Secret extension " + + "on session resumption"); + } else { // Otherwise, continue with a full handshake. + resumingSession = false; + } } } @@ -630,7 +685,7 @@ if (resumingSession) { CipherSuite suite = previous.getSuite(); ClientKeyExchangeService p = - ClientKeyExchangeService.find(suite.keyExchange.name); + ClientKeyExchangeService.find(suite.keyExchange.name); if (p != null) { Principal localPrincipal = previous.getLocalPrincipal(); @@ -784,7 +839,9 @@ session = new SSLSessionImpl(protocolVersion, CipherSuite.C_NULL, getLocalSupportedSignAlgs(), sslContext.getSecureRandom(), - getHostAddressSE(), getPortSE()); + getHostAddressSE(), getPortSE(), + (requestedToUseEMS && + protocolVersion.useTLS10PlusSpec())); if (protocolVersion.useTLS12PlusSpec()) { if (peerSupportedSignAlgs != null) { @@ -886,6 +943,10 @@ m1.extensions.add(maxFragLenExt); } + if (session.getUseExtendedMasterSecret()) { + m1.extensions.add(new ExtendedMasterSecretExtension()); + } + StaplingParameters staplingParams = processStapling(mesg); if (staplingParams != null) { // We now can safely assert status_request[_v2] in our @@ -963,7 +1024,8 @@ * defined in the protocol spec are explicitly stated to require * using RSA certificates. */ - if (ClientKeyExchangeService.find(cipherSuite.keyExchange.name) != null) { + if (ClientKeyExchangeService.find( + cipherSuite.keyExchange.name) != null) { // No external key exchange provider needs a cert now. } else if ((keyExchange != K_DH_ANON) && (keyExchange != K_ECDH_ANON)) { if (certs == null) { diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/security/tools/KeyStoreUtil.java --- a/src/java.base/share/classes/sun/security/tools/KeyStoreUtil.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/security/tools/KeyStoreUtil.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -93,8 +93,9 @@ * MSCAPI KeyStores */ public static boolean isWindowsKeyStore(String storetype) { - return storetype.equalsIgnoreCase("Windows-MY") - || storetype.equalsIgnoreCase("Windows-ROOT"); + return storetype != null + && (storetype.equalsIgnoreCase("Windows-MY") + || storetype.equalsIgnoreCase("Windows-ROOT")); } /** diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/security/tools/keytool/Main.java --- a/src/java.base/share/classes/sun/security/tools/keytool/Main.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/security/tools/keytool/Main.java Thu Dec 14 12:28:32 2017 +0000 @@ -134,8 +134,6 @@ private Set> providers = null; private Set> providerClasses = null; private String storetype = null; - private boolean hasStoretypeOption = false; - private boolean hasSrcStoretypeOption = false; private String srcProviderName = null; private String providerName = null; private String pathlist = null; @@ -549,14 +547,12 @@ passwords.add(storePass); } else if (collator.compare(flags, "-storetype") == 0 || collator.compare(flags, "-deststoretype") == 0) { - storetype = args[++i]; - hasStoretypeOption = true; + storetype = KeyStoreUtil.niceStoreTypeName(args[++i]); } else if (collator.compare(flags, "-srcstorepass") == 0) { srcstorePass = getPass(modifier, args[++i]); passwords.add(srcstorePass); } else if (collator.compare(flags, "-srcstoretype") == 0) { - srcstoretype = args[++i]; - hasSrcStoretypeOption = true; + srcstoretype = KeyStoreUtil.niceStoreTypeName(args[++i]); } else if (collator.compare(flags, "-srckeypass") == 0) { srckeyPass = getPass(modifier, args[++i]); passwords.add(srckeyPass); @@ -708,16 +704,6 @@ ksfname = KeyStoreUtil.getCacerts(); } - if (storetype == null) { - storetype = KeyStore.getDefaultType(); - } - storetype = KeyStoreUtil.niceStoreTypeName(storetype); - - if (srcstoretype == null) { - srcstoretype = KeyStore.getDefaultType(); - } - srcstoretype = KeyStoreUtil.niceStoreTypeName(srcstoretype); - if (P11KEYSTORE.equalsIgnoreCase(storetype) || KeyStoreUtil.isWindowsKeyStore(storetype)) { token = true; @@ -742,11 +728,6 @@ (".storepasswd.and.keypasswd.commands.not.supported.if.storetype.is.{0}"), storetype)); } - if (P12KEYSTORE.equalsIgnoreCase(storetype) && command == KEYPASSWD) { - throw new UnsupportedOperationException(rb.getString - (".keypasswd.commands.not.supported.if.storetype.is.PKCS12")); - } - if (token && (keyPass != null || newPass != null || destKeyPass != null)) { throw new IllegalArgumentException(MessageFormat.format(rb.getString (".keypass.and.new.can.not.be.specified.if.storetype.is.{0}"), storetype)); @@ -923,9 +904,13 @@ // Create new keystore // Probe for keystore type when filename is available if (ksfile != null && ksStream != null && providerName == null && - hasStoretypeOption == false && !inplaceImport) { + storetype == null && !inplaceImport) { keyStore = KeyStore.getInstance(ksfile, storePass); + storetype = keyStore.getType(); } else { + if (storetype == null) { + storetype = KeyStore.getDefaultType(); + } if (providerName == null) { keyStore = KeyStore.getInstance(storetype); } else { @@ -964,6 +949,11 @@ } } + if (P12KEYSTORE.equalsIgnoreCase(storetype) && command == KEYPASSWD) { + throw new UnsupportedOperationException(rb.getString + (".keypasswd.commands.not.supported.if.storetype.is.PKCS12")); + } + // All commands that create or modify the keystore require a keystore // password. @@ -2123,9 +2113,13 @@ try { // Probe for keystore type when filename is available if (srcksfile != null && is != null && srcProviderName == null && - hasSrcStoretypeOption == false) { + srcstoretype == null) { store = KeyStore.getInstance(srcksfile, srcstorePass); + srcstoretype = store.getType(); } else { + if (srcstoretype == null) { + srcstoretype = KeyStore.getDefaultType(); + } if (srcProviderName == null) { store = KeyStore.getInstance(srcstoretype); } else { diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/util/cldr/CLDRCalendarDataProviderImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/java.base/share/classes/sun/util/cldr/CLDRCalendarDataProviderImpl.java Thu Dec 14 12:28:32 2017 +0000 @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.util.cldr; + +import static sun.util.locale.provider.LocaleProviderAdapter.Type; + +import java.util.Arrays; +import java.util.Map; +import java.util.Locale; +import java.util.Set; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import sun.util.locale.provider.LocaleProviderAdapter; +import sun.util.locale.provider.LocaleResources; +import sun.util.locale.provider.CalendarDataProviderImpl; +import sun.util.locale.provider.CalendarDataUtility; + +/** + * Concrete implementation of the + * {@link java.util.spi.CalendarDataProvider CalendarDataProvider} class + * for the CLDR LocaleProviderAdapter. + * + * @author Naoto Sato + */ +public class CLDRCalendarDataProviderImpl extends CalendarDataProviderImpl { + + private static Map firstDay = new ConcurrentHashMap<>(); + private static Map minDays = new ConcurrentHashMap<>(); + + public CLDRCalendarDataProviderImpl(Type type, Set langtags) { + super(type, langtags); + } + + @Override + public int getFirstDayOfWeek(Locale locale) { + return findValue(CalendarDataUtility.FIRST_DAY_OF_WEEK, locale); + } + + @Override + public int getMinimalDaysInFirstWeek(Locale locale) { + return findValue(CalendarDataUtility.MINIMAL_DAYS_IN_FIRST_WEEK, locale); + } + + /** + * Finds the requested integer value for the locale. + * Each resource consists of the following: + * + * (n: cc1 cc2 ... ccx;)* + * + * where 'n' is the integer for the following region codes, terminated by + * a ';'. + * + */ + private static int findValue(String key, Locale locale) { + Map map = CalendarDataUtility.FIRST_DAY_OF_WEEK.equals(key) ? + firstDay : minDays; + String region = locale.getCountry(); + + if (region.isEmpty()) { + return 0; + } + + Integer val = map.get(region); + if (val == null) { + String valStr = + LocaleProviderAdapter.forType(Type.CLDR).getLocaleResources(Locale.ROOT) + .getCalendarData(key); + val = retrieveInteger(valStr, region) + .orElse(retrieveInteger(valStr, "001").orElse(0)); + map.putIfAbsent(region, val); + } + + return val; + } + + private static Optional retrieveInteger(String src, String region) { + return Arrays.stream(src.split(";")) + .filter(entry -> entry.contains(region)) + .map(entry -> entry.substring(0, entry.indexOf(":"))) + .findAny() + .map(Integer::parseInt); + } +} diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java --- a/src/java.base/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java Thu Dec 14 12:28:32 2017 +0000 @@ -27,6 +27,7 @@ import java.security.AccessController; import java.security.AccessControlException; +import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.text.spi.BreakIteratorProvider; @@ -37,15 +38,16 @@ import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Objects; +import java.util.Optional; import java.util.ServiceLoader; import java.util.ServiceConfigurationError; import java.util.Set; import java.util.StringTokenizer; import java.util.concurrent.ConcurrentHashMap; +import java.util.spi.CalendarDataProvider; import sun.util.locale.provider.JRELocaleProviderAdapter; +import sun.util.locale.provider.LocaleDataMetaInfo; import sun.util.locale.provider.LocaleProviderAdapter; -import sun.util.locale.provider.LocaleDataMetaInfo; /** * LocaleProviderAdapter implementation for the CLDR locale data. @@ -106,6 +108,24 @@ } @Override + public CalendarDataProvider getCalendarDataProvider() { + if (calendarDataProvider == null) { + CalendarDataProvider provider = AccessController.doPrivileged( + (PrivilegedAction) () -> + new CLDRCalendarDataProviderImpl( + getAdapterType(), + getLanguageTagSet("CalendarData"))); + + synchronized (this) { + if (calendarDataProvider == null) { + calendarDataProvider = provider; + } + } + } + return calendarDataProvider; + } + + @Override public CollatorProvider getCollatorProvider() { return null; } @@ -123,6 +143,10 @@ @Override protected Set createLanguageTagSet(String category) { + // Assume all categories support the same set as AvailableLocales + // in CLDR adapter. + category = "AvailableLocales"; + // Directly call Base tags, as we know it's in the base module. String supportedLocaleString = baseMetaInfo.availableLanguageTags(category); String nonBaseTags = null; @@ -220,4 +244,11 @@ || langtags.contains(locale.stripExtensions().toLanguageTag()) || langtags.contains(getEquivalentLoc(locale).toLanguageTag()); } + + /** + * Returns the time zone ID from an LDML's short ID + */ + public Optional getTimeZoneID(String shortID) { + return Optional.ofNullable(baseMetaInfo.tzShortIDs().get(shortID)); + } } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/util/locale/provider/CalendarDataProviderImpl.java --- a/src/java.base/share/classes/sun/util/locale/provider/CalendarDataProviderImpl.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/util/locale/provider/CalendarDataProviderImpl.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,14 +46,16 @@ @Override public int getFirstDayOfWeek(Locale locale) { - return LocaleProviderAdapter.forType(type).getLocaleResources(locale) + String fw = LocaleProviderAdapter.forType(type).getLocaleResources(locale) .getCalendarData(CalendarDataUtility.FIRST_DAY_OF_WEEK); + return convertToCalendarData(fw); } @Override public int getMinimalDaysInFirstWeek(Locale locale) { - return LocaleProviderAdapter.forType(type).getLocaleResources(locale) + String md = LocaleProviderAdapter.forType(type).getLocaleResources(locale) .getCalendarData(CalendarDataUtility.MINIMAL_DAYS_IN_FIRST_WEEK); + return convertToCalendarData(md); } @Override @@ -65,4 +67,9 @@ public Set getAvailableLanguageTags() { return langtags; } + + private int convertToCalendarData(String src) { + int val = Integer.parseInt(src); + return (src.isEmpty() || val <= 0 || val > 7) ? 0 : val; + } } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/util/locale/provider/CalendarDataUtility.java --- a/src/java.base/share/classes/sun/util/locale/provider/CalendarDataUtility.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/util/locale/provider/CalendarDataUtility.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,10 +47,34 @@ } public static int retrieveFirstDayOfWeek(Locale locale) { + // Look for the Unicode Extension in the locale parameter + if (locale.hasExtensions()) { + String fw = locale.getUnicodeLocaleType("fw"); + if (fw != null) { + switch (fw.toLowerCase(Locale.ROOT)) { + case "mon": + return MONDAY; + case "tue": + return TUESDAY; + case "wed": + return WEDNESDAY; + case "thu": + return THURSDAY; + case "fri": + return FRIDAY; + case "sat": + return SATURDAY; + case "sun": + return SUNDAY; + } + } + } + LocaleServiceProviderPool pool = LocaleServiceProviderPool.getPool(CalendarDataProvider.class); Integer value = pool.getLocalizedObject(CalendarWeekParameterGetter.INSTANCE, - locale, true, FIRST_DAY_OF_WEEK); + findRegionOverride(locale), + true, FIRST_DAY_OF_WEEK); return (value != null && (value >= SUNDAY && value <= SATURDAY)) ? value : SUNDAY; } @@ -58,7 +82,8 @@ LocaleServiceProviderPool pool = LocaleServiceProviderPool.getPool(CalendarDataProvider.class); Integer value = pool.getLocalizedObject(CalendarWeekParameterGetter.INSTANCE, - locale, true, MINIMAL_DAYS_IN_FIRST_WEEK); + findRegionOverride(locale), + true, MINIMAL_DAYS_IN_FIRST_WEEK); return (value != null && (value >= 1 && value <= 7)) ? value : 1; } @@ -102,6 +127,32 @@ return map; } + /** + * Utility to look for a region override extension. + * If no region override is found, returns the original locale. + */ + public static Locale findRegionOverride(Locale l) { + String rg = l.getUnicodeLocaleType("rg"); + Locale override = l; + + if (rg != null && rg.length() == 6) { + // UN M.49 code should not be allowed here + // cannot use regex here, as it could be a recursive call + rg = rg.toUpperCase(Locale.ROOT); + if (rg.charAt(0) >= 0x0041 && + rg.charAt(0) <= 0x005A && + rg.charAt(1) >= 0x0041 && + rg.charAt(1) <= 0x005A && + rg.substring(2).equals("ZZZZ")) { + override = new Locale.Builder().setLocale(l) + .setRegion(rg.substring(0, 2)) + .build(); + } + } + + return override; + } + static String normalizeCalendarType(String requestID) { String type; if (requestID.equals("gregorian") || requestID.equals("iso8601")) { @@ -179,7 +230,7 @@ } } - private static class CalendarWeekParameterGetter + private static class CalendarWeekParameterGetter implements LocaleServiceProviderPool.LocalizedObjectGetter { private static final CalendarWeekParameterGetter INSTANCE = diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/util/locale/provider/DateFormatProviderImpl.java --- a/src/java.base/share/classes/sun/util/locale/provider/DateFormatProviderImpl.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/util/locale/provider/DateFormatProviderImpl.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ import java.util.Locale; import java.util.MissingResourceException; import java.util.Set; +import java.util.TimeZone; /** * Concrete implementation of the {@link java.text.spi.DateFormatProvider @@ -147,11 +148,14 @@ throw new NullPointerException(); } - SimpleDateFormat sdf = new SimpleDateFormat("", locale); + // Check for region override + Locale rg = CalendarDataUtility.findRegionOverride(locale); + + SimpleDateFormat sdf = new SimpleDateFormat("", rg); Calendar cal = sdf.getCalendar(); try { String pattern = LocaleProviderAdapter.forType(type) - .getLocaleResources(locale).getDateTimePattern(timeStyle, dateStyle, + .getLocaleResources(rg).getDateTimePattern(timeStyle, dateStyle, cal); sdf.applyPattern(pattern); } catch (MissingResourceException mre) { @@ -159,6 +163,15 @@ sdf.applyPattern("M/d/yy h:mm a"); } + // Check for timezone override + String tz = locale.getUnicodeLocaleType("tz"); + if (tz != null) { + sdf.setTimeZone( + TimeZoneNameUtility.convertLDMLShortID(tz) + .map(TimeZone::getTimeZone) + .orElseGet(sdf::getTimeZone)); + } + return sdf; } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java --- a/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -130,7 +130,7 @@ private volatile CurrencyNameProvider currencyNameProvider; private volatile LocaleNameProvider localeNameProvider; private volatile TimeZoneNameProvider timeZoneNameProvider; - private volatile CalendarDataProvider calendarDataProvider; + protected volatile CalendarDataProvider calendarDataProvider; private volatile CalendarNameProvider calendarNameProvider; private volatile CalendarProvider calendarProvider; diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo.java --- a/src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,8 @@ package sun.util.locale.provider; +import java.util.Map; + /** * LocaleData meta info SPI * @@ -46,4 +48,13 @@ * @return concatenated language tags, separated by a space. */ public String availableLanguageTags(String category); + + /** + * Returns a map for short time zone ids in BCP47 Unicode extension and + * the long time zone ids. + * @return map of short id to long ids, separated by a space. + */ + default public Map tzShortIDs() { + return null; + } } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/util/locale/provider/LocaleNameProviderImpl.java --- a/src/java.base/share/classes/sun/util/locale/provider/LocaleNameProviderImpl.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/util/locale/provider/LocaleNameProviderImpl.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -168,6 +168,28 @@ return getDisplayString("%%"+vrnt, locale); } + /** + * @inheritDoc + */ + @Override + public String getDisplayUnicodeExtensionKey(String key, Locale locale) { + super.getDisplayUnicodeExtensionKey(key, locale); // null check + String rbKey = "key." + key; + String name = getDisplayString(rbKey, locale); + return rbKey.equals(name) ? key : name; + } + + /** + * @inheritDoc + */ + @Override + public String getDisplayUnicodeExtensionType(String extType, String key, Locale locale) { + super.getDisplayUnicodeExtensionType(extType, key, locale); // null check + String rbKey = "type." + key + "." + extType; + String name = getDisplayString(rbKey, locale); + return rbKey.equals(name) ? extType : name; + } + private String getDisplayString(String key, Locale locale) { if (key == null || locale == null) { throw new NullPointerException(); diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java --- a/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -122,23 +122,21 @@ return (byte[]) localeData.getBreakIteratorResources(locale).getObject(key); } - int getCalendarData(String key) { - Integer caldata; + public String getCalendarData(String key) { + String caldata = ""; String cacheKey = CALENDAR_DATA + key; removeEmptyReferences(); ResourceReference data = cache.get(cacheKey); - if (data == null || ((caldata = (Integer) data.get()) == null)) { + if (data == null || ((caldata = (String) data.get()) == null)) { ResourceBundle rb = localeData.getCalendarData(locale); if (rb.containsKey(key)) { - caldata = Integer.parseInt(rb.getString(key)); - } else { - caldata = 0; + caldata = rb.getString(key); } cache.put(cacheKey, - new ResourceReference(cacheKey, (Object) caldata, referenceQueue)); + new ResourceReference(cacheKey, caldata, referenceQueue)); } return caldata; diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/util/locale/provider/NumberFormatProviderImpl.java --- a/src/java.base/share/classes/sun/util/locale/provider/NumberFormatProviderImpl.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/util/locale/provider/NumberFormatProviderImpl.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -173,9 +173,14 @@ throw new NullPointerException(); } + // Check for region override + Locale override = locale.getUnicodeLocaleType("nu") == null ? + CalendarDataUtility.findRegionOverride(locale) : + locale; + LocaleProviderAdapter adapter = LocaleProviderAdapter.forType(type); - String[] numberPatterns = adapter.getLocaleResources(locale).getNumberPatterns(); - DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(locale); + String[] numberPatterns = adapter.getLocaleResources(override).getNumberPatterns(); + DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(override); int entry = (choice == INTEGERSTYLE) ? NUMBERSTYLE : choice; DecimalFormat format = new DecimalFormat(numberPatterns[entry], symbols); diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/util/locale/provider/SPILocaleProviderAdapter.java --- a/src/java.base/share/classes/sun/util/locale/provider/SPILocaleProviderAdapter.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/util/locale/provider/SPILocaleProviderAdapter.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -160,28 +160,24 @@ @Override public BreakIterator getWordInstance(Locale locale) { BreakIteratorProvider bip = getImpl(locale); - assert bip != null; return bip.getWordInstance(locale); } @Override public BreakIterator getLineInstance(Locale locale) { BreakIteratorProvider bip = getImpl(locale); - assert bip != null; return bip.getLineInstance(locale); } @Override public BreakIterator getCharacterInstance(Locale locale) { BreakIteratorProvider bip = getImpl(locale); - assert bip != null; return bip.getCharacterInstance(locale); } @Override public BreakIterator getSentenceInstance(Locale locale) { BreakIteratorProvider bip = getImpl(locale); - assert bip != null; return bip.getSentenceInstance(locale); } @@ -215,7 +211,6 @@ @Override public Collator getInstance(Locale locale) { CollatorProvider cp = getImpl(locale); - assert cp != null; return cp.getInstance(locale); } } @@ -249,21 +244,18 @@ @Override public DateFormat getTimeInstance(int style, Locale locale) { DateFormatProvider dfp = getImpl(locale); - assert dfp != null; return dfp.getTimeInstance(style, locale); } @Override public DateFormat getDateInstance(int style, Locale locale) { DateFormatProvider dfp = getImpl(locale); - assert dfp != null; return dfp.getDateInstance(style, locale); } @Override public DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale locale) { DateFormatProvider dfp = getImpl(locale); - assert dfp != null; return dfp.getDateTimeInstance(dateStyle, timeStyle, locale); } } @@ -297,7 +289,6 @@ @Override public DateFormatSymbols getInstance(Locale locale) { DateFormatSymbolsProvider dfsp = getImpl(locale); - assert dfsp != null; return dfsp.getInstance(locale); } } @@ -331,7 +322,6 @@ @Override public DecimalFormatSymbols getInstance(Locale locale) { DecimalFormatSymbolsProvider dfsp = getImpl(locale); - assert dfsp != null; return dfsp.getInstance(locale); } } @@ -365,28 +355,24 @@ @Override public NumberFormat getCurrencyInstance(Locale locale) { NumberFormatProvider nfp = getImpl(locale); - assert nfp != null; return nfp.getCurrencyInstance(locale); } @Override public NumberFormat getIntegerInstance(Locale locale) { NumberFormatProvider nfp = getImpl(locale); - assert nfp != null; return nfp.getIntegerInstance(locale); } @Override public NumberFormat getNumberInstance(Locale locale) { NumberFormatProvider nfp = getImpl(locale); - assert nfp != null; return nfp.getNumberInstance(locale); } @Override public NumberFormat getPercentInstance(Locale locale) { NumberFormatProvider nfp = getImpl(locale); - assert nfp != null; return nfp.getPercentInstance(locale); } } @@ -420,14 +406,12 @@ @Override public int getFirstDayOfWeek(Locale locale) { CalendarDataProvider cdp = getImpl(locale); - assert cdp != null; return cdp.getFirstDayOfWeek(locale); } @Override public int getMinimalDaysInFirstWeek(Locale locale) { CalendarDataProvider cdp = getImpl(locale); - assert cdp != null; return cdp.getMinimalDaysInFirstWeek(locale); } } @@ -463,7 +447,6 @@ int field, int value, int style, Locale locale) { CalendarNameProvider cdp = getImpl(locale); - assert cdp != null; return cdp.getDisplayName(calendarType, field, value, style, locale); } @@ -472,7 +455,6 @@ int field, int style, Locale locale) { CalendarNameProvider cdp = getImpl(locale); - assert cdp != null; return cdp.getDisplayNames(calendarType, field, style, locale); } } @@ -506,14 +488,12 @@ @Override public String getSymbol(String currencyCode, Locale locale) { CurrencyNameProvider cnp = getImpl(locale); - assert cnp != null; return cnp.getSymbol(currencyCode, locale); } @Override public String getDisplayName(String currencyCode, Locale locale) { CurrencyNameProvider cnp = getImpl(locale); - assert cnp != null; return cnp.getDisplayName(currencyCode, locale); } } @@ -547,30 +527,38 @@ @Override public String getDisplayLanguage(String languageCode, Locale locale) { LocaleNameProvider lnp = getImpl(locale); - assert lnp != null; return lnp.getDisplayLanguage(languageCode, locale); } @Override public String getDisplayScript(String scriptCode, Locale locale) { LocaleNameProvider lnp = getImpl(locale); - assert lnp != null; return lnp.getDisplayScript(scriptCode, locale); } @Override public String getDisplayCountry(String countryCode, Locale locale) { LocaleNameProvider lnp = getImpl(locale); - assert lnp != null; return lnp.getDisplayCountry(countryCode, locale); } @Override public String getDisplayVariant(String variant, Locale locale) { LocaleNameProvider lnp = getImpl(locale); - assert lnp != null; return lnp.getDisplayVariant(variant, locale); } + + @Override + public String getDisplayUnicodeExtensionKey(String key, Locale locale) { + LocaleNameProvider lnp = getImpl(locale); + return lnp.getDisplayUnicodeExtensionKey(key, locale); + } + + @Override + public String getDisplayUnicodeExtensionType(String extType, String key, Locale locale) { + LocaleNameProvider lnp = getImpl(locale); + return lnp.getDisplayUnicodeExtensionType(extType, key, locale); + } } static class TimeZoneNameProviderDelegate extends TimeZoneNameProvider @@ -602,14 +590,12 @@ @Override public String getDisplayName(String ID, boolean daylight, int style, Locale locale) { TimeZoneNameProvider tznp = getImpl(locale); - assert tznp != null; return tznp.getDisplayName(ID, daylight, style, locale); } @Override public String getGenericDisplayName(String ID, int style, Locale locale) { TimeZoneNameProvider tznp = getImpl(locale); - assert tznp != null; return tznp.getGenericDisplayName(ID, style, locale); } } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/util/locale/provider/TimeZoneNameUtility.java --- a/src/java.base/share/classes/sun/util/locale/provider/TimeZoneNameUtility.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/util/locale/provider/TimeZoneNameUtility.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,10 +31,13 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.spi.TimeZoneNameProvider; import sun.util.calendar.ZoneInfo; +import sun.util.cldr.CLDRLocaleProviderAdapter; +import static sun.util.locale.provider.LocaleProviderAdapter.Type; /** * Utility class that deals with the localized time zone names @@ -152,6 +155,18 @@ } } + /** + * Converts the time zone id from LDML's 5-letter id to tzdb's id + * + * @param shortID time zone short ID defined in LDML + * @return the tzdb's time zone ID + */ + public static Optional convertLDMLShortID(String shortID) { + return ((CLDRLocaleProviderAdapter)LocaleProviderAdapter.forType(Type.CLDR)) + .getTimeZoneID(shortID) + .map(id -> id.replaceAll("\\s.*", "")); + } + private static String[] retrieveDisplayNamesImpl(String id, Locale locale) { LocaleServiceProviderPool pool = LocaleServiceProviderPool.getPool(TimeZoneNameProvider.class); diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/classes/sun/util/resources/LocaleNames.properties --- a/src/java.base/share/classes/sun/util/resources/LocaleNames.properties Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/classes/sun/util/resources/LocaleNames.properties Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -1164,8 +1164,7 @@ # locale name patterns -# rarely localized DisplayNamePattern={0,choice,0#|1#{1}|2#{1} ({2})} -ListPattern={0,choice,0#|1#{1}|2#{1},{2}|3#{1},{2},{3}} +ListKeyTypePattern={0}:{1} ListCompositionPattern={0},{1} diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/lib/security/cacerts Binary file src/java.base/share/lib/security/cacerts has changed diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/native/include/jvm.h --- a/src/java.base/share/native/include/jvm.h Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1328 +0,0 @@ -/* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * 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. - */ - -#ifndef _JAVASOFT_JVM_H_ -#define _JAVASOFT_JVM_H_ - -#include - -#include "jni.h" -#include "jvm_md.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * This file contains additional functions exported from the VM. - * These functions are complementary to the standard JNI support. - * There are three parts to this file: - * - * First, this file contains the VM-related functions needed by native - * libraries in the standard Java API. For example, the java.lang.Object - * class needs VM-level functions that wait for and notify monitors. - * - * Second, this file contains the functions and constant definitions - * needed by the byte code verifier and class file format checker. - * These functions allow the verifier and format checker to be written - * in a VM-independent way. - * - * Third, this file contains various I/O and network operations needed - * by the standard Java I/O and network APIs. - */ - -/* - * Bump the version number when either of the following happens: - * - * 1. There is a change in JVM_* functions. - * - * 2. There is a change in the contract between VM and Java classes. - * For example, if the VM relies on a new private field in Thread - * class. - */ - -#define JVM_INTERFACE_VERSION 5 - -JNIEXPORT jint JNICALL -JVM_GetInterfaceVersion(void); - -/************************************************************************* - PART 1: Functions for Native Libraries - ************************************************************************/ -/* - * java.lang.Object - */ -JNIEXPORT jint JNICALL -JVM_IHashCode(JNIEnv *env, jobject obj); - -JNIEXPORT void JNICALL -JVM_MonitorWait(JNIEnv *env, jobject obj, jlong ms); - -JNIEXPORT void JNICALL -JVM_MonitorNotify(JNIEnv *env, jobject obj); - -JNIEXPORT void JNICALL -JVM_MonitorNotifyAll(JNIEnv *env, jobject obj); - -JNIEXPORT jobject JNICALL -JVM_Clone(JNIEnv *env, jobject obj); - -/* - * java.lang.String - */ -JNIEXPORT jstring JNICALL -JVM_InternString(JNIEnv *env, jstring str); - -/* - * java.lang.System - */ -JNIEXPORT jlong JNICALL -JVM_CurrentTimeMillis(JNIEnv *env, jclass ignored); - -JNIEXPORT jlong JNICALL -JVM_NanoTime(JNIEnv *env, jclass ignored); - -JNIEXPORT jlong JNICALL -JVM_GetNanoTimeAdjustment(JNIEnv *env, jclass ignored, jlong offset_secs); - -JNIEXPORT void JNICALL -JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos, - jobject dst, jint dst_pos, jint length); - -JNIEXPORT jobject JNICALL -JVM_InitProperties(JNIEnv *env, jobject p); - - -/* - * java.lang.Runtime - */ -JNIEXPORT void JNICALL -JVM_Halt(jint code); - -JNIEXPORT void JNICALL -JVM_GC(void); - -/* Returns the number of real-time milliseconds that have elapsed since the - * least-recently-inspected heap object was last inspected by the garbage - * collector. - * - * For simple stop-the-world collectors this value is just the time - * since the most recent collection. For generational collectors it is the - * time since the oldest generation was most recently collected. Other - * collectors are free to return a pessimistic estimate of the elapsed time, or - * simply the time since the last full collection was performed. - * - * Note that in the presence of reference objects, a given object that is no - * longer strongly reachable may have to be inspected multiple times before it - * can be reclaimed. - */ -JNIEXPORT jlong JNICALL -JVM_MaxObjectInspectionAge(void); - -JNIEXPORT jlong JNICALL -JVM_TotalMemory(void); - -JNIEXPORT jlong JNICALL -JVM_FreeMemory(void); - -JNIEXPORT jlong JNICALL -JVM_MaxMemory(void); - -JNIEXPORT jint JNICALL -JVM_ActiveProcessorCount(void); - -JNIEXPORT void * JNICALL -JVM_LoadLibrary(const char *name); - -JNIEXPORT void JNICALL -JVM_UnloadLibrary(void * handle); - -JNIEXPORT void * JNICALL -JVM_FindLibraryEntry(void *handle, const char *name); - -JNIEXPORT jboolean JNICALL -JVM_IsSupportedJNIVersion(jint version); - -JNIEXPORT jobjectArray JNICALL -JVM_GetVmArguments(JNIEnv *env); - - -/* - * java.lang.Throwable - */ -JNIEXPORT void JNICALL -JVM_FillInStackTrace(JNIEnv *env, jobject throwable); - -/* - * java.lang.StackTraceElement - */ -JNIEXPORT void JNICALL -JVM_InitStackTraceElementArray(JNIEnv *env, jobjectArray elements, jobject throwable); - -JNIEXPORT void JNICALL -JVM_InitStackTraceElement(JNIEnv* env, jobject element, jobject stackFrameInfo); - -/* - * java.lang.StackWalker - */ -enum { - JVM_STACKWALK_FILL_CLASS_REFS_ONLY = 0x2, - JVM_STACKWALK_GET_CALLER_CLASS = 0x04, - JVM_STACKWALK_SHOW_HIDDEN_FRAMES = 0x20, - JVM_STACKWALK_FILL_LIVE_STACK_FRAMES = 0x100 -}; - -JNIEXPORT jobject JNICALL -JVM_CallStackWalk(JNIEnv *env, jobject stackStream, jlong mode, - jint skip_frames, jint frame_count, jint start_index, - jobjectArray frames); - -JNIEXPORT jint JNICALL -JVM_MoreStackWalk(JNIEnv *env, jobject stackStream, jlong mode, jlong anchor, - jint frame_count, jint start_index, - jobjectArray frames); - -/* - * java.lang.Thread - */ -JNIEXPORT void JNICALL -JVM_StartThread(JNIEnv *env, jobject thread); - -JNIEXPORT void JNICALL -JVM_StopThread(JNIEnv *env, jobject thread, jobject exception); - -JNIEXPORT jboolean JNICALL -JVM_IsThreadAlive(JNIEnv *env, jobject thread); - -JNIEXPORT void JNICALL -JVM_SuspendThread(JNIEnv *env, jobject thread); - -JNIEXPORT void JNICALL -JVM_ResumeThread(JNIEnv *env, jobject thread); - -JNIEXPORT void JNICALL -JVM_SetThreadPriority(JNIEnv *env, jobject thread, jint prio); - -JNIEXPORT void JNICALL -JVM_Yield(JNIEnv *env, jclass threadClass); - -JNIEXPORT void JNICALL -JVM_Sleep(JNIEnv *env, jclass threadClass, jlong millis); - -JNIEXPORT jobject JNICALL -JVM_CurrentThread(JNIEnv *env, jclass threadClass); - -JNIEXPORT jint JNICALL -JVM_CountStackFrames(JNIEnv *env, jobject thread); - -JNIEXPORT void JNICALL -JVM_Interrupt(JNIEnv *env, jobject thread); - -JNIEXPORT jboolean JNICALL -JVM_IsInterrupted(JNIEnv *env, jobject thread, jboolean clearInterrupted); - -JNIEXPORT jboolean JNICALL -JVM_HoldsLock(JNIEnv *env, jclass threadClass, jobject obj); - -JNIEXPORT void JNICALL -JVM_DumpAllStacks(JNIEnv *env, jclass unused); - -JNIEXPORT jobjectArray JNICALL -JVM_GetAllThreads(JNIEnv *env, jclass dummy); - -JNIEXPORT void JNICALL -JVM_SetNativeThreadName(JNIEnv *env, jobject jthread, jstring name); - -/* getStackTrace() and getAllStackTraces() method */ -JNIEXPORT jobjectArray JNICALL -JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threads); - -/* - * java.lang.SecurityManager - */ -JNIEXPORT jobjectArray JNICALL -JVM_GetClassContext(JNIEnv *env); - -/* - * java.lang.Package - */ -JNIEXPORT jstring JNICALL -JVM_GetSystemPackage(JNIEnv *env, jstring name); - -JNIEXPORT jobjectArray JNICALL -JVM_GetSystemPackages(JNIEnv *env); - -/* - * java.lang.ref.Reference - */ -JNIEXPORT jobject JNICALL -JVM_GetAndClearReferencePendingList(JNIEnv *env); - -JNIEXPORT jboolean JNICALL -JVM_HasReferencePendingList(JNIEnv *env); - -JNIEXPORT void JNICALL -JVM_WaitForReferencePendingList(JNIEnv *env); - -/* - * java.io.ObjectInputStream - */ -JNIEXPORT jobject JNICALL -JVM_LatestUserDefinedLoader(JNIEnv *env); - -/* - * java.lang.reflect.Array - */ -JNIEXPORT jint JNICALL -JVM_GetArrayLength(JNIEnv *env, jobject arr); - -JNIEXPORT jobject JNICALL -JVM_GetArrayElement(JNIEnv *env, jobject arr, jint index); - -JNIEXPORT jvalue JNICALL -JVM_GetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jint wCode); - -JNIEXPORT void JNICALL -JVM_SetArrayElement(JNIEnv *env, jobject arr, jint index, jobject val); - -JNIEXPORT void JNICALL -JVM_SetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jvalue v, - unsigned char vCode); - -JNIEXPORT jobject JNICALL -JVM_NewArray(JNIEnv *env, jclass eltClass, jint length); - -JNIEXPORT jobject JNICALL -JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim); - -/* - * java.lang.Class and java.lang.ClassLoader - */ - -#define JVM_CALLER_DEPTH -1 - -/* - * Returns the immediate caller class of the native method invoking - * JVM_GetCallerClass. The Method.invoke and other frames due to - * reflection machinery are skipped. - * - * The depth parameter must be -1 (JVM_DEPTH). The caller is expected - * to be marked with sun.reflect.CallerSensitive. The JVM will throw - * an error if it is not marked propertly. - */ -JNIEXPORT jclass JNICALL -JVM_GetCallerClass(JNIEnv *env, int depth); - - -/* - * Find primitive classes - * utf: class name - */ -JNIEXPORT jclass JNICALL -JVM_FindPrimitiveClass(JNIEnv *env, const char *utf); - - -/* - * Find a class from a boot class loader. Returns NULL if class not found. - */ -JNIEXPORT jclass JNICALL -JVM_FindClassFromBootLoader(JNIEnv *env, const char *name); - -/* - * Find a class from a given class loader. Throws ClassNotFoundException. - * name: name of class - * init: whether initialization is done - * loader: class loader to look up the class. This may not be the same as the caller's - * class loader. - * caller: initiating class. The initiating class may be null when a security - * manager is not installed. - */ -JNIEXPORT jclass JNICALL -JVM_FindClassFromCaller(JNIEnv *env, const char *name, jboolean init, - jobject loader, jclass caller); - -/* - * Find a class from a given class. - */ -JNIEXPORT jclass JNICALL -JVM_FindClassFromClass(JNIEnv *env, const char *name, jboolean init, - jclass from); - -/* Find a loaded class cached by the VM */ -JNIEXPORT jclass JNICALL -JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name); - -/* Define a class */ -JNIEXPORT jclass JNICALL -JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, - jsize len, jobject pd); - -/* Define a class with a source (added in JDK1.5) */ -JNIEXPORT jclass JNICALL -JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader, - const jbyte *buf, jsize len, jobject pd, - const char *source); - -/* - * Module support funcions - */ - -/* - * Define a module with the specified packages and bind the module to the - * given class loader. - * module: module to define - * is_open: specifies if module is open (currently ignored) - * version: the module version - * location: the module location - * packages: list of packages in the module - * num_packages: number of packages in the module - */ -JNIEXPORT void JNICALL -JVM_DefineModule(JNIEnv *env, jobject module, jboolean is_open, jstring version, - jstring location, const char* const* packages, jsize num_packages); - -/* - * Set the boot loader's unnamed module. - * module: boot loader's unnamed module - */ -JNIEXPORT void JNICALL -JVM_SetBootLoaderUnnamedModule(JNIEnv *env, jobject module); - -/* - * Do a qualified export of a package. - * from_module: module containing the package to export - * package: name of the package to export - * to_module: module to export the package to - */ -JNIEXPORT void JNICALL -JVM_AddModuleExports(JNIEnv *env, jobject from_module, const char* package, jobject to_module); - -/* - * Do an export of a package to all unnamed modules. - * from_module: module containing the package to export - * package: name of the package to export to all unnamed modules - */ -JNIEXPORT void JNICALL -JVM_AddModuleExportsToAllUnnamed(JNIEnv *env, jobject from_module, const char* package); - -/* - * Do an unqualified export of a package. - * from_module: module containing the package to export - * package: name of the package to export - */ -JNIEXPORT void JNICALL -JVM_AddModuleExportsToAll(JNIEnv *env, jobject from_module, const char* package); - -/* - * Add a module to the list of modules that a given module can read. - * from_module: module requesting read access - * source_module: module that from_module wants to read - */ -JNIEXPORT void JNICALL -JVM_AddReadsModule(JNIEnv *env, jobject from_module, jobject source_module); - -/* - * Reflection support functions - */ - -JNIEXPORT jstring JNICALL -JVM_GetClassName(JNIEnv *env, jclass cls); - -JNIEXPORT jobjectArray JNICALL -JVM_GetClassInterfaces(JNIEnv *env, jclass cls); - -JNIEXPORT jboolean JNICALL -JVM_IsInterface(JNIEnv *env, jclass cls); - -JNIEXPORT jobjectArray JNICALL -JVM_GetClassSigners(JNIEnv *env, jclass cls); - -JNIEXPORT void JNICALL -JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers); - -JNIEXPORT jobject JNICALL -JVM_GetProtectionDomain(JNIEnv *env, jclass cls); - -JNIEXPORT jboolean JNICALL -JVM_IsArrayClass(JNIEnv *env, jclass cls); - -JNIEXPORT jboolean JNICALL -JVM_IsPrimitiveClass(JNIEnv *env, jclass cls); - -JNIEXPORT jint JNICALL -JVM_GetClassModifiers(JNIEnv *env, jclass cls); - -JNIEXPORT jobjectArray JNICALL -JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass); - -JNIEXPORT jclass JNICALL -JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass); - -JNIEXPORT jstring JNICALL -JVM_GetSimpleBinaryName(JNIEnv *env, jclass ofClass); - -/* Generics support (JDK 1.5) */ -JNIEXPORT jstring JNICALL -JVM_GetClassSignature(JNIEnv *env, jclass cls); - -/* Annotations support (JDK 1.5) */ -JNIEXPORT jbyteArray JNICALL -JVM_GetClassAnnotations(JNIEnv *env, jclass cls); - -/* Type use annotations support (JDK 1.8) */ - -JNIEXPORT jbyteArray JNICALL -JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls); - -JNIEXPORT jbyteArray JNICALL -JVM_GetFieldTypeAnnotations(JNIEnv *env, jobject field); - -JNIEXPORT jbyteArray JNICALL -JVM_GetMethodTypeAnnotations(JNIEnv *env, jobject method); - -/* - * New (JDK 1.4) reflection implementation - */ - -JNIEXPORT jobjectArray JNICALL -JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly); - -JNIEXPORT jobjectArray JNICALL -JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, jboolean publicOnly); - -JNIEXPORT jobjectArray JNICALL -JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly); - -/* Differs from JVM_GetClassModifiers in treatment of inner classes. - This returns the access flags for the class as specified in the - class file rather than searching the InnerClasses attribute (if - present) to find the source-level access flags. Only the values of - the low 13 bits (i.e., a mask of 0x1FFF) are guaranteed to be - valid. */ -JNIEXPORT jint JNICALL -JVM_GetClassAccessFlags(JNIEnv *env, jclass cls); - -/* The following two reflection routines are still needed due to startup time issues */ -/* - * java.lang.reflect.Method - */ -JNIEXPORT jobject JNICALL -JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jobjectArray args0); - -/* - * java.lang.reflect.Constructor - */ -JNIEXPORT jobject JNICALL -JVM_NewInstanceFromConstructor(JNIEnv *env, jobject c, jobjectArray args0); - -/* - * Constant pool access; currently used to implement reflective access to annotations (JDK 1.5) - */ - -JNIEXPORT jobject JNICALL -JVM_GetClassConstantPool(JNIEnv *env, jclass cls); - -JNIEXPORT jint JNICALL JVM_ConstantPoolGetSize -(JNIEnv *env, jobject unused, jobject jcpool); - -JNIEXPORT jclass JNICALL JVM_ConstantPoolGetClassAt -(JNIEnv *env, jobject unused, jobject jcpool, jint index); - -JNIEXPORT jclass JNICALL JVM_ConstantPoolGetClassAtIfLoaded -(JNIEnv *env, jobject unused, jobject jcpool, jint index); - -JNIEXPORT jint JNICALL JVM_ConstantPoolGetClassRefIndexAt -(JNIEnv *env, jobject obj, jobject unused, jint index); - -JNIEXPORT jobject JNICALL JVM_ConstantPoolGetMethodAt -(JNIEnv *env, jobject unused, jobject jcpool, jint index); - -JNIEXPORT jobject JNICALL JVM_ConstantPoolGetMethodAtIfLoaded -(JNIEnv *env, jobject unused, jobject jcpool, jint index); - -JNIEXPORT jobject JNICALL JVM_ConstantPoolGetFieldAt -(JNIEnv *env, jobject unused, jobject jcpool, jint index); - -JNIEXPORT jobject JNICALL JVM_ConstantPoolGetFieldAtIfLoaded -(JNIEnv *env, jobject unused, jobject jcpool, jint index); - -JNIEXPORT jobjectArray JNICALL JVM_ConstantPoolGetMemberRefInfoAt -(JNIEnv *env, jobject unused, jobject jcpool, jint index); - -JNIEXPORT jint JNICALL JVM_ConstantPoolGetNameAndTypeRefIndexAt -(JNIEnv *env, jobject obj, jobject unused, jint index); - -JNIEXPORT jobjectArray JNICALL JVM_ConstantPoolGetNameAndTypeRefInfoAt -(JNIEnv *env, jobject obj, jobject unused, jint index); - -JNIEXPORT jint JNICALL JVM_ConstantPoolGetIntAt -(JNIEnv *env, jobject unused, jobject jcpool, jint index); - -JNIEXPORT jlong JNICALL JVM_ConstantPoolGetLongAt -(JNIEnv *env, jobject unused, jobject jcpool, jint index); - -JNIEXPORT jfloat JNICALL JVM_ConstantPoolGetFloatAt -(JNIEnv *env, jobject unused, jobject jcpool, jint index); - -JNIEXPORT jdouble JNICALL JVM_ConstantPoolGetDoubleAt -(JNIEnv *env, jobject unused, jobject jcpool, jint index); - -JNIEXPORT jstring JNICALL JVM_ConstantPoolGetStringAt -(JNIEnv *env, jobject unused, jobject jcpool, jint index); - -JNIEXPORT jstring JNICALL JVM_ConstantPoolGetUTF8At -(JNIEnv *env, jobject unused, jobject jcpool, jint index); - -JNIEXPORT jbyte JNICALL JVM_ConstantPoolGetTagAt -(JNIEnv *env, jobject unused, jobject jcpool, jint index); - -/* - * Parameter reflection - */ - -JNIEXPORT jobjectArray JNICALL -JVM_GetMethodParameters(JNIEnv *env, jobject method); - -/* - * java.security.* - */ - -JNIEXPORT jobject JNICALL -JVM_DoPrivileged(JNIEnv *env, jclass cls, - jobject action, jobject context, jboolean wrapException); - -JNIEXPORT jobject JNICALL -JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls); - -JNIEXPORT jobject JNICALL -JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls); - -/* - * Signal support, used to implement the shutdown sequence. Every VM must - * support JVM_SIGINT and JVM_SIGTERM, raising the former for user interrupts - * (^C) and the latter for external termination (kill, system shutdown, etc.). - * Other platform-dependent signal values may also be supported. - */ - -JNIEXPORT void * JNICALL -JVM_RegisterSignal(jint sig, void *handler); - -JNIEXPORT jboolean JNICALL -JVM_RaiseSignal(jint sig); - -JNIEXPORT jint JNICALL -JVM_FindSignal(const char *name); - -/* - * Retrieve the assertion directives for the specified class. - */ -JNIEXPORT jboolean JNICALL -JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls); - -/* - * Retrieve the assertion directives from the VM. - */ -JNIEXPORT jobject JNICALL -JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused); - -/* - * java.util.concurrent.atomic.AtomicLong - */ -JNIEXPORT jboolean JNICALL -JVM_SupportsCX8(void); - -/* - * com.sun.dtrace.jsdt support - */ - -#define JVM_TRACING_DTRACE_VERSION 1 - -/* - * Structure to pass one probe description to JVM - */ -typedef struct { - jmethodID method; - jstring function; - jstring name; - void* reserved[4]; // for future use -} JVM_DTraceProbe; - -/** - * Encapsulates the stability ratings for a DTrace provider field - */ -typedef struct { - jint nameStability; - jint dataStability; - jint dependencyClass; -} JVM_DTraceInterfaceAttributes; - -/* - * Structure to pass one provider description to JVM - */ -typedef struct { - jstring name; - JVM_DTraceProbe* probes; - jint probe_count; - JVM_DTraceInterfaceAttributes providerAttributes; - JVM_DTraceInterfaceAttributes moduleAttributes; - JVM_DTraceInterfaceAttributes functionAttributes; - JVM_DTraceInterfaceAttributes nameAttributes; - JVM_DTraceInterfaceAttributes argsAttributes; - void* reserved[4]; // for future use -} JVM_DTraceProvider; - -/* - * Get the version number the JVM was built with - */ -JNIEXPORT jint JNICALL -JVM_DTraceGetVersion(JNIEnv* env); - -/* - * Register new probe with given signature, return global handle - * - * The version passed in is the version that the library code was - * built with. - */ -JNIEXPORT jlong JNICALL -JVM_DTraceActivate(JNIEnv* env, jint version, jstring module_name, - jint providers_count, JVM_DTraceProvider* providers); - -/* - * Check JSDT probe - */ -JNIEXPORT jboolean JNICALL -JVM_DTraceIsProbeEnabled(JNIEnv* env, jmethodID method); - -/* - * Destroy custom DOF - */ -JNIEXPORT void JNICALL -JVM_DTraceDispose(JNIEnv* env, jlong activation_handle); - -/* - * Check to see if DTrace is supported by OS - */ -JNIEXPORT jboolean JNICALL -JVM_DTraceIsSupported(JNIEnv* env); - -/************************************************************************* - PART 2: Support for the Verifier and Class File Format Checker - ************************************************************************/ -/* - * Return the class name in UTF format. The result is valid - * until JVM_ReleaseUTf is called. - * - * The caller must treat the string as a constant and not modify it - * in any way. - */ -JNIEXPORT const char * JNICALL -JVM_GetClassNameUTF(JNIEnv *env, jclass cb); - -/* - * Returns the constant pool types in the buffer provided by "types." - */ -JNIEXPORT void JNICALL -JVM_GetClassCPTypes(JNIEnv *env, jclass cb, unsigned char *types); - -/* - * Returns the number of Constant Pool entries. - */ -JNIEXPORT jint JNICALL -JVM_GetClassCPEntriesCount(JNIEnv *env, jclass cb); - -/* - * Returns the number of *declared* fields or methods. - */ -JNIEXPORT jint JNICALL -JVM_GetClassFieldsCount(JNIEnv *env, jclass cb); - -JNIEXPORT jint JNICALL -JVM_GetClassMethodsCount(JNIEnv *env, jclass cb); - -/* - * Returns the CP indexes of exceptions raised by a given method. - * Places the result in the given buffer. - * - * The method is identified by method_index. - */ -JNIEXPORT void JNICALL -JVM_GetMethodIxExceptionIndexes(JNIEnv *env, jclass cb, jint method_index, - unsigned short *exceptions); -/* - * Returns the number of exceptions raised by a given method. - * The method is identified by method_index. - */ -JNIEXPORT jint JNICALL -JVM_GetMethodIxExceptionsCount(JNIEnv *env, jclass cb, jint method_index); - -/* - * Returns the byte code sequence of a given method. - * Places the result in the given buffer. - * - * The method is identified by method_index. - */ -JNIEXPORT void JNICALL -JVM_GetMethodIxByteCode(JNIEnv *env, jclass cb, jint method_index, - unsigned char *code); - -/* - * Returns the length of the byte code sequence of a given method. - * The method is identified by method_index. - */ -JNIEXPORT jint JNICALL -JVM_GetMethodIxByteCodeLength(JNIEnv *env, jclass cb, jint method_index); - -/* - * A structure used to a capture exception table entry in a Java method. - */ -typedef struct { - jint start_pc; - jint end_pc; - jint handler_pc; - jint catchType; -} JVM_ExceptionTableEntryType; - -/* - * Returns the exception table entry at entry_index of a given method. - * Places the result in the given buffer. - * - * The method is identified by method_index. - */ -JNIEXPORT void JNICALL -JVM_GetMethodIxExceptionTableEntry(JNIEnv *env, jclass cb, jint method_index, - jint entry_index, - JVM_ExceptionTableEntryType *entry); - -/* - * Returns the length of the exception table of a given method. - * The method is identified by method_index. - */ -JNIEXPORT jint JNICALL -JVM_GetMethodIxExceptionTableLength(JNIEnv *env, jclass cb, int index); - -/* - * Returns the modifiers of a given field. - * The field is identified by field_index. - */ -JNIEXPORT jint JNICALL -JVM_GetFieldIxModifiers(JNIEnv *env, jclass cb, int index); - -/* - * Returns the modifiers of a given method. - * The method is identified by method_index. - */ -JNIEXPORT jint JNICALL -JVM_GetMethodIxModifiers(JNIEnv *env, jclass cb, int index); - -/* - * Returns the number of local variables of a given method. - * The method is identified by method_index. - */ -JNIEXPORT jint JNICALL -JVM_GetMethodIxLocalsCount(JNIEnv *env, jclass cb, int index); - -/* - * Returns the number of arguments (including this pointer) of a given method. - * The method is identified by method_index. - */ -JNIEXPORT jint JNICALL -JVM_GetMethodIxArgsSize(JNIEnv *env, jclass cb, int index); - -/* - * Returns the maximum amount of stack (in words) used by a given method. - * The method is identified by method_index. - */ -JNIEXPORT jint JNICALL -JVM_GetMethodIxMaxStack(JNIEnv *env, jclass cb, int index); - -/* - * Is a given method a constructor. - * The method is identified by method_index. - */ -JNIEXPORT jboolean JNICALL -JVM_IsConstructorIx(JNIEnv *env, jclass cb, int index); - -/* - * Is the given method generated by the VM. - * The method is identified by method_index. - */ -JNIEXPORT jboolean JNICALL -JVM_IsVMGeneratedMethodIx(JNIEnv *env, jclass cb, int index); - -/* - * Returns the name of a given method in UTF format. - * The result remains valid until JVM_ReleaseUTF is called. - * - * The caller must treat the string as a constant and not modify it - * in any way. - */ -JNIEXPORT const char * JNICALL -JVM_GetMethodIxNameUTF(JNIEnv *env, jclass cb, jint index); - -/* - * Returns the signature of a given method in UTF format. - * The result remains valid until JVM_ReleaseUTF is called. - * - * The caller must treat the string as a constant and not modify it - * in any way. - */ -JNIEXPORT const char * JNICALL -JVM_GetMethodIxSignatureUTF(JNIEnv *env, jclass cb, jint index); - -/* - * Returns the name of the field referred to at a given constant pool - * index. - * - * The result is in UTF format and remains valid until JVM_ReleaseUTF - * is called. - * - * The caller must treat the string as a constant and not modify it - * in any way. - */ -JNIEXPORT const char * JNICALL -JVM_GetCPFieldNameUTF(JNIEnv *env, jclass cb, jint index); - -/* - * Returns the name of the method referred to at a given constant pool - * index. - * - * The result is in UTF format and remains valid until JVM_ReleaseUTF - * is called. - * - * The caller must treat the string as a constant and not modify it - * in any way. - */ -JNIEXPORT const char * JNICALL -JVM_GetCPMethodNameUTF(JNIEnv *env, jclass cb, jint index); - -/* - * Returns the signature of the method referred to at a given constant pool - * index. - * - * The result is in UTF format and remains valid until JVM_ReleaseUTF - * is called. - * - * The caller must treat the string as a constant and not modify it - * in any way. - */ -JNIEXPORT const char * JNICALL -JVM_GetCPMethodSignatureUTF(JNIEnv *env, jclass cb, jint index); - -/* - * Returns the signature of the field referred to at a given constant pool - * index. - * - * The result is in UTF format and remains valid until JVM_ReleaseUTF - * is called. - * - * The caller must treat the string as a constant and not modify it - * in any way. - */ -JNIEXPORT const char * JNICALL -JVM_GetCPFieldSignatureUTF(JNIEnv *env, jclass cb, jint index); - -/* - * Returns the class name referred to at a given constant pool index. - * - * The result is in UTF format and remains valid until JVM_ReleaseUTF - * is called. - * - * The caller must treat the string as a constant and not modify it - * in any way. - */ -JNIEXPORT const char * JNICALL -JVM_GetCPClassNameUTF(JNIEnv *env, jclass cb, jint index); - -/* - * Returns the class name referred to at a given constant pool index. - * - * The constant pool entry must refer to a CONSTANT_Fieldref. - * - * The result is in UTF format and remains valid until JVM_ReleaseUTF - * is called. - * - * The caller must treat the string as a constant and not modify it - * in any way. - */ -JNIEXPORT const char * JNICALL -JVM_GetCPFieldClassNameUTF(JNIEnv *env, jclass cb, jint index); - -/* - * Returns the class name referred to at a given constant pool index. - * - * The constant pool entry must refer to CONSTANT_Methodref or - * CONSTANT_InterfaceMethodref. - * - * The result is in UTF format and remains valid until JVM_ReleaseUTF - * is called. - * - * The caller must treat the string as a constant and not modify it - * in any way. - */ -JNIEXPORT const char * JNICALL -JVM_GetCPMethodClassNameUTF(JNIEnv *env, jclass cb, jint index); - -/* - * Returns the modifiers of a field in calledClass. The field is - * referred to in class cb at constant pool entry index. - * - * The caller must treat the string as a constant and not modify it - * in any way. - * - * Returns -1 if the field does not exist in calledClass. - */ -JNIEXPORT jint JNICALL -JVM_GetCPFieldModifiers(JNIEnv *env, jclass cb, int index, jclass calledClass); - -/* - * Returns the modifiers of a method in calledClass. The method is - * referred to in class cb at constant pool entry index. - * - * Returns -1 if the method does not exist in calledClass. - */ -JNIEXPORT jint JNICALL -JVM_GetCPMethodModifiers(JNIEnv *env, jclass cb, int index, jclass calledClass); - -/* - * Releases the UTF string obtained from the VM. - */ -JNIEXPORT void JNICALL -JVM_ReleaseUTF(const char *utf); - -/* - * Compare if two classes are in the same package. - */ -JNIEXPORT jboolean JNICALL -JVM_IsSameClassPackage(JNIEnv *env, jclass class1, jclass class2); - -/* Get classfile constants */ -#include "classfile_constants.h" - -/* - * A function defined by the byte-code verifier and called by the VM. - * This is not a function implemented in the VM. - * - * Returns JNI_FALSE if verification fails. A detailed error message - * will be places in msg_buf, whose length is specified by buf_len. - */ -typedef jboolean (*verifier_fn_t)(JNIEnv *env, - jclass cb, - char * msg_buf, - jint buf_len); - - -/* - * Support for a VM-independent class format checker. - */ -typedef struct { - unsigned long code; /* byte code */ - unsigned long excs; /* exceptions */ - unsigned long etab; /* catch table */ - unsigned long lnum; /* line number */ - unsigned long lvar; /* local vars */ -} method_size_info; - -typedef struct { - unsigned int constants; /* constant pool */ - unsigned int fields; - unsigned int methods; - unsigned int interfaces; - unsigned int fields2; /* number of static 2-word fields */ - unsigned int innerclasses; /* # of records in InnerClasses attr */ - - method_size_info clinit; /* memory used in clinit */ - method_size_info main; /* used everywhere else */ -} class_size_info; - -/* - * Functions defined in libjava.so to perform string conversions. - * - */ - -typedef jstring (*to_java_string_fn_t)(JNIEnv *env, char *str); - -typedef char *(*to_c_string_fn_t)(JNIEnv *env, jstring s, jboolean *b); - -/* This is the function defined in libjava.so that performs class - * format checks. This functions fills in size information about - * the class file and returns: - * - * 0: good - * -1: out of memory - * -2: bad format - * -3: unsupported version - * -4: bad class name - */ - -typedef jint (*check_format_fn_t)(char *class_name, - unsigned char *data, - unsigned int data_size, - class_size_info *class_size, - char *message_buffer, - jint buffer_length, - jboolean measure_only, - jboolean check_relaxed); - -#define JVM_RECOGNIZED_CLASS_MODIFIERS (JVM_ACC_PUBLIC | \ - JVM_ACC_FINAL | \ - JVM_ACC_SUPER | \ - JVM_ACC_INTERFACE | \ - JVM_ACC_ABSTRACT | \ - JVM_ACC_ANNOTATION | \ - JVM_ACC_ENUM | \ - JVM_ACC_SYNTHETIC) - -#define JVM_RECOGNIZED_FIELD_MODIFIERS (JVM_ACC_PUBLIC | \ - JVM_ACC_PRIVATE | \ - JVM_ACC_PROTECTED | \ - JVM_ACC_STATIC | \ - JVM_ACC_FINAL | \ - JVM_ACC_VOLATILE | \ - JVM_ACC_TRANSIENT | \ - JVM_ACC_ENUM | \ - JVM_ACC_SYNTHETIC) - -#define JVM_RECOGNIZED_METHOD_MODIFIERS (JVM_ACC_PUBLIC | \ - JVM_ACC_PRIVATE | \ - JVM_ACC_PROTECTED | \ - JVM_ACC_STATIC | \ - JVM_ACC_FINAL | \ - JVM_ACC_SYNCHRONIZED | \ - JVM_ACC_BRIDGE | \ - JVM_ACC_VARARGS | \ - JVM_ACC_NATIVE | \ - JVM_ACC_ABSTRACT | \ - JVM_ACC_STRICT | \ - JVM_ACC_SYNTHETIC) - -/* - * This is the function defined in libjava.so to perform path - * canonicalization. VM call this function before opening jar files - * to load system classes. - * - */ - -typedef int (*canonicalize_fn_t)(JNIEnv *env, char *orig, char *out, int len); - -/************************************************************************* - PART 3: I/O and Network Support - ************************************************************************/ - -/* - * Convert a pathname into native format. This function does syntactic - * cleanup, such as removing redundant separator characters. It modifies - * the given pathname string in place. - */ -JNIEXPORT char * JNICALL -JVM_NativePath(char *); - -/* - * The standard printing functions supported by the Java VM. (Should they - * be renamed to JVM_* in the future? - */ - -/* jio_snprintf() and jio_vsnprintf() behave like snprintf(3) and vsnprintf(3), - * respectively, with the following differences: - * - The string written to str is always zero-terminated, also in case of - * truncation (count is too small to hold the result string), unless count - * is 0. In case of truncation count-1 characters are written and '\0' - * appendend. - * - If count is too small to hold the whole string, -1 is returned across - * all platforms. */ - -JNIEXPORT int -jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args); - -JNIEXPORT int -jio_snprintf(char *str, size_t count, const char *fmt, ...); - -JNIEXPORT int -jio_fprintf(FILE *, const char *fmt, ...); - -JNIEXPORT int -jio_vfprintf(FILE *, const char *fmt, va_list args); - - -JNIEXPORT void * JNICALL -JVM_RawMonitorCreate(void); - -JNIEXPORT void JNICALL -JVM_RawMonitorDestroy(void *mon); - -JNIEXPORT jint JNICALL -JVM_RawMonitorEnter(void *mon); - -JNIEXPORT void JNICALL -JVM_RawMonitorExit(void *mon); - -/* - * java.lang.management support - */ -JNIEXPORT void* JNICALL -JVM_GetManagement(jint version); - -/* - * com.sun.tools.attach.VirtualMachine support - * - * Initialize the agent properties with the properties maintained in the VM. - */ -JNIEXPORT jobject JNICALL -JVM_InitAgentProperties(JNIEnv *env, jobject agent_props); - -JNIEXPORT jstring JNICALL -JVM_GetTemporaryDirectory(JNIEnv *env); - -/* Generics reflection support. - * - * Returns information about the given class's EnclosingMethod - * attribute, if present, or null if the class had no enclosing - * method. - * - * If non-null, the returned array contains three elements. Element 0 - * is the java.lang.Class of which the enclosing method is a member, - * and elements 1 and 2 are the java.lang.Strings for the enclosing - * method's name and descriptor, respectively. - */ -JNIEXPORT jobjectArray JNICALL -JVM_GetEnclosingMethodInfo(JNIEnv* env, jclass ofClass); - -/* ========================================================================= - * The following defines a private JVM interface that the JDK can query - * for the JVM version and capabilities. sun.misc.Version defines - * the methods for getting the VM version and its capabilities. - * - * When a new bit is added, the following should be updated to provide - * access to the new capability: - * HS: JVM_GetVersionInfo and Abstract_VM_Version class - * SDK: Version class - * - * Similary, a private JDK interface JDK_GetVersionInfo0 is defined for - * JVM to query for the JDK version and capabilities. - * - * When a new bit is added, the following should be updated to provide - * access to the new capability: - * HS: JDK_Version class - * SDK: JDK_GetVersionInfo0 - * - * ========================================================================== - */ -typedef struct { - unsigned int jvm_version; /* Encoded $VNUM as specified by JEP-223 */ - unsigned int patch_version : 8; /* JEP-223 patch version */ - unsigned int reserved3 : 8; - unsigned int reserved1 : 16; - unsigned int reserved2; - - /* The following bits represents JVM supports that JDK has dependency on. - * JDK can use these bits to determine which JVM version - * and support it has to maintain runtime compatibility. - * - * When a new bit is added in a minor or update release, make sure - * the new bit is also added in the main/baseline. - */ - unsigned int is_attach_supported : 1; - unsigned int : 31; - unsigned int : 32; - unsigned int : 32; -} jvm_version_info; - -#define JVM_VERSION_MAJOR(version) ((version & 0xFF000000) >> 24) -#define JVM_VERSION_MINOR(version) ((version & 0x00FF0000) >> 16) -#define JVM_VERSION_SECURITY(version) ((version & 0x0000FF00) >> 8) -#define JVM_VERSION_BUILD(version) ((version & 0x000000FF)) - -JNIEXPORT void JNICALL -JVM_GetVersionInfo(JNIEnv* env, jvm_version_info* info, size_t info_size); - -typedef struct { - unsigned int jdk_version; /* Encoded $VNUM as specified by JEP-223 */ - unsigned int patch_version : 8; /* JEP-223 patch version */ - unsigned int reserved3 : 8; - unsigned int reserved1 : 16; - unsigned int reserved2; - - /* The following bits represents new JDK supports that VM has dependency on. - * VM implementation can use these bits to determine which JDK version - * and support it has to maintain runtime compatibility. - * - * When a new bit is added in a minor or update release, make sure - * the new bit is also added in the main/baseline. - */ - unsigned int thread_park_blocker : 1; - unsigned int post_vm_init_hook_enabled : 1; - unsigned int pending_list_uses_discovered_field : 1; - unsigned int : 29; - unsigned int : 32; - unsigned int : 32; -} jdk_version_info; - -#define JDK_VERSION_MAJOR(version) ((version & 0xFF000000) >> 24) -#define JDK_VERSION_MINOR(version) ((version & 0x00FF0000) >> 16) -#define JDK_VERSION_SECURITY(version) ((version & 0x0000FF00) >> 8) -#define JDK_VERSION_BUILD(version) ((version & 0x000000FF)) - -/* - * This is the function JDK_GetVersionInfo0 defined in libjava.so - * that is dynamically looked up by JVM. - */ -typedef void (*jdk_version_info_fn_t)(jdk_version_info* info, size_t info_size); - -/* - * This structure is used by the launcher to get the default thread - * stack size from the VM using JNI_GetDefaultJavaVMInitArgs() with a - * version of 1.1. As it is not supported otherwise, it has been removed - * from jni.h - */ -typedef struct JDK1_1InitArgs { - jint version; - - char **properties; - jint checkSource; - jint nativeStackSize; - jint javaStackSize; - jint minHeapSize; - jint maxHeapSize; - jint verifyMode; - char *classpath; - - jint (JNICALL *vfprintf)(FILE *fp, const char *format, va_list args); - void (JNICALL *exit)(jint code); - void (JNICALL *abort)(void); - - jint enableClassGC; - jint enableVerboseGC; - jint disableAsyncGC; - jint verbose; - jboolean debugging; - jint debugPort; -} JDK1_1InitArgs; - - -#ifdef __cplusplus -} /* extern "C" */ - -#endif /* __cplusplus */ - -#endif /* !_JAVASOFT_JVM_H_ */ diff -r 907bddce488c -r b6ff245c0db6 src/java.base/share/native/libjava/jdk_util.c --- a/src/java.base/share/native/libjava/jdk_util.c Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/share/native/libjava/jdk_util.c Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,9 +34,9 @@ JNIEXPORT void JDK_GetVersionInfo0(jdk_version_info* info, size_t info_size) { /* These VERSION_* macros are given by the build system */ - const unsigned int version_major = VERSION_MAJOR; - const unsigned int version_minor = VERSION_MINOR; - const unsigned int version_security = VERSION_SECURITY; + const unsigned int version_major = VERSION_FEATURE; + const unsigned int version_minor = VERSION_INTERIM; + const unsigned int version_security = VERSION_UPDATE; const unsigned int version_patch = VERSION_PATCH; const unsigned int version_build = VERSION_BUILD; diff -r 907bddce488c -r b6ff245c0db6 src/java.base/unix/classes/java/io/FileDescriptor.java --- a/src/java.base/unix/classes/java/io/FileDescriptor.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/unix/classes/java/io/FileDescriptor.java Thu Dec 14 12:28:32 2017 +0000 @@ -25,10 +25,14 @@ package java.io; +import java.lang.ref.Cleaner; import java.util.ArrayList; import java.util.List; + import jdk.internal.misc.JavaIOFileDescriptorAccess; import jdk.internal.misc.SharedSecrets; +import jdk.internal.ref.CleanerFactory; +import jdk.internal.ref.PhantomCleanable; /** * Instances of the file descriptor class serve as an opaque handle @@ -64,7 +68,7 @@ SharedSecrets.setJavaIOFileDescriptorAccess( new JavaIOFileDescriptorAccess() { public void set(FileDescriptor fdo, int fd) { - fdo.fd = fd; + fdo.set(fd); } public int get(FileDescriptor fdo) { @@ -79,10 +83,14 @@ return fdo.append; } - public void close(FileDescriptor fdo) { + public void close(FileDescriptor fdo) throws IOException { fdo.close(); } + public void registerCleanup(FileDescriptor fdo) { + fdo.registerCleanup(); + } + public void setHandle(FileDescriptor fdo, long handle) { throw new UnsupportedOperationException(); } @@ -95,6 +103,11 @@ } /** + * Cleanup in case FileDescriptor is not explicitly closed. + */ + private FDCleanup cleanup; + + /** * Constructs an (invalid) FileDescriptor * object. */ @@ -178,6 +191,34 @@ private static native void initIDs(); /** + * Set the fd. + * If setting to -1, clear the cleaner. + * The {@link #registerCleanup()} method should be called for new fds. + * @param fd the fd or -1 to indicate closed + */ + @SuppressWarnings("unchecked") + synchronized void set(int fd) { + if (fd == -1 && cleanup != null) { + cleanup.clear(); + cleanup = null; + } + this.fd = fd; + } + + /** + * Register a cleanup for the current raw fd. + * Used directly in java.io and indirectly via fdAccess. + * The cleanup should be registered after the fd is set in the FileDescriptor. + */ + @SuppressWarnings("unchecked") + synchronized void registerCleanup() { + if (cleanup != null) { + cleanup.clear(); + } + cleanup = FDCleanup.create(this); + } + + /** * Returns true, if the file was opened for appending. */ private static native boolean getAppend(int fd); @@ -185,9 +226,30 @@ /** * Close the raw file descriptor or handle, if it has not already been closed * and set the fd and handle to -1. + * Clear the cleaner so the close does not happen twice. * Package private to allow it to be used in java.io. + * @throws IOException if close fails */ - native void close(); + @SuppressWarnings("unchecked") + synchronized void close() throws IOException { + if (cleanup != null) { + cleanup.clear(); + cleanup = null; + } + close0(); + } + + /* + * Close the raw file descriptor or handle, if it has not already been closed + * and set the fd and handle to -1. + */ + private native void close0() throws IOException; + + /* + * Raw close of the file descriptor. + * Used only for last chance cleanup. + */ + private static native void cleanupClose0(int fd) throws IOException; /* * Package private methods to track referents. @@ -252,4 +314,45 @@ } } } + + /** + * Cleanup for a FileDescriptor when it becomes phantom reachable. + * Create a cleanup if fd != -1. + * Subclassed from {@code PhantomCleanable} so that {@code clear} can be + * called to disable the cleanup when the fd is closed by any means other + * than calling {@link FileDescriptor#close}. + * Otherwise, it may close the native fd after it has been reused. + */ + static final class FDCleanup extends PhantomCleanable { + private final int fd; + + static FDCleanup create(FileDescriptor fdo) { + return fdo.fd == -1 + ? null + : new FDCleanup(fdo, CleanerFactory.cleaner(), fdo.fd); + } + + /** + * Constructor for a phantom cleanable reference. + * @param obj the object to monitor + * @param cleaner the cleaner + * @param fd file descriptor to close + */ + private FDCleanup(Object obj, Cleaner cleaner, int fd) { + super(obj, cleaner); + this.fd = fd; + } + + /** + * Close the native fd. + */ + @Override + protected void performCleanup() { + try { + cleanupClose0(fd); + } catch (IOException ioe) { + throw new UncheckedIOException("close", ioe); + } + } + } } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/unix/native/include/jvm_md.h --- a/src/java.base/unix/native/include/jvm_md.h Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +0,0 @@ -/* - * Copyright (c) 1997, 2012, 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. - */ - -#ifndef _JAVASOFT_JVM_MD_H_ -#define _JAVASOFT_JVM_MD_H_ - -/* - * This file is currently collecting system-specific dregs for the - * JNI conversion, which should be sorted out later. - */ - -#include /* For DIR */ -#include /* For MAXPATHLEN */ -#include /* For F_OK, R_OK, W_OK */ -#include /* For ptrdiff_t */ -#include /* For uintptr_t */ - -#define JNI_ONLOAD_SYMBOLS {"JNI_OnLoad"} -#define JNI_ONUNLOAD_SYMBOLS {"JNI_OnUnload"} -#define JVM_ONLOAD_SYMBOLS {"JVM_OnLoad"} -#define AGENT_ONLOAD_SYMBOLS {"Agent_OnLoad"} -#define AGENT_ONUNLOAD_SYMBOLS {"Agent_OnUnload"} -#define AGENT_ONATTACH_SYMBOLS {"Agent_OnAttach"} - -#define JNI_LIB_PREFIX "lib" -#ifdef __APPLE__ -#define JNI_LIB_SUFFIX ".dylib" -#define VERSIONED_JNI_LIB_NAME(NAME, VERSION) JNI_LIB_PREFIX NAME "." VERSION JNI_LIB_SUFFIX -#else -#define JNI_LIB_SUFFIX ".so" -#define VERSIONED_JNI_LIB_NAME(NAME, VERSION) JNI_LIB_PREFIX NAME JNI_LIB_SUFFIX "." VERSION -#endif -#define JNI_LIB_NAME(NAME) JNI_LIB_PREFIX NAME JNI_LIB_SUFFIX - -#if defined(AIX) || defined(SOLARIS) -#define JVM_MAXPATHLEN MAXPATHLEN -#else -// Hack: MAXPATHLEN is 4095 on some Linux and 4096 on others. This may -// cause problems if JVM and the rest of JDK are built on different -// Linux releases. Here we define JVM_MAXPATHLEN to be MAXPATHLEN + 1, -// so buffers declared in VM are always >= 4096. -#define JVM_MAXPATHLEN MAXPATHLEN + 1 -#endif - -#define JVM_R_OK R_OK -#define JVM_W_OK W_OK -#define JVM_X_OK X_OK -#define JVM_F_OK F_OK - -/* - * File I/O - */ - -#include -#include -#include -#include -#include - -/* Signals */ - -#include // for socklen_t - -#define JVM_SIGINT SIGINT -#define JVM_SIGTERM SIGTERM - -#define BREAK_SIGNAL SIGQUIT /* Thread dumping support. */ -#ifdef SOLARIS -#define ASYNC_SIGNAL SIGJVM2 /* Event-based suspend/resume support */ -#endif // SOLARIS -#define SHUTDOWN1_SIGNAL SIGHUP /* Shutdown Hooks support. */ -#define SHUTDOWN2_SIGNAL SIGINT -#define SHUTDOWN3_SIGNAL SIGTERM - -/* With 1.4.1 libjsig added versioning: used in os_solaris.cpp and jsig.c */ -#define JSIG_VERSION_1_4_1 0x30140100 - -#endif /* !_JAVASOFT_JVM_MD_H_ */ diff -r 907bddce488c -r b6ff245c0db6 src/java.base/unix/native/libjava/FileDescriptor_md.c --- a/src/java.base/unix/native/libjava/FileDescriptor_md.c Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/unix/native/libjava/FileDescriptor_md.c Thu Dec 14 12:28:32 2017 +0000 @@ -71,8 +71,17 @@ return ((flags & O_APPEND) == 0) ? JNI_FALSE : JNI_TRUE; } +JNIEXPORT void JNICALL +Java_java_io_FileDescriptor_cleanupClose0(JNIEnv *env, jclass fdClass, jint fd) { + if (fd != -1) { + if (close(fd) == -1) { + JNU_ThrowIOExceptionWithLastError(env, "close failed"); + } + } +} + // instance method close0 for FileDescriptor JNIEXPORT void JNICALL -Java_java_io_FileDescriptor_close(JNIEnv *env, jobject this) { +Java_java_io_FileDescriptor_close0(JNIEnv *env, jobject this) { fileDescriptorClose(env, this); } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/unix/native/libjava/io_util_md.c --- a/src/java.base/unix/native/libjava/io_util_md.c Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/unix/native/libjava/io_util_md.c Thu Dec 14 12:28:32 2017 +0000 @@ -139,6 +139,11 @@ if ((*env)->ExceptionOccurred(env)) { return; } + + if (fd == -1) { + return; // already closed and set to -1 + } + /* Set the fd to -1 before closing it so that the timing window * of other threads using the wrong fd (closed but recycled fd, * that gets re-opened with some other filename) is reduced. diff -r 907bddce488c -r b6ff245c0db6 src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c --- a/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -476,10 +476,14 @@ (*env)->SetLongField(env, attrs, attrs_st_birthtime_sec, (jlong)buf->st_birthtime); #endif -#if (_POSIX_C_SOURCE >= 200809L) || defined(__solaris__) +#ifndef MACOSX (*env)->SetLongField(env, attrs, attrs_st_atime_nsec, (jlong)buf->st_atim.tv_nsec); (*env)->SetLongField(env, attrs, attrs_st_mtime_nsec, (jlong)buf->st_mtim.tv_nsec); (*env)->SetLongField(env, attrs, attrs_st_ctime_nsec, (jlong)buf->st_ctim.tv_nsec); +#else + (*env)->SetLongField(env, attrs, attrs_st_atime_nsec, (jlong)buf->st_atimespec.tv_nsec); + (*env)->SetLongField(env, attrs, attrs_st_mtime_nsec, (jlong)buf->st_mtimespec.tv_nsec); + (*env)->SetLongField(env, attrs, attrs_st_ctime_nsec, (jlong)buf->st_ctimespec.tv_nsec); #endif } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/windows/classes/java/io/FileDescriptor.java --- a/src/java.base/windows/classes/java/io/FileDescriptor.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/windows/classes/java/io/FileDescriptor.java Thu Dec 14 12:28:32 2017 +0000 @@ -25,10 +25,14 @@ package java.io; +import java.lang.ref.Cleaner; import java.util.ArrayList; import java.util.List; + import jdk.internal.misc.JavaIOFileDescriptorAccess; import jdk.internal.misc.SharedSecrets; +import jdk.internal.ref.CleanerFactory; +import jdk.internal.ref.PhantomCleanable; /** * Instances of the file descriptor class serve as an opaque handle @@ -81,12 +85,16 @@ return fdo.append; } - public void close(FileDescriptor fdo) { + public void close(FileDescriptor fdo) throws IOException { fdo.close(); } + public void registerCleanup(FileDescriptor fdo) { + fdo.registerCleanup(); + } + public void setHandle(FileDescriptor fdo, long handle) { - fdo.handle = handle; + fdo.setHandle(handle); } public long getHandle(FileDescriptor fdo) { @@ -97,6 +105,11 @@ } /** + * Cleanup in case FileDescriptor is not explicitly closed. + */ + private FDCleanup cleanup; + + /** * Constructs an (invalid) FileDescriptor * object. */ @@ -149,7 +162,7 @@ * relevant device(s). In particular, if this FileDescriptor * refers to a physical storage medium, such as a file in a file * system, sync will not return until all in-memory modified copies - * of buffers associated with this FileDesecriptor have been + * of buffers associated with this FileDescriptor have been * written to the physical medium. * * sync is meant to be used by code that requires physical @@ -175,20 +188,69 @@ /* This routine initializes JNI field offsets for the class */ private static native void initIDs(); - private static native long set(int d); - private static FileDescriptor standardStream(int fd) { FileDescriptor desc = new FileDescriptor(); - desc.handle = set(fd); + desc.handle = getHandle(fd); return desc; } + private static native long getHandle(int d); + + /** + * Set the handle. + * If setting to -1, clear the cleaner. + * The {@link #registerCleanup()} method should be called for new handles. + * @param handle the handle or -1 to indicate closed + */ + @SuppressWarnings("unchecked") + void setHandle(long handle) { + if (handle == -1 && cleanup != null) { + cleanup.clear(); + cleanup = null; + } + this.handle = handle; + } + + /** + * Register a cleanup for the current handle. + * Used directly in java.io and indirectly via fdAccess. + * The cleanup should be registered after the handle is set in the FileDescriptor. + */ + @SuppressWarnings("unchecked") + synchronized void registerCleanup() { + if (cleanup != null) { + cleanup.clear(); + } + cleanup = FDCleanup.create(this); + } + /** * Close the raw file descriptor or handle, if it has not already been closed * and set the fd and handle to -1. + * Clear the cleaner so the close does not happen twice. * Package private to allow it to be used in java.io. + * @throws IOException if close fails */ - native void close(); + @SuppressWarnings("unchecked") + synchronized void close() throws IOException { + if (cleanup != null) { + cleanup.clear(); + cleanup = null; + } + close0(); + } + + /* + * Close the raw file descriptor or handle, if it has not already been closed + * and set the fd and handle to -1. + */ + private native void close0() throws IOException; + + /* + * Raw close of the file handle. + * Used only for last chance cleanup. + */ + private static native void cleanupClose0(long handle) throws IOException; /* * Package private methods to track referents. @@ -253,4 +315,45 @@ } } } + + /** + * Cleanup for a FileDescriptor when it becomes phantom reachable. + * Create a cleanup if handle != -1. + * Subclassed from {@code PhantomCleanable} so that {@code clear} can be + * called to disable the cleanup when the fd is closed by any means other + * than calling {@link FileDescriptor#close}. + * Otherwise, it may close the handle after it has been reused. + */ + static final class FDCleanup extends PhantomCleanable { + private final long handle; + + static FDCleanup create(FileDescriptor fdo) { + return fdo.handle == -1 + ? null + : new FDCleanup(fdo, CleanerFactory.cleaner(), fdo.handle); + } + + /** + * Constructor for a phantom cleanable reference. + * @param obj the object to monitor + * @param cleaner the cleaner + * @param handle file handle to close + */ + private FDCleanup(Object obj, Cleaner cleaner, long handle) { + super(obj, cleaner); + this.handle = handle; + } + + /** + * Close the native handle. + */ + @Override + protected void performCleanup() { + try { + cleanupClose0(handle); + } catch (IOException ioe) { + throw new UncheckedIOException("close", ioe); + } + } + } } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java --- a/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java Thu Dec 14 12:28:32 2017 +0000 @@ -114,6 +114,7 @@ FileDescriptor result = new FileDescriptor(); long handle = duplicateHandle(fdAccess.getHandle(fd)); fdAccess.setHandle(result, handle); + fdAccess.registerCleanup(result); return result; } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java --- a/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java Thu Dec 14 12:28:32 2017 +0000 @@ -139,7 +139,7 @@ invalidateAllLocks(); // close the file - close0(handle); + nd.close(fdObj); // waits until all I/O operations have completed ioCache.close(); @@ -728,8 +728,6 @@ private static native int lockFile(long handle, long position, long size, boolean shared, long overlapped) throws IOException; - private static native void close0(long handle); - static { IOUtil.load(); } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/windows/classes/sun/nio/fs/WindowsChannelFactory.java --- a/src/java.base/windows/classes/sun/nio/fs/WindowsChannelFactory.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsChannelFactory.java Thu Dec 14 12:28:32 2017 +0000 @@ -216,8 +216,7 @@ } catch (IOException x) { // IOException is thrown if the file handle cannot be associated // with the completion port. All we can do is close the file. - long handle = fdAccess.getHandle(fdObj); - CloseHandle(handle); + fdAccess.close(fdObj); throw x; } } @@ -347,6 +346,7 @@ FileDescriptor fdObj = new FileDescriptor(); fdAccess.setHandle(fdObj, handle); fdAccess.setAppend(fdObj, flags.append); + fdAccess.registerCleanup(fdObj); return fdObj; } } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/windows/native/include/jvm_md.h --- a/src/java.base/windows/native/include/jvm_md.h Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -/* - * Copyright (c) 1997, 2008, 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. - */ - -#ifndef _JAVASOFT_JVM_MD_H_ -#define _JAVASOFT_JVM_MD_H_ - -/* - * This file is currently collecting system-specific dregs for the - * JNI conversion, which should be sorted out later. - */ - -#include -#include -#include - -#include "jni.h" - -typedef int socklen_t; - -#define JNI_ONLOAD_SYMBOLS {"_JNI_OnLoad@8", "JNI_OnLoad"} -#define JNI_ONUNLOAD_SYMBOLS {"_JNI_OnUnload@8", "JNI_OnUnload"} -#define JVM_ONLOAD_SYMBOLS {"_JVM_OnLoad@12", "JVM_OnLoad"} -#define AGENT_ONLOAD_SYMBOLS {"_Agent_OnLoad@12", "Agent_OnLoad"} -#define AGENT_ONUNLOAD_SYMBOLS {"_Agent_OnUnload@4", "Agent_OnUnload"} -#define AGENT_ONATTACH_SYMBOLS {"_Agent_OnAttach@12", "Agent_OnAttach"} - -#define JNI_LIB_PREFIX "" -#define JNI_LIB_SUFFIX ".dll" - -struct dirent { - char d_name[MAX_PATH]; -}; - -typedef struct { - struct dirent dirent; - char *path; - HANDLE handle; - WIN32_FIND_DATA find_data; -} DIR; - -#include /* For uintptr_t */ -#include - -#define JVM_MAXPATHLEN _MAX_PATH - -#define JVM_R_OK 4 -#define JVM_W_OK 2 -#define JVM_X_OK 1 -#define JVM_F_OK 0 - -#ifdef __cplusplus -extern "C" { -#endif - -JNIEXPORT void * JNICALL -JVM_GetThreadInterruptEvent(); - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ - -/* - * File I/O - */ - -#include -#include -#include -#include -#include - -/* Signals */ - -#define JVM_SIGINT SIGINT -#define JVM_SIGTERM SIGTERM - -#define SHUTDOWN1_SIGNAL SIGINT /* Shutdown Hooks support. */ -#define SHUTDOWN2_SIGNAL SIGTERM - -#endif /* !_JAVASOFT_JVM_MD_H_ */ diff -r 907bddce488c -r b6ff245c0db6 src/java.base/windows/native/libjava/FileDescriptor_md.c --- a/src/java.base/windows/native/libjava/FileDescriptor_md.c Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/windows/native/libjava/FileDescriptor_md.c Thu Dec 14 12:28:32 2017 +0000 @@ -57,7 +57,7 @@ } JNIEXPORT jlong JNICALL -Java_java_io_FileDescriptor_set(JNIEnv *env, jclass fdClass, jint fd) { +Java_java_io_FileDescriptor_getHandle(JNIEnv *env, jclass fdClass, jint fd) { SET_HANDLE(fd); } @@ -73,8 +73,17 @@ } } +JNIEXPORT void JNICALL +Java_java_io_FileDescriptor_cleanupClose0(JNIEnv *env, jclass fdClass, jlong handle) { + if (handle != -1) { + if (CloseHandle((HANDLE)handle) == -1) { + JNU_ThrowIOExceptionWithLastError(env, "close failed"); + } + } +} + // instance method close0 for FileDescriptor JNIEXPORT void JNICALL -Java_java_io_FileDescriptor_close(JNIEnv *env, jobject this) { +Java_java_io_FileDescriptor_close0(JNIEnv *env, jobject this) { fileDescriptorClose(env, this); } diff -r 907bddce488c -r b6ff245c0db6 src/java.base/windows/native/libnio/ch/SocketDispatcher.c --- a/src/java.base/windows/native/libnio/ch/SocketDispatcher.c Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/windows/native/libnio/ch/SocketDispatcher.c Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -179,7 +179,7 @@ } } - count += written; + count += (jint)written; address += written; } while ((count < total) && (written == MAX_BUFFER_SIZE)); diff -r 907bddce488c -r b6ff245c0db6 src/java.base/windows/native/libnio/ch/WindowsAsynchronousFileChannelImpl.c --- a/src/java.base/windows/native/libnio/ch/WindowsAsynchronousFileChannelImpl.c Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.base/windows/native/libnio/ch/WindowsAsynchronousFileChannelImpl.c Thu Dec 14 12:28:32 2017 +0000 @@ -121,13 +121,3 @@ return 0; } -JNIEXPORT void JNICALL -Java_sun_nio_ch_WindowsAsynchronousFileChannelImpl_close0(JNIEnv* env, jclass this, - jlong handle) -{ - HANDLE h = (HANDLE)jlong_to_ptr(handle); - BOOL result = CloseHandle(h); - if (result == 0) { - JNU_ThrowIOExceptionWithLastError(env, "Close failed"); - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.compiler/share/classes/javax/lang/model/SourceVersion.java --- a/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java Thu Dec 14 12:28:32 2017 +0000 @@ -56,7 +56,7 @@ * 1.7: diamond syntax, try-with-resources, etc. * 1.8: lambda expressions and default methods * 9: modules, small cleanups to 1.7 and 1.8 changes - * 10: to-be-determined changes + * 10: local-variable type inference (var) */ /** @@ -157,6 +157,9 @@ * The version recognized by the Java Platform, Standard Edition * 10. * + * Additions in this release include local-variable type inference + * ({@code var}). + * * @since 10 */ RELEASE_10; diff -r 907bddce488c -r b6ff245c0db6 src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor9.java --- a/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor9.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor9.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ /** * A skeletal visitor for annotation values with default behavior * appropriate for the {@link SourceVersion#RELEASE_9 RELEASE_9} - * source version. + * and {@link SourceVersion#RELEASE_10 RELEASE_10} source versions. * *

    WARNING: The {@code AnnotationValueVisitor} interface * implemented by this class may have methods added to it in the @@ -59,7 +59,7 @@ * @see AbstractAnnotationValueVisitor8 * @since 9 */ -@SupportedSourceVersion(RELEASE_9) +@SupportedSourceVersion(RELEASE_10) public abstract class AbstractAnnotationValueVisitor9 extends AbstractAnnotationValueVisitor8 { /** diff -r 907bddce488c -r b6ff245c0db6 src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor9.java --- a/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor9.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor9.java Thu Dec 14 12:28:32 2017 +0000 @@ -34,7 +34,7 @@ /** * A skeletal visitor of program elements with default behavior * appropriate for the {@link SourceVersion#RELEASE_9 RELEASE_9} - * source version. + * and {@link SourceVersion#RELEASE_10 RELEASE_10} source versions. * *

    WARNING: The {@code ElementVisitor} interface * implemented by this class may have methods added to it in the @@ -65,7 +65,7 @@ * @since 9 * @spec JPMS */ -@SupportedSourceVersion(RELEASE_9) +@SupportedSourceVersion(RELEASE_10) public abstract class AbstractElementVisitor9 extends AbstractElementVisitor8 { /** * Constructor for concrete subclasses to call. diff -r 907bddce488c -r b6ff245c0db6 src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor9.java --- a/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor9.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor9.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,13 +27,13 @@ import javax.annotation.processing.SupportedSourceVersion; import javax.lang.model.type.*; - +import javax.lang.model.SourceVersion; import static javax.lang.model.SourceVersion.*; /** * A skeletal visitor of types with default behavior appropriate for - * the {@link javax.lang.model.SourceVersion#RELEASE_9 RELEASE_9} - * source version. + * the {@link SourceVersion#RELEASE_9 RELEASE_9} + * and {@link SourceVersion#RELEASE_10 RELEASE_10} source versions. * *

    WARNING: The {@code TypeVisitor} interface implemented * by this class may have methods added to it in the future to @@ -63,7 +63,7 @@ * @see AbstractTypeVisitor8 * @since 9 */ -@SupportedSourceVersion(RELEASE_9) +@SupportedSourceVersion(RELEASE_10) public abstract class AbstractTypeVisitor9 extends AbstractTypeVisitor8 { /** * Constructor for concrete subclasses to call. diff -r 907bddce488c -r b6ff245c0db6 src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor9.java --- a/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor9.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor9.java Thu Dec 14 12:28:32 2017 +0000 @@ -33,7 +33,8 @@ /** * A visitor of program elements based on their {@linkplain * ElementKind kind} with default behavior appropriate for the {@link - * SourceVersion#RELEASE_9 RELEASE_9} source version. For {@linkplain + * SourceVersion#RELEASE_9 RELEASE_9} and {@link + * SourceVersion#RELEASE_10 RELEASE_10} source versions. For {@linkplain * Element elements} Xyz that may have more than one * kind, the visitXyz methods in this class delegate * to the visitXyzAsKind method corresponding to the @@ -77,7 +78,7 @@ * @since 9 * @spec JPMS */ -@SupportedSourceVersion(RELEASE_9) +@SupportedSourceVersion(RELEASE_10) public class ElementKindVisitor9 extends ElementKindVisitor8 { /** * Constructor for concrete subclasses; uses {@code null} for the diff -r 907bddce488c -r b6ff245c0db6 src/java.compiler/share/classes/javax/lang/model/util/ElementScanner9.java --- a/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner9.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner9.java Thu Dec 14 12:28:32 2017 +0000 @@ -34,7 +34,8 @@ /** * A scanning visitor of program elements with default behavior * appropriate for the {@link SourceVersion#RELEASE_9 RELEASE_9} - * source version. The visitXyz methods in this + * and {@link SourceVersion#RELEASE_10 RELEASE_10} source versions. + * The visitXyz methods in this * class scan their component elements by calling {@code scan} on * their {@linkplain Element#getEnclosedElements enclosed elements}, * {@linkplain ExecutableElement#getParameters parameters}, etc., as @@ -90,7 +91,7 @@ * @since 9 * @spec JPMS */ -@SupportedSourceVersion(RELEASE_9) +@SupportedSourceVersion(RELEASE_10) public class ElementScanner9 extends ElementScanner8 { /** * Constructor for concrete subclasses; uses {@code null} for the diff -r 907bddce488c -r b6ff245c0db6 src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor9.java --- a/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor9.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor9.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,8 @@ /** * A simple visitor for annotation values with default behavior * appropriate for the {@link SourceVersion#RELEASE_9 RELEASE_9} - * source version. Visit methods call {@link #defaultAction + * and {@link SourceVersion#RELEASE_10 RELEASE_10} source versions. + * Visit methods call {@link #defaultAction * defaultAction} passing their arguments to {@code defaultAction}'s * corresponding parameters. * @@ -66,7 +67,7 @@ * @see SimpleAnnotationValueVisitor8 * @since 9 */ -@SupportedSourceVersion(RELEASE_9) +@SupportedSourceVersion(RELEASE_10) public class SimpleAnnotationValueVisitor9 extends SimpleAnnotationValueVisitor8 { /** * Constructor for concrete subclasses; uses {@code null} for the diff -r 907bddce488c -r b6ff245c0db6 src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor9.java --- a/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor9.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor9.java Thu Dec 14 12:28:32 2017 +0000 @@ -33,7 +33,7 @@ /** * A simple visitor of program elements with default behavior * appropriate for the {@link SourceVersion#RELEASE_9 RELEASE_9} - * source version. + * and {@link SourceVersion#RELEASE_10 RELEASE_10} source versions. * * Visit methods corresponding to {@code RELEASE_9} and earlier * language constructs call {@link #defaultAction defaultAction}, @@ -73,7 +73,7 @@ * @since 9 * @spec JPMS */ -@SupportedSourceVersion(RELEASE_9) +@SupportedSourceVersion(RELEASE_10) public class SimpleElementVisitor9 extends SimpleElementVisitor8 { /** * Constructor for concrete subclasses; uses {@code null} for the diff -r 907bddce488c -r b6ff245c0db6 src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor9.java --- a/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor9.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor9.java Thu Dec 14 12:28:32 2017 +0000 @@ -32,7 +32,8 @@ /** * A simple visitor of types with default behavior appropriate for the - * {@link SourceVersion#RELEASE_9 RELEASE_9} source version. + * {@link SourceVersion#RELEASE_9 RELEASE_9} and + * {@link SourceVersion#RELEASE_10 RELEASE_10} source versions. * * Visit methods corresponding to {@code RELEASE_9} and earlier * language constructs call {@link #defaultAction defaultAction}, @@ -71,7 +72,7 @@ * @see SimpleTypeVisitor7 * @since 9 */ -@SupportedSourceVersion(RELEASE_9) +@SupportedSourceVersion(RELEASE_10) public class SimpleTypeVisitor9 extends SimpleTypeVisitor8 { /** * Constructor for concrete subclasses; uses {@code null} for the diff -r 907bddce488c -r b6ff245c0db6 src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor9.java --- a/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor9.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor9.java Thu Dec 14 12:28:32 2017 +0000 @@ -33,7 +33,8 @@ /** * A visitor of types based on their {@linkplain TypeKind kind} with * default behavior appropriate for the {@link SourceVersion#RELEASE_9 - * RELEASE_9} source version. For {@linkplain + * RELEASE_9} and {@link SourceVersion#RELEASE_10 RELEASE_10} source + * versions. For {@linkplain * TypeMirror types} Xyz that may have more than one * kind, the visitXyz methods in this class delegate * to the visitXyzAsKind method corresponding to the @@ -74,7 +75,7 @@ * @see TypeKindVisitor8 * @since 9 */ -@SupportedSourceVersion(RELEASE_9) +@SupportedSourceVersion(RELEASE_10) public class TypeKindVisitor9 extends TypeKindVisitor8 { /** * Constructor for concrete subclasses to call; uses {@code null} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -502,30 +502,18 @@ } } - /** - * Determines which modifier key is the appropriate accelerator - * key for menu shortcuts. - *

    - * Menu shortcuts, which are embodied in the - * {@code MenuShortcut} class, are handled by the - * {@code MenuBar} class. - *

    - * By default, this method returns {@code Event.CTRL_MASK}. - * Toolkit implementations should override this method if the - * Control key isn't the correct key for accelerators. - * @return the modifier mask on the {@code Event} class - * that is used for menu shortcuts on this toolkit. - * @see java.awt.MenuBar - * @see java.awt.MenuShortcut - * @since 1.1 - */ @Override - @SuppressWarnings("deprecation") + @Deprecated(since = "10") public int getMenuShortcutKeyMask() { return Event.META_MASK; } @Override + public int getMenuShortcutKeyMaskEx() { + return InputEvent.META_DOWN_MASK; + } + + @Override public Image getImage(final String filename) { final Image nsImage = checkForNSImage(filename); if (nsImage != null) { diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/AnimationController.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/AnimationController.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,436 +0,0 @@ -/* - * Copyright (c) 2006, 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 com.sun.java.swing.plaf.windows; - -import java.security.AccessController; -import sun.security.action.GetBooleanAction; - -import java.util.*; -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeEvent; -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; - - -import com.sun.java.swing.plaf.windows.TMSchema.State; -import static com.sun.java.swing.plaf.windows.TMSchema.State.*; -import com.sun.java.swing.plaf.windows.TMSchema.Part; -import com.sun.java.swing.plaf.windows.TMSchema.Prop; -import com.sun.java.swing.plaf.windows.XPStyle.Skin; - -import sun.awt.AppContext; - -/** - * A class to help mimic Vista theme animations. The only kind of - * animation it handles for now is 'transition' animation (this seems - * to be the only animation which Vista theme can do). This is when - * one picture fadein over another one in some period of time. - * According to - * https://connect.microsoft.com/feedback/ViewFeedback.aspx?FeedbackID=86852&SiteID=4 - * The animations are all linear. - * - * This class has a number of responsibilities. - *

      - *
    • It trigger rapaint for the UI components involved in the animation - *
    • It tracks the animation state for every UI component involved in the - * animation and paints {@code Skin} in new {@code State} over the - * {@code Skin} in last {@code State} using - * {@code AlphaComposite.SrcOver.derive(alpha)} where {code alpha} - * depends on the state of animation - *
    - * - * @author Igor Kushnirskiy - */ -class AnimationController implements ActionListener, PropertyChangeListener { - - private static final boolean VISTA_ANIMATION_DISABLED = - AccessController.doPrivileged(new GetBooleanAction("swing.disablevistaanimation")); - - - private static final Object ANIMATION_CONTROLLER_KEY = - new StringBuilder("ANIMATION_CONTROLLER_KEY"); - - private final Map> animationStateMap = - new WeakHashMap>(); - - //this timer is used to cause repaint on animated components - //30 repaints per second should give smooth animation affect - private final javax.swing.Timer timer = - new javax.swing.Timer(1000/30, this); - - private static synchronized AnimationController getAnimationController() { - AppContext appContext = AppContext.getAppContext(); - Object obj = appContext.get(ANIMATION_CONTROLLER_KEY); - if (obj == null) { - obj = new AnimationController(); - appContext.put(ANIMATION_CONTROLLER_KEY, obj); - } - return (AnimationController) obj; - } - - private AnimationController() { - timer.setRepeats(true); - timer.setCoalesce(true); - //we need to dispose the controller on l&f change - UIManager.addPropertyChangeListener(this); - } - - private static void triggerAnimation(JComponent c, - Part part, State newState) { - if (c instanceof javax.swing.JTabbedPane - || part == Part.TP_BUTTON) { - //idk: we can not handle tabs animation because - //the same (component,part) is used to handle all the tabs - //and we can not track the states - //Vista theme might have transition duration for toolbar buttons - //but native application does not seem to animate them - return; - } - AnimationController controller = - AnimationController.getAnimationController(); - State oldState = controller.getState(c, part); - if (oldState != newState) { - controller.putState(c, part, newState); - if (newState == State.DEFAULTED) { - // it seems for DEFAULTED button state Vista does animation from - // HOT - oldState = State.HOT; - } - if (oldState != null) { - long duration; - if (newState == State.DEFAULTED) { - //Only button might have DEFAULTED state - //idk: do not know how to get the value from Vista - //one second seems plausible value - duration = 1000; - } else { - XPStyle xp = XPStyle.getXP(); - duration = (xp != null) - ? xp.getThemeTransitionDuration( - c, part, - normalizeState(oldState), - normalizeState(newState), - Prop.TRANSITIONDURATIONS) - : 1000; - } - controller.startAnimation(c, part, oldState, newState, duration); - } - } - } - - // for scrollbar up, down, left and right button pictures are - // defined by states. It seems that theme has duration defined - // only for up button states thus we doing this translation here. - private static State normalizeState(State state) { - State rv; - switch (state) { - case DOWNPRESSED: - /* falls through */ - case LEFTPRESSED: - /* falls through */ - case RIGHTPRESSED: - rv = UPPRESSED; - break; - - case DOWNDISABLED: - /* falls through */ - case LEFTDISABLED: - /* falls through */ - case RIGHTDISABLED: - rv = UPDISABLED; - break; - - case DOWNHOT: - /* falls through */ - case LEFTHOT: - /* falls through */ - case RIGHTHOT: - rv = UPHOT; - break; - - case DOWNNORMAL: - /* falls through */ - case LEFTNORMAL: - /* falls through */ - case RIGHTNORMAL: - rv = UPNORMAL; - break; - - default : - rv = state; - break; - } - return rv; - } - - private synchronized State getState(JComponent component, Part part) { - State rv = null; - Object tmpObject = - component.getClientProperty(PartUIClientPropertyKey.getKey(part)); - if (tmpObject instanceof State) { - rv = (State) tmpObject; - } - return rv; - } - - private synchronized void putState(JComponent component, Part part, - State state) { - component.putClientProperty(PartUIClientPropertyKey.getKey(part), - state); - } - - private synchronized void startAnimation(JComponent component, - Part part, - State startState, - State endState, - long millis) { - boolean isForwardAndReverse = false; - if (endState == State.DEFAULTED) { - isForwardAndReverse = true; - } - Map map = animationStateMap.get(component); - if (millis <= 0) { - if (map != null) { - map.remove(part); - if (map.size() == 0) { - animationStateMap.remove(component); - } - } - return; - } - if (map == null) { - map = new EnumMap(Part.class); - animationStateMap.put(component, map); - } - map.put(part, - new AnimationState(startState, millis, isForwardAndReverse)); - if (! timer.isRunning()) { - timer.start(); - } - } - - static void paintSkin(JComponent component, Skin skin, - Graphics g, int dx, int dy, int dw, int dh, State state) { - if (VISTA_ANIMATION_DISABLED) { - skin.paintSkinRaw(g, dx, dy, dw, dh, state); - return; - } - triggerAnimation(component, skin.part, state); - AnimationController controller = getAnimationController(); - synchronized (controller) { - AnimationState animationState = null; - Map map = - controller.animationStateMap.get(component); - if (map != null) { - animationState = map.get(skin.part); - } - if (animationState != null) { - animationState.paintSkin(skin, g, dx, dy, dw, dh, state); - } else { - skin.paintSkinRaw(g, dx, dy, dw, dh, state); - } - } - } - - public synchronized void propertyChange(PropertyChangeEvent e) { - if ("lookAndFeel" == e.getPropertyName() - && ! (e.getNewValue() instanceof WindowsLookAndFeel) ) { - dispose(); - } - } - - public synchronized void actionPerformed(ActionEvent e) { - java.util.List componentsToRemove = null; - java.util.List partsToRemove = null; - for (JComponent component : animationStateMap.keySet()) { - component.repaint(); - if (partsToRemove != null) { - partsToRemove.clear(); - } - Map map = animationStateMap.get(component); - if (! component.isShowing() - || map == null - || map.size() == 0) { - if (componentsToRemove == null) { - componentsToRemove = new ArrayList(); - } - componentsToRemove.add(component); - continue; - } - for (Part part : map.keySet()) { - if (map.get(part).isDone()) { - if (partsToRemove == null) { - partsToRemove = new ArrayList(); - } - partsToRemove.add(part); - } - } - if (partsToRemove != null) { - if (partsToRemove.size() == map.size()) { - //animation is done for the component - if (componentsToRemove == null) { - componentsToRemove = new ArrayList(); - } - componentsToRemove.add(component); - } else { - for (Part part : partsToRemove) { - map.remove(part); - } - } - } - } - if (componentsToRemove != null) { - for (JComponent component : componentsToRemove) { - animationStateMap.remove(component); - } - } - if (animationStateMap.size() == 0) { - timer.stop(); - } - } - - private synchronized void dispose() { - timer.stop(); - UIManager.removePropertyChangeListener(this); - synchronized (AnimationController.class) { - AppContext.getAppContext() - .put(ANIMATION_CONTROLLER_KEY, null); - } - } - - private static class AnimationState { - private final State startState; - - //animation duration in nanoseconds - private final long duration; - - //animatin start time in nanoseconds - private long startTime; - - //direction the alpha value is changing - //forward - from 0 to 1 - //!forward - from 1 to 0 - private boolean isForward = true; - - //if isForwardAndReverse the animation continually goes - //forward and reverse. alpha value is changing from 0 to 1 then - //from 1 to 0 and so forth - private boolean isForwardAndReverse; - - private float progress; - - AnimationState(final State startState, - final long milliseconds, - boolean isForwardAndReverse) { - assert startState != null && milliseconds > 0; - assert SwingUtilities.isEventDispatchThread(); - - this.startState = startState; - this.duration = milliseconds * 1000000; - this.startTime = System.nanoTime(); - this.isForwardAndReverse = isForwardAndReverse; - progress = 0f; - } - private void updateProgress() { - assert SwingUtilities.isEventDispatchThread(); - - if (isDone()) { - return; - } - long currentTime = System.nanoTime(); - - progress = ((float) (currentTime - startTime)) - / duration; - progress = Math.max(progress, 0); //in case time was reset - if (progress >= 1) { - progress = 1; - if (isForwardAndReverse) { - startTime = currentTime; - progress = 0; - isForward = ! isForward; - } - } - } - void paintSkin(Skin skin, Graphics _g, - int dx, int dy, int dw, int dh, State state) { - assert SwingUtilities.isEventDispatchThread(); - - updateProgress(); - if (! isDone()) { - Graphics2D g = (Graphics2D) _g.create(); - if (skin.haveToSwitchStates()) { - skin.paintSkinRaw(g, dx, dy, dw, dh, state); - g.setComposite(AlphaComposite.SrcOver.derive(1 - progress)); - skin.paintSkinRaw(g, dx, dy, dw, dh, startState); - } else { - skin.paintSkinRaw(g, dx, dy, dw, dh, startState); - float alpha; - if (isForward) { - alpha = progress; - } else { - alpha = 1 - progress; - } - g.setComposite(AlphaComposite.SrcOver.derive(alpha)); - skin.paintSkinRaw(g, dx, dy, dw, dh, state); - } - g.dispose(); - } else { - skin.paintSkinRaw(_g, dx, dy, dw, dh, state); - skin.switchStates(false); - } - } - boolean isDone() { - assert SwingUtilities.isEventDispatchThread(); - - return progress >= 1; - } - } - - private static class PartUIClientPropertyKey - implements UIClientPropertyKey { - - private static final Map map = - new EnumMap(Part.class); - - static synchronized PartUIClientPropertyKey getKey(Part part) { - PartUIClientPropertyKey rv = map.get(part); - if (rv == null) { - rv = new PartUIClientPropertyKey(part); - map.put(part, rv); - } - return rv; - } - - private final Part part; - private PartUIClientPropertyKey(Part part) { - this.part = part; - } - public String toString() { - return part.toString(); - } - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/TMSchema.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/TMSchema.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,577 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/* - *

    These classes are designed to be used while the - * corresponding LookAndFeel class has been installed - * (UIManager.setLookAndFeel(new XXXLookAndFeel())). - * Using them while a different LookAndFeel is installed - * may produce unexpected results, including exceptions. - * Additionally, changing the LookAndFeel - * maintained by the UIManager without updating the - * corresponding ComponentUI of any - * JComponents may also produce unexpected results, - * such as the wrong colors showing up, and is generally not - * encouraged. - * - */ - -package com.sun.java.swing.plaf.windows; - -import java.awt.*; -import java.util.*; - -import javax.swing.*; - -import sun.awt.windows.ThemeReader; - -/** - * Implements Windows Parts and their States and Properties for the Windows Look and Feel. - * - * See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/userex/topics/partsandstates.asp - * See tmschema.h (or vssym32.h & vsstyle.h for MS Vista) - * - * @author Leif Samuelsson - */ -class TMSchema { - - /** - * An enumeration of the various Windows controls (also known as - * components, or top-level parts) - */ - public static enum Control { - BUTTON, - COMBOBOX, - EDIT, - HEADER, - LISTBOX, - LISTVIEW, - MENU, - PROGRESS, - REBAR, - SCROLLBAR, - SPIN, - TAB, - TOOLBAR, - TRACKBAR, - TREEVIEW, - WINDOW - } - - - /** - * An enumeration of the Windows compoent parts - */ - public static enum Part { - MENU (Control.MENU, 0), // Special case, not in native - MP_BARBACKGROUND (Control.MENU, 7), - MP_BARITEM (Control.MENU, 8), - MP_POPUPBACKGROUND (Control.MENU, 9), - MP_POPUPBORDERS (Control.MENU, 10), - MP_POPUPCHECK (Control.MENU, 11), - MP_POPUPCHECKBACKGROUND (Control.MENU, 12), - MP_POPUPGUTTER (Control.MENU, 13), - MP_POPUPITEM (Control.MENU, 14), - MP_POPUPSEPARATOR (Control.MENU, 15), - MP_POPUPSUBMENU (Control.MENU, 16), - - BP_PUSHBUTTON (Control.BUTTON, 1), - BP_RADIOBUTTON(Control.BUTTON, 2), - BP_CHECKBOX (Control.BUTTON, 3), - BP_GROUPBOX (Control.BUTTON, 4), - - CP_COMBOBOX (Control.COMBOBOX, 0), - CP_DROPDOWNBUTTON(Control.COMBOBOX, 1), - CP_BACKGROUND (Control.COMBOBOX, 2), - CP_TRANSPARENTBACKGROUND (Control.COMBOBOX, 3), - CP_BORDER (Control.COMBOBOX, 4), - CP_READONLY (Control.COMBOBOX, 5), - CP_DROPDOWNBUTTONRIGHT (Control.COMBOBOX, 6), - CP_DROPDOWNBUTTONLEFT (Control.COMBOBOX, 7), - CP_CUEBANNER (Control.COMBOBOX, 8), - - - EP_EDIT (Control.EDIT, 0), - EP_EDITTEXT(Control.EDIT, 1), - - HP_HEADERITEM(Control.HEADER, 1), - HP_HEADERSORTARROW(Control.HEADER, 4), - - LBP_LISTBOX(Control.LISTBOX, 0), - - LBCP_BORDER_HSCROLL (Control.LISTBOX, 1), - LBCP_BORDER_HVSCROLL (Control.LISTBOX, 2), - LBCP_BORDER_NOSCROLL (Control.LISTBOX, 3), - LBCP_BORDER_VSCROLL (Control.LISTBOX, 4), - LBCP_ITEM (Control.LISTBOX, 5), - - LVP_LISTVIEW(Control.LISTVIEW, 0), - - PP_PROGRESS (Control.PROGRESS, 0), - PP_BAR (Control.PROGRESS, 1), - PP_BARVERT (Control.PROGRESS, 2), - PP_CHUNK (Control.PROGRESS, 3), - PP_CHUNKVERT(Control.PROGRESS, 4), - - RP_GRIPPER (Control.REBAR, 1), - RP_GRIPPERVERT(Control.REBAR, 2), - - SBP_SCROLLBAR (Control.SCROLLBAR, 0), - SBP_ARROWBTN (Control.SCROLLBAR, 1), - SBP_THUMBBTNHORZ (Control.SCROLLBAR, 2), - SBP_THUMBBTNVERT (Control.SCROLLBAR, 3), - SBP_LOWERTRACKHORZ(Control.SCROLLBAR, 4), - SBP_UPPERTRACKHORZ(Control.SCROLLBAR, 5), - SBP_LOWERTRACKVERT(Control.SCROLLBAR, 6), - SBP_UPPERTRACKVERT(Control.SCROLLBAR, 7), - SBP_GRIPPERHORZ (Control.SCROLLBAR, 8), - SBP_GRIPPERVERT (Control.SCROLLBAR, 9), - SBP_SIZEBOX (Control.SCROLLBAR, 10), - - SPNP_UP (Control.SPIN, 1), - SPNP_DOWN(Control.SPIN, 2), - - TABP_TABITEM (Control.TAB, 1), - TABP_TABITEMLEFTEDGE (Control.TAB, 2), - TABP_TABITEMRIGHTEDGE(Control.TAB, 3), - TABP_PANE (Control.TAB, 9), - - TP_TOOLBAR (Control.TOOLBAR, 0), - TP_BUTTON (Control.TOOLBAR, 1), - TP_SEPARATOR (Control.TOOLBAR, 5), - TP_SEPARATORVERT (Control.TOOLBAR, 6), - - TKP_TRACK (Control.TRACKBAR, 1), - TKP_TRACKVERT (Control.TRACKBAR, 2), - TKP_THUMB (Control.TRACKBAR, 3), - TKP_THUMBBOTTOM(Control.TRACKBAR, 4), - TKP_THUMBTOP (Control.TRACKBAR, 5), - TKP_THUMBVERT (Control.TRACKBAR, 6), - TKP_THUMBLEFT (Control.TRACKBAR, 7), - TKP_THUMBRIGHT (Control.TRACKBAR, 8), - TKP_TICS (Control.TRACKBAR, 9), - TKP_TICSVERT (Control.TRACKBAR, 10), - - TVP_TREEVIEW(Control.TREEVIEW, 0), - TVP_GLYPH (Control.TREEVIEW, 2), - - WP_WINDOW (Control.WINDOW, 0), - WP_CAPTION (Control.WINDOW, 1), - WP_MINCAPTION (Control.WINDOW, 3), - WP_MAXCAPTION (Control.WINDOW, 5), - WP_FRAMELEFT (Control.WINDOW, 7), - WP_FRAMERIGHT (Control.WINDOW, 8), - WP_FRAMEBOTTOM (Control.WINDOW, 9), - WP_SYSBUTTON (Control.WINDOW, 13), - WP_MDISYSBUTTON (Control.WINDOW, 14), - WP_MINBUTTON (Control.WINDOW, 15), - WP_MDIMINBUTTON (Control.WINDOW, 16), - WP_MAXBUTTON (Control.WINDOW, 17), - WP_CLOSEBUTTON (Control.WINDOW, 18), - WP_MDICLOSEBUTTON (Control.WINDOW, 20), - WP_RESTOREBUTTON (Control.WINDOW, 21), - WP_MDIRESTOREBUTTON(Control.WINDOW, 22); - - private final Control control; - private final int value; - - private Part(Control control, int value) { - this.control = control; - this.value = value; - } - - public int getValue() { - return value; - } - - public String getControlName(Component component) { - String str = ""; - if (component instanceof JComponent) { - JComponent c = (JComponent)component; - String subAppName = (String)c.getClientProperty("XPStyle.subAppName"); - if (subAppName != null) { - str = subAppName + "::"; - } - } - return str + control.toString(); - } - - public String toString() { - return control.toString()+"."+name(); - } - } - - - /** - * An enumeration of the possible component states - */ - public static enum State { - ACTIVE, - ASSIST, - BITMAP, - CHECKED, - CHECKEDDISABLED, - CHECKEDHOT, - CHECKEDNORMAL, - CHECKEDPRESSED, - CHECKMARKNORMAL, - CHECKMARKDISABLED, - BULLETNORMAL, - BULLETDISABLED, - CLOSED, - DEFAULTED, - DISABLED, - DISABLEDHOT, - DISABLEDPUSHED, - DOWNDISABLED, - DOWNHOT, - DOWNNORMAL, - DOWNPRESSED, - FOCUSED, - HOT, - HOTCHECKED, - ICONHOT, - ICONNORMAL, - ICONPRESSED, - ICONSORTEDHOT, - ICONSORTEDNORMAL, - ICONSORTEDPRESSED, - INACTIVE, - INACTIVENORMAL, // See note 1 - INACTIVEHOT, // See note 1 - INACTIVEPUSHED, // See note 1 - INACTIVEDISABLED, // See note 1 - LEFTDISABLED, - LEFTHOT, - LEFTNORMAL, - LEFTPRESSED, - MIXEDDISABLED, - MIXEDHOT, - MIXEDNORMAL, - MIXEDPRESSED, - NORMAL, - PRESSED, - OPENED, - PUSHED, - READONLY, - RIGHTDISABLED, - RIGHTHOT, - RIGHTNORMAL, - RIGHTPRESSED, - SELECTED, - UNCHECKEDDISABLED, - UNCHECKEDHOT, - UNCHECKEDNORMAL, - UNCHECKEDPRESSED, - UPDISABLED, - UPHOT, - UPNORMAL, - UPPRESSED, - HOVER, - UPHOVER, - DOWNHOVER, - LEFTHOVER, - RIGHTHOVER, - SORTEDDOWN, - SORTEDHOT, - SORTEDNORMAL, - SORTEDPRESSED, - SORTEDUP; - - - /** - * A map of allowed states for each Part - */ - private static EnumMap stateMap; - - private static synchronized void initStates() { - stateMap = new EnumMap(Part.class); - - stateMap.put(Part.EP_EDITTEXT, - new State[] { - NORMAL, HOT, SELECTED, DISABLED, FOCUSED, READONLY, ASSIST - }); - - stateMap.put(Part.BP_PUSHBUTTON, - new State[] { NORMAL, HOT, PRESSED, DISABLED, DEFAULTED }); - - stateMap.put(Part.BP_RADIOBUTTON, - new State[] { - UNCHECKEDNORMAL, UNCHECKEDHOT, UNCHECKEDPRESSED, UNCHECKEDDISABLED, - CHECKEDNORMAL, CHECKEDHOT, CHECKEDPRESSED, CHECKEDDISABLED - }); - - stateMap.put(Part.BP_CHECKBOX, - new State[] { - UNCHECKEDNORMAL, UNCHECKEDHOT, UNCHECKEDPRESSED, UNCHECKEDDISABLED, - CHECKEDNORMAL, CHECKEDHOT, CHECKEDPRESSED, CHECKEDDISABLED, - MIXEDNORMAL, MIXEDHOT, MIXEDPRESSED, MIXEDDISABLED - }); - - State[] comboBoxStates = new State[] { NORMAL, HOT, PRESSED, DISABLED }; - stateMap.put(Part.CP_COMBOBOX, comboBoxStates); - stateMap.put(Part.CP_DROPDOWNBUTTON, comboBoxStates); - stateMap.put(Part.CP_BACKGROUND, comboBoxStates); - stateMap.put(Part.CP_TRANSPARENTBACKGROUND, comboBoxStates); - stateMap.put(Part.CP_BORDER, comboBoxStates); - stateMap.put(Part.CP_READONLY, comboBoxStates); - stateMap.put(Part.CP_DROPDOWNBUTTONRIGHT, comboBoxStates); - stateMap.put(Part.CP_DROPDOWNBUTTONLEFT, comboBoxStates); - stateMap.put(Part.CP_CUEBANNER, comboBoxStates); - - stateMap.put(Part.HP_HEADERITEM, new State[] { NORMAL, HOT, PRESSED, - SORTEDNORMAL, SORTEDHOT, SORTEDPRESSED, - ICONNORMAL, ICONHOT, ICONPRESSED, - ICONSORTEDNORMAL, ICONSORTEDHOT, ICONSORTEDPRESSED }); - - stateMap.put(Part.HP_HEADERSORTARROW, - new State[] {SORTEDDOWN, SORTEDUP}); - - State[] listBoxStates = new State[] { NORMAL, PRESSED, HOT, DISABLED}; - stateMap.put(Part.LBCP_BORDER_HSCROLL, listBoxStates); - stateMap.put(Part.LBCP_BORDER_HVSCROLL, listBoxStates); - stateMap.put(Part.LBCP_BORDER_NOSCROLL, listBoxStates); - stateMap.put(Part.LBCP_BORDER_VSCROLL, listBoxStates); - - State[] scrollBarStates = new State[] { NORMAL, HOT, PRESSED, DISABLED, HOVER }; - stateMap.put(Part.SBP_SCROLLBAR, scrollBarStates); - stateMap.put(Part.SBP_THUMBBTNVERT, scrollBarStates); - stateMap.put(Part.SBP_THUMBBTNHORZ, scrollBarStates); - stateMap.put(Part.SBP_GRIPPERVERT, scrollBarStates); - stateMap.put(Part.SBP_GRIPPERHORZ, scrollBarStates); - - stateMap.put(Part.SBP_ARROWBTN, - new State[] { - UPNORMAL, UPHOT, UPPRESSED, UPDISABLED, - DOWNNORMAL, DOWNHOT, DOWNPRESSED, DOWNDISABLED, - LEFTNORMAL, LEFTHOT, LEFTPRESSED, LEFTDISABLED, - RIGHTNORMAL, RIGHTHOT, RIGHTPRESSED, RIGHTDISABLED, - UPHOVER, DOWNHOVER, LEFTHOVER, RIGHTHOVER - }); - - - State[] spinnerStates = new State[] { NORMAL, HOT, PRESSED, DISABLED }; - stateMap.put(Part.SPNP_UP, spinnerStates); - stateMap.put(Part.SPNP_DOWN, spinnerStates); - - stateMap.put(Part.TVP_GLYPH, new State[] { CLOSED, OPENED }); - - State[] frameButtonStates = new State[] { - NORMAL, HOT, PUSHED, DISABLED, // See note 1 - INACTIVENORMAL, INACTIVEHOT, INACTIVEPUSHED, INACTIVEDISABLED, - }; - // Note 1: The INACTIVE frame button states apply when the frame - // is inactive. They are not defined in tmschema.h - - // Fix for 6316538: Vista has five frame button states - if (ThemeReader.getInt(Control.WINDOW.toString(), - Part.WP_CLOSEBUTTON.getValue(), 1, - Prop.IMAGECOUNT.getValue()) == 10) { - frameButtonStates = new State[] { - NORMAL, HOT, PUSHED, DISABLED, null, - INACTIVENORMAL, INACTIVEHOT, INACTIVEPUSHED, INACTIVEDISABLED, null - }; - } - - stateMap.put(Part.WP_MINBUTTON, frameButtonStates); - stateMap.put(Part.WP_MAXBUTTON, frameButtonStates); - stateMap.put(Part.WP_RESTOREBUTTON, frameButtonStates); - stateMap.put(Part.WP_CLOSEBUTTON, frameButtonStates); - - // States for Slider (trackbar) - stateMap.put(Part.TKP_TRACK, new State[] { NORMAL }); - stateMap.put(Part.TKP_TRACKVERT, new State[] { NORMAL }); - - State[] sliderThumbStates = - new State[] { NORMAL, HOT, PRESSED, FOCUSED, DISABLED }; - stateMap.put(Part.TKP_THUMB, sliderThumbStates); - stateMap.put(Part.TKP_THUMBBOTTOM, sliderThumbStates); - stateMap.put(Part.TKP_THUMBTOP, sliderThumbStates); - stateMap.put(Part.TKP_THUMBVERT, sliderThumbStates); - stateMap.put(Part.TKP_THUMBRIGHT, sliderThumbStates); - - // States for Tabs - State[] tabStates = new State[] { NORMAL, HOT, SELECTED, DISABLED, FOCUSED }; - stateMap.put(Part.TABP_TABITEM, tabStates); - stateMap.put(Part.TABP_TABITEMLEFTEDGE, tabStates); - stateMap.put(Part.TABP_TABITEMRIGHTEDGE, tabStates); - - - stateMap.put(Part.TP_BUTTON, - new State[] { - NORMAL, HOT, PRESSED, DISABLED, CHECKED, HOTCHECKED - }); - - State[] frameStates = new State[] { ACTIVE, INACTIVE }; - stateMap.put(Part.WP_WINDOW, frameStates); - stateMap.put(Part.WP_FRAMELEFT, frameStates); - stateMap.put(Part.WP_FRAMERIGHT, frameStates); - stateMap.put(Part.WP_FRAMEBOTTOM, frameStates); - - State[] captionStates = new State[] { ACTIVE, INACTIVE, DISABLED }; - stateMap.put(Part.WP_CAPTION, captionStates); - stateMap.put(Part.WP_MINCAPTION, captionStates); - stateMap.put(Part.WP_MAXCAPTION, captionStates); - - stateMap.put(Part.MP_BARBACKGROUND, - new State[] { ACTIVE, INACTIVE }); - stateMap.put(Part.MP_BARITEM, - new State[] { NORMAL, HOT, PUSHED, - DISABLED, DISABLEDHOT, DISABLEDPUSHED }); - stateMap.put(Part.MP_POPUPCHECK, - new State[] { CHECKMARKNORMAL, CHECKMARKDISABLED, - BULLETNORMAL, BULLETDISABLED }); - stateMap.put(Part.MP_POPUPCHECKBACKGROUND, - new State[] { DISABLEDPUSHED, NORMAL, BITMAP }); - stateMap.put(Part.MP_POPUPITEM, - new State[] { NORMAL, HOT, DISABLED, DISABLEDHOT }); - stateMap.put(Part.MP_POPUPSUBMENU, - new State[] { NORMAL, DISABLED }); - - } - - - public static synchronized int getValue(Part part, State state) { - if (stateMap == null) { - initStates(); - } - - Enum[] states = stateMap.get(part); - if (states != null) { - for (int i = 0; i < states.length; i++) { - if (state == states[i]) { - return i + 1; - } - } - } - - if (state == null || state == State.NORMAL) { - return 1; - } - - return 0; - } - - } - - - /** - * An enumeration of the possible component attributes and the - * corresponding value type - */ - public static enum Prop { - COLOR(Color.class, 204), - SIZE(Dimension.class, 207), - - FLATMENUS(Boolean.class, 1001), - - BORDERONLY(Boolean.class, 2203), // only draw the border area of the image - - IMAGECOUNT(Integer.class, 2401), // the number of state images in an imagefile - BORDERSIZE(Integer.class, 2403), // the size of the border line for bgtype=BorderFill - - PROGRESSCHUNKSIZE(Integer.class, 2411), // size of progress control chunks - PROGRESSSPACESIZE(Integer.class, 2412), // size of progress control spaces - - TEXTSHADOWOFFSET(Point.class, 3402), // where char shadows are drawn, relative to orig. chars - - NORMALSIZE(Dimension.class, 3409), // size of dest rect that exactly source - - - SIZINGMARGINS ( Insets.class, 3601), // margins used for 9-grid sizing - CONTENTMARGINS(Insets.class, 3602), // margins that define where content can be placed - CAPTIONMARGINS(Insets.class, 3603), // margins that define where caption text can be placed - - BORDERCOLOR(Color.class, 3801), // color of borders for BorderFill - FILLCOLOR ( Color.class, 3802), // color of bg fill - TEXTCOLOR ( Color.class, 3803), // color text is drawn in - - TEXTSHADOWCOLOR(Color.class, 3818), // color of text shadow - - BGTYPE(Integer.class, 4001), // basic drawing type for each part - - TEXTSHADOWTYPE(Integer.class, 4010), // type of shadow to draw with text - - TRANSITIONDURATIONS(Integer.class, 6000); - - private final Class type; - private final int value; - - private Prop(Class type, int value) { - this.type = type; - this.value = value; - } - - public int getValue() { - return value; - } - - public String toString() { - return name()+"["+type.getName()+"] = "+value; - } - } - - - /** - * An enumeration of attribute values for some Props - */ - public static enum TypeEnum { - BT_IMAGEFILE (Prop.BGTYPE, "imagefile", 0), - BT_BORDERFILL(Prop.BGTYPE, "borderfill", 1), - - TST_NONE(Prop.TEXTSHADOWTYPE, "none", 0), - TST_SINGLE(Prop.TEXTSHADOWTYPE, "single", 1), - TST_CONTINUOUS(Prop.TEXTSHADOWTYPE, "continuous", 2); - - - private TypeEnum(Prop prop, String enumName, int value) { - this.prop = prop; - this.enumName = enumName; - this.value = value; - } - - private final Prop prop; - private final String enumName; - private final int value; - - public String toString() { - return prop+"="+enumName+"="+value; - } - - String getName() { - return enumName; - } - - - static TypeEnum getTypeEnum(Prop prop, int enumval) { - for (TypeEnum e : TypeEnum.values()) { - if (e.prop == prop && e.value == enumval) { - return e; - } - } - return null; - } - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsBorders.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsBorders.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,341 +0,0 @@ -/* - * Copyright (c) 1998, 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 com.sun.java.swing.plaf.windows; - -import javax.swing.*; -import javax.swing.border.*; -import javax.swing.plaf.*; -import javax.swing.plaf.basic.*; - -import java.awt.Component; -import java.awt.Insets; -import java.awt.Color; -import java.awt.Graphics; - -import static com.sun.java.swing.plaf.windows.TMSchema.*; -import static com.sun.java.swing.plaf.windows.XPStyle.Skin; - -/** - * Factory object that can vend Borders appropriate for the Windows 95 {@literal L & F}. - * @author Rich Schiavi - */ - -public class WindowsBorders { - - /** - * Returns a border instance for a Windows Progress Bar - * @since 1.4 - */ - public static Border getProgressBarBorder() { - UIDefaults table = UIManager.getLookAndFeelDefaults(); - Border progressBarBorder = new BorderUIResource.CompoundBorderUIResource( - new WindowsBorders.ProgressBarBorder( - table.getColor("ProgressBar.shadow"), - table.getColor("ProgressBar.highlight")), - new EmptyBorder(1,1,1,1) - ); - return progressBarBorder; - } - - /** - * Returns a border instance for a Windows ToolBar - * - * @return a border used for the toolbar - * @since 1.4 - */ - public static Border getToolBarBorder() { - UIDefaults table = UIManager.getLookAndFeelDefaults(); - Border toolBarBorder = new WindowsBorders.ToolBarBorder( - table.getColor("ToolBar.shadow"), - table.getColor("ToolBar.highlight")); - return toolBarBorder; - } - - /** - * Returns an new instance of a border used to indicate which cell item - * has focus. - * - * @return a border to indicate which cell item has focus - * @since 1.4 - */ - public static Border getFocusCellHighlightBorder() { - return new ComplementDashedBorder(); - } - - public static Border getTableHeaderBorder() { - UIDefaults table = UIManager.getLookAndFeelDefaults(); - Border tableHeaderBorder = new BorderUIResource.CompoundBorderUIResource( - new BasicBorders.ButtonBorder( - table.getColor("Table.shadow"), - table.getColor("Table.darkShadow"), - table.getColor("Table.light"), - table.getColor("Table.highlight")), - new BasicBorders.MarginBorder()); - return tableHeaderBorder; - } - - public static Border getInternalFrameBorder() { - UIDefaults table = UIManager.getLookAndFeelDefaults(); - Border internalFrameBorder = new - BorderUIResource.CompoundBorderUIResource( - BorderFactory.createBevelBorder(BevelBorder.RAISED, - table.getColor("InternalFrame.borderColor"), - table.getColor("InternalFrame.borderHighlight"), - table.getColor("InternalFrame.borderDarkShadow"), - table.getColor("InternalFrame.borderShadow")), - new WindowsBorders.InternalFrameLineBorder( - table.getColor("InternalFrame.activeBorderColor"), - table.getColor("InternalFrame.inactiveBorderColor"), - table.getInt("InternalFrame.borderWidth"))); - - return internalFrameBorder; - } - - @SuppressWarnings("serial") // Superclass is not serializable across versions - public static class ProgressBarBorder extends AbstractBorder implements UIResource { - protected Color shadow; - protected Color highlight; - - public ProgressBarBorder(Color shadow, Color highlight) { - this.highlight = highlight; - this.shadow = shadow; - } - - public void paintBorder(Component c, Graphics g, int x, int y, - int width, int height) { - g.setColor(shadow); - g.drawLine(x,y, width-1,y); // draw top - g.drawLine(x,y, x,height-1); // draw left - g.setColor(highlight); - g.drawLine(x,height-1, width-1,height-1); // draw bottom - g.drawLine(width-1,y, width-1,height-1); // draw right - } - - public Insets getBorderInsets(Component c, Insets insets) { - insets.set(1,1,1,1); - return insets; - } - } - - /** - * A border for the ToolBar. If the ToolBar is floatable then the handle grip is drawn - * - * @since 1.4 - */ - @SuppressWarnings("serial") // Superclass is not serializable across versions - public static class ToolBarBorder extends AbstractBorder implements UIResource, SwingConstants { - protected Color shadow; - protected Color highlight; - - public ToolBarBorder(Color shadow, Color highlight) { - this.highlight = highlight; - this.shadow = shadow; - } - - public void paintBorder(Component c, Graphics g, int x, int y, - int width, int height) { - if (!(c instanceof JToolBar)) { - return; - } - g.translate(x, y); - - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - Border xpBorder = xp.getBorder(c, Part.TP_TOOLBAR); - if (xpBorder != null) { - xpBorder.paintBorder(c, g, 0, 0, width, height); - } - } - if (((JToolBar)c).isFloatable()) { - boolean vertical = ((JToolBar)c).getOrientation() == VERTICAL; - - if (xp != null) { - Part part = vertical ? Part.RP_GRIPPERVERT : Part.RP_GRIPPER; - Skin skin = xp.getSkin(c, part); - int dx, dy, dw, dh; - if (vertical) { - dx = 0; - dy = 2; - dw = width - 1; - dh = skin.getHeight(); - } else { - dw = skin.getWidth(); - dh = height - 1; - dx = c.getComponentOrientation().isLeftToRight() ? 2 : (width-dw-2); - dy = 0; - } - skin.paintSkin(g, dx, dy, dw, dh, State.NORMAL); - - } else { - - if (!vertical) { - if (c.getComponentOrientation().isLeftToRight()) { - g.setColor(shadow); - g.drawLine(4, 3, 4, height - 4); - g.drawLine(4, height - 4, 2, height - 4); - - g.setColor(highlight); - g.drawLine(2, 3, 3, 3); - g.drawLine(2, 3, 2, height - 5); - } else { - g.setColor(shadow); - g.drawLine(width - 3, 3, width - 3, height - 4); - g.drawLine(width - 4, height - 4, width - 4, height - 4); - - g.setColor(highlight); - g.drawLine(width - 5, 3, width - 4, 3); - g.drawLine(width - 5, 3, width - 5, height - 5); - } - } else { // Vertical - g.setColor(shadow); - g.drawLine(3, 4, width - 4, 4); - g.drawLine(width - 4, 2, width - 4, 4); - - g.setColor(highlight); - g.drawLine(3, 2, width - 4, 2); - g.drawLine(3, 2, 3, 3); - } - } - } - - g.translate(-x, -y); - } - - public Insets getBorderInsets(Component c, Insets insets) { - insets.set(1,1,1,1); - if (!(c instanceof JToolBar)) { - return insets; - } - if (((JToolBar)c).isFloatable()) { - int gripInset = (XPStyle.getXP() != null) ? 12 : 9; - if (((JToolBar)c).getOrientation() == HORIZONTAL) { - if (c.getComponentOrientation().isLeftToRight()) { - insets.left = gripInset; - } else { - insets.right = gripInset; - } - } else { - insets.top = gripInset; - } - } - return insets; - } - } - - /** - * This class is an implementation of a dashed border. - * @since 1.4 - */ - @SuppressWarnings("serial") // Superclass is not serializable across versions - public static class DashedBorder extends LineBorder implements UIResource { - public DashedBorder(Color color) { - super(color); - } - - public DashedBorder(Color color, int thickness) { - super(color, thickness); - } - - public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { - Color oldColor = g.getColor(); - int i; - - g.setColor(lineColor); - for(i = 0; i < thickness; i++) { - BasicGraphicsUtils.drawDashedRect(g, x+i, y+i, width-i-i, height-i-i); - } - g.setColor(oldColor); - } - } - - /** - * A dashed border that paints itself in the complementary color - * of the component's background color. - */ - @SuppressWarnings("serial") // Superclass is not serializable across versions - static class ComplementDashedBorder extends LineBorder implements UIResource { - private Color origColor; - private Color paintColor; - - public ComplementDashedBorder() { - super(null); - } - - public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { - Color color = c.getBackground(); - - if (origColor != color) { - origColor = color; - paintColor = new Color(~origColor.getRGB()); - } - - g.setColor(paintColor); - BasicGraphicsUtils.drawDashedRect(g, x, y, width, height); - } - } - - /** - * This class is an implementation of the InternalFrameLine border. - * @since 1.4 - */ - @SuppressWarnings("serial") // Superclass is not serializable across versions - public static class InternalFrameLineBorder extends LineBorder implements - UIResource { - protected Color activeColor; - protected Color inactiveColor; - - public InternalFrameLineBorder(Color activeBorderColor, - Color inactiveBorderColor, - int thickness) { - super(activeBorderColor, thickness); - activeColor = activeBorderColor; - inactiveColor = inactiveBorderColor; - } - - public void paintBorder(Component c, Graphics g, int x, int y, - int width, int height) { - - JInternalFrame jif = null; - if (c instanceof JInternalFrame) { - jif = (JInternalFrame)c; - } else if (c instanceof JInternalFrame.JDesktopIcon) { - jif = ((JInternalFrame.JDesktopIcon)c).getInternalFrame(); - } else { - return; - } - - if (jif.isSelected()) { - // Set the line color so the line border gets the correct - // color. - lineColor = activeColor; - super.paintBorder(c, g, x, y, width, height); - } else { - lineColor = inactiveColor; - super.paintBorder(c, g, x, y, width, height); - } - } - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsButtonListener.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsButtonListener.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1998, 2006, 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 com.sun.java.swing.plaf.windows; - -import java.beans.PropertyChangeEvent; - -import javax.swing.*; -import javax.swing.plaf.basic.*; - -/** - * Button Listener - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - * - * @author Rich Schiavi - */ -public class WindowsButtonListener extends BasicButtonListener { - public WindowsButtonListener(AbstractButton b) { - super(b); - } - /* - This class is currently not used, but exists in case customers - were subclassing it. - */ -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsButtonUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsButtonUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,321 +0,0 @@ -/* - * Copyright (c) 1997, 2006, 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 com.sun.java.swing.plaf.windows; - -import javax.swing.plaf.basic.*; -import javax.swing.border.*; -import javax.swing.plaf.*; -import javax.swing.*; - -import java.awt.*; - -import static com.sun.java.swing.plaf.windows.TMSchema.*; -import static com.sun.java.swing.plaf.windows.TMSchema.Part.*; -import static com.sun.java.swing.plaf.windows.XPStyle.Skin; -import sun.awt.AppContext; - - -/** - * Windows button. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - * - * @author Jeff Dinkins - * - */ -public class WindowsButtonUI extends BasicButtonUI -{ - protected int dashedRectGapX; - protected int dashedRectGapY; - protected int dashedRectGapWidth; - protected int dashedRectGapHeight; - - protected Color focusColor; - - private boolean defaults_initialized = false; - - private static final Object WINDOWS_BUTTON_UI_KEY = new Object(); - - // ******************************** - // Create PLAF - // ******************************** - public static ComponentUI createUI(JComponent c) { - AppContext appContext = AppContext.getAppContext(); - WindowsButtonUI windowsButtonUI = - (WindowsButtonUI) appContext.get(WINDOWS_BUTTON_UI_KEY); - if (windowsButtonUI == null) { - windowsButtonUI = new WindowsButtonUI(); - appContext.put(WINDOWS_BUTTON_UI_KEY, windowsButtonUI); - } - return windowsButtonUI; - } - - - // ******************************** - // Defaults - // ******************************** - protected void installDefaults(AbstractButton b) { - super.installDefaults(b); - if(!defaults_initialized) { - String pp = getPropertyPrefix(); - dashedRectGapX = UIManager.getInt(pp + "dashedRectGapX"); - dashedRectGapY = UIManager.getInt(pp + "dashedRectGapY"); - dashedRectGapWidth = UIManager.getInt(pp + "dashedRectGapWidth"); - dashedRectGapHeight = UIManager.getInt(pp + "dashedRectGapHeight"); - focusColor = UIManager.getColor(pp + "focus"); - defaults_initialized = true; - } - - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - b.setBorder(xp.getBorder(b, getXPButtonType(b))); - LookAndFeel.installProperty(b, "rolloverEnabled", Boolean.TRUE); - } - } - - protected void uninstallDefaults(AbstractButton b) { - super.uninstallDefaults(b); - defaults_initialized = false; - } - - protected Color getFocusColor() { - return focusColor; - } - - // ******************************** - // Paint Methods - // ******************************** - - /** - * Overridden method to render the text without the mnemonic - */ - protected void paintText(Graphics g, AbstractButton b, Rectangle textRect, String text) { - WindowsGraphicsUtils.paintText(g, b, textRect, text, getTextShiftOffset()); - } - - protected void paintFocus(Graphics g, AbstractButton b, Rectangle viewRect, Rectangle textRect, Rectangle iconRect){ - - // focus painted same color as text on Basic?? - int width = b.getWidth(); - int height = b.getHeight(); - g.setColor(getFocusColor()); - BasicGraphicsUtils.drawDashedRect(g, dashedRectGapX, dashedRectGapY, - width - dashedRectGapWidth, height - dashedRectGapHeight); - } - - protected void paintButtonPressed(Graphics g, AbstractButton b){ - setTextShiftOffset(); - } - - // ******************************** - // Layout Methods - // ******************************** - public Dimension getPreferredSize(JComponent c) { - Dimension d = super.getPreferredSize(c); - - /* Ensure that the width and height of the button is odd, - * to allow for the focus line if focus is painted - */ - AbstractButton b = (AbstractButton)c; - if (d != null && b.isFocusPainted()) { - if(d.width % 2 == 0) { d.width += 1; } - if(d.height % 2 == 0) { d.height += 1; } - } - return d; - } - - - /* These rectangles/insets are allocated once for all - * ButtonUI.paint() calls. Re-using rectangles rather than - * allocating them in each paint call substantially reduced the time - * it took paint to run. Obviously, this method can't be re-entered. - */ - private Rectangle viewRect = new Rectangle(); - - public void paint(Graphics g, JComponent c) { - if (XPStyle.getXP() != null) { - WindowsButtonUI.paintXPButtonBackground(g, c); - } - super.paint(g, c); - } - - static Part getXPButtonType(AbstractButton b) { - if(b instanceof JCheckBox) { - return Part.BP_CHECKBOX; - } - if(b instanceof JRadioButton) { - return Part.BP_RADIOBUTTON; - } - boolean toolbar = (b.getParent() instanceof JToolBar); - return toolbar ? Part.TP_BUTTON : Part.BP_PUSHBUTTON; - } - - static State getXPButtonState(AbstractButton b) { - Part part = getXPButtonType(b); - ButtonModel model = b.getModel(); - State state = State.NORMAL; - switch (part) { - case BP_RADIOBUTTON: - /* falls through */ - case BP_CHECKBOX: - if (! model.isEnabled()) { - state = (model.isSelected()) ? State.CHECKEDDISABLED - : State.UNCHECKEDDISABLED; - } else if (model.isPressed() && model.isArmed()) { - state = (model.isSelected()) ? State.CHECKEDPRESSED - : State.UNCHECKEDPRESSED; - } else if (model.isRollover()) { - state = (model.isSelected()) ? State.CHECKEDHOT - : State.UNCHECKEDHOT; - } else { - state = (model.isSelected()) ? State.CHECKEDNORMAL - : State.UNCHECKEDNORMAL; - } - break; - case BP_PUSHBUTTON: - /* falls through */ - case TP_BUTTON: - boolean toolbar = (b.getParent() instanceof JToolBar); - if (toolbar) { - if (model.isArmed() && model.isPressed()) { - state = State.PRESSED; - } else if (!model.isEnabled()) { - state = State.DISABLED; - } else if (model.isSelected() && model.isRollover()) { - state = State.HOTCHECKED; - } else if (model.isSelected()) { - state = State.CHECKED; - } else if (model.isRollover()) { - state = State.HOT; - } else if (b.hasFocus()) { - state = State.HOT; - } - } else { - if ((model.isArmed() && model.isPressed()) - || model.isSelected()) { - state = State.PRESSED; - } else if (!model.isEnabled()) { - state = State.DISABLED; - } else if (model.isRollover() || model.isPressed()) { - state = State.HOT; - } else if (b instanceof JButton - && ((JButton)b).isDefaultButton()) { - state = State.DEFAULTED; - } else if (b.hasFocus()) { - state = State.HOT; - } - } - break; - default : - state = State.NORMAL; - } - - return state; - } - - static void paintXPButtonBackground(Graphics g, JComponent c) { - AbstractButton b = (AbstractButton)c; - - XPStyle xp = XPStyle.getXP(); - - Part part = getXPButtonType(b); - - if (b.isContentAreaFilled() && b.getBorder() != null - && b.isBorderPainted() && xp != null) { - - Skin skin = xp.getSkin(b, part); - - State state = getXPButtonState(b); - Dimension d = c.getSize(); - int dx = 0; - int dy = 0; - int dw = d.width; - int dh = d.height; - - Border border = c.getBorder(); - Insets insets; - if (border != null) { - // Note: The border may be compound, containing an outer - // opaque border (supplied by the application), plus an - // inner transparent margin border. We want to size the - // background to fill the transparent part, but stay - // inside the opaque part. - insets = WindowsButtonUI.getOpaqueInsets(border, c); - } else { - insets = c.getInsets(); - } - if (insets != null) { - dx += insets.left; - dy += insets.top; - dw -= (insets.left + insets.right); - dh -= (insets.top + insets.bottom); - } - skin.paintSkin(g, dx, dy, dw, dh, state); - } - } - - /** - * returns - b.getBorderInsets(c) if border is opaque - * - null if border is completely non-opaque - * - somewhere inbetween if border is compound and - * outside border is opaque and inside isn't - */ - private static Insets getOpaqueInsets(Border b, Component c) { - if (b == null) { - return null; - } - if (b.isBorderOpaque()) { - return b.getBorderInsets(c); - } else if (b instanceof CompoundBorder) { - CompoundBorder cb = (CompoundBorder)b; - Insets iOut = getOpaqueInsets(cb.getOutsideBorder(), c); - if (iOut != null && iOut.equals(cb.getOutsideBorder().getBorderInsets(c))) { - // Outside border is opaque, keep looking - Insets iIn = getOpaqueInsets(cb.getInsideBorder(), c); - if (iIn == null) { - // Inside is non-opaque, use outside insets - return iOut; - } else { - // Found non-opaque somewhere in the inside (which is - // also compound). - return new Insets(iOut.top + iIn.top, iOut.left + iIn.left, - iOut.bottom + iIn.bottom, iOut.right + iIn.right); - } - } else { - // Outside is either all non-opaque or has non-opaque - // border inside another compound border - return iOut; - } - } else { - return null; - } - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsCheckBoxMenuItemUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsCheckBoxMenuItemUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,104 +0,0 @@ -/* - * Copyright (c) 1997, 2006, 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 com.sun.java.swing.plaf.windows; - -import java.awt.*; -import javax.swing.*; -import javax.swing.plaf.*; -import javax.swing.plaf.basic.*; - -import com.sun.java.swing.plaf.windows.TMSchema.Part; -import com.sun.java.swing.plaf.windows.TMSchema.State; - - -/** - * Windows check box menu item. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - */ -public class WindowsCheckBoxMenuItemUI extends BasicCheckBoxMenuItemUI { - - final WindowsMenuItemUIAccessor accessor = - new WindowsMenuItemUIAccessor() { - - public JMenuItem getMenuItem() { - return menuItem; - } - - public State getState(JMenuItem menuItem) { - return WindowsMenuItemUI.getState(this, menuItem); - } - - public Part getPart(JMenuItem menuItem) { - return WindowsMenuItemUI.getPart(this, menuItem); - } - }; - public static ComponentUI createUI(JComponent b) { - return new WindowsCheckBoxMenuItemUI(); - } - - @Override - protected void paintBackground(Graphics g, JMenuItem menuItem, - Color bgColor) { - if (WindowsMenuItemUI.isVistaPainting()) { - WindowsMenuItemUI.paintBackground(accessor, g, menuItem, bgColor); - return; - } - super.paintBackground(g, menuItem, bgColor); - } - /** - * Method which renders the text of the current menu item. - * - * @param g Graphics context - * @param menuItem Current menu item to render - * @param textRect Bounding rectangle to render the text. - * @param text String to render - * @since 1.4 - */ - protected void paintText(Graphics g, JMenuItem menuItem, - Rectangle textRect, String text) { - if (WindowsMenuItemUI.isVistaPainting()) { - WindowsMenuItemUI.paintText(accessor, g, menuItem, - textRect, text); - return; - } - ButtonModel model = menuItem.getModel(); - Color oldColor = g.getColor(); - - if(model.isEnabled() && model.isArmed()) { - g.setColor(selectionForeground); // Uses protected field. - } - - WindowsGraphicsUtils.paintText(g, menuItem, textRect, text, 0); - - g.setColor(oldColor); - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsCheckBoxUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsCheckBoxUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +0,0 @@ -/* - * Copyright (c) 1997, 1998, 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 com.sun.java.swing.plaf.windows; - -import sun.awt.AppContext; - -import javax.swing.plaf.basic.*; -import javax.swing.*; -import javax.swing.plaf.*; - -import java.awt.*; - -/** - * Windows check box. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - * - * @author Jeff Dinkins - */ -public class WindowsCheckBoxUI extends WindowsRadioButtonUI -{ - // NOTE: MetalCheckBoxUI inherts from MetalRadioButtonUI instead - // of BasicCheckBoxUI because we want to pick up all the - // painting changes made in MetalRadioButtonUI. - - private static final Object WINDOWS_CHECK_BOX_UI_KEY = new Object(); - - private static final String propertyPrefix = "CheckBox" + "."; - - private boolean defaults_initialized = false; - - // ******************************** - // Create PLAF - // ******************************** - public static ComponentUI createUI(JComponent c) { - AppContext appContext = AppContext.getAppContext(); - WindowsCheckBoxUI windowsCheckBoxUI = - (WindowsCheckBoxUI) appContext.get(WINDOWS_CHECK_BOX_UI_KEY); - if (windowsCheckBoxUI == null) { - windowsCheckBoxUI = new WindowsCheckBoxUI(); - appContext.put(WINDOWS_CHECK_BOX_UI_KEY, windowsCheckBoxUI); - } - return windowsCheckBoxUI; - } - - - public String getPropertyPrefix() { - return propertyPrefix; - } - - // ******************************** - // Defaults - // ******************************** - public void installDefaults(AbstractButton b) { - super.installDefaults(b); - if(!defaults_initialized) { - icon = UIManager.getIcon(getPropertyPrefix() + "icon"); - defaults_initialized = true; - } - } - - public void uninstallDefaults(AbstractButton b) { - super.uninstallDefaults(b); - defaults_initialized = false; - } - -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsClassicLookAndFeel.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsClassicLookAndFeel.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2003, 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 com.sun.java.swing.plaf.windows; - -/** - * Implements the Windows95/98/ME/NT/2000 Look and Feel. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - * - * @since 1.5 - */ -@SuppressWarnings("serial") // Superclass is not serializable across versions -public class WindowsClassicLookAndFeel extends WindowsLookAndFeel { - public String getName() { - return "Windows Classic"; - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsComboBoxUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsComboBoxUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,665 +0,0 @@ -/* - * Copyright (c) 1997, 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 com.sun.java.swing.plaf.windows; - -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeEvent; -import javax.swing.plaf.basic.*; -import javax.swing.plaf.*; -import javax.swing.border.*; -import javax.swing.*; -import java.awt.event.*; -import java.awt.*; - -import static com.sun.java.swing.plaf.windows.TMSchema.Part; -import static com.sun.java.swing.plaf.windows.TMSchema.State; -import static com.sun.java.swing.plaf.windows.XPStyle.Skin; - -import sun.swing.DefaultLookup; -import sun.swing.StringUIClientPropertyKey; - -import com.sun.java.swing.plaf.windows.WindowsBorders.DashedBorder; - -/** - * Windows combo box. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - * - * @author Tom Santos - * @author Igor Kushnirskiy - */ - -public class WindowsComboBoxUI extends BasicComboBoxUI { - - private static final MouseListener rolloverListener = - new MouseAdapter() { - private void handleRollover(MouseEvent e, boolean isRollover) { - JComboBox comboBox = getComboBox(e); - WindowsComboBoxUI comboBoxUI = getWindowsComboBoxUI(e); - if (comboBox == null || comboBoxUI == null) { - return; - } - if (! comboBox.isEditable()) { - //mouse over editable ComboBox does not switch rollover - //for the arrow button - ButtonModel m = null; - if (comboBoxUI.arrowButton != null) { - m = comboBoxUI.arrowButton.getModel(); - } - if (m != null ) { - m.setRollover(isRollover); - } - } - comboBoxUI.isRollover = isRollover; - comboBox.repaint(); - } - - public void mouseEntered(MouseEvent e) { - handleRollover(e, true); - } - - public void mouseExited(MouseEvent e) { - handleRollover(e, false); - } - - private JComboBox getComboBox(MouseEvent event) { - Object source = event.getSource(); - JComboBox rv = null; - if (source instanceof JComboBox) { - rv = (JComboBox) source; - } else if (source instanceof XPComboBoxButton) { - rv = ((XPComboBoxButton) source) - .getWindowsComboBoxUI().comboBox; - } else if (source instanceof JTextField && - ((JTextField) source).getParent() instanceof JComboBox) { - rv = (JComboBox) ((JTextField) source).getParent(); - } - return rv; - } - - private WindowsComboBoxUI getWindowsComboBoxUI(MouseEvent event) { - JComboBox comboBox = getComboBox(event); - WindowsComboBoxUI rv = null; - if (comboBox != null - && comboBox.getUI() instanceof WindowsComboBoxUI) { - rv = (WindowsComboBoxUI) comboBox.getUI(); - } - return rv; - } - - }; - private boolean isRollover = false; - - private static final PropertyChangeListener componentOrientationListener = - new PropertyChangeListener() { - public void propertyChange(PropertyChangeEvent e) { - String propertyName = e.getPropertyName(); - Object source = null; - if ("componentOrientation" == propertyName - && (source = e.getSource()) instanceof JComboBox - && ((JComboBox) source).getUI() instanceof - WindowsComboBoxUI) { - JComboBox comboBox = (JComboBox) source; - WindowsComboBoxUI comboBoxUI = (WindowsComboBoxUI) comboBox.getUI(); - if (comboBoxUI.arrowButton instanceof XPComboBoxButton) { - ((XPComboBoxButton) comboBoxUI.arrowButton).setPart( - (comboBox.getComponentOrientation() == - ComponentOrientation.RIGHT_TO_LEFT) - ? Part.CP_DROPDOWNBUTTONLEFT - : Part.CP_DROPDOWNBUTTONRIGHT); - } - } - } - }; - - public static ComponentUI createUI(JComponent c) { - return new WindowsComboBoxUI(); - } - - public void installUI( JComponent c ) { - super.installUI( c ); - isRollover = false; - comboBox.setRequestFocusEnabled( true ); - if (XPStyle.getXP() != null && arrowButton != null) { - //we can not do it in installListeners because arrowButton - //is initialized after installListeners is invoked - comboBox.addMouseListener(rolloverListener); - arrowButton.addMouseListener(rolloverListener); - // set empty border as default to see vista animated border - comboBox.setBorder(new EmptyBorder(0,0,0,0)); - } - } - - public void uninstallUI(JComponent c ) { - comboBox.removeMouseListener(rolloverListener); - if(arrowButton != null) { - arrowButton.removeMouseListener(rolloverListener); - } - super.uninstallUI( c ); - } - - /** - * {@inheritDoc} - * @since 1.6 - */ - @Override - protected void installListeners() { - super.installListeners(); - XPStyle xp = XPStyle.getXP(); - //button glyph for LTR and RTL combobox might differ - if (xp != null - && xp.isSkinDefined(comboBox, Part.CP_DROPDOWNBUTTONRIGHT)) { - comboBox.addPropertyChangeListener("componentOrientation", - componentOrientationListener); - } - } - - /** - * {@inheritDoc} - * @since 1.6 - */ - @Override - protected void uninstallListeners() { - super.uninstallListeners(); - comboBox.removePropertyChangeListener("componentOrientation", - componentOrientationListener); - } - - /** - * {@inheritDoc} - * @since 1.6 - */ - protected void configureEditor() { - super.configureEditor(); - if (XPStyle.getXP() != null) { - editor.addMouseListener(rolloverListener); - } - } - - /** - * {@inheritDoc} - * @since 1.6 - */ - protected void unconfigureEditor() { - super.unconfigureEditor(); - editor.removeMouseListener(rolloverListener); - } - - /** - * {@inheritDoc} - * @since 1.6 - */ - public void paint(Graphics g, JComponent c) { - if (XPStyle.getXP() != null) { - paintXPComboBoxBackground(g, c); - } - super.paint(g, c); - } - - State getXPComboBoxState(JComponent c) { - State state = State.NORMAL; - if (!c.isEnabled()) { - state = State.DISABLED; - } else if (isPopupVisible(comboBox)) { - state = State.PRESSED; - } else if (comboBox.isEditable() - && comboBox.getEditor().getEditorComponent().isFocusOwner()) { - state = State.PRESSED; - } else if (isRollover) { - state = State.HOT; - } - return state; - } - - private void paintXPComboBoxBackground(Graphics g, JComponent c) { - XPStyle xp = XPStyle.getXP(); - if (xp == null) { - return; - } - State state = getXPComboBoxState(c); - Skin skin = null; - if (! comboBox.isEditable() - && xp.isSkinDefined(c, Part.CP_READONLY)) { - skin = xp.getSkin(c, Part.CP_READONLY); - } - if (skin == null) { - skin = xp.getSkin(c, Part.CP_BORDER); - } - skin.paintSkin(g, 0, 0, c.getWidth(), c.getHeight(), state); - } - - /** - * If necessary paints the currently selected item. - * - * @param g Graphics to paint to - * @param bounds Region to paint current value to - * @param hasFocus whether or not the JComboBox has focus - * @throws NullPointerException if any of the arguments are null. - * @since 1.5 - */ - public void paintCurrentValue(Graphics g, Rectangle bounds, - boolean hasFocus) { - XPStyle xp = XPStyle.getXP(); - if ( xp != null) { - bounds.x += 2; - bounds.y += 2; - bounds.width -= 4; - bounds.height -= 4; - } else { - bounds.x += 1; - bounds.y += 1; - bounds.width -= 2; - bounds.height -= 2; - } - if (! comboBox.isEditable() - && xp != null - && xp.isSkinDefined(comboBox, Part.CP_READONLY)) { - // On vista for READNLY ComboBox - // color for currentValue is the same as for any other item - - // mostly copied from javax.swing.plaf.basic.BasicComboBoxUI.paintCurrentValue - ListCellRenderer renderer = comboBox.getRenderer(); - Component c; - if ( hasFocus && !isPopupVisible(comboBox) ) { - c = renderer.getListCellRendererComponent( - listBox, - comboBox.getSelectedItem(), - -1, - true, - false ); - } else { - c = renderer.getListCellRendererComponent( - listBox, - comboBox.getSelectedItem(), - -1, - false, - false ); - } - c.setFont(comboBox.getFont()); - if ( comboBox.isEnabled() ) { - c.setForeground(comboBox.getForeground()); - c.setBackground(comboBox.getBackground()); - } else { - c.setForeground(DefaultLookup.getColor( - comboBox, this, "ComboBox.disabledForeground", null)); - c.setBackground(DefaultLookup.getColor( - comboBox, this, "ComboBox.disabledBackground", null)); - } - boolean shouldValidate = false; - if (c instanceof JPanel) { - shouldValidate = true; - } - currentValuePane.paintComponent(g, c, comboBox, bounds.x, bounds.y, - bounds.width, bounds.height, shouldValidate); - - } else { - super.paintCurrentValue(g, bounds, hasFocus); - } - } - - /** - * {@inheritDoc} - * @since 1.6 - */ - public void paintCurrentValueBackground(Graphics g, Rectangle bounds, - boolean hasFocus) { - if (XPStyle.getXP() == null) { - super.paintCurrentValueBackground(g, bounds, hasFocus); - } - } - - public Dimension getMinimumSize( JComponent c ) { - Dimension d = super.getMinimumSize(c); - if (XPStyle.getXP() != null) { - d.width += 7; - boolean isEditable = false; - if (c instanceof JComboBox) { - isEditable = ((JComboBox) c).isEditable(); - } - d.height += isEditable ? 4 : 6; - } else { - d.width += 4; - d.height += 2; - } - return d; - } - - /** - * Creates a layout manager for managing the components which make up the - * combo box. - * - * @return an instance of a layout manager - */ - protected LayoutManager createLayoutManager() { - return new BasicComboBoxUI.ComboBoxLayoutManager() { - public void layoutContainer(Container parent) { - super.layoutContainer(parent); - - if (XPStyle.getXP() != null && arrowButton != null) { - Dimension d = parent.getSize(); - Insets insets = getInsets(); - int buttonWidth = arrowButton.getPreferredSize().width; - arrowButton.setBounds(WindowsGraphicsUtils.isLeftToRight((JComboBox)parent) - ? (d.width - insets.right - buttonWidth) - : insets.left, - insets.top, - buttonWidth, d.height - insets.top - insets.bottom); - } - } - }; - } - - protected void installKeyboardActions() { - super.installKeyboardActions(); - } - - protected ComboPopup createPopup() { - return new WinComboPopUp(comboBox); - } - - /** - * Creates the default editor that will be used in editable combo boxes. - * A default editor will be used only if an editor has not been - * explicitly set with setEditor. - * - * @return a ComboBoxEditor used for the combo box - * @see javax.swing.JComboBox#setEditor - */ - protected ComboBoxEditor createEditor() { - return new WindowsComboBoxEditor(); - } - - /** - * {@inheritDoc} - * @since 1.6 - */ - @Override - protected ListCellRenderer createRenderer() { - XPStyle xp = XPStyle.getXP(); - if (xp != null && xp.isSkinDefined(comboBox, Part.CP_READONLY)) { - return new WindowsComboBoxRenderer(); - } else { - return super.createRenderer(); - } - } - - /** - * Creates an button which will be used as the control to show or hide - * the popup portion of the combo box. - * - * @return a button which represents the popup control - */ - protected JButton createArrowButton() { - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - return new XPComboBoxButton(xp); - } else { - return super.createArrowButton(); - } - } - - @SuppressWarnings("serial") // Superclass is not serializable across versions - private class XPComboBoxButton extends XPStyle.GlyphButton { - private State prevState = null; - - public XPComboBoxButton(XPStyle xp) { - super(comboBox, - (! xp.isSkinDefined(comboBox, Part.CP_DROPDOWNBUTTONRIGHT)) - ? Part.CP_DROPDOWNBUTTON - : (comboBox.getComponentOrientation() == ComponentOrientation.RIGHT_TO_LEFT) - ? Part.CP_DROPDOWNBUTTONLEFT - : Part.CP_DROPDOWNBUTTONRIGHT - ); - setRequestFocusEnabled(false); - } - - @Override - protected State getState() { - State rv; - - getModel().setPressed(comboBox.isPopupVisible()); - - rv = super.getState(); - XPStyle xp = XPStyle.getXP(); - if (rv != State.DISABLED - && comboBox != null && ! comboBox.isEditable() - && xp != null && xp.isSkinDefined(comboBox, - Part.CP_DROPDOWNBUTTONRIGHT)) { - /* - * for non editable ComboBoxes Vista seems to have the - * same glyph for all non DISABLED states - */ - rv = State.NORMAL; - } - if (rv == State.NORMAL && (prevState == State.HOT || prevState == State.PRESSED)) { - /* - * State NORMAL of combobox button cannot overpaint states HOT or PRESSED - * Therefore HOT state must be painted from alpha 1 to 0 and not as usual that - * NORMAL state is painted from alpha 0 to alpha 1. - */ - skin.switchStates(true); - } - if (rv != prevState) { - prevState = rv; - } - - return rv; - } - - public Dimension getPreferredSize() { - return new Dimension(17, 21); - } - - void setPart(Part part) { - setPart(comboBox, part); - } - - WindowsComboBoxUI getWindowsComboBoxUI() { - return WindowsComboBoxUI.this; - } - } - - - /** - * Subclassed to add Windows specific Key Bindings. - * This class is now obsolete and doesn't do anything. - * Only included for backwards API compatibility. - * Do not call or override. - * - * @deprecated As of Java 2 platform v1.4. - */ - @Deprecated - @SuppressWarnings("serial") // Superclass is not serializable across versions - protected class WindowsComboPopup extends BasicComboPopup { - - public WindowsComboPopup( JComboBox cBox ) { - super( cBox ); - } - - protected KeyListener createKeyListener() { - return new InvocationKeyHandler(); - } - - protected class InvocationKeyHandler extends BasicComboPopup.InvocationKeyHandler { - protected InvocationKeyHandler() { - WindowsComboPopup.this.super(); - } - } - } - - @SuppressWarnings("serial") // Same-version serialization only - protected class WinComboPopUp extends BasicComboPopup { - private Skin listBoxBorder = null; - private XPStyle xp; - - public WinComboPopUp(JComboBox combo) { - super(combo); - xp = XPStyle.getXP(); - if (xp != null && xp.isSkinDefined(combo, Part.LBCP_BORDER_NOSCROLL)) { - this.listBoxBorder = new Skin(combo, Part.LBCP_BORDER_NOSCROLL); - this.setBorder(new EmptyBorder(1,1,1,1)); - } - } - - protected KeyListener createKeyListener() { - return new InvocationKeyHandler(); - } - - protected class InvocationKeyHandler extends BasicComboPopup.InvocationKeyHandler { - protected InvocationKeyHandler() { - WinComboPopUp.this.super(); - } - } - - protected void paintComponent(Graphics g) { - super.paintComponent(g); - if (this.listBoxBorder != null) { - this.listBoxBorder.paintSkinRaw(g, this.getX(), this.getY(), - this.getWidth(), this.getHeight(), State.HOT); - } - } - } - - - /** - * Subclassed to highlight selected item in an editable combo box. - */ - public static class WindowsComboBoxEditor - extends BasicComboBoxEditor.UIResource { - - /** - * {@inheritDoc} - * @since 1.6 - */ - protected JTextField createEditorComponent() { - JTextField editor = super.createEditorComponent(); - Border border = (Border)UIManager.get("ComboBox.editorBorder"); - - if (border != null) { - editor.setBorder(border); - } - editor.setOpaque(false); - return editor; - } - - public void setItem(Object item) { - super.setItem(item); - Object focus = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); - if ((focus == editor) || (focus == editor.getParent())) { - editor.selectAll(); - } - } - } - - /** - * Subclassed to set opacity {@code false} on the renderer - * and to show border for focused cells. - */ - @SuppressWarnings("serial") // Superclass is not serializable across versions - private static class WindowsComboBoxRenderer - extends BasicComboBoxRenderer.UIResource { - private static final Object BORDER_KEY - = new StringUIClientPropertyKey("BORDER_KEY"); - private static final Border NULL_BORDER = new EmptyBorder(0, 0, 0, 0); - - // Create own version of DashedBorder with more space on left side - private class WindowsComboBoxDashedBorder extends DashedBorder { - - public WindowsComboBoxDashedBorder(Color color, int thickness) { - super(color, thickness); - } - - public WindowsComboBoxDashedBorder(Color color) { - super(color); - } - - @Override - public Insets getBorderInsets(Component c, Insets i) { - return new Insets(0,2,0,0); - } - } - - public WindowsComboBoxRenderer() { - super(); - - // correct space on the left side of text items in the combo popup list - Insets i = getBorder().getBorderInsets(this); - setBorder(new EmptyBorder(0, 2, 0, i.right)); - } - /** - * {@inheritDoc} - */ - @Override - public Component getListCellRendererComponent( - JList list, - Object value, - int index, - boolean isSelected, - boolean cellHasFocus) { - Component rv = - super.getListCellRendererComponent(list, value, index, - isSelected, cellHasFocus); - if (rv instanceof JComponent) { - JComponent component = (JComponent) rv; - if (index == -1 && isSelected) { - Border border = component.getBorder(); - Border dashedBorder = - new WindowsComboBoxDashedBorder(list.getForeground()); - component.setBorder(dashedBorder); - //store current border in client property if needed - if (component.getClientProperty(BORDER_KEY) == null) { - component.putClientProperty(BORDER_KEY, - (border == null) ? NULL_BORDER : border); - } - } else { - if (component.getBorder() instanceof - WindowsBorders.DashedBorder) { - Object storedBorder = component.getClientProperty(BORDER_KEY); - if (storedBorder instanceof Border) { - component.setBorder( - (storedBorder == NULL_BORDER) ? null - : (Border) storedBorder); - } - component.putClientProperty(BORDER_KEY, null); - } - } - if (index == -1) { - component.setOpaque(false); - component.setForeground(list.getForeground()); - } else { - component.setOpaque(true); - } - } - return rv; - } - - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsDesktopIconUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsDesktopIconUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -/* - * Copyright (c) 1997, 2004, 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 com.sun.java.swing.plaf.windows; - -import java.awt.*; -import javax.swing.plaf.*; -import javax.swing.plaf.basic.*; -import javax.swing.*; -import javax.swing.border.*; - - - -/** - * Windows icon for a minimized window on the desktop. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - */ -public class WindowsDesktopIconUI extends BasicDesktopIconUI { - private int width; - - public static ComponentUI createUI(JComponent c) { - return new WindowsDesktopIconUI(); - } - - public void installDefaults() { - super.installDefaults(); - width = UIManager.getInt("DesktopIcon.width"); - } - - public void installUI(JComponent c) { - super.installUI(c); - - c.setOpaque(XPStyle.getXP() == null); - } - - // Uninstall the listeners added by the WindowsInternalFrameTitlePane - public void uninstallUI(JComponent c) { - WindowsInternalFrameTitlePane thePane = - (WindowsInternalFrameTitlePane)iconPane; - super.uninstallUI(c); - thePane.uninstallListeners(); - } - - protected void installComponents() { - iconPane = new WindowsInternalFrameTitlePane(frame); - desktopIcon.setLayout(new BorderLayout()); - desktopIcon.add(iconPane, BorderLayout.CENTER); - - if (XPStyle.getXP() != null) { - desktopIcon.setBorder(null); - } - } - - public Dimension getPreferredSize(JComponent c) { - // Windows desktop icons can not be resized. Therefore, we should - // always return the minimum size of the desktop icon. See - // getMinimumSize(JComponent c). - return getMinimumSize(c); - } - - /** - * Windows desktop icons are restricted to a width of 160 pixels by - * default. This value is retrieved by the DesktopIcon.width property. - */ - public Dimension getMinimumSize(JComponent c) { - Dimension dim = super.getMinimumSize(c); - dim.width = width; - return dim; - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsDesktopManager.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsDesktopManager.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,104 +0,0 @@ -/* - * Copyright (c) 1998, 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 com.sun.java.swing.plaf.windows; - -import javax.swing.DefaultDesktopManager; -import javax.swing.JInternalFrame; -import javax.swing.JLayeredPane; -import java.awt.Component; -import java.awt.Container; -import java.awt.Dimension; -import java.beans.PropertyVetoException; -import java.util.Vector; -import java.lang.ref.WeakReference; - -/** - * This class implements a DesktopManager which more closely follows - * the MDI model than the DefaultDesktopManager. Unlike the - * DefaultDesktopManager policy, MDI requires that the selected - * and activated child frames are the same, and that that frame - * always be the top-most window. - *

    - * The maximized state is managed by the DesktopManager with MDI, - * instead of just being a property of the individual child frame. - * This means that if the currently selected window is maximized - * and another window is selected, that new window will be maximized. - * - * @see javax.swing.DefaultDesktopManager - * @author Thomas Ball - */ -@SuppressWarnings("serial") // JDK-implementation class -public class WindowsDesktopManager extends DefaultDesktopManager - implements java.io.Serializable, javax.swing.plaf.UIResource { - - /* The frame which is currently selected/activated. - * We store this value to enforce MDI's single-selection model. - */ - private WeakReference currentFrameRef; - - public void activateFrame(JInternalFrame f) { - JInternalFrame currentFrame = currentFrameRef != null ? - currentFrameRef.get() : null; - try { - super.activateFrame(f); - if (currentFrame != null && f != currentFrame) { - // If the current frame is maximized, transfer that - // attribute to the frame being activated. - if (!currentFrame.isClosed() && currentFrame.isMaximum() && - (f.getClientProperty("JInternalFrame.frameType") != - "optionDialog") ) { - //Special case. If key binding was used to select next - //frame instead of minimizing the icon via the minimize - //icon. - if (!currentFrame.isIcon()) { - currentFrame.setMaximum(false); - if (f.isMaximizable()) { - if (!f.isMaximum()) { - f.setMaximum(true); - } else if (f.isMaximum() && f.isIcon()) { - f.setIcon(false); - } else { - f.setMaximum(false); - } - } - } - } - if (currentFrame.isSelected()) { - currentFrame.setSelected(false); - } - } - - if (!f.isSelected()) { - f.setSelected(true); - } - } catch (PropertyVetoException e) {} - if (f != currentFrame) { - currentFrameRef = new WeakReference(f); - } - } - -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsDesktopPaneUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsDesktopPaneUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* - * Copyright (c) 1997, 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 com.sun.java.swing.plaf.windows; - -import javax.swing.*; -import javax.swing.plaf.basic.*; -import javax.swing.plaf.ComponentUI; -import java.awt.event.*; - -/** - * Windows desktop pane. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - * - * @author David Kloba - */ -public class WindowsDesktopPaneUI extends BasicDesktopPaneUI -{ - public static ComponentUI createUI(JComponent c) { - return new WindowsDesktopPaneUI(); - } - - protected void installDesktopManager() { - desktopManager = desktop.getDesktopManager(); - if(desktopManager == null) { - desktopManager = new WindowsDesktopManager(); - desktop.setDesktopManager(desktopManager); - } - } - - protected void installDefaults() { - super.installDefaults(); - } - - @SuppressWarnings("deprecation") - protected void installKeyboardActions() { - super.installKeyboardActions(); - - // Request focus if it isn't set. - if(!desktop.requestDefaultFocus()) { - desktop.requestFocus(); - } - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsDesktopProperty.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsDesktopProperty.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * 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 com.sun.java.swing.plaf.windows; - -import javax.swing.UIManager; - -import sun.swing.plaf.DesktopProperty; - -/** - * Wrapper for a value from the desktop. The value is lazily looked up, and - * can be accessed using the UIManager.ActiveValue method - * createValue. If the underlying desktop property changes this - * will force the UIs to update all known Frames. You can invoke - * invalidate to force the value to be fetched again. - */ -public class WindowsDesktopProperty extends DesktopProperty { - - /** - * Updates the UIs of all the known Frames. - */ - @Override - protected final void updateAllUIs() { - // Check if the current UI is WindowsLookAndfeel and flush the XP style map. - // Note: Change the package test if this class is moved to a different package. - Class uiClass = UIManager.getLookAndFeel().getClass(); - if (uiClass.getPackage().equals(WindowsDesktopProperty.class.getPackage())) { - XPStyle.invalidateStyle(); - } - super.updateAllUIs(); - } - - /** - * Creates a WindowsDesktopProperty. - * - * @param key Key used in looking up desktop value. - * @param fallback Value used if desktop property is null. - */ - public WindowsDesktopProperty(String key, Object fallback) { - super(key,fallback); - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsEditorPaneUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsEditorPaneUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -/* - * Copyright (c) 1997, 1998, 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 com.sun.java.swing.plaf.windows; - -import javax.swing.plaf.*; -import javax.swing.plaf.basic.*; -import javax.swing.*; -import javax.swing.text.Caret; - - -/** - * Windows rendition of the component. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - */ -public class WindowsEditorPaneUI extends BasicEditorPaneUI -{ - - /** - * Creates a UI for a JEditorPane. - * - * @param c the configurable text component - * @return the UI - */ - public static ComponentUI createUI(JComponent c) { - return new WindowsEditorPaneUI(); - } - - /** - * Creates the object to use for a caret. By default an - * instance of WindowsCaret is created. This method - * can be redefined to provide something else that implements - * the InputPosition interface or a subclass of DefaultCaret. - * - * @return the caret object - */ - protected Caret createCaret() { - return new WindowsTextUI.WindowsCaret(); - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1325 +0,0 @@ -/* - * Copyright (c) 1997, 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 com.sun.java.swing.plaf.windows; - -import javax.swing.*; -import javax.swing.border.*; -import javax.swing.filechooser.*; -import javax.swing.event.*; -import javax.swing.plaf.*; -import javax.swing.plaf.basic.*; -import java.awt.*; -import java.awt.event.*; -import java.awt.image.BufferedImage; -import java.beans.*; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.*; -import java.security.AccessController; -import java.security.PrivilegedAction; - -import sun.awt.shell.ShellFolder; -import sun.swing.*; - -import javax.accessibility.*; - -/** - * Windows {@literal L&F} implementation of a FileChooser. - * - * @author Jeff Dinkins - */ -public class WindowsFileChooserUI extends BasicFileChooserUI { - - // The following are private because the implementation of the - // Windows FileChooser L&F is not complete yet. - - private JPanel centerPanel; - - private JLabel lookInLabel; - private JComboBox directoryComboBox; - private DirectoryComboBoxModel directoryComboBoxModel; - private ActionListener directoryComboBoxAction = new DirectoryComboBoxAction(); - - private FilterComboBoxModel filterComboBoxModel; - - private JTextField filenameTextField; - private FilePane filePane; - private WindowsPlacesBar placesBar; - - private JButton approveButton; - private JButton cancelButton; - - private JPanel buttonPanel; - private JPanel bottomPanel; - - private JComboBox filterComboBox; - - private static final Dimension hstrut10 = new Dimension(10, 1); - - private static final Dimension vstrut4 = new Dimension(1, 4); - private static final Dimension vstrut6 = new Dimension(1, 6); - private static final Dimension vstrut8 = new Dimension(1, 8); - - private static final Insets shrinkwrap = new Insets(0,0,0,0); - - // Preferred and Minimum sizes for the dialog box - private static int PREF_WIDTH = 425; - private static int PREF_HEIGHT = 245; - private static Dimension PREF_SIZE = new Dimension(PREF_WIDTH, PREF_HEIGHT); - - private static int MIN_WIDTH = 425; - private static int MIN_HEIGHT = 245; - - private static int LIST_PREF_WIDTH = 444; - private static int LIST_PREF_HEIGHT = 138; - private static Dimension LIST_PREF_SIZE = new Dimension(LIST_PREF_WIDTH, LIST_PREF_HEIGHT); - - // Labels, mnemonics, and tooltips (oh my!) - private int lookInLabelMnemonic = 0; - private String lookInLabelText = null; - private String saveInLabelText = null; - - private int fileNameLabelMnemonic = 0; - private String fileNameLabelText = null; - private int folderNameLabelMnemonic = 0; - private String folderNameLabelText = null; - - private int filesOfTypeLabelMnemonic = 0; - private String filesOfTypeLabelText = null; - - private String upFolderToolTipText = null; - private String upFolderAccessibleName = null; - - private String newFolderToolTipText = null; - private String newFolderAccessibleName = null; - - private String viewMenuButtonToolTipText = null; - private String viewMenuButtonAccessibleName = null; - - private BasicFileView fileView = new WindowsFileView(); - - private JLabel fileNameLabel; - - private void populateFileNameLabel() { - if (getFileChooser().getFileSelectionMode() == JFileChooser.DIRECTORIES_ONLY) { - fileNameLabel.setText(folderNameLabelText); - fileNameLabel.setDisplayedMnemonic(folderNameLabelMnemonic); - } else { - fileNameLabel.setText(fileNameLabelText); - fileNameLabel.setDisplayedMnemonic(fileNameLabelMnemonic); - } - } - - // - // ComponentUI Interface Implementation methods - // - public static ComponentUI createUI(JComponent c) { - return new WindowsFileChooserUI((JFileChooser) c); - } - - public WindowsFileChooserUI(JFileChooser filechooser) { - super(filechooser); - } - - public void installUI(JComponent c) { - super.installUI(c); - } - - public void uninstallComponents(JFileChooser fc) { - fc.removeAll(); - } - - private class WindowsFileChooserUIAccessor implements FilePane.FileChooserUIAccessor { - public JFileChooser getFileChooser() { - return WindowsFileChooserUI.this.getFileChooser(); - } - - public BasicDirectoryModel getModel() { - return WindowsFileChooserUI.this.getModel(); - } - - public JPanel createList() { - return WindowsFileChooserUI.this.createList(getFileChooser()); - } - - public JPanel createDetailsView() { - return WindowsFileChooserUI.this.createDetailsView(getFileChooser()); - } - - public boolean isDirectorySelected() { - return WindowsFileChooserUI.this.isDirectorySelected(); - } - - public File getDirectory() { - return WindowsFileChooserUI.this.getDirectory(); - } - - public Action getChangeToParentDirectoryAction() { - return WindowsFileChooserUI.this.getChangeToParentDirectoryAction(); - } - - public Action getApproveSelectionAction() { - return WindowsFileChooserUI.this.getApproveSelectionAction(); - } - - public Action getNewFolderAction() { - return WindowsFileChooserUI.this.getNewFolderAction(); - } - - public MouseListener createDoubleClickListener(JList list) { - return WindowsFileChooserUI.this.createDoubleClickListener(getFileChooser(), - list); - } - - public ListSelectionListener createListSelectionListener() { - return WindowsFileChooserUI.this.createListSelectionListener(getFileChooser()); - } - } - - public void installComponents(JFileChooser fc) { - filePane = new FilePane(new WindowsFileChooserUIAccessor()); - fc.addPropertyChangeListener(filePane); - - FileSystemView fsv = fc.getFileSystemView(); - - fc.setBorder(new EmptyBorder(4, 10, 10, 10)); - fc.setLayout(new BorderLayout(8, 8)); - - updateUseShellFolder(); - - // ********************************* // - // **** Construct the top panel **** // - // ********************************* // - - // Directory manipulation buttons - JToolBar topPanel = new JToolBar(); - topPanel.setFloatable(false); - topPanel.putClientProperty("JToolBar.isRollover", Boolean.TRUE); - - // Add the top panel to the fileChooser - fc.add(topPanel, BorderLayout.NORTH); - - // ComboBox Label - @SuppressWarnings("serial") // anonymous class - JLabel tmp1 = new JLabel(lookInLabelText, JLabel.TRAILING) { - public Dimension getPreferredSize() { - return getMinimumSize(); - } - - public Dimension getMinimumSize() { - Dimension d = super.getPreferredSize(); - if (placesBar != null) { - d.width = Math.max(d.width, placesBar.getWidth()); - } - return d; - } - }; - lookInLabel = tmp1; - lookInLabel.setDisplayedMnemonic(lookInLabelMnemonic); - lookInLabel.setAlignmentX(JComponent.LEFT_ALIGNMENT); - lookInLabel.setAlignmentY(JComponent.CENTER_ALIGNMENT); - topPanel.add(lookInLabel); - topPanel.add(Box.createRigidArea(new Dimension(8,0))); - - // CurrentDir ComboBox - @SuppressWarnings("serial") // anonymous class - JComboBox tmp2 = new JComboBox() { - public Dimension getMinimumSize() { - Dimension d = super.getMinimumSize(); - d.width = 60; - return d; - } - - public Dimension getPreferredSize() { - Dimension d = super.getPreferredSize(); - // Must be small enough to not affect total width. - d.width = 150; - return d; - } - }; - directoryComboBox = tmp2; - directoryComboBox.putClientProperty( "JComboBox.lightweightKeyboardNavigation", "Lightweight" ); - lookInLabel.setLabelFor(directoryComboBox); - directoryComboBoxModel = createDirectoryComboBoxModel(fc); - directoryComboBox.setModel(directoryComboBoxModel); - directoryComboBox.addActionListener(directoryComboBoxAction); - directoryComboBox.setRenderer(createDirectoryComboBoxRenderer(fc)); - directoryComboBox.setAlignmentX(JComponent.LEFT_ALIGNMENT); - directoryComboBox.setAlignmentY(JComponent.CENTER_ALIGNMENT); - directoryComboBox.setMaximumRowCount(8); - - topPanel.add(directoryComboBox); - topPanel.add(Box.createRigidArea(hstrut10)); - - // Up Button - JButton upFolderButton = createToolButton(getChangeToParentDirectoryAction(), upFolderIcon, - upFolderToolTipText, upFolderAccessibleName); - topPanel.add(upFolderButton); - - // New Directory Button - if (!UIManager.getBoolean("FileChooser.readOnly")) { - JButton newFolderButton = createToolButton(filePane.getNewFolderAction(), newFolderIcon, - newFolderToolTipText, newFolderAccessibleName); - topPanel.add(newFolderButton); - } - - // View button group - ButtonGroup viewButtonGroup = new ButtonGroup(); - - // Popup Menu - final JPopupMenu viewTypePopupMenu = new JPopupMenu(); - - final JRadioButtonMenuItem listViewMenuItem = new JRadioButtonMenuItem( - filePane.getViewTypeAction(FilePane.VIEWTYPE_LIST)); - listViewMenuItem.setSelected(filePane.getViewType() == FilePane.VIEWTYPE_LIST); - viewTypePopupMenu.add(listViewMenuItem); - viewButtonGroup.add(listViewMenuItem); - - final JRadioButtonMenuItem detailsViewMenuItem = new JRadioButtonMenuItem( - filePane.getViewTypeAction(FilePane.VIEWTYPE_DETAILS)); - detailsViewMenuItem.setSelected(filePane.getViewType() == FilePane.VIEWTYPE_DETAILS); - viewTypePopupMenu.add(detailsViewMenuItem); - viewButtonGroup.add(detailsViewMenuItem); - - // Create icon for viewMenuButton - BufferedImage image = new BufferedImage(viewMenuIcon.getIconWidth() + 7, viewMenuIcon.getIconHeight(), - BufferedImage.TYPE_INT_ARGB); - Graphics graphics = image.getGraphics(); - viewMenuIcon.paintIcon(filePane, graphics, 0, 0); - int x = image.getWidth() - 5; - int y = image.getHeight() / 2 - 1; - graphics.setColor(Color.BLACK); - graphics.fillPolygon(new int[]{x, x + 5, x + 2}, new int[]{y, y, y + 3}, 3); - - // Details Button - final JButton viewMenuButton = createToolButton(null, new ImageIcon(image), viewMenuButtonToolTipText, - viewMenuButtonAccessibleName); - - viewMenuButton.addMouseListener(new MouseAdapter() { - public void mousePressed(MouseEvent e) { - if (SwingUtilities.isLeftMouseButton(e) && !viewMenuButton.isSelected()) { - viewMenuButton.setSelected(true); - - viewTypePopupMenu.show(viewMenuButton, 0, viewMenuButton.getHeight()); - } - } - }); - viewMenuButton.addKeyListener(new KeyAdapter() { - public void keyPressed(KeyEvent e) { - // Forbid keyboard actions if the button is not in rollover state - if (e.getKeyCode() == KeyEvent.VK_SPACE && viewMenuButton.getModel().isRollover()) { - viewMenuButton.setSelected(true); - - viewTypePopupMenu.show(viewMenuButton, 0, viewMenuButton.getHeight()); - } - } - }); - viewTypePopupMenu.addPopupMenuListener(new PopupMenuListener() { - public void popupMenuWillBecomeVisible(PopupMenuEvent e) { - } - - public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - viewMenuButton.setSelected(false); - } - }); - } - - public void popupMenuCanceled(PopupMenuEvent e) { - } - }); - - topPanel.add(viewMenuButton); - - topPanel.add(Box.createRigidArea(new Dimension(80, 0))); - - filePane.addPropertyChangeListener(new PropertyChangeListener() { - public void propertyChange(PropertyChangeEvent e) { - if ("viewType".equals(e.getPropertyName())) { - switch (filePane.getViewType()) { - case FilePane.VIEWTYPE_LIST: - listViewMenuItem.setSelected(true); - break; - - case FilePane.VIEWTYPE_DETAILS: - detailsViewMenuItem.setSelected(true); - break; - } - } - } - }); - - // ************************************** // - // ******* Add the directory pane ******* // - // ************************************** // - centerPanel = new JPanel(new BorderLayout()); - centerPanel.add(getAccessoryPanel(), BorderLayout.AFTER_LINE_ENDS); - JComponent accessory = fc.getAccessory(); - if(accessory != null) { - getAccessoryPanel().add(accessory); - } - filePane.setPreferredSize(LIST_PREF_SIZE); - centerPanel.add(filePane, BorderLayout.CENTER); - fc.add(centerPanel, BorderLayout.CENTER); - - // ********************************** // - // **** Construct the bottom panel ** // - // ********************************** // - getBottomPanel().setLayout(new BoxLayout(getBottomPanel(), BoxLayout.LINE_AXIS)); - - // Add the bottom panel to file chooser - centerPanel.add(getBottomPanel(), BorderLayout.SOUTH); - - // labels - JPanel labelPanel = new JPanel(); - labelPanel.setLayout(new BoxLayout(labelPanel, BoxLayout.PAGE_AXIS)); - labelPanel.add(Box.createRigidArea(vstrut4)); - - fileNameLabel = new JLabel(); - populateFileNameLabel(); - fileNameLabel.setAlignmentY(0); - labelPanel.add(fileNameLabel); - - labelPanel.add(Box.createRigidArea(new Dimension(1,12))); - - JLabel ftl = new JLabel(filesOfTypeLabelText); - ftl.setDisplayedMnemonic(filesOfTypeLabelMnemonic); - labelPanel.add(ftl); - - getBottomPanel().add(labelPanel); - getBottomPanel().add(Box.createRigidArea(new Dimension(15, 0))); - - // file entry and filters - JPanel fileAndFilterPanel = new JPanel(); - fileAndFilterPanel.add(Box.createRigidArea(vstrut8)); - fileAndFilterPanel.setLayout(new BoxLayout(fileAndFilterPanel, BoxLayout.Y_AXIS)); - - @SuppressWarnings("serial") // anonymous class - JTextField tmp3 = new JTextField(35) { - public Dimension getMaximumSize() { - return new Dimension(Short.MAX_VALUE, super.getPreferredSize().height); - } - }; - filenameTextField = tmp3; - - fileNameLabel.setLabelFor(filenameTextField); - filenameTextField.addFocusListener( - new FocusAdapter() { - public void focusGained(FocusEvent e) { - if (!getFileChooser().isMultiSelectionEnabled()) { - filePane.clearSelection(); - } - } - } - ); - - if (fc.isMultiSelectionEnabled()) { - setFileName(fileNameString(fc.getSelectedFiles())); - } else { - setFileName(fileNameString(fc.getSelectedFile())); - } - - fileAndFilterPanel.add(filenameTextField); - fileAndFilterPanel.add(Box.createRigidArea(vstrut8)); - - filterComboBoxModel = createFilterComboBoxModel(); - fc.addPropertyChangeListener(filterComboBoxModel); - filterComboBox = new JComboBox(filterComboBoxModel); - ftl.setLabelFor(filterComboBox); - filterComboBox.setRenderer(createFilterComboBoxRenderer()); - fileAndFilterPanel.add(filterComboBox); - - getBottomPanel().add(fileAndFilterPanel); - getBottomPanel().add(Box.createRigidArea(new Dimension(30, 0))); - - // buttons - getButtonPanel().setLayout(new BoxLayout(getButtonPanel(), BoxLayout.Y_AXIS)); - - @SuppressWarnings("serial") // anonymous class - JButton tmp4 = new JButton(getApproveButtonText(fc)) { - public Dimension getMaximumSize() { - return approveButton.getPreferredSize().width > cancelButton.getPreferredSize().width ? - approveButton.getPreferredSize() : cancelButton.getPreferredSize(); - } - }; - approveButton = tmp4; - Insets buttonMargin = approveButton.getMargin(); - buttonMargin = new InsetsUIResource(buttonMargin.top, buttonMargin.left + 5, - buttonMargin.bottom, buttonMargin.right + 5); - approveButton.setMargin(buttonMargin); - approveButton.setMnemonic(getApproveButtonMnemonic(fc)); - approveButton.addActionListener(getApproveSelectionAction()); - approveButton.setToolTipText(getApproveButtonToolTipText(fc)); - getButtonPanel().add(Box.createRigidArea(vstrut6)); - getButtonPanel().add(approveButton); - getButtonPanel().add(Box.createRigidArea(vstrut4)); - - @SuppressWarnings("serial") // anonymous class - JButton tmp5 = new JButton(cancelButtonText) { - public Dimension getMaximumSize() { - return approveButton.getPreferredSize().width > cancelButton.getPreferredSize().width ? - approveButton.getPreferredSize() : cancelButton.getPreferredSize(); - } - }; - cancelButton = tmp5; - cancelButton.setMargin(buttonMargin); - cancelButton.setToolTipText(cancelButtonToolTipText); - cancelButton.addActionListener(getCancelSelectionAction()); - getButtonPanel().add(cancelButton); - - if(fc.getControlButtonsAreShown()) { - addControlButtons(); - } - } - - private void updateUseShellFolder() { - // Decide whether to use the ShellFolder class to populate shortcut - // panel and combobox. - JFileChooser fc = getFileChooser(); - - if (FilePane.usesShellFolder(fc)) { - if (placesBar == null && !UIManager.getBoolean("FileChooser.noPlacesBar")) { - placesBar = new WindowsPlacesBar(fc, XPStyle.getXP() != null); - fc.add(placesBar, BorderLayout.BEFORE_LINE_BEGINS); - fc.addPropertyChangeListener(placesBar); - } - } else { - if (placesBar != null) { - fc.remove(placesBar); - fc.removePropertyChangeListener(placesBar); - placesBar = null; - } - } - } - - protected JPanel getButtonPanel() { - if(buttonPanel == null) { - buttonPanel = new JPanel(); - } - return buttonPanel; - } - - protected JPanel getBottomPanel() { - if(bottomPanel == null) { - bottomPanel = new JPanel(); - } - return bottomPanel; - } - - protected void installStrings(JFileChooser fc) { - super.installStrings(fc); - - Locale l = fc.getLocale(); - - lookInLabelMnemonic = getMnemonic("FileChooser.lookInLabelMnemonic", l); - lookInLabelText = UIManager.getString("FileChooser.lookInLabelText",l); - saveInLabelText = UIManager.getString("FileChooser.saveInLabelText",l); - - fileNameLabelMnemonic = getMnemonic("FileChooser.fileNameLabelMnemonic", l); - fileNameLabelText = UIManager.getString("FileChooser.fileNameLabelText",l); - folderNameLabelMnemonic = getMnemonic("FileChooser.folderNameLabelMnemonic", l); - folderNameLabelText = UIManager.getString("FileChooser.folderNameLabelText",l); - - filesOfTypeLabelMnemonic = getMnemonic("FileChooser.filesOfTypeLabelMnemonic", l); - filesOfTypeLabelText = UIManager.getString("FileChooser.filesOfTypeLabelText",l); - - upFolderToolTipText = UIManager.getString("FileChooser.upFolderToolTipText",l); - upFolderAccessibleName = UIManager.getString("FileChooser.upFolderAccessibleName",l); - - newFolderToolTipText = UIManager.getString("FileChooser.newFolderToolTipText",l); - newFolderAccessibleName = UIManager.getString("FileChooser.newFolderAccessibleName",l); - - viewMenuButtonToolTipText = UIManager.getString("FileChooser.viewMenuButtonToolTipText",l); - viewMenuButtonAccessibleName = UIManager.getString("FileChooser.viewMenuButtonAccessibleName",l); - } - - private Integer getMnemonic(String key, Locale l) { - return SwingUtilities2.getUIDefaultsInt(key, l); - } - - protected void installListeners(JFileChooser fc) { - super.installListeners(fc); - ActionMap actionMap = getActionMap(); - SwingUtilities.replaceUIActionMap(fc, actionMap); - } - - protected ActionMap getActionMap() { - return createActionMap(); - } - - protected ActionMap createActionMap() { - ActionMap map = new ActionMapUIResource(); - FilePane.addActionsToMap(map, filePane.getActions()); - return map; - } - - protected JPanel createList(JFileChooser fc) { - return filePane.createList(); - } - - protected JPanel createDetailsView(JFileChooser fc) { - return filePane.createDetailsView(); - } - - /** - * Creates a selection listener for the list of files and directories. - * - * @param fc a JFileChooser - * @return a ListSelectionListener - */ - public ListSelectionListener createListSelectionListener(JFileChooser fc) { - return super.createListSelectionListener(fc); - } - - // Obsolete class, not used in this version. - @SuppressWarnings("serial") - protected class WindowsNewFolderAction extends NewFolderAction { - } - - // Obsolete class, not used in this version. - protected class SingleClickListener extends MouseAdapter { - } - - // Obsolete class, not used in this version. - @SuppressWarnings("serial") // Superclass is not serializable across versions - protected class FileRenderer extends DefaultListCellRenderer { - } - - public void uninstallUI(JComponent c) { - // Remove listeners - c.removePropertyChangeListener(filterComboBoxModel); - c.removePropertyChangeListener(filePane); - if (placesBar != null) { - c.removePropertyChangeListener(placesBar); - } - cancelButton.removeActionListener(getCancelSelectionAction()); - approveButton.removeActionListener(getApproveSelectionAction()); - filenameTextField.removeActionListener(getApproveSelectionAction()); - - if (filePane != null) { - filePane.uninstallUI(); - filePane = null; - } - - super.uninstallUI(c); - } - - /** - * Returns the preferred size of the specified - * JFileChooser. - * The preferred size is at least as large, - * in both height and width, - * as the preferred size recommended - * by the file chooser's layout manager. - * - * @param c a JFileChooser - * @return a Dimension specifying the preferred - * width and height of the file chooser - */ - @Override - public Dimension getPreferredSize(JComponent c) { - int prefWidth = PREF_SIZE.width; - Dimension d = c.getLayout().preferredLayoutSize(c); - if (d != null) { - return new Dimension(d.width < prefWidth ? prefWidth : d.width, - d.height < PREF_SIZE.height ? PREF_SIZE.height : d.height); - } else { - return new Dimension(prefWidth, PREF_SIZE.height); - } - } - - /** - * Returns the minimum size of the JFileChooser. - * - * @param c a JFileChooser - * @return a Dimension specifying the minimum - * width and height of the file chooser - */ - @Override - public Dimension getMinimumSize(JComponent c) { - return new Dimension(MIN_WIDTH, MIN_HEIGHT); - } - - /** - * Returns the maximum size of the JFileChooser. - * - * @param c a JFileChooser - * @return a Dimension specifying the maximum - * width and height of the file chooser - */ - @Override - public Dimension getMaximumSize(JComponent c) { - return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); - } - - private String fileNameString(File file) { - if (file == null) { - return null; - } else { - JFileChooser fc = getFileChooser(); - if ((fc.isDirectorySelectionEnabled() && !fc.isFileSelectionEnabled()) || - (fc.isDirectorySelectionEnabled() && fc.isFileSelectionEnabled() && fc.getFileSystemView().isFileSystemRoot(file))){ - return file.getPath(); - } else { - return file.getName(); - } - } - } - - private String fileNameString(File[] files) { - StringBuilder buf = new StringBuilder(); - for (int i = 0; files != null && i < files.length; i++) { - if (i > 0) { - buf.append(" "); - } - if (files.length > 1) { - buf.append("\""); - } - buf.append(fileNameString(files[i])); - if (files.length > 1) { - buf.append("\""); - } - } - return buf.toString(); - } - - /* The following methods are used by the PropertyChange Listener */ - - private void doSelectedFileChanged(PropertyChangeEvent e) { - File f = (File) e.getNewValue(); - JFileChooser fc = getFileChooser(); - if (f != null - && ((fc.isFileSelectionEnabled() && !f.isDirectory()) - || (f.isDirectory() && fc.isDirectorySelectionEnabled()))) { - - setFileName(fileNameString(f)); - } - } - - private void doSelectedFilesChanged(PropertyChangeEvent e) { - File[] files = (File[]) e.getNewValue(); - JFileChooser fc = getFileChooser(); - if (files != null - && files.length > 0 - && (files.length > 1 || fc.isDirectorySelectionEnabled() || !files[0].isDirectory())) { - setFileName(fileNameString(files)); - } - } - - private void doDirectoryChanged(PropertyChangeEvent e) { - JFileChooser fc = getFileChooser(); - FileSystemView fsv = fc.getFileSystemView(); - - clearIconCache(); - File currentDirectory = fc.getCurrentDirectory(); - if(currentDirectory != null) { - directoryComboBoxModel.addItem(currentDirectory); - - if (fc.isDirectorySelectionEnabled() && !fc.isFileSelectionEnabled()) { - if (fsv.isFileSystem(currentDirectory)) { - setFileName(currentDirectory.getPath()); - } else { - setFileName(null); - } - } - } - } - - private void doFilterChanged(PropertyChangeEvent e) { - clearIconCache(); - } - - private void doFileSelectionModeChanged(PropertyChangeEvent e) { - if (fileNameLabel != null) { - populateFileNameLabel(); - } - clearIconCache(); - - JFileChooser fc = getFileChooser(); - File currentDirectory = fc.getCurrentDirectory(); - if (currentDirectory != null - && fc.isDirectorySelectionEnabled() - && !fc.isFileSelectionEnabled() - && fc.getFileSystemView().isFileSystem(currentDirectory)) { - - setFileName(currentDirectory.getPath()); - } else { - setFileName(null); - } - } - - private void doAccessoryChanged(PropertyChangeEvent e) { - if(getAccessoryPanel() != null) { - if(e.getOldValue() != null) { - getAccessoryPanel().remove((JComponent) e.getOldValue()); - } - JComponent accessory = (JComponent) e.getNewValue(); - if(accessory != null) { - getAccessoryPanel().add(accessory, BorderLayout.CENTER); - } - } - } - - private void doApproveButtonTextChanged(PropertyChangeEvent e) { - JFileChooser chooser = getFileChooser(); - approveButton.setText(getApproveButtonText(chooser)); - approveButton.setToolTipText(getApproveButtonToolTipText(chooser)); - approveButton.setMnemonic(getApproveButtonMnemonic(chooser)); - } - - private void doDialogTypeChanged(PropertyChangeEvent e) { - JFileChooser chooser = getFileChooser(); - approveButton.setText(getApproveButtonText(chooser)); - approveButton.setToolTipText(getApproveButtonToolTipText(chooser)); - approveButton.setMnemonic(getApproveButtonMnemonic(chooser)); - if (chooser.getDialogType() == JFileChooser.SAVE_DIALOG) { - lookInLabel.setText(saveInLabelText); - } else { - lookInLabel.setText(lookInLabelText); - } - } - - private void doApproveButtonMnemonicChanged(PropertyChangeEvent e) { - approveButton.setMnemonic(getApproveButtonMnemonic(getFileChooser())); - } - - private void doControlButtonsChanged(PropertyChangeEvent e) { - if(getFileChooser().getControlButtonsAreShown()) { - addControlButtons(); - } else { - removeControlButtons(); - } - } - - /* - * Listen for filechooser property changes, such as - * the selected file changing, or the type of the dialog changing. - */ - public PropertyChangeListener createPropertyChangeListener(JFileChooser fc) { - return new PropertyChangeListener() { - public void propertyChange(PropertyChangeEvent e) { - String s = e.getPropertyName(); - if(s.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) { - doSelectedFileChanged(e); - } else if (s.equals(JFileChooser.SELECTED_FILES_CHANGED_PROPERTY)) { - doSelectedFilesChanged(e); - } else if(s.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)) { - doDirectoryChanged(e); - } else if(s.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY)) { - doFilterChanged(e); - } else if(s.equals(JFileChooser.FILE_SELECTION_MODE_CHANGED_PROPERTY)) { - doFileSelectionModeChanged(e); - } else if(s.equals(JFileChooser.ACCESSORY_CHANGED_PROPERTY)) { - doAccessoryChanged(e); - } else if (s.equals(JFileChooser.APPROVE_BUTTON_TEXT_CHANGED_PROPERTY) || - s.equals(JFileChooser.APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY)) { - doApproveButtonTextChanged(e); - } else if(s.equals(JFileChooser.DIALOG_TYPE_CHANGED_PROPERTY)) { - doDialogTypeChanged(e); - } else if(s.equals(JFileChooser.APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY)) { - doApproveButtonMnemonicChanged(e); - } else if(s.equals(JFileChooser.CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY)) { - doControlButtonsChanged(e); - } else if (s == "FileChooser.useShellFolder") { - updateUseShellFolder(); - doDirectoryChanged(e); - } else if (s.equals("componentOrientation")) { - ComponentOrientation o = (ComponentOrientation)e.getNewValue(); - JFileChooser cc = (JFileChooser)e.getSource(); - if (o != e.getOldValue()) { - cc.applyComponentOrientation(o); - } - } else if (s.equals("ancestor")) { - if (e.getOldValue() == null && e.getNewValue() != null) { - // Ancestor was added, set initial focus - filenameTextField.selectAll(); - filenameTextField.requestFocus(); - } - } - } - }; - } - - - protected void removeControlButtons() { - getBottomPanel().remove(getButtonPanel()); - } - - protected void addControlButtons() { - getBottomPanel().add(getButtonPanel()); - } - - public void ensureFileIsVisible(JFileChooser fc, File f) { - filePane.ensureFileIsVisible(fc, f); - } - - public void rescanCurrentDirectory(JFileChooser fc) { - filePane.rescanCurrentDirectory(); - } - - public String getFileName() { - if(filenameTextField != null) { - return filenameTextField.getText(); - } else { - return null; - } - } - - public void setFileName(String filename) { - if(filenameTextField != null) { - filenameTextField.setText(filename); - } - } - - /** - * Property to remember whether a directory is currently selected in the UI. - * This is normally called by the UI on a selection event. - * - * @param directorySelected if a directory is currently selected. - * @since 1.4 - */ - protected void setDirectorySelected(boolean directorySelected) { - super.setDirectorySelected(directorySelected); - JFileChooser chooser = getFileChooser(); - if(directorySelected) { - approveButton.setText(directoryOpenButtonText); - approveButton.setToolTipText(directoryOpenButtonToolTipText); - approveButton.setMnemonic(directoryOpenButtonMnemonic); - } else { - approveButton.setText(getApproveButtonText(chooser)); - approveButton.setToolTipText(getApproveButtonToolTipText(chooser)); - approveButton.setMnemonic(getApproveButtonMnemonic(chooser)); - } - } - - public String getDirectoryName() { - // PENDING(jeff) - get the name from the directory combobox - return null; - } - - public void setDirectoryName(String dirname) { - // PENDING(jeff) - set the name in the directory combobox - } - - protected DirectoryComboBoxRenderer createDirectoryComboBoxRenderer(JFileChooser fc) { - return new DirectoryComboBoxRenderer(); - } - - @SuppressWarnings("serial") // anonymous class - private static JButton createToolButton(Action a, Icon defaultIcon, String toolTipText, String accessibleName) { - final JButton result = new JButton(a); - - result.setText(null); - result.setIcon(defaultIcon); - result.setToolTipText(toolTipText); - result.setRequestFocusEnabled(false); - result.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, accessibleName); - result.putClientProperty(WindowsLookAndFeel.HI_RES_DISABLED_ICON_CLIENT_KEY, Boolean.TRUE); - result.setAlignmentX(JComponent.LEFT_ALIGNMENT); - result.setAlignmentY(JComponent.CENTER_ALIGNMENT); - result.setMargin(shrinkwrap); - result.setFocusPainted(false); - - result.setModel(new DefaultButtonModel() { - public void setPressed(boolean b) { - // Forbid keyboard actions if the button is not in rollover state - if (!b || isRollover()) { - super.setPressed(b); - } - } - - public void setRollover(boolean b) { - if (b && !isRollover()) { - // Reset other buttons - for (Component component : result.getParent().getComponents()) { - if (component instanceof JButton && component != result) { - ((JButton) component).getModel().setRollover(false); - } - } - } - - super.setRollover(b); - } - - public void setSelected(boolean b) { - super.setSelected(b); - - if (b) { - stateMask |= PRESSED | ARMED; - } else { - stateMask &= ~(PRESSED | ARMED); - } - } - }); - - result.addFocusListener(new FocusAdapter() { - public void focusGained(FocusEvent e) { - result.getModel().setRollover(true); - } - - public void focusLost(FocusEvent e) { - result.getModel().setRollover(false); - } - }); - - return result; - } - - // - // Renderer for DirectoryComboBox - // - @SuppressWarnings("serial") // Superclass is not serializable across versions - class DirectoryComboBoxRenderer extends DefaultListCellRenderer { - IndentIcon ii = new IndentIcon(); - public Component getListCellRendererComponent(JList list, Object value, - int index, boolean isSelected, - boolean cellHasFocus) { - - super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - - if (value == null) { - setText(""); - return this; - } - File directory = (File)value; - setText(getFileChooser().getName(directory)); - Icon icon = getFileChooser().getIcon(directory); - ii.icon = icon; - ii.depth = directoryComboBoxModel.getDepth(index); - setIcon(ii); - - return this; - } - } - - static final int space = 10; - class IndentIcon implements Icon { - - Icon icon = null; - int depth = 0; - - public void paintIcon(Component c, Graphics g, int x, int y) { - if (c.getComponentOrientation().isLeftToRight()) { - icon.paintIcon(c, g, x+depth*space, y); - } else { - icon.paintIcon(c, g, x, y); - } - } - - public int getIconWidth() { - return icon.getIconWidth() + depth*space; - } - - public int getIconHeight() { - return icon.getIconHeight(); - } - - } - - // - // DataModel for DirectoryComboxbox - // - protected DirectoryComboBoxModel createDirectoryComboBoxModel(JFileChooser fc) { - return new DirectoryComboBoxModel(); - } - - /** - * Data model for a type-face selection combo-box. - */ - @SuppressWarnings("serial") // Superclass is not serializable across versions - protected class DirectoryComboBoxModel extends AbstractListModel implements ComboBoxModel { - Vector directories = new Vector(); - int[] depths = null; - File selectedDirectory = null; - JFileChooser chooser = getFileChooser(); - FileSystemView fsv = chooser.getFileSystemView(); - - public DirectoryComboBoxModel() { - // Add the current directory to the model, and make it the - // selectedDirectory - File dir = getFileChooser().getCurrentDirectory(); - if(dir != null) { - addItem(dir); - } - } - - /** - * Adds the directory to the model and sets it to be selected, - * additionally clears out the previous selected directory and - * the paths leading up to it, if any. - */ - private void addItem(File directory) { - - if(directory == null) { - return; - } - - boolean useShellFolder = FilePane.usesShellFolder(chooser); - - directories.clear(); - - File[] baseFolders = (useShellFolder) - ? (File[]) ShellFolder.get("fileChooserComboBoxFolders") - : fsv.getRoots(); - directories.addAll(Arrays.asList(baseFolders)); - - // Get the canonical (full) path. This has the side - // benefit of removing extraneous chars from the path, - // for example /foo/bar/ becomes /foo/bar - File canonical; - try { - canonical = directory.getCanonicalFile(); - } catch (IOException e) { - // Maybe drive is not ready. Can't abort here. - canonical = directory; - } - - // create File instances of each directory leading up to the top - try { - File sf = useShellFolder ? ShellFolder.getShellFolder(canonical) - : canonical; - File f = sf; - Vector path = new Vector(10); - do { - path.addElement(f); - } while ((f = f.getParentFile()) != null); - - int pathCount = path.size(); - // Insert chain at appropriate place in vector - for (int i = 0; i < pathCount; i++) { - f = path.get(i); - if (directories.contains(f)) { - int topIndex = directories.indexOf(f); - for (int j = i-1; j >= 0; j--) { - directories.insertElementAt(path.get(j), topIndex+i-j); - } - break; - } - } - calculateDepths(); - setSelectedItem(sf); - } catch (FileNotFoundException ex) { - calculateDepths(); - } - } - - private void calculateDepths() { - depths = new int[directories.size()]; - for (int i = 0; i < depths.length; i++) { - File dir = directories.get(i); - File parent = dir.getParentFile(); - depths[i] = 0; - if (parent != null) { - for (int j = i-1; j >= 0; j--) { - if (parent.equals(directories.get(j))) { - depths[i] = depths[j] + 1; - break; - } - } - } - } - } - - public int getDepth(int i) { - return (depths != null && i >= 0 && i < depths.length) ? depths[i] : 0; - } - - public void setSelectedItem(Object selectedDirectory) { - this.selectedDirectory = (File)selectedDirectory; - fireContentsChanged(this, -1, -1); - } - - public Object getSelectedItem() { - return selectedDirectory; - } - - public int getSize() { - return directories.size(); - } - - public File getElementAt(int index) { - return directories.elementAt(index); - } - } - - // - // Renderer for Types ComboBox - // - protected FilterComboBoxRenderer createFilterComboBoxRenderer() { - return new FilterComboBoxRenderer(); - } - - /** - * Render different type sizes and styles. - */ - @SuppressWarnings("serial") // Superclass is not serializable across versions - public class FilterComboBoxRenderer extends DefaultListCellRenderer { - public Component getListCellRendererComponent(JList list, - Object value, int index, boolean isSelected, - boolean cellHasFocus) { - - super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - - if (value != null && value instanceof FileFilter) { - setText(((FileFilter)value).getDescription()); - } - - return this; - } - } - - // - // DataModel for Types Comboxbox - // - protected FilterComboBoxModel createFilterComboBoxModel() { - return new FilterComboBoxModel(); - } - - /** - * Data model for a type-face selection combo-box. - */ - @SuppressWarnings("serial") // Superclass is not serializable across versions - protected class FilterComboBoxModel extends AbstractListModel implements ComboBoxModel, - PropertyChangeListener { - protected FileFilter[] filters; - protected FilterComboBoxModel() { - super(); - filters = getFileChooser().getChoosableFileFilters(); - } - - public void propertyChange(PropertyChangeEvent e) { - String prop = e.getPropertyName(); - if(prop == JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - filters = (FileFilter[]) e.getNewValue(); - fireContentsChanged(this, -1, -1); - } else if (prop == JFileChooser.FILE_FILTER_CHANGED_PROPERTY) { - fireContentsChanged(this, -1, -1); - } - } - - public void setSelectedItem(Object filter) { - if(filter != null) { - getFileChooser().setFileFilter((FileFilter) filter); - fireContentsChanged(this, -1, -1); - } - } - - public Object getSelectedItem() { - // Ensure that the current filter is in the list. - // NOTE: we shouldnt' have to do this, since JFileChooser adds - // the filter to the choosable filters list when the filter - // is set. Lets be paranoid just in case someone overrides - // setFileFilter in JFileChooser. - FileFilter currentFilter = getFileChooser().getFileFilter(); - boolean found = false; - if(currentFilter != null) { - for (FileFilter filter : filters) { - if (filter == currentFilter) { - found = true; - } - } - if(found == false) { - getFileChooser().addChoosableFileFilter(currentFilter); - } - } - return getFileChooser().getFileFilter(); - } - - public int getSize() { - if(filters != null) { - return filters.length; - } else { - return 0; - } - } - - public FileFilter getElementAt(int index) { - if(index > getSize() - 1) { - // This shouldn't happen. Try to recover gracefully. - return getFileChooser().getFileFilter(); - } - if(filters != null) { - return filters[index]; - } else { - return null; - } - } - } - - public void valueChanged(ListSelectionEvent e) { - JFileChooser fc = getFileChooser(); - File f = fc.getSelectedFile(); - if (!e.getValueIsAdjusting() && f != null && !getFileChooser().isTraversable(f)) { - setFileName(fileNameString(f)); - } - } - - /** - * Acts when DirectoryComboBox has changed the selected item. - */ - protected class DirectoryComboBoxAction implements ActionListener { - - - - - public void actionPerformed(ActionEvent e) { - File f = (File)directoryComboBox.getSelectedItem(); - getFileChooser().setCurrentDirectory(f); - } - } - - protected JButton getApproveButton(JFileChooser fc) { - return approveButton; - } - - public FileView getFileView(JFileChooser fc) { - return fileView; - } - - // *********************** - // * FileView operations * - // *********************** - protected class WindowsFileView extends BasicFileView { - /* FileView type descriptions */ - - public Icon getIcon(File f) { - Icon icon = getCachedIcon(f); - if (icon != null) { - return icon; - } - if (f != null) { - icon = getFileChooser().getFileSystemView().getSystemIcon(f); - } - if (icon == null) { - icon = super.getIcon(f); - } - cacheIcon(f, icon); - return icon; - } - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsGraphicsUtils.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsGraphicsUtils.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,236 +0,0 @@ -/* - * Copyright (c) 2000, 2015, 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 com.sun.java.swing.plaf.windows; - -import sun.swing.SwingUtilities2; - -import java.awt.*; - -import javax.swing.*; -import javax.swing.plaf.UIResource; - -import static com.sun.java.swing.plaf.windows.TMSchema.*; - -/** - * A collection of static utility methods used for rendering the Windows look - * and feel. - * - * @author Mark Davidson - * @since 1.4 - */ -public class WindowsGraphicsUtils { - - /** - * Renders a text String in Windows without the mnemonic. - * This is here because the WindowsUI hierarchy doesn't match the Component hierarchy. All - * the overriden paintText methods of the ButtonUI delegates will call this static method. - * - * @param g Graphics context - * @param b Current button to render - * @param textRect Bounding rectangle to render the text. - * @param text String to render - */ - public static void paintText(Graphics g, AbstractButton b, - Rectangle textRect, String text, - int textShiftOffset) { - FontMetrics fm = SwingUtilities2.getFontMetrics(b, g); - - int mnemIndex = b.getDisplayedMnemonicIndex(); - // W2K Feature: Check to see if the Underscore should be rendered. - if (WindowsLookAndFeel.isMnemonicHidden() == true) { - mnemIndex = -1; - } - - XPStyle xp = XPStyle.getXP(); - if (xp != null && !(b instanceof JMenuItem)) { - paintXPText(b, g, textRect.x + textShiftOffset, - textRect.y + fm.getAscent() + textShiftOffset, - text, mnemIndex); - } else { - paintClassicText(b, g, textRect.x + textShiftOffset, - textRect.y + fm.getAscent() + textShiftOffset, - text, mnemIndex); - } - } - - static void paintClassicText(AbstractButton b, Graphics g, int x, int y, - String text, int mnemIndex) { - ButtonModel model = b.getModel(); - - /* Draw the Text */ - Color color = b.getForeground(); - if(model.isEnabled()) { - /*** paint the text normally */ - if(!(b instanceof JMenuItem && model.isArmed()) - && !(b instanceof JMenu && (model.isSelected() || model.isRollover()))) { - /* We shall not set foreground color for selected menu or - * armed menuitem. Foreground must be set in appropriate - * Windows* class because these colors passes from - * BasicMenuItemUI as protected fields and we can't - * reach them from this class */ - g.setColor(b.getForeground()); - } - SwingUtilities2.drawStringUnderlineCharAt(b, g,text, mnemIndex, x, y); - } else { /*** paint the text disabled ***/ - color = getDisabledTextColor(b); - if (color == null) { - color = UIManager.getColor("Button.shadow"); - } - Color shadow = UIManager.getColor("Button.disabledShadow"); - if(model.isArmed()) { - color = UIManager.getColor("Button.disabledForeground"); - } else { - if (shadow == null) { - shadow = b.getBackground().darker(); - } - g.setColor(shadow); - SwingUtilities2.drawStringUnderlineCharAt(b, g, text, mnemIndex, - x + 1, y + 1); - } - if (color == null) { - color = b.getBackground().brighter(); - } - g.setColor(color); - SwingUtilities2.drawStringUnderlineCharAt(b, g, text, mnemIndex, x, y); - } - } - - private static Color getDisabledTextColor(AbstractButton b) { - if (b instanceof JCheckBox) { - return UIManager.getColor("CheckBox.disabledText"); - } else if (b instanceof JRadioButton) { - return UIManager.getColor("RadioButton.disabledText"); - } else if (b instanceof JToggleButton) { - return UIManager.getColor("ToggleButton.disabledText"); - } else if (b instanceof JButton) { - return UIManager.getColor("Button.disabledText"); - } - return null; - } - - static void paintXPText(AbstractButton b, Graphics g, int x, int y, - String text, int mnemIndex) { - Part part = WindowsButtonUI.getXPButtonType(b); - State state = WindowsButtonUI.getXPButtonState(b); - paintXPText(b, part, state, g, x, y, text, mnemIndex); - } - - static void paintXPText(AbstractButton b, Part part, State state, - Graphics g, int x, int y, String text, int mnemIndex) { - XPStyle xp = XPStyle.getXP(); - if (xp == null) { - return; - } - Color textColor; - if (b.isEnabled()) { - textColor = b.getForeground(); - } - else { - textColor = getDisabledTextColor(b); - } - - if (textColor == null || textColor instanceof UIResource) { - textColor = xp.getColor(b, part, state, Prop.TEXTCOLOR, b.getForeground()); - // to work around an apparent bug in Windows, use the pushbutton - // color for disabled toolbar buttons if the disabled color is the - // same as the enabled color - if (part == Part.TP_BUTTON && state == State.DISABLED) { - Color enabledColor = xp.getColor(b, part, State.NORMAL, - Prop.TEXTCOLOR, b.getForeground()); - if(textColor.equals(enabledColor)) { - textColor = xp.getColor(b, Part.BP_PUSHBUTTON, state, - Prop.TEXTCOLOR, textColor); - } - } - // only draw shadow if developer hasn't changed the foreground color - // and if the current style has text shadows. - TypeEnum shadowType = xp.getTypeEnum(b, part, - state, Prop.TEXTSHADOWTYPE); - if (shadowType == TypeEnum.TST_SINGLE || - shadowType == TypeEnum.TST_CONTINUOUS) { - Color shadowColor = xp.getColor(b, part, state, - Prop.TEXTSHADOWCOLOR, Color.black); - Point offset = xp.getPoint(b, part, state, Prop.TEXTSHADOWOFFSET); - if (offset != null) { - g.setColor(shadowColor); - SwingUtilities2.drawStringUnderlineCharAt(b, g, text, mnemIndex, - x + offset.x, - y + offset.y); - } - } - } - - g.setColor(textColor); - SwingUtilities2.drawStringUnderlineCharAt(b, g, text, mnemIndex, x, y); - } - - static boolean isLeftToRight(Component c) { - return c.getComponentOrientation().isLeftToRight(); - } - - /* - * Repaints all the components with the mnemonics in the given window and - * all its owned windows. - */ - static void repaintMnemonicsInWindow(Window w) { - if(w == null || !w.isShowing()) { - return; - } - - Window[] ownedWindows = w.getOwnedWindows(); - for(int i=0;i - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - * - * @author David Kloba - * @author Georges Saab - * @author Rich Schiavi - */ -@SuppressWarnings("serial") // Same-version serialization only -public class WindowsIconFactory implements Serializable -{ - private static Icon frame_closeIcon; - private static Icon frame_iconifyIcon; - private static Icon frame_maxIcon; - private static Icon frame_minIcon; - private static Icon frame_resizeIcon; - private static Icon checkBoxIcon; - private static Icon radioButtonIcon; - private static Icon checkBoxMenuItemIcon; - private static Icon radioButtonMenuItemIcon; - private static Icon menuItemCheckIcon; - private static Icon menuItemArrowIcon; - private static Icon menuArrowIcon; - private static VistaMenuItemCheckIconFactory menuItemCheckIconFactory; - - public static Icon getMenuItemCheckIcon() { - if (menuItemCheckIcon == null) { - menuItemCheckIcon = new MenuItemCheckIcon(); - } - return menuItemCheckIcon; - } - - public static Icon getMenuItemArrowIcon() { - if (menuItemArrowIcon == null) { - menuItemArrowIcon = new MenuItemArrowIcon(); - } - return menuItemArrowIcon; - } - - public static Icon getMenuArrowIcon() { - if (menuArrowIcon == null) { - menuArrowIcon = new MenuArrowIcon(); - } - return menuArrowIcon; - } - - public static Icon getCheckBoxIcon() { - if (checkBoxIcon == null) { - checkBoxIcon = new CheckBoxIcon(); - } - return checkBoxIcon; - } - - public static Icon getRadioButtonIcon() { - if (radioButtonIcon == null) { - radioButtonIcon = new RadioButtonIcon(); - } - return radioButtonIcon; - } - - public static Icon getCheckBoxMenuItemIcon() { - if (checkBoxMenuItemIcon == null) { - checkBoxMenuItemIcon = new CheckBoxMenuItemIcon(); - } - return checkBoxMenuItemIcon; - } - - public static Icon getRadioButtonMenuItemIcon() { - if (radioButtonMenuItemIcon == null) { - radioButtonMenuItemIcon = new RadioButtonMenuItemIcon(); - } - return radioButtonMenuItemIcon; - } - - static - synchronized VistaMenuItemCheckIconFactory getMenuItemCheckIconFactory() { - if (menuItemCheckIconFactory == null) { - menuItemCheckIconFactory = - new VistaMenuItemCheckIconFactory(); - } - return menuItemCheckIconFactory; - } - - public static Icon createFrameCloseIcon() { - if (frame_closeIcon == null) { - frame_closeIcon = new FrameButtonIcon(Part.WP_CLOSEBUTTON); - } - return frame_closeIcon; - } - - public static Icon createFrameIconifyIcon() { - if (frame_iconifyIcon == null) { - frame_iconifyIcon = new FrameButtonIcon(Part.WP_MINBUTTON); - } - return frame_iconifyIcon; - } - - public static Icon createFrameMaximizeIcon() { - if (frame_maxIcon == null) { - frame_maxIcon = new FrameButtonIcon(Part.WP_MAXBUTTON); - } - return frame_maxIcon; - } - - public static Icon createFrameMinimizeIcon() { - if (frame_minIcon == null) { - frame_minIcon = new FrameButtonIcon(Part.WP_RESTOREBUTTON); - } - return frame_minIcon; - } - - public static Icon createFrameResizeIcon() { - if(frame_resizeIcon == null) - frame_resizeIcon = new ResizeIcon(); - return frame_resizeIcon; - } - - - @SuppressWarnings("serial") // Same-version serialization only - private static class FrameButtonIcon implements Icon, Serializable { - private Part part; - - private FrameButtonIcon(Part part) { - this.part = part; - } - - public void paintIcon(Component c, Graphics g, int x0, int y0) { - int width = getIconWidth(); - int height = getIconHeight(); - - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - Skin skin = xp.getSkin(c, part); - AbstractButton b = (AbstractButton)c; - ButtonModel model = b.getModel(); - - // Find out if frame is inactive - JInternalFrame jif = (JInternalFrame)SwingUtilities. - getAncestorOfClass(JInternalFrame.class, b); - boolean jifSelected = (jif != null && jif.isSelected()); - - State state; - if (jifSelected) { - if (!model.isEnabled()) { - state = State.DISABLED; - } else if (model.isArmed() && model.isPressed()) { - state = State.PUSHED; - } else if (model.isRollover()) { - state = State.HOT; - } else { - state = State.NORMAL; - } - } else { - if (!model.isEnabled()) { - state = State.INACTIVEDISABLED; - } else if (model.isArmed() && model.isPressed()) { - state = State.INACTIVEPUSHED; - } else if (model.isRollover()) { - state = State.INACTIVEHOT; - } else { - state = State.INACTIVENORMAL; - } - } - skin.paintSkin(g, 0, 0, width, height, state); - } else { - g.setColor(Color.black); - int x = width / 12 + 2; - int y = height / 5; - int h = height - y * 2 - 1; - int w = width * 3/4 -3; - int thickness2 = Math.max(height / 8, 2); - int thickness = Math.max(width / 15, 1); - if (part == Part.WP_CLOSEBUTTON) { - int lineWidth; - if (width > 47) lineWidth = 6; - else if (width > 37) lineWidth = 5; - else if (width > 26) lineWidth = 4; - else if (width > 16) lineWidth = 3; - else if (width > 12) lineWidth = 2; - else lineWidth = 1; - y = height / 12 + 2; - if (lineWidth == 1) { - if (w % 2 == 1) { x++; w++; } - g.drawLine(x, y, x+w-2, y+w-2); - g.drawLine(x+w-2, y, x, y+w-2); - } else if (lineWidth == 2) { - if (w > 6) { x++; w--; } - g.drawLine(x, y, x+w-2, y+w-2); - g.drawLine(x+w-2, y, x, y+w-2); - g.drawLine(x+1, y, x+w-1, y+w-2); - g.drawLine(x+w-1, y, x+1, y+w-2); - } else { - x += 2; y++; w -= 2; - g.drawLine(x, y, x+w-1, y+w-1); - g.drawLine(x+w-1, y, x, y+w-1); - g.drawLine(x+1, y, x+w-1, y+w-2); - g.drawLine(x+w-2, y, x, y+w-2); - g.drawLine(x, y+1, x+w-2, y+w-1); - g.drawLine(x+w-1, y+1, x+1, y+w-1); - for (int i = 4; i <= lineWidth; i++) { - g.drawLine(x+i-2, y, x+w-1, y+w-i+1); - g.drawLine(x, y+i-2, x+w-i+1, y+w-1); - g.drawLine(x+w-i+1, y, x, y+w-i+1); - g.drawLine(x+w-1, y+i-2, x+i-2, y+w-1); - } - } - } else if (part == Part.WP_MINBUTTON) { - g.fillRect(x, y+h-thickness2, w-w/3, thickness2); - } else if (part == Part.WP_MAXBUTTON) { - g.fillRect(x, y, w, thickness2); - g.fillRect(x, y, thickness, h); - g.fillRect(x+w-thickness, y, thickness, h); - g.fillRect(x, y+h-thickness, w, thickness); - } else if (part == Part.WP_RESTOREBUTTON) { - g.fillRect(x+w/3, y, w-w/3, thickness2); - g.fillRect(x+w/3, y, thickness, h/3); - g.fillRect(x+w-thickness, y, thickness, h-h/3); - g.fillRect(x+w-w/3, y+h-h/3-thickness, w/3, thickness); - - g.fillRect(x, y+h/3, w-w/3, thickness2); - g.fillRect(x, y+h/3, thickness, h-h/3); - g.fillRect(x+w-w/3-thickness, y+h/3, thickness, h-h/3); - g.fillRect(x, y+h-thickness, w-w/3, thickness); - } - } - } - - public int getIconWidth() { - int width; - if (XPStyle.getXP() != null) { - // Fix for XP bug where sometimes these sizes aren't updated properly - // Assume for now that height is correct and derive width using the - // ratio from the uxtheme part - width = UIManager.getInt("InternalFrame.titleButtonHeight") -2; - Dimension d = XPStyle.getPartSize(Part.WP_CLOSEBUTTON, State.NORMAL); - if (d != null && d.width != 0 && d.height != 0) { - width = (int) ((float) width * d.width / d.height); - } - } else { - width = UIManager.getInt("InternalFrame.titleButtonWidth") -2; - } - if (XPStyle.getXP() != null) { - width -= 2; - } - return width; - } - - public int getIconHeight() { - int height = UIManager.getInt("InternalFrame.titleButtonHeight")-4; - return height; - } - } - - - - @SuppressWarnings("serial") // Same-version serialization only - private static class ResizeIcon implements Icon, Serializable { - public void paintIcon(Component c, Graphics g, int x, int y) { - g.setColor(UIManager.getColor("InternalFrame.resizeIconHighlight")); - g.drawLine(0, 11, 11, 0); - g.drawLine(4, 11, 11, 4); - g.drawLine(8, 11, 11, 8); - - g.setColor(UIManager.getColor("InternalFrame.resizeIconShadow")); - g.drawLine(1, 11, 11, 1); - g.drawLine(2, 11, 11, 2); - g.drawLine(5, 11, 11, 5); - g.drawLine(6, 11, 11, 6); - g.drawLine(9, 11, 11, 9); - g.drawLine(10, 11, 11, 10); - } - public int getIconWidth() { return 13; } - public int getIconHeight() { return 13; } - }; - - @SuppressWarnings("serial") // Same-version serialization only - private static class CheckBoxIcon implements Icon, Serializable - { - static final int csize = 13; - public void paintIcon(Component c, Graphics g, int x, int y) { - JCheckBox cb = (JCheckBox) c; - ButtonModel model = cb.getModel(); - XPStyle xp = XPStyle.getXP(); - - if (xp != null) { - State state; - if (model.isSelected()) { - state = State.CHECKEDNORMAL; - if (!model.isEnabled()) { - state = State.CHECKEDDISABLED; - } else if (model.isPressed() && model.isArmed()) { - state = State.CHECKEDPRESSED; - } else if (model.isRollover()) { - state = State.CHECKEDHOT; - } - } else { - state = State.UNCHECKEDNORMAL; - if (!model.isEnabled()) { - state = State.UNCHECKEDDISABLED; - } else if (model.isPressed() && model.isArmed()) { - state = State.UNCHECKEDPRESSED; - } else if (model.isRollover()) { - state = State.UNCHECKEDHOT; - } - } - Part part = Part.BP_CHECKBOX; - xp.getSkin(c, part).paintSkin(g, x, y, state); - } else { - // outer bevel - if(!cb.isBorderPaintedFlat()) { - // Outer top/left - g.setColor(UIManager.getColor("CheckBox.shadow")); - g.drawLine(x, y, x+11, y); - g.drawLine(x, y+1, x, y+11); - - // Outer bottom/right - g.setColor(UIManager.getColor("CheckBox.highlight")); - g.drawLine(x+12, y, x+12, y+12); - g.drawLine(x, y+12, x+11, y+12); - - // Inner top.left - g.setColor(UIManager.getColor("CheckBox.darkShadow")); - g.drawLine(x+1, y+1, x+10, y+1); - g.drawLine(x+1, y+2, x+1, y+10); - - // Inner bottom/right - g.setColor(UIManager.getColor("CheckBox.light")); - g.drawLine(x+1, y+11, x+11, y+11); - g.drawLine(x+11, y+1, x+11, y+10); - - // inside box - if((model.isPressed() && model.isArmed()) || !model.isEnabled()) { - g.setColor(UIManager.getColor("CheckBox.background")); - } else { - g.setColor(UIManager.getColor("CheckBox.interiorBackground")); - } - g.fillRect(x+2, y+2, csize-4, csize-4); - } else { - g.setColor(UIManager.getColor("CheckBox.shadow")); - g.drawRect(x+1, y+1, csize-3, csize-3); - - if((model.isPressed() && model.isArmed()) || !model.isEnabled()) { - g.setColor(UIManager.getColor("CheckBox.background")); - } else { - g.setColor(UIManager.getColor("CheckBox.interiorBackground")); - } - g.fillRect(x+2, y+2, csize-4, csize-4); - } - - if(model.isEnabled()) { - g.setColor(UIManager.getColor("CheckBox.foreground")); - } else { - g.setColor(UIManager.getColor("CheckBox.shadow")); - } - - // paint check - if (model.isSelected()) { - if (SwingUtilities2.isScaledGraphics(g)) { - int[] xPoints = {3, 5, 9, 9, 5, 3}; - int[] yPoints = {5, 7, 3, 5, 9, 7}; - g.translate(x, y); - g.fillPolygon(xPoints, yPoints, 6); - g.drawPolygon(xPoints, yPoints, 6); - g.translate(-x, -y); - } else { - g.drawLine(x + 9, y + 3, x + 9, y + 3); - g.drawLine(x + 8, y + 4, x + 9, y + 4); - g.drawLine(x + 7, y + 5, x + 9, y + 5); - g.drawLine(x + 6, y + 6, x + 8, y + 6); - g.drawLine(x + 3, y + 7, x + 7, y + 7); - g.drawLine(x + 4, y + 8, x + 6, y + 8); - g.drawLine(x + 5, y + 9, x + 5, y + 9); - g.drawLine(x + 3, y + 5, x + 3, y + 5); - g.drawLine(x + 3, y + 6, x + 4, y + 6); - } - } - } - } - - public int getIconWidth() { - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - return xp.getSkin(null, Part.BP_CHECKBOX).getWidth(); - } else { - return csize; - } - } - - public int getIconHeight() { - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - return xp.getSkin(null, Part.BP_CHECKBOX).getHeight(); - } else { - return csize; - } - } - } - - @SuppressWarnings("serial") // Same-version serialization only - private static class RadioButtonIcon implements Icon, UIResource, Serializable - { - public void paintIcon(Component c, Graphics g, int x, int y) { - AbstractButton b = (AbstractButton) c; - ButtonModel model = b.getModel(); - XPStyle xp = XPStyle.getXP(); - - if (xp != null) { - Part part = Part.BP_RADIOBUTTON; - Skin skin = xp.getSkin(b, part); - State state; - int index = 0; - if (model.isSelected()) { - state = State.CHECKEDNORMAL; - if (!model.isEnabled()) { - state = State.CHECKEDDISABLED; - } else if (model.isPressed() && model.isArmed()) { - state = State.CHECKEDPRESSED; - } else if (model.isRollover()) { - state = State.CHECKEDHOT; - } - } else { - state = State.UNCHECKEDNORMAL; - if (!model.isEnabled()) { - state = State.UNCHECKEDDISABLED; - } else if (model.isPressed() && model.isArmed()) { - state = State.UNCHECKEDPRESSED; - } else if (model.isRollover()) { - state = State.UNCHECKEDHOT; - } - } - skin.paintSkin(g, x, y, state); - } else { - // fill interior - if((model.isPressed() && model.isArmed()) || !model.isEnabled()) { - g.setColor(UIManager.getColor("RadioButton.background")); - } else { - g.setColor(UIManager.getColor("RadioButton.interiorBackground")); - } - g.fillRect(x+2, y+2, 8, 8); - - - boolean isScaledGraphics = SwingUtilities2.isScaledGraphics(g); - - if (isScaledGraphics) { - - Graphics2D g2d = (Graphics2D) g; - Stroke oldStroke = g2d.getStroke(); - g2d.setStroke(new BasicStroke(1.03f, BasicStroke.CAP_ROUND, - BasicStroke.JOIN_ROUND)); - Object aaHint = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING); - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); - - // outter left arc - g.setColor(UIManager.getColor("RadioButton.shadow")); - g.drawArc(x, y, 11, 11, 45, 180); - // outter right arc - g.setColor(UIManager.getColor("RadioButton.highlight")); - g.drawArc(x, y, 11, 11, 45, -180); - // inner left arc - g.setColor(UIManager.getColor("RadioButton.darkShadow")); - g.drawArc(x + 1, y + 1, 9, 9, 45, 180); - // inner right arc - g.setColor(UIManager.getColor("RadioButton.light")); - g.drawArc(x + 1, y + 1, 9, 9, 45, -180); - - g2d.setStroke(oldStroke); - - if (model.isSelected()) { - if (model.isEnabled()) { - g.setColor(UIManager.getColor("RadioButton.foreground")); - } else { - g.setColor(UIManager.getColor("RadioButton.shadow")); - } - g.fillOval(x + 3, y + 3, 5, 5); - } - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aaHint); - - } else { - - // outter left arc - g.setColor(UIManager.getColor("RadioButton.shadow")); - g.drawLine(x+4, y+0, x+7, y+0); - g.drawLine(x+2, y+1, x+3, y+1); - g.drawLine(x+8, y+1, x+9, y+1); - g.drawLine(x+1, y+2, x+1, y+3); - g.drawLine(x+0, y+4, x+0, y+7); - g.drawLine(x+1, y+8, x+1, y+9); - - // outter right arc - g.setColor(UIManager.getColor("RadioButton.highlight")); - g.drawLine(x+2, y+10, x+3, y+10); - g.drawLine(x+4, y+11, x+7, y+11); - g.drawLine(x+8, y+10, x+9, y+10); - g.drawLine(x+10, y+9, x+10, y+8); - g.drawLine(x+11, y+7, x+11, y+4); - g.drawLine(x+10, y+3, x+10, y+2); - - - // inner left arc - g.setColor(UIManager.getColor("RadioButton.darkShadow")); - g.drawLine(x+4, y+1, x+7, y+1); - g.drawLine(x+2, y+2, x+3, y+2); - g.drawLine(x+8, y+2, x+9, y+2); - g.drawLine(x+2, y+3, x+2, y+3); - g.drawLine(x+1, y+4, x+1, y+7); - g.drawLine(x+2, y+8, x+2, y+8); - - - // inner right arc - g.setColor(UIManager.getColor("RadioButton.light")); - g.drawLine(x+2, y+9, x+3, y+9); - g.drawLine(x+4, y+10, x+7, y+10); - g.drawLine(x+8, y+9, x+9, y+9); - g.drawLine(x+9, y+8, x+9, y+8); - g.drawLine(x+10, y+7, x+10, y+4); - g.drawLine(x+9, y+3, x+9, y+3); - - - // indicate whether selected or not - if (model.isSelected()) { - if (model.isEnabled()) { - g.setColor(UIManager.getColor("RadioButton.foreground")); - } else { - g.setColor(UIManager.getColor("RadioButton.shadow")); - } - g.fillRect(x+4, y+5, 4, 2); - g.fillRect(x+5, y+4, 2, 4); - } - } - } - } - - public int getIconWidth() { - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - return xp.getSkin(null, Part.BP_RADIOBUTTON).getWidth(); - } else { - return 13; - } - } - - public int getIconHeight() { - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - return xp.getSkin(null, Part.BP_RADIOBUTTON).getHeight(); - } else { - return 13; - } - } - } // end class RadioButtonIcon - - - @SuppressWarnings("serial") // Same-version serialization only - private static class CheckBoxMenuItemIcon implements Icon, UIResource, Serializable - { - public void paintIcon(Component c, Graphics g, int x, int y) { - AbstractButton b = (AbstractButton) c; - ButtonModel model = b.getModel(); - boolean isSelected = model.isSelected(); - if (isSelected) { - y = y - getIconHeight() / 2; - g.drawLine(x+9, y+3, x+9, y+3); - g.drawLine(x+8, y+4, x+9, y+4); - g.drawLine(x+7, y+5, x+9, y+5); - g.drawLine(x+6, y+6, x+8, y+6); - g.drawLine(x+3, y+7, x+7, y+7); - g.drawLine(x+4, y+8, x+6, y+8); - g.drawLine(x+5, y+9, x+5, y+9); - g.drawLine(x+3, y+5, x+3, y+5); - g.drawLine(x+3, y+6, x+4, y+6); - } - } - public int getIconWidth() { return 9; } - public int getIconHeight() { return 9; } - - } // End class CheckBoxMenuItemIcon - - - @SuppressWarnings("serial") // Same-version serialization only - private static class RadioButtonMenuItemIcon implements Icon, UIResource, Serializable - { - public void paintIcon(Component c, Graphics g, int x, int y) { - AbstractButton b = (AbstractButton) c; - ButtonModel model = b.getModel(); - if (b.isSelected() == true) { - g.fillRoundRect(x+3,y+3, getIconWidth()-6, getIconHeight()-6, - 4, 4); - } - } - public int getIconWidth() { return 12; } - public int getIconHeight() { return 12; } - - } // End class RadioButtonMenuItemIcon - - - @SuppressWarnings("serial") // Same-version serialization only - private static class MenuItemCheckIcon implements Icon, UIResource, Serializable{ - public void paintIcon(Component c, Graphics g, int x, int y) { - /* For debugging: - Color oldColor = g.getColor(); - g.setColor(Color.orange); - g.fill3DRect(x,y,getIconWidth(), getIconHeight(), true); - g.setColor(oldColor); - */ - } - public int getIconWidth() { return 9; } - public int getIconHeight() { return 9; } - - } // End class MenuItemCheckIcon - - @SuppressWarnings("serial") // Same-version serialization only - private static class MenuItemArrowIcon implements Icon, UIResource, Serializable { - public void paintIcon(Component c, Graphics g, int x, int y) { - /* For debugging: - Color oldColor = g.getColor(); - g.setColor(Color.green); - g.fill3DRect(x,y,getIconWidth(), getIconHeight(), true); - g.setColor(oldColor); - */ - } - public int getIconWidth() { return 4; } - public int getIconHeight() { return 8; } - - } // End class MenuItemArrowIcon - - @SuppressWarnings("serial") // Same-version serialization only - private static class MenuArrowIcon implements Icon, UIResource, Serializable { - public void paintIcon(Component c, Graphics g, int x, int y) { - XPStyle xp = XPStyle.getXP(); - if (WindowsMenuItemUI.isVistaPainting(xp)) { - State state = State.NORMAL; - if (c instanceof JMenuItem) { - state = ((JMenuItem) c).getModel().isEnabled() - ? State.NORMAL : State.DISABLED; - } - Skin skin = xp.getSkin(c, Part.MP_POPUPSUBMENU); - if (WindowsGraphicsUtils.isLeftToRight(c)) { - skin.paintSkin(g, x, y, state); - } else { - Graphics2D g2d = (Graphics2D)g.create(); - g2d.translate(x + skin.getWidth(), y); - g2d.scale(-1, 1); - skin.paintSkin(g2d, 0, 0, state); - g2d.dispose(); - } - } else { - g.translate(x,y); - if( WindowsGraphicsUtils.isLeftToRight(c) ) { - g.drawLine( 0, 0, 0, 7 ); - g.drawLine( 1, 1, 1, 6 ); - g.drawLine( 2, 2, 2, 5 ); - g.drawLine( 3, 3, 3, 4 ); - } else { - g.drawLine( 4, 0, 4, 7 ); - g.drawLine( 3, 1, 3, 6 ); - g.drawLine( 2, 2, 2, 5 ); - g.drawLine( 1, 3, 1, 4 ); - } - g.translate(-x,-y); - } - } - public int getIconWidth() { - XPStyle xp = XPStyle.getXP(); - if (WindowsMenuItemUI.isVistaPainting(xp)) { - Skin skin = xp.getSkin(null, Part.MP_POPUPSUBMENU); - return skin.getWidth(); - } else { - return 4; - } - } - public int getIconHeight() { - XPStyle xp = XPStyle.getXP(); - if (WindowsMenuItemUI.isVistaPainting(xp)) { - Skin skin = xp.getSkin(null, Part.MP_POPUPSUBMENU); - return skin.getHeight(); - } else { - return 8; - } - } - } // End class MenuArrowIcon - - static class VistaMenuItemCheckIconFactory - implements MenuItemCheckIconFactory { - private static final int OFFSET = 3; - - public Icon getIcon(JMenuItem component) { - return new VistaMenuItemCheckIcon(component); - } - - public boolean isCompatible(Object icon, String prefix) { - return icon instanceof VistaMenuItemCheckIcon - && ((VistaMenuItemCheckIcon) icon).type == getType(prefix); - } - - public Icon getIcon(String type) { - return new VistaMenuItemCheckIcon(type); - } - - static int getIconWidth() { - XPStyle xp = XPStyle.getXP(); - return ((xp != null) ? xp.getSkin(null, Part.MP_POPUPCHECK).getWidth() : 16) - + 2 * OFFSET; - } - - private static Class getType(Component c) { - Class rv = null; - if (c instanceof JCheckBoxMenuItem) { - rv = JCheckBoxMenuItem.class; - } else if (c instanceof JRadioButtonMenuItem) { - rv = JRadioButtonMenuItem.class; - } else if (c instanceof JMenu) { - rv = JMenu.class; - } else if (c instanceof JMenuItem) { - rv = JMenuItem.class; - } - return rv; - } - - private static Class getType(String type) { - Class rv = null; - if (type == "CheckBoxMenuItem") { - rv = JCheckBoxMenuItem.class; - } else if (type == "RadioButtonMenuItem") { - rv = JRadioButtonMenuItem.class; - } else if (type == "Menu") { - rv = JMenu.class; - } else if (type == "MenuItem") { - rv = JMenuItem.class; - } else { - // this should never happen - rv = JMenuItem.class; - } - return rv; - } - - /** - * CheckIcon for JMenuItem, JMenu, JCheckBoxMenuItem and - * JRadioButtonMenuItem. - * Note: to be used on Vista only. - */ - @SuppressWarnings("serial") // Same-version serialization only - private static class VistaMenuItemCheckIcon - implements Icon, UIResource, Serializable { - - private final JMenuItem menuItem; - private final Class type; - - VistaMenuItemCheckIcon(JMenuItem menuItem) { - this.type = getType(menuItem); - this.menuItem = menuItem; - } - VistaMenuItemCheckIcon(String type) { - this.type = getType(type); - this.menuItem = null; - } - - public int getIconHeight() { - Icon lafIcon = getLaFIcon(); - if (lafIcon != null) { - return lafIcon.getIconHeight(); - } - Icon icon = getIcon(); - int height = 0; - if (icon != null) { - height = icon.getIconHeight(); - } else { - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - Skin skin = xp.getSkin(null, Part.MP_POPUPCHECK); - height = skin.getHeight(); - } else { - height = 16; - } - } - height += 2 * OFFSET; - return height; - } - - public int getIconWidth() { - Icon lafIcon = getLaFIcon(); - if (lafIcon != null) { - return lafIcon.getIconWidth(); - } - Icon icon = getIcon(); - int width = 0; - if (icon != null) { - width = icon.getIconWidth() + 2 * OFFSET; - } else { - width = VistaMenuItemCheckIconFactory.getIconWidth(); - } - return width; - } - - public void paintIcon(Component c, Graphics g, int x, int y) { - Icon lafIcon = getLaFIcon(); - if (lafIcon != null) { - lafIcon.paintIcon(c, g, x, y); - return; - } - assert menuItem == null || c == menuItem; - Icon icon = getIcon(); - if (type == JCheckBoxMenuItem.class - || type == JRadioButtonMenuItem.class) { - AbstractButton b = (AbstractButton) c; - if (b.isSelected()) { - Part backgroundPart = Part.MP_POPUPCHECKBACKGROUND; - Part part = Part.MP_POPUPCHECK; - State backgroundState; - State state; - if (isEnabled(c, null)) { - backgroundState = - (icon != null) ? State.BITMAP : State.NORMAL; - state = (type == JRadioButtonMenuItem.class) - ? State.BULLETNORMAL - : State.CHECKMARKNORMAL; - } else { - backgroundState = State.DISABLEDPUSHED; - state = - (type == JRadioButtonMenuItem.class) - ? State.BULLETDISABLED - : State.CHECKMARKDISABLED; - } - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - Skin skin; - skin = xp.getSkin(c, backgroundPart); - skin.paintSkin(g, x, y, - getIconWidth(), getIconHeight(), backgroundState); - if (icon == null) { - skin = xp.getSkin(c, part); - skin.paintSkin(g, x + OFFSET, y + OFFSET, state); - } - } - } - } - if (icon != null) { - icon.paintIcon(c, g, x + OFFSET, y + OFFSET); - } - } - private static WindowsMenuItemUIAccessor getAccessor( - JMenuItem menuItem) { - WindowsMenuItemUIAccessor rv = null; - ButtonUI uiObject = (menuItem != null) ? menuItem.getUI() - : null; - if (uiObject instanceof WindowsMenuItemUI) { - rv = ((WindowsMenuItemUI) uiObject).accessor; - } else if (uiObject instanceof WindowsMenuUI) { - rv = ((WindowsMenuUI) uiObject).accessor; - } else if (uiObject instanceof WindowsCheckBoxMenuItemUI) { - rv = ((WindowsCheckBoxMenuItemUI) uiObject).accessor; - } else if (uiObject instanceof WindowsRadioButtonMenuItemUI) { - rv = ((WindowsRadioButtonMenuItemUI) uiObject).accessor; - } - return rv; - } - - private static boolean isEnabled(Component c, State state) { - if (state == null && c instanceof JMenuItem) { - WindowsMenuItemUIAccessor accessor = - getAccessor((JMenuItem) c); - if (accessor != null) { - state = accessor.getState((JMenuItem) c); - } - } - if (state == null) { - if (c != null) { - return c.isEnabled(); - } else { - return true; - } - } else { - return (state != State.DISABLED) - && (state != State.DISABLEDHOT) - && (state != State.DISABLEDPUSHED); - } - } - private Icon getIcon() { - Icon rv = null; - if (menuItem == null) { - return rv; - } - WindowsMenuItemUIAccessor accessor = - getAccessor(menuItem); - State state = (accessor != null) ? accessor.getState(menuItem) - : null; - if (isEnabled(menuItem, null)) { - if (state == State.PUSHED) { - rv = menuItem.getPressedIcon(); - } else { - rv = menuItem.getIcon(); - } - } else { - rv = menuItem.getDisabledIcon(); - } - return rv; - } - /** - * Check if developer changed icon in the UI table. - * - * @return the icon to use or {@code null} if the current one is to - * be used - */ - private Icon getLaFIcon() { - // use icon from the UI table if it does not match this one. - Icon rv = (Icon) UIManager.getDefaults().get(typeToString(type)); - if (rv instanceof VistaMenuItemCheckIcon - && ((VistaMenuItemCheckIcon) rv).type == type) { - rv = null; - } - return rv; - } - - private static String typeToString( - Class type) { - assert type == JMenuItem.class - || type == JMenu.class - || type == JCheckBoxMenuItem.class - || type == JRadioButtonMenuItem.class; - StringBuilder sb = new StringBuilder(type.getName()); - // remove package name, dot and the first character - sb.delete(0, sb.lastIndexOf("J") + 1); - sb.append(".checkIcon"); - return sb.toString(); - } - } - } // End class VistaMenuItemCheckIconFactory -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsInternalFrameTitlePane.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsInternalFrameTitlePane.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,572 +0,0 @@ -/* - * Copyright (c) 2001, 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 com.sun.java.swing.plaf.windows; - -import sun.swing.SwingUtilities2; - -import javax.swing.*; -import javax.swing.border.*; -import javax.swing.UIManager; -import javax.swing.plaf.*; -import javax.swing.plaf.basic.BasicInternalFrameTitlePane; -import java.awt.*; -import java.awt.event.*; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.beans.PropertyVetoException; - -import static com.sun.java.swing.plaf.windows.TMSchema.*; -import static com.sun.java.swing.plaf.windows.XPStyle.Skin; - -@SuppressWarnings("serial") // Superclass is not serializable across versions -public class WindowsInternalFrameTitlePane extends BasicInternalFrameTitlePane { - private Color selectedTitleGradientColor; - private Color notSelectedTitleGradientColor; - private JPopupMenu systemPopupMenu; - private JLabel systemLabel; - - private Font titleFont; - private int titlePaneHeight; - private int buttonWidth, buttonHeight; - private boolean hotTrackingOn; - - public WindowsInternalFrameTitlePane(JInternalFrame f) { - super(f); - } - - protected void addSubComponents() { - add(systemLabel); - add(iconButton); - add(maxButton); - add(closeButton); - } - - protected void installDefaults() { - super.installDefaults(); - - titlePaneHeight = UIManager.getInt("InternalFrame.titlePaneHeight"); - buttonWidth = UIManager.getInt("InternalFrame.titleButtonWidth") - 4; - buttonHeight = UIManager.getInt("InternalFrame.titleButtonHeight") - 4; - - Object obj = UIManager.get("InternalFrame.titleButtonToolTipsOn"); - hotTrackingOn = (obj instanceof Boolean) ? (Boolean)obj : true; - - - if (XPStyle.getXP() != null) { - // Fix for XP bug where sometimes these sizes aren't updated properly - // Assume for now that height is correct and derive width using the - // ratio from the uxtheme part - buttonWidth = buttonHeight; - Dimension d = XPStyle.getPartSize(Part.WP_CLOSEBUTTON, State.NORMAL); - if (d != null && d.width != 0 && d.height != 0) { - buttonWidth = (int) ((float) buttonWidth * d.width / d.height); - } - } else { - buttonWidth += 2; - Color activeBorderColor = - UIManager.getColor("InternalFrame.activeBorderColor"); - setBorder(BorderFactory.createLineBorder(activeBorderColor, 1)); - } - // JDK-8039383: initialize these colors because getXP() may return null when theme is changed - selectedTitleGradientColor = - UIManager.getColor("InternalFrame.activeTitleGradient"); - notSelectedTitleGradientColor = - UIManager.getColor("InternalFrame.inactiveTitleGradient"); - } - - protected void uninstallListeners() { - // Get around protected method in superclass - super.uninstallListeners(); - } - - protected void createButtons() { - super.createButtons(); - if (XPStyle.getXP() != null) { - iconButton.setContentAreaFilled(false); - maxButton.setContentAreaFilled(false); - closeButton.setContentAreaFilled(false); - } - } - - protected void setButtonIcons() { - super.setButtonIcons(); - - if (!hotTrackingOn) { - iconButton.setToolTipText(null); - maxButton.setToolTipText(null); - closeButton.setToolTipText(null); - } - } - - - public void paintComponent(Graphics g) { - XPStyle xp = XPStyle.getXP(); - - paintTitleBackground(g); - - String title = frame.getTitle(); - if (title != null) { - boolean isSelected = frame.isSelected(); - Font oldFont = g.getFont(); - Font newFont = (titleFont != null) ? titleFont : getFont(); - g.setFont(newFont); - - // Center text vertically. - FontMetrics fm = SwingUtilities2.getFontMetrics(frame, g, newFont); - int baseline = (getHeight() + fm.getAscent() - fm.getLeading() - - fm.getDescent()) / 2; - - Rectangle lastIconBounds = new Rectangle(0, 0, 0, 0); - if (frame.isIconifiable()) { - lastIconBounds = iconButton.getBounds(); - } else if (frame.isMaximizable()) { - lastIconBounds = maxButton.getBounds(); - } else if (frame.isClosable()) { - lastIconBounds = closeButton.getBounds(); - } - - int titleX; - int titleW; - int gap = 2; - if (WindowsGraphicsUtils.isLeftToRight(frame)) { - if (lastIconBounds.x == 0) { // There are no icons - lastIconBounds.x = frame.getWidth() - frame.getInsets().right; - } - titleX = systemLabel.getX() + systemLabel.getWidth() + gap; - if (xp != null) { - titleX += 2; - } - titleW = lastIconBounds.x - titleX - gap; - } else { - if (lastIconBounds.x == 0) { // There are no icons - lastIconBounds.x = frame.getInsets().left; - } - titleW = SwingUtilities2.stringWidth(frame, fm, title); - int minTitleX = lastIconBounds.x + lastIconBounds.width + gap; - if (xp != null) { - minTitleX += 2; - } - int availableWidth = systemLabel.getX() - gap - minTitleX; - if (availableWidth > titleW) { - titleX = systemLabel.getX() - gap - titleW; - } else { - titleX = minTitleX; - titleW = availableWidth; - } - } - title = getTitle(frame.getTitle(), fm, titleW); - - if (xp != null) { - String shadowType = null; - if (isSelected) { - shadowType = xp.getString(this, Part.WP_CAPTION, - State.ACTIVE, Prop.TEXTSHADOWTYPE); - } - if ("single".equalsIgnoreCase(shadowType)) { - Point shadowOffset = xp.getPoint(this, Part.WP_WINDOW, State.ACTIVE, - Prop.TEXTSHADOWOFFSET); - Color shadowColor = xp.getColor(this, Part.WP_WINDOW, State.ACTIVE, - Prop.TEXTSHADOWCOLOR, null); - if (shadowOffset != null && shadowColor != null) { - g.setColor(shadowColor); - SwingUtilities2.drawString(frame, g, title, - titleX + shadowOffset.x, - baseline + shadowOffset.y); - } - } - } - g.setColor(isSelected ? selectedTextColor : notSelectedTextColor); - SwingUtilities2.drawString(frame, g, title, titleX, baseline); - g.setFont(oldFont); - } - } - - public Dimension getPreferredSize() { - return getMinimumSize(); - } - - public Dimension getMinimumSize() { - Dimension d = new Dimension(super.getMinimumSize()); - d.height = titlePaneHeight + 2; - - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - // Note: Don't know how to calculate height on XP, - // the captionbarheight is 25 but native caption is 30 (maximized 26) - if (frame.isMaximum()) { - d.height -= 1; - } else { - d.height += 3; - } - } - return d; - } - - protected void paintTitleBackground(Graphics g) { - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - Part part = frame.isIcon() ? Part.WP_MINCAPTION - : (frame.isMaximum() ? Part.WP_MAXCAPTION - : Part.WP_CAPTION); - State state = frame.isSelected() ? State.ACTIVE : State.INACTIVE; - Skin skin = xp.getSkin(this, part); - skin.paintSkin(g, 0, 0, getWidth(), getHeight(), state); - } else { - Boolean gradientsOn = (Boolean)LookAndFeel.getDesktopPropertyValue( - "win.frame.captionGradientsOn", Boolean.valueOf(false)); - if (gradientsOn.booleanValue() && g instanceof Graphics2D) { - Graphics2D g2 = (Graphics2D)g; - Paint savePaint = g2.getPaint(); - - boolean isSelected = frame.isSelected(); - int w = getWidth(); - - if (isSelected) { - GradientPaint titleGradient = new GradientPaint(0,0, - selectedTitleColor, - (int)(w*.75),0, - selectedTitleGradientColor); - g2.setPaint(titleGradient); - } else { - GradientPaint titleGradient = new GradientPaint(0,0, - notSelectedTitleColor, - (int)(w*.75),0, - notSelectedTitleGradientColor); - g2.setPaint(titleGradient); - } - g2.fillRect(0, 0, getWidth(), getHeight()); - g2.setPaint(savePaint); - } else { - super.paintTitleBackground(g); - } - } - } - - protected void assembleSystemMenu() { - systemPopupMenu = new JPopupMenu(); - addSystemMenuItems(systemPopupMenu); - enableActions(); - @SuppressWarnings("serial") // anonymous class - JLabel tmp = new JLabel(frame.getFrameIcon()) { - protected void paintComponent(Graphics g) { - int x = 0; - int y = 0; - int w = getWidth(); - int h = getHeight(); - g = g.create(); // Create scratch graphics - if (isOpaque()) { - g.setColor(getBackground()); - g.fillRect(0, 0, w, h); - } - Icon icon = getIcon(); - int iconWidth; - int iconHeight; - if (icon != null && - (iconWidth = icon.getIconWidth()) > 0 && - (iconHeight = icon.getIconHeight()) > 0) { - - // Set drawing scale to make icon scale to our desired size - double drawScale; - if (iconWidth > iconHeight) { - // Center icon vertically - y = (h - w*iconHeight/iconWidth) / 2; - drawScale = w / (double)iconWidth; - } else { - // Center icon horizontally - x = (w - h*iconWidth/iconHeight) / 2; - drawScale = h / (double)iconHeight; - } - ((Graphics2D)g).translate(x, y); - ((Graphics2D)g).scale(drawScale, drawScale); - icon.paintIcon(this, g, 0, 0); - } - g.dispose(); - } - }; - systemLabel = tmp; - systemLabel.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2 && frame.isClosable() && - !frame.isIcon()) { - systemPopupMenu.setVisible(false); - frame.doDefaultCloseAction(); - } - else { - super.mouseClicked(e); - } - } - public void mousePressed(MouseEvent e) { - try { - frame.setSelected(true); - } catch(PropertyVetoException pve) { - } - showSystemPopupMenu(e.getComponent()); - } - }); - } - - protected void addSystemMenuItems(JPopupMenu menu) { - JMenuItem mi = menu.add(restoreAction); - mi.setMnemonic(getButtonMnemonic("restore")); - mi = menu.add(moveAction); - mi.setMnemonic(getButtonMnemonic("move")); - mi = menu.add(sizeAction); - mi.setMnemonic(getButtonMnemonic("size")); - mi = menu.add(iconifyAction); - mi.setMnemonic(getButtonMnemonic("minimize")); - mi = menu.add(maximizeAction); - mi.setMnemonic(getButtonMnemonic("maximize")); - menu.add(new JSeparator()); - mi = menu.add(closeAction); - mi.setMnemonic(getButtonMnemonic("close")); - } - - private static int getButtonMnemonic(String button) { - try { - return Integer.parseInt(UIManager.getString( - "InternalFrameTitlePane." + button + "Button.mnemonic")); - } catch (NumberFormatException e) { - return -1; - } - } - - protected void showSystemMenu(){ - showSystemPopupMenu(systemLabel); - } - - private void showSystemPopupMenu(Component invoker){ - Dimension dim = new Dimension(); - Border border = frame.getBorder(); - if (border != null) { - dim.width += border.getBorderInsets(frame).left + - border.getBorderInsets(frame).right; - dim.height += border.getBorderInsets(frame).bottom + - border.getBorderInsets(frame).top; - } - if (!frame.isIcon()) { - systemPopupMenu.show(invoker, - getX() - dim.width, - getY() + getHeight() - dim.height); - } else { - systemPopupMenu.show(invoker, - getX() - dim.width, - getY() - systemPopupMenu.getPreferredSize().height - - dim.height); - } - } - - protected PropertyChangeListener createPropertyChangeListener() { - return new WindowsPropertyChangeHandler(); - } - - protected LayoutManager createLayout() { - return new WindowsTitlePaneLayout(); - } - - public class WindowsTitlePaneLayout extends BasicInternalFrameTitlePane.TitlePaneLayout { - private Insets captionMargin = null; - private Insets contentMargin = null; - private XPStyle xp = XPStyle.getXP(); - - WindowsTitlePaneLayout() { - if (xp != null) { - Component c = WindowsInternalFrameTitlePane.this; - captionMargin = xp.getMargin(c, Part.WP_CAPTION, null, Prop.CAPTIONMARGINS); - contentMargin = xp.getMargin(c, Part.WP_CAPTION, null, Prop.CONTENTMARGINS); - } - if (captionMargin == null) { - captionMargin = new Insets(0, 2, 0, 2); - } - if (contentMargin == null) { - contentMargin = new Insets(0, 0, 0, 0); - } - } - - private int layoutButton(JComponent button, Part part, - int x, int y, int w, int h, int gap, - boolean leftToRight) { - if (!leftToRight) { - x -= w; - } - button.setBounds(x, y, w, h); - if (leftToRight) { - x += w + 2; - } else { - x -= 2; - } - return x; - } - - public void layoutContainer(Container c) { - boolean leftToRight = WindowsGraphicsUtils.isLeftToRight(frame); - int x, y; - int w = getWidth(); - int h = getHeight(); - - // System button - // Note: this icon is square, but the buttons aren't always. - int iconSize = (xp != null) ? (h-2)*6/10 : h-4; - if (xp != null) { - x = (leftToRight) ? captionMargin.left + 2 : w - captionMargin.right - 2; - } else { - x = (leftToRight) ? captionMargin.left : w - captionMargin.right; - } - y = (h - iconSize) / 2; - layoutButton(systemLabel, Part.WP_SYSBUTTON, - x, y, iconSize, iconSize, 0, - leftToRight); - - // Right hand buttons - if (xp != null) { - x = (leftToRight) ? w - captionMargin.right - 2 : captionMargin.left + 2; - y = 1; // XP seems to ignore margins and offset here - if (frame.isMaximum()) { - y += 1; - } else { - y += 5; - } - } else { - x = (leftToRight) ? w - captionMargin.right : captionMargin.left; - y = (h - buttonHeight) / 2; - } - - if(frame.isClosable()) { - x = layoutButton(closeButton, Part.WP_CLOSEBUTTON, - x, y, buttonWidth, buttonHeight, 2, - !leftToRight); - } - - if(frame.isMaximizable()) { - x = layoutButton(maxButton, Part.WP_MAXBUTTON, - x, y, buttonWidth, buttonHeight, (xp != null) ? 2 : 0, - !leftToRight); - } - - if(frame.isIconifiable()) { - layoutButton(iconButton, Part.WP_MINBUTTON, - x, y, buttonWidth, buttonHeight, 0, - !leftToRight); - } - } - } // end WindowsTitlePaneLayout - - public class WindowsPropertyChangeHandler extends PropertyChangeHandler { - public void propertyChange(PropertyChangeEvent evt) { - String prop = evt.getPropertyName(); - - // Update the internal frame icon for the system menu. - if (JInternalFrame.FRAME_ICON_PROPERTY.equals(prop) && - systemLabel != null) { - systemLabel.setIcon(frame.getFrameIcon()); - } - - super.propertyChange(evt); - } - } - - /** - * A versatile Icon implementation which can take an array of Icon - * instances (typically ImageIcons) and choose one that gives the best - * quality for a given Graphics2D scale factor when painting. - *

    - * The class is public so it can be instantiated by UIDefaults.ProxyLazyValue. - *

    - * Note: We assume here that icons are square. - */ - public static class ScalableIconUIResource implements Icon, UIResource { - // We can use an arbitrary size here because we scale to it in paintIcon() - private static final int SIZE = 16; - - private Icon[] icons; - - /** - * @param objects an array of Icon or UIDefaults.LazyValue - *

    - * The constructor is public so it can be called by UIDefaults.ProxyLazyValue. - */ - public ScalableIconUIResource(Object[] objects) { - this.icons = new Icon[objects.length]; - - for (int i = 0; i < objects.length; i++) { - if (objects[i] instanceof UIDefaults.LazyValue) { - icons[i] = (Icon)((UIDefaults.LazyValue)objects[i]).createValue(null); - } else { - icons[i] = (Icon)objects[i]; - } - } - } - - /** - * @return the Icon closest to the requested size - */ - protected Icon getBestIcon(int size) { - if (icons != null && icons.length > 0) { - int bestIndex = 0; - int minDiff = Integer.MAX_VALUE; - for (int i=0; i < icons.length; i++) { - Icon icon = icons[i]; - int iconSize; - if (icon != null && (iconSize = icon.getIconWidth()) > 0) { - int diff = Math.abs(iconSize - size); - if (diff < minDiff) { - minDiff = diff; - bestIndex = i; - } - } - } - return icons[bestIndex]; - } else { - return null; - } - } - - public void paintIcon(Component c, Graphics g, int x, int y) { - Graphics2D g2d = (Graphics2D)g.create(); - // Calculate how big our drawing area is in pixels - // Assume we are square - int size = getIconWidth(); - double scale = g2d.getTransform().getScaleX(); - Icon icon = getBestIcon((int)(size * scale)); - int iconSize; - if (icon != null && (iconSize = icon.getIconWidth()) > 0) { - // Set drawing scale to make icon act true to our reported size - double drawScale = size / (double)iconSize; - g2d.translate(x, y); - g2d.scale(drawScale, drawScale); - icon.paintIcon(c, g2d, 0, 0); - } - g2d.dispose(); - } - - public int getIconWidth() { - return SIZE; - } - - public int getIconHeight() { - return SIZE; - } - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsInternalFrameUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsInternalFrameUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,135 +0,0 @@ -/* - * Copyright (c) 1997, 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 com.sun.java.swing.plaf.windows; - -import java.awt.*; -import java.beans.*; -import javax.swing.*; -import javax.swing.border.*; -import javax.swing.plaf.basic.*; -import javax.swing.plaf.ComponentUI; - -import static com.sun.java.swing.plaf.windows.TMSchema.*; -import static com.sun.java.swing.plaf.windows.XPStyle.Skin; - -/** - * Windows rendition of the component. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - */ -public class WindowsInternalFrameUI extends BasicInternalFrameUI -{ - XPStyle xp = XPStyle.getXP(); - - public void installDefaults() { - super.installDefaults(); - - if (xp != null) { - frame.setBorder(new XPBorder()); - } else { - frame.setBorder(UIManager.getBorder("InternalFrame.border")); - } - } - - public void installUI(JComponent c) { - super.installUI(c); - - LookAndFeel.installProperty(c, "opaque", - xp == null? Boolean.TRUE : Boolean.FALSE); - } - - public void uninstallDefaults() { - frame.setBorder(null); - super.uninstallDefaults(); - } - - public static ComponentUI createUI(JComponent b) { - return new WindowsInternalFrameUI((JInternalFrame)b); - } - - public WindowsInternalFrameUI(JInternalFrame w){ - super(w); - } - - protected DesktopManager createDesktopManager(){ - return new WindowsDesktopManager(); - } - - protected JComponent createNorthPane(JInternalFrame w) { - titlePane = new WindowsInternalFrameTitlePane(w); - return titlePane; - } - - @SuppressWarnings("serial") // Superclass is not serializable across versions - private class XPBorder extends AbstractBorder { - private Skin leftSkin = xp.getSkin(frame, Part.WP_FRAMELEFT); - private Skin rightSkin = xp.getSkin(frame, Part.WP_FRAMERIGHT); - private Skin bottomSkin = xp.getSkin(frame, Part.WP_FRAMEBOTTOM); - - /** - * @param x the x position of the painted border - * @param y the y position of the painted border - * @param width the width of the painted border - * @param height the height of the painted border - */ - public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { - State state = ((JInternalFrame)c).isSelected() ? State.ACTIVE : State.INACTIVE; - int topBorderHeight = (titlePane != null) ? titlePane.getSize().height : 0; - - bottomSkin.paintSkin(g, 0, height-bottomSkin.getHeight(), - width, bottomSkin.getHeight(), - state); - - leftSkin.paintSkin(g, 0, topBorderHeight-1, - leftSkin.getWidth(), height-topBorderHeight-bottomSkin.getHeight()+2, - state); - - rightSkin.paintSkin(g, width-rightSkin.getWidth(), topBorderHeight-1, - rightSkin.getWidth(), height-topBorderHeight-bottomSkin.getHeight()+2, - state); - - } - - public Insets getBorderInsets(Component c, Insets insets) { - insets.top = 4; - insets.left = leftSkin.getWidth(); - insets.right = rightSkin.getWidth(); - insets.bottom = bottomSkin.getHeight(); - - return insets; - } - - public boolean isBorderOpaque() { - return true; - } - } - -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLabelUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLabelUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,112 +0,0 @@ -/* - * Copyright (c) 1997, 2005, 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 com.sun.java.swing.plaf.windows; - -import sun.swing.SwingUtilities2; -import sun.awt.AppContext; - -import java.awt.Color; -import java.awt.Graphics; - -import javax.swing.JComponent; -import javax.swing.JLabel; -import javax.swing.UIManager; - -import javax.swing.plaf.ComponentUI; - -import javax.swing.plaf.basic.BasicLabelUI; - - - -/** - * Windows rendition of the component. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - */ -public class WindowsLabelUI extends BasicLabelUI { - - private static final Object WINDOWS_LABEL_UI_KEY = new Object(); - - // ******************************** - // Create PLAF - // ******************************** - public static ComponentUI createUI(JComponent c) { - AppContext appContext = AppContext.getAppContext(); - WindowsLabelUI windowsLabelUI = - (WindowsLabelUI) appContext.get(WINDOWS_LABEL_UI_KEY); - if (windowsLabelUI == null) { - windowsLabelUI = new WindowsLabelUI(); - appContext.put(WINDOWS_LABEL_UI_KEY, windowsLabelUI); - } - return windowsLabelUI; - } - - protected void paintEnabledText(JLabel l, Graphics g, String s, - int textX, int textY) { - int mnemonicIndex = l.getDisplayedMnemonicIndex(); - // W2K Feature: Check to see if the Underscore should be rendered. - if (WindowsLookAndFeel.isMnemonicHidden() == true) { - mnemonicIndex = -1; - } - - g.setColor(l.getForeground()); - SwingUtilities2.drawStringUnderlineCharAt(l, g, s, mnemonicIndex, - textX, textY); - } - - protected void paintDisabledText(JLabel l, Graphics g, String s, - int textX, int textY) { - int mnemonicIndex = l.getDisplayedMnemonicIndex(); - // W2K Feature: Check to see if the Underscore should be rendered. - if (WindowsLookAndFeel.isMnemonicHidden() == true) { - mnemonicIndex = -1; - } - if ( UIManager.getColor("Label.disabledForeground") instanceof Color && - UIManager.getColor("Label.disabledShadow") instanceof Color) { - g.setColor( UIManager.getColor("Label.disabledShadow") ); - SwingUtilities2.drawStringUnderlineCharAt(l, g, s, - mnemonicIndex, - textX + 1, textY + 1); - g.setColor( UIManager.getColor("Label.disabledForeground") ); - SwingUtilities2.drawStringUnderlineCharAt(l, g, s, - mnemonicIndex, - textX, textY); - } else { - Color background = l.getBackground(); - g.setColor(background.brighter()); - SwingUtilities2.drawStringUnderlineCharAt(l,g, s, mnemonicIndex, - textX + 1, textY + 1); - g.setColor(background.darker()); - SwingUtilities2.drawStringUnderlineCharAt(l,g, s, mnemonicIndex, - textX, textY); - } - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2588 +0,0 @@ -/* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * 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. - */ - -/* - *

    These classes are designed to be used while the - * corresponding LookAndFeel class has been installed - * (UIManager.setLookAndFeel(new XXXLookAndFeel())). - * Using them while a different LookAndFeel is installed - * may produce unexpected results, including exceptions. - * Additionally, changing the LookAndFeel - * maintained by the UIManager without updating the - * corresponding ComponentUI of any - * JComponents may also produce unexpected results, - * such as the wrong colors showing up, and is generally not - * encouraged. - * - */ - -package com.sun.java.swing.plaf.windows; - -import java.awt.*; -import java.awt.image.BufferedImage; -import java.awt.image.ImageFilter; -import java.awt.image.ImageProducer; -import java.awt.image.FilteredImageSource; -import java.awt.image.RGBImageFilter; - -import javax.swing.plaf.*; -import javax.swing.*; -import javax.swing.plaf.basic.*; -import javax.swing.border.*; -import javax.swing.text.DefaultEditorKit; -import static javax.swing.UIDefaults.LazyValue; - -import java.awt.Font; -import java.awt.Color; -import java.awt.event.ActionEvent; - -import java.security.AccessController; - -import sun.awt.SunToolkit; -import sun.awt.OSInfo; -import sun.awt.shell.ShellFolder; -import sun.font.FontUtilities; -import sun.security.action.GetPropertyAction; - -import sun.swing.DefaultLayoutStyle; -import sun.swing.ImageIconUIResource; -import sun.swing.SwingAccessor; -import sun.swing.icon.SortArrowIcon; -import sun.swing.SwingUtilities2; -import sun.swing.StringUIClientPropertyKey; -import sun.swing.plaf.windows.ClassicSortArrowIcon; - -import static com.sun.java.swing.plaf.windows.TMSchema.*; -import static com.sun.java.swing.plaf.windows.XPStyle.Skin; - -import com.sun.java.swing.plaf.windows.WindowsIconFactory.VistaMenuItemCheckIconFactory; - -/** - * Implements the Windows95/98/NT/2000 Look and Feel. - * UI classes not implemented specifically for Windows will - * default to those implemented in Basic. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - * - * @author unattributed - */ -@SuppressWarnings("serial") // Superclass is not serializable across versions -public class WindowsLookAndFeel extends BasicLookAndFeel -{ - /** - * A client property that can be used with any JComponent that will end up - * calling the LookAndFeel.getDisabledIcon method. This client property, - * when set to Boolean.TRUE, will cause getDisabledIcon to use an - * alternate algorithm for creating disabled icons to produce icons - * that appear similar to the native Windows file chooser - */ - static final Object HI_RES_DISABLED_ICON_CLIENT_KEY = - new StringUIClientPropertyKey( - "WindowsLookAndFeel.generateHiResDisabledIcon"); - - private boolean updatePending = false; - - private boolean useSystemFontSettings = true; - private boolean useSystemFontSizeSettings; - - // These properties are not used directly, but are kept as - // private members to avoid being GC'd. - private WindowsDesktopProperty themeActive, dllName, colorName, sizeName; - private WindowsDesktopProperty aaSettings; - - private transient LayoutStyle style; - - /** - * Base dialog units along the horizontal axis. - */ - private int baseUnitX; - - /** - * Base dialog units along the vertical axis. - */ - private int baseUnitY; - - public String getName() { - return "Windows"; - } - - public String getDescription() { - return "The Microsoft Windows Look and Feel"; - } - - public String getID() { - return "Windows"; - } - - public boolean isNativeLookAndFeel() { - return OSInfo.getOSType() == OSInfo.OSType.WINDOWS; - } - - public boolean isSupportedLookAndFeel() { - return isNativeLookAndFeel(); - } - - public void initialize() { - super.initialize(); - - // Set the flag which determines which version of Windows should - // be rendered. This flag only need to be set once. - // if version <= 4.0 then the classic LAF should be loaded. - if (OSInfo.getWindowsVersion().compareTo(OSInfo.WINDOWS_95) <= 0) { - isClassicWindows = true; - } else { - isClassicWindows = false; - XPStyle.invalidateStyle(); - } - - // Using the fonts set by the user can potentially cause - // performance and compatibility issues, so allow this feature - // to be switched off either at runtime or programmatically - // - String systemFonts = java.security.AccessController.doPrivileged( - new GetPropertyAction("swing.useSystemFontSettings")); - useSystemFontSettings = (systemFonts == null || - Boolean.valueOf(systemFonts).booleanValue()); - - if (useSystemFontSettings) { - Object value = UIManager.get("Application.useSystemFontSettings"); - - useSystemFontSettings = (value == null || - Boolean.TRUE.equals(value)); - } - KeyboardFocusManager.getCurrentKeyboardFocusManager(). - addKeyEventPostProcessor(WindowsRootPaneUI.altProcessor); - - } - - /** - * Initialize the uiClassID to BasicComponentUI mapping. - * The JComponent classes define their own uiClassID constants - * (see AbstractComponent.getUIClassID). This table must - * map those constants to a BasicComponentUI class of the - * appropriate type. - * - * @see BasicLookAndFeel#getDefaults - */ - protected void initClassDefaults(UIDefaults table) - { - super.initClassDefaults(table); - - final String windowsPackageName = "com.sun.java.swing.plaf.windows."; - - Object[] uiDefaults = { - "ButtonUI", windowsPackageName + "WindowsButtonUI", - "CheckBoxUI", windowsPackageName + "WindowsCheckBoxUI", - "CheckBoxMenuItemUI", windowsPackageName + "WindowsCheckBoxMenuItemUI", - "LabelUI", windowsPackageName + "WindowsLabelUI", - "RadioButtonUI", windowsPackageName + "WindowsRadioButtonUI", - "RadioButtonMenuItemUI", windowsPackageName + "WindowsRadioButtonMenuItemUI", - "ToggleButtonUI", windowsPackageName + "WindowsToggleButtonUI", - "ProgressBarUI", windowsPackageName + "WindowsProgressBarUI", - "SliderUI", windowsPackageName + "WindowsSliderUI", - "SeparatorUI", windowsPackageName + "WindowsSeparatorUI", - "SplitPaneUI", windowsPackageName + "WindowsSplitPaneUI", - "SpinnerUI", windowsPackageName + "WindowsSpinnerUI", - "TabbedPaneUI", windowsPackageName + "WindowsTabbedPaneUI", - "TextAreaUI", windowsPackageName + "WindowsTextAreaUI", - "TextFieldUI", windowsPackageName + "WindowsTextFieldUI", - "PasswordFieldUI", windowsPackageName + "WindowsPasswordFieldUI", - "TextPaneUI", windowsPackageName + "WindowsTextPaneUI", - "EditorPaneUI", windowsPackageName + "WindowsEditorPaneUI", - "TreeUI", windowsPackageName + "WindowsTreeUI", - "ToolBarUI", windowsPackageName + "WindowsToolBarUI", - "ToolBarSeparatorUI", windowsPackageName + "WindowsToolBarSeparatorUI", - "ComboBoxUI", windowsPackageName + "WindowsComboBoxUI", - "TableHeaderUI", windowsPackageName + "WindowsTableHeaderUI", - "InternalFrameUI", windowsPackageName + "WindowsInternalFrameUI", - "DesktopPaneUI", windowsPackageName + "WindowsDesktopPaneUI", - "DesktopIconUI", windowsPackageName + "WindowsDesktopIconUI", - "FileChooserUI", windowsPackageName + "WindowsFileChooserUI", - "MenuUI", windowsPackageName + "WindowsMenuUI", - "MenuItemUI", windowsPackageName + "WindowsMenuItemUI", - "MenuBarUI", windowsPackageName + "WindowsMenuBarUI", - "PopupMenuUI", windowsPackageName + "WindowsPopupMenuUI", - "PopupMenuSeparatorUI", windowsPackageName + "WindowsPopupMenuSeparatorUI", - "ScrollBarUI", windowsPackageName + "WindowsScrollBarUI", - "RootPaneUI", windowsPackageName + "WindowsRootPaneUI" - }; - - table.putDefaults(uiDefaults); - } - - /** - * Load the SystemColors into the defaults table. The keys - * for SystemColor defaults are the same as the names of - * the public fields in SystemColor. If the table is being - * created on a native Windows platform we use the SystemColor - * values, otherwise we create color objects whose values match - * the defaults Windows95 colors. - */ - protected void initSystemColorDefaults(UIDefaults table) - { - String[] defaultSystemColors = { - "desktop", "#005C5C", /* Color of the desktop background */ - "activeCaption", "#000080", /* Color for captions (title bars) when they are active. */ - "activeCaptionText", "#FFFFFF", /* Text color for text in captions (title bars). */ - "activeCaptionBorder", "#C0C0C0", /* Border color for caption (title bar) window borders. */ - "inactiveCaption", "#808080", /* Color for captions (title bars) when not active. */ - "inactiveCaptionText", "#C0C0C0", /* Text color for text in inactive captions (title bars). */ - "inactiveCaptionBorder", "#C0C0C0", /* Border color for inactive caption (title bar) window borders. */ - "window", "#FFFFFF", /* Default color for the interior of windows */ - "windowBorder", "#000000", /* ??? */ - "windowText", "#000000", /* ??? */ - "menu", "#C0C0C0", /* Background color for menus */ - "menuPressedItemB", "#000080", /* LightShadow of menubutton highlight */ - "menuPressedItemF", "#FFFFFF", /* Default color for foreground "text" in menu item */ - "menuText", "#000000", /* Text color for menus */ - "text", "#C0C0C0", /* Text background color */ - "textText", "#000000", /* Text foreground color */ - "textHighlight", "#000080", /* Text background color when selected */ - "textHighlightText", "#FFFFFF", /* Text color when selected */ - "textInactiveText", "#808080", /* Text color when disabled */ - "control", "#C0C0C0", /* Default color for controls (buttons, sliders, etc) */ - "controlText", "#000000", /* Default color for text in controls */ - "controlHighlight", "#C0C0C0", - - /*"controlHighlight", "#E0E0E0",*/ /* Specular highlight (opposite of the shadow) */ - "controlLtHighlight", "#FFFFFF", /* Highlight color for controls */ - "controlShadow", "#808080", /* Shadow color for controls */ - "controlDkShadow", "#000000", /* Dark shadow color for controls */ - "scrollbar", "#E0E0E0", /* Scrollbar background (usually the "track") */ - "info", "#FFFFE1", /* ??? */ - "infoText", "#000000" /* ??? */ - }; - - loadSystemColors(table, defaultSystemColors, isNativeLookAndFeel()); - } - - /** - * Initialize the defaults table with the name of the ResourceBundle - * used for getting localized defaults. - */ - private void initResourceBundle(UIDefaults table) { - SwingAccessor.getUIDefaultsAccessor() - .addInternalBundle(table, - "com.sun.java.swing.plaf.windows.resources.windows"); - } - - // XXX - there are probably a lot of redundant values that could be removed. - // ie. Take a look at RadioButtonBorder, etc... - protected void initComponentDefaults(UIDefaults table) - { - super.initComponentDefaults( table ); - - initResourceBundle(table); - - // *** Shared Fonts - LazyValue dialogPlain12 = t -> new FontUIResource(Font.DIALOG, Font.PLAIN, 12); - - LazyValue sansSerifPlain12 = t -> new FontUIResource(Font.SANS_SERIF, Font.PLAIN, 12); - LazyValue monospacedPlain12 = t -> new FontUIResource(Font.MONOSPACED, Font.PLAIN, 12); - LazyValue dialogBold12 = t -> new FontUIResource(Font.DIALOG, Font.BOLD, 12); - - // *** Colors - // XXX - some of these doens't seem to be used - ColorUIResource red = new ColorUIResource(Color.red); - ColorUIResource black = new ColorUIResource(Color.black); - ColorUIResource white = new ColorUIResource(Color.white); - ColorUIResource gray = new ColorUIResource(Color.gray); - ColorUIResource darkGray = new ColorUIResource(Color.darkGray); - ColorUIResource scrollBarTrackHighlight = darkGray; - - // Set the flag which determines which version of Windows should - // be rendered. This flag only need to be set once. - // if version <= 4.0 then the classic LAF should be loaded. - isClassicWindows = OSInfo.getWindowsVersion().compareTo(OSInfo.WINDOWS_95) <= 0; - - // *** Tree - Object treeExpandedIcon = WindowsTreeUI.ExpandedIcon.createExpandedIcon(); - - Object treeCollapsedIcon = WindowsTreeUI.CollapsedIcon.createCollapsedIcon(); - - - // *** Text - Object fieldInputMap = new UIDefaults.LazyInputMap(new Object[] { - "control C", DefaultEditorKit.copyAction, - "control V", DefaultEditorKit.pasteAction, - "control X", DefaultEditorKit.cutAction, - "COPY", DefaultEditorKit.copyAction, - "PASTE", DefaultEditorKit.pasteAction, - "CUT", DefaultEditorKit.cutAction, - "control INSERT", DefaultEditorKit.copyAction, - "shift INSERT", DefaultEditorKit.pasteAction, - "shift DELETE", DefaultEditorKit.cutAction, - "control A", DefaultEditorKit.selectAllAction, - "control BACK_SLASH", "unselect"/*DefaultEditorKit.unselectAction*/, - "shift LEFT", DefaultEditorKit.selectionBackwardAction, - "shift RIGHT", DefaultEditorKit.selectionForwardAction, - "control LEFT", DefaultEditorKit.previousWordAction, - "control RIGHT", DefaultEditorKit.nextWordAction, - "control shift LEFT", DefaultEditorKit.selectionPreviousWordAction, - "control shift RIGHT", DefaultEditorKit.selectionNextWordAction, - "HOME", DefaultEditorKit.beginLineAction, - "END", DefaultEditorKit.endLineAction, - "shift HOME", DefaultEditorKit.selectionBeginLineAction, - "shift END", DefaultEditorKit.selectionEndLineAction, - "BACK_SPACE", DefaultEditorKit.deletePrevCharAction, - "shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction, - "ctrl H", DefaultEditorKit.deletePrevCharAction, - "DELETE", DefaultEditorKit.deleteNextCharAction, - "ctrl DELETE", DefaultEditorKit.deleteNextWordAction, - "ctrl BACK_SPACE", DefaultEditorKit.deletePrevWordAction, - "RIGHT", DefaultEditorKit.forwardAction, - "LEFT", DefaultEditorKit.backwardAction, - "KP_RIGHT", DefaultEditorKit.forwardAction, - "KP_LEFT", DefaultEditorKit.backwardAction, - "ENTER", JTextField.notifyAction, - "control shift O", "toggle-componentOrientation"/*DefaultEditorKit.toggleComponentOrientation*/ - }); - - Object passwordInputMap = new UIDefaults.LazyInputMap(new Object[] { - "control C", DefaultEditorKit.copyAction, - "control V", DefaultEditorKit.pasteAction, - "control X", DefaultEditorKit.cutAction, - "COPY", DefaultEditorKit.copyAction, - "PASTE", DefaultEditorKit.pasteAction, - "CUT", DefaultEditorKit.cutAction, - "control INSERT", DefaultEditorKit.copyAction, - "shift INSERT", DefaultEditorKit.pasteAction, - "shift DELETE", DefaultEditorKit.cutAction, - "control A", DefaultEditorKit.selectAllAction, - "control BACK_SLASH", "unselect"/*DefaultEditorKit.unselectAction*/, - "shift LEFT", DefaultEditorKit.selectionBackwardAction, - "shift RIGHT", DefaultEditorKit.selectionForwardAction, - "control LEFT", DefaultEditorKit.beginLineAction, - "control RIGHT", DefaultEditorKit.endLineAction, - "control shift LEFT", DefaultEditorKit.selectionBeginLineAction, - "control shift RIGHT", DefaultEditorKit.selectionEndLineAction, - "HOME", DefaultEditorKit.beginLineAction, - "END", DefaultEditorKit.endLineAction, - "shift HOME", DefaultEditorKit.selectionBeginLineAction, - "shift END", DefaultEditorKit.selectionEndLineAction, - "BACK_SPACE", DefaultEditorKit.deletePrevCharAction, - "shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction, - "ctrl H", DefaultEditorKit.deletePrevCharAction, - "DELETE", DefaultEditorKit.deleteNextCharAction, - "RIGHT", DefaultEditorKit.forwardAction, - "LEFT", DefaultEditorKit.backwardAction, - "KP_RIGHT", DefaultEditorKit.forwardAction, - "KP_LEFT", DefaultEditorKit.backwardAction, - "ENTER", JTextField.notifyAction, - "control shift O", "toggle-componentOrientation"/*DefaultEditorKit.toggleComponentOrientation*/ - }); - - Object multilineInputMap = new UIDefaults.LazyInputMap(new Object[] { - "control C", DefaultEditorKit.copyAction, - "control V", DefaultEditorKit.pasteAction, - "control X", DefaultEditorKit.cutAction, - "COPY", DefaultEditorKit.copyAction, - "PASTE", DefaultEditorKit.pasteAction, - "CUT", DefaultEditorKit.cutAction, - "control INSERT", DefaultEditorKit.copyAction, - "shift INSERT", DefaultEditorKit.pasteAction, - "shift DELETE", DefaultEditorKit.cutAction, - "shift LEFT", DefaultEditorKit.selectionBackwardAction, - "shift RIGHT", DefaultEditorKit.selectionForwardAction, - "control LEFT", DefaultEditorKit.previousWordAction, - "control RIGHT", DefaultEditorKit.nextWordAction, - "control shift LEFT", DefaultEditorKit.selectionPreviousWordAction, - "control shift RIGHT", DefaultEditorKit.selectionNextWordAction, - "control A", DefaultEditorKit.selectAllAction, - "control BACK_SLASH", "unselect"/*DefaultEditorKit.unselectAction*/, - "HOME", DefaultEditorKit.beginLineAction, - "END", DefaultEditorKit.endLineAction, - "shift HOME", DefaultEditorKit.selectionBeginLineAction, - "shift END", DefaultEditorKit.selectionEndLineAction, - "control HOME", DefaultEditorKit.beginAction, - "control END", DefaultEditorKit.endAction, - "control shift HOME", DefaultEditorKit.selectionBeginAction, - "control shift END", DefaultEditorKit.selectionEndAction, - "UP", DefaultEditorKit.upAction, - "DOWN", DefaultEditorKit.downAction, - "BACK_SPACE", DefaultEditorKit.deletePrevCharAction, - "shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction, - "ctrl H", DefaultEditorKit.deletePrevCharAction, - "DELETE", DefaultEditorKit.deleteNextCharAction, - "ctrl DELETE", DefaultEditorKit.deleteNextWordAction, - "ctrl BACK_SPACE", DefaultEditorKit.deletePrevWordAction, - "RIGHT", DefaultEditorKit.forwardAction, - "LEFT", DefaultEditorKit.backwardAction, - "KP_RIGHT", DefaultEditorKit.forwardAction, - "KP_LEFT", DefaultEditorKit.backwardAction, - "PAGE_UP", DefaultEditorKit.pageUpAction, - "PAGE_DOWN", DefaultEditorKit.pageDownAction, - "shift PAGE_UP", "selection-page-up", - "shift PAGE_DOWN", "selection-page-down", - "ctrl shift PAGE_UP", "selection-page-left", - "ctrl shift PAGE_DOWN", "selection-page-right", - "shift UP", DefaultEditorKit.selectionUpAction, - "shift DOWN", DefaultEditorKit.selectionDownAction, - "ENTER", DefaultEditorKit.insertBreakAction, - "TAB", DefaultEditorKit.insertTabAction, - "control T", "next-link-action", - "control shift T", "previous-link-action", - "control SPACE", "activate-link-action", - "control shift O", "toggle-componentOrientation"/*DefaultEditorKit.toggleComponentOrientation*/ - }); - - Object menuItemAcceleratorDelimiter = "+"; - - Object ControlBackgroundColor = new WindowsDesktopProperty( - "win.3d.backgroundColor", - table.get("control")); - Object ControlLightColor = new WindowsDesktopProperty( - "win.3d.lightColor", - table.get("controlHighlight")); - Object ControlHighlightColor = new WindowsDesktopProperty( - "win.3d.highlightColor", - table.get("controlLtHighlight")); - Object ControlShadowColor = new WindowsDesktopProperty( - "win.3d.shadowColor", - table.get("controlShadow")); - Object ControlDarkShadowColor = new WindowsDesktopProperty( - "win.3d.darkShadowColor", - table.get("controlDkShadow")); - Object ControlTextColor = new WindowsDesktopProperty( - "win.button.textColor", - table.get("controlText")); - Object MenuBackgroundColor = new WindowsDesktopProperty( - "win.menu.backgroundColor", - table.get("menu")); - Object MenuBarBackgroundColor = new WindowsDesktopProperty( - "win.menubar.backgroundColor", - table.get("menu")); - Object MenuTextColor = new WindowsDesktopProperty( - "win.menu.textColor", - table.get("menuText")); - Object SelectionBackgroundColor = new WindowsDesktopProperty( - "win.item.highlightColor", - table.get("textHighlight")); - Object SelectionTextColor = new WindowsDesktopProperty( - "win.item.highlightTextColor", - table.get("textHighlightText")); - Object WindowBackgroundColor = new WindowsDesktopProperty( - "win.frame.backgroundColor", - table.get("window")); - Object WindowTextColor = new WindowsDesktopProperty( - "win.frame.textColor", - table.get("windowText")); - Object WindowBorderWidth = new WindowsDesktopProperty( - "win.frame.sizingBorderWidth", - Integer.valueOf(1)); - Object TitlePaneHeight = new WindowsDesktopProperty( - "win.frame.captionHeight", - Integer.valueOf(18)); - Object TitleButtonWidth = new WindowsDesktopProperty( - "win.frame.captionButtonWidth", - Integer.valueOf(16)); - Object TitleButtonHeight = new WindowsDesktopProperty( - "win.frame.captionButtonHeight", - Integer.valueOf(16)); - Object InactiveTextColor = new WindowsDesktopProperty( - "win.text.grayedTextColor", - table.get("textInactiveText")); - Object ScrollbarBackgroundColor = new WindowsDesktopProperty( - "win.scrollbar.backgroundColor", - table.get("scrollbar")); - Object buttonFocusColor = new FocusColorProperty(); - - Object TextBackground = new XPColorValue(Part.EP_EDIT, null, Prop.FILLCOLOR, - WindowBackgroundColor); - //The following four lines were commented out as part of bug 4991597 - //This code *is* correct, however it differs from WindowsXP and is, apparently - //a Windows XP bug. Until Windows fixes this bug, we shall also exhibit the same - //behavior - //Object ReadOnlyTextBackground = new XPColorValue(Part.EP_EDITTEXT, State.READONLY, Prop.FILLCOLOR, - // ControlBackgroundColor); - //Object DisabledTextBackground = new XPColorValue(Part.EP_EDITTEXT, State.DISABLED, Prop.FILLCOLOR, - // ControlBackgroundColor); - Object ReadOnlyTextBackground = ControlBackgroundColor; - Object DisabledTextBackground = ControlBackgroundColor; - - Object MenuFont = dialogPlain12; - Object FixedControlFont = monospacedPlain12; - Object ControlFont = dialogPlain12; - Object MessageFont = dialogPlain12; - Object WindowFont = dialogBold12; - Object ToolTipFont = sansSerifPlain12; - Object IconFont = ControlFont; - - Object scrollBarWidth = new WindowsDesktopProperty("win.scrollbar.width", Integer.valueOf(16)); - - Object menuBarHeight = new WindowsDesktopProperty("win.menu.height", null); - - Object hotTrackingOn = new WindowsDesktopProperty("win.item.hotTrackingOn", true); - - Object showMnemonics = new WindowsDesktopProperty("win.menu.keyboardCuesOn", Boolean.TRUE); - - if (useSystemFontSettings) { - MenuFont = getDesktopFontValue("win.menu.font", MenuFont); - FixedControlFont = getDesktopFontValue("win.ansiFixed.font", FixedControlFont); - ControlFont = getDesktopFontValue("win.defaultGUI.font", ControlFont); - MessageFont = getDesktopFontValue("win.messagebox.font", MessageFont); - WindowFont = getDesktopFontValue("win.frame.captionFont", WindowFont); - IconFont = getDesktopFontValue("win.icon.font", IconFont); - ToolTipFont = getDesktopFontValue("win.tooltip.font", ToolTipFont); - - /* Put the desktop AA settings in the defaults. - * JComponent.setUI() retrieves this and makes it available - * as a client property on the JComponent. Use the same key name - * for both client property and UIDefaults. - * Also need to set up listeners for changes in these settings. - */ - SwingUtilities2.putAATextInfo(true, table); - this.aaSettings = - new FontDesktopProperty(SunToolkit.DESKTOPFONTHINTS); - } - if (useSystemFontSizeSettings) { - MenuFont = new WindowsFontSizeProperty("win.menu.font.height", Font.DIALOG, Font.PLAIN, 12); - FixedControlFont = new WindowsFontSizeProperty("win.ansiFixed.font.height", Font.MONOSPACED, - Font.PLAIN, 12); - ControlFont = new WindowsFontSizeProperty("win.defaultGUI.font.height", Font.DIALOG, Font.PLAIN, 12); - MessageFont = new WindowsFontSizeProperty("win.messagebox.font.height", Font.DIALOG, Font.PLAIN, 12); - WindowFont = new WindowsFontSizeProperty("win.frame.captionFont.height", Font.DIALOG, Font.BOLD, 12); - ToolTipFont = new WindowsFontSizeProperty("win.tooltip.font.height", Font.SANS_SERIF, Font.PLAIN, 12); - IconFont = new WindowsFontSizeProperty("win.icon.font.height", Font.DIALOG, Font.PLAIN, 12); - } - - - if (!(this instanceof WindowsClassicLookAndFeel) && - (OSInfo.getOSType() == OSInfo.OSType.WINDOWS && - OSInfo.getWindowsVersion().compareTo(OSInfo.WINDOWS_XP) >= 0) && - AccessController.doPrivileged(new GetPropertyAction("swing.noxp")) == null) { - - // These desktop properties are not used directly, but are needed to - // trigger realoading of UI's. - this.themeActive = new TriggerDesktopProperty("win.xpstyle.themeActive"); - this.dllName = new TriggerDesktopProperty("win.xpstyle.dllName"); - this.colorName = new TriggerDesktopProperty("win.xpstyle.colorName"); - this.sizeName = new TriggerDesktopProperty("win.xpstyle.sizeName"); - } - - - Object[] defaults = { - // *** Auditory Feedback - // this key defines which of the various cues to render - // Overridden from BasicL&F. This L&F should play all sounds - // all the time. The infrastructure decides what to play. - // This is disabled until sound bugs can be resolved. - "AuditoryCues.playList", null, // table.get("AuditoryCues.cueList"), - - "Application.useSystemFontSettings", Boolean.valueOf(useSystemFontSettings), - - "TextField.focusInputMap", fieldInputMap, - "PasswordField.focusInputMap", passwordInputMap, - "TextArea.focusInputMap", multilineInputMap, - "TextPane.focusInputMap", multilineInputMap, - "EditorPane.focusInputMap", multilineInputMap, - - // Buttons - "Button.font", ControlFont, - "Button.background", ControlBackgroundColor, - // Button.foreground, Button.shadow, Button.darkShadow, - // Button.disabledForground, and Button.disabledShadow are only - // used for Windows Classic. Windows XP will use colors - // from the current visual style. - "Button.foreground", ControlTextColor, - "Button.shadow", ControlShadowColor, - "Button.darkShadow", ControlDarkShadowColor, - "Button.light", ControlLightColor, - "Button.highlight", ControlHighlightColor, - "Button.disabledForeground", InactiveTextColor, - "Button.disabledShadow", ControlHighlightColor, - "Button.focus", buttonFocusColor, - "Button.dashedRectGapX", new XPValue(Integer.valueOf(3), Integer.valueOf(5)), - "Button.dashedRectGapY", new XPValue(Integer.valueOf(3), Integer.valueOf(4)), - "Button.dashedRectGapWidth", new XPValue(Integer.valueOf(6), Integer.valueOf(10)), - "Button.dashedRectGapHeight", new XPValue(Integer.valueOf(6), Integer.valueOf(8)), - "Button.textShiftOffset", new XPValue(Integer.valueOf(0), - Integer.valueOf(1)), - // W2K keyboard navigation hidding. - "Button.showMnemonics", showMnemonics, - "Button.focusInputMap", - new UIDefaults.LazyInputMap(new Object[] { - "SPACE", "pressed", - "released SPACE", "released" - }), - - "Caret.width", - new WindowsDesktopProperty("win.caret.width", null), - - "CheckBox.font", ControlFont, - "CheckBox.interiorBackground", WindowBackgroundColor, - "CheckBox.background", ControlBackgroundColor, - "CheckBox.foreground", WindowTextColor, - "CheckBox.shadow", ControlShadowColor, - "CheckBox.darkShadow", ControlDarkShadowColor, - "CheckBox.light", ControlLightColor, - "CheckBox.highlight", ControlHighlightColor, - "CheckBox.focus", buttonFocusColor, - "CheckBox.focusInputMap", - new UIDefaults.LazyInputMap(new Object[] { - "SPACE", "pressed", - "released SPACE", "released" - }), - // margin is 2 all the way around, BasicBorders.RadioButtonBorder - // (checkbox uses RadioButtonBorder) is 2 all the way around too. - "CheckBox.totalInsets", new Insets(4, 4, 4, 4), - - "CheckBoxMenuItem.font", MenuFont, - "CheckBoxMenuItem.background", MenuBackgroundColor, - "CheckBoxMenuItem.foreground", MenuTextColor, - "CheckBoxMenuItem.selectionForeground", SelectionTextColor, - "CheckBoxMenuItem.selectionBackground", SelectionBackgroundColor, - "CheckBoxMenuItem.acceleratorForeground", MenuTextColor, - "CheckBoxMenuItem.acceleratorSelectionForeground", SelectionTextColor, - "CheckBoxMenuItem.commandSound", "win.sound.menuCommand", - - "ComboBox.font", ControlFont, - "ComboBox.background", WindowBackgroundColor, - "ComboBox.foreground", WindowTextColor, - "ComboBox.buttonBackground", ControlBackgroundColor, - "ComboBox.buttonShadow", ControlShadowColor, - "ComboBox.buttonDarkShadow", ControlDarkShadowColor, - "ComboBox.buttonHighlight", ControlHighlightColor, - "ComboBox.selectionBackground", SelectionBackgroundColor, - "ComboBox.selectionForeground", SelectionTextColor, - "ComboBox.editorBorder", new XPValue(new EmptyBorder(1,4,1,1), - new EmptyBorder(1,4,1,4)), - "ComboBox.disabledBackground", - new XPColorValue(Part.CP_COMBOBOX, State.DISABLED, - Prop.FILLCOLOR, DisabledTextBackground), - "ComboBox.disabledForeground", - new XPColorValue(Part.CP_COMBOBOX, State.DISABLED, - Prop.TEXTCOLOR, InactiveTextColor), - "ComboBox.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] { - "ESCAPE", "hidePopup", - "PAGE_UP", "pageUpPassThrough", - "PAGE_DOWN", "pageDownPassThrough", - "HOME", "homePassThrough", - "END", "endPassThrough", - "DOWN", "selectNext2", - "KP_DOWN", "selectNext2", - "UP", "selectPrevious2", - "KP_UP", "selectPrevious2", - "ENTER", "enterPressed", - "F4", "togglePopup", - "alt DOWN", "togglePopup", - "alt KP_DOWN", "togglePopup", - "alt UP", "togglePopup", - "alt KP_UP", "togglePopup" - }), - - // DeskTop. - "Desktop.background", new WindowsDesktopProperty( - "win.mdi.backgroundColor", - table.get("desktop")), - "Desktop.ancestorInputMap", - new UIDefaults.LazyInputMap(new Object[] { - "ctrl F5", "restore", - "ctrl F4", "close", - "ctrl F7", "move", - "ctrl F8", "resize", - "RIGHT", "right", - "KP_RIGHT", "right", - "LEFT", "left", - "KP_LEFT", "left", - "UP", "up", - "KP_UP", "up", - "DOWN", "down", - "KP_DOWN", "down", - "ESCAPE", "escape", - "ctrl F9", "minimize", - "ctrl F10", "maximize", - "ctrl F6", "selectNextFrame", - "ctrl TAB", "selectNextFrame", - "ctrl alt F6", "selectNextFrame", - "shift ctrl alt F6", "selectPreviousFrame", - "ctrl F12", "navigateNext", - "shift ctrl F12", "navigatePrevious" - }), - - // DesktopIcon - "DesktopIcon.width", Integer.valueOf(160), - - "EditorPane.font", ControlFont, - "EditorPane.background", WindowBackgroundColor, - "EditorPane.foreground", WindowTextColor, - "EditorPane.selectionBackground", SelectionBackgroundColor, - "EditorPane.selectionForeground", SelectionTextColor, - "EditorPane.caretForeground", WindowTextColor, - "EditorPane.inactiveForeground", InactiveTextColor, - "EditorPane.inactiveBackground", WindowBackgroundColor, - "EditorPane.disabledBackground", DisabledTextBackground, - - "FileChooser.homeFolderIcon", new LazyWindowsIcon(null, - "icons/HomeFolder.gif"), - "FileChooser.listFont", IconFont, - "FileChooser.listViewBackground", new XPColorValue(Part.LVP_LISTVIEW, null, Prop.FILLCOLOR, - WindowBackgroundColor), - "FileChooser.listViewBorder", new XPBorderValue(Part.LVP_LISTVIEW, - (LazyValue) t -> BorderUIResource.getLoweredBevelBorderUIResource()), - "FileChooser.listViewIcon", new LazyWindowsIcon("fileChooserIcon ListView", - "icons/ListView.gif"), - "FileChooser.listViewWindowsStyle", Boolean.TRUE, - "FileChooser.detailsViewIcon", new LazyWindowsIcon("fileChooserIcon DetailsView", - "icons/DetailsView.gif"), - "FileChooser.viewMenuIcon", new LazyWindowsIcon("fileChooserIcon ViewMenu", - "icons/ListView.gif"), - "FileChooser.upFolderIcon", new LazyWindowsIcon("fileChooserIcon UpFolder", - "icons/UpFolder.gif"), - "FileChooser.newFolderIcon", new LazyWindowsIcon("fileChooserIcon NewFolder", - "icons/NewFolder.gif"), - "FileChooser.useSystemExtensionHiding", Boolean.TRUE, - - "FileChooser.usesSingleFilePane", Boolean.TRUE, - "FileChooser.noPlacesBar", new WindowsDesktopProperty("win.comdlg.noPlacesBar", - Boolean.FALSE), - "FileChooser.ancestorInputMap", - new UIDefaults.LazyInputMap(new Object[] { - "ESCAPE", "cancelSelection", - "F2", "editFileName", - "F5", "refresh", - "BACK_SPACE", "Go Up" - }), - - "FileView.directoryIcon", SwingUtilities2.makeIcon(getClass(), - WindowsLookAndFeel.class, - "icons/Directory.gif"), - "FileView.fileIcon", SwingUtilities2.makeIcon(getClass(), - WindowsLookAndFeel.class, - "icons/File.gif"), - "FileView.computerIcon", SwingUtilities2.makeIcon(getClass(), - WindowsLookAndFeel.class, - "icons/Computer.gif"), - "FileView.hardDriveIcon", SwingUtilities2.makeIcon(getClass(), - WindowsLookAndFeel.class, - "icons/HardDrive.gif"), - "FileView.floppyDriveIcon", SwingUtilities2.makeIcon(getClass(), - WindowsLookAndFeel.class, - "icons/FloppyDrive.gif"), - - "FormattedTextField.font", ControlFont, - "InternalFrame.titleFont", WindowFont, - "InternalFrame.titlePaneHeight", TitlePaneHeight, - "InternalFrame.titleButtonWidth", TitleButtonWidth, - "InternalFrame.titleButtonHeight", TitleButtonHeight, - "InternalFrame.titleButtonToolTipsOn", hotTrackingOn, - "InternalFrame.borderColor", ControlBackgroundColor, - "InternalFrame.borderShadow", ControlShadowColor, - "InternalFrame.borderDarkShadow", ControlDarkShadowColor, - "InternalFrame.borderHighlight", ControlHighlightColor, - "InternalFrame.borderLight", ControlLightColor, - "InternalFrame.borderWidth", WindowBorderWidth, - "InternalFrame.minimizeIconBackground", ControlBackgroundColor, - "InternalFrame.resizeIconHighlight", ControlLightColor, - "InternalFrame.resizeIconShadow", ControlShadowColor, - "InternalFrame.activeBorderColor", new WindowsDesktopProperty( - "win.frame.activeBorderColor", - table.get("windowBorder")), - "InternalFrame.inactiveBorderColor", new WindowsDesktopProperty( - "win.frame.inactiveBorderColor", - table.get("windowBorder")), - "InternalFrame.activeTitleBackground", new WindowsDesktopProperty( - "win.frame.activeCaptionColor", - table.get("activeCaption")), - "InternalFrame.activeTitleGradient", new WindowsDesktopProperty( - "win.frame.activeCaptionGradientColor", - table.get("activeCaption")), - "InternalFrame.activeTitleForeground", new WindowsDesktopProperty( - "win.frame.captionTextColor", - table.get("activeCaptionText")), - "InternalFrame.inactiveTitleBackground", new WindowsDesktopProperty( - "win.frame.inactiveCaptionColor", - table.get("inactiveCaption")), - "InternalFrame.inactiveTitleGradient", new WindowsDesktopProperty( - "win.frame.inactiveCaptionGradientColor", - table.get("inactiveCaption")), - "InternalFrame.inactiveTitleForeground", new WindowsDesktopProperty( - "win.frame.inactiveCaptionTextColor", - table.get("inactiveCaptionText")), - - "InternalFrame.maximizeIcon", - WindowsIconFactory.createFrameMaximizeIcon(), - "InternalFrame.minimizeIcon", - WindowsIconFactory.createFrameMinimizeIcon(), - "InternalFrame.iconifyIcon", - WindowsIconFactory.createFrameIconifyIcon(), - "InternalFrame.closeIcon", - WindowsIconFactory.createFrameCloseIcon(), - "InternalFrame.icon", - (LazyValue) t -> new WindowsInternalFrameTitlePane.ScalableIconUIResource(new Object[]{ - // The constructor takes one arg: an array of UIDefaults.LazyValue - // representing the icons - SwingUtilities2.makeIcon(getClass(), BasicLookAndFeel.class, "icons/JavaCup16.png"), - SwingUtilities2.makeIcon(getClass(), WindowsLookAndFeel.class, "icons/JavaCup32.png") - }), - // Internal Frame Auditory Cue Mappings - "InternalFrame.closeSound", "win.sound.close", - "InternalFrame.maximizeSound", "win.sound.maximize", - "InternalFrame.minimizeSound", "win.sound.minimize", - "InternalFrame.restoreDownSound", "win.sound.restoreDown", - "InternalFrame.restoreUpSound", "win.sound.restoreUp", - - "InternalFrame.windowBindings", new Object[] { - "shift ESCAPE", "showSystemMenu", - "ctrl SPACE", "showSystemMenu", - "ESCAPE", "hideSystemMenu"}, - - // Label - "Label.font", ControlFont, - "Label.background", ControlBackgroundColor, - "Label.foreground", WindowTextColor, - "Label.disabledForeground", InactiveTextColor, - "Label.disabledShadow", ControlHighlightColor, - - // List. - "List.font", ControlFont, - "List.background", WindowBackgroundColor, - "List.foreground", WindowTextColor, - "List.selectionBackground", SelectionBackgroundColor, - "List.selectionForeground", SelectionTextColor, - "List.lockToPositionOnScroll", Boolean.TRUE, - "List.focusInputMap", - new UIDefaults.LazyInputMap(new Object[] { - "ctrl C", "copy", - "ctrl V", "paste", - "ctrl X", "cut", - "COPY", "copy", - "PASTE", "paste", - "CUT", "cut", - "control INSERT", "copy", - "shift INSERT", "paste", - "shift DELETE", "cut", - "UP", "selectPreviousRow", - "KP_UP", "selectPreviousRow", - "shift UP", "selectPreviousRowExtendSelection", - "shift KP_UP", "selectPreviousRowExtendSelection", - "ctrl shift UP", "selectPreviousRowExtendSelection", - "ctrl shift KP_UP", "selectPreviousRowExtendSelection", - "ctrl UP", "selectPreviousRowChangeLead", - "ctrl KP_UP", "selectPreviousRowChangeLead", - "DOWN", "selectNextRow", - "KP_DOWN", "selectNextRow", - "shift DOWN", "selectNextRowExtendSelection", - "shift KP_DOWN", "selectNextRowExtendSelection", - "ctrl shift DOWN", "selectNextRowExtendSelection", - "ctrl shift KP_DOWN", "selectNextRowExtendSelection", - "ctrl DOWN", "selectNextRowChangeLead", - "ctrl KP_DOWN", "selectNextRowChangeLead", - "LEFT", "selectPreviousColumn", - "KP_LEFT", "selectPreviousColumn", - "shift LEFT", "selectPreviousColumnExtendSelection", - "shift KP_LEFT", "selectPreviousColumnExtendSelection", - "ctrl shift LEFT", "selectPreviousColumnExtendSelection", - "ctrl shift KP_LEFT", "selectPreviousColumnExtendSelection", - "ctrl LEFT", "selectPreviousColumnChangeLead", - "ctrl KP_LEFT", "selectPreviousColumnChangeLead", - "RIGHT", "selectNextColumn", - "KP_RIGHT", "selectNextColumn", - "shift RIGHT", "selectNextColumnExtendSelection", - "shift KP_RIGHT", "selectNextColumnExtendSelection", - "ctrl shift RIGHT", "selectNextColumnExtendSelection", - "ctrl shift KP_RIGHT", "selectNextColumnExtendSelection", - "ctrl RIGHT", "selectNextColumnChangeLead", - "ctrl KP_RIGHT", "selectNextColumnChangeLead", - "HOME", "selectFirstRow", - "shift HOME", "selectFirstRowExtendSelection", - "ctrl shift HOME", "selectFirstRowExtendSelection", - "ctrl HOME", "selectFirstRowChangeLead", - "END", "selectLastRow", - "shift END", "selectLastRowExtendSelection", - "ctrl shift END", "selectLastRowExtendSelection", - "ctrl END", "selectLastRowChangeLead", - "PAGE_UP", "scrollUp", - "shift PAGE_UP", "scrollUpExtendSelection", - "ctrl shift PAGE_UP", "scrollUpExtendSelection", - "ctrl PAGE_UP", "scrollUpChangeLead", - "PAGE_DOWN", "scrollDown", - "shift PAGE_DOWN", "scrollDownExtendSelection", - "ctrl shift PAGE_DOWN", "scrollDownExtendSelection", - "ctrl PAGE_DOWN", "scrollDownChangeLead", - "ctrl A", "selectAll", - "ctrl SLASH", "selectAll", - "ctrl BACK_SLASH", "clearSelection", - "SPACE", "addToSelection", - "ctrl SPACE", "toggleAndAnchor", - "shift SPACE", "extendTo", - "ctrl shift SPACE", "moveSelectionTo" - }), - - // PopupMenu - "PopupMenu.font", MenuFont, - "PopupMenu.background", MenuBackgroundColor, - "PopupMenu.foreground", MenuTextColor, - "PopupMenu.popupSound", "win.sound.menuPopup", - "PopupMenu.consumeEventOnClose", Boolean.TRUE, - - // Menus - "Menu.font", MenuFont, - "Menu.foreground", MenuTextColor, - "Menu.background", MenuBackgroundColor, - "Menu.useMenuBarBackgroundForTopLevel", Boolean.TRUE, - "Menu.selectionForeground", SelectionTextColor, - "Menu.selectionBackground", SelectionBackgroundColor, - "Menu.acceleratorForeground", MenuTextColor, - "Menu.acceleratorSelectionForeground", SelectionTextColor, - "Menu.menuPopupOffsetX", Integer.valueOf(0), - "Menu.menuPopupOffsetY", Integer.valueOf(0), - "Menu.submenuPopupOffsetX", Integer.valueOf(-4), - "Menu.submenuPopupOffsetY", Integer.valueOf(-3), - "Menu.crossMenuMnemonic", Boolean.FALSE, - "Menu.preserveTopLevelSelection", Boolean.TRUE, - - // MenuBar. - "MenuBar.font", MenuFont, - "MenuBar.background", new XPValue(MenuBarBackgroundColor, - MenuBackgroundColor), - "MenuBar.foreground", MenuTextColor, - "MenuBar.shadow", ControlShadowColor, - "MenuBar.highlight", ControlHighlightColor, - "MenuBar.height", menuBarHeight, - "MenuBar.rolloverEnabled", hotTrackingOn, - "MenuBar.windowBindings", new Object[] { - "F10", "takeFocus" }, - - "MenuItem.font", MenuFont, - "MenuItem.acceleratorFont", MenuFont, - "MenuItem.foreground", MenuTextColor, - "MenuItem.background", MenuBackgroundColor, - "MenuItem.selectionForeground", SelectionTextColor, - "MenuItem.selectionBackground", SelectionBackgroundColor, - "MenuItem.disabledForeground", InactiveTextColor, - "MenuItem.acceleratorForeground", MenuTextColor, - "MenuItem.acceleratorSelectionForeground", SelectionTextColor, - "MenuItem.acceleratorDelimiter", menuItemAcceleratorDelimiter, - // Menu Item Auditory Cue Mapping - "MenuItem.commandSound", "win.sound.menuCommand", - // indicates that keyboard navigation won't skip disabled menu items - "MenuItem.disabledAreNavigable", Boolean.TRUE, - - "RadioButton.font", ControlFont, - "RadioButton.interiorBackground", WindowBackgroundColor, - "RadioButton.background", ControlBackgroundColor, - "RadioButton.foreground", WindowTextColor, - "RadioButton.shadow", ControlShadowColor, - "RadioButton.darkShadow", ControlDarkShadowColor, - "RadioButton.light", ControlLightColor, - "RadioButton.highlight", ControlHighlightColor, - "RadioButton.focus", buttonFocusColor, - "RadioButton.focusInputMap", - new UIDefaults.LazyInputMap(new Object[] { - "SPACE", "pressed", - "released SPACE", "released" - }), - // margin is 2 all the way around, BasicBorders.RadioButtonBorder - // is 2 all the way around too. - "RadioButton.totalInsets", new Insets(4, 4, 4, 4), - - - "RadioButtonMenuItem.font", MenuFont, - "RadioButtonMenuItem.foreground", MenuTextColor, - "RadioButtonMenuItem.background", MenuBackgroundColor, - "RadioButtonMenuItem.selectionForeground", SelectionTextColor, - "RadioButtonMenuItem.selectionBackground", SelectionBackgroundColor, - "RadioButtonMenuItem.disabledForeground", InactiveTextColor, - "RadioButtonMenuItem.acceleratorForeground", MenuTextColor, - "RadioButtonMenuItem.acceleratorSelectionForeground", SelectionTextColor, - "RadioButtonMenuItem.commandSound", "win.sound.menuCommand", - - // OptionPane. - "OptionPane.font", MessageFont, - "OptionPane.messageFont", MessageFont, - "OptionPane.buttonFont", MessageFont, - "OptionPane.background", ControlBackgroundColor, - "OptionPane.foreground", WindowTextColor, - "OptionPane.buttonMinimumWidth", new XPDLUValue(50, 50, SwingConstants.EAST), - "OptionPane.messageForeground", ControlTextColor, - "OptionPane.errorIcon", new LazyWindowsIcon("optionPaneIcon Error", - "icons/Error.gif"), - "OptionPane.informationIcon", new LazyWindowsIcon("optionPaneIcon Information", - "icons/Inform.gif"), - "OptionPane.questionIcon", new LazyWindowsIcon("optionPaneIcon Question", - "icons/Question.gif"), - "OptionPane.warningIcon", new LazyWindowsIcon("optionPaneIcon Warning", - "icons/Warn.gif"), - "OptionPane.windowBindings", new Object[] { - "ESCAPE", "close" }, - // Option Pane Auditory Cue Mappings - "OptionPane.errorSound", "win.sound.hand", // Error - "OptionPane.informationSound", "win.sound.asterisk", // Info Plain - "OptionPane.questionSound", "win.sound.question", // Question - "OptionPane.warningSound", "win.sound.exclamation", // Warning - - "FormattedTextField.focusInputMap", - new UIDefaults.LazyInputMap(new Object[] { - "ctrl C", DefaultEditorKit.copyAction, - "ctrl V", DefaultEditorKit.pasteAction, - "ctrl X", DefaultEditorKit.cutAction, - "COPY", DefaultEditorKit.copyAction, - "PASTE", DefaultEditorKit.pasteAction, - "CUT", DefaultEditorKit.cutAction, - "control INSERT", DefaultEditorKit.copyAction, - "shift INSERT", DefaultEditorKit.pasteAction, - "shift DELETE", DefaultEditorKit.cutAction, - "shift LEFT", DefaultEditorKit.selectionBackwardAction, - "shift KP_LEFT", DefaultEditorKit.selectionBackwardAction, - "shift RIGHT", DefaultEditorKit.selectionForwardAction, - "shift KP_RIGHT", DefaultEditorKit.selectionForwardAction, - "ctrl LEFT", DefaultEditorKit.previousWordAction, - "ctrl KP_LEFT", DefaultEditorKit.previousWordAction, - "ctrl RIGHT", DefaultEditorKit.nextWordAction, - "ctrl KP_RIGHT", DefaultEditorKit.nextWordAction, - "ctrl shift LEFT", DefaultEditorKit.selectionPreviousWordAction, - "ctrl shift KP_LEFT", DefaultEditorKit.selectionPreviousWordAction, - "ctrl shift RIGHT", DefaultEditorKit.selectionNextWordAction, - "ctrl shift KP_RIGHT", DefaultEditorKit.selectionNextWordAction, - "ctrl A", DefaultEditorKit.selectAllAction, - "HOME", DefaultEditorKit.beginLineAction, - "END", DefaultEditorKit.endLineAction, - "shift HOME", DefaultEditorKit.selectionBeginLineAction, - "shift END", DefaultEditorKit.selectionEndLineAction, - "BACK_SPACE", DefaultEditorKit.deletePrevCharAction, - "shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction, - "ctrl H", DefaultEditorKit.deletePrevCharAction, - "DELETE", DefaultEditorKit.deleteNextCharAction, - "ctrl DELETE", DefaultEditorKit.deleteNextWordAction, - "ctrl BACK_SPACE", DefaultEditorKit.deletePrevWordAction, - "RIGHT", DefaultEditorKit.forwardAction, - "LEFT", DefaultEditorKit.backwardAction, - "KP_RIGHT", DefaultEditorKit.forwardAction, - "KP_LEFT", DefaultEditorKit.backwardAction, - "ENTER", JTextField.notifyAction, - "ctrl BACK_SLASH", "unselect", - "control shift O", "toggle-componentOrientation", - "ESCAPE", "reset-field-edit", - "UP", "increment", - "KP_UP", "increment", - "DOWN", "decrement", - "KP_DOWN", "decrement", - }), - "FormattedTextField.inactiveBackground", ReadOnlyTextBackground, - "FormattedTextField.disabledBackground", DisabledTextBackground, - "FormattedTextField.background", TextBackground, - "FormattedTextField.foreground", WindowTextColor, - - // *** Panel - "Panel.font", ControlFont, - "Panel.background", ControlBackgroundColor, - "Panel.foreground", WindowTextColor, - - // *** PasswordField - "PasswordField.font", ControlFont, - "PasswordField.background", TextBackground, - "PasswordField.foreground", WindowTextColor, - "PasswordField.inactiveForeground", InactiveTextColor, // for disabled - "PasswordField.inactiveBackground", ReadOnlyTextBackground, // for readonly - "PasswordField.disabledBackground", DisabledTextBackground, // for disabled - "PasswordField.selectionBackground", SelectionBackgroundColor, - "PasswordField.selectionForeground", SelectionTextColor, - "PasswordField.caretForeground",WindowTextColor, - "PasswordField.echoChar", new XPValue((char)0x25CF, '*'), - - // *** ProgressBar - "ProgressBar.font", ControlFont, - "ProgressBar.foreground", SelectionBackgroundColor, - "ProgressBar.background", ControlBackgroundColor, - "ProgressBar.shadow", ControlShadowColor, - "ProgressBar.highlight", ControlHighlightColor, - "ProgressBar.selectionForeground", ControlBackgroundColor, - "ProgressBar.selectionBackground", SelectionBackgroundColor, - "ProgressBar.cellLength", Integer.valueOf(7), - "ProgressBar.cellSpacing", Integer.valueOf(2), - "ProgressBar.indeterminateInsets", new Insets(3, 3, 3, 3), - - // *** RootPane. - // These bindings are only enabled when there is a default - // button set on the rootpane. - "RootPane.defaultButtonWindowKeyBindings", new Object[] { - "ENTER", "press", - "released ENTER", "release", - "ctrl ENTER", "press", - "ctrl released ENTER", "release" - }, - - // *** ScrollBar. - "ScrollBar.background", ScrollbarBackgroundColor, - "ScrollBar.foreground", ControlBackgroundColor, - "ScrollBar.track", white, - "ScrollBar.trackForeground", ScrollbarBackgroundColor, - "ScrollBar.trackHighlight", black, - "ScrollBar.trackHighlightForeground", scrollBarTrackHighlight, - "ScrollBar.thumb", ControlBackgroundColor, - "ScrollBar.thumbHighlight", ControlHighlightColor, - "ScrollBar.thumbDarkShadow", ControlDarkShadowColor, - "ScrollBar.thumbShadow", ControlShadowColor, - "ScrollBar.width", scrollBarWidth, - "ScrollBar.ancestorInputMap", - new UIDefaults.LazyInputMap(new Object[] { - "RIGHT", "positiveUnitIncrement", - "KP_RIGHT", "positiveUnitIncrement", - "DOWN", "positiveUnitIncrement", - "KP_DOWN", "positiveUnitIncrement", - "PAGE_DOWN", "positiveBlockIncrement", - "ctrl PAGE_DOWN", "positiveBlockIncrement", - "LEFT", "negativeUnitIncrement", - "KP_LEFT", "negativeUnitIncrement", - "UP", "negativeUnitIncrement", - "KP_UP", "negativeUnitIncrement", - "PAGE_UP", "negativeBlockIncrement", - "ctrl PAGE_UP", "negativeBlockIncrement", - "HOME", "minScroll", - "END", "maxScroll" - }), - - // *** ScrollPane. - "ScrollPane.font", ControlFont, - "ScrollPane.background", ControlBackgroundColor, - "ScrollPane.foreground", ControlTextColor, - "ScrollPane.ancestorInputMap", - new UIDefaults.LazyInputMap(new Object[] { - "RIGHT", "unitScrollRight", - "KP_RIGHT", "unitScrollRight", - "DOWN", "unitScrollDown", - "KP_DOWN", "unitScrollDown", - "LEFT", "unitScrollLeft", - "KP_LEFT", "unitScrollLeft", - "UP", "unitScrollUp", - "KP_UP", "unitScrollUp", - "PAGE_UP", "scrollUp", - "PAGE_DOWN", "scrollDown", - "ctrl PAGE_UP", "scrollLeft", - "ctrl PAGE_DOWN", "scrollRight", - "ctrl HOME", "scrollHome", - "ctrl END", "scrollEnd" - }), - - // *** Separator - "Separator.background", ControlHighlightColor, - "Separator.foreground", ControlShadowColor, - - // *** Slider. - "Slider.font", ControlFont, - "Slider.foreground", ControlBackgroundColor, - "Slider.background", ControlBackgroundColor, - "Slider.highlight", ControlHighlightColor, - "Slider.shadow", ControlShadowColor, - "Slider.focus", ControlDarkShadowColor, - "Slider.focusInputMap", - new UIDefaults.LazyInputMap(new Object[] { - "RIGHT", "positiveUnitIncrement", - "KP_RIGHT", "positiveUnitIncrement", - "DOWN", "negativeUnitIncrement", - "KP_DOWN", "negativeUnitIncrement", - "PAGE_DOWN", "negativeBlockIncrement", - "LEFT", "negativeUnitIncrement", - "KP_LEFT", "negativeUnitIncrement", - "UP", "positiveUnitIncrement", - "KP_UP", "positiveUnitIncrement", - "PAGE_UP", "positiveBlockIncrement", - "HOME", "minScroll", - "END", "maxScroll" - }), - - // Spinner - "Spinner.font", ControlFont, - "Spinner.ancestorInputMap", - new UIDefaults.LazyInputMap(new Object[] { - "UP", "increment", - "KP_UP", "increment", - "DOWN", "decrement", - "KP_DOWN", "decrement", - }), - - // *** SplitPane - "SplitPane.background", ControlBackgroundColor, - "SplitPane.highlight", ControlHighlightColor, - "SplitPane.shadow", ControlShadowColor, - "SplitPane.darkShadow", ControlDarkShadowColor, - "SplitPane.dividerSize", Integer.valueOf(5), - "SplitPane.ancestorInputMap", - new UIDefaults.LazyInputMap(new Object[] { - "UP", "negativeIncrement", - "DOWN", "positiveIncrement", - "LEFT", "negativeIncrement", - "RIGHT", "positiveIncrement", - "KP_UP", "negativeIncrement", - "KP_DOWN", "positiveIncrement", - "KP_LEFT", "negativeIncrement", - "KP_RIGHT", "positiveIncrement", - "HOME", "selectMin", - "END", "selectMax", - "F8", "startResize", - "F6", "toggleFocus", - "ctrl TAB", "focusOutForward", - "ctrl shift TAB", "focusOutBackward" - }), - - // *** TabbedPane - "TabbedPane.tabsOverlapBorder", new XPValue(Boolean.TRUE, Boolean.FALSE), - "TabbedPane.tabInsets", new XPValue(new InsetsUIResource(1, 4, 1, 4), - new InsetsUIResource(0, 4, 1, 4)), - "TabbedPane.tabAreaInsets", new XPValue(new InsetsUIResource(3, 2, 2, 2), - new InsetsUIResource(3, 2, 0, 2)), - "TabbedPane.font", ControlFont, - "TabbedPane.background", ControlBackgroundColor, - "TabbedPane.foreground", ControlTextColor, - "TabbedPane.highlight", ControlHighlightColor, - "TabbedPane.light", ControlLightColor, - "TabbedPane.shadow", ControlShadowColor, - "TabbedPane.darkShadow", ControlDarkShadowColor, - "TabbedPane.focus", ControlTextColor, - "TabbedPane.focusInputMap", - new UIDefaults.LazyInputMap(new Object[] { - "RIGHT", "navigateRight", - "KP_RIGHT", "navigateRight", - "LEFT", "navigateLeft", - "KP_LEFT", "navigateLeft", - "UP", "navigateUp", - "KP_UP", "navigateUp", - "DOWN", "navigateDown", - "KP_DOWN", "navigateDown", - "ctrl DOWN", "requestFocusForVisibleComponent", - "ctrl KP_DOWN", "requestFocusForVisibleComponent", - }), - "TabbedPane.ancestorInputMap", - new UIDefaults.LazyInputMap(new Object[] { - "ctrl TAB", "navigateNext", - "ctrl shift TAB", "navigatePrevious", - "ctrl PAGE_DOWN", "navigatePageDown", - "ctrl PAGE_UP", "navigatePageUp", - "ctrl UP", "requestFocus", - "ctrl KP_UP", "requestFocus", - }), - - // *** Table - "Table.font", ControlFont, - "Table.foreground", ControlTextColor, // cell text color - "Table.background", WindowBackgroundColor, // cell background color - "Table.highlight", ControlHighlightColor, - "Table.light", ControlLightColor, - "Table.shadow", ControlShadowColor, - "Table.darkShadow", ControlDarkShadowColor, - "Table.selectionForeground", SelectionTextColor, - "Table.selectionBackground", SelectionBackgroundColor, - "Table.gridColor", gray, // grid line color - "Table.focusCellBackground", WindowBackgroundColor, - "Table.focusCellForeground", ControlTextColor, - "Table.ancestorInputMap", - new UIDefaults.LazyInputMap(new Object[] { - "ctrl C", "copy", - "ctrl V", "paste", - "ctrl X", "cut", - "COPY", "copy", - "PASTE", "paste", - "CUT", "cut", - "control INSERT", "copy", - "shift INSERT", "paste", - "shift DELETE", "cut", - "RIGHT", "selectNextColumn", - "KP_RIGHT", "selectNextColumn", - "shift RIGHT", "selectNextColumnExtendSelection", - "shift KP_RIGHT", "selectNextColumnExtendSelection", - "ctrl shift RIGHT", "selectNextColumnExtendSelection", - "ctrl shift KP_RIGHT", "selectNextColumnExtendSelection", - "ctrl RIGHT", "selectNextColumnChangeLead", - "ctrl KP_RIGHT", "selectNextColumnChangeLead", - "LEFT", "selectPreviousColumn", - "KP_LEFT", "selectPreviousColumn", - "shift LEFT", "selectPreviousColumnExtendSelection", - "shift KP_LEFT", "selectPreviousColumnExtendSelection", - "ctrl shift LEFT", "selectPreviousColumnExtendSelection", - "ctrl shift KP_LEFT", "selectPreviousColumnExtendSelection", - "ctrl LEFT", "selectPreviousColumnChangeLead", - "ctrl KP_LEFT", "selectPreviousColumnChangeLead", - "DOWN", "selectNextRow", - "KP_DOWN", "selectNextRow", - "shift DOWN", "selectNextRowExtendSelection", - "shift KP_DOWN", "selectNextRowExtendSelection", - "ctrl shift DOWN", "selectNextRowExtendSelection", - "ctrl shift KP_DOWN", "selectNextRowExtendSelection", - "ctrl DOWN", "selectNextRowChangeLead", - "ctrl KP_DOWN", "selectNextRowChangeLead", - "UP", "selectPreviousRow", - "KP_UP", "selectPreviousRow", - "shift UP", "selectPreviousRowExtendSelection", - "shift KP_UP", "selectPreviousRowExtendSelection", - "ctrl shift UP", "selectPreviousRowExtendSelection", - "ctrl shift KP_UP", "selectPreviousRowExtendSelection", - "ctrl UP", "selectPreviousRowChangeLead", - "ctrl KP_UP", "selectPreviousRowChangeLead", - "HOME", "selectFirstColumn", - "shift HOME", "selectFirstColumnExtendSelection", - "ctrl shift HOME", "selectFirstRowExtendSelection", - "ctrl HOME", "selectFirstRow", - "END", "selectLastColumn", - "shift END", "selectLastColumnExtendSelection", - "ctrl shift END", "selectLastRowExtendSelection", - "ctrl END", "selectLastRow", - "PAGE_UP", "scrollUpChangeSelection", - "shift PAGE_UP", "scrollUpExtendSelection", - "ctrl shift PAGE_UP", "scrollLeftExtendSelection", - "ctrl PAGE_UP", "scrollLeftChangeSelection", - "PAGE_DOWN", "scrollDownChangeSelection", - "shift PAGE_DOWN", "scrollDownExtendSelection", - "ctrl shift PAGE_DOWN", "scrollRightExtendSelection", - "ctrl PAGE_DOWN", "scrollRightChangeSelection", - "TAB", "selectNextColumnCell", - "shift TAB", "selectPreviousColumnCell", - "ENTER", "selectNextRowCell", - "shift ENTER", "selectPreviousRowCell", - "ctrl A", "selectAll", - "ctrl SLASH", "selectAll", - "ctrl BACK_SLASH", "clearSelection", - "ESCAPE", "cancel", - "F2", "startEditing", - "SPACE", "addToSelection", - "ctrl SPACE", "toggleAndAnchor", - "shift SPACE", "extendTo", - "ctrl shift SPACE", "moveSelectionTo", - "F8", "focusHeader" - }), - "Table.sortIconHighlight", ControlShadowColor, - "Table.sortIconLight", white, - - "TableHeader.font", ControlFont, - "TableHeader.foreground", ControlTextColor, // header text color - "TableHeader.background", ControlBackgroundColor, // header background - "TableHeader.focusCellBackground", - new XPValue(XPValue.NULL_VALUE, // use default bg from XP styles - WindowBackgroundColor), // or white bg otherwise - - // *** TextArea - "TextArea.font", FixedControlFont, - "TextArea.background", WindowBackgroundColor, - "TextArea.foreground", WindowTextColor, - "TextArea.inactiveForeground", InactiveTextColor, - "TextArea.inactiveBackground", WindowBackgroundColor, - "TextArea.disabledBackground", DisabledTextBackground, - "TextArea.selectionBackground", SelectionBackgroundColor, - "TextArea.selectionForeground", SelectionTextColor, - "TextArea.caretForeground", WindowTextColor, - - // *** TextField - "TextField.font", ControlFont, - "TextField.background", TextBackground, - "TextField.foreground", WindowTextColor, - "TextField.shadow", ControlShadowColor, - "TextField.darkShadow", ControlDarkShadowColor, - "TextField.light", ControlLightColor, - "TextField.highlight", ControlHighlightColor, - "TextField.inactiveForeground", InactiveTextColor, // for disabled - "TextField.inactiveBackground", ReadOnlyTextBackground, // for readonly - "TextField.disabledBackground", DisabledTextBackground, // for disabled - "TextField.selectionBackground", SelectionBackgroundColor, - "TextField.selectionForeground", SelectionTextColor, - "TextField.caretForeground", WindowTextColor, - - // *** TextPane - "TextPane.font", ControlFont, - "TextPane.background", WindowBackgroundColor, - "TextPane.foreground", WindowTextColor, - "TextPane.selectionBackground", SelectionBackgroundColor, - "TextPane.selectionForeground", SelectionTextColor, - "TextPane.inactiveBackground", WindowBackgroundColor, - "TextPane.disabledBackground", DisabledTextBackground, - "TextPane.caretForeground", WindowTextColor, - - // *** TitledBorder - "TitledBorder.font", ControlFont, - "TitledBorder.titleColor", - new XPColorValue(Part.BP_GROUPBOX, null, Prop.TEXTCOLOR, - WindowTextColor), - - // *** ToggleButton - "ToggleButton.font", ControlFont, - "ToggleButton.background", ControlBackgroundColor, - "ToggleButton.foreground", ControlTextColor, - "ToggleButton.shadow", ControlShadowColor, - "ToggleButton.darkShadow", ControlDarkShadowColor, - "ToggleButton.light", ControlLightColor, - "ToggleButton.highlight", ControlHighlightColor, - "ToggleButton.focus", ControlTextColor, - "ToggleButton.textShiftOffset", Integer.valueOf(1), - "ToggleButton.focusInputMap", - new UIDefaults.LazyInputMap(new Object[] { - "SPACE", "pressed", - "released SPACE", "released" - }), - - // *** ToolBar - "ToolBar.font", MenuFont, - "ToolBar.background", ControlBackgroundColor, - "ToolBar.foreground", ControlTextColor, - "ToolBar.shadow", ControlShadowColor, - "ToolBar.darkShadow", ControlDarkShadowColor, - "ToolBar.light", ControlLightColor, - "ToolBar.highlight", ControlHighlightColor, - "ToolBar.dockingBackground", ControlBackgroundColor, - "ToolBar.dockingForeground", red, - "ToolBar.floatingBackground", ControlBackgroundColor, - "ToolBar.floatingForeground", darkGray, - "ToolBar.ancestorInputMap", - new UIDefaults.LazyInputMap(new Object[] { - "UP", "navigateUp", - "KP_UP", "navigateUp", - "DOWN", "navigateDown", - "KP_DOWN", "navigateDown", - "LEFT", "navigateLeft", - "KP_LEFT", "navigateLeft", - "RIGHT", "navigateRight", - "KP_RIGHT", "navigateRight" - }), - "ToolBar.separatorSize", null, - - // *** ToolTip - "ToolTip.font", ToolTipFont, - "ToolTip.background", new WindowsDesktopProperty("win.tooltip.backgroundColor", table.get("info")), - "ToolTip.foreground", new WindowsDesktopProperty("win.tooltip.textColor", table.get("infoText")), - - // *** ToolTipManager - "ToolTipManager.enableToolTipMode", "activeApplication", - - // *** Tree - "Tree.selectionBorderColor", black, - "Tree.drawDashedFocusIndicator", Boolean.TRUE, - "Tree.lineTypeDashed", Boolean.TRUE, - "Tree.font", ControlFont, - "Tree.background", WindowBackgroundColor, - "Tree.foreground", WindowTextColor, - "Tree.hash", gray, - "Tree.leftChildIndent", Integer.valueOf(8), - "Tree.rightChildIndent", Integer.valueOf(11), - "Tree.textForeground", WindowTextColor, - "Tree.textBackground", WindowBackgroundColor, - "Tree.selectionForeground", SelectionTextColor, - "Tree.selectionBackground", SelectionBackgroundColor, - "Tree.expandedIcon", treeExpandedIcon, - "Tree.collapsedIcon", treeCollapsedIcon, - "Tree.openIcon", new ActiveWindowsIcon("win.icon.shellIconBPP", - "shell32Icon 5", "icons/TreeOpen.gif"), - "Tree.closedIcon", new ActiveWindowsIcon("win.icon.shellIconBPP", - "shell32Icon 4", "icons/TreeClosed.gif"), - "Tree.focusInputMap", - new UIDefaults.LazyInputMap(new Object[] { - "ADD", "expand", - "SUBTRACT", "collapse", - "ctrl C", "copy", - "ctrl V", "paste", - "ctrl X", "cut", - "COPY", "copy", - "PASTE", "paste", - "CUT", "cut", - "control INSERT", "copy", - "shift INSERT", "paste", - "shift DELETE", "cut", - "UP", "selectPrevious", - "KP_UP", "selectPrevious", - "shift UP", "selectPreviousExtendSelection", - "shift KP_UP", "selectPreviousExtendSelection", - "ctrl shift UP", "selectPreviousExtendSelection", - "ctrl shift KP_UP", "selectPreviousExtendSelection", - "ctrl UP", "selectPreviousChangeLead", - "ctrl KP_UP", "selectPreviousChangeLead", - "DOWN", "selectNext", - "KP_DOWN", "selectNext", - "shift DOWN", "selectNextExtendSelection", - "shift KP_DOWN", "selectNextExtendSelection", - "ctrl shift DOWN", "selectNextExtendSelection", - "ctrl shift KP_DOWN", "selectNextExtendSelection", - "ctrl DOWN", "selectNextChangeLead", - "ctrl KP_DOWN", "selectNextChangeLead", - "RIGHT", "selectChild", - "KP_RIGHT", "selectChild", - "LEFT", "selectParent", - "KP_LEFT", "selectParent", - "PAGE_UP", "scrollUpChangeSelection", - "shift PAGE_UP", "scrollUpExtendSelection", - "ctrl shift PAGE_UP", "scrollUpExtendSelection", - "ctrl PAGE_UP", "scrollUpChangeLead", - "PAGE_DOWN", "scrollDownChangeSelection", - "shift PAGE_DOWN", "scrollDownExtendSelection", - "ctrl shift PAGE_DOWN", "scrollDownExtendSelection", - "ctrl PAGE_DOWN", "scrollDownChangeLead", - "HOME", "selectFirst", - "shift HOME", "selectFirstExtendSelection", - "ctrl shift HOME", "selectFirstExtendSelection", - "ctrl HOME", "selectFirstChangeLead", - "END", "selectLast", - "shift END", "selectLastExtendSelection", - "ctrl shift END", "selectLastExtendSelection", - "ctrl END", "selectLastChangeLead", - "F2", "startEditing", - "ctrl A", "selectAll", - "ctrl SLASH", "selectAll", - "ctrl BACK_SLASH", "clearSelection", - "ctrl LEFT", "scrollLeft", - "ctrl KP_LEFT", "scrollLeft", - "ctrl RIGHT", "scrollRight", - "ctrl KP_RIGHT", "scrollRight", - "SPACE", "addToSelection", - "ctrl SPACE", "toggleAndAnchor", - "shift SPACE", "extendTo", - "ctrl shift SPACE", "moveSelectionTo" - }), - "Tree.ancestorInputMap", - new UIDefaults.LazyInputMap(new Object[] { - "ESCAPE", "cancel" - }), - - // *** Viewport - "Viewport.font", ControlFont, - "Viewport.background", ControlBackgroundColor, - "Viewport.foreground", WindowTextColor, - - - }; - - table.putDefaults(defaults); - table.putDefaults(getLazyValueDefaults()); - initVistaComponentDefaults(table); - } - - static boolean isOnVista() { - return OSInfo.getOSType() == OSInfo.OSType.WINDOWS - && OSInfo.getWindowsVersion().compareTo(OSInfo.WINDOWS_VISTA) >= 0; - } - - static boolean isOnWindows7() { - return OSInfo.getOSType() == OSInfo.OSType.WINDOWS - && OSInfo.getWindowsVersion().compareTo(OSInfo.WINDOWS_7) >= 0; - } - - private void initVistaComponentDefaults(UIDefaults table) { - if (! isOnVista()) { - return; - } - /* START handling menus for Vista */ - String[] menuClasses = { "MenuItem", "Menu", - "CheckBoxMenuItem", "RadioButtonMenuItem", - }; - - Object menuDefaults[] = new Object[menuClasses.length * 2]; - - /* all the menus need to be non opaque. */ - for (int i = 0, j = 0; i < menuClasses.length; i++) { - String key = menuClasses[i] + ".opaque"; - Object oldValue = table.get(key); - menuDefaults[j++] = key; - menuDefaults[j++] = - new XPValue(Boolean.FALSE, oldValue); - } - table.putDefaults(menuDefaults); - - /* - * acceleratorSelectionForeground color is the same as - * acceleratorForeground - */ - for (int i = 0, j = 0; i < menuClasses.length; i++) { - String key = menuClasses[i] + ".acceleratorSelectionForeground"; - Object oldValue = table.get(key); - menuDefaults[j++] = key; - menuDefaults[j++] = - new XPValue( - table.getColor( - menuClasses[i] + ".acceleratorForeground"), - oldValue); - } - table.putDefaults(menuDefaults); - - /* they have the same MenuItemCheckIconFactory */ - VistaMenuItemCheckIconFactory menuItemCheckIconFactory = - WindowsIconFactory.getMenuItemCheckIconFactory(); - for (int i = 0, j = 0; i < menuClasses.length; i++) { - String key = menuClasses[i] + ".checkIconFactory"; - Object oldValue = table.get(key); - menuDefaults[j++] = key; - menuDefaults[j++] = - new XPValue(menuItemCheckIconFactory, oldValue); - } - table.putDefaults(menuDefaults); - - for (int i = 0, j = 0; i < menuClasses.length; i++) { - String key = menuClasses[i] + ".checkIcon"; - Object oldValue = table.get(key); - menuDefaults[j++] = key; - menuDefaults[j++] = - new XPValue(menuItemCheckIconFactory.getIcon(menuClasses[i]), - oldValue); - } - table.putDefaults(menuDefaults); - - - /* height can be even */ - for (int i = 0, j = 0; i < menuClasses.length; i++) { - String key = menuClasses[i] + ".evenHeight"; - Object oldValue = table.get(key); - menuDefaults[j++] = key; - menuDefaults[j++] = new XPValue(Boolean.TRUE, oldValue); - } - table.putDefaults(menuDefaults); - - /*For Windows7 margin and checkIconOffset should be greater than 0 */ - if (!isOnWindows7()) { - /* no margins */ - InsetsUIResource insets = new InsetsUIResource(0, 0, 0, 0); - for (int i = 0, j = 0; i < menuClasses.length; i++) { - String key = menuClasses[i] + ".margin"; - Object oldValue = table.get(key); - menuDefaults[j++] = key; - menuDefaults[j++] = new XPValue(insets, oldValue); - } - table.putDefaults(menuDefaults); - - /* set checkIcon offset */ - Integer checkIconOffsetInteger = - Integer.valueOf(0); - for (int i = 0, j = 0; i < menuClasses.length; i++) { - String key = menuClasses[i] + ".checkIconOffset"; - Object oldValue = table.get(key); - menuDefaults[j++] = key; - menuDefaults[j++] = - new XPValue(checkIconOffsetInteger, oldValue); - } - table.putDefaults(menuDefaults); - } - /* set width of the gap after check icon */ - Integer afterCheckIconGap = WindowsPopupMenuUI.getSpanBeforeGutter() - + WindowsPopupMenuUI.getGutterWidth() - + WindowsPopupMenuUI.getSpanAfterGutter(); - for (int i = 0, j = 0; i < menuClasses.length; i++) { - String key = menuClasses[i] + ".afterCheckIconGap"; - Object oldValue = table.get(key); - menuDefaults[j++] = key; - menuDefaults[j++] = - new XPValue(afterCheckIconGap, oldValue); - } - table.putDefaults(menuDefaults); - - /* text is started after this position */ - Object minimumTextOffset = new UIDefaults.ActiveValue() { - public Object createValue(UIDefaults table) { - return VistaMenuItemCheckIconFactory.getIconWidth() - + WindowsPopupMenuUI.getSpanBeforeGutter() - + WindowsPopupMenuUI.getGutterWidth() - + WindowsPopupMenuUI.getSpanAfterGutter(); - } - }; - for (int i = 0, j = 0; i < menuClasses.length; i++) { - String key = menuClasses[i] + ".minimumTextOffset"; - Object oldValue = table.get(key); - menuDefaults[j++] = key; - menuDefaults[j++] = new XPValue(minimumTextOffset, oldValue); - } - table.putDefaults(menuDefaults); - - /* - * JPopupMenu has a bit of free space around menu items - */ - String POPUP_MENU_BORDER = "PopupMenu.border"; - - Object popupMenuBorder = new XPBorderValue(Part.MENU, - (LazyValue) t -> BasicBorders.getInternalFrameBorder(), - BorderFactory.createEmptyBorder(2, 2, 2, 2)); - table.put(POPUP_MENU_BORDER, popupMenuBorder); - /* END handling menus for Vista */ - - /* START table handling for Vista */ - table.put("Table.ascendingSortIcon", new XPValue( - new SkinIcon(Part.HP_HEADERSORTARROW, State.SORTEDDOWN), - (LazyValue) t -> new ClassicSortArrowIcon(true))); - table.put("Table.descendingSortIcon", new XPValue( - new SkinIcon(Part.HP_HEADERSORTARROW, State.SORTEDUP), - (LazyValue) t -> new ClassicSortArrowIcon(false))); - /* END table handling for Vista */ - } - - /** - * If we support loading of fonts from the desktop this will return - * a WindowsDesktopProperty representing the font. If the font can't be - * represented in the current encoding this will return null and - * turn off the use of system fonts. - */ - private Object getDesktopFontValue(String fontName, Object backup) { - if (useSystemFontSettings) { - return new WindowsFontProperty(fontName, backup); - } - return null; - } - - // When a desktop property change is detected, these classes must be - // reinitialized in the defaults table to ensure the classes reference - // the updated desktop property values (colors mostly) - // - private Object[] getLazyValueDefaults() { - - Object buttonBorder = - new XPBorderValue(Part.BP_PUSHBUTTON, - (LazyValue) t -> BasicBorders.getButtonBorder()); - - Object textFieldBorder = - new XPBorderValue(Part.EP_EDIT, - (LazyValue) t -> BasicBorders.getTextFieldBorder()); - - Object textFieldMargin = - new XPValue(new InsetsUIResource(2, 2, 2, 2), - new InsetsUIResource(1, 1, 1, 1)); - - Object spinnerBorder = - new XPBorderValue(Part.EP_EDIT, textFieldBorder, - new EmptyBorder(2, 2, 2, 2)); - - Object spinnerArrowInsets = - new XPValue(new InsetsUIResource(1, 1, 1, 1), - null); - - Object comboBoxBorder = new XPBorderValue(Part.CP_COMBOBOX, textFieldBorder); - - // For focus rectangle for cells and trees. - LazyValue focusCellHighlightBorder = t -> WindowsBorders.getFocusCellHighlightBorder(); - - LazyValue etchedBorder = t -> BorderUIResource.getEtchedBorderUIResource(); - - LazyValue internalFrameBorder = t -> WindowsBorders.getInternalFrameBorder(); - - LazyValue loweredBevelBorder = t -> BorderUIResource.getLoweredBevelBorderUIResource(); - - - LazyValue marginBorder = t -> new BasicBorders.MarginBorder(); - - LazyValue menuBarBorder = t -> BasicBorders.getMenuBarBorder(); - - - Object popupMenuBorder = new XPBorderValue(Part.MENU, - (LazyValue) t -> BasicBorders.getInternalFrameBorder()); - - // *** ProgressBar - LazyValue progressBarBorder = t -> WindowsBorders.getProgressBarBorder(); - - LazyValue radioButtonBorder = t -> BasicBorders.getRadioButtonBorder(); - - Object scrollPaneBorder = - new XPBorderValue(Part.LBP_LISTBOX, textFieldBorder); - - Object tableScrollPaneBorder = - new XPBorderValue(Part.LBP_LISTBOX, loweredBevelBorder); - - LazyValue tableHeaderBorder = t -> WindowsBorders.getTableHeaderBorder(); - - // *** ToolBar - LazyValue toolBarBorder = t -> WindowsBorders.getToolBarBorder(); - - // *** ToolTips - LazyValue toolTipBorder = t -> BorderUIResource.getBlackLineBorderUIResource(); - - - - LazyValue checkBoxIcon = t -> WindowsIconFactory.getCheckBoxIcon(); - - LazyValue radioButtonIcon = t -> WindowsIconFactory.getRadioButtonIcon(); - - LazyValue radioButtonMenuItemIcon = t -> WindowsIconFactory.getRadioButtonMenuItemIcon(); - - LazyValue menuItemCheckIcon = t -> WindowsIconFactory.getMenuItemCheckIcon(); - - LazyValue menuItemArrowIcon = t -> WindowsIconFactory.getMenuItemArrowIcon(); - - LazyValue menuArrowIcon = t -> WindowsIconFactory.getMenuArrowIcon(); - - Color highlight = (Color) Toolkit.getDefaultToolkit(). - getDesktopProperty("win.3d.highlightColor"); - - Color shadow = (Color) Toolkit.getDefaultToolkit(). - getDesktopProperty("win.3d.shadowColor"); - - Object[] lazyDefaults = { - "Button.border", buttonBorder, - "CheckBox.border", radioButtonBorder, - "ComboBox.border", comboBoxBorder, - "DesktopIcon.border", internalFrameBorder, - "FormattedTextField.border", textFieldBorder, - "FormattedTextField.margin", textFieldMargin, - "InternalFrame.border", internalFrameBorder, - "List.focusCellHighlightBorder", focusCellHighlightBorder, - "Table.focusCellHighlightBorder", focusCellHighlightBorder, - "Menu.border", marginBorder, - "MenuBar.border", menuBarBorder, - "MenuItem.border", marginBorder, - "PasswordField.border", textFieldBorder, - "PasswordField.margin", textFieldMargin, - "PopupMenu.border", popupMenuBorder, - "ProgressBar.border", progressBarBorder, - "RadioButton.border", radioButtonBorder, - "ScrollPane.border", scrollPaneBorder, - "Spinner.border", spinnerBorder, - "Spinner.arrowButtonInsets", spinnerArrowInsets, - "Spinner.arrowButtonSize", new Dimension(17, 9), - "Table.scrollPaneBorder", tableScrollPaneBorder, - "TableHeader.cellBorder", tableHeaderBorder, - "TextArea.margin", textFieldMargin, - "TextField.border", textFieldBorder, - "TextField.margin", textFieldMargin, - "TitledBorder.border", new UIDefaults.LazyValue() { - public Object createValue(UIDefaults table) { - return new BorderUIResource. - EtchedBorderUIResource(highlight, shadow); - } - }, - "ToggleButton.border", radioButtonBorder, - "ToolBar.border", toolBarBorder, - "ToolTip.border", toolTipBorder, - - "CheckBox.icon", checkBoxIcon, - "Menu.arrowIcon", menuArrowIcon, - "MenuItem.checkIcon", menuItemCheckIcon, - "MenuItem.arrowIcon", menuItemArrowIcon, - "RadioButton.icon", radioButtonIcon, - "RadioButtonMenuItem.checkIcon", radioButtonMenuItemIcon, - "InternalFrame.layoutTitlePaneAtOrigin", - new XPValue(Boolean.TRUE, Boolean.FALSE), - "Table.ascendingSortIcon", new XPValue( - (LazyValue) t -> new SortArrowIcon(true,"Table.sortIconColor"), - (LazyValue) t -> new ClassicSortArrowIcon(true)), - "Table.descendingSortIcon", new XPValue( - (LazyValue) t -> new SortArrowIcon(false,"Table.sortIconColor"), - (LazyValue) t -> new ClassicSortArrowIcon(false)), - }; - - return lazyDefaults; - } - - public void uninitialize() { - super.uninitialize(); - - if (WindowsPopupMenuUI.mnemonicListener != null) { - MenuSelectionManager.defaultManager(). - removeChangeListener(WindowsPopupMenuUI.mnemonicListener); - } - KeyboardFocusManager.getCurrentKeyboardFocusManager(). - removeKeyEventPostProcessor(WindowsRootPaneUI.altProcessor); - WindowsDesktopProperty.flushUnreferencedProperties(); - } - - - // Toggle flag for drawing the mnemonic state - private static boolean isMnemonicHidden = true; - - // Flag which indicates that the Win98/Win2k/WinME features - // should be disabled. - private static boolean isClassicWindows = false; - - /** - * Sets the state of the hide mnemonic flag. This flag is used by the - * component UI delegates to determine if the mnemonic should be rendered. - * This method is a non operation if the underlying operating system - * does not support the mnemonic hiding feature. - * - * @param hide true if mnemonics should be hidden - * @since 1.4 - */ - public static void setMnemonicHidden(boolean hide) { - if (UIManager.getBoolean("Button.showMnemonics") == true) { - // Do not hide mnemonics if the UI defaults do not support this - isMnemonicHidden = false; - } else { - isMnemonicHidden = hide; - } - } - - /** - * Gets the state of the hide mnemonic flag. This only has meaning - * if this feature is supported by the underlying OS. - * - * @return true if mnemonics are hidden, otherwise, false - * @see #setMnemonicHidden - * @since 1.4 - */ - public static boolean isMnemonicHidden() { - if (UIManager.getBoolean("Button.showMnemonics") == true) { - // Do not hide mnemonics if the UI defaults do not support this - isMnemonicHidden = false; - } - return isMnemonicHidden; - } - - /** - * Gets the state of the flag which indicates if the old Windows - * look and feel should be rendered. This flag is used by the - * component UI delegates as a hint to determine which style the component - * should be rendered. - * - * @return true if Windows 95 and Windows NT 4 look and feel should - * be rendered - * @since 1.4 - */ - public static boolean isClassicWindows() { - return isClassicWindows; - } - - /** - *

    - * Invoked when the user attempts an invalid operation, - * such as pasting into an uneditable JTextField - * that has focus. - *

    - *

    - * If the user has enabled visual error indication on - * the desktop, this method will flash the caption bar - * of the active window. The user can also set the - * property awt.visualbell=true to achieve the same - * results. - *

    - * - * @param component Component the error occurred in, may be - * null indicating the error condition is - * not directly associated with a - * Component. - * - * @see javax.swing.LookAndFeel#provideErrorFeedback - */ - public void provideErrorFeedback(Component component) { - super.provideErrorFeedback(component); - } - - /** - * {@inheritDoc} - */ - public LayoutStyle getLayoutStyle() { - LayoutStyle style = this.style; - if (style == null) { - style = new WindowsLayoutStyle(); - this.style = style; - } - return style; - } - - // ********* Auditory Cue support methods and objects ********* - - /** - * Returns an Action. - *

    - * This Action contains the information and logic to render an - * auditory cue. The Object that is passed to this - * method contains the information needed to render the auditory - * cue. Normally, this Object is a String - * that points to a Toolkit desktopProperty. - * This desktopProperty is resolved by AWT and the - * Windows OS. - *

    - * This Action's actionPerformed method - * is fired by the playSound method. - * - * @return an Action which knows how to render the auditory - * cue for one particular system or user activity - * @see #playSound(Action) - * @since 1.4 - */ - protected Action createAudioAction(Object key) { - if (key != null) { - String audioKey = (String)key; - String audioValue = (String)UIManager.get(key); - return new AudioAction(audioKey, audioValue); - } else { - return null; - } - } - - static void repaintRootPane(Component c) { - JRootPane root = null; - for (; c != null; c = c.getParent()) { - if (c instanceof JRootPane) { - root = (JRootPane)c; - } - } - - if (root != null) { - root.repaint(); - } else { - c.repaint(); - } - } - - /** - * Pass the name String to the super constructor. This is used - * later to identify the Action and decide whether to play it or - * not. Store the resource String. It is used to get the audio - * resource. In this case, the resource is a Runnable - * supplied by Toolkit. This Runnable is - * effectively a pointer down into the Win32 OS that knows how to - * play the right sound. - * - * @since 1.4 - */ - @SuppressWarnings("serial") // Superclass is not serializable across versions - private static class AudioAction extends AbstractAction { - private Runnable audioRunnable; - private String audioResource; - /** - * We use the String as the name of the Action and as a pointer to - * the underlying OSes audio resource. - */ - public AudioAction(String name, String resource) { - super(name); - audioResource = resource; - } - public void actionPerformed(ActionEvent e) { - if (audioRunnable == null) { - audioRunnable = (Runnable)Toolkit.getDefaultToolkit().getDesktopProperty(audioResource); - } - if (audioRunnable != null) { - // Runnable appears to block until completed playing, hence - // start up another thread to handle playing. - new Thread(null, audioRunnable, "Audio", 0, false).start(); - } - } - } - - /** - * Gets an Icon from the native libraries if available, - * otherwise gets it from an image resource file. - */ - private static class LazyWindowsIcon implements UIDefaults.LazyValue { - private String nativeImage; - private String resource; - - LazyWindowsIcon(String nativeImage, String resource) { - this.nativeImage = nativeImage; - this.resource = resource; - } - - public Object createValue(UIDefaults table) { - if (nativeImage != null) { - Image image = (Image)ShellFolder.get(nativeImage); - if (image != null) { - return new ImageIcon(image); - } - } - return SwingUtilities2.makeIcon(getClass(), - WindowsLookAndFeel.class, - resource); - } - } - - - /** - * Gets an Icon from the native libraries if available. - * A desktop property is used to trigger reloading the icon when needed. - */ - private class ActiveWindowsIcon implements UIDefaults.ActiveValue { - private Icon icon; - private String nativeImageName; - private String fallbackName; - private WindowsDesktopProperty desktopProperty; - - ActiveWindowsIcon(String desktopPropertyName, - String nativeImageName, String fallbackName) { - this.nativeImageName = nativeImageName; - this.fallbackName = fallbackName; - - if (OSInfo.getOSType() == OSInfo.OSType.WINDOWS && - OSInfo.getWindowsVersion().compareTo(OSInfo.WINDOWS_XP) < 0) { - // This desktop property is needed to trigger reloading the icon. - // It is kept in member variable to avoid GC. - this.desktopProperty = new TriggerDesktopProperty(desktopPropertyName) { - @Override protected void updateUI() { - icon = null; - super.updateUI(); - } - }; - } - } - - @Override - public Object createValue(UIDefaults table) { - if (icon == null) { - Image image = (Image)ShellFolder.get(nativeImageName); - if (image != null) { - icon = new ImageIconUIResource(image); - } - } - if (icon == null && fallbackName != null) { - UIDefaults.LazyValue fallback = (UIDefaults.LazyValue) - SwingUtilities2.makeIcon(WindowsLookAndFeel.class, - BasicLookAndFeel.class, fallbackName); - icon = (Icon) fallback.createValue(table); - } - return icon; - } - } - - /** - * Icon backed-up by XP Skin. - */ - private static class SkinIcon implements Icon, UIResource { - private final Part part; - private final State state; - SkinIcon(Part part, State state) { - this.part = part; - this.state = state; - } - - /** - * Draw the icon at the specified location. Icon implementations - * may use the Component argument to get properties useful for - * painting, e.g. the foreground or background color. - */ - public void paintIcon(Component c, Graphics g, int x, int y) { - XPStyle xp = XPStyle.getXP(); - assert xp != null; - if (xp != null) { - Skin skin = xp.getSkin(null, part); - skin.paintSkin(g, x, y, state); - } - } - - /** - * Returns the icon's width. - * - * @return an int specifying the fixed width of the icon. - */ - public int getIconWidth() { - int width = 0; - XPStyle xp = XPStyle.getXP(); - assert xp != null; - if (xp != null) { - Skin skin = xp.getSkin(null, part); - width = skin.getWidth(); - } - return width; - } - - /** - * Returns the icon's height. - * - * @return an int specifying the fixed height of the icon. - */ - public int getIconHeight() { - int height = 0; - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - Skin skin = xp.getSkin(null, part); - height = skin.getHeight(); - } - return height; - } - - } - - /** - * WindowsDesktopProperty for fonts. If a font with the name 'MS Sans Serif' - * is returned, it is mapped to 'Microsoft Sans Serif'. - */ - private static class WindowsFontProperty extends WindowsDesktopProperty { - WindowsFontProperty(String key, Object backup) { - super(key, backup); - } - - public void invalidate(LookAndFeel laf) { - if ("win.defaultGUI.font.height".equals(getKey())) { - ((WindowsLookAndFeel)laf).style = null; - } - super.invalidate(laf); - } - - protected Object configureValue(Object value) { - if (value instanceof Font) { - Font font = (Font)value; - if ("MS Sans Serif".equals(font.getName())) { - int size = font.getSize(); - // 4950968: Workaround to mimic the way Windows maps the default - // font size of 6 pts to the smallest available bitmap font size. - // This happens mostly on Win 98/Me & NT. - int dpi; - try { - dpi = Toolkit.getDefaultToolkit().getScreenResolution(); - } catch (HeadlessException ex) { - dpi = 96; - } - if (Math.round(size * 72F / dpi) < 8) { - size = Math.round(8 * dpi / 72F); - } - Font msFont = new FontUIResource("Microsoft Sans Serif", - font.getStyle(), size); - if (msFont.getName() != null && - msFont.getName().equals(msFont.getFamily())) { - font = msFont; - } else if (size != font.getSize()) { - font = new FontUIResource("MS Sans Serif", - font.getStyle(), size); - } - } - - if (FontUtilities.fontSupportsDefaultEncoding(font)) { - if (!(font instanceof UIResource)) { - font = new FontUIResource(font); - } - } - else { - font = FontUtilities.getCompositeFontUIResource(font); - } - return font; - - } - return super.configureValue(value); - } - } - - - /** - * WindowsDesktopProperty for fonts that only gets sizes from the desktop, - * font name and style are passed into the constructor - */ - private static class WindowsFontSizeProperty extends - WindowsDesktopProperty { - private String fontName; - private int fontSize; - private int fontStyle; - - WindowsFontSizeProperty(String key, String fontName, - int fontStyle, int fontSize) { - super(key, null); - this.fontName = fontName; - this.fontSize = fontSize; - this.fontStyle = fontStyle; - } - - protected Object configureValue(Object value) { - if (value == null) { - value = new FontUIResource(fontName, fontStyle, fontSize); - } - else if (value instanceof Integer) { - value = new FontUIResource(fontName, fontStyle, - ((Integer)value).intValue()); - } - return value; - } - } - - - /** - * A value wrapper that actively retrieves values from xp or falls back - * to the classic value if not running XP styles. - */ - private static class XPValue implements UIDefaults.ActiveValue { - protected Object classicValue, xpValue; - - // A constant that lets you specify null when using XP styles. - private static final Object NULL_VALUE = new Object(); - - XPValue(Object xpValue, Object classicValue) { - this.xpValue = xpValue; - this.classicValue = classicValue; - } - - public Object createValue(UIDefaults table) { - Object value = null; - if (XPStyle.getXP() != null) { - value = getXPValue(table); - } - - if (value == null) { - value = getClassicValue(table); - } else if (value == NULL_VALUE) { - value = null; - } - - return value; - } - - protected Object getXPValue(UIDefaults table) { - return recursiveCreateValue(xpValue, table); - } - - protected Object getClassicValue(UIDefaults table) { - return recursiveCreateValue(classicValue, table); - } - - private Object recursiveCreateValue(Object value, UIDefaults table) { - if (value instanceof UIDefaults.LazyValue) { - value = ((UIDefaults.LazyValue)value).createValue(table); - } - if (value instanceof UIDefaults.ActiveValue) { - return ((UIDefaults.ActiveValue)value).createValue(table); - } else { - return value; - } - } - } - - private static class XPBorderValue extends XPValue { - private final Border extraMargin; - - XPBorderValue(Part xpValue, Object classicValue) { - this(xpValue, classicValue, null); - } - - XPBorderValue(Part xpValue, Object classicValue, Border extraMargin) { - super(xpValue, classicValue); - this.extraMargin = extraMargin; - } - - public Object getXPValue(UIDefaults table) { - XPStyle xp = XPStyle.getXP(); - Border xpBorder = xp != null ? xp.getBorder(null, (Part)xpValue) : null; - if (xpBorder != null && extraMargin != null) { - return new BorderUIResource. - CompoundBorderUIResource(xpBorder, extraMargin); - } else { - return xpBorder; - } - } - } - - private static class XPColorValue extends XPValue { - XPColorValue(Part part, State state, Prop prop, Object classicValue) { - super(new XPColorValueKey(part, state, prop), classicValue); - } - - public Object getXPValue(UIDefaults table) { - XPColorValueKey key = (XPColorValueKey)xpValue; - XPStyle xp = XPStyle.getXP(); - return xp != null ? xp.getColor(key.skin, key.prop, null) : null; - } - - private static class XPColorValueKey { - Skin skin; - Prop prop; - - XPColorValueKey(Part part, State state, Prop prop) { - this.skin = new Skin(part, state); - this.prop = prop; - } - } - } - - private class XPDLUValue extends XPValue { - private int direction; - - XPDLUValue(int xpdlu, int classicdlu, int direction) { - super(Integer.valueOf(xpdlu), Integer.valueOf(classicdlu)); - this.direction = direction; - } - - public Object getXPValue(UIDefaults table) { - int px = dluToPixels(((Integer)xpValue).intValue(), direction); - return Integer.valueOf(px); - } - - public Object getClassicValue(UIDefaults table) { - int px = dluToPixels(((Integer)classicValue).intValue(), direction); - return Integer.valueOf(px); - } - } - - private class TriggerDesktopProperty extends WindowsDesktopProperty { - TriggerDesktopProperty(String key) { - super(key, null); - // This call adds a property change listener for the property, - // which triggers a call to updateUI(). The value returned - // is not interesting here. - getValueFromDesktop(); - } - - protected void updateUI() { - super.updateUI(); - - // Make sure property change listener is readded each time - getValueFromDesktop(); - } - } - - private class FontDesktopProperty extends TriggerDesktopProperty { - FontDesktopProperty(String key) { - super(key); - } - - protected void updateUI() { - UIDefaults defaults = UIManager.getLookAndFeelDefaults(); - SwingUtilities2.putAATextInfo(true, defaults); - super.updateUI(); - } - } - - // Windows LayoutStyle. From: - // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwue/html/ch14e.asp - @SuppressWarnings("fallthrough") - private class WindowsLayoutStyle extends DefaultLayoutStyle { - @Override - public int getPreferredGap(JComponent component1, - JComponent component2, ComponentPlacement type, int position, - Container parent) { - // Checks args - super.getPreferredGap(component1, component2, type, position, - parent); - - switch(type) { - case INDENT: - // Windows doesn't spec this - if (position == SwingConstants.EAST || - position == SwingConstants.WEST) { - int indent = getIndent(component1, position); - if (indent > 0) { - return indent; - } - return 10; - } - // Fall through to related. - case RELATED: - if (isLabelAndNonlabel(component1, component2, position)) { - // Between text labels and their associated controls (for - // example, text boxes and list boxes): 3 - // NOTE: We're not honoring: - // 'Text label beside a button 3 down from the top of - // the button,' but I suspect that is an attempt to - // enforce a baseline layout which will be handled - // separately. In order to enforce this we would need - // this API to return a more complicated type (Insets, - // or something else). - return getButtonGap(component1, component2, position, - dluToPixels(3, position)); - } - // Between related controls: 4 - return getButtonGap(component1, component2, position, - dluToPixels(4, position)); - case UNRELATED: - // Between unrelated controls: 7 - return getButtonGap(component1, component2, position, - dluToPixels(7, position)); - } - return 0; - } - - @Override - public int getContainerGap(JComponent component, int position, - Container parent) { - // Checks args - super.getContainerGap(component, position, parent); - return getButtonGap(component, position, dluToPixels(7, position)); - } - - } - - /** - * Converts the dialog unit argument to pixels along the specified - * axis. - */ - private int dluToPixels(int dlu, int direction) { - if (baseUnitX == 0) { - calculateBaseUnits(); - } - if (direction == SwingConstants.EAST || - direction == SwingConstants.WEST) { - return dlu * baseUnitX / 4; - } - assert (direction == SwingConstants.NORTH || - direction == SwingConstants.SOUTH); - return dlu * baseUnitY / 8; - } - - /** - * Calculates the dialog unit mapping. - */ - @SuppressWarnings("deprecation") - private void calculateBaseUnits() { - // This calculation comes from: - // http://support.microsoft.com/default.aspx?scid=kb;EN-US;125681 - FontMetrics metrics = Toolkit.getDefaultToolkit().getFontMetrics( - UIManager.getFont("Button.font")); - baseUnitX = metrics.stringWidth( - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); - baseUnitX = (baseUnitX / 26 + 1) / 2; - // The -1 comes from experimentation. - baseUnitY = metrics.getAscent() + metrics.getDescent() - 1; - } - - /** - * {@inheritDoc} - * - * @since 1.6 - */ - public Icon getDisabledIcon(JComponent component, Icon icon) { - // if the component has a HI_RES_DISABLED_ICON_CLIENT_KEY - // client property set to Boolean.TRUE, then use the new - // hi res algorithm for creating the disabled icon (used - // in particular by the WindowsFileChooserUI class) - if (icon != null - && component != null - && Boolean.TRUE.equals(component.getClientProperty(HI_RES_DISABLED_ICON_CLIENT_KEY)) - && icon.getIconWidth() > 0 - && icon.getIconHeight() > 0) { - BufferedImage img = new BufferedImage(icon.getIconWidth(), - icon.getIconWidth(), BufferedImage.TYPE_INT_ARGB); - icon.paintIcon(component, img.getGraphics(), 0, 0); - ImageFilter filter = new RGBGrayFilter(); - ImageProducer producer = new FilteredImageSource(img.getSource(), filter); - Image resultImage = component.createImage(producer); - return new ImageIconUIResource(resultImage); - } - return super.getDisabledIcon(component, icon); - } - - private static class RGBGrayFilter extends RGBImageFilter { - public RGBGrayFilter() { - canFilterIndexColorModel = true; - } - public int filterRGB(int x, int y, int rgb) { - // find the average of red, green, and blue - float avg = (((rgb >> 16) & 0xff) / 255f + - ((rgb >> 8) & 0xff) / 255f + - (rgb & 0xff) / 255f) / 3; - // pull out the alpha channel - float alpha = (((rgb>>24)&0xff)/255f); - // calc the average - avg = Math.min(1.0f, (1f-avg)/(100.0f/35.0f) + avg); - // turn back into rgb - int rgbval = (int)(alpha * 255f) << 24 | - (int)(avg * 255f) << 16 | - (int)(avg * 255f) << 8 | - (int)(avg * 255f); - return rgbval; - } - } - - private static class FocusColorProperty extends WindowsDesktopProperty { - public FocusColorProperty () { - // Fallback value is never used because of the configureValue method doesn't return null - super("win.3d.backgroundColor", Color.BLACK); - } - - @Override - protected Object configureValue(Object value) { - Object highContrastOn = Toolkit.getDefaultToolkit(). - getDesktopProperty("win.highContrast.on"); - if (highContrastOn == null || !((Boolean) highContrastOn).booleanValue()) { - return Color.BLACK; - } - return Color.BLACK.equals(value) ? Color.WHITE : Color.BLACK; - } - } - -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsMenuBarUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsMenuBarUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,187 +0,0 @@ -/* - * Copyright (c) 1997, 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 com.sun.java.swing.plaf.windows; - -import javax.swing.plaf.basic.*; -import javax.swing.*; -import javax.swing.plaf.ActionMapUIResource; -import javax.swing.plaf.ComponentUI; -import java.awt.event.ActionEvent; -import java.awt.event.HierarchyEvent; -import java.awt.event.HierarchyListener; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.awt.event.WindowListener; -import java.awt.event.WindowStateListener; - -import java.awt.*; - -import com.sun.java.swing.plaf.windows.TMSchema.*; -import com.sun.java.swing.plaf.windows.XPStyle.*; - -/** - * Windows rendition of the component. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - */ -public class WindowsMenuBarUI extends BasicMenuBarUI -{ - /* to be accessed on the EDT only */ - private WindowListener windowListener = null; - private HierarchyListener hierarchyListener = null; - private Window window = null; - - public static ComponentUI createUI(JComponent x) { - return new WindowsMenuBarUI(); - } - - @Override - protected void uninstallListeners() { - uninstallWindowListener(); - if (hierarchyListener != null) { - menuBar.removeHierarchyListener(hierarchyListener); - hierarchyListener = null; - } - super.uninstallListeners(); - } - private void installWindowListener() { - if (windowListener == null) { - Component component = menuBar.getTopLevelAncestor(); - if (component instanceof Window) { - window = (Window) component; - windowListener = new WindowAdapter() { - @Override - public void windowActivated(WindowEvent e) { - menuBar.repaint(); - } - @Override - public void windowDeactivated(WindowEvent e) { - menuBar.repaint(); - } - }; - ((Window) component).addWindowListener(windowListener); - } - } - } - private void uninstallWindowListener() { - if (windowListener != null && window != null) { - window.removeWindowListener(windowListener); - } - window = null; - windowListener = null; - } - @Override - protected void installListeners() { - if (WindowsLookAndFeel.isOnVista()) { - installWindowListener(); - hierarchyListener = - new HierarchyListener() { - public void hierarchyChanged(HierarchyEvent e) { - if ((e.getChangeFlags() - & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) { - if (menuBar.isDisplayable()) { - installWindowListener(); - } else { - uninstallWindowListener(); - } - } - } - }; - menuBar.addHierarchyListener(hierarchyListener); - } - super.installListeners(); - } - - protected void installKeyboardActions() { - super.installKeyboardActions(); - ActionMap map = SwingUtilities.getUIActionMap(menuBar); - if (map == null) { - map = new ActionMapUIResource(); - SwingUtilities.replaceUIActionMap(menuBar, map); - } - map.put("takeFocus", new TakeFocus()); - } - - /** - * Action that activates the menu (e.g. when F10 is pressed). - * Unlike BasicMenuBarUI.TakeFocus, this Action will not show menu popup. - */ - @SuppressWarnings("serial") // Superclass is not serializable across versions - private static class TakeFocus extends AbstractAction { - public void actionPerformed(ActionEvent e) { - JMenuBar menuBar = (JMenuBar)e.getSource(); - JMenu menu = menuBar.getMenu(0); - if (menu != null) { - MenuSelectionManager msm = - MenuSelectionManager.defaultManager(); - MenuElement path[] = new MenuElement[2]; - path[0] = (MenuElement)menuBar; - path[1] = (MenuElement)menu; - msm.setSelectedPath(path); - - // show mnemonics - WindowsLookAndFeel.setMnemonicHidden(false); - WindowsLookAndFeel.repaintRootPane(menuBar); - } - } - } - - @Override - public void paint(Graphics g, JComponent c) { - XPStyle xp = XPStyle.getXP(); - if (WindowsMenuItemUI.isVistaPainting(xp)) { - Skin skin; - skin = xp.getSkin(c, Part.MP_BARBACKGROUND); - int width = c.getWidth(); - int height = c.getHeight(); - State state = isActive(c) ? State.ACTIVE : State.INACTIVE; - skin.paintSkin(g, 0, 0, width, height, state); - } else { - super.paint(g, c); - } - } - - /** - * Checks if component belongs to an active window. - * @param c component to check - * @return true if component belongs to an active window - */ - static boolean isActive(JComponent c) { - JRootPane rootPane = c.getRootPane(); - if (rootPane != null) { - Component component = rootPane.getParent(); - if (component instanceof Window) { - return ((Window) component).isActive(); - } - } - return true; - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsMenuItemUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsMenuItemUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,180 +0,0 @@ -/* - * Copyright (c) 1997, 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 com.sun.java.swing.plaf.windows; - -import java.awt.*; -import javax.swing.*; -import javax.swing.plaf.*; -import javax.swing.plaf.basic.*; - -import sun.swing.SwingUtilities2; - -import com.sun.java.swing.plaf.windows.TMSchema.*; -import com.sun.java.swing.plaf.windows.XPStyle.*; - -/** - * Windows rendition of the component. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - * - * @author Igor Kushnirskiy - */ - -public class WindowsMenuItemUI extends BasicMenuItemUI { - final WindowsMenuItemUIAccessor accessor = - new WindowsMenuItemUIAccessor() { - - public JMenuItem getMenuItem() { - return menuItem; - } - - public State getState(JMenuItem menuItem) { - return WindowsMenuItemUI.getState(this, menuItem); - } - - public Part getPart(JMenuItem menuItem) { - return WindowsMenuItemUI.getPart(this, menuItem); - } - }; - public static ComponentUI createUI(JComponent c) { - return new WindowsMenuItemUI(); - } - - /** - * Method which renders the text of the current menu item. - * - * @param g Graphics context - * @param menuItem Current menu item to render - * @param textRect Bounding rectangle to render the text. - * @param text String to render - */ - protected void paintText(Graphics g, JMenuItem menuItem, - Rectangle textRect, String text) { - if (WindowsMenuItemUI.isVistaPainting()) { - WindowsMenuItemUI.paintText(accessor, g, menuItem, textRect, text); - return; - } - ButtonModel model = menuItem.getModel(); - Color oldColor = g.getColor(); - - if(model.isEnabled() && - (model.isArmed() || (menuItem instanceof JMenu && - model.isSelected()))) { - g.setColor(selectionForeground); // Uses protected field. - } - - WindowsGraphicsUtils.paintText(g, menuItem, textRect, text, 0); - - g.setColor(oldColor); - } - - @Override - protected void paintBackground(Graphics g, JMenuItem menuItem, - Color bgColor) { - if (WindowsMenuItemUI.isVistaPainting()) { - WindowsMenuItemUI.paintBackground(accessor, g, menuItem, bgColor); - return; - } - super.paintBackground(g, menuItem, bgColor); - } - - static void paintBackground(WindowsMenuItemUIAccessor menuItemUI, - Graphics g, JMenuItem menuItem, Color bgColor) { - XPStyle xp = XPStyle.getXP(); - assert isVistaPainting(xp); - if (isVistaPainting(xp)) { - int menuWidth = menuItem.getWidth(); - int menuHeight = menuItem.getHeight(); - if (menuItem.isOpaque()) { - Color oldColor = g.getColor(); - g.setColor(menuItem.getBackground()); - g.fillRect(0,0, menuWidth, menuHeight); - g.setColor(oldColor); - } - Part part = menuItemUI.getPart(menuItem); - Skin skin = xp.getSkin(menuItem, part); - skin.paintSkin(g, 0 , 0, - menuWidth, - menuHeight, - menuItemUI.getState(menuItem)); - } - } - - static void paintText(WindowsMenuItemUIAccessor menuItemUI, Graphics g, - JMenuItem menuItem, Rectangle textRect, - String text) { - assert isVistaPainting(); - if (isVistaPainting()) { - State state = menuItemUI.getState(menuItem); - - /* part of it copied from WindowsGraphicsUtils.java */ - FontMetrics fm = SwingUtilities2.getFontMetrics(menuItem, g); - int mnemIndex = menuItem.getDisplayedMnemonicIndex(); - // W2K Feature: Check to see if the Underscore should be rendered. - if (WindowsLookAndFeel.isMnemonicHidden() == true) { - mnemIndex = -1; - } - WindowsGraphicsUtils.paintXPText(menuItem, - menuItemUI.getPart(menuItem), state, - g, textRect.x, - textRect.y + fm.getAscent(), - text, mnemIndex); - } - } - - static State getState(WindowsMenuItemUIAccessor menuItemUI, JMenuItem menuItem) { - State state; - ButtonModel model = menuItem.getModel(); - if (model.isArmed()) { - state = (model.isEnabled()) ? State.HOT : State.DISABLEDHOT; - } else { - state = (model.isEnabled()) ? State.NORMAL : State.DISABLED; - } - return state; - } - - static Part getPart(WindowsMenuItemUIAccessor menuItemUI, JMenuItem menuItem) { - return Part.MP_POPUPITEM; - } - - /* - * TODO idk can we use XPStyle.isVista? - * is it possible that in some theme some Vista parts are not defined while - * others are? - */ - static boolean isVistaPainting(final XPStyle xp) { - return xp != null && xp.isSkinDefined(null, Part.MP_POPUPITEM); - } - - static boolean isVistaPainting() { - return isVistaPainting(XPStyle.getXP()); - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsMenuItemUIAccessor.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsMenuItemUIAccessor.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2006, 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 com.sun.java.swing.plaf.windows; - -import java.awt.Color; -import java.awt.Graphics; - -import javax.swing.JMenuItem; - -import com.sun.java.swing.plaf.windows.TMSchema.Part; -import com.sun.java.swing.plaf.windows.TMSchema.State; - -/** - * Accessor interface for WindowsMenuItemUI to allow for "multiple implementation - * inheritance". - * - * @author Igor Kushnirskiy - */ -interface WindowsMenuItemUIAccessor { - JMenuItem getMenuItem(); - State getState(JMenuItem menuItem); - Part getPart(JMenuItem menuItem); -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsMenuUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsMenuUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,295 +0,0 @@ -/* - * Copyright (c) 1997, 2007, 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 com.sun.java.swing.plaf.windows; - -import java.awt.*; -import java.awt.event.MouseEvent; - -import javax.swing.plaf.ComponentUI; -import javax.swing.plaf.basic.BasicMenuUI; -import javax.swing.event.MouseInputListener; -import javax.swing.*; - -import com.sun.java.swing.plaf.windows.TMSchema.Part; -import com.sun.java.swing.plaf.windows.TMSchema.State; - -/** - * Windows rendition of the component. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - */ -public class WindowsMenuUI extends BasicMenuUI { - protected Integer menuBarHeight; - protected boolean hotTrackingOn; - - final WindowsMenuItemUIAccessor accessor = - new WindowsMenuItemUIAccessor() { - - public JMenuItem getMenuItem() { - return menuItem; - } - - public State getState(JMenuItem menu) { - State state = menu.isEnabled() ? State.NORMAL - : State.DISABLED; - ButtonModel model = menu.getModel(); - if (model.isArmed() || model.isSelected()) { - state = (menu.isEnabled()) ? State.PUSHED - : State.DISABLEDPUSHED; - } else if (model.isRollover() - && ((JMenu) menu).isTopLevelMenu()) { - /* - * Only paint rollover if no other menu on menubar is - * selected - */ - State stateTmp = state; - state = (menu.isEnabled()) ? State.HOT - : State.DISABLEDHOT; - for (MenuElement menuElement : - ((JMenuBar) menu.getParent()).getSubElements()) { - if (((JMenuItem) menuElement).isSelected()) { - state = stateTmp; - break; - } - } - } - - //non top level menus have HOT state instead of PUSHED - if (!((JMenu) menu).isTopLevelMenu()) { - if (state == State.PUSHED) { - state = State.HOT; - } else if (state == State.DISABLEDPUSHED) { - state = State.DISABLEDHOT; - } - } - - /* - * on Vista top level menu for non active frame looks disabled - */ - if (((JMenu) menu).isTopLevelMenu() && WindowsMenuItemUI.isVistaPainting()) { - if (! WindowsMenuBarUI.isActive(menu)) { - state = State.DISABLED; - } - } - return state; - } - - public Part getPart(JMenuItem menuItem) { - return ((JMenu) menuItem).isTopLevelMenu() ? Part.MP_BARITEM - : Part.MP_POPUPITEM; - } - }; - public static ComponentUI createUI(JComponent x) { - return new WindowsMenuUI(); - } - - protected void installDefaults() { - super.installDefaults(); - if (!WindowsLookAndFeel.isClassicWindows()) { - menuItem.setRolloverEnabled(true); - } - - menuBarHeight = (Integer)UIManager.getInt("MenuBar.height"); - - Object obj = UIManager.get("MenuBar.rolloverEnabled"); - hotTrackingOn = (obj instanceof Boolean) ? (Boolean)obj : true; - } - - /** - * Draws the background of the menu. - * @since 1.4 - */ - protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) { - if (WindowsMenuItemUI.isVistaPainting()) { - WindowsMenuItemUI.paintBackground(accessor, g, menuItem, bgColor); - return; - } - - JMenu menu = (JMenu)menuItem; - ButtonModel model = menu.getModel(); - - // Use superclass method for the old Windows LAF, - // for submenus, and for XP toplevel if selected or pressed - if (WindowsLookAndFeel.isClassicWindows() || - !menu.isTopLevelMenu() || - (XPStyle.getXP() != null && (model.isArmed() || model.isSelected()))) { - - super.paintBackground(g, menu, bgColor); - return; - } - - Color oldColor = g.getColor(); - int menuWidth = menu.getWidth(); - int menuHeight = menu.getHeight(); - - UIDefaults table = UIManager.getLookAndFeelDefaults(); - Color highlight = table.getColor("controlLtHighlight"); - Color shadow = table.getColor("controlShadow"); - - g.setColor(menu.getBackground()); - g.fillRect(0,0, menuWidth, menuHeight); - - if (menu.isOpaque()) { - if (model.isArmed() || model.isSelected()) { - // Draw a lowered bevel border - g.setColor(shadow); - g.drawLine(0,0, menuWidth - 1,0); - g.drawLine(0,0, 0,menuHeight - 2); - - g.setColor(highlight); - g.drawLine(menuWidth - 1,0, menuWidth - 1,menuHeight - 2); - g.drawLine(0,menuHeight - 2, menuWidth - 1,menuHeight - 2); - } else if (model.isRollover() && model.isEnabled()) { - // Only paint rollover if no other menu on menubar is selected - boolean otherMenuSelected = false; - MenuElement[] menus = ((JMenuBar)menu.getParent()).getSubElements(); - for (int i = 0; i < menus.length; i++) { - if (((JMenuItem)menus[i]).isSelected()) { - otherMenuSelected = true; - break; - } - } - if (!otherMenuSelected) { - if (XPStyle.getXP() != null) { - g.setColor(selectionBackground); // Uses protected field. - g.fillRect(0, 0, menuWidth, menuHeight); - } else { - // Draw a raised bevel border - g.setColor(highlight); - g.drawLine(0,0, menuWidth - 1,0); - g.drawLine(0,0, 0,menuHeight - 2); - - g.setColor(shadow); - g.drawLine(menuWidth - 1,0, menuWidth - 1,menuHeight - 2); - g.drawLine(0,menuHeight - 2, menuWidth - 1,menuHeight - 2); - } - } - } - } - g.setColor(oldColor); - } - - /** - * Method which renders the text of the current menu item. - * - * @param g Graphics context - * @param menuItem Current menu item to render - * @param textRect Bounding rectangle to render the text. - * @param text String to render - * @since 1.4 - */ - protected void paintText(Graphics g, JMenuItem menuItem, - Rectangle textRect, String text) { - if (WindowsMenuItemUI.isVistaPainting()) { - WindowsMenuItemUI.paintText(accessor, g, menuItem, textRect, text); - return; - } - JMenu menu = (JMenu)menuItem; - ButtonModel model = menuItem.getModel(); - Color oldColor = g.getColor(); - - // Only paint rollover if no other menu on menubar is selected - boolean paintRollover = model.isRollover(); - if (paintRollover && menu.isTopLevelMenu()) { - MenuElement[] menus = ((JMenuBar)menu.getParent()).getSubElements(); - for (int i = 0; i < menus.length; i++) { - if (((JMenuItem)menus[i]).isSelected()) { - paintRollover = false; - break; - } - } - } - - if ((model.isSelected() && (WindowsLookAndFeel.isClassicWindows() || - !menu.isTopLevelMenu())) || - (XPStyle.getXP() != null && (paintRollover || - model.isArmed() || - model.isSelected()))) { - g.setColor(selectionForeground); // Uses protected field. - } - - WindowsGraphicsUtils.paintText(g, menuItem, textRect, text, 0); - - g.setColor(oldColor); - } - - protected MouseInputListener createMouseInputListener(JComponent c) { - return new WindowsMouseInputHandler(); - } - - /** - * This class implements a mouse handler that sets the rollover flag to - * true when the mouse enters the menu and false when it exits. - * @since 1.4 - */ - protected class WindowsMouseInputHandler extends BasicMenuUI.MouseInputHandler { - public void mouseEntered(MouseEvent evt) { - super.mouseEntered(evt); - - JMenu menu = (JMenu)evt.getSource(); - if (hotTrackingOn && menu.isTopLevelMenu() && menu.isRolloverEnabled()) { - menu.getModel().setRollover(true); - menuItem.repaint(); - } - } - - public void mouseExited(MouseEvent evt) { - super.mouseExited(evt); - - JMenu menu = (JMenu)evt.getSource(); - ButtonModel model = menu.getModel(); - if (menu.isRolloverEnabled()) { - model.setRollover(false); - menuItem.repaint(); - } - } - } - - protected Dimension getPreferredMenuItemSize(JComponent c, - Icon checkIcon, - Icon arrowIcon, - int defaultTextIconGap) { - - Dimension d = super.getPreferredMenuItemSize(c, checkIcon, arrowIcon, - defaultTextIconGap); - - // Note: When toolbar containers (rebars) are implemented, only do - // this if the JMenuBar is not in a rebar (i.e. ignore the desktop - // property win.menu.height if in a rebar.) - if (c instanceof JMenu && ((JMenu)c).isTopLevelMenu() && - menuBarHeight != null && d.height < menuBarHeight) { - - d.height = menuBarHeight; - } - - return d; - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsOptionPaneUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsOptionPaneUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* - * Copyright (c) 1997, 2000, 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 com.sun.java.swing.plaf.windows; - -import javax.swing.*; -import javax.swing.plaf.*; -import javax.swing.plaf.basic.*; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; - - - -/** - * Windows rendition of the component. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - */ -public class WindowsOptionPaneUI extends BasicOptionPaneUI { -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsPasswordFieldUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsPasswordFieldUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* - * Copyright (c) 1997, 1998, 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 com.sun.java.swing.plaf.windows; - -import javax.swing.plaf.*; -import javax.swing.plaf.basic.*; -import javax.swing.*; -import javax.swing.text.Caret; - - - -/** - * Windows rendition of the component. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - */ -public class WindowsPasswordFieldUI extends BasicPasswordFieldUI { - - /** - * Creates a UI for a JPasswordField - * - * @param c the password field - * @return the UI - */ - public static ComponentUI createUI(JComponent c) { - return new WindowsPasswordFieldUI(); - } - - - /** - * Creates the object to use for a caret. By default an - * instance of WindowsCaret is created. This method - * can be redefined to provide something else that implements - * the InputPosition interface or a subclass of DefaultCaret. - * - * @return the caret object - */ - protected Caret createCaret() { - return new WindowsTextUI.WindowsCaret(); - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsPopupMenuSeparatorUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsPopupMenuSeparatorUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2004, 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 com.sun.java.swing.plaf.windows; - -import java.awt.*; - -import javax.swing.*; -import javax.swing.plaf.basic.BasicPopupMenuSeparatorUI; -import javax.swing.plaf.ComponentUI; - -import com.sun.java.swing.plaf.windows.TMSchema.Part; -import com.sun.java.swing.plaf.windows.TMSchema.State; -import com.sun.java.swing.plaf.windows.XPStyle.Skin; - -/** - * Windows {@literal L&F} implementation of PopupMenuSeparatorUI. - * - * @author Leif Samuelsson - * @author Igor Kushnirskiy - */ - -public class WindowsPopupMenuSeparatorUI extends BasicPopupMenuSeparatorUI { - - public static ComponentUI createUI(JComponent c) { - return new WindowsPopupMenuSeparatorUI(); - } - - public void paint(Graphics g, JComponent c) { - Dimension s = c.getSize(); - XPStyle xp = XPStyle.getXP(); - if (WindowsMenuItemUI.isVistaPainting(xp)) { - int x = 1; - Component parent = c.getParent(); - if (parent instanceof JComponent) { - Object gutterOffsetObject = - ((JComponent) parent).getClientProperty( - WindowsPopupMenuUI.GUTTER_OFFSET_KEY); - if (gutterOffsetObject instanceof Integer) { - /* - * gutter offset is in parent's coordinates. - * See comment in - * WindowsPopupMenuUI.getTextOffset(JComponent) - */ - x = ((Integer) gutterOffsetObject).intValue() - c.getX(); - x += WindowsPopupMenuUI.getGutterWidth(); - } - } - Skin skin = xp.getSkin(c, Part.MP_POPUPSEPARATOR); - int skinHeight = skin.getHeight(); - int y = (s.height - skinHeight) / 2; - skin.paintSkin(g, x, y, s.width - x - 1, skinHeight, State.NORMAL); - } else { - int y = s.height / 2; - g.setColor(c.getForeground()); - g.drawLine(1, y - 1, s.width - 2, y - 1); - - g.setColor(c.getBackground()); - g.drawLine(1, y, s.width - 2, y); - } - } - - public Dimension getPreferredSize(JComponent c) { - int fontHeight = 0; - Font font = c.getFont(); - if (font != null) { - fontHeight = c.getFontMetrics(font).getHeight(); - } - - return new Dimension(0, fontHeight/2 + 2); - } - -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsPopupMenuUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsPopupMenuUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,224 +0,0 @@ -/* - * Copyright (c) 1997, 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 com.sun.java.swing.plaf.windows; - -import java.awt.Component; -import java.awt.Graphics; -import java.awt.Insets; -import java.awt.KeyEventPostProcessor; -import java.awt.KeyboardFocusManager; -import java.awt.Window; -import java.awt.event.KeyEvent; -import javax.swing.*; -import javax.swing.event.*; -import javax.swing.plaf.*; -import javax.swing.plaf.basic.*; - -import sun.swing.StringUIClientPropertyKey; - -import com.sun.java.swing.plaf.windows.TMSchema.Part; -import com.sun.java.swing.plaf.windows.TMSchema.State; -import com.sun.java.swing.plaf.windows.XPStyle.Skin; -import static sun.swing.SwingUtilities2.BASICMENUITEMUI_MAX_TEXT_OFFSET; - -/** - * Windows rendition of the component. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - * - * @author Igor Kushnirskiy - */ -public class WindowsPopupMenuUI extends BasicPopupMenuUI { - - static MnemonicListener mnemonicListener = null; - static final Object GUTTER_OFFSET_KEY = - new StringUIClientPropertyKey("GUTTER_OFFSET_KEY"); - - public static ComponentUI createUI(JComponent c) { - return new WindowsPopupMenuUI(); - } - - public void installListeners() { - super.installListeners(); - if (! UIManager.getBoolean("Button.showMnemonics") && - mnemonicListener == null) { - - mnemonicListener = new MnemonicListener(); - MenuSelectionManager.defaultManager(). - addChangeListener(mnemonicListener); - } - } - - /** - * Returns the Popup that will be responsible for - * displaying the JPopupMenu. - * - * @param popupMenu JPopupMenu requesting Popup - * @param x Screen x location Popup is to be shown at - * @param y Screen y location Popup is to be shown at. - * @return Popup that will show the JPopupMenu - * @since 1.4 - */ - public Popup getPopup(JPopupMenu popupMenu, int x, int y) { - PopupFactory popupFactory = PopupFactory.getSharedInstance(); - return popupFactory.getPopup(popupMenu.getInvoker(), popupMenu, x, y); - } - - static class MnemonicListener implements ChangeListener { - JRootPane repaintRoot = null; - - public void stateChanged(ChangeEvent ev) { - MenuSelectionManager msm = (MenuSelectionManager)ev.getSource(); - MenuElement[] path = msm.getSelectedPath(); - if (path.length == 0) { - if(!WindowsLookAndFeel.isMnemonicHidden()) { - // menu was canceled -- hide mnemonics - WindowsLookAndFeel.setMnemonicHidden(true); - if (repaintRoot != null) { - Window win = - SwingUtilities.getWindowAncestor(repaintRoot); - WindowsGraphicsUtils.repaintMnemonicsInWindow(win); - } - } - } else { - Component c = (Component)path[0]; - if (c instanceof JPopupMenu) c = ((JPopupMenu)c).getInvoker(); - repaintRoot = SwingUtilities.getRootPane(c); - } - } - } - - /** - * Returns offset for the text. - * BasicMenuItemUI sets max text offset on the JPopupMenuUI. - * @param c PopupMenu to return text offset for. - * @return text offset for the component - */ - static int getTextOffset(JComponent c) { - int rv = -1; - Object maxTextOffset = - c.getClientProperty(BASICMENUITEMUI_MAX_TEXT_OFFSET); - if (maxTextOffset instanceof Integer) { - /* - * this is in JMenuItem coordinates. - * Let's assume all the JMenuItem have the same offset along X. - */ - rv = (Integer) maxTextOffset; - int menuItemOffset = 0; - Component component = c.getComponent(0); - if (component != null) { - menuItemOffset = component.getX(); - } - rv += menuItemOffset; - } - return rv; - } - - /** - * Returns span before gutter. - * used only on Vista. - * @return span before gutter - */ - static int getSpanBeforeGutter() { - return 3; - } - - /** - * Returns span after gutter. - * used only on Vista. - * @return span after gutter - */ - static int getSpanAfterGutter() { - return 3; - } - - /** - * Returns gutter width. - * used only on Vista. - * @return width of the gutter - */ - static int getGutterWidth() { - int rv = 2; - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - Skin skin = xp.getSkin(null, Part.MP_POPUPGUTTER); - rv = skin.getWidth(); - } - return rv; - } - - /** - * Checks if PopupMenu is leftToRight - * The orientation is derived from the children of the component. - * It is leftToRight if all the children are leftToRight - * - * @param c component to return orientation for - * @return true if all the children are leftToRight - */ - private static boolean isLeftToRight(JComponent c) { - boolean leftToRight = true; - for (int i = c.getComponentCount() - 1; i >=0 && leftToRight; i-- ) { - leftToRight = - c.getComponent(i).getComponentOrientation().isLeftToRight(); - } - return leftToRight; - } - - @Override - public void paint(Graphics g, JComponent c) { - XPStyle xp = XPStyle.getXP(); - if (WindowsMenuItemUI.isVistaPainting(xp)) { - Skin skin = xp.getSkin(c, Part.MP_POPUPBACKGROUND); - skin.paintSkin(g, 0, 0, c.getWidth(),c.getHeight(), State.NORMAL); - int textOffset = getTextOffset(c); - if (textOffset >= 0 - /* paint gutter only for leftToRight case */ - && isLeftToRight(c)) { - skin = xp.getSkin(c, Part.MP_POPUPGUTTER); - int gutterWidth = getGutterWidth(); - int gutterOffset = - textOffset - getSpanAfterGutter() - gutterWidth; - c.putClientProperty(GUTTER_OFFSET_KEY, - Integer.valueOf(gutterOffset)); - Insets insets = c.getInsets(); - skin.paintSkin(g, gutterOffset, insets.top, - gutterWidth, c.getHeight() - insets.bottom - insets.top, - State.NORMAL); - } else { - if (c.getClientProperty(GUTTER_OFFSET_KEY) != null) { - c.putClientProperty(GUTTER_OFFSET_KEY, null); - } - } - } else { - super.paint(g, c); - } - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsPopupWindow.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsPopupWindow.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2001, 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 com.sun.java.swing.plaf.windows; - -import javax.swing.JWindow; -import java.awt.Window; -import java.awt.Graphics; - -/** - * A class which tags a window with a particular semantic usage, - * either tooltip, menu, sub-menu, popup-menu, or comobobox-popup. - * This is used as a temporary solution for getting native AWT support - * for transition effects in Windows 98 and Windows 2000. The native - * code will interpret the windowType property and automatically - * implement appropriate animation when the window is shown/hidden. - *

    - * Note that support for transition effects may be supported with a - * different mechanism in the future and so this class is - * package-private and targeted for Swing implementation use only. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - * - * @author Amy Fowler - */ -@SuppressWarnings("serial") // Superclass is not serializable across versions -class WindowsPopupWindow extends JWindow { - - static final int UNDEFINED_WINDOW_TYPE = 0; - static final int TOOLTIP_WINDOW_TYPE = 1; - static final int MENU_WINDOW_TYPE = 2; - static final int SUBMENU_WINDOW_TYPE = 3; - static final int POPUPMENU_WINDOW_TYPE = 4; - static final int COMBOBOX_POPUP_WINDOW_TYPE = 5; - - private int windowType; - - WindowsPopupWindow(Window parent) { - super(parent); - setFocusableWindowState(false); - } - - void setWindowType(int type) { - windowType = type; - } - - int getWindowType() { - return windowType; - } - - public void update(Graphics g) { - paint(g); - } - - @SuppressWarnings("deprecation") - public void hide() { - super.hide(); - /** We need to call removeNotify() here because hide() does - * something only if Component.visible is true. When the app - * frame is miniaturized, the parent frame of this frame is - * invisible, causing AWT to believe that this frame - * is invisible and causing hide() to do nothing - */ - removeNotify(); - } - - @SuppressWarnings("deprecation") - public void show() { - super.show(); - this.pack(); - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsProgressBarUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsProgressBarUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,412 +0,0 @@ -/* - * Copyright (c) 1997, 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 com.sun.java.swing.plaf.windows; - -import javax.swing.plaf.basic.*; -import javax.swing.plaf.*; -import javax.swing.*; -import java.awt.*; - -import static com.sun.java.swing.plaf.windows.TMSchema.*; -import static com.sun.java.swing.plaf.windows.XPStyle.Skin; - - -/** - * Windows rendition of the component. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - * - * @author Michael C. Albers - */ -public class WindowsProgressBarUI extends BasicProgressBarUI -{ - - private Rectangle previousFullBox; - private Insets indeterminateInsets; - - public static ComponentUI createUI(JComponent x) { - return new WindowsProgressBarUI(); - } - - - protected void installDefaults() { - super.installDefaults(); - - if (XPStyle.getXP() != null) { - LookAndFeel.installProperty(progressBar, "opaque", Boolean.FALSE); - progressBar.setBorder(null); - indeterminateInsets = UIManager.getInsets("ProgressBar.indeterminateInsets"); - } - } - - /** - * Returns the baseline. - * - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - * @see javax.swing.JComponent#getBaseline(int, int) - * @since 1.6 - */ - public int getBaseline(JComponent c, int width, int height) { - int baseline = super.getBaseline(c, width, height); - if (XPStyle.getXP() != null && progressBar.isStringPainted() && - progressBar.getOrientation() == JProgressBar.HORIZONTAL) { - FontMetrics metrics = progressBar. - getFontMetrics(progressBar.getFont()); - int y = progressBar.getInsets().top; - if (progressBar.isIndeterminate()) { - y = -1; - height--; - } - else { - y = 0; - height -= 3; - } - baseline = y + (height + metrics.getAscent() - - metrics.getLeading() - - metrics.getDescent()) / 2; - } - return baseline; - } - - protected Dimension getPreferredInnerHorizontal() { - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - Skin skin = xp.getSkin(progressBar, Part.PP_BAR); - return new Dimension( - (int)super.getPreferredInnerHorizontal().getWidth(), - skin.getHeight()); - } - return super.getPreferredInnerHorizontal(); - } - - protected Dimension getPreferredInnerVertical() { - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - Skin skin = xp.getSkin(progressBar, Part.PP_BARVERT); - return new Dimension( - skin.getWidth(), - (int)super.getPreferredInnerVertical().getHeight()); - } - return super.getPreferredInnerVertical(); - } - - protected void paintDeterminate(Graphics g, JComponent c) { - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - boolean vertical = (progressBar.getOrientation() == JProgressBar.VERTICAL); - boolean isLeftToRight = WindowsGraphicsUtils.isLeftToRight(c); - int barRectWidth = progressBar.getWidth(); - int barRectHeight = progressBar.getHeight()-1; - // amount of progress to draw - int amountFull = getAmountFull(null, barRectWidth, barRectHeight); - - paintXPBackground(g, vertical, barRectWidth, barRectHeight); - // Paint progress - if (progressBar.isStringPainted()) { - // Do not paint the standard stripes from the skin, because they obscure - // the text - g.setColor(progressBar.getForeground()); - barRectHeight -= 2; - barRectWidth -= 2; - - if (barRectWidth <= 0 || barRectHeight <= 0) { - return; - } - - Graphics2D g2 = (Graphics2D)g; - g2.setStroke(new BasicStroke((float)(vertical ? barRectWidth : barRectHeight), - BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); - if (!vertical) { - if (isLeftToRight) { - g2.drawLine(2, barRectHeight / 2 + 1, - amountFull - 2, barRectHeight / 2 + 1); - } else { - g2.drawLine(2 + barRectWidth, - barRectHeight / 2 + 1, - 2 + barRectWidth - (amountFull - 2), - barRectHeight / 2 + 1); - } - paintString(g, 0, 0, barRectWidth, barRectHeight, amountFull, null); - } else { - g2.drawLine(barRectWidth/2 + 1, barRectHeight + 1, - barRectWidth/2 + 1, barRectHeight + 1 - amountFull + 2); - paintString(g, 2, 2, barRectWidth, barRectHeight, amountFull, null); - } - - } else { - Skin skin = xp.getSkin(progressBar, vertical ? Part.PP_CHUNKVERT : Part.PP_CHUNK); - int thickness; - if (vertical) { - thickness = barRectWidth - 5; - } else { - thickness = barRectHeight - 5; - } - - int chunkSize = xp.getInt(progressBar, Part.PP_PROGRESS, null, Prop.PROGRESSCHUNKSIZE, 2); - int spaceSize = xp.getInt(progressBar, Part.PP_PROGRESS, null, Prop.PROGRESSSPACESIZE, 0); - int nChunks = (amountFull-4) / (chunkSize + spaceSize); - - // See if we can squeeze in an extra chunk without spacing after - if (spaceSize > 0 && (nChunks * (chunkSize + spaceSize) + chunkSize) < (amountFull-4)) { - nChunks++; - } - - for (int i = 0; i < nChunks; i++) { - if (vertical) { - skin.paintSkin(g, - 3, barRectHeight - i * (chunkSize + spaceSize) - chunkSize - 2, - thickness, chunkSize, null); - } else { - if (isLeftToRight) { - skin.paintSkin(g, - 4 + i * (chunkSize + spaceSize), 2, - chunkSize, thickness, null); - } else { - skin.paintSkin(g, - barRectWidth - (2 + (i+1) * (chunkSize + spaceSize)), 2, - chunkSize, thickness, null); - } - } - } - } - } else { - super.paintDeterminate(g, c); - } - } - - - /** - * {@inheritDoc} - * @since 1.6 - */ - protected void setAnimationIndex(int newValue) { - super.setAnimationIndex(newValue); - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - if (boxRect != null) { - // get the full repaint area and add it the - // previous one so we can erase it - Rectangle chunk = getFullChunkBounds(boxRect); - if (previousFullBox != null) { - chunk.add(previousFullBox); - } - progressBar.repaint(chunk); - } else { - progressBar.repaint(); - } - } - } - - - /** - * {@inheritDoc} - * @since 1.6 - */ - protected int getBoxLength(int availableLength, int otherDimension) { - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - return 6; // an apparently hard coded value in Windows - } - return super.getBoxLength(availableLength, otherDimension); - } - - /** - * {@inheritDoc} - * @since 1.6 - */ - protected Rectangle getBox(Rectangle r) { - Rectangle rect = super.getBox(r); - - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - boolean vertical = (progressBar.getOrientation() - == JProgressBar.VERTICAL); - Part part = vertical ? Part.PP_BARVERT : Part.PP_BAR; - Insets ins = indeterminateInsets; - - int currentFrame = getAnimationIndex(); - int framecount = getFrameCount()/2; - - int gap = xp.getInt(progressBar, Part.PP_PROGRESS, null, - Prop.PROGRESSSPACESIZE, 0); - currentFrame = currentFrame % framecount; - - // this code adjusts the chunk size to properly account for the - // size and gap specified in the XP style. It also does it's own - // box placement for the chunk animation. This is required because - // the inherited algorithm from BasicProgressBarUI goes back and - // forth whereas XP only goes in one direction. XP also has ghosted - // trailing chunks to create the illusion of speed. This code - // adjusts the pixel length of the animation to account for the - // trails. - if (!vertical) { - rect.y = rect.y + ins.top; - rect.height = progressBar.getHeight() - ins.top - ins.bottom; - int len = progressBar.getWidth() - ins.left - ins.right; - len += (rect.width+gap)*2; // add 2x for the trails - double delta = (double)(len) / (double)framecount; - rect.x = (int)(delta * currentFrame) + ins.left; - } else { - rect.x = rect.x + ins.left; - rect.width = progressBar.getWidth() - ins.left - ins.right; - int len = progressBar.getHeight() - ins.top - ins.bottom; - len += (rect.height+gap)*2; // add 2x for the trails - double delta = (double)(len) / (double)framecount; - rect.y = (int)(delta * currentFrame) + ins.top; - } - } - return rect; - } - - - protected void paintIndeterminate(Graphics g, JComponent c) { - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - boolean vertical = (progressBar.getOrientation() - == JProgressBar.VERTICAL); - int barRectWidth = progressBar.getWidth(); - int barRectHeight = progressBar.getHeight(); - paintXPBackground(g, vertical, barRectWidth, barRectHeight); - - // Paint the bouncing box. - boxRect = getBox(boxRect); - if (boxRect != null) { - g.setColor(progressBar.getForeground()); - if (!(g instanceof Graphics2D)) { - return; - } - paintIndeterminateFrame(boxRect, (Graphics2D)g, vertical, - barRectWidth, barRectHeight); - if (progressBar.isStringPainted()) { - if (!vertical) { - paintString(g, -1, -1, barRectWidth, barRectHeight, 0, null); - } else { - paintString(g, 1, 1, barRectWidth, barRectHeight, 0, null); - } - } - } - } else { - super.paintIndeterminate(g, c); - } - } - - private Rectangle getFullChunkBounds(Rectangle box) { - boolean vertical = (progressBar.getOrientation() == JProgressBar.VERTICAL); - XPStyle xp = XPStyle.getXP(); - int gap = (xp != null) ? xp.getInt(progressBar, Part.PP_PROGRESS, - null, Prop.PROGRESSSPACESIZE, 0) - : 0; - - if (!vertical) { - int chunksize = box.width+gap; - return new Rectangle(box.x-chunksize*2, box.y, chunksize*3, box.height); - } else { - int chunksize = box.height+gap; - return new Rectangle(box.x, box.y-chunksize*2, box.width, chunksize*3); - } - } - - private void paintIndeterminateFrame(Rectangle box, Graphics2D g, - boolean vertical, - int bgwidth, int bgheight) { - XPStyle xp = XPStyle.getXP(); - if (xp == null) { - return; - } - - // create a new graphics to keep drawing surface state - Graphics2D gfx = (Graphics2D)g.create(); - - Part part = vertical ? Part.PP_BARVERT : Part.PP_BAR; - Part chunk = vertical ? Part.PP_CHUNKVERT : Part.PP_CHUNK; - - // calculate the chunk offsets - int gap = xp.getInt(progressBar, Part.PP_PROGRESS, null, - Prop.PROGRESSSPACESIZE, 0); - int deltax = 0; - int deltay = 0; - if (!vertical) { - deltax = -box.width - gap; - deltay = 0; - } else { - deltax = 0; - deltay = -box.height - gap; - } - - // Calculate the area of the chunks combined - Rectangle fullBox = getFullChunkBounds(box); - - // save this box for the next time - previousFullBox = fullBox; - - // this is the entire progress bar minus the track and borders - Insets ins = indeterminateInsets; - Rectangle progbarExtents = new Rectangle(ins.left, ins.top, - bgwidth - ins.left - ins.right, - bgheight - ins.top - ins.bottom); - - // only paint where the chunks overlap with the progress bar drawing area - Rectangle repaintArea = progbarExtents.intersection(fullBox); - - // adjust the cliprect to chop the chunks when they go off the end - gfx.clip(repaintArea); - - // get the skin - XPStyle.Skin skin = xp.getSkin(progressBar, chunk); - - // do the drawing - gfx.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f)); - skin.paintSkin(gfx, box.x, box.y, box.width, box.height, null); - box.translate(deltax, deltay); - gfx.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f)); - skin.paintSkin(gfx, box.x, box.y, box.width, box.height, null); - box.translate(deltax, deltay); - gfx.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f)); - skin.paintSkin(gfx, box.x, box.y, box.width, box.height, null); - - // get rid of our clip and composite changes - gfx.dispose(); - } - - private void paintXPBackground(Graphics g, boolean vertical, - int barRectWidth, int barRectHeight) { - XPStyle xp = XPStyle.getXP(); - if (xp == null) { - return; - } - Part part = vertical ? Part.PP_BARVERT : Part.PP_BAR; - Skin skin = xp.getSkin(progressBar, part); - - // Paint background - skin.paintSkin(g, 0, 0, barRectWidth, barRectHeight, null); - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsRadioButtonMenuItemUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsRadioButtonMenuItemUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,103 +0,0 @@ -/* - * Copyright (c) 1997, 2006, 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 com.sun.java.swing.plaf.windows; - -import java.awt.*; -import javax.swing.*; -import javax.swing.plaf.*; -import javax.swing.plaf.basic.*; - -import com.sun.java.swing.plaf.windows.TMSchema.Part; -import com.sun.java.swing.plaf.windows.TMSchema.State; - -/** - * Windows rendition of the component. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - */ -public class WindowsRadioButtonMenuItemUI extends BasicRadioButtonMenuItemUI { - - final WindowsMenuItemUIAccessor accessor = - new WindowsMenuItemUIAccessor() { - - public JMenuItem getMenuItem() { - return menuItem; - } - - public State getState(JMenuItem menuItem) { - return WindowsMenuItemUI.getState(this, menuItem); - } - - public Part getPart(JMenuItem menuItem) { - return WindowsMenuItemUI.getPart(this, menuItem); - } - }; - public static ComponentUI createUI(JComponent b) { - return new WindowsRadioButtonMenuItemUI(); - } - - @Override - protected void paintBackground(Graphics g, JMenuItem menuItem, - Color bgColor) { - if (WindowsMenuItemUI.isVistaPainting()) { - WindowsMenuItemUI.paintBackground(accessor, g, menuItem, bgColor); - return; - } - super.paintBackground(g, menuItem, bgColor); - } - - /** - * Method which renders the text of the current menu item. - * - * @param g Graphics context - * @param menuItem Current menu item to render - * @param textRect Bounding rectangle to render the text. - * @param text String to render - * @since 1.4 - */ - protected void paintText(Graphics g, JMenuItem menuItem, - Rectangle textRect, String text) { - if (WindowsMenuItemUI.isVistaPainting()) { - WindowsMenuItemUI.paintText(accessor, g, menuItem, textRect, text); - return; - } - ButtonModel model = menuItem.getModel(); - Color oldColor = g.getColor(); - - if(model.isEnabled() && model.isArmed()) { - g.setColor(selectionForeground); // Uses protected field. - } - - WindowsGraphicsUtils.paintText(g, menuItem, textRect, text, 0); - - g.setColor(oldColor); - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsRadioButtonUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsRadioButtonUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,135 +0,0 @@ -/* - * Copyright (c) 1997, 2012, 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 com.sun.java.swing.plaf.windows; - -import sun.awt.AppContext; - -import javax.swing.plaf.basic.*; -import javax.swing.*; -import javax.swing.plaf.*; - -import java.awt.*; - - -/** - * Windows rendition of the component. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - */ -public class WindowsRadioButtonUI extends BasicRadioButtonUI -{ - private static final Object WINDOWS_RADIO_BUTTON_UI_KEY = new Object(); - - protected int dashedRectGapX; - protected int dashedRectGapY; - protected int dashedRectGapWidth; - protected int dashedRectGapHeight; - - protected Color focusColor; - - private boolean initialized = false; - - // ******************************** - // Create PLAF - // ******************************** - public static ComponentUI createUI(JComponent c) { - AppContext appContext = AppContext.getAppContext(); - WindowsRadioButtonUI windowsRadioButtonUI = - (WindowsRadioButtonUI) appContext.get(WINDOWS_RADIO_BUTTON_UI_KEY); - if (windowsRadioButtonUI == null) { - windowsRadioButtonUI = new WindowsRadioButtonUI(); - appContext.put(WINDOWS_RADIO_BUTTON_UI_KEY, windowsRadioButtonUI); - } - return windowsRadioButtonUI; - } - - // ******************************** - // Defaults - // ******************************** - public void installDefaults(AbstractButton b) { - super.installDefaults(b); - if(!initialized) { - dashedRectGapX = ((Integer)UIManager.get("Button.dashedRectGapX")).intValue(); - dashedRectGapY = ((Integer)UIManager.get("Button.dashedRectGapY")).intValue(); - dashedRectGapWidth = ((Integer)UIManager.get("Button.dashedRectGapWidth")).intValue(); - dashedRectGapHeight = ((Integer)UIManager.get("Button.dashedRectGapHeight")).intValue(); - focusColor = UIManager.getColor(getPropertyPrefix() + "focus"); - initialized = true; - } - if (XPStyle.getXP() != null) { - LookAndFeel.installProperty(b, "rolloverEnabled", Boolean.TRUE); - } - } - - protected void uninstallDefaults(AbstractButton b) { - super.uninstallDefaults(b); - initialized = false; - } - - protected Color getFocusColor() { - return focusColor; - } - - // ******************************** - // Paint Methods - // ******************************** - - /** - * Overridden method to render the text without the mnemonic - */ - protected void paintText(Graphics g, AbstractButton b, Rectangle textRect, String text) { - WindowsGraphicsUtils.paintText(g, b, textRect, text, getTextShiftOffset()); - } - - - protected void paintFocus(Graphics g, Rectangle textRect, Dimension d){ - g.setColor(getFocusColor()); - BasicGraphicsUtils.drawDashedRect(g, textRect.x, textRect.y, textRect.width, textRect.height); - } - - // ******************************** - // Layout Methods - // ******************************** - public Dimension getPreferredSize(JComponent c) { - Dimension d = super.getPreferredSize(c); - - /* Ensure that the width and height of the button is odd, - * to allow for the focus line if focus is painted - */ - AbstractButton b = (AbstractButton)c; - if (d != null && b.isFocusPainted()) { - if(d.width % 2 == 0) { d.width += 1; } - if(d.height % 2 == 0) { d.height += 1; } - } - return d; - } - -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsRootPaneUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsRootPaneUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2000, 2012, 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 com.sun.java.swing.plaf.windows; - -import java.awt.Component; -import java.awt.Container; -import java.awt.Event; -import java.awt.KeyEventPostProcessor; -import java.awt.Window; -import java.awt.Toolkit; - -import sun.awt.AWTAccessor; -import sun.awt.SunToolkit; - -import java.awt.event.ActionEvent; -import java.awt.event.KeyEvent; - -import javax.swing.AbstractAction; -import javax.swing.ActionMap; -import javax.swing.InputMap; -import javax.swing.KeyStroke; -import javax.swing.JComponent; -import javax.swing.JLabel; -import javax.swing.JRootPane; -import javax.swing.SwingUtilities; -import javax.swing.UIManager; -import javax.swing.AbstractButton; -import javax.swing.JFrame; -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.MenuElement; -import javax.swing.MenuSelectionManager; - -import javax.swing.plaf.ActionMapUIResource; -import javax.swing.plaf.ComponentUI; -import javax.swing.plaf.InputMapUIResource; - -import javax.swing.plaf.basic.BasicRootPaneUI; -import javax.swing.plaf.basic.ComboPopup; - -/** - * Windows implementation of RootPaneUI, there is one shared between all - * JRootPane instances. - * - * @author Mark Davidson - * @since 1.4 - */ -public class WindowsRootPaneUI extends BasicRootPaneUI { - - private static final WindowsRootPaneUI windowsRootPaneUI = new WindowsRootPaneUI(); - static final AltProcessor altProcessor = new AltProcessor(); - - public static ComponentUI createUI(JComponent c) { - return windowsRootPaneUI; - } - - static class AltProcessor implements KeyEventPostProcessor { - static boolean altKeyPressed = false; - static boolean menuCanceledOnPress = false; - static JRootPane root = null; - static Window winAncestor = null; - - void altPressed(KeyEvent ev) { - MenuSelectionManager msm = - MenuSelectionManager.defaultManager(); - MenuElement[] path = msm.getSelectedPath(); - if (path.length > 0 && ! (path[0] instanceof ComboPopup)) { - msm.clearSelectedPath(); - menuCanceledOnPress = true; - ev.consume(); - } else if(path.length > 0) { // We are in ComboBox - menuCanceledOnPress = false; - WindowsLookAndFeel.setMnemonicHidden(false); - WindowsGraphicsUtils.repaintMnemonicsInWindow(winAncestor); - ev.consume(); - } else { - menuCanceledOnPress = false; - WindowsLookAndFeel.setMnemonicHidden(false); - WindowsGraphicsUtils.repaintMnemonicsInWindow(winAncestor); - JMenuBar mbar = root != null ? root.getJMenuBar() : null; - if(mbar == null && winAncestor instanceof JFrame) { - mbar = ((JFrame)winAncestor).getJMenuBar(); - } - JMenu menu = mbar != null ? mbar.getMenu(0) : null; - if(menu != null) { - ev.consume(); - } - } - } - - void altReleased(KeyEvent ev) { - if (menuCanceledOnPress) { - WindowsLookAndFeel.setMnemonicHidden(true); - WindowsGraphicsUtils.repaintMnemonicsInWindow(winAncestor); - return; - } - - MenuSelectionManager msm = - MenuSelectionManager.defaultManager(); - if (msm.getSelectedPath().length == 0) { - // if no menu is active, we try activating the menubar - - JMenuBar mbar = root != null ? root.getJMenuBar() : null; - if(mbar == null && winAncestor instanceof JFrame) { - mbar = ((JFrame)winAncestor).getJMenuBar(); - } - JMenu menu = mbar != null ? mbar.getMenu(0) : null; - - // It might happen that the altRelease event is processed - // with a reasonable delay since it has been generated. - // Here we check the last deactivation time of the containing - // window. If this time appears to be greater than the altRelease - // event time the event is skipped to avoid unexpected menu - // activation. See 7121442. - // Also we must ensure that original source of key event belongs - // to the same window object as winAncestor. See 8001633. - boolean skip = false; - Toolkit tk = Toolkit.getDefaultToolkit(); - if (tk instanceof SunToolkit) { - Component originalSource = AWTAccessor.getKeyEventAccessor() - .getOriginalSource(ev); - skip = SunToolkit.getContainingWindow(originalSource) != winAncestor || - ev.getWhen() <= ((SunToolkit) tk).getWindowDeactivationTime(winAncestor); - } - - if (menu != null && !skip) { - MenuElement[] path = new MenuElement[2]; - path[0] = mbar; - path[1] = menu; - msm.setSelectedPath(path); - } else if(!WindowsLookAndFeel.isMnemonicHidden()) { - WindowsLookAndFeel.setMnemonicHidden(true); - WindowsGraphicsUtils.repaintMnemonicsInWindow(winAncestor); - } - } else { - if((msm.getSelectedPath())[0] instanceof ComboPopup) { - WindowsLookAndFeel.setMnemonicHidden(true); - WindowsGraphicsUtils.repaintMnemonicsInWindow(winAncestor); - } - } - - } - - public boolean postProcessKeyEvent(KeyEvent ev) { - if(ev.isConsumed() && ev.getKeyCode() != KeyEvent.VK_ALT) { - // mnemonic combination, it's consumed, but we need - // set altKeyPressed to false, otherwise after selection - // component by mnemonic combination a menu will be open - altKeyPressed = false; - return false; - } - if (ev.getKeyCode() == KeyEvent.VK_ALT) { - root = SwingUtilities.getRootPane(ev.getComponent()); - winAncestor = (root == null ? null : - SwingUtilities.getWindowAncestor(root)); - - if (ev.getID() == KeyEvent.KEY_PRESSED) { - if (!altKeyPressed) { - altPressed(ev); - } - altKeyPressed = true; - return true; - } else if (ev.getID() == KeyEvent.KEY_RELEASED) { - if (altKeyPressed) { - altReleased(ev); - } else { - MenuSelectionManager msm = - MenuSelectionManager.defaultManager(); - MenuElement[] path = msm.getSelectedPath(); - if (path.length <= 0) { - WindowsLookAndFeel.setMnemonicHidden(true); - WindowsGraphicsUtils.repaintMnemonicsInWindow(winAncestor); - } - } - altKeyPressed = false; - } - root = null; - winAncestor = null; - } else { - if (WindowsLookAndFeel.isMnemonicHidden() && ev.isAltDown()) { - WindowsLookAndFeel.setMnemonicHidden(false); - WindowsGraphicsUtils.repaintMnemonicsInWindow(winAncestor); - } - altKeyPressed = false; - } - return false; - } - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsScrollBarUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsScrollBarUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,503 +0,0 @@ -/* - * Copyright (c) 1997, 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 com.sun.java.swing.plaf.windows; - -import java.awt.*; -import java.awt.event.*; -import java.awt.image.*; -import java.lang.ref.*; -import java.util.*; -import javax.swing.plaf.basic.*; -import javax.swing.*; -import javax.swing.plaf.ComponentUI; - -import static com.sun.java.swing.plaf.windows.TMSchema.*; -import static com.sun.java.swing.plaf.windows.XPStyle.Skin; - - -/** - * Windows rendition of the component. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - */ -public class WindowsScrollBarUI extends BasicScrollBarUI { - private Grid thumbGrid; - private Grid highlightGrid; - private Dimension horizontalThumbSize; - private Dimension verticalThumbSize; - - /** - * Creates a UI for a JScrollBar. - * - * @param c the text field - * @return the UI - */ - public static ComponentUI createUI(JComponent c) { - return new WindowsScrollBarUI(); - } - - protected void installDefaults() { - super.installDefaults(); - - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - scrollbar.setBorder(null); - horizontalThumbSize = getSize(scrollbar, xp, Part.SBP_THUMBBTNHORZ); - verticalThumbSize = getSize(scrollbar, xp, Part.SBP_THUMBBTNVERT); - } else { - horizontalThumbSize = null; - verticalThumbSize = null; - } - } - - private static Dimension getSize(Component component, XPStyle xp, Part part) { - Skin skin = xp.getSkin(component, part); - return new Dimension(skin.getWidth(), skin.getHeight()); - } - - @Override - protected Dimension getMinimumThumbSize() { - if ((horizontalThumbSize == null) || (verticalThumbSize == null)) { - return super.getMinimumThumbSize(); - } - return JScrollBar.HORIZONTAL == scrollbar.getOrientation() - ? horizontalThumbSize - : verticalThumbSize; - } - - public void uninstallUI(JComponent c) { - super.uninstallUI(c); - thumbGrid = highlightGrid = null; - } - - protected void configureScrollBarColors() { - super.configureScrollBarColors(); - Color color = UIManager.getColor("ScrollBar.trackForeground"); - if (color != null && trackColor != null) { - thumbGrid = Grid.getGrid(color, trackColor); - } - - color = UIManager.getColor("ScrollBar.trackHighlightForeground"); - if (color != null && trackHighlightColor != null) { - highlightGrid = Grid.getGrid(color, trackHighlightColor); - } - } - - protected JButton createDecreaseButton(int orientation) { - return new WindowsArrowButton(orientation, - UIManager.getColor("ScrollBar.thumb"), - UIManager.getColor("ScrollBar.thumbShadow"), - UIManager.getColor("ScrollBar.thumbDarkShadow"), - UIManager.getColor("ScrollBar.thumbHighlight")); - } - - protected JButton createIncreaseButton(int orientation) { - return new WindowsArrowButton(orientation, - UIManager.getColor("ScrollBar.thumb"), - UIManager.getColor("ScrollBar.thumbShadow"), - UIManager.getColor("ScrollBar.thumbDarkShadow"), - UIManager.getColor("ScrollBar.thumbHighlight")); - } - - /** - * {@inheritDoc} - * @since 1.6 - */ - @Override - protected ArrowButtonListener createArrowButtonListener(){ - // we need to repaint the entire scrollbar because state change for each - // button causes a state change for the thumb and other button on Vista - if(XPStyle.isVista()) { - return new ArrowButtonListener() { - public void mouseEntered(MouseEvent evt) { - repaint(); - super.mouseEntered(evt); - } - public void mouseExited(MouseEvent evt) { - repaint(); - super.mouseExited(evt); - } - private void repaint() { - scrollbar.repaint(); - } - }; - } else { - return super.createArrowButtonListener(); - } - } - - protected void paintTrack(Graphics g, JComponent c, Rectangle trackBounds){ - boolean v = (scrollbar.getOrientation() == JScrollBar.VERTICAL); - - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - JScrollBar sb = (JScrollBar)c; - State state = State.NORMAL; - // Pending: Implement rollover (hot) and pressed - if (!sb.isEnabled()) { - state = State.DISABLED; - } - Part part = v ? Part.SBP_LOWERTRACKVERT : Part.SBP_LOWERTRACKHORZ; - xp.getSkin(sb, part).paintSkin(g, trackBounds, state); - } else if (thumbGrid == null) { - super.paintTrack(g, c, trackBounds); - } - else { - thumbGrid.paint(g, trackBounds.x, trackBounds.y, trackBounds.width, - trackBounds.height); - if (trackHighlight == DECREASE_HIGHLIGHT) { - paintDecreaseHighlight(g); - } - else if (trackHighlight == INCREASE_HIGHLIGHT) { - paintIncreaseHighlight(g); - } - } - } - - protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) { - boolean v = (scrollbar.getOrientation() == JScrollBar.VERTICAL); - - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - JScrollBar sb = (JScrollBar)c; - State state = State.NORMAL; - if (!sb.isEnabled()) { - state = State.DISABLED; - } else if (isDragging) { - state = State.PRESSED; - } else if (isThumbRollover()) { - state = State.HOT; - } else if (XPStyle.isVista()) { - if ((incrButton != null && incrButton.getModel().isRollover()) || - (decrButton != null && decrButton.getModel().isRollover())) { - state = State.HOVER; - } - } - // Paint thumb - Part thumbPart = v ? Part.SBP_THUMBBTNVERT : Part.SBP_THUMBBTNHORZ; - xp.getSkin(sb, thumbPart).paintSkin(g, thumbBounds, state); - // Paint gripper - Part gripperPart = v ? Part.SBP_GRIPPERVERT : Part.SBP_GRIPPERHORZ; - Skin skin = xp.getSkin(sb, gripperPart); - Insets gripperInsets = xp.getMargin(c, thumbPart, null, Prop.CONTENTMARGINS); - if (gripperInsets == null || - (v && (thumbBounds.height - gripperInsets.top - - gripperInsets.bottom >= skin.getHeight())) || - (!v && (thumbBounds.width - gripperInsets.left - - gripperInsets.right >= skin.getWidth()))) { - skin.paintSkin(g, - thumbBounds.x + (thumbBounds.width - skin.getWidth()) / 2, - thumbBounds.y + (thumbBounds.height - skin.getHeight()) / 2, - skin.getWidth(), skin.getHeight(), state); - } - } else { - super.paintThumb(g, c, thumbBounds); - } - } - - - protected void paintDecreaseHighlight(Graphics g) { - if (highlightGrid == null) { - super.paintDecreaseHighlight(g); - } - else { - Insets insets = scrollbar.getInsets(); - Rectangle thumbR = getThumbBounds(); - int x, y, w, h; - - if (scrollbar.getOrientation() == JScrollBar.VERTICAL) { - x = insets.left; - y = decrButton.getY() + decrButton.getHeight(); - w = scrollbar.getWidth() - (insets.left + insets.right); - h = thumbR.y - y; - } - else { - x = decrButton.getX() + decrButton.getHeight(); - y = insets.top; - w = thumbR.x - x; - h = scrollbar.getHeight() - (insets.top + insets.bottom); - } - highlightGrid.paint(g, x, y, w, h); - } - } - - - protected void paintIncreaseHighlight(Graphics g) { - if (highlightGrid == null) { - super.paintDecreaseHighlight(g); - } - else { - Insets insets = scrollbar.getInsets(); - Rectangle thumbR = getThumbBounds(); - int x, y, w, h; - - if (scrollbar.getOrientation() == JScrollBar.VERTICAL) { - x = insets.left; - y = thumbR.y + thumbR.height; - w = scrollbar.getWidth() - (insets.left + insets.right); - h = incrButton.getY() - y; - } - else { - x = thumbR.x + thumbR.width; - y = insets.top; - w = incrButton.getX() - x; - h = scrollbar.getHeight() - (insets.top + insets.bottom); - } - highlightGrid.paint(g, x, y, w, h); - } - } - - - /** - * {@inheritDoc} - * @since 1.6 - */ - @Override - protected void setThumbRollover(boolean active) { - boolean old = isThumbRollover(); - super.setThumbRollover(active); - // we need to repaint the entire scrollbar because state change for thumb - // causes state change for incr and decr buttons on Vista - if(XPStyle.isVista() && active != old) { - scrollbar.repaint(); - } - } - - /** - * WindowsArrowButton is used for the buttons to position the - * document up/down. It differs from BasicArrowButton in that the - * preferred size is always a square. - */ - @SuppressWarnings("serial") // Superclass is not serializable across versions - private class WindowsArrowButton extends BasicArrowButton { - - public WindowsArrowButton(int direction, Color background, Color shadow, - Color darkShadow, Color highlight) { - super(direction, background, shadow, darkShadow, highlight); - } - - public WindowsArrowButton(int direction) { - super(direction); - } - - public void paint(Graphics g) { - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - ButtonModel model = getModel(); - Skin skin = xp.getSkin(this, Part.SBP_ARROWBTN); - State state = null; - - boolean jointRollover = XPStyle.isVista() && (isThumbRollover() || - (this == incrButton && decrButton.getModel().isRollover()) || - (this == decrButton && incrButton.getModel().isRollover())); - - // normal, rollover, pressed, disabled - if (model.isArmed() && model.isPressed()) { - switch (direction) { - case NORTH: state = State.UPPRESSED; break; - case SOUTH: state = State.DOWNPRESSED; break; - case WEST: state = State.LEFTPRESSED; break; - case EAST: state = State.RIGHTPRESSED; break; - } - } else if (!model.isEnabled()) { - switch (direction) { - case NORTH: state = State.UPDISABLED; break; - case SOUTH: state = State.DOWNDISABLED; break; - case WEST: state = State.LEFTDISABLED; break; - case EAST: state = State.RIGHTDISABLED; break; - } - } else if (model.isRollover() || model.isPressed()) { - switch (direction) { - case NORTH: state = State.UPHOT; break; - case SOUTH: state = State.DOWNHOT; break; - case WEST: state = State.LEFTHOT; break; - case EAST: state = State.RIGHTHOT; break; - } - } else if (jointRollover) { - switch (direction) { - case NORTH: state = State.UPHOVER; break; - case SOUTH: state = State.DOWNHOVER; break; - case WEST: state = State.LEFTHOVER; break; - case EAST: state = State.RIGHTHOVER; break; - } - } else { - switch (direction) { - case NORTH: state = State.UPNORMAL; break; - case SOUTH: state = State.DOWNNORMAL; break; - case WEST: state = State.LEFTNORMAL; break; - case EAST: state = State.RIGHTNORMAL; break; - } - } - - skin.paintSkin(g, 0, 0, getWidth(), getHeight(), state); - } else { - super.paint(g); - } - } - - public Dimension getPreferredSize() { - int size = 16; - if (scrollbar != null) { - switch (scrollbar.getOrientation()) { - case JScrollBar.VERTICAL: - size = scrollbar.getWidth(); - break; - case JScrollBar.HORIZONTAL: - size = scrollbar.getHeight(); - break; - } - size = Math.max(size, 5); - } - return new Dimension(size, size); - } - } - - - /** - * This should be pulled out into its own class if more classes need to - * use it. - *

    - * Grid is used to draw the track for windows scrollbars. Grids - * are cached in a HashMap, with the key being the rgb components - * of the foreground/background colors. Further the Grid is held through - * a WeakRef so that it can be freed when no longer needed. As the - * Grid is rather expensive to draw, it is drawn in a BufferedImage. - */ - private static class Grid { - private static final int BUFFER_SIZE = 64; - private static HashMap> map; - - private BufferedImage image; - - static { - map = new HashMap>(); - } - - public static Grid getGrid(Color fg, Color bg) { - String key = fg.getRGB() + " " + bg.getRGB(); - WeakReference ref = map.get(key); - Grid grid = (ref == null) ? null : ref.get(); - if (grid == null) { - grid = new Grid(fg, bg); - map.put(key, new WeakReference(grid)); - } - return grid; - } - - public Grid(Color fg, Color bg) { - int cmap[] = { fg.getRGB(), bg.getRGB() }; - IndexColorModel icm = new IndexColorModel(8, 2, cmap, 0, false, -1, - DataBuffer.TYPE_BYTE); - image = new BufferedImage(BUFFER_SIZE, BUFFER_SIZE, - BufferedImage.TYPE_BYTE_INDEXED, icm); - Graphics g = image.getGraphics(); - try { - g.setClip(0, 0, BUFFER_SIZE, BUFFER_SIZE); - paintGrid(g, fg, bg); - } - finally { - g.dispose(); - } - } - - /** - * Paints the grid into the specified Graphics at the specified - * location. - */ - public void paint(Graphics g, int x, int y, int w, int h) { - Rectangle clipRect = g.getClipBounds(); - int minX = Math.max(x, clipRect.x); - int minY = Math.max(y, clipRect.y); - int maxX = Math.min(clipRect.x + clipRect.width, x + w); - int maxY = Math.min(clipRect.y + clipRect.height, y + h); - - if (maxX <= minX || maxY <= minY) { - return; - } - int xOffset = (minX - x) % 2; - for (int xCounter = minX; xCounter < maxX; - xCounter += BUFFER_SIZE) { - int yOffset = (minY - y) % 2; - int width = Math.min(BUFFER_SIZE - xOffset, - maxX - xCounter); - - for (int yCounter = minY; yCounter < maxY; - yCounter += BUFFER_SIZE) { - int height = Math.min(BUFFER_SIZE - yOffset, - maxY - yCounter); - - g.drawImage(image, xCounter, yCounter, - xCounter + width, yCounter + height, - xOffset, yOffset, - xOffset + width, yOffset + height, null); - if (yOffset != 0) { - yCounter -= yOffset; - yOffset = 0; - } - } - if (xOffset != 0) { - xCounter -= xOffset; - xOffset = 0; - } - } - } - - /** - * Actually renders the grid into the Graphics g. - */ - private void paintGrid(Graphics g, Color fg, Color bg) { - Rectangle clipRect = g.getClipBounds(); - g.setColor(bg); - g.fillRect(clipRect.x, clipRect.y, clipRect.width, - clipRect.height); - g.setColor(fg); - g.translate(clipRect.x, clipRect.y); - int width = clipRect.width; - int height = clipRect.height; - int xCounter = clipRect.x % 2; - for (int end = width - height; xCounter < end; xCounter += 2) { - g.drawLine(xCounter, 0, xCounter + height, height); - } - for (int end = width; xCounter < end; xCounter += 2) { - g.drawLine(xCounter, 0, width, width - xCounter); - } - - int yCounter = ((clipRect.x % 2) == 0) ? 2 : 1; - for (int end = height - width; yCounter < end; yCounter += 2) { - g.drawLine(0, yCounter, width, yCounter + width); - } - for (int end = height; yCounter < end; yCounter += 2) { - g.drawLine(0, yCounter, height - yCounter, height); - } - g.translate(-clipRect.x, -clipRect.y); - } - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsScrollPaneUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsScrollPaneUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -/* - * Copyright (c) 1997, 1998, 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 com.sun.java.swing.plaf.windows; - -import javax.swing.plaf.basic.*; -import javax.swing.*; - - - -/** - * Windows rendition of the component. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - */ -public class WindowsScrollPaneUI extends BasicScrollPaneUI -{} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsSeparatorUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsSeparatorUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2002, 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 com.sun.java.swing.plaf.windows; - -import javax.swing.plaf.basic.*; - -/** - * Windows Separator. - */ -public class WindowsSeparatorUI extends BasicSeparatorUI { } diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsSliderUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsSliderUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,233 +0,0 @@ -/* - * Copyright (c) 1997, 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 com.sun.java.swing.plaf.windows; - -import java.awt.*; -import java.awt.event.MouseEvent; - -import javax.swing.plaf.*; -import javax.swing.plaf.basic.*; -import javax.swing.*; - -import static com.sun.java.swing.plaf.windows.TMSchema.*; -import static com.sun.java.swing.plaf.windows.XPStyle.Skin; - - -/** - * Windows rendition of the component. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - */ -public class WindowsSliderUI extends BasicSliderUI -{ - private boolean rollover = false; - private boolean pressed = false; - - public WindowsSliderUI(JSlider b){ - super(b); - } - - public static ComponentUI createUI(JComponent b) { - return new WindowsSliderUI((JSlider)b); - } - - - /** - * Overrides to return a private track listener subclass which handles - * the HOT, PRESSED, and FOCUSED states. - * @since 1.6 - */ - protected TrackListener createTrackListener(JSlider slider) { - return new WindowsTrackListener(); - } - - private class WindowsTrackListener extends TrackListener { - - public void mouseMoved(MouseEvent e) { - updateRollover(thumbRect.contains(e.getX(), e.getY())); - super.mouseMoved(e); - } - - public void mouseEntered(MouseEvent e) { - updateRollover(thumbRect.contains(e.getX(), e.getY())); - super.mouseEntered(e); - } - - public void mouseExited(MouseEvent e) { - updateRollover(false); - super.mouseExited(e); - } - - public void mousePressed(MouseEvent e) { - updatePressed(thumbRect.contains(e.getX(), e.getY())); - super.mousePressed(e); - } - - public void mouseReleased(MouseEvent e) { - updatePressed(false); - super.mouseReleased(e); - } - - public void updatePressed(boolean newPressed) { - // You can't press a disabled slider - if (!slider.isEnabled()) { - return; - } - if (pressed != newPressed) { - pressed = newPressed; - slider.repaint(thumbRect); - } - } - - public void updateRollover(boolean newRollover) { - // You can't have a rollover on a disabled slider - if (!slider.isEnabled()) { - return; - } - if (rollover != newRollover) { - rollover = newRollover; - slider.repaint(thumbRect); - } - } - - } - - - public void paintTrack(Graphics g) { - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - boolean vertical = (slider.getOrientation() == JSlider.VERTICAL); - Part part = vertical ? Part.TKP_TRACKVERT : Part.TKP_TRACK; - Skin skin = xp.getSkin(slider, part); - - if (vertical) { - int x = (trackRect.width - skin.getWidth()) / 2; - skin.paintSkin(g, trackRect.x + x, trackRect.y, - skin.getWidth(), trackRect.height, null); - } else { - int y = (trackRect.height - skin.getHeight()) / 2; - skin.paintSkin(g, trackRect.x, trackRect.y + y, - trackRect.width, skin.getHeight(), null); - } - } else { - super.paintTrack(g); - } - } - - - protected void paintMinorTickForHorizSlider( Graphics g, Rectangle tickBounds, int x ) { - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - g.setColor(xp.getColor(slider, Part.TKP_TICS, null, Prop.COLOR, Color.black)); - } - super.paintMinorTickForHorizSlider(g, tickBounds, x); - } - - protected void paintMajorTickForHorizSlider( Graphics g, Rectangle tickBounds, int x ) { - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - g.setColor(xp.getColor(slider, Part.TKP_TICS, null, Prop.COLOR, Color.black)); - } - super.paintMajorTickForHorizSlider(g, tickBounds, x); - } - - protected void paintMinorTickForVertSlider( Graphics g, Rectangle tickBounds, int y ) { - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - g.setColor(xp.getColor(slider, Part.TKP_TICSVERT, null, Prop.COLOR, Color.black)); - } - super.paintMinorTickForVertSlider(g, tickBounds, y); - } - - protected void paintMajorTickForVertSlider( Graphics g, Rectangle tickBounds, int y ) { - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - g.setColor(xp.getColor(slider, Part.TKP_TICSVERT, null, Prop.COLOR, Color.black)); - } - super.paintMajorTickForVertSlider(g, tickBounds, y); - } - - - public void paintThumb(Graphics g) { - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - Part part = getXPThumbPart(); - State state = State.NORMAL; - - if (slider.hasFocus()) { - state = State.FOCUSED; - } - if (rollover) { - state = State.HOT; - } - if (pressed) { - state = State.PRESSED; - } - if(!slider.isEnabled()) { - state = State.DISABLED; - } - - xp.getSkin(slider, part).paintSkin(g, thumbRect.x, thumbRect.y, state); - } else { - super.paintThumb(g); - } - } - - protected Dimension getThumbSize() { - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - Dimension size = new Dimension(); - Skin s = xp.getSkin(slider, getXPThumbPart()); - size.width = s.getWidth(); - size.height = s.getHeight(); - return size; - } else { - return super.getThumbSize(); - } - } - - private Part getXPThumbPart() { - Part part; - boolean vertical = (slider.getOrientation() == JSlider.VERTICAL); - boolean leftToRight = slider.getComponentOrientation().isLeftToRight(); - Boolean paintThumbArrowShape = - (Boolean)slider.getClientProperty("Slider.paintThumbArrowShape"); - if ((!slider.getPaintTicks() && paintThumbArrowShape == null) || - paintThumbArrowShape == Boolean.FALSE) { - part = vertical ? Part.TKP_THUMBVERT - : Part.TKP_THUMB; - } else { - part = vertical ? (leftToRight ? Part.TKP_THUMBRIGHT : Part.TKP_THUMBLEFT) - : Part.TKP_THUMBBOTTOM; - } - return part; - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsSpinnerUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsSpinnerUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,106 +0,0 @@ -/* - * Copyright (c) 1997, 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 com.sun.java.swing.plaf.windows; - -import java.awt.*; -import java.awt.event.*; - -import javax.swing.plaf.basic.*; -import javax.swing.plaf.*; -import javax.swing.*; - -import static com.sun.java.swing.plaf.windows.TMSchema.Part; -import static com.sun.java.swing.plaf.windows.TMSchema.State; -import static com.sun.java.swing.plaf.windows.XPStyle.Skin; - - -public class WindowsSpinnerUI extends BasicSpinnerUI { - public static ComponentUI createUI(JComponent c) { - return new WindowsSpinnerUI(); - } - - /** - * {@inheritDoc} - * @since 1.6 - */ - public void paint(Graphics g, JComponent c) { - if (XPStyle.getXP() != null) { - paintXPBackground(g, c); - } - super.paint(g,c); - } - - private State getXPState(JComponent c) { - State state = State.NORMAL; - if (!c.isEnabled()) { - state = State.DISABLED; - } - return state; - } - - private void paintXPBackground(Graphics g, JComponent c) { - XPStyle xp = XPStyle.getXP(); - if (xp == null) { - return; - } - Skin skin = xp.getSkin(c, Part.EP_EDIT); - State state = getXPState(c); - skin.paintSkin(g, 0, 0, c.getWidth(), c.getHeight(), state); - } - - protected Component createPreviousButton() { - if (XPStyle.getXP() != null) { - JButton xpButton = new XPStyle.GlyphButton(spinner, Part.SPNP_DOWN); - Dimension size = UIManager.getDimension("Spinner.arrowButtonSize"); - xpButton.setPreferredSize(size); - xpButton.setRequestFocusEnabled(false); - installPreviousButtonListeners(xpButton); - return xpButton; - } - return super.createPreviousButton(); - } - - protected Component createNextButton() { - if (XPStyle.getXP() != null) { - JButton xpButton = new XPStyle.GlyphButton(spinner, Part.SPNP_UP); - Dimension size = UIManager.getDimension("Spinner.arrowButtonSize"); - xpButton.setPreferredSize(size); - xpButton.setRequestFocusEnabled(false); - installNextButtonListeners(xpButton); - return xpButton; - } - return super.createNextButton(); - } - - private UIResource getUIResource(Object[] listeners) { - for (int counter = 0; counter < listeners.length; counter++) { - if (listeners[counter] instanceof UIResource) { - return (UIResource)listeners[counter]; - } - } - return null; - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsSplitPaneDivider.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsSplitPaneDivider.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright (c) 1998, 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 com.sun.java.swing.plaf.windows; - -import java.awt.*; -import javax.swing.JSplitPane; -import javax.swing.UIManager; -import javax.swing.plaf.basic.BasicSplitPaneUI; -import javax.swing.plaf.basic.BasicSplitPaneDivider; - - -/** - * Divider used for Windows split pane. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - * - * @author Jeff Dinkins - */ -@SuppressWarnings("serial") // Superclass is not serializable across versions -public class WindowsSplitPaneDivider extends BasicSplitPaneDivider -{ - - /** - * Creates a new Windows SplitPaneDivider - */ - public WindowsSplitPaneDivider(BasicSplitPaneUI ui) { - super(ui); - } - - /** - * Paints the divider. - */ - public void paint(Graphics g) { - Color bgColor = (splitPane.hasFocus()) ? - UIManager.getColor("SplitPane.shadow") : - getBackground(); - Dimension size = getSize(); - - if(bgColor != null) { - g.setColor(bgColor); - g.fillRect(0, 0, size.width, size.height); - } - super.paint(g); - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsSplitPaneUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsSplitPaneUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright (c) 1997, 1998, 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 com.sun.java.swing.plaf.windows; - -import javax.swing.plaf.basic.*; -import javax.swing.*; - -import javax.swing.plaf.basic.BasicSplitPaneUI; -import javax.swing.plaf.basic.BasicSplitPaneDivider; -import javax.swing.plaf.*; - - -/** - * Windows rendition of the component. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - */ -public class WindowsSplitPaneUI extends BasicSplitPaneUI -{ - - public WindowsSplitPaneUI() { - super(); - } - - /** - * Creates a new WindowsSplitPaneUI instance - */ - public static ComponentUI createUI(JComponent x) { - return new WindowsSplitPaneUI(); - } - - /** - * Creates the default divider. - */ - public BasicSplitPaneDivider createDefaultDivider() { - return new WindowsSplitPaneDivider(this); - } - -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsTabbedPaneUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsTabbedPaneUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,228 +0,0 @@ -/* - * Copyright (c) 1997, 2008, 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 com.sun.java.swing.plaf.windows; - -import java.awt.*; - -import javax.swing.plaf.basic.*; -import javax.swing.plaf.*; -import javax.swing.*; -import java.util.Set; -import java.util.HashSet; -import java.awt.event.*; - -import static com.sun.java.swing.plaf.windows.TMSchema.*; -import static com.sun.java.swing.plaf.windows.XPStyle.Skin; - - -/** - * Windows rendition of the component. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - */ -public class WindowsTabbedPaneUI extends BasicTabbedPaneUI { - /** - * Keys to use for forward focus traversal when the JComponent is - * managing focus. - */ - private static Set managingFocusForwardTraversalKeys; - - /** - * Keys to use for backward focus traversal when the JComponent is - * managing focus. - */ - private static Set managingFocusBackwardTraversalKeys; - - private boolean contentOpaque = true; - - @SuppressWarnings("deprecation") - protected void installDefaults() { - super.installDefaults(); - contentOpaque = UIManager.getBoolean("TabbedPane.contentOpaque"); - - // focus forward traversal key - if (managingFocusForwardTraversalKeys==null) { - managingFocusForwardTraversalKeys = new HashSet(); - managingFocusForwardTraversalKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0)); - } - tabPane.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, managingFocusForwardTraversalKeys); - // focus backward traversal key - if (managingFocusBackwardTraversalKeys==null) { - managingFocusBackwardTraversalKeys = new HashSet(); - managingFocusBackwardTraversalKeys.add( KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_MASK)); - } - tabPane.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, managingFocusBackwardTraversalKeys); - } - - protected void uninstallDefaults() { - // sets the focus forward and backward traversal keys to null - // to restore the defaults - tabPane.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null); - tabPane.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null); - super.uninstallDefaults(); - } - - public static ComponentUI createUI(JComponent c) { - return new WindowsTabbedPaneUI(); - } - - protected void setRolloverTab(int index) { - // Rollover is only supported on XP - if (XPStyle.getXP() != null) { - int oldRolloverTab = getRolloverTab(); - super.setRolloverTab(index); - Rectangle r1 = null; - Rectangle r2 = null; - if ( (oldRolloverTab >= 0) && (oldRolloverTab < tabPane.getTabCount()) ) { - r1 = getTabBounds(tabPane, oldRolloverTab); - } - if (index >= 0) { - r2 = getTabBounds(tabPane, index); - } - if (r1 != null) { - if (r2 != null) { - tabPane.repaint(r1.union(r2)); - } else { - tabPane.repaint(r1); - } - } else if (r2 != null) { - tabPane.repaint(r2); - } - } - } - - protected void paintContentBorder(Graphics g, int tabPlacement, int selectedIndex) { - XPStyle xp = XPStyle.getXP(); - if (xp != null && (contentOpaque || tabPane.isOpaque())) { - Skin skin = xp.getSkin(tabPane, Part.TABP_PANE); - if (skin != null) { - Insets insets = tabPane.getInsets(); - // Note: don't call getTabAreaInsets(), because it causes rotation. - // Make sure "TabbedPane.tabsOverlapBorder" is set to true in WindowsLookAndFeel - Insets tabAreaInsets = UIManager.getInsets("TabbedPane.tabAreaInsets"); - int x = insets.left; - int y = insets.top; - int w = tabPane.getWidth() - insets.right - insets.left; - int h = tabPane.getHeight() - insets.top - insets.bottom; - - // Expand area by tabAreaInsets.bottom to allow tabs to overlap onto the border. - if (tabPlacement == LEFT || tabPlacement == RIGHT) { - int tabWidth = calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth); - if (tabPlacement == LEFT) { - x += (tabWidth - tabAreaInsets.bottom); - } - w -= (tabWidth - tabAreaInsets.bottom); - } else { - int tabHeight = calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight); - if (tabPlacement == TOP) { - y += (tabHeight - tabAreaInsets.bottom); - } - h -= (tabHeight - tabAreaInsets.bottom); - } - - paintRotatedSkin(g, skin, tabPlacement, x, y, w, h, null); - return; - } - } - super.paintContentBorder(g, tabPlacement, selectedIndex); - } - - protected void paintTabBackground(Graphics g, int tabPlacement, int tabIndex, - int x, int y, int w, int h, boolean isSelected ) { - if (XPStyle.getXP() == null) { - super.paintTabBackground(g, tabPlacement, tabIndex, x, y, w, h, isSelected); - } - } - - protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex, - int x, int y, int w, int h, boolean isSelected ) { - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - Part part; - - int tabCount = tabPane.getTabCount(); - int tabRun = getRunForTab(tabCount, tabIndex); - if (tabRuns[tabRun] == tabIndex) { - part = Part.TABP_TABITEMLEFTEDGE; - } else if (tabCount > 1 && lastTabInRun(tabCount, tabRun) == tabIndex) { - part = Part.TABP_TABITEMRIGHTEDGE; - if (isSelected) { - // Align with right edge - if (tabPlacement == TOP || tabPlacement == BOTTOM) { - w++; - } else { - h++; - } - } - } else { - part = Part.TABP_TABITEM; - } - - State state = State.NORMAL; - if (isSelected) { - state = State.SELECTED; - } else if (tabIndex == getRolloverTab()) { - state = State.HOT; - } - - paintRotatedSkin(g, xp.getSkin(tabPane, part), tabPlacement, x, y, w, h, state); - } else { - super.paintTabBorder(g, tabPlacement, tabIndex, x, y, w, h, isSelected); - } - } - - private void paintRotatedSkin(Graphics g, Skin skin, int tabPlacement, - int x, int y, int w, int h, State state) { - Graphics2D g2d = (Graphics2D)g.create(); - g2d.translate(x, y); - switch (tabPlacement) { - case RIGHT: g2d.translate(w, 0); - g2d.rotate(Math.toRadians(90.0)); - skin.paintSkin(g2d, 0, 0, h, w, state); - break; - - case LEFT: g2d.scale(-1.0, 1.0); - g2d.rotate(Math.toRadians(90.0)); - skin.paintSkin(g2d, 0, 0, h, w, state); - break; - - case BOTTOM: g2d.translate(0, h); - g2d.scale(-1.0, 1.0); - g2d.rotate(Math.toRadians(180.0)); - skin.paintSkin(g2d, 0, 0, w, h, state); - break; - - case TOP: - default: skin.paintSkin(g2d, 0, 0, w, h, state); - } - g2d.dispose(); - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsTableHeaderUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsTableHeaderUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,247 +0,0 @@ -/* - * Copyright (c) 1997, 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 com.sun.java.swing.plaf.windows; - -import java.awt.*; -import javax.swing.*; -import javax.swing.border.*; -import javax.swing.plaf.*; -import javax.swing.plaf.basic.*; -import javax.swing.table.*; - -import static com.sun.java.swing.plaf.windows.TMSchema.*; -import static com.sun.java.swing.plaf.windows.XPStyle.*; -import sun.swing.table.*; -import sun.swing.SwingUtilities2; - - -public class WindowsTableHeaderUI extends BasicTableHeaderUI { - private TableCellRenderer originalHeaderRenderer; - - public static ComponentUI createUI(JComponent h) { - return new WindowsTableHeaderUI(); - } - - public void installUI(JComponent c) { - super.installUI(c); - - if (XPStyle.getXP() != null) { - originalHeaderRenderer = header.getDefaultRenderer(); - if (originalHeaderRenderer instanceof UIResource) { - header.setDefaultRenderer(new XPDefaultRenderer()); - } - } - } - - public void uninstallUI(JComponent c) { - if (header.getDefaultRenderer() instanceof XPDefaultRenderer) { - header.setDefaultRenderer(originalHeaderRenderer); - } - super.uninstallUI(c); - } - - @Override - protected void rolloverColumnUpdated(int oldColumn, int newColumn) { - if (XPStyle.getXP() != null) { - header.repaint(header.getHeaderRect(oldColumn)); - header.repaint(header.getHeaderRect(newColumn)); - } - } - - @SuppressWarnings("serial") // JDK-implementation class - private class XPDefaultRenderer extends DefaultTableCellHeaderRenderer { - Skin skin; - boolean isSelected, hasFocus, hasRollover; - int column; - - XPDefaultRenderer() { - setHorizontalAlignment(LEADING); - } - - public Component getTableCellRendererComponent(JTable table, Object value, - boolean isSelected, boolean hasFocus, - int row, int column) { - super.getTableCellRendererComponent(table, value, isSelected, - hasFocus, row, column); - this.isSelected = isSelected; - this.hasFocus = hasFocus; - this.column = column; - this.hasRollover = (column == getRolloverColumn()); - if (skin == null) { - XPStyle xp = XPStyle.getXP(); - skin = (xp != null) ? xp.getSkin(header, Part.HP_HEADERITEM) : null; - } - Insets margins = (skin != null) ? skin.getContentMargin() : null; - Border border = null; - int contentTop = 0; - int contentLeft = 0; - int contentBottom = 0; - int contentRight = 0; - if (margins != null) { - contentTop = margins.top; - contentLeft = margins.left; - contentBottom = margins.bottom; - contentRight = margins.right; - } - /* idk: - * Both on Vista and XP there is some offset to the - * HP_HEADERITEM content. It does not seem to come from - * Prop.CONTENTMARGINS. Do not know where it is defined. - * using some hardcoded values. - */ - contentLeft += 5; - contentBottom += 4; - contentRight += 5; - - /* On Vista sortIcon is painted above the header's text. - * We use border to paint it. - */ - Icon sortIcon; - if (WindowsLookAndFeel.isOnVista() - && ((sortIcon = getIcon()) instanceof javax.swing.plaf.UIResource - || sortIcon == null)) { - contentTop += 1; - setIcon(null); - sortIcon = null; - SortOrder sortOrder = - getColumnSortOrder(table, column); - if (sortOrder != null) { - switch (sortOrder) { - case ASCENDING: - sortIcon = - UIManager.getIcon("Table.ascendingSortIcon"); - break; - case DESCENDING: - sortIcon = - UIManager.getIcon("Table.descendingSortIcon"); - break; - } - } - if (sortIcon != null) { - contentBottom = sortIcon.getIconHeight(); - border = new IconBorder(sortIcon, contentTop, contentLeft, - contentBottom, contentRight); - } else { - sortIcon = - UIManager.getIcon("Table.ascendingSortIcon"); - int sortIconHeight = - (sortIcon != null) ? sortIcon.getIconHeight() : 0; - if (sortIconHeight != 0) { - contentBottom = sortIconHeight; - } - border = - new EmptyBorder( - sortIconHeight + contentTop, contentLeft, - contentBottom, contentRight); - } - } else { - contentTop += 3; - border = new EmptyBorder(contentTop, contentLeft, - contentBottom, contentRight); - } - setBorder(border); - return this; - } - - public void paint(Graphics g) { - Dimension size = getSize(); - State state = State.NORMAL; - TableColumn draggedColumn = header.getDraggedColumn(); - if (draggedColumn != null && - column == SwingUtilities2.convertColumnIndexToView( - header.getColumnModel(), draggedColumn.getModelIndex())) { - state = State.PRESSED; - } else if (isSelected || hasFocus || hasRollover) { - state = State.HOT; - } - /* on Vista there are more states for sorted columns */ - if (WindowsLookAndFeel.isOnVista()) { - SortOrder sortOrder = getColumnSortOrder(header.getTable(), column); - if (sortOrder != null) { - switch(sortOrder) { - case ASCENDING: - case DESCENDING: - switch (state) { - case NORMAL: - state = State.SORTEDNORMAL; - break; - case PRESSED: - state = State.SORTEDPRESSED; - break; - case HOT: - state = State.SORTEDHOT; - break; - default: - /* do nothing */ - } - break; - default : - /* do nothing */ - } - } - } - skin.paintSkin(g, 0, 0, size.width-1, size.height-1, state); - super.paint(g); - } - } - - /** - * A border with an Icon at the middle of the top side. - * Outer insets can be provided for this border. - */ - private static class IconBorder implements Border, UIResource{ - private final Icon icon; - private final int top; - private final int left; - private final int bottom; - private final int right; - /** - * Creates this border; - * @param icon - icon to paint for this border - * @param top, left, bottom, right - outer insets for this border - */ - public IconBorder(Icon icon, int top, int left, - int bottom, int right) { - this.icon = icon; - this.top = top; - this.left = left; - this.bottom = bottom; - this.right = right; - } - public Insets getBorderInsets(Component c) { - return new Insets(icon.getIconHeight() + top, left, bottom, right); - } - public boolean isBorderOpaque() { - return false; - } - public void paintBorder(Component c, Graphics g, int x, int y, - int width, int height) { - icon.paintIcon(c, g, - x + left + (width - left - right - icon.getIconWidth()) / 2, - y + top); - } - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsTextAreaUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsTextAreaUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -/* - * Copyright (c) 1997, 1998, 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 com.sun.java.swing.plaf.windows; - -import javax.swing.plaf.*; -import javax.swing.plaf.basic.*; -import javax.swing.*; -import javax.swing.text.Caret; - - - -/** - * Windows rendition of the component. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - */ -public class WindowsTextAreaUI extends BasicTextAreaUI { - /** - * Creates the object to use for a caret. By default an - * instance of WindowsCaret is created. This method - * can be redefined to provide something else that implements - * the InputPosition interface or a subclass of DefaultCaret. - * - * @return the caret object - */ - protected Caret createCaret() { - return new WindowsTextUI.WindowsCaret(); - } - - /** - * Creates a UI for a JTextField. - * - * @param c the text field - * @return the UI - */ - public static ComponentUI createUI(JComponent c) { - return new WindowsTextAreaUI(); - } - -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsTextFieldUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsTextFieldUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,177 +0,0 @@ -/* - * Copyright (c) 1997, 2013, 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 com.sun.java.swing.plaf.windows; - -import java.awt.*; -import java.awt.event.*; -import java.beans.PropertyChangeEvent; -import javax.swing.plaf.*; -import javax.swing.plaf.basic.BasicTextFieldUI; -import javax.swing.text.*; -import javax.swing.*; -import javax.swing.plaf.UIResource; -import sun.swing.DefaultLookup; - - - -/** - * Provides the Windows look and feel for a text field. This - * is basically the following customizations to the default - * look-and-feel. - *

      - *
    • The border is beveled (using the standard control color). - *
    • The background is white by default. - *
    • The highlight color is a dark color, blue by default. - *
    • The foreground color is high contrast in the selected - * area, white by default. The unselected foreground is black. - *
    • The cursor blinks at about 1/2 second intervals. - *
    • The entire value is selected when focus is gained. - *
    • Shift-left-arrow and shift-right-arrow extend selection - *
    • Ctrl-left-arrow and ctrl-right-arrow act like home and - * end respectively. - *
    - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - * - * @author Timothy Prinzing - */ -public class WindowsTextFieldUI extends BasicTextFieldUI -{ - /** - * Creates a UI for a JTextField. - * - * @param c the text field - * @return the UI - */ - public static ComponentUI createUI(JComponent c) { - return new WindowsTextFieldUI(); - } - - /** - * Paints a background for the view. This will only be - * called if isOpaque() on the associated component is - * true. The default is to paint the background color - * of the component. - * - * @param g the graphics context - */ - protected void paintBackground(Graphics g) { - super.paintBackground(g); - } - - /** - * Creates the caret for a field. - * - * @return the caret - */ - protected Caret createCaret() { - return new WindowsFieldCaret(); - } - - /** - * WindowsFieldCaret has different scrolling behavior than - * DefaultCaret. - */ - @SuppressWarnings("serial") // Superclass is not serializable across versions - static class WindowsFieldCaret extends DefaultCaret implements UIResource { - - public WindowsFieldCaret() { - super(); - } - - /** - * Adjusts the visibility of the caret according to - * the windows feel which seems to be to move the - * caret out into the field by about a quarter of - * a field length if not visible. - */ - protected void adjustVisibility(Rectangle r) { - SwingUtilities.invokeLater(new SafeScroller(r)); - } - - /** - * Gets the painter for the Highlighter. - * - * @return the painter - */ - protected Highlighter.HighlightPainter getSelectionPainter() { - return WindowsTextUI.WindowsPainter; - } - - - private class SafeScroller implements Runnable { - SafeScroller(Rectangle r) { - this.r = r; - } - - @SuppressWarnings("deprecation") - public void run() { - JTextField field = (JTextField) getComponent(); - if (field != null) { - TextUI ui = field.getUI(); - int dot = getDot(); - // PENDING: We need to expose the bias in DefaultCaret. - Position.Bias bias = Position.Bias.Forward; - Rectangle startRect = null; - try { - startRect = ui.modelToView(field, dot, bias); - } catch (BadLocationException ble) {} - - Insets i = field.getInsets(); - BoundedRangeModel vis = field.getHorizontalVisibility(); - int x = r.x + vis.getValue() - i.left; - int quarterSpan = vis.getExtent() / 4; - if (r.x < i.left) { - vis.setValue(x - quarterSpan); - } else if (r.x + r.width > i.left + vis.getExtent()) { - vis.setValue(x - (3 * quarterSpan)); - } - // If we scroll, our visual location will have changed, - // but we won't have updated our internal location as - // the model hasn't changed. This checks for the change, - // and if necessary, resets the internal location. - if (startRect != null) { - try { - Rectangle endRect; - endRect = ui.modelToView(field, dot, bias); - if (endRect != null && !endRect.equals(startRect)){ - damage(endRect); - } - } catch (BadLocationException ble) {} - } - } - } - - private Rectangle r; - } - } - -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsTextPaneUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsTextPaneUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright (c) 1997, 1998, 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 com.sun.java.swing.plaf.windows; - -import javax.swing.plaf.*; -import javax.swing.plaf.basic.*; -import javax.swing.*; -import javax.swing.text.Caret; - - -/** - * Windows rendition of the component. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - */ -public class WindowsTextPaneUI extends BasicTextPaneUI -{ - /** - * Creates a UI for a JTextPane. - * - * @param c the styled text component - * @return the UI - */ - public static ComponentUI createUI(JComponent c) { - return new WindowsTextPaneUI(); - } - - /** - * Creates the object to use for a caret. By default an - * instance of WindowsCaret is created. This method - * can be redefined to provide something else that implements - * the InputPosition interface or a subclass of DefaultCaret. - * - * @return the caret object - */ - protected Caret createCaret() { - return new WindowsTextUI.WindowsCaret(); - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsTextUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsTextUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,238 +0,0 @@ -/* - * Copyright (c) 1997, 2013, 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 com.sun.java.swing.plaf.windows; - -import java.awt.Color; -import java.awt.Graphics; -import java.awt.Rectangle; -import java.awt.Shape; -import javax.swing.plaf.basic.*; -import javax.swing.*; -import javax.swing.plaf.TextUI; -import javax.swing.plaf.UIResource; -import javax.swing.text.*; - -/** - * Windows text rendering. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - */ -public abstract class WindowsTextUI extends BasicTextUI { - /** - * Creates the object to use for a caret. By default an - * instance of WindowsCaret is created. This method - * can be redefined to provide something else that implements - * the InputPosition interface or a subclass of DefaultCaret. - * - * @return the caret object - */ - protected Caret createCaret() { - return new WindowsCaret(); - } - - /* public */ - static LayeredHighlighter.LayerPainter WindowsPainter = new WindowsHighlightPainter(null); - - /* public */ - @SuppressWarnings("serial") // Superclass is not serializable across versions - static class WindowsCaret extends DefaultCaret - implements UIResource { - /** - * Gets the painter for the Highlighter. - * - * @return the painter - */ - protected Highlighter.HighlightPainter getSelectionPainter() { - return WindowsTextUI.WindowsPainter; - } - } - - /* public */ - static class WindowsHighlightPainter extends - DefaultHighlighter.DefaultHighlightPainter { - WindowsHighlightPainter(Color c) { - super(c); - } - - // --- HighlightPainter methods --------------------------------------- - - /** - * Paints a highlight. - * - * @param g the graphics context - * @param offs0 the starting model offset >= 0 - * @param offs1 the ending model offset >= offs1 - * @param bounds the bounding box for the highlight - * @param c the editor - */ - @SuppressWarnings("deprecation") - public void paint(Graphics g, int offs0, int offs1, Shape bounds, JTextComponent c) { - Rectangle alloc = bounds.getBounds(); - try { - // --- determine locations --- - TextUI mapper = c.getUI(); - Rectangle p0 = mapper.modelToView(c, offs0); - Rectangle p1 = mapper.modelToView(c, offs1); - - // --- render --- - Color color = getColor(); - - if (color == null) { - g.setColor(c.getSelectionColor()); - } - else { - g.setColor(color); - } - boolean firstIsDot = false; - boolean secondIsDot = false; - if (c.isEditable()) { - int dot = c.getCaretPosition(); - firstIsDot = (offs0 == dot); - secondIsDot = (offs1 == dot); - } - if (p0.y == p1.y) { - // same line, render a rectangle - Rectangle r = p0.union(p1); - if (r.width > 0) { - if (firstIsDot) { - r.x++; - r.width--; - } - else if (secondIsDot) { - r.width--; - } - } - g.fillRect(r.x, r.y, r.width, r.height); - } else { - // different lines - int p0ToMarginWidth = alloc.x + alloc.width - p0.x; - if (firstIsDot && p0ToMarginWidth > 0) { - p0.x++; - p0ToMarginWidth--; - } - g.fillRect(p0.x, p0.y, p0ToMarginWidth, p0.height); - if ((p0.y + p0.height) != p1.y) { - g.fillRect(alloc.x, p0.y + p0.height, alloc.width, - p1.y - (p0.y + p0.height)); - } - if (secondIsDot && p1.x > alloc.x) { - p1.x--; - } - g.fillRect(alloc.x, p1.y, (p1.x - alloc.x), p1.height); - } - } catch (BadLocationException e) { - // can't render - } - } - - // --- LayerPainter methods ---------------------------- - /** - * Paints a portion of a highlight. - * - * @param g the graphics context - * @param offs0 the starting model offset >= 0 - * @param offs1 the ending model offset >= offs1 - * @param bounds the bounding box of the view, which is not - * necessarily the region to paint. - * @param c the editor - * @param view View painting for - * @return region drawing occurred in - */ - public Shape paintLayer(Graphics g, int offs0, int offs1, - Shape bounds, JTextComponent c, View view) { - Color color = getColor(); - - if (color == null) { - g.setColor(c.getSelectionColor()); - } - else { - g.setColor(color); - } - boolean firstIsDot = false; - boolean secondIsDot = false; - if (c.isEditable()) { - int dot = c.getCaretPosition(); - firstIsDot = (offs0 == dot); - secondIsDot = (offs1 == dot); - } - if (offs0 == view.getStartOffset() && - offs1 == view.getEndOffset()) { - // Contained in view, can just use bounds. - Rectangle alloc; - if (bounds instanceof Rectangle) { - alloc = (Rectangle)bounds; - } - else { - alloc = bounds.getBounds(); - } - if (firstIsDot && alloc.width > 0) { - g.fillRect(alloc.x + 1, alloc.y, alloc.width - 1, - alloc.height); - } - else if (secondIsDot && alloc.width > 0) { - g.fillRect(alloc.x, alloc.y, alloc.width - 1, - alloc.height); - } - else { - g.fillRect(alloc.x, alloc.y, alloc.width, alloc.height); - } - return alloc; - } - else { - // Should only render part of View. - try { - // --- determine locations --- - Shape shape = view.modelToView(offs0, Position.Bias.Forward, - offs1,Position.Bias.Backward, - bounds); - Rectangle r = (shape instanceof Rectangle) ? - (Rectangle)shape : shape.getBounds(); - if (firstIsDot && r.width > 0) { - g.fillRect(r.x + 1, r.y, r.width - 1, r.height); - } - else if (secondIsDot && r.width > 0) { - g.fillRect(r.x, r.y, r.width - 1, r.height); - } - else { - g.fillRect(r.x, r.y, r.width, r.height); - } - return r; - } catch (BadLocationException e) { - // can't render - } - } - // Only if exception - return null; - } - - } - -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsToggleButtonUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsToggleButtonUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,181 +0,0 @@ -/* - * Copyright (c) 1997, 2006, 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 com.sun.java.swing.plaf.windows; - -import sun.awt.AppContext; - -import javax.swing.plaf.basic.*; -import javax.swing.border.*; -import javax.swing.plaf.*; -import javax.swing.*; - -import java.awt.*; -import java.beans.PropertyChangeEvent; - - - -/** - * A Windows toggle button. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - * - * @author Jeff Dinkins - */ -public class WindowsToggleButtonUI extends BasicToggleButtonUI -{ - protected int dashedRectGapX; - protected int dashedRectGapY; - protected int dashedRectGapWidth; - protected int dashedRectGapHeight; - - protected Color focusColor; - - private static final Object WINDOWS_TOGGLE_BUTTON_UI_KEY = new Object(); - - private boolean defaults_initialized = false; - - public static ComponentUI createUI(JComponent b) { - AppContext appContext = AppContext.getAppContext(); - WindowsToggleButtonUI windowsToggleButtonUI = - (WindowsToggleButtonUI) appContext.get(WINDOWS_TOGGLE_BUTTON_UI_KEY); - if (windowsToggleButtonUI == null) { - windowsToggleButtonUI = new WindowsToggleButtonUI(); - appContext.put(WINDOWS_TOGGLE_BUTTON_UI_KEY, windowsToggleButtonUI); - } - return windowsToggleButtonUI; - } - - - // ******************************** - // Defaults - // ******************************** - protected void installDefaults(AbstractButton b) { - super.installDefaults(b); - if(!defaults_initialized) { - String pp = getPropertyPrefix(); - dashedRectGapX = ((Integer)UIManager.get("Button.dashedRectGapX")).intValue(); - dashedRectGapY = ((Integer)UIManager.get("Button.dashedRectGapY")).intValue(); - dashedRectGapWidth = ((Integer)UIManager.get("Button.dashedRectGapWidth")).intValue(); - dashedRectGapHeight = ((Integer)UIManager.get("Button.dashedRectGapHeight")).intValue(); - focusColor = UIManager.getColor(pp + "focus"); - defaults_initialized = true; - } - - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - b.setBorder(xp.getBorder(b, WindowsButtonUI.getXPButtonType(b))); - LookAndFeel.installProperty(b, "opaque", Boolean.FALSE); - LookAndFeel.installProperty(b, "rolloverEnabled", Boolean.TRUE); - } - } - - protected void uninstallDefaults(AbstractButton b) { - super.uninstallDefaults(b); - defaults_initialized = false; - } - - - protected Color getFocusColor() { - return focusColor; - } - - - // ******************************** - // Paint Methods - // ******************************** - - private transient Color cachedSelectedColor = null; - private transient Color cachedBackgroundColor = null; - private transient Color cachedHighlightColor = null; - - protected void paintButtonPressed(Graphics g, AbstractButton b) { - if (XPStyle.getXP() == null && b.isContentAreaFilled()) { - Color oldColor = g.getColor(); - Color c1 = b.getBackground(); - Color c2 = UIManager.getColor("ToggleButton.highlight"); - if (c1 != cachedBackgroundColor || c2 != cachedHighlightColor) { - int r1 = c1.getRed(), r2 = c2.getRed(); - int g1 = c1.getGreen(), g2 = c2.getGreen(); - int b1 = c1.getBlue(), b2 = c2.getBlue(); - cachedSelectedColor = new Color( - Math.min(r1, r2) + Math.abs(r1 - r2) / 2, - Math.min(g1, g2) + Math.abs(g1 - g2) / 2, - Math.min(b1, b2) + Math.abs(b1 - b2) / 2 - ); - cachedBackgroundColor = c1; - cachedHighlightColor = c2; - } - g.setColor(cachedSelectedColor); - g.fillRect(0, 0, b.getWidth(), b.getHeight()); - g.setColor(oldColor); - } - } - - public void paint(Graphics g, JComponent c) { - if (XPStyle.getXP() != null) { - WindowsButtonUI.paintXPButtonBackground(g, c); - } - super.paint(g, c); - } - - - /** - * Overridden method to render the text without the mnemonic - */ - protected void paintText(Graphics g, AbstractButton b, Rectangle textRect, String text) { - WindowsGraphicsUtils.paintText(g, b, textRect, text, getTextShiftOffset()); - } - - protected void paintFocus(Graphics g, AbstractButton b, - Rectangle viewRect, Rectangle textRect, Rectangle iconRect) { - g.setColor(getFocusColor()); - BasicGraphicsUtils.drawDashedRect(g, dashedRectGapX, dashedRectGapY, - b.getWidth() - dashedRectGapWidth, - b.getHeight() - dashedRectGapHeight); - } - - // ******************************** - // Layout Methods - // ******************************** - public Dimension getPreferredSize(JComponent c) { - Dimension d = super.getPreferredSize(c); - - /* Ensure that the width and height of the button is odd, - * to allow for the focus line if focus is painted - */ - AbstractButton b = (AbstractButton)c; - if (d != null && b.isFocusPainted()) { - if(d.width % 2 == 0) { d.width += 1; } - if(d.height % 2 == 0) { d.height += 1; } - } - return d; - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsToolBarSeparatorUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsToolBarSeparatorUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,123 +0,0 @@ -/* - * Copyright (c) 1997, 2005, 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 com.sun.java.swing.plaf.windows; - -import java.awt.*; - -import javax.swing.plaf.ComponentUI; -import javax.swing.plaf.basic.*; -import javax.swing.*; - -import static com.sun.java.swing.plaf.windows.TMSchema.Part; -import static com.sun.java.swing.plaf.windows.XPStyle.Skin; - - -/** - * Draws Windows toolbar separators. - * - * @author Mark Davidson - */ -public class WindowsToolBarSeparatorUI extends BasicToolBarSeparatorUI { - - public static ComponentUI createUI( JComponent c ) { - return new WindowsToolBarSeparatorUI(); - } - - public Dimension getPreferredSize(JComponent c) { - Dimension size = ((JToolBar.Separator)c).getSeparatorSize(); - - if (size != null) { - size = size.getSize(); - } else { - size = new Dimension(6, 6); - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - boolean vertical = ((JSeparator)c).getOrientation() == SwingConstants.VERTICAL; - Part part = vertical ? Part.TP_SEPARATOR : Part.TP_SEPARATORVERT; - Skin skin = xp.getSkin(c, part); - size.width = skin.getWidth(); - size.height = skin.getHeight(); - } - - if (((JSeparator)c).getOrientation() == SwingConstants.VERTICAL) { - size.height = 0; - } else { - size.width = 0; - } - } - return size; - } - - public Dimension getMaximumSize(JComponent c) { - Dimension pref = getPreferredSize(c); - if (((JSeparator)c).getOrientation() == SwingConstants.VERTICAL) { - return new Dimension(pref.width, Short.MAX_VALUE); - } else { - return new Dimension(Short.MAX_VALUE, pref.height); - } - } - - public void paint( Graphics g, JComponent c ) { - boolean vertical = ((JSeparator)c).getOrientation() == SwingConstants.VERTICAL; - Dimension size = c.getSize(); - - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - Part part = vertical ? Part.TP_SEPARATOR : Part.TP_SEPARATORVERT; - Skin skin = xp.getSkin(c, part); - - int dx = vertical ? (size.width - skin.getWidth()) / 2 : 0; - int dy = vertical ? 0 : (size.height - skin.getHeight()) / 2; - int dw = vertical ? skin.getWidth() : size.width; - int dh = vertical ? size.height : skin.getHeight(); - skin.paintSkin(g, dx, dy, dw, dh, null); - } else { - - Color temp = g.getColor(); - - UIDefaults table = UIManager.getLookAndFeelDefaults(); - - Color shadow = table.getColor("ToolBar.shadow"); - Color highlight = table.getColor("ToolBar.highlight"); - - if (vertical) { - int x = (size.width / 2) - 1; - g.setColor(shadow); - g.drawLine(x, 2, x, size.height - 2); - - g.setColor(highlight); - g.drawLine(x + 1, 2, x + 1, size.height - 2); - } else { - int y = (size.height / 2) - 1; - g.setColor(shadow); - g.drawLine(2, y, size.width - 2, y); - g.setColor(highlight); - g.drawLine(2, y + 1, size.width - 2, y + 1); - } - g.setColor(temp); - } - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsToolBarUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsToolBarUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,99 +0,0 @@ -/* - * Copyright (c) 1997, 2006, 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 com.sun.java.swing.plaf.windows; - -import java.awt.*; - -import javax.swing.AbstractButton; -import javax.swing.JComponent; -import javax.swing.JToggleButton; -import javax.swing.UIDefaults; -import javax.swing.UIManager; - -import javax.swing.border.Border; -import javax.swing.border.CompoundBorder; -import javax.swing.border.EmptyBorder; - -import javax.swing.plaf.*; - -import javax.swing.plaf.basic.BasicBorders; -import javax.swing.plaf.basic.BasicToolBarUI; - -import static com.sun.java.swing.plaf.windows.TMSchema.Part; - - -public class WindowsToolBarUI extends BasicToolBarUI { - - public static ComponentUI createUI(JComponent c) { - return new WindowsToolBarUI(); - } - - protected void installDefaults() { - if (XPStyle.getXP() != null) { - setRolloverBorders(true); - } - super.installDefaults(); - } - - protected Border createRolloverBorder() { - if (XPStyle.getXP() != null) { - return new EmptyBorder(3, 3, 3, 3); - } else { - return super.createRolloverBorder(); - } - } - - protected Border createNonRolloverBorder() { - if (XPStyle.getXP() != null) { - return new EmptyBorder(3, 3, 3, 3); - } else { - return super.createNonRolloverBorder(); - } - } - - public void paint(Graphics g, JComponent c) { - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - xp.getSkin(c, Part.TP_TOOLBAR).paintSkin(g, 0, 0, - c.getWidth(), c.getHeight(), null, true); - } else { - super.paint(g, c); - } - } - - /** - * {@inheritDoc} - * @since 1.6 - */ - protected Border getRolloverBorder(AbstractButton b) { - XPStyle xp = XPStyle.getXP(); - if (xp != null) { - return xp.getBorder(b, WindowsButtonUI.getXPButtonType(b)); - } else { - return super.getRolloverBorder(b); - } - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsTreeUI.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsTreeUI.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,245 +0,0 @@ -/* - * Copyright (c) 1997, 2013, 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 com.sun.java.swing.plaf.windows; - -import java.awt.*; -import java.awt.event.*; - -import java.io.*; -import java.util.*; - -import javax.swing.plaf.basic.*; -import javax.swing.*; -import javax.swing.plaf.*; - -import javax.swing.tree.*; - -import static com.sun.java.swing.plaf.windows.TMSchema.*; -import static com.sun.java.swing.plaf.windows.XPStyle.Skin; - - -/** - * A Windows tree. - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - * - * @author Scott Violet - */ -public class WindowsTreeUI extends BasicTreeUI { - - public static ComponentUI createUI( JComponent c ) - { - return new WindowsTreeUI(); - } - - - /** - * Ensures that the rows identified by beginRow through endRow are - * visible. - */ - protected void ensureRowsAreVisible(int beginRow, int endRow) { - if(tree != null && beginRow >= 0 && endRow < getRowCount(tree)) { - Rectangle visRect = tree.getVisibleRect(); - if(beginRow == endRow) { - Rectangle scrollBounds = getPathBounds(tree, getPathForRow - (tree, beginRow)); - - if(scrollBounds != null) { - scrollBounds.x = visRect.x; - scrollBounds.width = visRect.width; - tree.scrollRectToVisible(scrollBounds); - } - } - else { - Rectangle beginRect = getPathBounds(tree, getPathForRow - (tree, beginRow)); - if (beginRect != null) { - Rectangle testRect = beginRect; - int beginY = beginRect.y; - int maxY = beginY + visRect.height; - - for(int counter = beginRow + 1; counter <= endRow; counter++) { - testRect = getPathBounds(tree, - getPathForRow(tree, counter)); - if(testRect != null && (testRect.y + testRect.height) > maxY) { - counter = endRow; - } - } - - if (testRect == null) { - return; - } - - tree.scrollRectToVisible(new Rectangle(visRect.x, beginY, 1, - testRect.y + testRect.height- - beginY)); - } - } - } - } - - protected static final int HALF_SIZE = 4; - protected static final int SIZE = 9; - - /** - * Returns the default cell renderer that is used to do the - * stamping of each node. - */ - protected TreeCellRenderer createDefaultCellRenderer() { - return new WindowsTreeCellRenderer(); - } - - /** - * The minus sign button icon - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - */ - @SuppressWarnings("serial") // Same-version serialization only - public static class ExpandedIcon implements Icon, Serializable { - - public static Icon createExpandedIcon() { - return new ExpandedIcon(); - } - - Skin getSkin(Component c) { - XPStyle xp = XPStyle.getXP(); - return (xp != null) ? xp.getSkin(c, Part.TVP_GLYPH) : null; - } - - public void paintIcon(Component c, Graphics g, int x, int y) { - Skin skin = getSkin(c); - if (skin != null) { - skin.paintSkin(g, x, y, State.OPENED); - return; - } - - Color backgroundColor = c.getBackground(); - - if(backgroundColor != null) - g.setColor(backgroundColor); - else - g.setColor(Color.white); - g.fillRect(x, y, SIZE-1, SIZE-1); - g.setColor(Color.gray); - g.drawRect(x, y, SIZE-1, SIZE-1); - g.setColor(Color.black); - g.drawLine(x + 2, y + HALF_SIZE, x + (SIZE - 3), y + HALF_SIZE); - } - - public int getIconWidth() { - Skin skin = getSkin(null); - return (skin != null) ? skin.getWidth() : SIZE; - } - - public int getIconHeight() { - Skin skin = getSkin(null); - return (skin != null) ? skin.getHeight() : SIZE; - } - } - - /** - * The plus sign button icon - *

    - * Warning: - * Serialized objects of this class will not be compatible with - * future Swing releases. The current serialization support is appropriate - * for short term storage or RMI between applications running the same - * version of Swing. A future release of Swing will provide support for - * long term persistence. - */ - @SuppressWarnings("serial") // Superclass is not serializable across versions - public static class CollapsedIcon extends ExpandedIcon { - public static Icon createCollapsedIcon() { - return new CollapsedIcon(); - } - - public void paintIcon(Component c, Graphics g, int x, int y) { - Skin skin = getSkin(c); - if (skin != null) { - skin.paintSkin(g, x, y, State.CLOSED); - } else { - super.paintIcon(c, g, x, y); - g.drawLine(x + HALF_SIZE, y + 2, x + HALF_SIZE, y + (SIZE - 3)); - } - } - } - - @SuppressWarnings("serial") // Superclass is not serializable across versions - public class WindowsTreeCellRenderer extends DefaultTreeCellRenderer { - - /** - * Configures the renderer based on the passed in components. - * The value is set from messaging the tree with - * convertValueToText, which ultimately invokes - * toString on value. - * The foreground color is set based on the selection and the icon - * is set based on on leaf and expanded. - */ - public Component getTreeCellRendererComponent(JTree tree, Object value, - boolean sel, - boolean expanded, - boolean leaf, int row, - boolean hasFocus) { - super.getTreeCellRendererComponent(tree, value, sel, - expanded, leaf, row, - hasFocus); - // Windows displays the open icon when the tree item selected. - if (!tree.isEnabled()) { - setEnabled(false); - if (leaf) { - setDisabledIcon(getLeafIcon()); - } else if (sel) { - setDisabledIcon(getOpenIcon()); - } else { - setDisabledIcon(getClosedIcon()); - } - } - else { - setEnabled(true); - if (leaf) { - setIcon(getLeafIcon()); - } else if (sel) { - setIcon(getOpenIcon()); - } else { - setIcon(getClosedIcon()); - } - } - return this; - } - - } - -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/XPStyle.java --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/XPStyle.java Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,774 +0,0 @@ -/* - * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - *

    These classes are designed to be used while the - * corresponding LookAndFeel class has been installed - * (UIManager.setLookAndFeel(new XXXLookAndFeel())). - * Using them while a different LookAndFeel is installed - * may produce unexpected results, including exceptions. - * Additionally, changing the LookAndFeel - * maintained by the UIManager without updating the - * corresponding ComponentUI of any - * JComponents may also produce unexpected results, - * such as the wrong colors showing up, and is generally not - * encouraged. - * - */ - -package com.sun.java.swing.plaf.windows; - -import java.awt.*; -import java.awt.image.*; -import java.security.AccessController; -import java.util.*; - -import javax.swing.*; -import javax.swing.border.*; -import javax.swing.plaf.*; -import javax.swing.text.JTextComponent; - -import sun.awt.image.SunWritableRaster; -import sun.awt.windows.ThemeReader; -import sun.security.action.GetPropertyAction; -import sun.swing.CachedPainter; - -import static com.sun.java.swing.plaf.windows.TMSchema.*; - - -/** - * Implements Windows XP Styles for the Windows Look and Feel. - * - * @author Leif Samuelsson - */ -class XPStyle { - // Singleton instance of this class - private static XPStyle xp; - - // Singleton instance of SkinPainter - private static SkinPainter skinPainter = new SkinPainter(); - - private static Boolean themeActive = null; - - private HashMap borderMap; - private HashMap colorMap; - - private boolean flatMenus; - - static { - invalidateStyle(); - } - - /** Static method for clearing the hashmap and loading the - * current XP style and theme - */ - static synchronized void invalidateStyle() { - xp = null; - themeActive = null; - skinPainter.flush(); - } - - /** Get the singleton instance of this class - * - * @return the singleton instance of this class or null if XP styles - * are not active or if this is not Windows XP - */ - static synchronized XPStyle getXP() { - if (themeActive == null) { - Toolkit toolkit = Toolkit.getDefaultToolkit(); - themeActive = - (Boolean)toolkit.getDesktopProperty("win.xpstyle.themeActive"); - if (themeActive == null) { - themeActive = Boolean.FALSE; - } - if (themeActive.booleanValue()) { - GetPropertyAction propertyAction = - new GetPropertyAction("swing.noxp"); - if (AccessController.doPrivileged(propertyAction) == null && - ThemeReader.isThemed() && - !(UIManager.getLookAndFeel() - instanceof WindowsClassicLookAndFeel)) { - - xp = new XPStyle(); - } - } - } - return ThemeReader.isXPStyleEnabled() ? xp : null; - } - - static boolean isVista() { - XPStyle xp = XPStyle.getXP(); - return (xp != null && xp.isSkinDefined(null, Part.CP_DROPDOWNBUTTONRIGHT)); - } - - /** Get a named String value from the current style - * - * @param part a Part - * @param state a String - * @param prop a String - * @return a String or null if key is not found - * in the current style - * - * This is currently only used by WindowsInternalFrameTitlePane for painting - * title foregound and can be removed when no longer needed - */ - String getString(Component c, Part part, State state, Prop prop) { - return getTypeEnumName(c, part, state, prop); - } - - TypeEnum getTypeEnum(Component c, Part part, State state, Prop prop) { - int enumValue = ThemeReader.getEnum(part.getControlName(c), part.getValue(), - State.getValue(part, state), - prop.getValue()); - return TypeEnum.getTypeEnum(prop, enumValue); - } - - private static String getTypeEnumName(Component c, Part part, State state, Prop prop) { - int enumValue = ThemeReader.getEnum(part.getControlName(c), part.getValue(), - State.getValue(part, state), - prop.getValue()); - if (enumValue == -1) { - return null; - } - return TypeEnum.getTypeEnum(prop, enumValue).getName(); - } - - - - - /** Get a named int value from the current style - * - * @param part a Part - * @return an int or null if key is not found - * in the current style - */ - int getInt(Component c, Part part, State state, Prop prop, int fallback) { - return ThemeReader.getInt(part.getControlName(c), part.getValue(), - State.getValue(part, state), - prop.getValue()); - } - - /** Get a named Dimension value from the current style - * - * @return a Dimension or null if key is not found - * in the current style - * - * This is currently only used by WindowsProgressBarUI and the value - * should probably be cached there instead of here. - */ - Dimension getDimension(Component c, Part part, State state, Prop prop) { - Dimension d = ThemeReader.getPosition(part.getControlName(c), part.getValue(), - State.getValue(part, state), - prop.getValue()); - return (d != null) ? d : new Dimension(); - } - - /** Get a named Point (e.g. a location or an offset) value - * from the current style - * - * @return a Point or null if key is not found - * in the current style - * - * This is currently only used by WindowsInternalFrameTitlePane for painting - * title foregound and can be removed when no longer needed - */ - Point getPoint(Component c, Part part, State state, Prop prop) { - Dimension d = ThemeReader.getPosition(part.getControlName(c), part.getValue(), - State.getValue(part, state), - prop.getValue()); - return (d != null) ? new Point(d.width, d.height) : new Point(); - } - - /** Get a named Insets value from the current style - * - * @return an Insets object or null if key is not found - * in the current style - * - * This is currently only used to create borders and by - * WindowsInternalFrameTitlePane for painting title foregound. - * The return value is already cached in those places. - */ - Insets getMargin(Component c, Part part, State state, Prop prop) { - Insets insets = ThemeReader.getThemeMargins(part.getControlName(c), part.getValue(), - State.getValue(part, state), - prop.getValue()); - return (insets != null) ? insets : new Insets(0, 0, 0, 0); - } - - - /** Get a named Color value from the current style - * - * @return a Color or null if key is not found - * in the current style - */ - synchronized Color getColor(Skin skin, Prop prop, Color fallback) { - String key = skin.toString() + "." + prop.name(); - Part part = skin.part; - Color color = colorMap.get(key); - if (color == null) { - color = ThemeReader.getColor(part.getControlName(null), part.getValue(), - State.getValue(part, skin.state), - prop.getValue()); - if (color != null) { - color = new ColorUIResource(color); - colorMap.put(key, color); - } - } - return (color != null) ? color : fallback; - } - - Color getColor(Component c, Part part, State state, Prop prop, Color fallback) { - return getColor(new Skin(c, part, state), prop, fallback); - } - - - - /** Get a named Border value from the current style - * - * @param part a Part - * @return a Border or null if key is not found - * in the current style or if the style for the particular - * part is not defined as "borderfill". - */ - synchronized Border getBorder(Component c, Part part) { - if (part == Part.MENU) { - // Special case because XP has no skin for menus - if (flatMenus) { - // TODO: The classic border uses this color, but we should - // create a new UI property called "PopupMenu.borderColor" - // instead. - return new XPFillBorder(UIManager.getColor("InternalFrame.borderShadow"), - 1); - } else { - return null; // Will cause L&F to use classic border - } - } - Skin skin = new Skin(c, part, null); - Border border = borderMap.get(skin.string); - if (border == null) { - String bgType = getTypeEnumName(c, part, null, Prop.BGTYPE); - if ("borderfill".equalsIgnoreCase(bgType)) { - int thickness = getInt(c, part, null, Prop.BORDERSIZE, 1); - Color color = getColor(skin, Prop.BORDERCOLOR, Color.black); - border = new XPFillBorder(color, thickness); - if (part == Part.CP_COMBOBOX) { - border = new XPStatefulFillBorder(color, thickness, part, Prop.BORDERCOLOR); - } - } else if ("imagefile".equalsIgnoreCase(bgType)) { - Insets m = getMargin(c, part, null, Prop.SIZINGMARGINS); - if (m != null) { - if (getBoolean(c, part, null, Prop.BORDERONLY)) { - border = new XPImageBorder(c, part); - } else if (part == Part.CP_COMBOBOX) { - border = new EmptyBorder(1, 1, 1, 1); - } else { - if(part == Part.TP_BUTTON) { - border = new XPEmptyBorder(new Insets(3,3,3,3)); - } else { - border = new XPEmptyBorder(m); - } - } - } - } - if (border != null) { - borderMap.put(skin.string, border); - } - } - return border; - } - - @SuppressWarnings("serial") // Superclass is not serializable across versions - private class XPFillBorder extends LineBorder implements UIResource { - XPFillBorder(Color color, int thickness) { - super(color, thickness); - } - - public Insets getBorderInsets(Component c, Insets insets) { - Insets margin = null; - // - // Ideally we'd have an interface defined for classes which - // support margins (to avoid this hackery), but we've - // decided against it for simplicity - // - if (c instanceof AbstractButton) { - margin = ((AbstractButton)c).getMargin(); - } else if (c instanceof JToolBar) { - margin = ((JToolBar)c).getMargin(); - } else if (c instanceof JTextComponent) { - margin = ((JTextComponent)c).getMargin(); - } - insets.top = (margin != null? margin.top : 0) + thickness; - insets.left = (margin != null? margin.left : 0) + thickness; - insets.bottom = (margin != null? margin.bottom : 0) + thickness; - insets.right = (margin != null? margin.right : 0) + thickness; - - return insets; - } - } - - @SuppressWarnings("serial") // Superclass is not serializable across versions - private class XPStatefulFillBorder extends XPFillBorder { - private final Part part; - private final Prop prop; - XPStatefulFillBorder(Color color, int thickness, Part part, Prop prop) { - super(color, thickness); - this.part = part; - this.prop = prop; - } - - public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { - State state = State.NORMAL; - // special casing for comboboxes. - // there may be more special cases in the future - if(c instanceof JComboBox) { - JComboBox cb = (JComboBox)c; - // note. in the future this should be replaced with a call - // to BasicLookAndFeel.getUIOfType() - if(cb.getUI() instanceof WindowsComboBoxUI) { - WindowsComboBoxUI wcb = (WindowsComboBoxUI)cb.getUI(); - state = wcb.getXPComboBoxState(cb); - } - } - lineColor = getColor(c, part, state, prop, Color.black); - super.paintBorder(c, g, x, y, width, height); - } - } - - @SuppressWarnings("serial") // Superclass is not serializable across versions - private class XPImageBorder extends AbstractBorder implements UIResource { - Skin skin; - - XPImageBorder(Component c, Part part) { - this.skin = getSkin(c, part); - } - - public void paintBorder(Component c, Graphics g, - int x, int y, int width, int height) { - skin.paintSkin(g, x, y, width, height, null); - } - - public Insets getBorderInsets(Component c, Insets insets) { - Insets margin = null; - Insets borderInsets = skin.getContentMargin(); - if(borderInsets == null) { - borderInsets = new Insets(0, 0, 0, 0); - } - // - // Ideally we'd have an interface defined for classes which - // support margins (to avoid this hackery), but we've - // decided against it for simplicity - // - if (c instanceof AbstractButton) { - margin = ((AbstractButton)c).getMargin(); - } else if (c instanceof JToolBar) { - margin = ((JToolBar)c).getMargin(); - } else if (c instanceof JTextComponent) { - margin = ((JTextComponent)c).getMargin(); - } - insets.top = (margin != null? margin.top : 0) + borderInsets.top; - insets.left = (margin != null? margin.left : 0) + borderInsets.left; - insets.bottom = (margin != null? margin.bottom : 0) + borderInsets.bottom; - insets.right = (margin != null? margin.right : 0) + borderInsets.right; - - return insets; - } - } - - @SuppressWarnings("serial") // Superclass is not serializable across versions - private class XPEmptyBorder extends EmptyBorder implements UIResource { - XPEmptyBorder(Insets m) { - super(m.top+2, m.left+2, m.bottom+2, m.right+2); - } - - public Insets getBorderInsets(Component c, Insets insets) { - insets = super.getBorderInsets(c, insets); - - Insets margin = null; - if (c instanceof AbstractButton) { - Insets m = ((AbstractButton)c).getMargin(); - // if this is a toolbar button then ignore getMargin() - // and subtract the padding added by the constructor - if(c.getParent() instanceof JToolBar - && ! (c instanceof JRadioButton) - && ! (c instanceof JCheckBox) - && m instanceof InsetsUIResource) { - insets.top -= 2; - insets.left -= 2; - insets.bottom -= 2; - insets.right -= 2; - } else { - margin = m; - } - } else if (c instanceof JToolBar) { - margin = ((JToolBar)c).getMargin(); - } else if (c instanceof JTextComponent) { - margin = ((JTextComponent)c).getMargin(); - } - if (margin != null) { - insets.top = margin.top + 2; - insets.left = margin.left + 2; - insets.bottom = margin.bottom + 2; - insets.right = margin.right + 2; - } - return insets; - } - } - boolean isSkinDefined(Component c, Part part) { - return (part.getValue() == 0) - || ThemeReader.isThemePartDefined( - part.getControlName(c), part.getValue(), 0); - } - - - /** Get a Skin object from the current style - * for a named part (component type) - * - * @param part a Part - * @return a Skin object - */ - synchronized Skin getSkin(Component c, Part part) { - assert isSkinDefined(c, part) : "part " + part + " is not defined"; - return new Skin(c, part, null); - } - - - long getThemeTransitionDuration(Component c, Part part, State stateFrom, - State stateTo, Prop prop) { - return ThemeReader.getThemeTransitionDuration(part.getControlName(c), - part.getValue(), - State.getValue(part, stateFrom), - State.getValue(part, stateTo), - (prop != null) ? prop.getValue() : 0); - } - - - /** A class which encapsulates attributes for a given part - * (component type) and which provides methods for painting backgrounds - * and glyphs - */ - static class Skin { - final Component component; - final Part part; - final State state; - - private final String string; - private Dimension size = null; - private boolean switchStates = false; - - Skin(Component component, Part part) { - this(component, part, null); - } - - Skin(Part part, State state) { - this(null, part, state); - } - - Skin(Component component, Part part, State state) { - this.component = component; - this.part = part; - this.state = state; - - String str = part.getControlName(component) +"." + part.name(); - if (state != null) { - str += "("+state.name()+")"; - } - string = str; - } - - Insets getContentMargin() { - /* idk: it seems margins are the same for all 'big enough' - * bounding rectangles. - */ - int boundingWidth = 100; - int boundingHeight = 100; - - Insets insets = ThemeReader.getThemeBackgroundContentMargins( - part.getControlName(null), part.getValue(), - 0, boundingWidth, boundingHeight); - return (insets != null) ? insets : new Insets(0, 0, 0, 0); - } - - boolean haveToSwitchStates() { - return switchStates; - } - - void switchStates(boolean b) { - switchStates = b; - } - - private int getWidth(State state) { - if (size == null) { - size = getPartSize(part, state); - } - return (size != null) ? size.width : 0; - } - - int getWidth() { - return getWidth((state != null) ? state : State.NORMAL); - } - - private int getHeight(State state) { - if (size == null) { - size = getPartSize(part, state); - } - return (size != null) ? size.height : 0; - } - - int getHeight() { - return getHeight((state != null) ? state : State.NORMAL); - } - - public String toString() { - return string; - } - - public boolean equals(Object obj) { - return (obj instanceof Skin && ((Skin)obj).string.equals(string)); - } - - public int hashCode() { - return string.hashCode(); - } - - /** Paint a skin at x, y. - * - * @param g the graphics context to use for painting - * @param dx the destination x coordinate - * @param dy the destination y coordinate - * @param state which state to paint - */ - void paintSkin(Graphics g, int dx, int dy, State state) { - if (state == null) { - state = this.state; - } - paintSkin(g, dx, dy, getWidth(state), getHeight(state), state); - } - - /** Paint a skin in an area defined by a rectangle. - * - * @param g the graphics context to use for painting - * @param r a Rectangle defining the area to fill, - * may cause the image to be stretched or tiled - * @param state which state to paint - */ - void paintSkin(Graphics g, Rectangle r, State state) { - paintSkin(g, r.x, r.y, r.width, r.height, state); - } - - /** Paint a skin at a defined position and size - * This method supports animation. - * - * @param g the graphics context to use for painting - * @param dx the destination x coordinate - * @param dy the destination y coordinate - * @param dw the width of the area to fill, may cause - * the image to be stretched or tiled - * @param dh the height of the area to fill, may cause - * the image to be stretched or tiled - * @param state which state to paint - */ - void paintSkin(Graphics g, int dx, int dy, int dw, int dh, State state) { - if (XPStyle.getXP() == null) { - return; - } - if (ThemeReader.isGetThemeTransitionDurationDefined() - && component instanceof JComponent - && SwingUtilities.getAncestorOfClass(CellRendererPane.class, - component) == null) { - AnimationController.paintSkin((JComponent) component, this, - g, dx, dy, dw, dh, state); - } else { - paintSkinRaw(g, dx, dy, dw, dh, state); - } - } - - /** Paint a skin at a defined position and size. This method - * does not trigger animation. It is needed for the animation - * support. - * - * @param g the graphics context to use for painting - * @param dx the destination x coordinate. - * @param dy the destination y coordinate. - * @param dw the width of the area to fill, may cause - * the image to be stretched or tiled - * @param dh the height of the area to fill, may cause - * the image to be stretched or tiled - * @param state which state to paint - */ - void paintSkinRaw(Graphics g, int dx, int dy, int dw, int dh, State state) { - if (XPStyle.getXP() == null) { - return; - } - skinPainter.paint(null, g, dx, dy, dw, dh, this, state); - } - - /** Paint a skin at a defined position and size - * - * @param g the graphics context to use for painting - * @param dx the destination x coordinate - * @param dy the destination y coordinate - * @param dw the width of the area to fill, may cause - * the image to be stretched or tiled - * @param dh the height of the area to fill, may cause - * the image to be stretched or tiled - * @param state which state to paint - * @param borderFill should test if the component uses a border fill - and skip painting if it is - */ - void paintSkin(Graphics g, int dx, int dy, int dw, int dh, State state, - boolean borderFill) { - if (XPStyle.getXP() == null) { - return; - } - if(borderFill && "borderfill".equals(getTypeEnumName(component, part, - state, Prop.BGTYPE))) { - return; - } - skinPainter.paint(null, g, dx, dy, dw, dh, this, state); - } - } - - private static class SkinPainter extends CachedPainter { - SkinPainter() { - super(30); - flush(); - } - - public void flush() { - super.flush(); - } - - protected void paintToImage(Component c, Image image, Graphics g, - int w, int h, Object[] args) { - Skin skin = (Skin)args[0]; - Part part = skin.part; - State state = (State)args[1]; - if (state == null) { - state = skin.state; - } - if (c == null) { - c = skin.component; - } - BufferedImage bi = (BufferedImage)image; - w = bi.getWidth(); - h = bi.getHeight(); - - WritableRaster raster = bi.getRaster(); - DataBufferInt dbi = (DataBufferInt)raster.getDataBuffer(); - // Note that stealData() requires a markDirty() afterwards - // since we modify the data in it. - ThemeReader.paintBackground(SunWritableRaster.stealData(dbi, 0), - part.getControlName(c), part.getValue(), - State.getValue(part, state), - 0, 0, w, h, w); - SunWritableRaster.markDirty(dbi); - } - - protected Image createImage(Component c, int w, int h, - GraphicsConfiguration config, Object[] args) { - return new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); - } - } - - @SuppressWarnings("serial") // Superclass is not serializable across versions - static class GlyphButton extends JButton { - protected Skin skin; - - public GlyphButton(Component parent, Part part) { - XPStyle xp = getXP(); - skin = xp != null ? xp.getSkin(parent, part) : null; - setBorder(null); - setContentAreaFilled(false); - setMinimumSize(new Dimension(5, 5)); - setPreferredSize(new Dimension(16, 16)); - setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE)); - } - - @SuppressWarnings("deprecation") - public boolean isFocusTraversable() { - return false; - } - - protected State getState() { - State state = State.NORMAL; - if (!isEnabled()) { - state = State.DISABLED; - } else if (getModel().isPressed()) { - state = State.PRESSED; - } else if (getModel().isRollover()) { - state = State.HOT; - } - return state; - } - - public void paintComponent(Graphics g) { - if (XPStyle.getXP() == null || skin == null) { - return; - } - Dimension d = getSize(); - skin.paintSkin(g, 0, 0, d.width, d.height, getState()); - } - - public void setPart(Component parent, Part part) { - XPStyle xp = getXP(); - skin = xp != null ? xp.getSkin(parent, part) : null; - revalidate(); - repaint(); - } - - protected void paintBorder(Graphics g) { - } - - - } - - // Private constructor - private XPStyle() { - flatMenus = getSysBoolean(Prop.FLATMENUS); - - colorMap = new HashMap(); - borderMap = new HashMap(); - // Note: All further access to the maps must be synchronized - } - - - private boolean getBoolean(Component c, Part part, State state, Prop prop) { - return ThemeReader.getBoolean(part.getControlName(c), part.getValue(), - State.getValue(part, state), - prop.getValue()); - } - - - - static Dimension getPartSize(Part part, State state) { - return ThemeReader.getPartSize(part.getControlName(null), part.getValue(), - State.getValue(part, state)); - } - - private static boolean getSysBoolean(Prop prop) { - // We can use any widget name here, I guess. - return ThemeReader.getSysBoolean("window", prop.getValue()); - } -} diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/Computer.gif Binary file src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/Computer.gif has changed diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/DetailsView.gif Binary file src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/DetailsView.gif has changed diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/Directory.gif Binary file src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/Directory.gif has changed diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/Error.gif Binary file src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/Error.gif has changed diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/File.gif Binary file src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/File.gif has changed diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/FloppyDrive.gif Binary file src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/FloppyDrive.gif has changed diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/HardDrive.gif Binary file src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/HardDrive.gif has changed diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/HomeFolder.gif Binary file src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/HomeFolder.gif has changed diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/Inform.gif Binary file src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/Inform.gif has changed diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/JavaCup32.png Binary file src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/JavaCup32.png has changed diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/ListView.gif Binary file src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/ListView.gif has changed diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/NewFolder.gif Binary file src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/NewFolder.gif has changed diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/Question.gif Binary file src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/Question.gif has changed diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/TreeClosed.gif Binary file src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/TreeClosed.gif has changed diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/TreeLeaf.gif Binary file src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/TreeLeaf.gif has changed diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/TreeOpen.gif Binary file src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/TreeOpen.gif has changed diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/UpFolder.gif Binary file src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/UpFolder.gif has changed diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/Warn.gif Binary file src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/Warn.gif has changed diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/image-delayed.png Binary file src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/image-delayed.png has changed diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/image-failed.png Binary file src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/icons/image-failed.png has changed diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/resources/windows.properties --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/resources/windows.properties Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -# This properties file is used to create a PropertyResourceBundle -# It contains Locale specific strings used be the Windows Look and Feel. -# Currently, the following components need this for support: -# -# FileChooser -# -# When this file is read in, the strings are put into the -# defaults table. This is an implementation detail of the current -# workings of Swing. DO NOT DEPEND ON THIS. -# This may change in future versions of Swing as we improve localization -# support. -# -# Refer to the note in basic.properties for a description as to what -# the mnemonics correspond to and how to calculate them. -# -# @author Steve Wilson - - -############ FILE CHOOSER STRINGS ############# - -FileChooser.lookInLabel.textAndMnemonic=Look &in: -FileChooser.saveInLabel.textAndMnemonic=Save in: -FileChooser.fileNameLabel.textAndMnemonic=File &name: -FileChooser.folderNameLabel.textAndMnemonic=Folder &name: -FileChooser.filesOfTypeLabel.textAndMnemonic=Files of &type: -FileChooser.upFolderToolTip.textAndMnemonic=Up One Level -FileChooser.upFolderAccessibleName=Up -FileChooser.homeFolderToolTip.textAndMnemonic=Home -FileChooser.homeFolderAccessibleName=Home -FileChooser.newFolderToolTip.textAndMnemonic=Create New Folder -FileChooser.newFolderAccessibleName=New Folder -FileChooser.newFolderActionLabel.textAndMnemonic=New Folder -FileChooser.listViewButtonToolTip.textAndMnemonic=List -FileChooser.listViewButtonAccessibleName=List -FileChooser.listViewActionLabel.textAndMnemonic=List -FileChooser.detailsViewButtonToolTip.textAndMnemonic=Details -FileChooser.detailsViewButtonAccessibleName=Details -FileChooser.viewMenuButtonToolTipText = View Menu -FileChooser.viewMenuButtonAccessibleName = View Menu -FileChooser.detailsViewActionLabel.textAndMnemonic=Details -FileChooser.refreshActionLabel.textAndMnemonic=Refresh -FileChooser.viewMenuLabel.textAndMnemonic=View -FileChooser.fileNameHeader.textAndMnemonic=Name -FileChooser.fileSizeHeader.textAndMnemonic=Size -FileChooser.fileTypeHeader.textAndMnemonic=Type -FileChooser.fileDateHeader.textAndMnemonic=Modified -FileChooser.fileAttrHeader.textAndMnemonic=Attributes diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/resources/windows_de.properties --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/resources/windows_de.properties Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -# This properties file is used to create a PropertyResourceBundle -# It contains Locale specific strings used be the Windows Look and Feel. -# Currently, the following components need this for support: -# -# FileChooser -# -# When this file is read in, the strings are put into the -# defaults table. This is an implementation detail of the current -# workings of Swing. DO NOT DEPEND ON THIS. -# This may change in future versions of Swing as we improve localization -# support. -# -# Refer to the note in basic.properties for a description as to what -# the mnemonics correspond to and how to calculate them. -# -# @author Steve Wilson - - -############ FILE CHOOSER STRINGS ############# - -FileChooser.lookInLabel.textAndMnemonic=Suchen &in: -FileChooser.saveInLabel.textAndMnemonic=Speichern in: -FileChooser.fileNameLabel.textAndMnemonic=&Dateiname: -FileChooser.folderNameLabel.textAndMnemonic=Ordner&name: -FileChooser.filesOfTypeLabel.textAndMnemonic=Datei&typ: -FileChooser.upFolderToolTip.textAndMnemonic=Eine Ebene h\u00F6her -FileChooser.upFolderAccessibleName=Nach oben -FileChooser.homeFolderToolTip.textAndMnemonic=Home -FileChooser.homeFolderAccessibleName=Home -FileChooser.newFolderToolTip.textAndMnemonic=Neuen Ordner erstellen -FileChooser.newFolderAccessibleName=Neuer Ordner -FileChooser.newFolderActionLabel.textAndMnemonic=Neuer Ordner -FileChooser.listViewButtonToolTip.textAndMnemonic=Liste -FileChooser.listViewButtonAccessibleName=Liste -FileChooser.listViewActionLabel.textAndMnemonic=Liste -FileChooser.detailsViewButtonToolTip.textAndMnemonic=Details -FileChooser.detailsViewButtonAccessibleName=Details -FileChooser.viewMenuButtonToolTipText = Ansichtsmen\u00FC -FileChooser.viewMenuButtonAccessibleName = Ansichtsmen\u00FC -FileChooser.detailsViewActionLabel.textAndMnemonic=Details -FileChooser.refreshActionLabel.textAndMnemonic=Aktualisieren -FileChooser.viewMenuLabel.textAndMnemonic=Ansicht -FileChooser.fileNameHeader.textAndMnemonic=Name -FileChooser.fileSizeHeader.textAndMnemonic=Gr\u00F6\u00DFe -FileChooser.fileTypeHeader.textAndMnemonic=Typ -FileChooser.fileDateHeader.textAndMnemonic=Ge\u00E4ndert -FileChooser.fileAttrHeader.textAndMnemonic=Attribute diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/resources/windows_es.properties --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/resources/windows_es.properties Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -# This properties file is used to create a PropertyResourceBundle -# It contains Locale specific strings used be the Windows Look and Feel. -# Currently, the following components need this for support: -# -# FileChooser -# -# When this file is read in, the strings are put into the -# defaults table. This is an implementation detail of the current -# workings of Swing. DO NOT DEPEND ON THIS. -# This may change in future versions of Swing as we improve localization -# support. -# -# Refer to the note in basic.properties for a description as to what -# the mnemonics correspond to and how to calculate them. -# -# @author Steve Wilson - - -############ FILE CHOOSER STRINGS ############# - -FileChooser.lookInLabel.textAndMnemonic=&Buscar en: -FileChooser.saveInLabel.textAndMnemonic=Guardar en: -FileChooser.fileNameLabel.textAndMnemonic=&Nombre de archivo: -FileChooser.folderNameLabel.textAndMnemonic=&Nombre de carpeta: -FileChooser.filesOfTypeLabel.textAndMnemonic=Archivos de &tipo: -FileChooser.upFolderToolTip.textAndMnemonic=Subir un Nivel -FileChooser.upFolderAccessibleName=Arriba -FileChooser.homeFolderToolTip.textAndMnemonic=Inicio -FileChooser.homeFolderAccessibleName=Inicio -FileChooser.newFolderToolTip.textAndMnemonic=Crear Nueva Carpeta -FileChooser.newFolderAccessibleName=Nueva Carpeta -FileChooser.newFolderActionLabel.textAndMnemonic=Nueva Carpeta -FileChooser.listViewButtonToolTip.textAndMnemonic=Lista -FileChooser.listViewButtonAccessibleName=Lista -FileChooser.listViewActionLabel.textAndMnemonic=Lista -FileChooser.detailsViewButtonToolTip.textAndMnemonic=Detalles -FileChooser.detailsViewButtonAccessibleName=Detalles -FileChooser.viewMenuButtonToolTipText = Men\u00FA Ver -FileChooser.viewMenuButtonAccessibleName = Men\u00FA Ver -FileChooser.detailsViewActionLabel.textAndMnemonic=Detalles -FileChooser.refreshActionLabel.textAndMnemonic=Refrescar -FileChooser.viewMenuLabel.textAndMnemonic=Ver -FileChooser.fileNameHeader.textAndMnemonic=Nombre -FileChooser.fileSizeHeader.textAndMnemonic=Tama\u00F1o -FileChooser.fileTypeHeader.textAndMnemonic=Tipo -FileChooser.fileDateHeader.textAndMnemonic=Modificado -FileChooser.fileAttrHeader.textAndMnemonic=Atributos diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/resources/windows_fr.properties --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/resources/windows_fr.properties Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -# This properties file is used to create a PropertyResourceBundle -# It contains Locale specific strings used be the Windows Look and Feel. -# Currently, the following components need this for support: -# -# FileChooser -# -# When this file is read in, the strings are put into the -# defaults table. This is an implementation detail of the current -# workings of Swing. DO NOT DEPEND ON THIS. -# This may change in future versions of Swing as we improve localization -# support. -# -# Refer to the note in basic.properties for a description as to what -# the mnemonics correspond to and how to calculate them. -# -# @author Steve Wilson - - -############ FILE CHOOSER STRINGS ############# - -FileChooser.lookInLabel.textAndMnemonic=Rechercher &dans : -FileChooser.saveInLabel.textAndMnemonic=Enregistrer dans : -FileChooser.fileNameLabel.textAndMnemonic=&Nom du fichier : -FileChooser.folderNameLabel.textAndMnemonic=&Nom du dossier : -FileChooser.filesOfTypeLabel.textAndMnemonic=&Type de fichier : -FileChooser.upFolderToolTip.textAndMnemonic=Remonte d'un niveau. -FileChooser.upFolderAccessibleName=Monter -FileChooser.homeFolderToolTip.textAndMnemonic=R\u00E9pertoire de base -FileChooser.homeFolderAccessibleName=R\u00E9pertoire de base -FileChooser.newFolderToolTip.textAndMnemonic=Cr\u00E9e un dossier. -FileChooser.newFolderAccessibleName=Nouveau dossier -FileChooser.newFolderActionLabel.textAndMnemonic=Nouveau dossier -FileChooser.listViewButtonToolTip.textAndMnemonic=Liste -FileChooser.listViewButtonAccessibleName=Liste -FileChooser.listViewActionLabel.textAndMnemonic=Liste -FileChooser.detailsViewButtonToolTip.textAndMnemonic=D\u00E9tails -FileChooser.detailsViewButtonAccessibleName=D\u00E9tails -FileChooser.viewMenuButtonToolTipText = Menu Affichage -FileChooser.viewMenuButtonAccessibleName = Menu Affichage -FileChooser.detailsViewActionLabel.textAndMnemonic=D\u00E9tails -FileChooser.refreshActionLabel.textAndMnemonic=Actualiser -FileChooser.viewMenuLabel.textAndMnemonic=Affichage -FileChooser.fileNameHeader.textAndMnemonic=Nom -FileChooser.fileSizeHeader.textAndMnemonic=Taille -FileChooser.fileTypeHeader.textAndMnemonic=Type -FileChooser.fileDateHeader.textAndMnemonic=Modifi\u00E9 -FileChooser.fileAttrHeader.textAndMnemonic=Attributs diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/resources/windows_it.properties --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/resources/windows_it.properties Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -# This properties file is used to create a PropertyResourceBundle -# It contains Locale specific strings used be the Windows Look and Feel. -# Currently, the following components need this for support: -# -# FileChooser -# -# When this file is read in, the strings are put into the -# defaults table. This is an implementation detail of the current -# workings of Swing. DO NOT DEPEND ON THIS. -# This may change in future versions of Swing as we improve localization -# support. -# -# Refer to the note in basic.properties for a description as to what -# the mnemonics correspond to and how to calculate them. -# -# @author Steve Wilson - - -############ FILE CHOOSER STRINGS ############# - -FileChooser.lookInLabel.textAndMnemonic=Cerca &in: -FileChooser.saveInLabel.textAndMnemonic=Salva in: -FileChooser.fileNameLabel.textAndMnemonic=&Nome file: -FileChooser.folderNameLabel.textAndMnemonic=&Nome cartella: -FileChooser.filesOfTypeLabel.textAndMnemonic=&Tipo file: -FileChooser.upFolderToolTip.textAndMnemonic=Cartella superiore -FileChooser.upFolderAccessibleName=Superiore -FileChooser.homeFolderToolTip.textAndMnemonic=Home -FileChooser.homeFolderAccessibleName=Home -FileChooser.newFolderToolTip.textAndMnemonic=Crea nuova cartella -FileChooser.newFolderAccessibleName=Nuova cartella -FileChooser.newFolderActionLabel.textAndMnemonic=Nuova cartella -FileChooser.listViewButtonToolTip.textAndMnemonic=Lista -FileChooser.listViewButtonAccessibleName=Lista -FileChooser.listViewActionLabel.textAndMnemonic=Lista -FileChooser.detailsViewButtonToolTip.textAndMnemonic=Dettagli -FileChooser.detailsViewButtonAccessibleName=Dettagli -FileChooser.viewMenuButtonToolTipText = Visualizza menu -FileChooser.viewMenuButtonAccessibleName = Visualizza menu -FileChooser.detailsViewActionLabel.textAndMnemonic=Dettagli -FileChooser.refreshActionLabel.textAndMnemonic=Aggiorna -FileChooser.viewMenuLabel.textAndMnemonic=Visualizza -FileChooser.fileNameHeader.textAndMnemonic=Nome -FileChooser.fileSizeHeader.textAndMnemonic=Dimensioni -FileChooser.fileTypeHeader.textAndMnemonic=Tipo -FileChooser.fileDateHeader.textAndMnemonic=Modificato -FileChooser.fileAttrHeader.textAndMnemonic=Attributi diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/resources/windows_ja.properties --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/resources/windows_ja.properties Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -# This properties file is used to create a PropertyResourceBundle -# It contains Locale specific strings used be the Windows Look and Feel. -# Currently, the following components need this for support: -# -# FileChooser -# -# When this file is read in, the strings are put into the -# defaults table. This is an implementation detail of the current -# workings of Swing. DO NOT DEPEND ON THIS. -# This may change in future versions of Swing as we improve localization -# support. -# -# Refer to the note in basic.properties for a description as to what -# the mnemonics correspond to and how to calculate them. -# -# @author Steve Wilson - - -############ FILE CHOOSER STRINGS ############# - -FileChooser.lookInLabel.textAndMnemonic=\u30D5\u30A1\u30A4\u30EB\u306E\u5834\u6240(&I): -FileChooser.saveInLabel.textAndMnemonic=\u4FDD\u5B58: -FileChooser.fileNameLabel.textAndMnemonic=\u30D5\u30A1\u30A4\u30EB\u540D(&N): -FileChooser.folderNameLabel.textAndMnemonic=\u30D5\u30A9\u30EB\u30C0\u540D(&N): -FileChooser.filesOfTypeLabel.textAndMnemonic=\u30D5\u30A1\u30A4\u30EB\u306E\u30BF\u30A4\u30D7(&T): -FileChooser.upFolderToolTip.textAndMnemonic=1\u30EC\u30D9\u30EB\u4E0A\u3078 -FileChooser.upFolderAccessibleName=\u4E0A\u3078 -FileChooser.homeFolderToolTip.textAndMnemonic=\u30DB\u30FC\u30E0 -FileChooser.homeFolderAccessibleName=\u30DB\u30FC\u30E0 -FileChooser.newFolderToolTip.textAndMnemonic=\u65B0\u898F\u30D5\u30A9\u30EB\u30C0\u306E\u4F5C\u6210 -FileChooser.newFolderAccessibleName=\u65B0\u898F\u30D5\u30A9\u30EB\u30C0 -FileChooser.newFolderActionLabel.textAndMnemonic=\u65B0\u898F\u30D5\u30A9\u30EB\u30C0 -FileChooser.listViewButtonToolTip.textAndMnemonic=\u30EA\u30B9\u30C8 -FileChooser.listViewButtonAccessibleName=\u30EA\u30B9\u30C8 -FileChooser.listViewActionLabel.textAndMnemonic=\u30EA\u30B9\u30C8 -FileChooser.detailsViewButtonToolTip.textAndMnemonic=\u8A73\u7D30 -FileChooser.detailsViewButtonAccessibleName=\u8A73\u7D30 -FileChooser.viewMenuButtonToolTipText = \u8868\u793A\u30E1\u30CB\u30E5\u30FC -FileChooser.viewMenuButtonAccessibleName = \u8868\u793A\u30E1\u30CB\u30E5\u30FC -FileChooser.detailsViewActionLabel.textAndMnemonic=\u8A73\u7D30 -FileChooser.refreshActionLabel.textAndMnemonic=\u30EA\u30D5\u30EC\u30C3\u30B7\u30E5 -FileChooser.viewMenuLabel.textAndMnemonic=\u8868\u793A -FileChooser.fileNameHeader.textAndMnemonic=\u540D\u524D -FileChooser.fileSizeHeader.textAndMnemonic=\u30B5\u30A4\u30BA -FileChooser.fileTypeHeader.textAndMnemonic=\u30BF\u30A4\u30D7 -FileChooser.fileDateHeader.textAndMnemonic=\u4FEE\u6B63\u65E5 -FileChooser.fileAttrHeader.textAndMnemonic=\u5C5E\u6027 diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/resources/windows_ko.properties --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/resources/windows_ko.properties Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -# This properties file is used to create a PropertyResourceBundle -# It contains Locale specific strings used be the Windows Look and Feel. -# Currently, the following components need this for support: -# -# FileChooser -# -# When this file is read in, the strings are put into the -# defaults table. This is an implementation detail of the current -# workings of Swing. DO NOT DEPEND ON THIS. -# This may change in future versions of Swing as we improve localization -# support. -# -# Refer to the note in basic.properties for a description as to what -# the mnemonics correspond to and how to calculate them. -# -# @author Steve Wilson - - -############ FILE CHOOSER STRINGS ############# - -FileChooser.lookInLabel.textAndMnemonic=\uCC3E\uB294 \uC704\uCE58(&I): -FileChooser.saveInLabel.textAndMnemonic=\uC800\uC7A5 \uC704\uCE58: -FileChooser.fileNameLabel.textAndMnemonic=\uD30C\uC77C \uC774\uB984(&N): -FileChooser.folderNameLabel.textAndMnemonic=\uD3F4\uB354 \uC774\uB984(&N): -FileChooser.filesOfTypeLabel.textAndMnemonic=\uD30C\uC77C \uC720\uD615(&T): -FileChooser.upFolderToolTip.textAndMnemonic=\uD55C \uB808\uBCA8 \uC704\uB85C -FileChooser.upFolderAccessibleName=\uC704\uB85C -FileChooser.homeFolderToolTip.textAndMnemonic=\uD648 -FileChooser.homeFolderAccessibleName=\uD648 -FileChooser.newFolderToolTip.textAndMnemonic=\uC0C8 \uD3F4\uB354 \uC0DD\uC131 -FileChooser.newFolderAccessibleName=\uC0C8 \uD3F4\uB354 -FileChooser.newFolderActionLabel.textAndMnemonic=\uC0C8 \uD3F4\uB354 -FileChooser.listViewButtonToolTip.textAndMnemonic=\uBAA9\uB85D -FileChooser.listViewButtonAccessibleName=\uBAA9\uB85D -FileChooser.listViewActionLabel.textAndMnemonic=\uBAA9\uB85D -FileChooser.detailsViewButtonToolTip.textAndMnemonic=\uC138\uBD80\uC815\uBCF4 -FileChooser.detailsViewButtonAccessibleName=\uC138\uBD80\uC815\uBCF4 -FileChooser.viewMenuButtonToolTipText = \uBCF4\uAE30 \uBA54\uB274 -FileChooser.viewMenuButtonAccessibleName = \uBCF4\uAE30 \uBA54\uB274 -FileChooser.detailsViewActionLabel.textAndMnemonic=\uC138\uBD80\uC815\uBCF4 -FileChooser.refreshActionLabel.textAndMnemonic=\uC0C8\uB85C\uACE0\uCE68 -FileChooser.viewMenuLabel.textAndMnemonic=\uBCF4\uAE30 -FileChooser.fileNameHeader.textAndMnemonic=\uC774\uB984 -FileChooser.fileSizeHeader.textAndMnemonic=\uD06C\uAE30 -FileChooser.fileTypeHeader.textAndMnemonic=\uC720\uD615 -FileChooser.fileDateHeader.textAndMnemonic=\uC218\uC815 \uB0A0\uC9DC -FileChooser.fileAttrHeader.textAndMnemonic=\uC18D\uC131 diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/resources/windows_pt_BR.properties --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/resources/windows_pt_BR.properties Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -# This properties file is used to create a PropertyResourceBundle -# It contains Locale specific strings used be the Windows Look and Feel. -# Currently, the following components need this for support: -# -# FileChooser -# -# When this file is read in, the strings are put into the -# defaults table. This is an implementation detail of the current -# workings of Swing. DO NOT DEPEND ON THIS. -# This may change in future versions of Swing as we improve localization -# support. -# -# Refer to the note in basic.properties for a description as to what -# the mnemonics correspond to and how to calculate them. -# -# @author Steve Wilson - - -############ FILE CHOOSER STRINGS ############# - -FileChooser.lookInLabel.textAndMnemonic=Pesquisar &em: -FileChooser.saveInLabel.textAndMnemonic=Salvar em: -FileChooser.fileNameLabel.textAndMnemonic=&Nome do arquivo: -FileChooser.folderNameLabel.textAndMnemonic=&Nome da pasta: -FileChooser.filesOfTypeLabel.textAndMnemonic=Arquivos do &tipo: -FileChooser.upFolderToolTip.textAndMnemonic=Um N\u00EDvel Acima -FileChooser.upFolderAccessibleName=Acima -FileChooser.homeFolderToolTip.textAndMnemonic=In\u00EDcio -FileChooser.homeFolderAccessibleName=In\u00EDcio -FileChooser.newFolderToolTip.textAndMnemonic=Criar Nova Pasta -FileChooser.newFolderAccessibleName=Nova Pasta -FileChooser.newFolderActionLabel.textAndMnemonic=Nova Pasta -FileChooser.listViewButtonToolTip.textAndMnemonic=Lista -FileChooser.listViewButtonAccessibleName=Lista -FileChooser.listViewActionLabel.textAndMnemonic=Lista -FileChooser.detailsViewButtonToolTip.textAndMnemonic=Detalhes -FileChooser.detailsViewButtonAccessibleName=Detalhes -FileChooser.viewMenuButtonToolTipText = Exibir Menu -FileChooser.viewMenuButtonAccessibleName = Exibir Menu -FileChooser.detailsViewActionLabel.textAndMnemonic=Detalhes -FileChooser.refreshActionLabel.textAndMnemonic=Atualizar -FileChooser.viewMenuLabel.textAndMnemonic=Exibir -FileChooser.fileNameHeader.textAndMnemonic=Nome -FileChooser.fileSizeHeader.textAndMnemonic=Tamanho -FileChooser.fileTypeHeader.textAndMnemonic=Tipo -FileChooser.fileDateHeader.textAndMnemonic=Modificado -FileChooser.fileAttrHeader.textAndMnemonic=Atributos diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/resources/windows_sv.properties --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/resources/windows_sv.properties Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -# This properties file is used to create a PropertyResourceBundle -# It contains Locale specific strings used be the Windows Look and Feel. -# Currently, the following components need this for support: -# -# FileChooser -# -# When this file is read in, the strings are put into the -# defaults table. This is an implementation detail of the current -# workings of Swing. DO NOT DEPEND ON THIS. -# This may change in future versions of Swing as we improve localization -# support. -# -# Refer to the note in basic.properties for a description as to what -# the mnemonics correspond to and how to calculate them. -# -# @author Steve Wilson - - -############ FILE CHOOSER STRINGS ############# - -FileChooser.lookInLabel.textAndMnemonic=Leta &i: -FileChooser.saveInLabel.textAndMnemonic=Spara i: -FileChooser.fileNameLabel.textAndMnemonic=Fil&namn: -FileChooser.folderNameLabel.textAndMnemonic=Mapp&namn: -FileChooser.filesOfTypeLabel.textAndMnemonic=Filer av &typen: -FileChooser.upFolderToolTip.textAndMnemonic=Upp en niv\u00E5 -FileChooser.upFolderAccessibleName=Upp -FileChooser.homeFolderToolTip.textAndMnemonic=Hem -FileChooser.homeFolderAccessibleName=Hem -FileChooser.newFolderToolTip.textAndMnemonic=Skapa ny mapp -FileChooser.newFolderAccessibleName=Ny mapp -FileChooser.newFolderActionLabel.textAndMnemonic=Ny mapp -FileChooser.listViewButtonToolTip.textAndMnemonic=Lista -FileChooser.listViewButtonAccessibleName=Lista -FileChooser.listViewActionLabel.textAndMnemonic=Lista -FileChooser.detailsViewButtonToolTip.textAndMnemonic=Detaljer -FileChooser.detailsViewButtonAccessibleName=Detaljer -FileChooser.viewMenuButtonToolTipText = Menyn Visa -FileChooser.viewMenuButtonAccessibleName = Menyn Visa -FileChooser.detailsViewActionLabel.textAndMnemonic=Detaljer -FileChooser.refreshActionLabel.textAndMnemonic=F\u00F6rnya -FileChooser.viewMenuLabel.textAndMnemonic=Vy -FileChooser.fileNameHeader.textAndMnemonic=Namn -FileChooser.fileSizeHeader.textAndMnemonic=Storlek -FileChooser.fileTypeHeader.textAndMnemonic=Typ -FileChooser.fileDateHeader.textAndMnemonic=\u00C4ndrad -FileChooser.fileAttrHeader.textAndMnemonic=Attribut diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/resources/windows_zh_CN.properties --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/resources/windows_zh_CN.properties Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -# This properties file is used to create a PropertyResourceBundle -# It contains Locale specific strings used be the Windows Look and Feel. -# Currently, the following components need this for support: -# -# FileChooser -# -# When this file is read in, the strings are put into the -# defaults table. This is an implementation detail of the current -# workings of Swing. DO NOT DEPEND ON THIS. -# This may change in future versions of Swing as we improve localization -# support. -# -# Refer to the note in basic.properties for a description as to what -# the mnemonics correspond to and how to calculate them. -# -# @author Steve Wilson - - -############ FILE CHOOSER STRINGS ############# - -FileChooser.lookInLabel.textAndMnemonic=\u67E5\u627E(&I): -FileChooser.saveInLabel.textAndMnemonic=\u4FDD\u5B58: -FileChooser.fileNameLabel.textAndMnemonic=\u6587\u4EF6\u540D(&N): -FileChooser.folderNameLabel.textAndMnemonic=\u6587\u4EF6\u5939\u540D(&N): -FileChooser.filesOfTypeLabel.textAndMnemonic=\u6587\u4EF6\u7C7B\u578B(&T): -FileChooser.upFolderToolTip.textAndMnemonic=\u5411\u4E0A\u4E00\u7EA7 -FileChooser.upFolderAccessibleName=\u5411\u4E0A -FileChooser.homeFolderToolTip.textAndMnemonic=\u4E3B\u76EE\u5F55 -FileChooser.homeFolderAccessibleName=\u4E3B\u76EE\u5F55 -FileChooser.newFolderToolTip.textAndMnemonic=\u521B\u5EFA\u65B0\u6587\u4EF6\u5939 -FileChooser.newFolderAccessibleName=\u65B0\u5EFA\u6587\u4EF6\u5939 -FileChooser.newFolderActionLabel.textAndMnemonic=\u65B0\u5EFA\u6587\u4EF6\u5939 -FileChooser.listViewButtonToolTip.textAndMnemonic=\u5217\u8868 -FileChooser.listViewButtonAccessibleName=\u5217\u8868 -FileChooser.listViewActionLabel.textAndMnemonic=\u5217\u8868 -FileChooser.detailsViewButtonToolTip.textAndMnemonic=\u8BE6\u7EC6\u4FE1\u606F -FileChooser.detailsViewButtonAccessibleName=\u8BE6\u7EC6\u4FE1\u606F -FileChooser.viewMenuButtonToolTipText = \u67E5\u770B\u83DC\u5355 -FileChooser.viewMenuButtonAccessibleName = \u67E5\u770B\u83DC\u5355 -FileChooser.detailsViewActionLabel.textAndMnemonic=\u8BE6\u7EC6\u4FE1\u606F -FileChooser.refreshActionLabel.textAndMnemonic=\u5237\u65B0 -FileChooser.viewMenuLabel.textAndMnemonic=\u89C6\u56FE -FileChooser.fileNameHeader.textAndMnemonic=\u540D\u79F0 -FileChooser.fileSizeHeader.textAndMnemonic=\u5927\u5C0F -FileChooser.fileTypeHeader.textAndMnemonic=\u7C7B\u578B -FileChooser.fileDateHeader.textAndMnemonic=\u4FEE\u6539\u65E5\u671F -FileChooser.fileAttrHeader.textAndMnemonic=\u5C5E\u6027 diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/resources/windows_zh_TW.properties --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/resources/windows_zh_TW.properties Mon Dec 11 16:43:11 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -# This properties file is used to create a PropertyResourceBundle -# It contains Locale specific strings used be the Windows Look and Feel. -# Currently, the following components need this for support: -# -# FileChooser -# -# When this file is read in, the strings are put into the -# defaults table. This is an implementation detail of the current -# workings of Swing. DO NOT DEPEND ON THIS. -# This may change in future versions of Swing as we improve localization -# support. -# -# Refer to the note in basic.properties for a description as to what -# the mnemonics correspond to and how to calculate them. -# -# @author Steve Wilson - - -############ FILE CHOOSER STRINGS ############# - -FileChooser.lookInLabel.textAndMnemonic=\u67E5\u8A62(&I): -FileChooser.saveInLabel.textAndMnemonic=\u5132\u5B58\u65BC: -FileChooser.fileNameLabel.textAndMnemonic=\u6A94\u6848\u540D\u7A31(&N): -FileChooser.folderNameLabel.textAndMnemonic=\u8CC7\u6599\u593E\u540D\u7A31(&N): -FileChooser.filesOfTypeLabel.textAndMnemonic=\u6A94\u6848\u985E\u578B(&T): -FileChooser.upFolderToolTip.textAndMnemonic=\u5F80\u4E0A\u4E00\u5C64 -FileChooser.upFolderAccessibleName=\u5F80\u4E0A -FileChooser.homeFolderToolTip.textAndMnemonic=\u4E3B\u76EE\u9304 -FileChooser.homeFolderAccessibleName=\u4E3B\u76EE\u9304 -FileChooser.newFolderToolTip.textAndMnemonic=\u5EFA\u7ACB\u65B0\u8CC7\u6599\u593E -FileChooser.newFolderAccessibleName=\u65B0\u8CC7\u6599\u593E -FileChooser.newFolderActionLabel.textAndMnemonic=\u65B0\u8CC7\u6599\u593E -FileChooser.listViewButtonToolTip.textAndMnemonic=\u6E05\u55AE -FileChooser.listViewButtonAccessibleName=\u6E05\u55AE -FileChooser.listViewActionLabel.textAndMnemonic=\u6E05\u55AE -FileChooser.detailsViewButtonToolTip.textAndMnemonic=\u8A73\u7D30\u8CC7\u8A0A -FileChooser.detailsViewButtonAccessibleName=\u8A73\u7D30\u8CC7\u8A0A -FileChooser.viewMenuButtonToolTipText = \u6AA2\u8996\u529F\u80FD\u8868 -FileChooser.viewMenuButtonAccessibleName = \u6AA2\u8996\u529F\u80FD\u8868 -FileChooser.detailsViewActionLabel.textAndMnemonic=\u8A73\u7D30\u8CC7\u8A0A -FileChooser.refreshActionLabel.textAndMnemonic=\u91CD\u65B0\u6574\u7406 -FileChooser.viewMenuLabel.textAndMnemonic=\u6AA2\u8996 -FileChooser.fileNameHeader.textAndMnemonic=\u540D\u7A31 -FileChooser.fileSizeHeader.textAndMnemonic=\u5927\u5C0F -FileChooser.fileTypeHeader.textAndMnemonic=\u985E\u578B -FileChooser.fileDateHeader.textAndMnemonic=\u4FEE\u6539\u65E5\u671F -FileChooser.fileAttrHeader.textAndMnemonic=\u5C6C\u6027 diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/media/sound/AiffFileWriter.java --- a/src/java.desktop/share/classes/com/sun/media/sound/AiffFileWriter.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/com/sun/media/sound/AiffFileWriter.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -113,10 +113,11 @@ AiffFileFormat aiffFileFormat = (AiffFileFormat)getAudioFileFormat(fileType, stream); // first write the file without worrying about length fields - FileOutputStream fos = new FileOutputStream( out ); // throws IOException - BufferedOutputStream bos = new BufferedOutputStream( fos, bisBufferSize ); - int bytesWritten = writeAiffFile(stream, aiffFileFormat, bos ); - bos.close(); + final int bytesWritten; + try (final FileOutputStream fos = new FileOutputStream(out); + final BufferedOutputStream bos = new BufferedOutputStream(fos)) { + bytesWritten = writeAiffFile(stream, aiffFileFormat, bos); + } // now, if length fields were not specified, calculate them, // open as a random access file, write the appropriate fields, @@ -134,20 +135,19 @@ long dataSize=ssndChunkSize-16; //TODO possibly incorrect round int numFrames = (int) (dataSize / ssndBlockSize); - - RandomAccessFile raf=new RandomAccessFile(out, "rw"); - // skip FORM magic - raf.skipBytes(4); - raf.writeInt(aiffLength-8); - // skip aiff2 magic, fver chunk, comm magic, comm size, channel count, - raf.skipBytes(4+aiffFileFormat.getFverChunkSize()+4+4+2); - // write frame count - raf.writeInt(numFrames); - // skip sample size, samplerate, SSND magic - raf.skipBytes(2+10+4); - raf.writeInt(ssndChunkSize-8); - // that's all - raf.close(); + try (final RandomAccessFile raf = new RandomAccessFile(out, "rw")) { + // skip FORM magic + raf.skipBytes(4); + raf.writeInt(aiffLength - 8); + // skip aiff2 magic, fver chunk, comm magic, comm size, channel count, + raf.skipBytes(4 + aiffFileFormat.getFverChunkSize() + 4 + 4 + 2); + // write frame count + raf.writeInt(numFrames); + // skip sample size, samplerate, SSND magic + raf.skipBytes(2 + 10 + 4); + raf.writeInt(ssndChunkSize - 8); + // that's all + } } return bytesWritten; @@ -289,10 +289,6 @@ int compCode = AiffFileFormat.AIFC_PCM; byte header[] = null; - ByteArrayInputStream headerStream = null; - ByteArrayOutputStream baos = null; - DataOutputStream dos = null; - SequenceInputStream aiffStream = null; InputStream codedAudioStream = audioStream; // if we need to do any format conversion, do it here.... @@ -343,52 +339,39 @@ // Now create an AIFF stream header... - baos = new ByteArrayOutputStream(); - dos = new DataOutputStream(baos); - - // Write the outer FORM chunk - dos.writeInt(AiffFileFormat.AIFF_MAGIC); - dos.writeInt( (aiffLength-8) ); - dos.writeInt(AiffFileFormat.AIFF_MAGIC2); - - // Write a FVER chunk - only for AIFC - //dos.writeInt(FVER_MAGIC); - //dos.writeInt( (fverChunkSize-8) ); - //dos.writeInt(FVER_TIMESTAMP); - - // Write a COMM chunk - dos.writeInt(AiffFileFormat.COMM_MAGIC); - dos.writeInt( (commChunkSize-8) ); - dos.writeShort(channels); - dos.writeInt(numFrames); - dos.writeShort(sampleSize); - write_ieee_extended(dos, sampleFramesPerSecond); // 10 bytes - - //Only for AIFC - //dos.writeInt(compCode); - //dos.writeInt(compCode); - //dos.writeShort(0); - - // Write the SSND chunk header - dos.writeInt(AiffFileFormat.SSND_MAGIC); - dos.writeInt( (ssndChunkSize-8) ); - // ssndOffset and ssndBlockSize set to 0 upon - // recommendation in "Sound Manager" chapter in - // "Inside Macintosh Sound", pp 2-87 (from Babu) - dos.writeInt(0); // ssndOffset - dos.writeInt(0); // ssndBlockSize - - // Concat this with the audioStream and return it - - dos.close(); - header = baos.toByteArray(); - headerStream = new ByteArrayInputStream( header ); - - aiffStream = new SequenceInputStream(headerStream, - new NoCloseInputStream(codedAudioStream)); - - return aiffStream; - + try (final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + final DataOutputStream dos = new DataOutputStream(baos)) { + // Write the outer FORM chunk + dos.writeInt(AiffFileFormat.AIFF_MAGIC); + dos.writeInt((aiffLength - 8)); + dos.writeInt(AiffFileFormat.AIFF_MAGIC2); + // Write a FVER chunk - only for AIFC + //dos.writeInt(FVER_MAGIC); + //dos.writeInt( (fverChunkSize-8) ); + //dos.writeInt(FVER_TIMESTAMP); + // Write a COMM chunk + dos.writeInt(AiffFileFormat.COMM_MAGIC); + dos.writeInt((commChunkSize - 8)); + dos.writeShort(channels); + dos.writeInt(numFrames); + dos.writeShort(sampleSize); + write_ieee_extended(dos, sampleFramesPerSecond); // 10 bytes + //Only for AIFC + //dos.writeInt(compCode); + //dos.writeInt(compCode); + //dos.writeShort(0); + // Write the SSND chunk header + dos.writeInt(AiffFileFormat.SSND_MAGIC); + dos.writeInt((ssndChunkSize - 8)); + // ssndOffset and ssndBlockSize set to 0 upon + // recommendation in "Sound Manager" chapter in + // "Inside Macintosh Sound", pp 2-87 (from Babu) + dos.writeInt(0); // ssndOffset + dos.writeInt(0); // ssndBlockSize + header = baos.toByteArray(); + } + return new SequenceInputStream(new ByteArrayInputStream(header), + new NoCloseInputStream(codedAudioStream)); } // HELPER METHODS diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/media/sound/AuFileWriter.java --- a/src/java.desktop/share/classes/com/sun/media/sound/AuFileWriter.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/com/sun/media/sound/AuFileWriter.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -111,10 +111,11 @@ AuFileFormat auFileFormat = (AuFileFormat)getAudioFileFormat(fileType, stream); // first write the file without worrying about length fields - FileOutputStream fos = new FileOutputStream( out ); // throws IOException - BufferedOutputStream bos = new BufferedOutputStream( fos, bisBufferSize ); - int bytesWritten = writeAuFile(stream, auFileFormat, bos ); - bos.close(); + final int bytesWritten; + try (final FileOutputStream fos = new FileOutputStream(out); + final BufferedOutputStream bos = new BufferedOutputStream(fos)) { + bytesWritten = writeAuFile(stream, auFileFormat, bos); + } // now, if length fields were not specified, calculate them, // open as a random access file, write the appropriate fields, @@ -123,14 +124,14 @@ // $$kk: 10.22.99: jan: please either implement this or throw an exception! // $$fb: 2001-07-13: done. Fixes Bug 4479981 - RandomAccessFile raf=new RandomAccessFile(out, "rw"); - if (raf.length()<=0x7FFFFFFFl) { - // skip AU magic and data offset field - raf.skipBytes(8); - raf.writeInt(bytesWritten-AuFileFormat.AU_HEADERSIZE); - // that's all + try (final RandomAccessFile raf = new RandomAccessFile(out, "rw")) { + if (raf.length() <= 0x7FFFFFFFl) { + // skip AU magic and data offset field + raf.skipBytes(8); + raf.writeInt(bytesWritten - AuFileFormat.AU_HEADERSIZE); + // that's all + } } - raf.close(); } return bytesWritten; @@ -191,39 +192,29 @@ int sampleRate = (int)format.getSampleRate(); int channels = format.getChannels(); - byte header[] = null; - ByteArrayInputStream headerStream = null; - ByteArrayOutputStream baos = null; - DataOutputStream dos = null; - SequenceInputStream auStream = null; - // if we need to do any format conversion, we do it here. //$$ fb 2001-07-13: Bug 4391108 audioStream = AudioSystem.getAudioInputStream(format, audioStream); - baos = new ByteArrayOutputStream(); - dos = new DataOutputStream(baos); - - dos.writeInt(AuFileFormat.AU_SUN_MAGIC); - dos.writeInt(headerSize); - dos.writeInt((int)dataSizeInBytes); - dos.writeInt(auType); - dos.writeInt(sampleRate); - dos.writeInt(channels); - + final byte[] header; + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos)) { + dos.writeInt(AuFileFormat.AU_SUN_MAGIC); + dos.writeInt(headerSize); + dos.writeInt((int) dataSizeInBytes); + dos.writeInt(auType); + dos.writeInt(sampleRate); + dos.writeInt(channels); + header = baos.toByteArray(); + } // Now create a new InputStream from headerStream and the InputStream // in audioStream - - dos.close(); - header = baos.toByteArray(); - headerStream = new ByteArrayInputStream( header ); - auStream = new SequenceInputStream(headerStream, - new NoCloseInputStream(audioStream)); - - return auStream; + return new SequenceInputStream(new ByteArrayInputStream(header), + new NoCloseInputStream(audioStream)); } - private int writeAuFile(AudioInputStream in, AuFileFormat auFileFormat, OutputStream out) throws IOException { + private int writeAuFile(AudioInputStream in, AuFileFormat auFileFormat, + OutputStream out) throws IOException { int bytesRead = 0; int bytesWritten = 0; diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/media/sound/WaveFileWriter.java --- a/src/java.desktop/share/classes/com/sun/media/sound/WaveFileWriter.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/com/sun/media/sound/WaveFileWriter.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -113,10 +113,11 @@ WaveFileFormat waveFileFormat = (WaveFileFormat)getAudioFileFormat(fileType, stream); // first write the file without worrying about length fields - FileOutputStream fos = new FileOutputStream( out ); // throws IOException - BufferedOutputStream bos = new BufferedOutputStream( fos, bisBufferSize ); - int bytesWritten = writeWaveFile(stream, waveFileFormat, bos ); - bos.close(); + final int bytesWritten; + try (final FileOutputStream fos = new FileOutputStream(out); + final BufferedOutputStream bos = new BufferedOutputStream(fos)) { + bytesWritten = writeWaveFile(stream, waveFileFormat, bos); + } // now, if length fields were not specified, calculate them, // open as a random access file, write the appropriate fields, @@ -125,16 +126,16 @@ int dataLength=bytesWritten-waveFileFormat.getHeaderSize(); int riffLength=dataLength + waveFileFormat.getHeaderSize() - 8; - - RandomAccessFile raf=new RandomAccessFile(out, "rw"); - // skip RIFF magic - raf.skipBytes(4); - raf.writeInt(big2little( riffLength )); - // skip WAVE magic, fmt_ magic, fmt_ length, fmt_ chunk, data magic - raf.skipBytes(4+4+4+WaveFileFormat.getFmtChunkSize(waveFileFormat.getWaveType())+4); - raf.writeInt(big2little( dataLength )); - // that's all - raf.close(); + try (final RandomAccessFile raf = new RandomAccessFile(out, "rw")) { + // skip RIFF magic + raf.skipBytes(4); + raf.writeInt(big2little(riffLength)); + // skip WAVE magic, fmt_ magic, fmt_ length, fmt_ chunk, data magic + raf.skipBytes(4 + 4 + 4 + WaveFileFormat.getFmtChunkSize( + waveFileFormat.getWaveType()) + 4); + raf.writeInt(big2little(dataLength)); + // that's all + } } return bytesWritten; @@ -262,12 +263,6 @@ int length = waveFileFormat.getByteLength(); int riffLength = dataLength + headerLength - 8; - byte header[] = null; - ByteArrayInputStream headerStream = null; - ByteArrayOutputStream baos = null; - DataOutputStream dos = null; - SequenceInputStream waveStream = null; - AudioFormat audioStreamFormat = null; AudioFormat.Encoding encoding = null; InputStream codedAudioStream = audioStream; @@ -314,37 +309,31 @@ // Now push the header into a stream, concat, and return the new SequenceInputStream - - baos = new ByteArrayOutputStream(); - dos = new DataOutputStream(baos); - - // we write in littleendian... - dos.writeInt(riffMagic); - dos.writeInt(big2little( riffLength )); - dos.writeInt(waveMagic); - dos.writeInt(fmtMagic); - dos.writeInt(big2little(fmtLength)); - dos.writeShort(big2littleShort(wav_type)); - dos.writeShort(big2littleShort(channels)); - dos.writeInt(big2little(sampleRate)); - dos.writeInt(big2little(avgBytesPerSec)); - dos.writeShort(big2littleShort(blockAlign)); - dos.writeShort(big2littleShort(sampleSizeInBits)); - //$$fb 2002-04-16: Fix for 4636355: RIFF audio headers could be _more_ spec compliant - if (wav_type != WaveFileFormat.WAVE_FORMAT_PCM) { - // add length 0 for "codec specific data length" - dos.writeShort(0); + final byte[] header; + try (final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + final DataOutputStream dos = new DataOutputStream(baos)) { + // we write in littleendian... + dos.writeInt(riffMagic); + dos.writeInt(big2little(riffLength)); + dos.writeInt(waveMagic); + dos.writeInt(fmtMagic); + dos.writeInt(big2little(fmtLength)); + dos.writeShort(big2littleShort(wav_type)); + dos.writeShort(big2littleShort(channels)); + dos.writeInt(big2little(sampleRate)); + dos.writeInt(big2little(avgBytesPerSec)); + dos.writeShort(big2littleShort(blockAlign)); + dos.writeShort(big2littleShort(sampleSizeInBits)); + //$$fb 2002-04-16: Fix for 4636355: RIFF audio headers could be _more_ spec compliant + if (wav_type != WaveFileFormat.WAVE_FORMAT_PCM) { + // add length 0 for "codec specific data length" + dos.writeShort(0); + } + dos.writeInt(dataMagic); + dos.writeInt(big2little(dataLength)); + header = baos.toByteArray(); } - - dos.writeInt(dataMagic); - dos.writeInt(big2little(dataLength)); - - dos.close(); - header = baos.toByteArray(); - headerStream = new ByteArrayInputStream( header ); - waveStream = new SequenceInputStream(headerStream, - new NoCloseInputStream(codedAudioStream)); - - return waveStream; + return new SequenceInputStream(new ByteArrayInputStream(header), + new NoCloseInputStream(codedAudioStream)); } } diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/com/sun/media/sound/WaveFloatFileWriter.java --- a/src/java.desktop/share/classes/com/sun/media/sound/WaveFloatFileWriter.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/com/sun/media/sound/WaveFloatFileWriter.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,24 +69,23 @@ public void write(AudioInputStream stream, RIFFWriter writer) throws IOException { - - RIFFWriter fmt_chunk = writer.writeChunk("fmt "); - - AudioFormat format = stream.getFormat(); - fmt_chunk.writeUnsignedShort(3); // WAVE_FORMAT_IEEE_FLOAT - fmt_chunk.writeUnsignedShort(format.getChannels()); - fmt_chunk.writeUnsignedInt((int) format.getSampleRate()); - fmt_chunk.writeUnsignedInt(((int) format.getFrameRate()) - * format.getFrameSize()); - fmt_chunk.writeUnsignedShort(format.getFrameSize()); - fmt_chunk.writeUnsignedShort(format.getSampleSizeInBits()); - fmt_chunk.close(); - RIFFWriter data_chunk = writer.writeChunk("data"); - byte[] buff = new byte[1024]; - int len; - while ((len = stream.read(buff, 0, buff.length)) != -1) - data_chunk.write(buff, 0, len); - data_chunk.close(); + try (final RIFFWriter fmt_chunk = writer.writeChunk("fmt ")) { + AudioFormat format = stream.getFormat(); + fmt_chunk.writeUnsignedShort(3); // WAVE_FORMAT_IEEE_FLOAT + fmt_chunk.writeUnsignedShort(format.getChannels()); + fmt_chunk.writeUnsignedInt((int) format.getSampleRate()); + fmt_chunk.writeUnsignedInt(((int) format.getFrameRate()) + * format.getFrameSize()); + fmt_chunk.writeUnsignedShort(format.getFrameSize()); + fmt_chunk.writeUnsignedShort(format.getSampleSizeInBits()); + } + try (RIFFWriter data_chunk = writer.writeChunk("data")) { + byte[] buff = new byte[1024]; + int len; + while ((len = stream.read(buff, 0, buff.length)) != -1) { + data_chunk.write(buff, 0, len); + } + } } private static final class NoCloseOutputStream extends OutputStream { @@ -136,11 +135,11 @@ checkFormat(fileType, stream); if (stream.getFormat().isBigEndian()) stream = toLittleEndian(stream); - RIFFWriter writer = new RIFFWriter(new NoCloseOutputStream(out), "WAVE"); - write(stream, writer); - int fpointer = (int) writer.getFilePointer(); - writer.close(); - return fpointer; + try (final RIFFWriter writer = new RIFFWriter( + new NoCloseOutputStream(out), "WAVE")) { + write(stream, writer); + return (int) writer.getFilePointer(); + } } @Override @@ -153,10 +152,9 @@ checkFormat(fileType, stream); if (stream.getFormat().isBigEndian()) stream = toLittleEndian(stream); - RIFFWriter writer = new RIFFWriter(out, "WAVE"); - write(stream, writer); - int fpointer = (int) writer.getFilePointer(); - writer.close(); - return fpointer; + try (final RIFFWriter writer = new RIFFWriter(out, "WAVE")) { + write(stream, writer); + return (int) writer.getFilePointer(); + } } } diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/java/awt/AWTEvent.java --- a/src/java.desktop/share/classes/java/awt/AWTEvent.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/java/awt/AWTEvent.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,16 +25,24 @@ package java.awt; -import java.util.EventObject; -import java.awt.event.*; +import java.awt.event.ActionEvent; +import java.awt.event.AdjustmentEvent; +import java.awt.event.ComponentEvent; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.awt.event.InputMethodEvent; +import java.awt.event.ItemEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.event.TextEvent; +import java.awt.event.WindowEvent; import java.awt.peer.ComponentPeer; import java.awt.peer.LightweightPeer; -import java.lang.reflect.Field; -import sun.awt.AWTAccessor; -import sun.util.logging.PlatformLogger; - import java.security.AccessControlContext; import java.security.AccessController; +import java.util.EventObject; + +import sun.awt.AWTAccessor; /** * The root event class for all AWT events. @@ -78,7 +86,7 @@ * @since 1.1 */ public abstract class AWTEvent extends EventObject { - private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.AWTEvent"); + private byte bdata[]; /** @@ -241,9 +249,6 @@ */ public static final int RESERVED_ID_MAX = 1999; - // security stuff - private static Field inputEvent_CanAccessSystemClipboard_Field = null; - /* * JDK 1.1 serialVersionUID */ diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/java/awt/Font.java --- a/src/java.desktop/share/classes/java/awt/Font.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/java/awt/Font.java Thu Dec 14 12:28:32 2017 +0000 @@ -56,6 +56,7 @@ import sun.font.Font2D; import sun.font.Font2DHandle; import sun.font.FontAccess; +import sun.font.FontDesignMetrics; import sun.font.FontManager; import sun.font.FontManagerFactory; import sun.font.FontUtilities; @@ -2603,9 +2604,8 @@ } if (simple) { - GlyphVector gv = new StandardGlyphVector(this, chars, beginIndex, - limit - beginIndex, frc); - return gv.getLogicalBounds(); + FontDesignMetrics metrics = FontDesignMetrics.getMetrics(this, frc); + return metrics.getSimpleBounds(chars, beginIndex, limit-beginIndex); } else { // need char array constructor on textlayout String str = new String(chars, beginIndex, limit - beginIndex); diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/java/awt/MenuBar.java --- a/src/java.desktop/share/classes/java/awt/MenuBar.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/java/awt/MenuBar.java Thu Dec 14 12:28:32 2017 +0000 @@ -377,7 +377,6 @@ * keydown). Returns true if there is an associated * keyboard event. */ - @SuppressWarnings("deprecation") boolean handleShortcut(KeyEvent e) { // Is it a key event? int id = e.getID(); @@ -386,8 +385,8 @@ } // Is the accelerator modifier key pressed? - int accelKey = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); - if ((e.getModifiers() & accelKey) == 0) { + int accelKey = Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx(); + if ((e.getModifiersEx() & accelKey) == 0) { return false; } diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/java/awt/MenuShortcut.java --- a/src/java.desktop/share/classes/java/awt/MenuShortcut.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/java/awt/MenuShortcut.java Thu Dec 14 12:28:32 2017 +0000 @@ -24,6 +24,7 @@ */ package java.awt; +import java.awt.event.InputEvent; import java.awt.event.KeyEvent; /** @@ -51,7 +52,7 @@ * only work if the current keyboard layout produces a corresponding letter. *

    * The accelerator key is platform-dependent and may be obtained - * via {@link Toolkit#getMenuShortcutKeyMask}. + * via {@link Toolkit#getMenuShortcutKeyMaskEx()}. * * @author Thomas Ball * @since 1.1 @@ -180,16 +181,15 @@ * @return a string representation of this MenuShortcut. * @since 1.1 */ - @SuppressWarnings("deprecation") public String toString() { int modifiers = 0; if (!GraphicsEnvironment.isHeadless()) { - modifiers = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); + modifiers = Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx(); } if (usesShiftModifier()) { - modifiers |= Event.SHIFT_MASK; + modifiers |= InputEvent.SHIFT_DOWN_MASK; } - return KeyEvent.getKeyModifiersText(modifiers) + "+" + + return InputEvent.getModifiersExText(modifiers) + "+" + KeyEvent.getKeyText(key); } diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/java/awt/Toolkit.java --- a/src/java.desktop/share/classes/java/awt/Toolkit.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/java/awt/Toolkit.java Thu Dec 14 12:28:32 2017 +0000 @@ -29,7 +29,23 @@ import java.awt.dnd.DragGestureListener; import java.awt.dnd.DragGestureRecognizer; import java.awt.dnd.DragSource; -import java.awt.event.*; +import java.awt.event.AWTEventListener; +import java.awt.event.AWTEventListenerProxy; +import java.awt.event.ActionEvent; +import java.awt.event.AdjustmentEvent; +import java.awt.event.ComponentEvent; +import java.awt.event.ContainerEvent; +import java.awt.event.FocusEvent; +import java.awt.event.HierarchyEvent; +import java.awt.event.InputEvent; +import java.awt.event.InputMethodEvent; +import java.awt.event.InvocationEvent; +import java.awt.event.ItemEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.event.PaintEvent; +import java.awt.event.TextEvent; +import java.awt.event.WindowEvent; import java.awt.im.InputMethodHighlight; import java.awt.image.ColorModel; import java.awt.image.ImageObserver; @@ -40,15 +56,22 @@ import java.io.File; import java.io.FileInputStream; import java.net.URL; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.ArrayList; +import java.util.Arrays; import java.util.EventListener; import java.util.HashMap; import java.util.Map; import java.util.MissingResourceException; import java.util.Properties; import java.util.ResourceBundle; -import java.util.StringTokenizer; +import java.util.ServiceLoader; +import java.util.Set; import java.util.WeakHashMap; +import java.util.stream.Collectors; + +import javax.accessibility.AccessibilityProvider; import sun.awt.AWTAccessor; import sun.awt.AWTPermissions; @@ -57,14 +80,6 @@ import sun.awt.PeerEvent; import sun.awt.SunToolkit; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.Arrays; -import java.util.ServiceLoader; -import java.util.Set; -import java.util.stream.Collectors; -import javax.accessibility.AccessibilityProvider; - /** * This class is the abstract superclass of all actual * implementations of the Abstract Window Toolkit. Subclasses of @@ -1065,9 +1080,11 @@ * @see java.awt.GraphicsEnvironment#isHeadless * @see java.awt.MenuBar * @see java.awt.MenuShortcut + * @deprecated It is recommended that extended modifier keys and + * {@link #getMenuShortcutKeyMaskEx()} be used instead * @since 1.1 */ - @SuppressWarnings("deprecation") + @Deprecated(since = "10") public int getMenuShortcutKeyMask() throws HeadlessException { GraphicsEnvironment.checkHeadless(); @@ -1075,6 +1092,32 @@ } /** + * Determines which extended modifier key is the appropriate accelerator + * key for menu shortcuts. + *

    + * Menu shortcuts, which are embodied in the {@code MenuShortcut} class, are + * handled by the {@code MenuBar} class. + *

    + * By default, this method returns {@code InputEvent.CTRL_DOWN_MASK}. + * Toolkit implementations should override this method if the + * Control key isn't the correct key for accelerators. + * + * @return the modifier mask on the {@code InputEvent} class that is used + * for menu shortcuts on this toolkit + * @throws HeadlessException if GraphicsEnvironment.isHeadless() returns + * true + * @see java.awt.GraphicsEnvironment#isHeadless + * @see java.awt.MenuBar + * @see java.awt.MenuShortcut + * @since 10 + */ + public int getMenuShortcutKeyMaskEx() throws HeadlessException { + GraphicsEnvironment.checkHeadless(); + + return InputEvent.CTRL_DOWN_MASK; + } + + /** * Returns whether the given locking key on the keyboard is currently in * its "on" state. * Valid key codes are diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/java/awt/doc-files/AWTThreadIssues.html --- a/src/java.desktop/share/classes/java/awt/doc-files/AWTThreadIssues.html Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/java/awt/doc-files/AWTThreadIssues.html Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,11 @@ + + + + + AWT Threading Issues + - - - - - - + -

    AWT Threading Issues

    +

    AWT Threading Issues

    - +

    Listeners and threads

    Unless otherwise noted all AWT listeners are notified on the event @@ -41,7 +42,7 @@
    For example, if a key listeners is added from another key listener, the newly added listener is only notified on subsequent key events. - +

    Auto-shutdown

    According to @@ -53,7 +54,7 @@ one of two things happens:
    • All the threads that are not daemon threads terminate. -
    • Some thread invokes the exit method of class +
    • Some thread invokes the exit method of class Runtime or class System, and the exit operation is permitted by the security manager.
    @@ -84,13 +85,15 @@ posted to the EventQueue can be coalesced) are dispatched:
      -
    • Sequentially. -
      That is, it is not permitted that several events from +
    • +
      Sequentially. +
      That is, it is not permitted that several events from this queue are dispatched simultaneously.
      -
    • In the same order as they are enqueued. -
      That is, if AWTEvent A is enqueued +
    • +
      In the same order as they are enqueued. +
      That is, if AWTEvent A is enqueued to the EventQueue before - AWTEvent B then event B will not be + AWTEvent B then event B will not be dispatched before event A.
  • There is at least one alive non-daemon thread while there is at @@ -98,7 +101,7 @@ application (see Component.isDisplayable). -The implications of the third restriction are as follows: +The implications of the third restriction are as follows:
    • The JVM will exit if some thread invokes the exit method of class Runtime or class System @@ -108,8 +111,8 @@ displayable component.
    It depends on the implementation if and when the non-daemon helper -threads are terminated once all components are made undisplayable. -The implementation-specific details are given below. +threads are terminated once all components are made undisplayable. +The implementation-specific details are given below.

    Implementation-dependent behavior. @@ -147,7 +150,7 @@ Note, that while an application following these recommendations will exit cleanly under normal conditions, it is not guaranteed that it -will exit cleanly in all cases. Two examples: +will exit cleanly in all cases. Two examples:
    • Other packages can create displayable components for internal needs and never make them undisplayable. See @@ -156,7 +159,7 @@ 4671025, and -4465537. +4465537.
    • Both Microsoft Windows and X11 allow an application to send native events to windows that belong to another application. With this feature it is possible to write a malicious program that will @@ -165,10 +168,10 @@
    On the other hand, if you require the JVM to continue running even after the application has made all components undisplayable you should start a -non-daemon thread that blocks forever. +non-daemon thread that blocks forever.
    -        <...>
    +        <...>
             Runnable r = new Runnable() {
                 public void run() {
                     Object o = new Object();
    @@ -183,7 +186,7 @@
             Thread t = new Thread(r);
             t.setDaemon(false);
             t.start();
    -        <...>
    +        <...>
     
    The Java™ Virtual Machine Specification diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/java/awt/doc-files/DesktopProperties.html --- a/src/java.desktop/share/classes/java/awt/doc-files/DesktopProperties.html Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/java/awt/doc-files/DesktopProperties.html Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,11 @@ + + + + + AWT Desktop Properties + - - - - - - + -

    AWT Desktop Properties

    +

    AWT Desktop Properties

    The following refers to standard AWT desktop properties that may be obtained via the @@ -76,7 +77,7 @@

    Desktop Font Rendering Hints

    -Desktop Property: "awt.font.desktophints" +Desktop Property: "awt.font.desktophints"

    Modern desktops support various forms of text antialiasing (font smoothing).

    @@ -116,7 +117,7 @@ using a PropertyChangeListener :

    
    -tk.addPropertyChangeListener("awt.font.desktophints", pcl); 
    +tk.addPropertyChangeListener("awt.font.desktophints", pcl);
     
    Listening for changes is recommended as users can, on rare occasions, reconfigure a desktop environment whilst applications are running @@ -194,7 +195,7 @@ and dynamic updates will not be available. This is a typical behaviour if the JDK does not recognise the desktop environment, or it is one which has no such settings. The Headless toolkit is one such example. -Therefore it is important to test against null before using the map. +Therefore it is important to test against null before using the map.

  • If non-null the value will be a Map of RenderingHints such that every key is an instance of @@ -229,7 +230,7 @@ the per-device property name.

    Mouse Functionality

    -Desktop Property: "sun.awt.enableExtraMouseButtons" +Desktop Property: "sun.awt.enableExtraMouseButtons"

    This property determines if events from extra mouse buttons (if they are exist and are enabled by the underlying operating system) are allowed to be processed and posted into @@ -245,7 +246,7 @@ Current value could also be queried using getDesktopProperty("sun.awt.enableExtraMouseButtons") method.
    -If the property is set to {@code true} then +If the property is set to {@code true} then

    • it is still legal to create {@code MouseEvent} objects with standard buttons and, if the mouse has more @@ -256,13 +257,13 @@ and {@code Robot.mouseRelease()} methods and, if the mouse has more then three buttons, it is also legal to use masks for existing extended mouse buttons. That way, if there are more then three buttons on the mouse then it is allowed to -use button masks corresponding to the buttons +use button masks corresponding to the buttons in the range from 1 up to {@link java.awt.MouseInfo#getNumberOfButtons() getNumberOfButtons()}

    -If the property is set to {@code false} then +If the property is set to {@code false} then
      -
    • it is legal to create {@code MouseEvent} objects with standard buttons +
    • it is legal to create {@code MouseEvent} objects with standard buttons only: {@code NOBUTTON}, {@code BUTTON1}, {@code BUTTON2} and {@code BUTTON3}
    • it is legal to use standard button masks only: diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/java/awt/doc-files/FocusSpec.html --- a/src/java.desktop/share/classes/java/awt/doc-files/FocusSpec.html Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/java/awt/doc-files/FocusSpec.html Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,11 @@ + + + + + The AWT Focus Subsystem + - - - - - The AWT Focus Subsystem - - - -

      The AWT Focus Subsystem

      + +

      The AWT Focus Subsystem

      Prior to Java 2 Standard Edition, JDK 1.4, the AWT focus subsystem @@ -57,8 +56,8 @@ determining the "opposite" Component involved in the focus or activation change. For example, when a Component received a FOCUS_LOST event, it had no way of knowing which Component was gaining - focus. Since Microsoft Windows provides this functionality for free, - developers migrating from Microsoft Windows C/C++ or Visual Basic to + focus. Since Microsoft Windows provides this functionality for free, + developers migrating from Microsoft Windows C/C++ or Visual Basic to Java had been frustrated by the omission.

      To address these and other deficiencies, we have designed a new focus @@ -101,7 +100,7 @@

    • Incompatibilities with Previous Releases
    - +

    Overview of KeyboardFocusManager

    The focus model is centralized around a single class, @@ -160,7 +159,7 @@ define new focus cycle but only modifies the order by which its children are traversed "forward" and "backward". Focus traversal policy provider can be set using - setFocusTraversalPolicyProvider on the Container. + setFocusTraversalPolicyProvider on the Container.

    @@ -180,7 +179,7 @@ descendants.

    - Here is an example:
    Three groups as described below: ABCF BDE and DGH.

    Assume the following: @@ -193,7 +192,7 @@

  • G, H, E, and F are all Components. - + There are a total of three focus cycle roots in this example:
      @@ -213,7 +212,7 @@ implementation in the DefaultKeyboardFocusManager class. - +

      KeyboardFocusManager and Browser Contexts

      Some browsers partition applets in different code bases into separate @@ -229,7 +228,7 @@ owner, focused Window, or active Window, per ClassLoader. - +

      KeyEventDispatcher and KeyEventPostProcessor

      While the user's KeyEvents should generally be delivered to the focus @@ -272,7 +271,7 @@ KeyEventPostProcessor, and similar restrictions apply to its use in that capacity. - +

      FocusEvent and WindowEvent

      The AWT defines the following six event types central to the focus @@ -296,7 +295,7 @@ not a Frame or Dialog) when it is no longer the active Window.

    - +

    Event Delivery

    If the focus is not in java application and the user clicks on a focusable @@ -347,7 +346,7 @@ and VetoableChangeListener. - +

    Opposite Components and Windows

    Each event includes information about the "opposite" Component or @@ -371,7 +370,7 @@ using the opposite Component of a focus change that occurred within a top-level Window. - +

    Temporary FocusEvents

    FOCUS_GAINED and FOCUS_LOST events are @@ -380,7 +379,7 @@ Temporary FOCUS_LOST events are sent when a Component is losing the focus, but will regain the focus shortly. These events can be useful when focus changes are used as triggers for validation -of data. For instance, a text Component may want to commit its +of data. For instance, a text Component may want to commit its contents when the user begins interacting with another Component, and can accomplish this by responding to FOCUS_LOST events. However, if the FocusEvent received is temporary, @@ -402,8 +401,8 @@ When a Component receives a temporary FOCUS_LOST event, the event's opposite Component (if any) may receive a temporary FOCUS_GAINED event, but could also receive a permanent -FOCUS_GAINED event. Showing a Menu or PopupMenu, or -clicking or dragging a Scrollbar, should generate a temporary +FOCUS_GAINED event. Showing a Menu or PopupMenu, or +clicking or dragging a Scrollbar, should generate a temporary FOCUS_GAINED event. Changing the focused Window, however, will yield a permanent FOCUS_GAINED event for the new focus owner. @@ -416,7 +415,7 @@ Components. This method is not intended for general use, but exists instead as a hook for lightweight Component libraries, such as Swing. - +

    Focus Traversal

    Each Component defines its own Set of focus traversal keys for a given @@ -428,11 +427,11 @@ recursively inherits a Set from its parent, and ultimately from a context-wide default set on the current KeyboardFocusManager.

    -Using the AWTKeyStroke API, client code can specify -on which of two specific KeyEvents, KEY_PRESSED or +Using the AWTKeyStroke API, client code can specify +on which of two specific KeyEvents, KEY_PRESSED or KEY_RELEASED, the focus traversal operation will occur. Regardless of which KeyEvent is specified, however, all KeyEvents -related to the focus traversal key, including the associated +related to the focus traversal key, including the associated KEY_TYPED event, will be consumed, and will not be dispatched to any Component. It is a runtime error to specify a KEY_TYPED event as mapping to a focus traversal operation, @@ -475,7 +474,7 @@ normal focus traversal. Thus, the current KeyboardFocusManager maintains a reference to the "current" focus cycle root, which is global across all contexts. The -current focus cycle root is used to resolve the ambiguity. +current focus cycle root is used to resolve the ambiguity.

    For up-cycle traversal, the focus owner is set to the current focus owner's focus cycle root, and the current focus cycle root is set to @@ -491,10 +490,10 @@ root, then no focus traversal operation occurs. - +

    FocusTraversalPolicy

    - + A FocusTraversalPolicy defines the order in which Components within a particular focus cycle root or focus traversal policy provider are traversed. Instances of FocusTraversalPolicy can be shared across @@ -524,7 +523,7 @@

    -A FocusTraversalPolicy may optionally provide an +A FocusTraversalPolicy may optionally provide an algorithm for the following:

    Given a Window, the "initial" Component in that Window. The initial @@ -551,7 +550,7 @@ ancestor. Top-levels initialize their focus traversal policies using the context default policy. The context default policy is established by using KeyboardFocusManager. setDefaultFocusTraversalPolicy. - +

    AWT provides two standard FocusTraversalPolicy implementations for use by client code. @@ -573,14 +572,14 @@

  • DefaultFocusTraversalPolicy: A subclass of ContainerOrderFocusTraversalPolicy which redefines the fitness test. If client code has explicitly set the - focusability of a Component by either overriding + focusability of a Component by either overriding Component.isFocusTraversable() or Component.isFocusable(), or by calling - Component.setFocusable(boolean), then a + Component.setFocusable(boolean), then a DefaultFocusTraversalPolicy behaves exactly like a ContainerOrderFocusTraversalPolicy. If, however, the Component is relying on default focusability, then a - DefaultFocusTraversalPolicy will reject all + DefaultFocusTraversalPolicy will reject all Components with non-focusable peers.
    The focusability of a peer is implementation-dependent. Sun @@ -627,7 +626,7 @@

    The figure below shows an implicit focus transfer: -
    Implicit focus transfer.
    +
    Implicit focus transfer.
    Assume the following:

      @@ -653,7 +652,7 @@ All other applications, including pure AWT applications, will use DefaultFocusTraversalPolicy by default. - +

      Focus Traversal Policy Providers

      A Container that isn't a focus cycle root has an option to provide a @@ -674,7 +673,7 @@ If focus traversal policy provider property is set on a focus cycle root, it isn't considered a focus traversal policy provider and behaves just like any other focus cycle root. - +

      The main difference between focus cycle roots and focus traversal policy providers is that the latter allow focus to enter and leave them just as all other @@ -740,7 +739,7 @@

    - +

    Programmatic Traversal

    In addition to user-initiated focus traversal, client code can @@ -811,7 +810,7 @@ unchanged. - +

    Focusability

    A focusable Component can become the focus owner ("focusability") and @@ -825,7 +824,7 @@ change this default by calling Component.setFocusable(boolean). - +

    Focusable Windows

    To support palette windows and input methods, client code can prevent @@ -877,7 +876,7 @@ all such focus change requests will fail. In this case, the global focus owner will be cleared and the focused Window will remain unchanged. - +

    Requesting Focus

    @@ -949,7 +948,7 @@ a temporary state. See Temporary FocusEvents - +

    Focus and PropertyChangeListener

    Client code can listen to changes in context-wide focus state, or to @@ -957,7 +956,7 @@ PropertyChangeListeners.

    The KeyboardFocusManager supports the following properties: - +

    1. focusOwner: the focus owner
    2. focusedWindow: the focused Window @@ -977,7 +976,7 @@

      A PropertyChangeListener installed on the current KeyboardFocusManager will only see these changes within -the KeyboardFocusManager's context, even though the +the KeyboardFocusManager's context, even though the focus owner, focused Window, active Window, and current focus cycle root comprise the global focus state shared by all contexts. We believe this is less intrusive than requiring client code to pass @@ -1001,7 +1000,7 @@ following focus-related properties:

        -
      1. downCycleFocusTraversalKeys: the Container's Set of +
      2. downCycleFocusTraversalKeys: the Container's Set of DOWN_CYCLE_TRAVERSAL_KEYS
      3. focusTraversalPolicy: the Container's focus traversal policy @@ -1020,10 +1019,10 @@ focusCycleRoot property. A Window is always a focus cycle root; this property cannot change.

        - +

        Focus and VetoableChangeListener

        -The KeyboardFocusManager also supports +The KeyboardFocusManager also supports VetoableChangeListeners for the following properties:

          @@ -1054,13 +1053,13 @@ KeyboardFocusManager is free to attempt to dispatch this event and it is the responsibility of the VetoableChangeListener to veto it as well. In addition, -during processing of the FOCUS_GAINED event, the +during processing of the FOCUS_GAINED event, the KeyboardFocusManager may attempt to resync the global focus state by synthesizing another FOCUS_LOST event. This event must be vetoed just as the first FOCUS_LOST event was.

          -A KeyboardFocusManager may not hold any locks while -notifying PropertyChangeListeners of a state change. +A KeyboardFocusManager may not hold any locks while +notifying PropertyChangeListeners of a state change. This requirement is relaxed for VetoableChangeListeners, however. Therefore, client-definied VetoableChangeListeners should avoid acquiring additional locks inside @@ -1089,13 +1088,13 @@ vetoed focus changes and recovery attempts. - +

          Z-Order

          On some native windowing systems, the Z-order of a Window can affect -its focused or active (if applicable) state. On Microsoft Windows, the -top-most Window is naturally the focused Window as well. However, on -Solaris, many window managers use a point-to-focus model that ignores +its focused or active (if applicable) state. On Microsoft Windows, the +top-most Window is naturally the focused Window as well. However, on +Solaris, many window managers use a point-to-focus model that ignores Z-order in determining the focused Window. When focusing or activating Windows, the AWT adheres to the UI @@ -1114,8 +1113,8 @@ Microsoft Windows and Solaris is as follows:

          • Window.toFront():
            - Microsoft Windows: The Window is moved to front, if possible. - While we will always be able to move this Window in front of other + Microsoft Windows: The Window is moved to front, if possible. + While we will always be able to move this Window in front of other Windows in the same VM, Windows 98 and Windows 2000 do not allow an application to bring any of its windows to the front unless one of that application's windows is already in the foreground. In @@ -1129,15 +1128,15 @@ window manager, the focused Window will remain unchanged.
          • Window.toBack():
            - Microsoft Windows: The Window is moved to back. Note however - that Microsoft Windows insists that an owned Window always be in - front of all of its recursive owners. Thus, after the completion of - this operation, the Window may not be the lowest Java Window in the - Z-order. If the Window, or any of its owners, was the focused Window, + Microsoft Windows: The Window is moved to back. Note however + that Microsoft Windows insists that an owned Window always be in + front of all of its recursive owners. Thus, after the completion of + this operation, the Window may not be the lowest Java Window in the + Z-order. If the Window, or any of its owners, was the focused Window, then the focused Window is reset to the top-most Window in the VM.
            - Solaris: The Window is moved to back. Like Microsoft Windows, - some window managers insist than an owned Window always be in front + Solaris: The Window is moved to back. Like Microsoft Windows, + some window managers insist than an owned Window always be in front of all of its recursive owners. Thus, after the completion of this operation, the Window may not be the lowest Java Window in the Z-order. If the Window was the focused Window, it will lose @@ -1156,7 +1155,7 @@
          • Window.hide()/Window.setVisible(false)/Window.dispose()/ Frame.setState(ICONIFIED):
            - Microsoft Windows: If the Window was the focused Window, the focused + Microsoft Windows: If the Window was the focused Window, the focused Window is reset to a window chosen by the OS, or to no window. The window may be in a native application, or a Java application in another VM. @@ -1169,7 +1168,7 @@ application in another VM.
          - +

          Replacing DefaultKeyboardFocusManager

          KeyboardFocusManagers are pluggable at the browser context @@ -1238,7 +1237,7 @@ heavyweight Container, not the focus owner.

        1. A FOCUS_LOST event must be retargeted to the focus owner. Again, this is necessary because the peer layer is - unaware of lightweight Components. + unaware of lightweight Components.
        2. A WINDOW_LOST_FOCUS event must be retargeted to the focused Window. The implementation of the Window class may cause the native focused Window to differ from the Java @@ -1269,7 +1268,7 @@ to set the global focus owner to a non-focusable Component.
        3. If the KeyboardFocusManager attempts to set the global focused Window to a non-focusable Window. -
        4. If the change is rejected by an installed +
        5. If the change is rejected by an installed VetoableChangeListener.

          @@ -1302,13 +1301,13 @@ recent focus owner.

        6. The KeyboardFocusManager must ensure that the opposite Component or Window are as accurate as the native - windowing platform permits. For example, the + windowing platform permits. For example, the KeyboardFocusManager may need to retarget the opposite Component to a lightweight child of the heavyweight initially specified by the peer layer.
          If the peer layer states that the opposite Component or Window is - null, it is acceptable for the + null, it is acceptable for the KeyboardFocusManager to propagate this value. null indicates that it is highly probably that no other Component or Window was involved @@ -1325,7 +1324,7 @@ events. - +

          Incompatibilities with Previous Releases

          Cross-platform changes:

            @@ -1343,7 +1342,7 @@
          1. KeyListeners installed on Components will no longer see KeyEvents that map to focus traversal operations, and - Component.handleEvent() will no longer be invoked + Component.handleEvent() will no longer be invoked for such events. Previously, AWT Components saw these events and had an opportunity to consume them before AWT initiated focus traversal. Code that requires this @@ -1352,7 +1351,7 @@ itself. Alternately, the code can use an AWTEventListener or KeyEventDispatcher to pre-listen to all - KeyEvents. + KeyEvents.

          Changes specific to Microsoft Windows:

            diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/java/awt/doc-files/Modality.html --- a/src/java.desktop/share/classes/java/awt/doc-files/Modality.html Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/java/awt/doc-files/Modality.html Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,11 @@ + + + + + The AWT Modality + - - - - - + - The AWT Modality - - - - - -

            The AWT Modality

            +

            The AWT Modality

            This document, together with the API documentation for modality-related @@ -53,7 +49,7 @@

          1. Examples
          2. - +

            Definitions

            @@ -63,7 +59,7 @@ Every window belongs to some document — its root can be found as the closest ancestor window without an owner.

            - + Modal blocked window - a window, that:

            • doesn't receive any user input events @@ -73,7 +69,7 @@

              Warning! Some window managers allow users to change the window - Z-order in an arbitrary way — in that case the last requirement + Z-order in an arbitrary way — in that case the last requirement may not be met.
              @@ -87,7 +83,7 @@ then all its owned windows and child components are also excluded.

              Scope of blocking (SB) - the set of windows (instances of - java.awt.Window and all derived classes) that are blocked by + java.awt.Window and all derived classes) that are blocked by the modal dialog while it is visible.


              Note: Everywhere in this document the notion of "window" is equal @@ -95,7 +91,7 @@ an instance of java.awt.Window or any descendant class.
              - +

              Modality types

              @@ -159,7 +155,7 @@ dialog may have no effect until it is hidden and then shown again.


  • - +

    Show/hide blocking

    @@ -171,7 +167,7 @@

    Showing the modal dialog: "M"
    When modal dialog M is shown, all the visible windows fall into one of - three distinct groups: + three distinct groups:

    • Blockers of M (modal dialogs that block M and either are in M's child hierarchy, or are not blocked by M, or have @@ -260,11 +256,11 @@ If M was blocked by any other modal dialog, for example, "N", it becomes unblocked and is removed from N's blocked windows list. Then, all the windows and dialogs - blocked by M become unblocked, and after that the same checks + blocked by M become unblocked, and after that the same checks (as in Showing the modal dialog: "M") are performed for each of them in the order they were initially shown. - +

      Modal exclusion

      @@ -290,7 +286,7 @@ may have no effect until it is hidden and then shown again. - +

      Related AWT features

      @@ -333,21 +329,21 @@

    • If the modal dialog to be hidden does not have focus, the active window remains unchanged. - - + +

      Security

      A special AWTPermission, "toolkitModality", is required to show toolkit-modal - dialogs. This would prevent, for example, blocking a browser or + dialogs. This would prevent, for example, blocking a browser or Java Web Start (JWS) by modal dialogs shown from applets.

      The same permission is required to exclude a window from toolkit modality. This would prevent, for example, a dialog shown from an applet not to be blocked by a browser's or JWS's modal dialog. - +

      Platform support

      @@ -366,18 +362,18 @@ and a window is marked as E-excluded, this has no effect.

    - +

    Compatibility

    The default modality type is application-modal. It is used by the API - calls: Dialog.setModal(true), + calls: Dialog.setModal(true), Dialog(owner, true), etc. Prior to JDK 6 the default type was toolkit-modal, but the only distinction between application- and toolkit-modality is for applets and applications launched from Java Web Start. - +

    Examples

    @@ -429,7 +425,7 @@ it's in the same application
  • Di is shown
  • Di becomes blocked by Dii — it's its owner
    -
  • Diii remains unblocked — it blocks Dii and +
  • Diii remains unblocked — it blocks Dii and Dii blocks Di

    diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/java/awt/image/FilteredImageSource.java --- a/src/java.desktop/share/classes/java/awt/image/FilteredImageSource.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/java/awt/image/FilteredImageSource.java Thu Dec 14 12:28:32 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,8 @@ /** * This class is an implementation of the ImageProducer interface which * takes an existing image and a filter object and uses them to produce - * image data for a new filtered version of the original image. + * image data for a new filtered version of the original image. Furthermore, + * {@code FilteredImageSource} is safe for use by multiple threads. * Here is an example which filters an image by swapping the red and * blue components: *
    @@ -171,7 +172,7 @@
          * @param ic  the consumer for the filtered image
          * @see ImageConsumer
          */
    -    public void startProduction(ImageConsumer ic) {
    +    public synchronized void startProduction(ImageConsumer ic) {
             if (proxies == null) {
                 proxies = new Hashtable<>();
             }
    @@ -198,7 +199,7 @@
          *
          * @see ImageConsumer
          */
    -    public void requestTopDownLeftRightResend(ImageConsumer ic) {
    +    public synchronized void requestTopDownLeftRightResend(ImageConsumer ic) {
             if (proxies != null) {
                 ImageFilter imgf = proxies.get(ic);
                 if (imgf != null) {
    diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/javax/imageio/metadata/doc-files/bmp_metadata.html
    --- a/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/bmp_metadata.html	Mon Dec 11 16:43:11 2017 +0000
    +++ b/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/bmp_metadata.html	Thu Dec 14 12:28:32 2017 +0000
    @@ -1,8 +1,11 @@
    -
    -
    +
    +
     
    +  
    +  BMP Metadata Format Specification
    +
     
     
    -BMP Metadata Format Specification
    -
    -
     
    -

    -BMP Metadata Format Specification -

    +

    BMP Metadata Format Specification

    The XML schema for the native image metadata format is as follows: @@ -108,7 +106,7 @@ </xsd:element> <!-- Color space --> - <xsd:element name="ColorSpaceType" type="xsd:unsignedInt" + <xsd:element name="ColorSpaceType" type="xsd:unsignedInt" minOccurs="0"/> <!-- CIE XYZ for the LCS_CALIBRATED_RGB color space --> diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/javax/imageio/metadata/doc-files/gif_metadata.html --- a/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/gif_metadata.html Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/gif_metadata.html Thu Dec 14 12:28:32 2017 +0000 @@ -1,8 +1,11 @@ - - + + + + GIF Metadata Format Specification + -GIF Metadata Format Specification - - - + -

    -GIF Metadata Format Specification -

    - -

    -GIF Stream Metadata Format Specification -

    +

    GIF Metadata Format Specification

    + +

    GIF Stream Metadata Format Specification

    @@ -59,7 +55,7 @@

     <!DOCTYPE "javax_imageio_gif_stream_1.0" [
     
    -  <!ELEMENT "javax_imageio_gif_stream_1.0" (Version?, 
    +  <!ELEMENT "javax_imageio_gif_stream_1.0" (Version?,
         LogicalScreenDescriptor?, GlobalColorTable?)>
     
         <!ELEMENT "Version" EMPTY>
    @@ -98,7 +94,7 @@
           <!-- The global color table -->
           <!-- Min children: 2 -->
           <!-- Max children: 256 -->
    -      <!ATTLIST "GlobalColorTable" "sizeOfGlobalColorTable" ("2" | 
    +      <!ATTLIST "GlobalColorTable" "sizeOfGlobalColorTable" ("2" |
             "4" | "8" | "16" | "32" | "64" | "128" | "256") #REQUIRED>
             <!-- The number of entries in the global color table -->
           <!ATTLIST "GlobalColorTable" "backgroundColorIndex" #CDATA
    @@ -135,10 +131,8 @@
               <!-- Max value: 255 (inclusive) -->
     ]>
     
    - -

    -GIF Image Metadata Format Specification -

    + +

    GIF Image Metadata Format Specification

    The GIF image metadata format encodes the image descriptor, local @@ -180,8 +174,8 @@

     <!DOCTYPE "javax_imageio_gif_image_1.0" [
     
    -  <!ELEMENT "javax_imageio_gif_image_1.0" (ImageDescriptor?, 
    -    LocalColorTable?, GraphicControlExtension?, PlainTextExtension?, 
    +  <!ELEMENT "javax_imageio_gif_image_1.0" (ImageDescriptor?,
    +    LocalColorTable?, GraphicControlExtension?, PlainTextExtension?,
         ApplicationExtensions?, CommentExtensions?)>
     
         <!ELEMENT "ImageDescriptor" EMPTY>
    @@ -214,7 +208,7 @@
           <!-- The local color table -->
           <!-- Min children: 2 -->
           <!-- Max children: 256 -->
    -      <!ATTLIST "LocalColorTable" "sizeOfLocalColorTable" ("2" | 
    +      <!ATTLIST "LocalColorTable" "sizeOfLocalColorTable" ("2" |
             "4" | "8" | "16" | "32" | "64" | "128" | "256") #REQUIRED>
             <!-- The number of entries in the local color table -->
           <!ATTLIST "LocalColorTable" "sortFlag" ("TRUE" | "FALSE")
    @@ -246,13 +240,13 @@
     
         <!ELEMENT "GraphicControlExtension" EMPTY>
           <!-- A graphic control extension -->
    -      <!ATTLIST "GraphicControlExtension" "disposalMethod" ("none" | 
    -        "doNotDispose" | "restoreToBackgroundColor" | 
    -        "restoreToPrevious" | "undefinedDisposalMethod4" | 
    -        "undefinedDisposalMethod5" | "undefinedDisposalMethod6" | 
    +      <!ATTLIST "GraphicControlExtension" "disposalMethod" ("none" |
    +        "doNotDispose" | "restoreToBackgroundColor" |
    +        "restoreToPrevious" | "undefinedDisposalMethod4" |
    +        "undefinedDisposalMethod5" | "undefinedDisposalMethod6" |
             "undefinedDisposalMethod7") #REQUIRED>
             <!-- The disposal method for this frame -->
    -      <!ATTLIST "GraphicControlExtension" "userInputFlag" ("TRUE" | 
    +      <!ATTLIST "GraphicControlExtension" "userInputFlag" ("TRUE" |
             "FALSE") #REQUIRED>
             <!-- True if the frame should be advanced based on user input -->
           <!ATTLIST "GraphicControlExtension" "transparentColorFlag" (
    @@ -350,8 +344,7 @@
     

    - -

    +
  • @@ -399,9 +392,7 @@
    Mapping of Standard to GIF Native Stream Metadata
    /Version@value
    - -
    @@ -443,7 +434,6 @@ "TRUE")
    Mapping of Standard to GIF Native Image Metadata
    -
    diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/javax/imageio/metadata/doc-files/jpeg_metadata.html --- a/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/jpeg_metadata.html Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/jpeg_metadata.html Thu Dec 14 12:28:32 2017 +0000 @@ -1,8 +1,11 @@ - - + + + + JPEG Metadata Format Specification and Usage Notes + -JPEG Metadata Format Specification and Usage Notes - + - - -

    -JPEG Metadata Format Specification and Usage Notes -

    +

    JPEG Metadata Format Specification and Usage Notes

    JPEG Metadata
    @@ -46,11 +44,11 @@ Image Metadata DTD
    Stream Metadata DTD

    -NOTE: It is important to call dispose() -on the JPEG reader and writer objects when they are no longer needed, as -they consume significant native resources which are not adequately recovered -by garbage collection. Both reader and writer call dispose() -in their finalizers, but those finalizers may not be called before the native +NOTE: It is important to call dispose() +on the JPEG reader and writer objects when they are no longer needed, as +they consume significant native resources which are not adequately recovered +by garbage collection. Both reader and writer call dispose() +in their finalizers, but those finalizers may not be called before the native code has exhausted native memory.

    @@ -58,45 +56,45 @@ The JPEG writer does not support replacing pixels.

    -JPEG Metadata +JPEG Metadata

    JPEG metadata consists of the data contained in marker segments in a JPEG stream. The image metadata object returned from a read describes the -contents of the marker segments between the SOI marker and -the EOI marker for that image. The image metadata object -passed into a write determines the contents of the stream between the -SOI marker and the EOI marker for that image, +contents of the marker segments between the SOI marker and +the EOI marker for that image. The image metadata object +passed into a write determines the contents of the stream between the +SOI marker and the EOI marker for that image, subject to the controls in any ImageWriteParam.

    -Stream metadata is used only for tables-only images found (or to be -placed) at the beginning of a stream containing abbreviated images. -Tables-only images are not treated as images and do not consume an +Stream metadata is used only for tables-only images found (or to be +placed) at the beginning of a stream containing abbreviated images. +Tables-only images are not treated as images and do not consume an image index. The stream metadata object returned from a read describes the -contents of the marker segments between the SOI marker and -the EOI marker for the single tables-only image at the -beginning of the stream, if one is present. If no tables-only image is -present at the front of the stream, the getStreamMetadata -method of ImageReader returns null. If -stream metadata is provided to the writer, a single tables-only image -containing the tables from the stream metadata object will be written at +contents of the marker segments between the SOI marker and +the EOI marker for the single tables-only image at the +beginning of the stream, if one is present. If no tables-only image is +present at the front of the stream, the getStreamMetadata +method of ImageReader returns null. If +stream metadata is provided to the writer, a single tables-only image +containing the tables from the stream metadata object will be written at the beginning of the stream. If the stream metadata object contains no tables, default tables will be written. As the sole purpose of stream -metadata is for specifying tables-only images at the front of abbreviated -streams, the stream metadata argument is useful only on the -ImageWriter.prepareWriteSequence method. It is ignored on all +metadata is for specifying tables-only images at the front of abbreviated +streams, the stream metadata argument is useful only on the +ImageWriter.prepareWriteSequence method. It is ignored on all other methods. -

    -The ImageWriter.getDefaultStreamMetadata method returns an -object containing the tables from the ImageWriteParam argument, -if it is a JPEGImageWriteParam and contains tables. Otherwise, +

    +The ImageWriter.getDefaultStreamMetadata method returns an +object containing the tables from the ImageWriteParam argument, +if it is a JPEGImageWriteParam and contains tables. Otherwise, the returned object will contain default tables. -

    The ImageWriter.getDefaultImageMetadata method returns a -metadata object containing no tables if the -ImageWriteParam argument contains tables. Otherwise the -returned metadata object will contain default visually lossless tables. +

    The ImageWriter.getDefaultImageMetadata method returns a +metadata object containing no tables if the +ImageWriteParam argument contains tables. Otherwise the +returned metadata object will contain default visually lossless tables. Of course, only a JPEGImageWriteParam may contain tables.

    @@ -105,59 +103,59 @@ metadata will.

    -Abbreviated Streams +Abbreviated Streams

    -Both the reader and the writer retain their tables from one operation to the -next, thus permitting the use of abbreviated streams quite naturally, with a -few minor restrictions: +Both the reader and the writer retain their tables from one operation to the +next, thus permitting the use of abbreviated streams quite naturally, with a +few minor restrictions:
      -
    1. Abbreviated streams may contain only one tables-only image, which must +
    2. Abbreviated streams may contain only one tables-only image, which must come first in the stream. Subsequent tables-only images will cause undefined behavior.
    3. Abbreviated streams must be read fully and in order. No random access - is allowed, in either direction. The same image may be read multiple + is allowed, in either direction. The same image may be read multiple times. If a call is made with an image index that is not the same as or one greater than the most recent call (or 0 if no calls have been made), then an IllegalArgumentException is thrown.
    -These restrictions mean that streams may contain abbreviated images +These restrictions mean that streams may contain abbreviated images interspersed with images containing tables. As required by JPEG, any tables appearing in the stream override previous tables, regardless of the source -of the previous tables. +of the previous tables.

    Note that once a tables-only image has been read, it's contents is available as stream metadata from the reader until either another tables-only image is read from another stream or the reader is reset. Changing the input does not reset the stream metadata. This is useful for reading the tables from -one file, then changing the input to read an abbreviated stream containing +one file, then changing the input to read an abbreviated stream containing a sequence of images. The tables will be used automatically, and will remain available as "stream" metadata.

    -Abbreviated streams are written using the sequence methods of -ImageWriter. Stream metadata is used to write a tables-only +Abbreviated streams are written using the sequence methods of +ImageWriter. Stream metadata is used to write a tables-only image at the beginning of the stream, and the tables are set up for use, using -ImageWriter.prepareWriteSequence. If no stream metadata is -supplied to ImageWriter.prepareWriteSequence, then no +ImageWriter.prepareWriteSequence. If no stream metadata is +supplied to ImageWriter.prepareWriteSequence, then no tables-only image is written. If stream metadata containing no tables is supplied to ImageWriter.prepareWriteSequence, then a tables-only image containing default visually lossless tables is written.

    -Sources of Tables +Sources of Tables

    -Images are written with tables if tables are present in their metadata objects +Images are written with tables if tables are present in their metadata objects or without them if no tables are present in their metadata objects. If no -metadata object is present then the tables are written. The tables used for -compression are taken from one of the following sources, which are consulted -in order: +metadata object is present then the tables are written. The tables used for +compression are taken from one of the following sources, which are consulted +in order:

    1. If there is an ImageWriteParam and the compression mode is set to EXPLICIT, default tables constructed using the - quality setting are used. They are written only if the metadata - contains tables or if there is no metadata, but they replace the + quality setting are used. They are written only if the metadata + contains tables or if there is no metadata, but they replace the tables in the metadata.
    2. If there is an ImageWriteParam and the compression mode is set to DEFAULT, default visually lossles tables are used. @@ -176,39 +174,39 @@
    -This ordering implements the design intention that tables should be included -in JPEGImageWriteParams only as a means of specifying tables +This ordering implements the design intention that tables should be included +in JPEGImageWriteParams only as a means of specifying tables when no other source is available, and this can occur only when writing to an -abbreviated stream without tables using known non-standard tables for +abbreviated stream without tables using known non-standard tables for compression.

    -When reading, tables in a JPEGImageReadParam are consulted only -if tables have not been set by any previous read. Tables set from a -JPEGImageReadParam are overridden by any tables present in the +When reading, tables in a JPEGImageReadParam are consulted only +if tables have not been set by any previous read. Tables set from a +JPEGImageReadParam are overridden by any tables present in the stream being read.

    -Note that if no image metadata object is specified for a particular image, a +Note that if no image metadata object is specified for a particular image, a default object is used, which includes default tables.

    -Colorspace Transformations and Conventional Markers +Colorspace Transformations and Conventional Markers

    Colorspace transformations are controlled by the destination type for both reading and writing of images. When Rasters are -read, no colorspace transformation is performed, and any destination type -is ignored. A warning is sent to any listeners if a destination type is -specified in this case. When Rasters are written, any +read, no colorspace transformation is performed, and any destination type +is ignored. A warning is sent to any listeners if a destination type is +specified in this case. When Rasters are written, any destination type is used to interpret the bands. This might result in a -JFIF or Adobe header being written, or different component ids being written -to the frame and scan headers. If values present in a metadata object do not -match the destination type, the destination type is used and a warning is sent +JFIF or Adobe header being written, or different component ids being written +to the frame and scan headers. If values present in a metadata object do not +match the destination type, the destination type is used and a warning is sent to any listeners.

    -Optional ColorSpace support: +Optional ColorSpace support: Handling of PhotoYCC (YCC), PhotoYCCA (YCCA), RGBA and YCbCrA color spaces by the standard plugin, as described below, is dependent on capabilities of the libraries used to interpret the JPEG data. Thus all consequential @@ -219,7 +217,7 @@ When writing, an Exception may be thrown if no suitable conversion can be applied before encoding. But where the support for these color spaces is available, the behavior -must be as documented. +must be as documented.

    When reading, the contents of the stream are interpreted by the usual @@ -232,7 +230,7 @@ the YCbCr is converted to RGB according to the formulas given in the JFIF spec, and the ICC profile is assumed to refer to the resulting RGB space. -

  • If an Adobe APP14 marker segment is present, the +
  • If an Adobe APP14 marker segment is present, the colorspace is determined by consulting the transform flag. The transform flag takes one of three values:
      @@ -242,7 +240,7 @@
    • 1 - The image is encoded as YCbCr (implicitly converted from RGB on encoding). -
    • 0 - Unknown. 3-channel images are assumed to be RGB, 4-channel +
    • 0 - Unknown. 3-channel images are assumed to be RGB, 4-channel images are assumed to be CMYK.
  • If neither marker segment is present, the following procedure is @@ -253,9 +251,9 @@ YCbCr. Subject to the availability of the optional color space support described above, if these values are 1-4 for a 4-channel image, - then the image is assumed to be YCbCrA. - If these values are > 4, they are checked - against the ASCII codes for 'R', 'G', 'B', 'A', 'C', 'c'. These can + then the image is assumed to be YCbCrA. + If these values are > 4, they are checked + against the ASCII codes for 'R', 'G', 'B', 'A', 'C', 'c'. These can encode the following colorspaces:


    RGB @@ -263,28 +261,28 @@
    YCC (as 'Y','C','c'), assumed to be PhotoYCC
    YCCA (as 'Y','C','c','A'), assumed to be PhotoYCCA

    - Otherwise, 3-channel subsampled images are assumed to be YCbCr, - 3-channel non-subsampled images are assumed to be RGB, 4-channel + Otherwise, 3-channel subsampled images are assumed to be YCbCr, + 3-channel non-subsampled images are assumed to be RGB, 4-channel subsampled images are assumed to be YCCK, and 4-channel, non-subsampled images are assumed to be CMYK.

  • All other images are declared uninterpretable and an exception is - thrown if an attempt is made to read one as a - BufferedImage. Such an image may be read only as a + thrown if an attempt is made to read one as a + BufferedImage. Such an image may be read only as a Raster. If an image is interpretable but there is no Java - ColorSpace available corresponding to the encoded - colorspace (e.g. YCbCr), then + ColorSpace available corresponding to the encoded + colorspace (e.g. YCbCr), then ImageReader.getRawImageType will return null. -Once an encoded colorspace is determined, then the target colorspace is +Once an encoded colorspace is determined, then the target colorspace is determined as follows:
    • If a destination type is not set, then the following default - transformations take place after upsampling: YCbCr (and YCbCrA) images + transformations take place after upsampling: YCbCr (and YCbCrA) images are converted to RGB (and RGBA) using the conversion provided by the - underlying IJG library and either the built-in sRGB + underlying IJG library and either the built-in sRGB ColorSpace or a custom RGB ColorSpace object based on an embedded ICC profile is used to create the output ColorModel. PhotoYCC and PhotoYCCA images are not @@ -292,16 +290,16 @@
    • If a destination image or type is set, it is used as follows: If the IJG library provides an appropriate conversion, it is used. - Otherwise the default library conversion is followed by a colorspace + Otherwise the default library conversion is followed by a colorspace conversion in Java.
    • -
    • Bands are selected AFTER any library colorspace conversion. If a - subset of either source or destination bands is used, then the default +
    • Bands are selected AFTER any library colorspace conversion. If a + subset of either source or destination bands is used, then the default library conversions are used with no further conversion in Java, regardless of any destination type.
    • -
    • An exception is thrown if an attempt is made to read an image in an - unsupported jpeg colorspace as a BufferedImage +
    • An exception is thrown if an attempt is made to read an image in an + unsupported jpeg colorspace as a BufferedImage (e.g. CMYK). Such images may be read as Rasters. If an image colorspace is unsupported or uninterpretable, then ImageReader.getImageTypes will @@ -315,26 +313,26 @@ follows:

      -If a subset of the source bands is to be written, no color conversion is -performed. Any destination, if set, must match the number of bands that will -be written, and serves as an interpretation of the selected bands, rather than -a conversion request. This behavior is identical to that for -Rasters. If all the bands are to be written and an image -(as opposed to a Raster) is being written, any destination type +If a subset of the source bands is to be written, no color conversion is +performed. Any destination, if set, must match the number of bands that will +be written, and serves as an interpretation of the selected bands, rather than +a conversion request. This behavior is identical to that for +Rasters. If all the bands are to be written and an image +(as opposed to a Raster) is being written, any destination type is ignored and a warning is sent to any listeners.

      -If a destination type is used and any aspect of the metadata object, if there -is one, is not compatible with that type, the destination type is used, the -metadata written is modified from that provided, and a warning is sent to -listeners. This includes the app0JFIF and -app14Adobe nodes. The component ids in the sof and -sos nodes are not modified, however, as unless a +If a destination type is used and any aspect of the metadata object, if there +is one, is not compatible with that type, the destination type is used, the +metadata written is modified from that provided, and a warning is sent to +listeners. This includes the app0JFIF and +app14Adobe nodes. The component ids in the sof and +sos nodes are not modified, however, as unless a app0JFIF node is present, any values may be used.

      -When a full image is written, a destination colorspace will be -chosen based on the image contents and the metadata settings, according to +When a full image is written, a destination colorspace will be +chosen based on the image contents and the metadata settings, according to the following algorithm:

      @@ -351,9 +349,9 @@ channels by half both vertically and horizontally, and written with a JFIF APP0 marker segment. If the ColorSpace of the image is based on an ICCProfile (it is an instance - of ICC_ColorSpace, but is not one of the standard built-in - ColorSpaces), then that profile is embedded in an - APP2 marker segment. As required by JFIF, the + of ICC_ColorSpace, but is not one of the standard built-in + ColorSpaces), then that profile is embedded in an + APP2 marker segment. As required by JFIF, the component ids in the frame and scan headers are set to 1, 2, and 3. @@ -361,7 +359,7 @@ described above, RGBA images are converted to YCbCrA, subsampled in the chrominance channels by half both vertically and horizontally, and - written without any special marker segments. The component ids + written without any special marker segments. The component ids in the frame and scan headers are set to 1, 2, 3, and 4.

    • Subject to the optional library support @@ -378,16 +376,16 @@

      If a metadata object is specified, then the number of channels in the -frame and scan headers must always match the number of bands to be -written, or an exception is thrown. app0JFIF and -app14Adobe nodes may appear in the same metadata object only -if the app14Adobe node indicates YCbCr, and the component ids -are JFIF compatible (0-2). The various image types are processed in the +frame and scan headers must always match the number of bands to be +written, or an exception is thrown. app0JFIF and +app14Adobe nodes may appear in the same metadata object only +if the app14Adobe node indicates YCbCr, and the component ids +are JFIF compatible (0-2). The various image types are processed in the following ways:
      -(All multi-channel images are subsampled according to the sampling factors +(All multi-channel images are subsampled according to the sampling factors in the frame header node of the metadata object, regardless of color space.)

        @@ -395,10 +393,10 @@
        • If an app0JFIF node is present in the metadata object, a JFIF APP0 marker segment is written. -
        • If an app14Adobe node is present in the metadata +
        • If an app14Adobe node is present in the metadata object, it is checked for validity (transform must be UNKNOWN) and written. -
        • If neither node is present in the metadata object, no special +
        • If neither node is present in the metadata object, no special marker segment is written.
        @@ -412,14 +410,14 @@ UNKNOWN) and written. If transform is not UNKNOWN, a warning is sent to listeners and the correct transform is written. -
      • If neither node is present in the metadata object, no special +
      • If neither node is present in the metadata object, no special marker segment is written.
    • RGB Images:
      • If an app0JFIF node is present in the metadata object, - the image is converted to YCbCr and written with a JFIF + the image is converted to YCbCr and written with a JFIF APP0 marker segment. If the ColorSpace of the image is based on a non-standard ICC Profile, then that profile is embedded in an APP2 marker segment. If the @@ -439,7 +437,7 @@
      • If neither node is present, the component ids in the frame header are consulted. If these indicate a colorspace as described - above, then the image is converted to that colorspace if possible. + above, then the image is converted to that colorspace if possible. If the component ids do not indicate a colorspace, then the sampling factors are consulted. If the image is to be subsampled, it is converted to YCbCr first. If the image is not to be @@ -459,7 +457,7 @@ object, the image is written with an Adobe APP14 marker segment. No colorspace conversion is performed. Component ids are written just as they appear in the frame and scan headers. - The color transform must be UNKNOWN. If it is + The color transform must be UNKNOWN. If it is not, a warning is sent to listeners.
      • If no app14Adobe node is present, the component ids in @@ -509,16 +507,16 @@

      -Thumbnail Images +Thumbnail Images

      Thumbnails are supported by the use of JFIF and JFIF extension marker segments. -Thumbnails provided on the write methods determine the thumbnails that will be -included. app0JFIF and app0JFXX nodes present in -the metadata do not contain any thumbnail pixel data. However, the kinds of -thumbnails written depend on the contents of the metadata object, as follows. -Any thumbnail which is to be written as an indexed or RGB image and which is -larger than 255 by 255 will be clipped, not scaled, to 255 by 255. Thumbnails -written as JPEG images may be any size. A warning is sent to any listeners +Thumbnails provided on the write methods determine the thumbnails that will be +included. app0JFIF and app0JFXX nodes present in +the metadata do not contain any thumbnail pixel data. However, the kinds of +thumbnails written depend on the contents of the metadata object, as follows. +Any thumbnail which is to be written as an indexed or RGB image and which is +larger than 255 by 255 will be clipped, not scaled, to 255 by 255. Thumbnails +written as JPEG images may be any size. A warning is sent to any listeners whenever a thumbnail is clipped.
      • If there is a single thumbnail, it is processed as follows: @@ -534,14 +532,14 @@
      • If the first app0JFXX node present in the metadata contains another thumbnail form (RGB or JPEG), the palette image is expanded to RGB and the indicated thumbnail form is - written. + written.
    • If the thumbnail image is an RGB image, it is processed as follows:
      • If no app0JFXX node is present in the metadata, the thumbnail is written as part of the JFIF APP0 - marker segment. + marker segment.
      • If the first app0JFXX node present in the metadata contains a JFIFthumbRGB element, an RGB thumbnail is written in a JFXX APP0 marker @@ -561,7 +559,7 @@
        • If no app0JFXX node is present in the metadata, the thumbnail is expanded to RGB and written as part of the - JFIF APP0 marker segment. + JFIF APP0 marker segment.
        • If the first app0JFXX node present in the metadata contains a JFIFthumbRGB element, the thumbnail is expanded to RGB and written in a separate JFXX RGB @@ -587,50 +585,50 @@ sequence as the thumbnail. I.e. the first app0JFXX node applies to the first thumbnail, the second node to the second thumbnail, and so on. If there are fewer - app0JFXX nodes in the metadata than thumbnails, then + app0JFXX nodes in the metadata than thumbnails, then those thumbnails are considered to have no matching app0JFXX node. An RGB thumbnail with no matching app0JFXX node is written in a JFXX APP0 marker segment. A grayscale thumbnail with no matching - app0JFXX node is written as a JPEG image to a JFXX + app0JFXX node is written as a JPEG image to a JFXX APP0 marker segment.

        Note that as the only mechanism for storing thumbnails is via the -JFIF or JFIF extension marker segments, only grayscale or RGB images -may have thumbnails. If thumbnails are present when writing any other type +JFIF or JFIF extension marker segments, only grayscale or RGB images +may have thumbnails. If thumbnails are present when writing any other type of image, the thumbnails are ignored and a warning is sent to any warning listeners.

        -Progressive Encoding +Progressive Encoding

        Progressive encoding must be enabled on the ImageWriteParam passed in to a write operation, or the image will be written sequentially, -regardless of the scan headers included in the metadata object. If +regardless of the scan headers included in the metadata object. If progressive encoding is enabled and set to copy from metadata, then -the sequence of scan headers from the metadata is used to write the -image. If progressive encoding is enabled and set to use a default, -then the scans in the metadata are ignored and a default set of scans +the sequence of scan headers from the metadata is used to write the +image. If progressive encoding is enabled and set to use a default, +then the scans in the metadata are ignored and a default set of scans is used. Progressive encoding always forces optimized Huffman tables to be used. Any Huffman tables present in the metadata will be ignored, and a warning will be sent to any warning listeners. If Huffman-table optimization is requested on the ImageWriteParam, -all Huffman tables in the metadata or in the ImageWriteParam -itself are ignored, and a warning will be sent to any warning listeners if +all Huffman tables in the metadata or in the ImageWriteParam +itself are ignored, and a warning will be sent to any warning listeners if any such tables are present.

        -Native Metadata Format Tree Structure and Editing +Native Metadata Format Tree Structure and Editing

        The DTDs below describe just the trees of metadata objects actually returned -by the IIOMetadata object. They do not include nodes -corresponding to SOI, EOI, or RST -markers, as these parsing delimiters do not carry any meaningful metadata. +by the IIOMetadata object. They do not include nodes +corresponding to SOI, EOI, or RST +markers, as these parsing delimiters do not carry any meaningful metadata.

        The first node is always a JPEGvariety node. In the @@ -659,60 +657,60 @@

        -On reading, JFXX and app2ICC nodes occur as +On reading, JFXX and app2ICC nodes occur as children of an app0JFIF node. -This is true regardless of where the JFXX APP0 and -APP2 marker segments actually occur in the stream. The ordering -of nodes within the markerSequence node corresponds to the +This is true regardless of where the JFXX APP0 and +APP2 marker segments actually occur in the stream. The ordering +of nodes within the markerSequence node corresponds to the ordering of marker segments found in the JPEG stream.

        -On writing, any JFXX and app2ICC nodes must -occur as children of an app0JFIF node, itself a child of a +On writing, any JFXX and app2ICC nodes must +occur as children of an app0JFIF node, itself a child of a JPEGvariety node, which must always be the first node. (If the stream is not to be JFIF compliant, no app0JFIF node should be provided, and the JPEGvariety node should have no -children.) Any -JFIF APP0, JFXX APP0, and APP2 marker -segments are written first, followed by all Adobe APP14, -APPn, COM and unknown segments in the -order in which their corresponding nodes appear in the -markerSequence node, followed by DQT (and -DHT for non-progressive writes) marker segments, followed by the +children.) Any +JFIF APP0, JFXX APP0, and APP2 marker +segments are written first, followed by all Adobe APP14, +APPn, COM and unknown segments in the +order in which their corresponding nodes appear in the +markerSequence node, followed by DQT (and +DHT for non-progressive writes) marker segments, followed by the SOF and SOS marker segments. For progressive writes -using metadata to control progression, the SOS segments are used -in the order in which their corresponding nodes occur in the +using metadata to control progression, the SOS segments are used +in the order in which their corresponding nodes occur in the markerSequence node.

        -The reset, mergeTree and setFromTree +The reset, mergeTree and setFromTree operations have the following semantics for the JPEG plug-in metadata object: -

        reset - A call to reset will restore the -metadata object to the same state it had immediately after creation, whether -this came about from reading a stream or by obtaining a default object from -the ImageWriter. This is true regardless of how many times the +

        reset - A call to reset will restore the +metadata object to the same state it had immediately after creation, whether +this came about from reading a stream or by obtaining a default object from +the ImageWriter. This is true regardless of how many times the metadata object has been modified since creation.

        mergeTree - Native Format -
        The mergeTree operation accepts valid trees conforming to -the DTD below, and merges the nodes using the following ordering rules. In -all cases, only data present in the new node is changed in a corresponding -existing node, if any. This means that nodes cannot be removed using -mergeTree. To remove nodes, use setFromTree. The +
        The mergeTree operation accepts valid trees conforming to +the DTD below, and merges the nodes using the following ordering rules. In +all cases, only data present in the new node is changed in a corresponding +existing node, if any. This means that nodes cannot be removed using +mergeTree. To remove nodes, use setFromTree. The tree must consist of IIOMetadataNodes.

        • app0JFIF
            -
          • If an app0JFIF node already exists, the contents - of the new one modify the existing one. +
          • If an app0JFIF node already exists, the contents + of the new one modify the existing one.
          • If there is no such node, a new one is created and inserted in the appropriate position. -
          +
      • dqt
        • If there already exist dqt nodes in the sequence, then each table in the node replaces the first table, in any - dqt node, with the same table id. + dqt node, with the same table id.
        • If none of the existing dqt nodes contain a table with the same id, then the table is added to the last existing dqt node. @@ -720,10 +718,10 @@ created and added as follows:
          • If there are dht nodes, the new - dqt node is inserted before the first one. + dqt node is inserted before the first one.
          • If there are no dht nodes, the new dqt node is inserted before an - sof node, if there is one. + sof node, if there is one.
          • If there is no sof node, the new dqt node is inserted before the first sos node, if there is one. @@ -747,7 +745,7 @@ last dqt node.
          • If there are no dqt nodes, the new dht node is inserted before an - sof node, if there is one. + sof node, if there is one.
          • If there is no sof node, the new dht node is inserted before the first sos node, if there is one. @@ -757,7 +755,7 @@
        • dri
            -
          • If there already exists a dri node, the restart +
          • If there already exists a dri node, the restart interval value is updated.
          • If there is no dri node, then a new one is created and added as follows: @@ -785,11 +783,11 @@
        • app14Adobe
            -
          • If there already exists an app14Adobe node, then +
          • If there already exists an app14Adobe node, then its attributes are updated from the node. -
          • If there is no app14Adobe node, then a new one is +
          • If there is no app14Adobe node, then a new one is created and added as follows: -
              +
              • The new app14Adobe node is inserted after the last unknown node, if there are any.
              • If there are no unknown nodes, the new @@ -838,13 +836,13 @@

                mergeTree - Standard Format
                -The mergeTree operation, when given a tree in the standard +The mergeTree operation, when given a tree in the standard format, will modify the native tree in the following ways:

                • Chroma - The ColorSpaceType subnode of a Chroma node may change the target colorspace of the compressed image. The selection of a new colorspace can cause a number - of changes, in keeping with the algorithms described above: + of changes, in keeping with the algorithms described above: app0JFIF and app14Adobe nodes may be added or removed, subsampling may be added or removed, component ids may be changed, and sof and sos nodes will be @@ -871,17 +869,17 @@

                  setFromTree - Native Format
                  -The setFromTree operation, when given a tree in the native -format described below, will simply replace the existing tree in its entirety +The setFromTree operation, when given a tree in the native +format described below, will simply replace the existing tree in its entirety with the new one. The tree must consist of IIOMetadataNodes.

                  setFromTree - Standard Format
                  -The setFromTree operation, when given a tree in the standard +The setFromTree operation, when given a tree in the standard format, performs a reset followed by a merge of the new tree.

                  -Image Metadata DTD +Image Metadata DTD

                  @@ -891,39 +889,39 @@
                   
                       <!ELEMENT "JPEGvariety" (app0JFIF)>
                         <!-- A node grouping all marker segments specific to the variety of
                  -              stream being read/written (e.g. JFIF) - may be empty --> 
                  +              stream being read/written (e.g. JFIF) - may be empty -->
                   
                         <!ELEMENT "app0JFIF" (JFXX?, app2ICC?)>
                           <!ATTLIST "app0JFIF" "majorVersion" #CDATA "1">
                  -          <!-- The major JFIF version number --> 
                  +          <!-- The major JFIF version number -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 0 (inclusive) -->
                             <!-- Max value: 255 (inclusive) -->
                           <!ATTLIST "app0JFIF" "minorVersion" #CDATA "2">
                  -          <!-- The minor JFIF version number --> 
                  +          <!-- The minor JFIF version number -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 0 (inclusive) -->
                             <!-- Max value: 255 (inclusive) -->
                           <!ATTLIST "app0JFIF" "resUnits" ("0" | "1" | "2") "0">
                  -          <!-- The resolution units for Xdensisty and Ydensity (0 = no 
                  -               units, just aspect ratio; 1 = dots/inch; 2 = dots/cm) --> 
                  +          <!-- The resolution units for Xdensisty and Ydensity (0 = no
                  +               units, just aspect ratio; 1 = dots/inch; 2 = dots/cm) -->
                           <!ATTLIST "app0JFIF" "Xdensity" #CDATA "1">
                  -          <!-- The horizontal density or aspect ratio numerator --> 
                  +          <!-- The horizontal density or aspect ratio numerator -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 1 (inclusive) -->
                             <!-- Max value: 65535 (inclusive) -->
                           <!ATTLIST "app0JFIF" "Ydensity" #CDATA "1">
                  -          <!-- The vertical density or aspect ratio denominator --> 
                  +          <!-- The vertical density or aspect ratio denominator -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 1 (inclusive) -->
                             <!-- Max value: 65535 (inclusive) -->
                           <!ATTLIST "app0JFIF" "thumbWidth" #CDATA "0">
                  -          <!-- The width of the thumbnail, or 0 if there isn't one --> 
                  +          <!-- The width of the thumbnail, or 0 if there isn't one -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 0 (inclusive) -->
                             <!-- Max value: 255 (inclusive) -->
                           <!ATTLIST "app0JFIF" "thumbHeight" #CDATA "0">
                  -          <!-- The height of the thumbnail, or 0 if there isn't one --> 
                  +          <!-- The height of the thumbnail, or 0 if there isn't one -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 0 (inclusive) -->
                             <!-- Max value: 255 (inclusive) -->
                  @@ -931,233 +929,233 @@
                           <!ELEMENT "JFXX" (app0JFXX)*>
                             <!-- Min children: 1 -->
                   
                  -        <!ELEMENT "app0JFXX" (JFIFthumbJPEG | JFIFthumbPalette | 
                  +        <!ELEMENT "app0JFXX" (JFIFthumbJPEG | JFIFthumbPalette |
                             JFIFthumbRGB)>
                  -          <!-- A JFIF extension marker segment --> 
                  +          <!-- A JFIF extension marker segment -->
                             <!ATTLIST "app0JFXX" "extensionCode" ("16" | "17" | "19")
                                #IMPLIED>
                  -            <!-- The JFXX extension code identifying thumbnail type: (16 = 
                  -                 JPEG, 17 = indexed, 19 = RGB --> 
                  +            <!-- The JFXX extension code identifying thumbnail type: (16 =
                  +                 JPEG, 17 = indexed, 19 = RGB -->
                   
                             <!ELEMENT "JFIFthumbJPEG" (markerSequence?)>
                  -            <!-- A JFIF thumbnail in JPEG format (no JFIF segments 
                  -                 permitted) --> 
                  +            <!-- A JFIF thumbnail in JPEG format (no JFIF segments
                  +                 permitted) -->
                   
                             <!ELEMENT "JFIFthumbPalette" EMPTY>
                  -            <!-- A JFIF thumbnail as an RGB indexed image --> 
                  +            <!-- A JFIF thumbnail as an RGB indexed image -->
                               <!ATTLIST "JFIFthumbPalette" "thumbWidth" #CDATA #IMPLIED>
                  -              <!-- The width of the thumbnail --> 
                  +              <!-- The width of the thumbnail -->
                                 <!-- Data type: Integer -->
                                 <!-- Min value: 0 (inclusive) -->
                                 <!-- Max value: 255 (inclusive) -->
                               <!ATTLIST "JFIFthumbPalette" "thumbHeight" #CDATA #IMPLIED>
                  -              <!-- The height of the thumbnail --> 
                  +              <!-- The height of the thumbnail -->
                                 <!-- Data type: Integer -->
                                 <!-- Min value: 0 (inclusive) -->
                                 <!-- Max value: 255 (inclusive) -->
                   
                             <!ELEMENT "JFIFthumbRGB" EMPTY>
                  -            <!-- A JFIF thumbnail as an RGB image --> 
                  +            <!-- A JFIF thumbnail as an RGB image -->
                               <!ATTLIST "JFIFthumbRGB" "thumbWidth" #CDATA #IMPLIED>
                  -              <!-- The width of the thumbnail --> 
                  +              <!-- The width of the thumbnail -->
                                 <!-- Data type: Integer -->
                                 <!-- Min value: 0 (inclusive) -->
                                 <!-- Max value: 255 (inclusive) -->
                               <!ATTLIST "JFIFthumbRGB" "thumbHeight" #CDATA #IMPLIED>
                  -              <!-- The height of the thumbnail --> 
                  +              <!-- The height of the thumbnail -->
                                 <!-- Data type: Integer -->
                                 <!-- Min value: 0 (inclusive) -->
                                 <!-- Max value: 255 (inclusive) -->
                   
                           <!ELEMENT "app2ICC" EMPTY>
                  -          <!-- An ICC profile APP2 marker segment --> 
                  +          <!-- An ICC profile APP2 marker segment -->
                             <!-- Optional User object: java.awt.color.ICC_Profile -->
                   
                  -    <!ELEMENT "markerSequence" (dqt | dht | dri | com | unknown | 
                  +    <!ELEMENT "markerSequence" (dqt | dht | dri | com | unknown |
                         app14Adobe | sof | sos)*>
                  -      <!-- A node grouping all non-jfif marker segments --> 
                  +      <!-- A node grouping all non-jfif marker segments -->
                   
                         <!ELEMENT "dqt" (dqtable)*>
                  -        <!-- A Define Quantization Table(s) marker segment --> 
                  +        <!-- A Define Quantization Table(s) marker segment -->
                           <!-- Min children: 1 -->
                           <!-- Max children: 4 -->
                   
                           <!ELEMENT "dqtable" EMPTY>
                  -          <!-- A single quantization table --> 
                  +          <!-- A single quantization table -->
                             <!-- User object: javax.imageio.plugins.jpeg.JPEGQTable -->
                             <!ATTLIST "dqtable" "elementPrecision" #CDATA "0">
                  -            <!-- The number of bits in each table element (0 = 8, 1 = 16) 
                  -                 --> 
                  +            <!-- The number of bits in each table element (0 = 8, 1 = 16)
                  +                 -->
                               <!-- Data type: Integer -->
                             <!ATTLIST "dqtable" "qtableId" ("0" | "1" | "2" | "3") #REQUIRED>
                   
                         <!ELEMENT "dht" (dhtable)*>
                  -        <!-- A Define Huffman Table(s) marker segment --> 
                  +        <!-- A Define Huffman Table(s) marker segment -->
                           <!-- Min children: 1 -->
                           <!-- Max children: 4 -->
                   
                           <!ELEMENT "dhtable" EMPTY>
                  -          <!-- A single Huffman table --> 
                  +          <!-- A single Huffman table -->
                             <!-- User object: javax.imageio.plugins.jpeg.JPEGHuffmanTable -->
                             <!ATTLIST "dhtable" "class" ("0" | "1") #REQUIRED>
                  -            <!-- Indicates whether this is a DC (0) or an AC (1) table --> 
                  +            <!-- Indicates whether this is a DC (0) or an AC (1) table -->
                             <!ATTLIST "dhtable" "htableId" ("0" | "1" | "2" | "3") #REQUIRED>
                  -            <!-- The table id --> 
                  +            <!-- The table id -->
                   
                         <!ELEMENT "dri" EMPTY>
                  -        <!-- A Define Restart Interval marker segment --> 
                  +        <!-- A Define Restart Interval marker segment -->
                           <!ATTLIST "dri" "interval" #CDATA #REQUIRED>
                  -          <!-- The restart interval in MCUs --> 
                  +          <!-- The restart interval in MCUs -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 0 (inclusive) -->
                             <!-- Max value: 65535 (inclusive) -->
                   
                         <!ELEMENT "com" EMPTY>
                  -        <!-- A Comment marker segment. The user object contains the actual 
                  -             bytes. --> 
                  +        <!-- A Comment marker segment. The user object contains the actual
                  +             bytes. -->
                           <!-- User object: array of [B -->
                           <!-- Min length: 1 -->
                           <!-- Max length: 65533 -->
                           <!ATTLIST "com" "comment" #CDATA #IMPLIED>
                  -          <!-- The comment as a string (used only if user object is null) 
                  -               --> 
                  +          <!-- The comment as a string (used only if user object is null)
                  +               -->
                             <!-- Data type: String -->
                   
                         <!ELEMENT "unknown" EMPTY>
                  -        <!-- An unrecognized marker segment. The user object contains the 
                  -             data not including length. --> 
                  +        <!-- An unrecognized marker segment. The user object contains the
                  +             data not including length. -->
                           <!-- User object: array of [B -->
                           <!-- Min length: 1 -->
                           <!-- Max length: 65533 -->
                           <!ATTLIST "unknown" "MarkerTag" #CDATA #REQUIRED>
                  -          <!-- The tag identifying this marker segment --> 
                  +          <!-- The tag identifying this marker segment -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 0 (inclusive) -->
                             <!-- Max value: 255 (inclusive) -->
                   
                         <!ELEMENT "app14Adobe" EMPTY>
                  -        <!-- An Adobe APP14 marker segment --> 
                  +        <!-- An Adobe APP14 marker segment -->
                           <!ATTLIST "app14Adobe" "version" #CDATA "100">
                  -          <!-- The version of Adobe APP14 marker segment --> 
                  +          <!-- The version of Adobe APP14 marker segment -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 100 (inclusive) -->
                             <!-- Max value: 255 (inclusive) -->
                           <!ATTLIST "app14Adobe" "flags0" #CDATA "0">
                  -          <!-- The flags0 variable of an APP14 marker segment --> 
                  +          <!-- The flags0 variable of an APP14 marker segment -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 0 (inclusive) -->
                             <!-- Max value: 65535 (inclusive) -->
                           <!ATTLIST "app14Adobe" "flags1" #CDATA "0">
                  -          <!-- The flags1 variable of an APP14 marker segment --> 
                  +          <!-- The flags1 variable of an APP14 marker segment -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 0 (inclusive) -->
                             <!-- Max value: 65535 (inclusive) -->
                           <!ATTLIST "app14Adobe" "transform" ("0" | "1" | "2") #REQUIRED>
                  -          <!-- The color transform applied to the image (0 = Unknown, 1 = 
                  -               YCbCr, 2 = YCCK) --> 
                  +          <!-- The color transform applied to the image (0 = Unknown, 1 =
                  +               YCbCr, 2 = YCCK) -->
                   
                         <!ELEMENT "sof" (componentSpec)*>
                  -        <!-- A Start Of Frame marker segment --> 
                  +        <!-- A Start Of Frame marker segment -->
                           <!-- Min children: 1 -->
                           <!-- Max children: 4 -->
                           <!ATTLIST "sof" "process" ("0" | "1" | "2") #IMPLIED>
                  -          <!-- The JPEG process (0 = Baseline sequential, 1 = Extended 
                  -               sequential, 2 = Progressive) --> 
                  +          <!-- The JPEG process (0 = Baseline sequential, 1 = Extended
                  +               sequential, 2 = Progressive) -->
                           <!ATTLIST "sof" "samplePrecision" #CDATA "8">
                  -          <!-- The number of bits per sample --> 
                  +          <!-- The number of bits per sample -->
                             <!-- Data type: Integer -->
                           <!ATTLIST "sof" "numLines" #CDATA #IMPLIED>
                  -          <!-- The number of lines in the image --> 
                  +          <!-- The number of lines in the image -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 0 (inclusive) -->
                             <!-- Max value: 65535 (inclusive) -->
                           <!ATTLIST "sof" "samplesPerLine" #CDATA #IMPLIED>
                  -          <!-- The number of samples per line --> 
                  +          <!-- The number of samples per line -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 0 (inclusive) -->
                             <!-- Max value: 65535 (inclusive) -->
                           <!ATTLIST "sof" "numFrameComponents" ("1" | "2" | "3" | "4")
                              #IMPLIED>
                  -          <!-- The number of components in the image --> 
                  +          <!-- The number of components in the image -->
                   
                           <!ELEMENT "componentSpec" EMPTY>
                  -          <!-- A component specification for a frame --> 
                  +          <!-- A component specification for a frame -->
                             <!ATTLIST "componentSpec" "componentId" #CDATA #REQUIRED>
                  -            <!-- The id for this component --> 
                  +            <!-- The id for this component -->
                               <!-- Data type: Integer -->
                               <!-- Min value: 0 (inclusive) -->
                               <!-- Max value: 255 (inclusive) -->
                             <!ATTLIST "componentSpec" "HsamplingFactor" #CDATA #REQUIRED>
                  -            <!-- The horizontal sampling factor for this component --> 
                  +            <!-- The horizontal sampling factor for this component -->
                               <!-- Data type: Integer -->
                               <!-- Min value: 1 (inclusive) -->
                               <!-- Max value: 255 (inclusive) -->
                             <!ATTLIST "componentSpec" "VsamplingFactor" #CDATA #REQUIRED>
                  -            <!-- The vertical sampling factor for this component --> 
                  +            <!-- The vertical sampling factor for this component -->
                               <!-- Data type: Integer -->
                               <!-- Min value: 1 (inclusive) -->
                               <!-- Max value: 255 (inclusive) -->
                  -          <!ATTLIST "componentSpec" "QtableSelector" ("0" | "1" | "2" | 
                  +          <!ATTLIST "componentSpec" "QtableSelector" ("0" | "1" | "2" |
                               "3") #REQUIRED>
                  -            <!-- The quantization table to use for this component --> 
                  +            <!-- The quantization table to use for this component -->
                   
                         <!ELEMENT "sos" (scanComponentSpec)*>
                  -        <!-- A Start Of Scan marker segment --> 
                  +        <!-- A Start Of Scan marker segment -->
                           <!-- Min children: 1 -->
                           <!-- Max children: 4 -->
                           <!ATTLIST "sos" "numScanComponents" ("1" | "2" | "3" | "4")
                              #REQUIRED>
                  -          <!-- The number of components in the scan --> 
                  +          <!-- The number of components in the scan -->
                           <!ATTLIST "sos" "startSpectralSelection" #CDATA "0">
                  -          <!-- The first spectral band included in this scan --> 
                  +          <!-- The first spectral band included in this scan -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 0 (inclusive) -->
                             <!-- Max value: 63 (inclusive) -->
                           <!ATTLIST "sos" "endSpectralSelection" #CDATA "63">
                  -          <!-- The last spectral band included in this scan --> 
                  +          <!-- The last spectral band included in this scan -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 0 (inclusive) -->
                             <!-- Max value: 63 (inclusive) -->
                           <!ATTLIST "sos" "approxHigh" #CDATA "0">
                  -          <!-- The highest bit position included in this scan --> 
                  +          <!-- The highest bit position included in this scan -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 0 (inclusive) -->
                             <!-- Max value: 15 (inclusive) -->
                           <!ATTLIST "sos" "approxLow" #CDATA "0">
                  -          <!-- The lowest bit position included in this scan --> 
                  +          <!-- The lowest bit position included in this scan -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 0 (inclusive) -->
                             <!-- Max value: 15 (inclusive) -->
                   
                           <!ELEMENT "scanComponentSpec" EMPTY>
                  -          <!-- A component specification for a scan --> 
                  +          <!-- A component specification for a scan -->
                             <!ATTLIST "scanComponentSpec" "componentSelector" #CDATA
                                #REQUIRED>
                  -            <!-- The id of this component --> 
                  +            <!-- The id of this component -->
                               <!-- Data type: Integer -->
                               <!-- Min value: 0 (inclusive) -->
                               <!-- Max value: 255 (inclusive) -->
                  -          <!ATTLIST "scanComponentSpec" "dcHuffTable" ("0" | "1" | "2" | 
                  +          <!ATTLIST "scanComponentSpec" "dcHuffTable" ("0" | "1" | "2" |
                               "3") #REQUIRED>
                  -            <!-- The huffman table to use for encoding DC coefficients --> 
                  -          <!ATTLIST "scanComponentSpec" "acHuffTable" ("0" | "1" | "2" | 
                  +            <!-- The huffman table to use for encoding DC coefficients -->
                  +          <!ATTLIST "scanComponentSpec" "acHuffTable" ("0" | "1" | "2" |
                               "3") #REQUIRED>
                  -            <!-- The huffman table to use for encoding AC coefficients --> 
                  +            <!-- The huffman table to use for encoding AC coefficients -->
                   ]>
                   

                  -Stream Metadata DTD +Stream Metadata DTD

                   <!DOCTYPE "javax_imageio_jpeg_stream_1.0" [
                     <!ELEMENT "javax_imageio_jpeg_stream_1.0" (dqt |
                  -                      dht | 
                  -                      dri | 
                  -                      com | 
                  +                      dht |
                  +                      dri |
                  +                      com |
                                         unknown)*>
                  -   
                  +
                     <!-- All elements are as defined above for image metadata -->
                   ]>
                   
                  diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/javax/imageio/metadata/doc-files/png_metadata.html --- a/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/png_metadata.html Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/png_metadata.html Thu Dec 14 12:28:32 2017 +0000 @@ -1,8 +1,11 @@ - - + + + + PNG Metadata Format Specification + -PNG Metadata Format Specification - + - - -

                  -PNG Metadata Format Specification -

                  +

                  PNG Metadata Format Specification

                  @@ -59,7 +57,7 @@ type set in the metadata is "Palette", palette color will be used.

                  - + If no metadata is supplied when encoding an image, the header is initialized from the image being encoded, and no optional chunks are included. @@ -85,7 +83,7 @@ The child nodes of the bKGD, sBIT, and tRNS chunks must match the image's color type. -

                  +

                  Certain chunks may meaningfully appear multiple times in a PNG file, in particular the text-related chunks. In order to simplify the @@ -104,8 +102,8 @@

                   <!DOCTYPE "javax_imageio_png_1.0" [
                   
                  -  <!ELEMENT "javax_imageio_png_1.0" (IHDR?, PLTE?, bKGD?, cHRM?, 
                  -    gAMA?, hIST?, iCCP?, iTXt?, pHYS?, sBIT?, sPLT?, sRGB?, tEXt?, 
                  +  <!ELEMENT "javax_imageio_png_1.0" (IHDR?, PLTE?, bKGD?, cHRM?,
                  +    gAMA?, hIST?, iCCP?, iTXt?, pHYS?, sBIT?, sPLT?, sRGB?, tEXt?,
                       tIME?, tRNS?, zTXt?, UnknownChunks?)>
                   
                       <!ELEMENT "IHDR" EMPTY>
                  @@ -123,7 +121,7 @@
                         <!ATTLIST "IHDR" "bitDepth" ("1" | "2" | "4" | "8" | "16")
                            #REQUIRED>
                           <!-- The bit depth of the image samples -->
                  -      <!ATTLIST "IHDR" "colorType" ("Grayscale" | "RGB" | "Palette" | 
                  +      <!ATTLIST "IHDR" "colorType" ("Grayscale" | "RGB" | "Palette" |
                           "GrayAlpha" | "RGBAlpha") #REQUIRED>
                           <!-- The color type of the image -->
                         <!ATTLIST "IHDR" "compressionMethod" ("deflate") #REQUIRED>
                  @@ -318,7 +316,7 @@
                         <!ATTLIST "pHYS" "unitSpecifier" ("unknown" | "meter") #REQUIRED>
                           <!-- The unit specifier for this chunk (i.e., meters) -->
                   
                  -    <!ELEMENT "sBIT" (sBIT_Grayscale | sBIT_GrayAlpha | sBIT_RGB | 
                  +    <!ELEMENT "sBIT" (sBIT_Grayscale | sBIT_GrayAlpha | sBIT_RGB |
                         sBIT_RGBAlpha | sBIT_Palette)>
                         <!-- The sBIT chunk, containing significant bit information -->
                   
                  @@ -437,8 +435,8 @@
                   
                       <!ELEMENT "sRGB" EMPTY>
                         <!-- The sRGB chunk, containing rendering intent information -->
                  -      <!ATTLIST "sRGB" "renderingIntent" ("Perceptual" | 
                  -        "Relative colorimetric" | "Saturation" | 
                  +      <!ATTLIST "sRGB" "renderingIntent" ("Perceptual" |
                  +        "Relative colorimetric" | "Saturation" |
                           "Absolute colorimetric") #REQUIRED>
                           <!-- The rendering intent -->
                   
                  diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/javax/imageio/metadata/doc-files/standard_metadata.html
                  --- a/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/standard_metadata.html	Mon Dec 11 16:43:11 2017 +0000
                  +++ b/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/standard_metadata.html	Thu Dec 14 12:28:32 2017 +0000
                  @@ -1,8 +1,11 @@
                  -
                  -
                  +
                  +
                   
                  +  
                  +  Standard Metadata Format Specification
                  +
                   
                   
                  -Standard Metadata Format Specification
                  -
                  +
                   
                  -
                  -
                  -

                  -Standard (Plug-in Neutral) Metadata Format Specification -

                  +

                  Standard (Plug-in Neutral) Metadata Format Specification

                  The plug-in neutral "javax_imageio_1.0" format consists of a root node named "javax_imageio_1.0" which has child @@ -44,355 +42,355 @@

                   <!DOCTYPE "javax_imageio_1.0" [
                   
                  -  <!ELEMENT "javax_imageio_1.0" (Chroma?, Compression?, Data?, Dimension?, 
                  +  <!ELEMENT "javax_imageio_1.0" (Chroma?, Compression?, Data?, Dimension?,
                       Document?, Text?, Transparency?)>
                   
                  -    <!ELEMENT "Chroma" (ColorSpaceType?, NumChannels?, Gamma?, 
                  +    <!ELEMENT "Chroma" (ColorSpaceType?, NumChannels?, Gamma?,
                         BlackIsZero?, Palette?, BackgroundIndex?, BackgroundColor?)>
                  -      <!-- Chroma (color) information --> 
                  +      <!-- Chroma (color) information -->
                   
                         <!ELEMENT "ColorSpaceType" EMPTY>
                  -        <!-- The raw color space of the image --> 
                  -        <!ATTLIST "ColorSpaceType" "name" ("XYZ" | "Lab" | "Luv" | 
                  -          "YCbCr" | "Yxy" | "YCCK" | "PhotoYCC" | "RGB" | "GRAY" | "HSV" | 
                  -          "HLS" | "CMYK" | "CMY" | "2CLR" | "3CLR" | "4CLR" | "5CLR" | 
                  -          "6CLR" | "7CLR" | "8CLR" | "9CLR" | "ACLR" | "BCLR" | "CCLR" | 
                  +        <!-- The raw color space of the image -->
                  +        <!ATTLIST "ColorSpaceType" "name" ("XYZ" | "Lab" | "Luv" |
                  +          "YCbCr" | "Yxy" | "YCCK" | "PhotoYCC" | "RGB" | "GRAY" | "HSV" |
                  +          "HLS" | "CMYK" | "CMY" | "2CLR" | "3CLR" | "4CLR" | "5CLR" |
                  +          "6CLR" | "7CLR" | "8CLR" | "9CLR" | "ACLR" | "BCLR" | "CCLR" |
                             "DCLR" | "ECLR" | "FCLR") #REQUIRED>
                   
                         <!ELEMENT "NumChannels" EMPTY>
                  -        <!-- The number of channels in the raw image, including alpha --> 
                  +        <!-- The number of channels in the raw image, including alpha -->
                           <!ATTLIST "NumChannels" "value" #CDATA #REQUIRED>
                             <!-- Data type: List of Integer -->
                   
                         <!ELEMENT "Gamma" EMPTY>
                  -        <!-- The image gamma --> 
                  +        <!-- The image gamma -->
                           <!ATTLIST "Gamma" "value" #CDATA #REQUIRED>
                             <!-- Data type: Float -->
                   
                         <!ELEMENT "BlackIsZero" EMPTY>
                  -        <!-- True if smaller values represent darker shades --> 
                  +        <!-- True if smaller values represent darker shades -->
                           <!ATTLIST "BlackIsZero" "value" ("TRUE" | "FALSE") "TRUE">
                   
                         <!ELEMENT "Palette" (PaletteEntry)*>
                  -        <!-- Palette-color information --> 
                  +        <!-- Palette-color information -->
                   
                           <!ELEMENT "PaletteEntry" EMPTY>
                  -          <!-- A palette entry --> 
                  +          <!-- A palette entry -->
                             <!ATTLIST "PaletteEntry" "index" #CDATA #REQUIRED>
                  -            <!-- The index of the palette entry --> 
                  +            <!-- The index of the palette entry -->
                               <!-- Data type: Integer -->
                             <!ATTLIST "PaletteEntry" "red" #CDATA #REQUIRED>
                  -            <!-- The red value for the palette entry --> 
                  +            <!-- The red value for the palette entry -->
                               <!-- Data type: Integer -->
                             <!ATTLIST "PaletteEntry" "green" #CDATA #REQUIRED>
                  -            <!-- The green value for the palette entry --> 
                  +            <!-- The green value for the palette entry -->
                               <!-- Data type: Integer -->
                             <!ATTLIST "PaletteEntry" "blue" #CDATA #REQUIRED>
                  -            <!-- The blue value for the palette entry --> 
                  +            <!-- The blue value for the palette entry -->
                               <!-- Data type: Integer -->
                             <!ATTLIST "PaletteEntry" "alpha" #CDATA "255">
                  -            <!-- The alpha value for the palette entry --> 
                  +            <!-- The alpha value for the palette entry -->
                               <!-- Data type: Integer -->
                   
                         <!ELEMENT "BackgroundIndex" EMPTY>
                  -        <!-- A palette index to be used as a background --> 
                  +        <!-- A palette index to be used as a background -->
                           <!ATTLIST "BackgroundIndex" "value" #CDATA #REQUIRED>
                             <!-- Data type: Integer -->
                   
                         <!ELEMENT "BackgroundColor" EMPTY>
                  -        <!-- An RGB triple to be used as a background --> 
                  +        <!-- An RGB triple to be used as a background -->
                           <!ATTLIST "BackgroundColor" "red" #CDATA #REQUIRED>
                  -          <!-- The red background value --> 
                  +          <!-- The red background value -->
                             <!-- Data type: Integer -->
                           <!ATTLIST "BackgroundColor" "green" #CDATA #REQUIRED>
                  -          <!-- The green background value --> 
                  +          <!-- The green background value -->
                             <!-- Data type: Integer -->
                           <!ATTLIST "BackgroundColor" "blue" #CDATA #REQUIRED>
                  -          <!-- The blue background value --> 
                  +          <!-- The blue background value -->
                             <!-- Data type: Integer -->
                   
                  -    <!ELEMENT "Compression" (CompressionTypeName?, Lossless?, 
                  +    <!ELEMENT "Compression" (CompressionTypeName?, Lossless?,
                         NumProgressiveScans?, BitRate?)>
                  -      <!-- Compression information --> 
                  +      <!-- Compression information -->
                   
                         <!ELEMENT "CompressionTypeName" EMPTY>
                  -        <!-- The name of the compression scheme in use --> 
                  +        <!-- The name of the compression scheme in use -->
                           <!ATTLIST "CompressionTypeName" "value" #CDATA #REQUIRED>
                             <!-- Data type: String -->
                   
                         <!ELEMENT "Lossless" EMPTY>
                  -        <!-- True if the compression scheme is lossless --> 
                  +        <!-- True if the compression scheme is lossless -->
                           <!ATTLIST "Lossless" "value" ("TRUE" | "FALSE") "TRUE">
                   
                         <!ELEMENT "NumProgressiveScans" EMPTY>
                  -        <!-- The number of progressive scans used in the image encoding --> 
                  +        <!-- The number of progressive scans used in the image encoding -->
                           <!ATTLIST "NumProgressiveScans" "value" #CDATA #REQUIRED>
                             <!-- Data type: Integer -->
                   
                         <!ELEMENT "BitRate" EMPTY>
                  -        <!-- The estimated bit rate of the compression scheme --> 
                  +        <!-- The estimated bit rate of the compression scheme -->
                           <!ATTLIST "BitRate" "value" #CDATA #REQUIRED>
                             <!-- Data type: Float -->
                   
                  -    <!ELEMENT "Data" (PlanarConfiguration?, SampleFormat?, BitsPerSample?, 
                  +    <!ELEMENT "Data" (PlanarConfiguration?, SampleFormat?, BitsPerSample?,
                         SignificantBitsPerSample?, SampleMSB?)>
                  -      <!-- Information on the image layout --> 
                  +      <!-- Information on the image layout -->
                   
                         <!ELEMENT "PlanarConfiguration" EMPTY>
                  -        <!-- The organization of image samples in the stream --> 
                  -        <!ATTLIST "PlanarConfiguration" "value" ("PixelInterleaved" | 
                  +        <!-- The organization of image samples in the stream -->
                  +        <!ATTLIST "PlanarConfiguration" "value" ("PixelInterleaved" |
                             "PlaneInterleaved" | "LineInterleaved" | "TileInterleaved")
                              #REQUIRED>
                   
                         <!ELEMENT "SampleFormat" EMPTY>
                  -        <!-- The numeric format of image samples --> 
                  -        <!ATTLIST "SampleFormat" "value" ("SignedIntegral" | 
                  +        <!-- The numeric format of image samples -->
                  +        <!ATTLIST "SampleFormat" "value" ("SignedIntegral" |
                             "UnsignedIntegral" | "Real" | "Index") #REQUIRED>
                   
                         <!ELEMENT "BitsPerSample" EMPTY>
                  -        <!-- The number of bits per sample --> 
                  +        <!-- The number of bits per sample -->
                           <!ATTLIST "BitsPerSample" "value" #CDATA #REQUIRED>
                  -          <!-- A list of integers, one per channel --> 
                  +          <!-- A list of integers, one per channel -->
                             <!-- Data type: List of Integer -->
                             <!-- Min length: 1 -->
                   
                         <!ELEMENT "SignificantBitsPerSample" EMPTY>
                  -        <!-- The number of significant bits per sample --> 
                  +        <!-- The number of significant bits per sample -->
                           <!ATTLIST "SignificantBitsPerSample" "value" #CDATA #REQUIRED>
                  -          <!-- A list of integers, one per channel --> 
                  +          <!-- A list of integers, one per channel -->
                             <!-- Data type: List of Integer -->
                             <!-- Min length: 1 -->
                   
                         <!ELEMENT "SampleMSB" EMPTY>
                  -        <!-- The position of the most significant bit of each sample --> 
                  +        <!-- The position of the most significant bit of each sample -->
                           <!ATTLIST "SampleMSB" "value" #CDATA #REQUIRED>
                  -          <!-- A list of integers, one per channel --> 
                  +          <!-- A list of integers, one per channel -->
                             <!-- Data type: List of Integer -->
                             <!-- Min length: 1 -->
                   
                  -    <!ELEMENT "Dimension" (PixelAspectRatio?, ImageOrientation?, 
                  -      HorizontalPixelSize?, VerticalPixelSize?, 
                  -      HorizontalPhysicalPixelSpacing?, VerticalPhysicalPixelSpacing?, 
                  -      HorizontalPosition?, VerticalPosition?, HorizontalPixelOffset?, 
                  +    <!ELEMENT "Dimension" (PixelAspectRatio?, ImageOrientation?,
                  +      HorizontalPixelSize?, VerticalPixelSize?,
                  +      HorizontalPhysicalPixelSpacing?, VerticalPhysicalPixelSpacing?,
                  +      HorizontalPosition?, VerticalPosition?, HorizontalPixelOffset?,
                         VerticalPixelOffset?, HorizontalScreenSize?, VerticalScreenSize?)>
                  -      <!-- Dimension information --> 
                  +      <!-- Dimension information -->
                   
                         <!ELEMENT "PixelAspectRatio" EMPTY>
                  -        <!-- The width of a pixel divided by its height --> 
                  +        <!-- The width of a pixel divided by its height -->
                           <!ATTLIST "PixelAspectRatio" "value" #CDATA #REQUIRED>
                             <!-- Data type: Float -->
                   
                         <!ELEMENT "ImageOrientation" EMPTY>
                  -        <!-- The desired orientation of the image in terms of flips and 
                  -             counter-clockwise rotations --> 
                  -        <!ATTLIST "ImageOrientation" "value" ("Normal" | "Rotate90" | 
                  -          "Rotate180" | "Rotate270" | "FlipH" | "FlipV" | 
                  +        <!-- The desired orientation of the image in terms of flips and
                  +             counter-clockwise rotations -->
                  +        <!ATTLIST "ImageOrientation" "value" ("Normal" | "Rotate90" |
                  +          "Rotate180" | "Rotate270" | "FlipH" | "FlipV" |
                             "FlipHRotate90" | "FlipVRotate90") #REQUIRED>
                   
                         <!ELEMENT "HorizontalPixelSize" EMPTY>
                  -        <!-- The width of a pixel, in millimeters, as it should be rendered 
                  -             on media --> 
                  +        <!-- The width of a pixel, in millimeters, as it should be rendered
                  +             on media -->
                           <!ATTLIST "HorizontalPixelSize" "value" #CDATA #REQUIRED>
                             <!-- Data type: Float -->
                   
                         <!ELEMENT "VerticalPixelSize" EMPTY>
                  -        <!-- The height of a pixel, in millimeters, as it should be 
                  -             rendered on media --> 
                  +        <!-- The height of a pixel, in millimeters, as it should be
                  +             rendered on media -->
                           <!ATTLIST "VerticalPixelSize" "value" #CDATA #REQUIRED>
                             <!-- Data type: Float -->
                   
                         <!ELEMENT "HorizontalPhysicalPixelSpacing" EMPTY>
                  -        <!-- The horizontal distance in the subject of the image, in 
                  -             millimeters, represented by one pixel at the center of the 
                  -             image --> 
                  +        <!-- The horizontal distance in the subject of the image, in
                  +             millimeters, represented by one pixel at the center of the
                  +             image -->
                           <!ATTLIST "HorizontalPhysicalPixelSpacing" "value" #CDATA #REQUIRED>
                             <!-- Data type: Float -->
                   
                         <!ELEMENT "VerticalPhysicalPixelSpacing" EMPTY>
                  -        <!-- The vertical distance in the subject of the image, in 
                  -             millimeters, represented by one pixel at the center of the 
                  -             image --> 
                  +        <!-- The vertical distance in the subject of the image, in
                  +             millimeters, represented by one pixel at the center of the
                  +             image -->
                           <!ATTLIST "VerticalPhysicalPixelSpacing" "value" #CDATA #REQUIRED>
                             <!-- Data type: Float -->
                   
                         <!ELEMENT "HorizontalPosition" EMPTY>
                  -        <!-- The horizontal position, in millimeters, where the image 
                  -             should be rendered on media --> 
                  +        <!-- The horizontal position, in millimeters, where the image
                  +             should be rendered on media -->
                           <!ATTLIST "HorizontalPosition" "value" #CDATA #REQUIRED>
                             <!-- Data type: Float -->
                   
                         <!ELEMENT "VerticalPosition" EMPTY>
                  -        <!-- The vertical position, in millimeters, where the image should 
                  -             be rendered on media --> 
                  +        <!-- The vertical position, in millimeters, where the image should
                  +             be rendered on media -->
                           <!ATTLIST "VerticalPosition" "value" #CDATA #REQUIRED>
                             <!-- Data type: Float -->
                   
                         <!ELEMENT "HorizontalPixelOffset" EMPTY>
                  -        <!-- The horizontal position, in pixels, where the image should be 
                  -             rendered onto a raster display --> 
                  +        <!-- The horizontal position, in pixels, where the image should be
                  +             rendered onto a raster display -->
                           <!ATTLIST "HorizontalPixelOffset" "value" #CDATA #REQUIRED>
                             <!-- Data type: Integer -->
                   
                         <!ELEMENT "VerticalPixelOffset" EMPTY>
                  -        <!-- The vertical position, in pixels, where the image should be 
                  -             rendered onto a raster display --> 
                  +        <!-- The vertical position, in pixels, where the image should be
                  +             rendered onto a raster display -->
                           <!ATTLIST "VerticalPixelOffset" "value" #CDATA #REQUIRED>
                             <!-- Data type: Integer -->
                   
                         <!ELEMENT "HorizontalScreenSize" EMPTY>
                  -        <!-- The width, in pixels, of the raster display into which the 
                  -             image should be rendered --> 
                  +        <!-- The width, in pixels, of the raster display into which the
                  +             image should be rendered -->
                           <!ATTLIST "HorizontalScreenSize" "value" #CDATA #REQUIRED>
                             <!-- Data type: Integer -->
                   
                         <!ELEMENT "VerticalScreenSize" EMPTY>
                  -        <!-- The height, in pixels, of the raster display into which the 
                  -             image should be rendered --> 
                  +        <!-- The height, in pixels, of the raster display into which the
                  +             image should be rendered -->
                           <!ATTLIST "VerticalScreenSize" "value" #CDATA #REQUIRED>
                             <!-- Data type: Integer -->
                   
                  -    <!ELEMENT "Document" (FormatVersion?, SubimageInterpretation?, 
                  +    <!ELEMENT "Document" (FormatVersion?, SubimageInterpretation?,
                         ImageCreationTime?, ImageModificationTime?)>
                  -      <!-- Document information --> 
                  +      <!-- Document information -->
                   
                         <!ELEMENT "FormatVersion" EMPTY>
                  -        <!-- The version of the format used by the stream --> 
                  +        <!-- The version of the format used by the stream -->
                           <!ATTLIST "FormatVersion" "value" #CDATA #REQUIRED>
                             <!-- Data type: String -->
                   
                         <!ELEMENT "SubimageInterpretation" EMPTY>
                  -        <!-- The interpretation of this image in relation to the other 
                  -             images stored in the same stream --> 
                  -        <!ATTLIST "SubimageInterpretation" "value" ("Standalone" | 
                  -          "SinglePage" | "FullResolution" | "ReducedResolution" | 
                  -          "PyramidLayer" | "Preview" | "VolumeSlice" | "ObjectView" | 
                  -          "Panorama" | "AnimationFrame" | "TransparencyMask" | 
                  +        <!-- The interpretation of this image in relation to the other
                  +             images stored in the same stream -->
                  +        <!ATTLIST "SubimageInterpretation" "value" ("Standalone" |
                  +          "SinglePage" | "FullResolution" | "ReducedResolution" |
                  +          "PyramidLayer" | "Preview" | "VolumeSlice" | "ObjectView" |
                  +          "Panorama" | "AnimationFrame" | "TransparencyMask" |
                             "CompositingLayer" | "SpectralSlice" | "Unknown") #REQUIRED>
                   
                         <!ELEMENT "ImageCreationTime" EMPTY>
                  -        <!-- The time of image creation --> 
                  +        <!-- The time of image creation -->
                           <!ATTLIST "ImageCreationTime" "year" #CDATA #REQUIRED>
                  -          <!-- The full year (e.g., 1967, not 67) --> 
                  +          <!-- The full year (e.g., 1967, not 67) -->
                             <!-- Data type: Integer -->
                           <!ATTLIST "ImageCreationTime" "month" #CDATA #REQUIRED>
                  -          <!-- The month, with January = 1 --> 
                  +          <!-- The month, with January = 1 -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 1 (inclusive) -->
                             <!-- Max value: 12 (inclusive) -->
                           <!ATTLIST "ImageCreationTime" "day" #CDATA #REQUIRED>
                  -          <!-- The day of the month --> 
                  +          <!-- The day of the month -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 1 (inclusive) -->
                             <!-- Max value: 31 (inclusive) -->
                           <!ATTLIST "ImageCreationTime" "hour" #CDATA "0">
                  -          <!-- The hour from 0 to 23 --> 
                  +          <!-- The hour from 0 to 23 -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 0 (inclusive) -->
                             <!-- Max value: 23 (inclusive) -->
                           <!ATTLIST "ImageCreationTime" "minute" #CDATA "0">
                  -          <!-- The minute from 0 to 59 --> 
                  +          <!-- The minute from 0 to 59 -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 0 (inclusive) -->
                             <!-- Max value: 59 (inclusive) -->
                           <!ATTLIST "ImageCreationTime" "second" #CDATA "0">
                  -          <!-- The second from 0 to 60 (60 = leap second) --> 
                  +          <!-- The second from 0 to 60 (60 = leap second) -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 0 (inclusive) -->
                             <!-- Max value: 60 (inclusive) -->
                   
                         <!ELEMENT "ImageModificationTime" EMPTY>
                  -        <!-- The time of the last image modification --> 
                  +        <!-- The time of the last image modification -->
                           <!ATTLIST "ImageModificationTime" "year" #CDATA #REQUIRED>
                  -          <!-- The full year (e.g., 1967, not 67) --> 
                  +          <!-- The full year (e.g., 1967, not 67) -->
                             <!-- Data type: Integer -->
                           <!ATTLIST "ImageModificationTime" "month" #CDATA #REQUIRED>
                  -          <!-- The month, with January = 1 --> 
                  +          <!-- The month, with January = 1 -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 1 (inclusive) -->
                             <!-- Max value: 12 (inclusive) -->
                           <!ATTLIST "ImageModificationTime" "day" #CDATA #REQUIRED>
                  -          <!-- The day of the month --> 
                  +          <!-- The day of the month -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 1 (inclusive) -->
                             <!-- Max value: 31 (inclusive) -->
                           <!ATTLIST "ImageModificationTime" "hour" #CDATA "0">
                  -          <!-- The hour from 0 to 23 --> 
                  +          <!-- The hour from 0 to 23 -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 0 (inclusive) -->
                             <!-- Max value: 23 (inclusive) -->
                           <!ATTLIST "ImageModificationTime" "minute" #CDATA "0">
                  -          <!-- The minute from 0 to 59 --> 
                  +          <!-- The minute from 0 to 59 -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 0 (inclusive) -->
                             <!-- Max value: 59 (inclusive) -->
                           <!ATTLIST "ImageModificationTime" "second" #CDATA "0">
                  -          <!-- The second from 0 to 60 (60 = leap second) --> 
                  +          <!-- The second from 0 to 60 (60 = leap second) -->
                             <!-- Data type: Integer -->
                             <!-- Min value: 0 (inclusive) -->
                             <!-- Max value: 60 (inclusive) -->
                   
                       <!ELEMENT "Text" (TextEntry)*>
                  -      <!-- Text information --> 
                  +      <!-- Text information -->
                   
                         <!ELEMENT "TextEntry" EMPTY>
                  -        <!-- A text entry --> 
                  +        <!-- A text entry -->
                           <!ATTLIST "TextEntry" "keyword" #CDATA #IMPLIED>
                  -          <!-- A keyword associated with the text entry --> 
                  +          <!-- A keyword associated with the text entry -->
                             <!-- Data type: String -->
                           <!ATTLIST "TextEntry" "value" #CDATA #REQUIRED>
                  -          <!-- the text entry --> 
                  +          <!-- the text entry -->
                             <!-- Data type: String -->
                           <!ATTLIST "TextEntry" "language" #CDATA #IMPLIED>
                  -          <!-- The language of the text --> 
                  +          <!-- The language of the text -->
                             <!-- Data type: String -->
                           <!ATTLIST "TextEntry" "encoding" #CDATA #IMPLIED>
                  -          <!-- The encoding of the text --> 
                  +          <!-- The encoding of the text -->
                             <!-- Data type: String -->
                  -        <!ATTLIST "TextEntry" "compression" ("none" | "lzw" | "zip" | 
                  +        <!ATTLIST "TextEntry" "compression" ("none" | "lzw" | "zip" |
                             "bzip" | "other") "none">
                  -          <!-- The method used to compress the text --> 
                  +          <!-- The method used to compress the text -->
                   
                  -    <!ELEMENT "Transparency" (Alpha?, TransparentIndex?, 
                  +    <!ELEMENT "Transparency" (Alpha?, TransparentIndex?,
                         TransparentColor?, TileTransparencies?, TileOpacities?)>
                  -      <!-- Transparency information --> 
                  +      <!-- Transparency information -->
                   
                         <!ELEMENT "Alpha" EMPTY>
                  -        <!-- The type of alpha information contained in the image --> 
                  -        <!ATTLIST "Alpha" "value" ("none" | "premultiplied" | 
                  +        <!-- The type of alpha information contained in the image -->
                  +        <!ATTLIST "Alpha" "value" ("none" | "premultiplied" |
                             "nonpremultiplied") "none">
                   
                         <!ELEMENT "TransparentIndex" EMPTY>
                  -        <!-- A palette index to be treated as transparent --> 
                  +        <!-- A palette index to be treated as transparent -->
                           <!ATTLIST "TransparentIndex" "value" #CDATA #REQUIRED>
                             <!-- Data type: Integer -->
                   
                         <!ELEMENT "TransparentColor" EMPTY>
                  -        <!-- An RGB color to be treated as transparent --> 
                  +        <!-- An RGB color to be treated as transparent -->
                           <!ATTLIST "TransparentColor" "value" #CDATA #REQUIRED>
                             <!-- Data type: List of Integer -->
                   
                         <!ELEMENT "TileTransparencies" (TransparentTile)*>
                  -        <!-- A list of completely transparent tiles --> 
                  +        <!-- A list of completely transparent tiles -->
                   
                           <!ELEMENT "TransparentTile" EMPTY>
                  -          <!-- The index of a completely transparent tile --> 
                  +          <!-- The index of a completely transparent tile -->
                             <!ATTLIST "TransparentTile" "x" #CDATA #REQUIRED>
                  -            <!-- The tile's X index --> 
                  +            <!-- The tile's X index -->
                               <!-- Data type: Integer -->
                             <!ATTLIST "TransparentTile" "y" #CDATA #REQUIRED>
                  -            <!-- The tile's Y index --> 
                  +            <!-- The tile's Y index -->
                               <!-- Data type: Integer -->
                   
                         <!ELEMENT "TileOpacities" (OpaqueTile)*>
                  -        <!-- A list of completely opaque tiles --> 
                  +        <!-- A list of completely opaque tiles -->
                   
                           <!ELEMENT "OpaqueTile" EMPTY>
                  -          <!-- The index of a completely opaque tile --> 
                  +          <!-- The index of a completely opaque tile -->
                             <!ATTLIST "OpaqueTile" "x" #CDATA #REQUIRED>
                  -            <!-- The tile's X index --> 
                  +            <!-- The tile's X index -->
                               <!-- Data type: Integer -->
                             <!ATTLIST "OpaqueTile" "y" #CDATA #REQUIRED>
                  -            <!-- The tile's Y index --> 
                  +            <!-- The tile's Y index -->
                               <!-- Data type: Integer -->
                   ]>
                   
                  diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/javax/imageio/metadata/doc-files/tiff_metadata.html --- a/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/tiff_metadata.html Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/tiff_metadata.html Thu Dec 14 12:28:32 2017 +0000 @@ -1,8 +1,11 @@ - - + + + + TIFF Metadata Format Specification and Usage Notes + -TIFF Metadata Format Specification and Usage Notes - - - + -

                  -TIFF Metadata Format Specification and Usage Notes -

                  +

                  TIFF Metadata Format Specification and Usage Notes

                  -

                  -Reading Images
                  - +Reading Images

                  - Writing Images
                  - - Native Stream Metadata Format
                  Native Image Metadata Format -

                  -

                  Reading Images

                  +

                  Reading Images

                  TIFF images are read by an ImageReader which may be controlled by its public interface as well as via a supplied @@ -95,14 +79,14 @@ -

                  Color Conversion

                  +

                  Color Conversion

                  If the source image data have photometric type CIE L*a*b* or YCbCr, and the destination color space type is RGB, then the source image data will be automatically converted to RGB using an internal color converter.

                  -

                  Color Spaces

                  +

                  Color Spaces

                  The raw color space assigned by default, i.e., in the absence of a user-supplied ImageTypeSpecifier, @@ -112,7 +96,7 @@
                • A color space created from the ICC Profile metadata field if it is present and compatible with the image data layout.
                • -
                • sRGB if the image is monochrome/bilevel +
                • sRGB if the image is monochrome/bilevel (a two-level color map is created internally).
                • sRGB if the image is palette-color.
                • Linear RGB if the image has three samples per pixel, has photometric type @@ -136,7 +120,7 @@ sample.
                -

                The normalized color coordinate transformations +

                The normalized color coordinate transformations used for the default CMYK color space are defined as follows:

                  @@ -160,9 +144,8 @@
                -

                -

                The generic color space used when no other color space +

                The generic color space used when no other color space can be inferred is provided merely to enable the data to be loaded. It is not intended to provide accurate conversions of any kind.

                @@ -171,7 +154,7 @@ supplied to the reader and should be derived from a color space which is correct for the data in question.

                -

                ICC Profiles

                +

                ICC Profiles

                If an ICC profile is contained in the image metadata ( @@ -203,7 +186,6 @@ ImageReadParam.setDestinationType.
              • Pass the parameter object to the appropriate read method.
              • -

                If the inferred color space not based on the ICC Profile field is compatible with the ICC profile-based color space, then a second @@ -214,7 +196,7 @@ more than one type, the first one will be based on the ICC profile and the second on the inferred color space.

                -

                Metadata Issues

                +

                Metadata Issues

                By default all recognized fields in the TIFF image file directory (IFD) are loaded into the native image metadata object. Which fields are loaded may be @@ -244,7 +226,7 @@ object returned by the TIFF reader using the TIFFDirectory.createFromMetadata method.

                -
                +
                Mapping of TIFF Native Image Metadata to the Standard Metadata Format
                The derivation of standard metadata format @@ -252,7 +234,6 @@ elements from TIFF native image metadata is given in the following table. -

                @@ -261,9 +242,9 @@ +"GRAY"; RGB, PaletteColor => "RGB"; CMYK => "CMYK"; +YCbCr => "YCbCr"; +CIELab, ICCLab => "Lab". @@ -271,7 +252,7 @@ - + @@ -279,28 +260,28 @@ - +Deflate => "Deflate"; Exif JPEG => "JPEG". - + - + - @@ -310,8 +291,8 @@ - + @@ -343,9 +324,9 @@ - + @@ -357,24 +338,23 @@ Artist, HostComputer, InkNames, Copyright: /Text/TextEntry@keyword = field name, /Text/TextEntry@value = field value.
                -Example: TIFF Software field => /Text/TextEntry@keyword = "Software", +Example: TIFF Software field => /Text/TextEntry@keyword = "Software", /Text/TextEntry@value = Name and version number of the software package(s) used to create the image. - +
                Standard Metadata Element
                /Chroma/ColorSpaceType@name PhotometricInterpretation: WhiteIsZero, BlackIsZero, TransparencyMask = -"GRAY"; RGB, PaletteColor => "RGB"; CMYK => "CMYK"; -YCbCr => "YCbCr"; -CIELab, ICCLab => "Lab".
                /Chroma/NumChannels@value
                /Chroma/BlackIsZero@value"TRUE" <=> PhotometricInterpretation => WhiteIsZero"TRUE" <=> PhotometricInterpretation => WhiteIsZero
                /Chroma/Palette
                /Compression/CompressionTypeName@valueCompression: Uncompressed => "none"; CCITT 1D => "CCITT +Compression: Uncompressed => "none"; CCITT 1D => "CCITT RLE"; -Group 3 Fax => "CCITT T.4"; Group 4 Fax => "CCITT T.6"; -LZW => "LZW"; -JPEG => "Old JPEG"; New JPEG => "JPEG"; Zlib =>> "ZLib"; PackBits => +Group 3 Fax => "CCITT T.4"; Group 4 Fax => "CCITT T.6"; +LZW => "LZW"; +JPEG => "Old JPEG"; New JPEG => "JPEG"; Zlib =>> "ZLib"; PackBits => "PackBits"; -Deflate => "Deflate"; Exif JPEG => "JPEG".
                /Compression/Lossless@valueCompression: JPEG or New JPEG => "FALSE"; otherwise "TRUE".Compression: JPEG or New JPEG => "FALSE"; otherwise "TRUE".
                /Data/PlanarConfiguration@valueChunky => "PixelInterleaved"; Planar => "PlaneInterleaved".Chunky => "PixelInterleaved"; Planar => "PlaneInterleaved".
                /Data/SampleFormat@valuePhotometricInterpretation PaletteColor => "Index"; -SampleFormat unsigned integer data => "UnsignedIntegral"; -SampleFormat two's complement signed integer data => "SignedIntegral"; -SampleFormat IEEE floating point data => "Real"; +PhotometricInterpretation PaletteColor => "Index"; +SampleFormat unsigned integer data => "UnsignedIntegral"; +SampleFormat two's complement signed integer data => "SignedIntegral"; +SampleFormat IEEE floating point data => "Real"; otherwise element not emitted.
                /Data/SampleMSB@valueFillOrder: left-to-right => space-separated list of BitsPerSample-1; -right-to-left => space-separated list of 0s.FillOrder: left-to-right => space-separated list of BitsPerSample-1; +right-to-left => space-separated list of 0s.
                /Dimension/PixelAspectRatio@value
                /Document/SubimageInterpretation@valueNewSubFileType: transparency => "TransparencyMask"; -reduced-resolution => "ReducedResolution"; -single page => "SinglePage".NewSubFileType: transparency => "TransparencyMask"; +reduced-resolution => "ReducedResolution"; +single page => "SinglePage".
                /Document/ImageCreationTime@value
                /Transparency/Alpha@valueExtraSamples: associated alpha => "premultiplied"; -unassociated alpha => "nonpremultiplied".ExtraSamples: associated alpha => "premultiplied"; +unassociated alpha => "nonpremultiplied".
                -

                -

                Reading Exif Images

                +

                Reading Exif Images

                The TIFF reader may be used to read an uncompressed Exif image or the -contents of the APP1 marker segment of a compressed Exif image. +contents of the APP1 marker segment of a compressed Exif image. -
                Reading Uncompressed Exif Images
                +
                Reading Uncompressed Exif Images
                An uncompressed Exif image is a one- or two-page uncompressed TIFF image with a specific ordering of its IFD and image data content. Each pixel @@ -406,12 +386,12 @@ stream and not as a thumbnail, i.e., tiffReader.hasThumbnails(0) will return false. -
                Reading Compressed Exif Images
                +
                Reading Compressed Exif Images
                A compressed Exif image is a 3-band ISO/IEC 10918-1 baseline DCT JPEG stream -with an inserted APP1 marker segment. The parameters of the marker +with an inserted APP1 marker segment. The parameters of the marker segment after the length are the 6-byte sequence -{'E', 'x', 'i', 'f', 0x00, 0x00} +{'E', 'x', 'i', 'f', 0x00, 0x00} followed by a complete TIFF stream. The embedded TIFF stream contains a primary IFD describing the JPEG image optionally followed by a thumbnail IFD and compressed or uncompressed thumbnail image data. Note that the embedded TIFF @@ -419,12 +399,12 @@ nor any descriptive fields which duplicate information found in the JPEG stream itself. -

                The parameter content of the APP1 marker segment may be obtained +

                The parameter content of the APP1 marker segment may be obtained from the user object of the associated Node in a -javax_imageio_jpeg_image_1.0 native image metadata tree extracted +javax_imageio_jpeg_image_1.0 native image metadata tree extracted from the image metadata object returned by the JPEG reader. This APP1 Exif node will be a child of the node named "markerSequence" and will -have name unknown and an attribute named MarkerTag with +have name unknown and an attribute named MarkerTag with integral value 0xE1 (String value "225"). The user object of this node will be a byte array which starts with the six bytes {'E', 'x', 'i', 'f', '0', '0'}. @@ -472,9 +452,8 @@ images. Calling tiffReader.read(0, readParam) will throw an exception as the primary image in the embedded TIFF stream is always empty; the primary image should be obtained using the JPEG reader itself. -

                -

                Writing Images

                +

                Writing Images

                TIFF images are written by a ImageWriter which may be controlled by its public interface as well as via a supplied @@ -482,7 +461,7 @@ by the getDefaultWriteParam() method of the TIFF ImageWriter, the canWriteTiles() and canWriteCompressed() methods will return true; the canOffsetTiles() and -canWriteProgressive() methods will return false.

                +canWriteProgressive() methods will return false. The TIFF writer supports many optional capabilities including writing tiled images, inserting images, writing or inserting empty images, and replacing image @@ -497,12 +476,12 @@ compression is being used and strips are being written, the number of rows per strip is rounded to a multiple of 8 times the maximum MCU over both dimensions.

                - + -

                Compression

                +

                Compression

                The compression type may be set via the setCompressionType() method of the ImageWriteParam after setting the compression mode to @@ -592,21 +571,21 @@

                If ZLib/Deflate or JPEG compression is used, the compression quality may be set. For ZLib/Deflate the supplied floating point quality value is -rescaled to the range [1, 9] and truncated to an integer +rescaled to the range [1, 9] and truncated to an integer to derive the Deflate compression level. For JPEG the floating point quality value is passed directly to the JPEG writer plug-in which interprets it in the usual way.

                -

                Color Conversion

                +

                Color Conversion

                If the source image data color space type is RGB, and the destination photometric type is CIE L*a*b* or YCbCr, then the source image data will be automatically converted from RGB using an internal color converter.

                -

                ICC Profiles

                +

                ICC Profiles

                -An ICC Profile field will be written if either: +An ICC Profile field will be written if either:
                • one is present in the native image metadata IIOMetadata instance supplied to the writer, @@ -614,50 +593,50 @@
                • the ColorSpace of the destination ImageTypeSpecifier is an instance of ICC_ColorSpace which is not one of the standard -color spaces defined by the CS_* constants in the +color spaces defined by the CS_* constants in the ColorSpace class. The destination type is set via ImageWriteParam.setDestinationType(ImageTypeSpecifier) and defaults to the ImageTypeSpecifier of the image being written.
                -

                Metadata Issues

                +

                Metadata Issues

                Some behavior of the writer is affected by or may affect the contents of the image metadata which may be supplied by the user. -

                For bilevel images, the FillOrder, and T4Options +

                For bilevel images, the FillOrder, and T4Options fields affect the output data. The data will be filled right-to-left if -FillOrder is present with a value of 2 +FillOrder is present with a value of 2 (BaselineTIFFTagSet.FILL_ORDER_RIGHT_TO_LEFT) -and will be filled left-to-right otherwise. The value of T4Options +and will be filled left-to-right otherwise. The value of T4Options specifies whether the data should be 1D- or 2D-encoded and whether EOL padding should be used.

                -

                For all images the value of the RowsPerStrip field is used +

                For all images the value of the RowsPerStrip field is used to the set the number of rows per strip if the image is not tiled. The default number of rows per strip is either 8 or the number of rows which would fill no more than 8 kilobytes, whichever is larger.

                -

                For all images the tile dimensions may be set using the TileWidth -and TileLength field values if the tiling mode is +

                For all images the tile dimensions may be set using the TileWidth +and TileLength field values if the tiling mode is ImageWriteParam.MODE_COPY_FROM_METADATA. If this mode is set but the fields are not, their respective default values are the image width and height.

                -

                When using JPEG-in-TIFF compression, a JPEGTables field will be +

                When using JPEG-in-TIFF compression, a JPEGTables field will be written to the IFD and abbreviated JPEG streams to each strip or tile if and -only if a JPEGTables field is contained in the metadata object -provided to the writer. If the contents of the JPEGTables field is +only if a JPEGTables field is contained in the metadata object +provided to the writer. If the contents of the JPEGTables field is a valid tables-only JPEG stream, then it will be used; otherwise the contents of the field will be replaced with default visually lossless tables. If no -such JPEGTables field is present in the metadata, then no -JPEGTables field will be written to the output and each strip or +such JPEGTables field is present in the metadata, then no +JPEGTables field will be written to the output and each strip or tile will be written as a separate, self-contained JPEG stream.

                When using Deflate/ZLib or LZW compression, if the image has 8 bits per sample, a horizontal differencing predictor will be used if the -Predictor field is present with a value of 2 +Predictor field is present with a value of 2 (BaselineTIFFTagSet.PREDICTOR_HORIZONTAL_DIFFERENCING). If prediction is so requested but the image does not have 8 bits per sample the field will be reset to have the value 1 @@ -667,30 +646,30 @@

                Some fields may be added or modified:

                  -
                • PhotometricInterpretation if not present.
                • -
                • PlanarConfiguration if this field is present with value -Planar is is reset to Chunky.
                • -
                • Compression always.
                • -
                • BitsPerSample if the image is not bilevel.
                • -
                • SamplesPerPixel always.
                • -
                • ExtraSamples if an alpha channel is present.
                • -
                • SampleFormat if not present and the data are 16- or 32-bit +
                • PhotometricInterpretation if not present.
                • +
                • PlanarConfiguration if this field is present with value +Planar is is reset to Chunky.
                • +
                • Compression always.
                • +
                • BitsPerSample if the image is not bilevel.
                • +
                • SamplesPerPixel always.
                • +
                • ExtraSamples if an alpha channel is present.
                • +
                • SampleFormat if not present and the data are 16- or 32-bit integers or floating point.
                • -
                • ColorMap if the PhotometricInterpretation is -RGBPalette.
                • -
                • ImageWidth and ImageLength always.
                • -
                • TileWidth, TileLength, TileOffsets, and -TileByteCounts if a tiled image is being written.
                • -
                • RowsPerStrip, StripOffsets, and StripByteCounts +
                • ColorMap if the PhotometricInterpretation is +RGBPalette.
                • +
                • ImageWidth and ImageLength always.
                • +
                • TileWidth, TileLength, TileOffsets, and +TileByteCounts if a tiled image is being written.
                • +
                • RowsPerStrip, StripOffsets, and StripByteCounts if a tiled image is not being written.
                • -
                • XResolution, YResolution, and ResolutionUnit +
                • XResolution, YResolution, and ResolutionUnit if none of these is present.
                • -
                • YCbCrSubsampling and YCbCrPositioning if the +
                • YCbCrSubsampling and YCbCrPositioning if the photometric interpretation is YCbCr and the compression type is not JPEG (only [1, 1] subsampling and cosited positioning are supported for non-JPEG YCbCr output).
                • -
                • YCbCrSubsampling, YCbCrPositioning, and -ReferenceBlackWhite: if the compression type is JPEG and the color +
                • YCbCrSubsampling, YCbCrPositioning, and +ReferenceBlackWhite: if the compression type is JPEG and the color space is RGB these will be reset to [2, 2] centered subsampling with no headroom/footroom (0:255,128:255,128:255).
                @@ -698,24 +677,23 @@

                Some fields may be removed:

                  -
                • BitsPerSample if the image is bilevel.
                • -
                • ExtraSamples if the image does not have an alpha channel.
                • -
                • ColorMap if the photometric interpretation is not -RGBPalette.
                • -
                • TileWidth, TileLength, TileOffsets, and -TileByteCounts if tiling is not being used.
                • -
                • RowsPerStrip, StripOffsets, and StripByteCounts +
                • BitsPerSample if the image is bilevel.
                • +
                • ExtraSamples if the image does not have an alpha channel.
                • +
                • ColorMap if the photometric interpretation is not +RGBPalette.
                • +
                • TileWidth, TileLength, TileOffsets, and +TileByteCounts if tiling is not being used.
                • +
                • RowsPerStrip, StripOffsets, and StripByteCounts if tiling is being used.
                • -
                • YCbCrSubsampling, YCbCrPositioning, and -ReferenceBlackWhite if the compression type is JPEG and the +
                • YCbCrSubsampling, YCbCrPositioning, and +ReferenceBlackWhite if the compression type is JPEG and the color space is grayscale.
                • -
                • JPEGProc, JPEGInterchangeFormat, -JPEGInterchangeFormatLength, JPEGRestartInterval, -JPEGLosslessPredictors, JPEGPointTransforms, -JPEGQTables, JPEGDCTables, and -JPEGACTables if the compression type is JPEG.
                • +
                • JPEGProc, JPEGInterchangeFormat, +JPEGInterchangeFormatLength, JPEGRestartInterval, +JPEGLosslessPredictors, JPEGPointTransforms, +JPEGQTables, JPEGDCTables, and +JPEGACTables if the compression type is JPEG.
                -

                Other fields present in the supplied metadata are uninterpreted and will be written as supplied.

                @@ -735,7 +713,7 @@ IIOMetadata object so obtained may then be passed to the TIFF writer.

                -
                +
                Mapping of the Standard Metadata Format to TIFF Native Image Metadata
                The derivation of TIFF native image metadata @@ -743,7 +721,6 @@ javax_imageio_1.0 is given in the following table. -

                @@ -754,10 +731,10 @@ PhotometricInterpretation +=> WhiteIsZero; "GRAY" and /Document/SubimageInterpretation@value = +"TransparencyMask" => TransparencyMask; "RGB" and /Chroma/Palette present => +PaletteColor; "GRAY" => BlackIsZero; "RGB" => RGB; "YCbCr" => YCbCr; +"CMYK" => CMYK; "Lab" => CIELab. @@ -769,21 +746,21 @@ - + - + - @@ -792,8 +769,8 @@ - @@ -826,9 +803,9 @@ - + @@ -843,29 +820,28 @@ - +
                TIFF Field /Chroma/ColorSpaceType@name: "GRAY" and /Chroma/BlackIsZero@value = "FALSE" -=> WhiteIsZero; "GRAY" and /Document/SubimageInterpretation@value = -"TransparencyMask" => TransparencyMask; "RGB" and /Chroma/Palette present => -PaletteColor; "GRAY" => BlackIsZero; "RGB" => RGB; "YCbCr" => YCbCr; -"CMYK" => CMYK; "Lab" => CIELab.
                SamplesPerPixel
                Compression/Compression/CompressionTypeName@value: "none" => Uncompressed; -"CCITT RLE" => CCITT 1D; "CCITT T.4" => Group 3 Fax; "CCITT T.6" => Group 4 -Fax; "LZW" => LZW; "Old JPEG" => JPEG; "JPEG" => New JPEG; "ZLib" => ZLib; -"PackBits" => PackBits; "Deflate" => Deflate./Compression/CompressionTypeName@value: "none" => Uncompressed; +"CCITT RLE" => CCITT 1D; "CCITT T.4" => Group 3 Fax; "CCITT T.6" => Group 4 +Fax; "LZW" => LZW; "Old JPEG" => JPEG; "JPEG" => New JPEG; "ZLib" => ZLib; +"PackBits" => PackBits; "Deflate" => Deflate.
                PlanarConfiguration/Data/PlanarConfiguration@value: "PixelInterleaved" => Chunky; -"PlaneInterleaved" => Planar./Data/PlanarConfiguration@value: "PixelInterleaved" => Chunky; +"PlaneInterleaved" => Planar.
                SampleFormat/Data/SampleFormat@value: "SignedIntegral" => two's complement signed -integer data; "UnsignedIntegral" => unsigned integer data; "Real" => -IEEE floating point data; "Index" => unsigned integer data. +/Data/SampleFormat@value: "SignedIntegral" => two's complement signed +integer data; "UnsignedIntegral" => unsigned integer data; "Real" => +IEEE floating point data; "Index" => unsigned integer data.
                FillOrder/Data/SampleMSB@value: if all values in space-separated list are 0s => -right-to-left; otherwise => left-to-right. +/Data/SampleMSB@value: if all values in space-separated list are 0s => +right-to-left; otherwise => left-to-right.
                NewSubFileType/Document/SubimageInterpretation@value: "TransparencyMask" => -transparency mask; "ReducedResolution" => reduced-resolution; -"SinglePage" => single page./Document/SubimageInterpretation@value: "TransparencyMask" => +transparency mask; "ReducedResolution" => reduced-resolution; +"SinglePage" => single page.
                DateTime
                ExtraSamples/Transparency/Alpha@value: "premultiplied" => associated alpha, count 1; -"nonpremultiplied" => unassociated alpha, count 1./Transparency/Alpha@value: "premultiplied" => associated alpha, count 1; +"nonpremultiplied" => unassociated alpha, count 1.
                -

                -

                Writing Exif Images

                +

                Writing Exif Images

                The TIFF writer may be used to write an uncompressed Exif image or the -contents of the APP1 marker segment of a compressed Exif image. +contents of the APP1 marker segment of a compressed Exif image. -
                Writing Uncompressed Exif Images
                +
                Writing Uncompressed Exif Images
                When writing a sequence of images each image is normally recorded as {IFD, IFD Value, Image Data}. The Exif specification requires that an uncompressed Exif image be structured as follows: +
                  -
                1. Image File Header
                2. Primary IFD
                3. Primary IFD Value
                4. @@ -925,9 +901,9 @@ } -
                  Writing Compressed Exif Images
                  +
                  Writing Compressed Exif Images
                  -The structure of the embedded TIFF stream in the APP1 segment of a +The structure of the embedded TIFF stream in the APP1 segment of a compressed Exif image is identical to the uncompressed Exif image structure except that there are no primary image data, i.e., the primary IFD does not refer to any image data. @@ -1013,7 +989,7 @@ Node tree = jpegImageMetadata.getAsTree(nativeFormat); NodeList children = tree.getChildNodes(); int numChildren = children.getLength(); - for (int i = 0; i < numChildren; i++) { + for (int i = 0; i < numChildren; i++) { Node child = children.item(i); if (child.getNodeName().equals("markerSequence")) { child.appendChild(app1Node); @@ -1032,7 +1008,7 @@ and written to the JPEG stream when the primary image is written using the JPEG writer. -

                  Stream Metadata

                  +

                  Stream Metadata

                  The DTD for the TIFF native stream metadata format is as follows: @@ -1042,14 +1018,14 @@ <!ELEMENT "javax_imageio_tiff_stream_1.0" (ByteOrder)> <!ELEMENT "ByteOrder" EMPTY> - <!-- The stream byte order --> + <!-- The stream byte order --> <!ATTLIST "ByteOrder" "value" #CDATA #REQUIRED> - <!-- One of "BIG_ENDIAN" or "LITTLE_ENDIAN" --> + <!-- One of "BIG_ENDIAN" or "LITTLE_ENDIAN" --> <!-- Data type: String --> ]> -

                  Image Metadata

                  +

                  Image Metadata

                  The DTD for the TIFF native image metadata format is as follows: @@ -1059,140 +1035,140 @@ <!ELEMENT "javax_imageio_tiff_image_1.0" (TIFFIFD)*> <!ELEMENT "TIFFIFD" (TIFFField | TIFFIFD)*> - <!-- An IFD (directory) containing fields --> + <!-- An IFD (directory) containing fields --> <!ATTLIST "TIFFIFD" "tagSets" #CDATA #REQUIRED> <!-- Data type: String --> <!ATTLIST "TIFFIFD" "parentTagNumber" #CDATA #IMPLIED> - <!-- The tag number of the field pointing to this IFD --> + <!-- The tag number of the field pointing to this IFD --> <!-- Data type: Integer --> <!ATTLIST "TIFFIFD" "parentTagName" #CDATA #IMPLIED> - <!-- A mnemonic name for the field pointing to this IFD, if known - --> + <!-- A mnemonic name for the field pointing to this IFD, if known + --> <!-- Data type: String --> <!ELEMENT "TIFFField" (TIFFBytes | TIFFAsciis | TIFFShorts | TIFFSShorts | TIFFLongs | TIFFSLongs | TIFFRationals | TIFFSRationals | TIFFFloats | TIFFDoubles | TIFFUndefined)> - <!-- A field containing data --> + <!-- A field containing data --> <!ATTLIST "TIFFField" "number" #CDATA #REQUIRED> - <!-- The tag number asociated with the field --> + <!-- The tag number asociated with the field --> <!-- Data type: String --> <!ATTLIST "TIFFField" "name" #CDATA #IMPLIED> - <!-- A mnemonic name associated with the field, if known --> + <!-- A mnemonic name associated with the field, if known --> <!-- Data type: String --> <!ELEMENT "TIFFBytes" (TIFFByte)*> - <!-- A sequence of TIFFByte nodes --> + <!-- A sequence of TIFFByte nodes --> <!ELEMENT "TIFFByte" EMPTY> - <!-- An integral value between 0 and 255 --> + <!-- An integral value between 0 and 255 --> <!ATTLIST "TIFFByte" "value" #CDATA #IMPLIED> - <!-- The value --> + <!-- The value --> <!-- Data type: String --> <!ATTLIST "TIFFByte" "description" #CDATA #IMPLIED> - <!-- A description, if available --> + <!-- A description, if available --> <!-- Data type: String --> <!ELEMENT "TIFFAsciis" (TIFFAscii)*> - <!-- A sequence of TIFFAscii nodes --> + <!-- A sequence of TIFFAscii nodes --> <!ELEMENT "TIFFAscii" EMPTY> - <!-- A String value --> + <!-- A String value --> <!ATTLIST "TIFFAscii" "value" #CDATA #IMPLIED> - <!-- The value --> + <!-- The value --> <!-- Data type: String --> <!ELEMENT "TIFFShorts" (TIFFShort)*> - <!-- A sequence of TIFFShort nodes --> + <!-- A sequence of TIFFShort nodes --> <!ELEMENT "TIFFShort" EMPTY> - <!-- An integral value between 0 and 65535 --> + <!-- An integral value between 0 and 65535 --> <!ATTLIST "TIFFShort" "value" #CDATA #IMPLIED> - <!-- The value --> + <!-- The value --> <!-- Data type: String --> <!ATTLIST "TIFFShort" "description" #CDATA #IMPLIED> - <!-- A description, if available --> + <!-- A description, if available --> <!-- Data type: String --> <!ELEMENT "TIFFSShorts" (TIFFSShort)*> - <!-- A sequence of TIFFSShort nodes --> + <!-- A sequence of TIFFSShort nodes --> <!ELEMENT "TIFFSShort" EMPTY> - <!-- An integral value between -32768 and 32767 --> + <!-- An integral value between -32768 and 32767 --> <!ATTLIST "TIFFSShort" "value" #CDATA #IMPLIED> - <!-- The value --> + <!-- The value --> <!-- Data type: String --> <!ATTLIST "TIFFSShort" "description" #CDATA #IMPLIED> - <!-- A description, if available --> + <!-- A description, if available --> <!-- Data type: String --> <!ELEMENT "TIFFLongs" (TIFFLong)*> - <!-- A sequence of TIFFLong nodes --> + <!-- A sequence of TIFFLong nodes --> <!ELEMENT "TIFFLong" EMPTY> - <!-- An integral value between 0 and 4294967295 --> + <!-- An integral value between 0 and 4294967295 --> <!ATTLIST "TIFFLong" "value" #CDATA #IMPLIED> - <!-- The value --> + <!-- The value --> <!-- Data type: String --> <!ATTLIST "TIFFLong" "description" #CDATA #IMPLIED> - <!-- A description, if available --> + <!-- A description, if available --> <!-- Data type: String --> <!ELEMENT "TIFFSLongs" (TIFFSLong)*> - <!-- A sequence of TIFFSLong nodes --> + <!-- A sequence of TIFFSLong nodes --> <!ELEMENT "TIFFSLong" EMPTY> - <!-- An integral value between -2147483648 and 2147482647 --> + <!-- An integral value between -2147483648 and 2147482647 --> <!ATTLIST "TIFFSLong" "value" #CDATA #IMPLIED> - <!-- The value --> + <!-- The value --> <!-- Data type: String --> <!ATTLIST "TIFFSLong" "description" #CDATA #IMPLIED> - <!-- A description, if available --> + <!-- A description, if available --> <!-- Data type: String --> <!ELEMENT "TIFFRationals" (TIFFRational)*> - <!-- A sequence of TIFFRational nodes --> + <!-- A sequence of TIFFRational nodes --> <!ELEMENT "TIFFRational" EMPTY> - <!-- A rational value consisting of an unsigned numerator and - denominator --> + <!-- A rational value consisting of an unsigned numerator and + denominator --> <!ATTLIST "TIFFRational" "value" #CDATA #IMPLIED> - <!-- The numerator and denominator, separated by a slash --> + <!-- The numerator and denominator, separated by a slash --> <!-- Data type: String --> <!ELEMENT "TIFFSRationals" (TIFFSRational)*> - <!-- A sequence of TIFFSRational nodes --> + <!-- A sequence of TIFFSRational nodes --> <!ELEMENT "TIFFSRational" EMPTY> - <!-- A rational value consisting of a signed numerator and - denominator --> + <!-- A rational value consisting of a signed numerator and + denominator --> <!ATTLIST "TIFFSRational" "value" #CDATA #IMPLIED> - <!-- The numerator and denominator, separated by a slash --> + <!-- The numerator and denominator, separated by a slash --> <!-- Data type: String --> <!ELEMENT "TIFFFloats" (TIFFFloat)*> - <!-- A sequence of TIFFFloat nodes --> + <!-- A sequence of TIFFFloat nodes --> <!ELEMENT "TIFFFloat" EMPTY> - <!-- A single-precision floating-point value --> + <!-- A single-precision floating-point value --> <!ATTLIST "TIFFFloat" "value" #CDATA #IMPLIED> - <!-- The value --> + <!-- The value --> <!-- Data type: String --> <!ELEMENT "TIFFDoubles" (TIFFDouble)*> - <!-- A sequence of TIFFDouble nodes --> + <!-- A sequence of TIFFDouble nodes --> <!ELEMENT "TIFFDouble" EMPTY> - <!-- A double-precision floating-point value --> + <!-- A double-precision floating-point value --> <!ATTLIST "TIFFDouble" "value" #CDATA #IMPLIED> - <!-- The value --> + <!-- The value --> <!-- Data type: String --> <!ELEMENT "TIFFUndefined" EMPTY> - <!-- Uninterpreted byte data --> + <!-- Uninterpreted byte data --> <!ATTLIST "TIFFUndefined" "value" #CDATA #IMPLIED> - <!-- A list of comma-separated byte values --> + <!-- A list of comma-separated byte values --> <!-- Data type: String --> ]> diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/javax/imageio/metadata/doc-files/wbmp_metadata.html --- a/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/wbmp_metadata.html Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/wbmp_metadata.html Thu Dec 14 12:28:32 2017 +0000 @@ -1,8 +1,11 @@ - - + + + + WBMP Metadata Format Specification + -WBMP Metadata Format Specification - - -

                  -WBMP Metadata Format Specification -

                  +

                  WBMP Metadata Format Specification

                  The XML schema for the native image metadata format is as follows: diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/javax/imageio/package-info.java --- a/src/java.desktop/share/classes/javax/imageio/package-info.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/javax/imageio/package-info.java Thu Dec 14 12:28:32 2017 +0000 @@ -113,7 +113,7 @@ * *

                  Standard Plug-in Notes

                  * - *

                  Standard plug-in for GIF image format

                  + *

                  Standard plug-in for GIF image format

                  * ImageIO provides {@code ImageReader} and {@code ImageWriter}plug-ins for the * Graphics * Interchange Format (GIF) image format. These are the "standard" GIF diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/javax/imageio/spi/IIORegistry.java --- a/src/java.desktop/share/classes/javax/imageio/spi/IIORegistry.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/javax/imageio/spi/IIORegistry.java Thu Dec 14 12:28:32 2017 +0000 @@ -56,46 +56,24 @@ import java.util.ServiceConfigurationError; /** - * A registry for service provider instances. Service provider - * classes may be detected at run time by means of meta-information in - * the JAR files containing them. The intent is that it be relatively - * inexpensive to load and inspect all available service provider - * classes. These classes may them be used to locate and instantiate + * A registry for Image I/O service provider instances. Service provider + * classes may be discovered at runtime by the mechanisms documented in + * {@link java.util.ServiceLoader ServiceLoader}. + * + * The intent is that it be relatively inexpensive to load and inspect + * all available Image I/O service provider classes. + * These classes may then be used to locate and instantiate * more heavyweight classes that will perform actual work, in this * case instances of {@code ImageReader}, * {@code ImageWriter}, {@code ImageTranscoder}, * {@code ImageInputStream}, and {@code ImageOutputStream}. * - * Service providers found from the Java platform are automatically + * Service providers included in the Java runtime are automatically * loaded as soon as this class is instantiated. * *

                  When the {@code registerApplicationClasspathSpis} method - * is called, service provider instances declared in the - * meta-information section of JAR files on the application class path - * are loaded. To declare a service provider, a {@code services} - * subdirectory is placed within the {@code META-INF} directory - * that is present in every JAR file. This directory contains a file - * for each service provider interface that has one or more - * implementation classes present in the JAR file. For example, if - * the JAR file contained a class named - * {@code com.mycompany.imageio.MyFormatReaderSpi} which - * implements the {@code ImageReaderSpi} interface, the JAR file - * would contain a file named: - * - *

                  - * META-INF/services/javax.imageio.spi.ImageReaderSpi
                  - * 
                  - * - * containing the line: - * - *
                  - * com.mycompany.imageio.MyFormatReaderSpi
                  - * 
                  - * - *

                  The service provider classes are intended to be lightweight - * and quick to load. Implementations of these interfaces - * should avoid complex dependencies on other classes and on - * native code. + * is called, additional service provider instances will be discovered + * using {@link java.util.ServiceLoader ServiceLoader}. * *

                  It is also possible to manually add service providers not found * automatically, as well as to remove those that are using the @@ -103,9 +81,8 @@ * the application may customize the contents of the registry as it * sees fit. * - *

                  For more details on declaring service providers, and the JAR - * format in general, see the - * JAR File Specification. + *

                  For information on how to create and deploy service providers, + * refer to the documentation on {@link java.util.ServiceLoader ServiceLoader} */ public final class IIORegistry extends ServiceRegistry { diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/javax/imageio/spi/ServiceRegistry.java --- a/src/java.desktop/share/classes/javax/imageio/spi/ServiceRegistry.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/javax/imageio/spi/ServiceRegistry.java Thu Dec 14 12:28:32 2017 +0000 @@ -39,19 +39,13 @@ import java.util.ServiceLoader; /** - * A registry for service provider instances. - * - *

                  A service is a well-known set of interfaces and (usually - * abstract) classes. A service provider is a specific - * implementation of a service. The classes in a provider typically - * implement the interface or subclass the class defined by the - * service itself. + * A registry for service provider instances for Image I/O service types. * *

                  Service providers are stored in one or more categories, - * each of which is defined by a class of interface (described by a + * each of which is defined by a class or interface (described by a * {@code Class} object) that all of its members must implement. * - *

                  The set of categories supported is limited + *

                  The set of categories supported by this class is limited * to the following standard Image I/O service types: * *

                    @@ -63,9 +57,10 @@ *
                  * *

                  An attempt to load a provider that is not a subtype of one of the - * above types will result in {@code IllegalArgumentException}. For - * a general mechanism to load service providers, see - * {@link java.util.ServiceLoader ServiceLoader}. + * above types will result in {@code IllegalArgumentException}. + *

                  For the general mechanism to load service providers, see + * {@link java.util.ServiceLoader ServiceLoader}, which is + * the underlying standard mechanism used by this class. * *

                  Only a single instance of a given leaf class (that is, the * actual class returned by {@code getClass()}, as opposed to any @@ -80,24 +75,7 @@ * the previous instance. In practice, service provider objects are * usually singletons so this behavior is appropriate. * - *

                  To declare a service provider, a {@code services} - * subdirectory is placed within the {@code META-INF} directory - * that is present in every JAR file. This directory contains a file - * for each service provider interface that has one or more - * implementation classes present in the JAR file. For example, if - * the JAR file contained a class named - * {@code com.mycompany.mypkg.GreenImageReaderProvider} which implements the - * {@code javax.imageio.spi.ImageReaderSpi} interface, the JAR file - * would contain a file named:

                  - * META-INF/services/javax.imageio.spi.ImageReaderSpi
                  - * - * containing the line: - * - *
                  - * com.mycompany.mypkg.GreenImageReaderProvider
                  - * 
                  - * - *

                  The service provider classes should be to be lightweight and + *

                  The service provider classes should be lightweight and * quick to load. Implementations of these interfaces should avoid * complex dependencies on other classes and on native code. The usual * pattern for more complex services is to register a lightweight @@ -106,9 +84,8 @@ *

                  An application may customize the contents of a registry as it * sees fit, so long as it has the appropriate runtime permission. * - *

                  For more details on declaring service providers, and the JAR - * format in general, see the - * JAR File Specification. + *

                  For information on how to create and deploy service providers, + * refer to the documentation on {@link java.util.ServiceLoader ServiceLoader} * * @see RegisterableService * @see java.util.ServiceLoader diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/javax/print/attribute/package-info.java --- a/src/java.desktop/share/classes/javax/print/attribute/package-info.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/javax/print/attribute/package-info.java Thu Dec 14 12:28:32 2017 +0000 @@ -80,7 +80,7 @@ * attribute category, and the {@code Copies} instance represents the attribute * value. * - *

                  Attribute Roles

                  + *

                  Attribute Roles

                  * When submitting a print job to a printer, the client provides the attributes * describing the characteristics of the print data, such as the document name, * and how the print data should be printed, such as double-sided, five copies. diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/javax/swing/DefaultListSelectionModel.java --- a/src/java.desktop/share/classes/javax/swing/DefaultListSelectionModel.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/javax/swing/DefaultListSelectionModel.java Thu Dec 14 12:28:32 2017 +0000 @@ -95,14 +95,37 @@ * @throws IllegalArgumentException {@inheritDoc} */ public void setSelectionMode(int selectionMode) { + int oldMode = this.selectionMode; switch (selectionMode) { - case SINGLE_SELECTION: - case SINGLE_INTERVAL_SELECTION: - case MULTIPLE_INTERVAL_SELECTION: - this.selectionMode = selectionMode; - break; - default: - throw new IllegalArgumentException("invalid selectionMode"); + case SINGLE_SELECTION: + case SINGLE_INTERVAL_SELECTION: + case MULTIPLE_INTERVAL_SELECTION: + this.selectionMode = selectionMode; + break; + default: + throw new IllegalArgumentException("invalid selectionMode"); + } + + /* + This code will only be executed when selection needs to be updated on + changing selection mode. It will happen only if selection mode is changed + from MULTIPLE_INTERVAL to SINGLE_INTERVAL or SINGLE or from + SINGLE_INTERVAL to SINGLE + */ + if (oldMode > this.selectionMode) { + if (this.selectionMode == SINGLE_SELECTION) { + if (!isSelectionEmpty()) { + setSelectionInterval(minIndex, minIndex); + } + } else if (this.selectionMode == SINGLE_INTERVAL_SELECTION) { + if(!isSelectionEmpty()) { + int selectionEndindex = minIndex; + while (value.get(selectionEndindex + 1)) { + selectionEndindex++; + } + setSelectionInterval(minIndex, selectionEndindex); + } + } } } diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/javax/swing/package-info.java --- a/src/java.desktop/share/classes/javax/swing/package-info.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/javax/swing/package-info.java Thu Dec 14 12:28:32 2017 +0000 @@ -32,7 +32,7 @@ * The Java Tutorial. For other resources, see * Related Documentation. * - *

                  Swing's Threading Policy

                  + *

                  Swing's Threading Policy

                  * In general Swing is not thread safe. All Swing components and related * classes, unless otherwise documented, must be accessed on the event * dispatching thread. @@ -94,6 +94,23 @@ * If you modify the model on a separate thread you run the risk of exceptions * and possible display corruption. *

                  + * Although it is generally safe to make updates to the UI immediately, + * when executing on the event dispatch thread, there is an exception : + * if a model listener tries to further change the UI before the UI has been + * updated to reflect a pending change then the UI may render incorrectly. + * + * This can happen if an application installed listener needs to update the UI + * in response to an event which will cause a change in the model structure. + * It is important to first allow component installed listeners to process this + * change, since there is no guarantee of the order in which listeners may be + * called. + * + * The solution is for the application listener to make the change using + * {@link SwingUtilities.invokeLater} so that any changes to UI rendering will + * be done post processing all the model listeners installed by the component. + *

                  + *

                  + * * As all events are delivered on the event dispatching thread, care must be * taken in event processing. In particular, a long running task, such as * network io or computational intensive processing, executed on the event @@ -110,7 +127,7 @@ * href="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html"> * Concurrency in Swing. * - *

                  Related Documentation

                  + *

                  Related Documentation

                  * For overviews, tutorials, examples, guides, and other documentation, * please see: *
                    diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/javax/swing/plaf/basic/BasicComboPopup.java --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicComboPopup.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicComboPopup.java Thu Dec 14 12:28:32 2017 +0000 @@ -530,7 +530,6 @@ */ protected JList createList() { return new JList( comboBox.getModel() ) { - @SuppressWarnings("deprecation") public void processMouseEvent(MouseEvent e) { if (BasicGraphicsUtils.isMenuShortcutKeyDown(e)) { // Fix for 4234053. Filter out the Control Key from the list. @@ -538,7 +537,7 @@ Toolkit toolkit = Toolkit.getDefaultToolkit(); MouseEvent newEvent = new MouseEvent( (Component)e.getSource(), e.getID(), e.getWhen(), - e.getModifiers() ^ toolkit.getMenuShortcutKeyMask(), + e.getModifiersEx() ^ toolkit.getMenuShortcutKeyMaskEx(), e.getX(), e.getY(), e.getXOnScreen(), e.getYOnScreen(), e.getClickCount(), diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java Thu Dec 14 12:28:32 2017 +0000 @@ -1134,6 +1134,7 @@ boolean isTrav = (selectedFile != null && chooser.isTraversable(selectedFile)); boolean isDirSelEnabled = chooser.isDirectorySelectionEnabled(); boolean isFileSelEnabled = chooser.isFileSelectionEnabled(); + @SuppressWarnings("deprecation") boolean isCtrl = (e != null && (e.getModifiers() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) != 0); diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/javax/swing/plaf/basic/BasicGraphicsUtils.java --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicGraphicsUtils.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicGraphicsUtils.java Thu Dec 14 12:28:32 2017 +0000 @@ -382,10 +382,9 @@ return c.getComponentOrientation().isLeftToRight(); } - @SuppressWarnings("deprecation") static boolean isMenuShortcutKeyDown(InputEvent event) { - return (event.getModifiers() & - Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) != 0; + return (event.getModifiersEx() & + Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx()) != 0; } /** diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/javax/swing/plaf/basic/BasicListUI.java --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicListUI.java Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicListUI.java Thu Dec 14 12:28:32 2017 +0000 @@ -2134,8 +2134,11 @@ Rectangle leadRect = (lead==-1) ? new Rectangle() : list.getCellBounds(lead, lead); + if (leadRect == null) { + return index; + } if (list.getLayoutOrientation() == JList.VERTICAL_WRAP && - list.getVisibleRowCount() <= 0) { + list.getVisibleRowCount() <= 0) { if (!list.getComponentOrientation().isLeftToRight()) { direction = -direction; } @@ -2146,14 +2149,20 @@ visRect.x = leadRect.x + leadRect.width - visRect.width; Point p = new Point(visRect.x - 1, leadRect.y); index = list.locationToIndex(p); + if (index == -1) { + return index; + } Rectangle cellBounds = list.getCellBounds(index, index); - if (visRect.intersects(cellBounds)) { + if (cellBounds != null && visRect.intersects(cellBounds)) { p.x = cellBounds.x - 1; index = list.locationToIndex(p); + if (index == -1) { + return index; + } cellBounds = list.getCellBounds(index, index); } // this is necessary for right-to-left orientation only - if (cellBounds.y != leadRect.y) { + if (cellBounds != null && cellBounds.y != leadRect.y) { p.x = cellBounds.x + cellBounds.width; index = list.locationToIndex(p); } @@ -2163,13 +2172,19 @@ visRect.x = leadRect.x; Point p = new Point(visRect.x + visRect.width, leadRect.y); index = list.locationToIndex(p); + if (index == -1) { + return index; + } Rectangle cellBounds = list.getCellBounds(index, index); - if (visRect.intersects(cellBounds)) { + if (cellBounds != null && visRect.intersects(cellBounds)) { p.x = cellBounds.x + cellBounds.width; index = list.locationToIndex(p); + if (index == -1) { + return index; + } cellBounds = list.getCellBounds(index, index); } - if (cellBounds.y != leadRect.y) { + if (cellBounds != null && cellBounds.y != leadRect.y) { p.x = cellBounds.x - 1; index = list.locationToIndex(p); } @@ -2187,17 +2202,23 @@ visRect.y = leadRect.y + leadRect.height - visRect.height; p.y = visRect.y; index = list.locationToIndex(p); + if (index == -1) { + return index; + } Rectangle cellBounds = list.getCellBounds(index, index); // go one cell down if first visible cell doesn't fit // into adjasted visible rectangle - if (cellBounds.y < visRect.y) { + if (cellBounds != null && cellBounds.y < visRect.y) { p.y = cellBounds.y + cellBounds.height; index = list.locationToIndex(p); + if (index == -1) { + return index; + } cellBounds = list.getCellBounds(index, index); } // if index isn't less then lead // try to go to cell previous to lead - if (cellBounds.y >= leadRect.y) { + if (cellBounds != null && cellBounds.y >= leadRect.y) { p.y = leadRect.y - 1; index = list.locationToIndex(p); } @@ -2207,15 +2228,23 @@ // down // go to the last completely visible cell Point p = new Point(leadRect.x, - visRect.y + visRect.height - 1); + visRect.y + visRect.height - 1); index = list.locationToIndex(p); + if (index == -1) { + return index; + } Rectangle cellBounds = list.getCellBounds(index, index); // go up one cell if last visible cell doesn't fit // into visible rectangle - if (cellBounds.y + cellBounds.height > - visRect.y + visRect.height) { + if (cellBounds != null && + cellBounds.y + cellBounds.height > + visRect.y + visRect.height) + { p.y = cellBounds.y - 1; index = list.locationToIndex(p); + if (index == -1) { + return index; + } cellBounds = list.getCellBounds(index, index); index = Math.max(index, lead); } @@ -2226,24 +2255,33 @@ visRect.y = leadRect.y; p.y = visRect.y + visRect.height - 1; index = list.locationToIndex(p); + if (index == -1) { + return index; + } cellBounds = list.getCellBounds(index, index); // go one cell up if last visible cell doesn't fit // into adjasted visible rectangle - if (cellBounds.y + cellBounds.height > - visRect.y + visRect.height) { + if (cellBounds != null && + cellBounds.y + cellBounds.height > + visRect.y + visRect.height) + { p.y = cellBounds.y - 1; index = list.locationToIndex(p); + if (index == -1) { + return index; + } cellBounds = list.getCellBounds(index, index); } // if index isn't greater then lead // try to go to cell next after lead - if (cellBounds.y <= leadRect.y) { + if (cellBounds != null && cellBounds.y <= leadRect.y) { p.y = leadRect.y + leadRect.height; index = list.locationToIndex(p); } } } } + return index; } @@ -2308,18 +2346,27 @@ cellBounds.x + cellBounds.width - visRect.width); int startIndex = list.locationToIndex(new Point(x, cellBounds.y)); + if (startIndex == -1) { + return; + } Rectangle startRect = list.getCellBounds(startIndex, startIndex); - if (startRect.x < x && startRect.x < cellBounds.x) { + if (startRect != null && + startRect.x < x && startRect.x < cellBounds.x) { startRect.x += startRect.width; startIndex = list.locationToIndex(startRect.getLocation()); + if (startIndex == -1) { + return; + } startRect = list.getCellBounds(startIndex, startIndex); } cellBounds = startRect; } - cellBounds.width = visRect.width; + if (cellBounds != null) { + cellBounds.width = visRect.width; + } } else { if (direction > 0) { @@ -2327,15 +2374,20 @@ int x = cellBounds.x + visRect.width; int rightIndex = list.locationToIndex(new Point(x, cellBounds.y)); + if (rightIndex == -1) { + return; + } Rectangle rightRect = list.getCellBounds(rightIndex, rightIndex); - if (rightRect.x + rightRect.width > x && - rightRect.x > cellBounds.x) { - rightRect.width = 0; + if (rightRect != null) { + if (rightRect.x + rightRect.width > x && + rightRect.x > cellBounds.x) { + rightRect.width = 0; + } + cellBounds.x = Math.max(0, + rightRect.x + rightRect.width - visRect.width); + cellBounds.width = visRect.width; } - cellBounds.x = Math.max(0, - rightRect.x + rightRect.width - visRect.width); - cellBounds.width = visRect.width; } else { cellBounds.x += Math.max(0, @@ -2357,24 +2409,35 @@ cellBounds.y + cellBounds.height - visRect.height); int startIndex = list.locationToIndex(new Point(cellBounds.x, y)); + if (startIndex == -1) { + return; + } Rectangle startRect = list.getCellBounds(startIndex, startIndex); - if (startRect.y < y && startRect.y < cellBounds.y) { + if (startRect != null && + startRect.y < y && startRect.y < cellBounds.y) { startRect.y += startRect.height; startIndex = list.locationToIndex(startRect.getLocation()); + if (startIndex == -1) { + return; + } startRect = list.getCellBounds(startIndex, startIndex); } cellBounds = startRect; - cellBounds.height = visRect.height; + if (cellBounds != null) { + cellBounds.height = visRect.height; + } } else { // adjust height to fit into visible rectangle cellBounds.height = Math.min(cellBounds.height, visRect.height); } } - list.scrollRectToVisible(cellBounds); + if (cellBounds != null) { + list.scrollRectToVisible(cellBounds); + } } } diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/javax/swing/plaf/multi/doc-files/multi_tsc.html --- a/src/java.desktop/share/classes/javax/swing/plaf/multi/doc-files/multi_tsc.html Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/javax/swing/plaf/multi/doc-files/multi_tsc.html Thu Dec 14 12:28:32 2017 +0000 @@ -1,16 +1,37 @@ - - - -Using the Multiplexing Look and Feel - + + + + + Using the Multiplexing Look and Feel + + + + + +

                    Using the Multiplexing Look and Feel


                    @@ -18,8 +39,8 @@ This document is based on an article originally published in -The Swing -Connection. +The Swing Connection.


                    @@ -31,10 +52,10 @@ (called the default look and feel) with one or more auxiliary look and feels. For example, you could -simultaneously provide text-to-speech and Braille outputs, -in addition to the ordinary visual output that a Swing-based +simultaneously provide text-to-speech and Braille outputs, +in addition to the ordinary visual output that a Swing-based application generates, -by adding +by adding two auxiliary look and feels (one for text-to-speech, the other for Braille) to the default look and feel. @@ -62,169 +83,160 @@

                    -Before reading further, you should be familiar +Before reading further, you should be familiar with the concept of pluggable look and feels. For basic information, see -How to Set the Look and Feel, -a section in -The Java Tutorial. + + How to Set the Look and Feel, a section in The Java Tutorial. For architectural details, you can read Pluggable look-and-feel architecture, a section within +href="http://www.oracle.com/technetwork/java/architecture-142923.html#pluggable"> + Pluggable look-and-feel architecture, a section within a Swing Connection article.

                    -

                    - -


                    - -Overview - - +

                    + +


                    +

                    Overview

                    -The classes in the +The classes in the javax.swing.plaf.multi package -implement a +implement a multiplexing look and feel. -A multiplexing look and feel transparently creates -- and +A multiplexing look and feel transparently creates -- and simultaneously supports -- UI objects from several different look and feels in response to a component requesting its UI object (with the getUI method).

                    -Without a multiplexing look and feel, a -developer who wanted to enhance a particular look and feel would -need to extend the classes supporting that look and feel. For example, to -add text-to-speech support to the Java look and feel without using a multiplexing +Without a multiplexing look and feel, a +developer who wanted to enhance a particular look and feel would +need to extend the classes supporting that look and feel. For example, to +add text-to-speech support to the Java look and feel without using a multiplexing look and feel, the developer would need to create a group of classes that extend those of -the Java look and feel, and add text-to-speech support to the new classes. +the Java look and feel, and add text-to-speech support to the new classes. If the developer also wanted to add text-to-speech support to other look -and feels, -such as Motif or Windows, the developers would need to create subclasses +and feels, +such as Motif or Windows, the developers would need to create subclasses of those classes as well.

                    -This approach has at least two shortcomings: -

                      -
                    • First, each subclass must use what is - essentially a copy of the same code, potentially creating a difficult +This approach has at least two shortcomings: +
                        +
                      • First, each subclass must use what is + essentially a copy of the same code, potentially creating a difficult support situation for the developer.
                      • -
                      • Second, and more significantly for the +
                      • Second, and more significantly for the end user, some application developers might force a - particular look and feel to be used. When this approach is used, + particular look and feel to be used. When this approach is used, the end user can't even use the enhanced look and feel.

                      -A multiplexing look and feel -both these problems simultaneously because it allows multiple look +A multiplexing look and feel +both these problems simultaneously because it allows multiple look and feels to be combined. -The first problem (having to use what amounts to a second copy of the same -code) is solved because the developer can create a specialized look +The first problem (having to use what amounts to a second copy of the same +code) is solved because the developer can create a specialized look and feel that can then be combined with other look and feels.

                      -The second problem (having to force the use of -a particular look and feel) is solved because a specialized look and feel -can be used with whatever default look and feel the +The second problem (having to force the use of +a particular look and feel) is solved because a specialized look and feel +can be used with whatever default look and feel the application may have locked in place.

                      -The default multiplexing look and feel implementation, +The default multiplexing look and feel implementation, represented by the MultiLookAndFeel class in the javax.swing.plaf.multi package, -is called (unsurprisingly) +is called (unsurprisingly) the Multiplexing look and feel. -

                      - -


                      - -How to Use Auxiliary Look and Feels - - +

                      + +


                      +

                      How to Use Auxiliary Look and Feels

                      -It's easy to use auxiliary look and feels with Swing. To instruct -Swing to use the Multiplexing look and feel, all an application +It's easy to use auxiliary look and feels with Swing. To instruct +Swing to use the Multiplexing look and feel, all an application has to do is modify the $JDKHOME/conf/swing.properties file to include a definition of the swing.auxiliarylaf property. Swing treats the swing.auxiliarylaf property as a comma-separated list of LookAndFeel -subclasses that specify what auxiliary look and feels should be -used in addition to the default look and feel. If at least one valid +subclasses that specify what auxiliary look and feels should be +used in addition to the default look and feel. If at least one valid LookAndFeel subclass is specified in the swing.auxiliarylaf -property, Swing automatically uses the Multiplexing look and feel +property, Swing automatically uses the Multiplexing look and feel to load and support the default and auxiliary look and feels.

                      -For example, let's assume that an application -makes use of a look and feel that supports text-to-speech feedback, and also +For example, let's assume that an application +makes use of a look and feel that supports text-to-speech feedback, and also uses an look and feel that adds support for a device that emits perfume. Let's assume that the text-to-speech -look and feel is named com.myco.TextTalkerLookAndFeel, +look and feel is named com.myco.TextTalkerLookAndFeel, and the look and feel that adds support for perfume is named com.smellco.OlfactoryLookAndFeel.

                      -To tell Swing to use both these look and feels --- and to use a default look and feel at the same time -- your application +To tell Swing to use both these look and feels +-- and to use a default look and feel at the same time -- your application could simply add the following line to the $JDKHOME/conf/swing.properties file:

                      -    +    swing.auxiliarylaf=com.myco.TextTalkerLookAndFeel,
                              com.smellco.OlfactoryLookAndFeel

                      -This statement tells Swing to obtain a component's UI from the Multiplexing -look and feel automatically, instead of obtaining it directly from -the default look and feel. The resulting multiplexing UI is a small -delegate that obtains and maintains UIs from the default and auxiliary -look and feels. As a result, when a method is invoked in a multiplexing -UI object, the multiplexing UI invokes the same method on each +This statement tells Swing to obtain a component's UI from the Multiplexing +look and feel automatically, instead of obtaining it directly from +the default look and feel. The resulting multiplexing UI is a small +delegate that obtains and maintains UIs from the default and auxiliary +look and feels. As a result, when a method is invoked in a multiplexing +UI object, the multiplexing UI invokes the same method on each of the UIs obtained from the default and auxiliary look and feels.

                      -

                      - -


                      - -Tips for Writing an Auxiliary Look and Feel - - +

                      + +


                      +

                      Tips for Writing an Auxiliary Look and Feel

                      An auxiliary look and feel is like any other look and feel, -except that it doesn't have to provide the complete support -that a default look and feel must. For -example, an auxiliary look and feel that supports just text-to-speech feedback -doesn't need to provide any code for painting. +except that it doesn't have to provide the complete support +that a default look and feel must. For +example, an auxiliary look and feel that supports just text-to-speech feedback +doesn't need to provide any code for painting. Also, it might not need to support all components -- JSeparators, for example, might be ignored.

                      Auxiliary look and feels tend to be simple, -so developing one can be easier than developing a visual +so developing one can be easier than developing a visual look and feel. -The developer can concentrate solely -on providing the specialized functionality. +The developer can concentrate solely +on providing the specialized functionality.

                      -Because the primary purpose of an auxiliary look and feel is to enhance the -default look and feel, auxiliary look and feels tend +Because the primary purpose of an auxiliary look and feel is to enhance the +default look and feel, auxiliary look and feels tend be nonvisual. Since an auxiliary look and feel is a genuine look and feel, however, there is nothing to prevent it from rendering information on the display. @@ -234,29 +246,26 @@ Just like for any other look and feel, you implement an auxiliary look and feel by writing a subclass of javax.swing.LookAndFeel -and creating subclasses of the +and creating subclasses of the FooUI classes defined in the javax.swing.plaf package.

                      -

                      -
                      - -Dos and Don'ts + +

                      Dos and Don'ts

                      -

                      -The following paragraphs provide some general recommendations for developing +The following paragraphs provide some general recommendations for developing auxiliary look and feels.

                      -Use the installUI method +

                      Use the installUI method to perform all initialization, and the uninstallUI method -to perform all cleanup. -

                      +to perform all cleanup.

                      +
                      The installUI and uninstallUI methods are invoked when a component's look and feel is set. @@ -265,142 +274,134 @@ Similarly, the uninstallUI method lets the previous UI object remove its listeners.
                      -

                      Don't extend - visual look and feels.

                      +

                      Don't extend visual look and feels.

                      - We recommended that you don't implement - UI classes of an auxiliary look and feel as subclasses of the - UI classes of a visual look and feel. Why not? Because they might - accidentally inherit code that installs listeners on a component - object or renders the component on the display. As a result, - your auxiliary look and feel would compete with the default look + We recommended that you don't implement + UI classes of an auxiliary look and feel as subclasses of the + UI classes of a visual look and feel. Why not? Because they might + accidentally inherit code that installs listeners on a component + object or renders the component on the display. As a result, + your auxiliary look and feel would compete with the default look and feel rather than cooperating with it.

                      - Instead, we recommend that the UI classes of an auxiliary look - and feel directly extend the abstract UI classes in the javax.swing.plaf - package. By using this strategy, the developer of an auxiliary + Instead, we recommend that the UI classes of an auxiliary look + and feel directly extend the abstract UI classes in the javax.swing.plaf + package. By using this strategy, the developer of an auxiliary look and feel can avoid competing with the default look and feel.
                      -

                      Override all UI-specific methods - your UI classes inherit. -

                      +

                      Override all UI-specific methods your UI classes inherit.

                      +
                      - We recommend that each UI class of - an auxiliary look and feel override the methods + We recommend that each UI class of + an auxiliary look and feel override the methods defined in the javax.swing.plaf UI classes it descends from - The reasons for this recommendation are similar + The reasons for this recommendation are similar to those for not extending a visual look and feel. For example, the ComponentUI class, from which all UI classes descend, provides a default implementation for the update method. This default implementation paints on the display - if the - component is opaque. If a UI class from a non-visual auxiliary - look and feel does not override this method, all + if the + component is opaque. If a UI class from a non-visual auxiliary + look and feel does not override this method, all opaque components appear as blank areas on the screen!
                      -

                      + + +

                      Extending UIDefaults

                      -
                      - -Extending UIDefaults - - -

                      In many cases, you - might want an auxiliary look and feel to be "incomplete." That - is, you might not need to support the complete set +

                      In many cases, you + might want an auxiliary look and feel to be "incomplete." That + is, you might not need to support the complete set of components. - For example, an auxiliary look and feel might choose - to provide a ButtonUI subclass but no + For example, an auxiliary look and feel might choose + to provide a ButtonUI subclass but no LabelUI subclass. - This - option is allowed, and the multiplexing look and feel gracefully + This + option is allowed, and the multiplexing look and feel gracefully handles such situations.

                      -

                      By default, however, Swing issues an error message when it asks - a look and feel for a UI object and the look and feel does not - support that UI. This message can be annoying, especially to auxiliary - look-and-feel developers who don't want to support a particular +

                      By default, however, Swing issues an error message when it asks + a look and feel for a UI object and the look and feel does not + support that UI. This message can be annoying, especially to auxiliary + look-and-feel developers who don't want to support a particular component.

                      -

                      Fortunately, you can prevent this error - message by creating a subclass of the UIDefaults - class and returning an instance of it from the +

                      Fortunately, you can prevent this error + message by creating a subclass of the UIDefaults + class and returning an instance of it from the getDefaults method of your LookAndFeel class. For example:

                      -

                      public class MyAuxLookAndFeel +

                      public class MyAuxLookAndFeel extends LookAndFeel {
                      -     ...
                      -     public UIDefaults getDefaults() {
                      -         UIDefaults table =
                      -             + ...
                      + public UIDefaults getDefaults() {
                      + UIDefaults table =
                      +             new MyAuxUIDefaults();
                      -
                              Object[] uiDefaults = {
                      -           "ButtonUI", "MyAuxButtonUI",
                      -           ...
                      -         }
                      -         table.putDefaults(uiDefaults);
                      -         return table;
                      -     }
                      +
                      Object[] uiDefaults = {
                      + "ButtonUI", "MyAuxButtonUI",
                      + ...
                      + }
                      + table.putDefaults(uiDefaults);
                      + return table;
                      + }
                      }

                      class MyAuxUIDefaults extends UIDefaults {
                      -     protected void getUIError(String msg) {
                      -         //System.err.println
                      -         //   ("An + protected void getUIError(String msg) {
                      + //System.err.println
                      +         //   ("An annoying message!");
                      -     }
                      + }
                      }

                      -In the preceding example, an auxiliary look and feel named MyAux - creates a UIDefaults subclass - that overrides the getUIError - method. The getUIError - method is the method that is invoked when Swing cannot find a UI - object in a look and feel. By merely doing nothing in this method, +In the preceding example, an auxiliary look and feel named MyAux + creates a UIDefaults subclass + that overrides the getUIError + method. The getUIError + method is the method that is invoked when Swing cannot find a UI + object in a look and feel. By merely doing nothing in this method, you can avoid the error message.

                      -

                      +

                      -
                      - -Examining Other UI Objects - + +

                      Examining Other UI Objects

                      -

                      In - rare instances, a UI object from an auxiliary look and feel - may be interested in the default UI object used by the component. In - these cases, the UI object from auxiliary look and feel can obtain +

                      In + rare instances, a UI object from an auxiliary look and feel + may be interested in the default UI object used by the component. In + these cases, the UI object from auxiliary look and feel can obtain the UI from a component by calling its getUI - method. The returned UI is an instance of one of the multiplexing - look and feel UI classes (for example, MultiButtonUI). - The UI object from the auxiliary look and feel can call the getUIs - method of the returned object to obtain an array containing a complete list - of all UI objects handled by the multiplexing UI. The first element + method. The returned UI is an instance of one of the multiplexing + look and feel UI classes (for example, MultiButtonUI). + The UI object from the auxiliary look and feel can call the getUIs + method of the returned object to obtain an array containing a complete list + of all UI objects handled by the multiplexing UI. The first element is guaranteed to be the UI created from the default look and feel.

                      -

                      - -


                      -How the Multiplexing Look and Feel -Is Implemented +

                      + +


                      +

                      How the Multiplexing Look and Feel Is Implemented

                      The Multiplexing look and feel (represented by javax.swing.plaf.multi.MultiLookAndFeel) -is meant to be transparent to -all developers and users. It should "just work" -- and - it is used only when the user tells Swing to use an auxiliary look +is meant to be transparent to +all developers and users. It should "just work" -- and + it is used only when the user tells Swing to use an auxiliary look and feel.

                      - When the Multiplexing look and - feel is in use, the type of the UI object - associated with each component - depends on whether + When the Multiplexing look and + feel is in use, the type of the UI object + associated with each component + depends on whether any of the auxiliary look and feels currently in use support the component. If so, the component's UI object is @@ -408,81 +409,80 @@ If only the default look and feel supports the component, then the component gets a UI object from the default look and feel, - just as if no auxiliary look and feels were installed. + just as if no auxiliary look and feels were installed.

                      A multiplexing UI object obtains and maintains UI objects from the default and auxiliary look and feels, - referring to these UIs in the following manner: + referring to these UIs in the following manner: -

                        -
                      • The UI object from the default look - and feel is always the first to be created. After that, a UI object - is created from each auxiliary look and feel in the order - they are specified in the swing.auxiliarylaf +
                          +
                        • The UI object from the default look + and feel is always the first to be created. After that, a UI object + is created from each auxiliary look and feel in the order + they are specified in the swing.auxiliarylaf property.

                        • -
                        • When a method that requests information - from a UI object is invoked, the multiplexing UI object - invokes the method on all the UI objects, but returns +
                        • When a method that requests information + from a UI object is invoked, the multiplexing UI object + invokes the method on all the UI objects, but returns only the results from the UI for the default look and feel. - For example, when the getPreferredSize - method is invoked on a multiplexing UI, the UI returns only the - results of invoking getPreferredSize + For example, when the getPreferredSize + method is invoked on a multiplexing UI, the UI returns only the + results of invoking getPreferredSize on the UI obtained from the default look and feel. The getPreferredSize method is also invoked on the UI object for each auxiliary look and feel, but the return values are ignored.

                        • -
                        • When a method that does not request information - from the UI object is invoked, the multiplexing UI object +
                        • When a method that does not request information + from the UI object is invoked, the multiplexing UI object invokes that method on all UIs -- on the UI object obtained from the default look and feel and on all the UIs obtained from the auxiliary look and feels, - as well. - For example, invoking the installUI - method on a multiplexing UI causes the multiplexing UI to invoke - installUI - on the UI obtained from the default look and feel and the UIs obtained from + as well. + For example, invoking the installUI + method on a multiplexing UI causes the multiplexing UI to invoke + installUI + on the UI obtained from the default look and feel and the UIs obtained from the auxiliary factories.
                        -

                        In all cases, the UI object obtained from - the default look and feel is acted upon first, and then the auxiliary - look and feels are acted upon in the order they are specified in - the swing.auxiliarylaf +

                        In all cases, the UI object obtained from + the default look and feel is acted upon first, and then the auxiliary + look and feels are acted upon in the order they are specified in + the swing.auxiliarylaf property.

                        -

                        +

                        - -


                        -How to Provide a Custom Multiplexing Look -and Feel + +
                        +

                        How to Provide a Custom Multiplexing Look and Feel

                        -

                        While - we hope the behavior of the Multiplexing look and feel is - flexible enough not to require an alternative multiplexing look - and feel, Swing allows the user to specify another multiplexing look +

                        While + we hope the behavior of the Multiplexing look and feel is + flexible enough not to require an alternative multiplexing look + and feel, Swing allows the user to specify another multiplexing look and feel to use.

                        -

                        To do that, all the user has to do is modify - the $JDKHOME/conf/swing.properties - file to include a definition of the swing.plaf.multiplexinglaf - property. Swing then treats the swing.plaf.multiplexinglaf - property as a LookAndFeel +

                        To do that, all the user has to do is modify + the $JDKHOME/conf/swing.properties + file to include a definition of the swing.plaf.multiplexinglaf + property. Swing then treats the swing.plaf.multiplexinglaf + property as a LookAndFeel subclass that supports multiplexing.

                        -

                        For example, if a user has a multiplexing - look and feel represented by com.myco.SuperMultiLookAndFeel - that is a better match for their needs than the Multiplexing - look and feel - (javax.swing.plaf.multi.MultiLookAndFeel), +

                        For example, if a user has a multiplexing + look and feel represented by com.myco.SuperMultiLookAndFeel + that is a better match for their needs than the Multiplexing + look and feel + (javax.swing.plaf.multi.MultiLookAndFeel), the user could include the following line in $JDKHOME/conf/swing.properties:

                        @@ -491,12 +491,12 @@

                        -This statement instructs Swing to use com.myco.SuperMultiLookAndFeel -instead of javax.swing.plaf.multi.MultiLookAndFeel. But -if you use this kind of statement, be careful, because the suppliers -of auxiliary look and feels will most likely have developed and +This statement instructs Swing to use com.myco.SuperMultiLookAndFeel +instead of javax.swing.plaf.multi.MultiLookAndFeel. But +if you use this kind of statement, be careful, because the suppliers +of auxiliary look and feels will most likely have developed and tested against our Multiplexing look and feel.

                        - - + + diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/javax/swing/plaf/nimbus/doc-files/properties.html --- a/src/java.desktop/share/classes/javax/swing/plaf/nimbus/doc-files/properties.html Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/javax/swing/plaf/nimbus/doc-files/properties.html Thu Dec 14 12:28:32 2017 +0000 @@ -1,8 +1,34 @@ - - + + - + + Nimbus colors + +

                        Primary Colors

                        diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/javax/swing/plaf/synth/doc-files/componentProperties.html --- a/src/java.desktop/share/classes/javax/swing/plaf/synth/doc-files/componentProperties.html Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/doc-files/componentProperties.html Thu Dec 14 12:28:32 2017 +0000 @@ -1,8 +1,11 @@ - - + + + + Component Specific Properties + ---> -

                        Component Specific Properties

                        The look, and to some degree the feel of Synth -can be customized by way of component specific properties. -These properties are accessed from SynthStyle#get. Refer to synth file format for examples of how to specify these properties in a synth configuration file.

                        -

                        + can be customized by way of component specific properties. + These properties are accessed from SynthStyle#get. Refer to synth file format for examples + of how to specify these properties in a synth configuration file.

                        +

                        This file specifies the expected class type each of the values are to take. The behavior of supplying the wrong type is unspecified: typically a ClassCastException is @@ -66,7 +70,7 @@


                        -

                        JButton

                        +

                        JButton

                        JButton paints text using the TEXT_FOREGROUND ColorType. In addition to the Button properties, JButton supports the following property:

                        @@ -89,7 +93,7 @@
                        -

                        JCheckBox

                        +

                        JCheckBox

                        JCheckBox paints text using the TEXT_FOREGROUND ColorType. In addition to the Button properties, JCheckBox supports the following property:

                        @@ -111,7 +115,7 @@
                        -

                        JComboBox

                        +

                        JComboBox

                        JComboBox is a composite component that consists of the following child Components:

                        @@ -144,7 +148,7 @@ - @@ -279,7 +283,7 @@ - + @@ -301,7 +305,7 @@ - + @@ -312,7 +316,7 @@ - + @@ -324,7 +328,7 @@ regular files list view, showing only an icon and the name of each file and directory. - + @@ -339,7 +343,7 @@
                        ComboBox.renderer Component The renderer used for the JComboBox. This is ONLY set if + The renderer used for the JComboBox. This is ONLY set if the renderer is a UIResource.
                        Icon used by the button that creates a new folder.
                        FileChooser.upFolderIcon
                        Icon used by the button that navigates to the current user's home directory.
                        FileChooser.detailsViewIcon
                        Icon used by the button that toggles the detailed files list view.
                        FileChooser.listViewIcon
                        FileChooser.viewMenuIcon

                        -

                        JInternalFrame

                        +

                        JInternalFrame

                        JInternalFrame Specific Properties
                        @@ -369,7 +373,7 @@

                        -

                        JInternalFrameTitlePane

                        +

                        JInternalFrameTitlePane

                        JInternalFrameTitlePane is the control bar located at the top of the internal frame similar to that found in a frame.

                        @@ -469,7 +473,7 @@
                        -

                        JList

                        +

                        JList

                        JList's sets the name of the renderer to List.renderer. JList supports the following properties:

                        JList Specific Properties
                        @@ -486,7 +490,7 @@ Boolean true If true the renderers state is not updated, and the text -colors come from JList's getSelectionBackground and +colors come from JList's getSelectionBackground and getSelectionForeground methods. If false, the renderer's state is updated and the colors will instead come from the Style. @@ -508,7 +512,7 @@
                        -

                        Menu Properties

                        +

                        Menu Properties

                        The Menu classes (JCheckBoxMenuItem, JMenu, JMenuItem, and JRadioButtonMenuItem) all support the same set of properties and behave similarly. Each component consists of two Regions: the region @@ -536,7 +540,7 @@ prefix.arrowIcon Icon null - Icon drawn to the right of the text (or left when the + Icon drawn to the right of the text (or left when the ComponentOrientation is right to left) of the text. This is typically only defined for JMenu. @@ -544,7 +548,7 @@ prefix.checkIcon Icon null - Icon drawn to the left of the text (or right when the + Icon drawn to the left of the text (or right when the ComponentOrientation is right to left) of the text. This is typically only defined for JCheckBoxMenuItem and JRadioButtonMenuItem to provide the check or radio button. @@ -561,7 +565,7 @@ prefix.textIconGap Integer 4 - Padding between the icon and text. Refer to the javadoc for + Padding between the icon and text. Refer to the javadoc for javax.swing.AbstractButton#setIconTextGap(int) for details of how this is used. @@ -593,7 +597,7 @@
                        -

                        JOptionPane

                        +

                        JOptionPane

                        JOptionPane is a composite component and may consist of numerous child components, they are: OptionPane.button, OptionPane.label, OptionPane.comboBox, OptionPane.scrollPane, OptionPane.list, @@ -623,7 +627,7 @@ OptionPane.buttonOrientation Integer SwingConstants.CENTER - How the buttons should be layed out, one of + How the buttons should be layed out, one of SwingConstants.LEFT, SwingConstants.RIGHT or SwingConstants.CENTER (this will be flipped when in a right to left locale). @@ -709,7 +713,7 @@
                        -

                        JProgressBar
                        +

                        JProgressBar

                        JProgressBar Specific Properties
                        @@ -749,7 +753,7 @@ -

                        JRadioButton

                        +

                        JRadioButton

                        JRadioButton paints text using the TEXT_FOREGROUND ColorType. In addition to the Button properties, JRadioButton supports the following property:

                        @@ -771,7 +775,7 @@
                        -

                        JScrollBar

                        +

                        JScrollBar

                        JScrollBar is a composite component that consists of the following child Components:

                        @@ -841,7 +845,7 @@

                        -

                        Separators

                        +

                        Separators

                        All of the separator classes, JSeparator, JPopupMenu.Separator and JToolBar.Separator use the same property:

                        @@ -856,7 +860,7 @@ - @@ -875,20 +879,21 @@ - - + +
                        Separator.thickness Integer 2 Preferred width, for vertically aligned separators, or + Preferred width, for vertically aligned separators, or preferred height for horizontally aligned separators. The resulting preferred size will include the Insets.
                        ToolBar.separatorSize Dimension null The value of this is passed to the javax.swing.JToolBar$Separator#setSeparatorSize(java.awt.Dimension) -method. If unspecified setSeparatorSize is not -invoked.
                        The value of this is passed to the + javax.swing.JToolBar$Separator#setSeparatorSize(java.awt.Dimension) + method. If unspecified setSeparatorSize is not invoked. +

                        -

                        JScrollPane

                        -

                        +

                        JScrollPane

                        +

                        JScrollPane is unique in that it provides a method for setting the Border around the JViewport with JViewport throwing an IllegalArgumentException from setBorder. To accommodate this a special border is installed on the - JScrollPane that uses the + JScrollPane that uses the insets from the key ScrollPane.viewportBorderInsets. The SynthPainter method @@ -913,7 +918,7 @@
                        -

                        JSplitPane

                        +

                        JSplitPane

                        JSplitPane is a composite component that will contain a divider and potentially two buttons, if setOneTouchExpandable(true) has been invoked. The two buttons will be named: @@ -950,7 +955,7 @@ SplitPane.oneTouchExpandable Boolean null - If non null, the value of this is passed to + If non null, the value of this is passed to setOneTouchExpandable. @@ -962,7 +967,7 @@
                        -

                        JSlider

                        +

                        JSlider

                        JSlider Specific Properties
                        @@ -1022,7 +1027,7 @@

                        -

                        JTabbedPane

                        +

                        JTabbedPane

                        JTabbedPane Specific Properties
                        @@ -1084,8 +1089,8 @@

                        -

                        JTable

                        -

                        JTable sets the name of the renderer to Table.cellRenderer. +

                        JTable

                        +

                        JTable sets the name of the renderer to Table.cellRenderer. JTable supports the following properties:

                        JTable Specific Properties
                        @@ -1108,7 +1113,7 @@ @@ -1116,7 +1121,7 @@ - @@ -1129,7 +1134,7 @@
                        Boolean true If true the renderers state is not updated, and the text -colors come from JTable's getSelectionBackground and +colors come from JTable's getSelectionBackground and getSelectionForeground methods. If false, the renderer's state is updated and the colors will instead come from the Style.
                        Table.rendererUseUIBorder Boolean true If true setBorder on the renderer will succeed + If true setBorder on the renderer will succeed regardless of the border passed in, otherwise setBorder on the renderer will only succeed if it is a Synth Border.

                        -

                        JTree

                        +

                        JTree

                        JTree sets the name of the renderer to Tree.renderer, the name of the editor is Tree.cellEditor.

                        JTree Specific Properties
                        @@ -1151,7 +1156,7 @@ Tree.drawHorizontalLines Boolean true - If true nodes have a horizontal connecting them to the + If true nodes have a horizontal connecting them to the leading edge of their parent. @@ -1198,7 +1203,7 @@ Tree.scrollsOnExpand Boolean true - Whether or not the JTree should scroll when a node is + Whether or not the JTree should scroll when a node is expanded. @@ -1212,7 +1217,7 @@ -

                        JToggleButton

                        +

                        JToggleButton

                        JToggleButton paints text using the TEXT_FOREGROUND ColorType. In addition to the Button properties, JToggleButton supports the following property:

                        @@ -1234,7 +1239,7 @@
                        -

                        Button Properties

                        +

                        Button Properties

                        Each of the Button classes (JButton, JCheckBox, JRadioButton, JToggleButton and SynthArrowButton) support a similar set of properties. These properties are:

                        @@ -1250,23 +1255,29 @@ prefix.contentAreaFilled Integer true - Refer to the javadoc of javax.swing.AbstractButton#contentAreaFilled(boolean) for details -of how this is used. It is up to the Painter to properly honor this -property. - + Refer to the javadoc of + javax.swing.AbstractButton#contentAreaFilled(boolean) + for details of how this is used. It is up to the Painter to properly honor + this property. + + prefix.iconTextGap Integer - If unspecified, JButton.setIconTextGap is not invoked. - Padding between the icon and text. Refer to the javadoc of javax.swing.AbstractButton#setIconTextGap(int) for details of how -this is used. + If unspecified, JButton.setIconTextGap is not invoked. + Padding between the icon and text. Refer to the javadoc of + javax.swing.AbstractButton#setIconTextGap(int) + for details of how this is used. + prefix.margin Insets Empty Insets (0, 0, 0, 0) - Margin for the JButton. Refer to the javadoc of javax.swing.AbstractButton#setMargin(java.awt.Insets) for details -of how the margin is used. + Margin for the JButton. Refer to the javadoc of + javax.swing.AbstractButton#setMargin(java.awt.Insets) for + details of how the margin is used. + prefix.textShiftOffset @@ -1281,7 +1292,7 @@

                        Prefix is one of: Button, CheckBox, RadioButton or JToggleButton.

                        -

                        Text Properties
                        +

                        Text Properties

                        diff -r 907bddce488c -r b6ff245c0db6 src/java.desktop/share/classes/javax/swing/plaf/synth/doc-files/synthFileFormat.html --- a/src/java.desktop/share/classes/javax/swing/plaf/synth/doc-files/synthFileFormat.html Mon Dec 11 16:43:11 2017 +0000 +++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/doc-files/synthFileFormat.html Thu Dec 14 12:28:32 2017 +0000 @@ -1,7 +1,33 @@ - - - - Synth File Format + + + + + Synth File Format + +