This commit is contained in:
Jesper Wilhelmsson 2017-01-24 00:30:25 +01:00
commit 9400d2bd29
613 changed files with 21126 additions and 12323 deletions

View File

@ -394,3 +394,5 @@ f4e854a77aa38749bd90f722b06974a56e7233d5 jdk-9+147
cf139f925da04c8bd7efd33270a0315d72b338d3 jdk-9+149
17469f16fbb406ec9f0dd262ce776ab6efbc38f1 jdk-9+150
37b95df0042ae0687324e1f7dc4a2519e230e704 jdk-9+151
ab2c8b03c3284fcbdd157551a66f807e3a182d9b jdk-9+152
d7034ff7f8e257e81c9f95c7785dd4eaaa3c2afc jdk-9+153

View File

@ -394,3 +394,5 @@ a22e2671d88f6b22a4aa82e3966986542ed2a381 jdk-9+146
b119012d1c2ab2570fe8718633840d0c1f1f441d jdk-9+149
6234069ff9789f7582e1faa32cb6283cbd1a5a2d jdk-9+150
71a766d4c18041a7f833ee22823125b02e1a7f1e jdk-9+151
ef056360ddf3977d7d2ddbeb456a4d612d19ea05 jdk-9+152
816a6d03a7c44edfbd8780110529f1bdc3964fb9 jdk-9+153

View File

@ -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
@ -1011,6 +1011,8 @@ AC_DEFUN([BASIC_CHECK_TAR],
# Test which kind of tar was found
if test "x$($TAR --version | $GREP "GNU tar")" != "x"; then
TAR_TYPE="gnu"
elif test "x$($TAR --version | $GREP "bsdtar")" != "x"; then
TAR_TYPE="bsd"
elif test "x$($TAR -v | $GREP "bsdtar")" != "x"; then
TAR_TYPE="bsd"
elif test "x$OPENJDK_BUILD_OS" = "xsolaris"; then
@ -1038,12 +1040,36 @@ AC_DEFUN([BASIC_CHECK_TAR],
AC_SUBST(TAR_SUPPORTS_TRANSFORM)
])
AC_DEFUN([BASIC_CHECK_GREP],
[
# Test that grep supports -Fx with a list of pattern which includes null pattern.
# This is a problem for the grep resident on AIX.
AC_MSG_CHECKING([that grep ($GREP) -Fx handles empty lines in the pattern list correctly])
# Multiple subsequent spaces..
STACK_SPACES='aaa bbb ccc'
# ..converted to subsequent newlines, causes STACK_LIST to be a list with some empty
# patterns in it.
STACK_LIST=${STACK_SPACES// /$'\n'}
NEEDLE_SPACES='ccc bbb aaa'
NEEDLE_LIST=${NEEDLE_SPACES// /$'\n'}
RESULT="$($GREP -Fvx "$STACK_LIST" <<< "$NEEDLE_LIST")"
if test "x$RESULT" == "x"; then
AC_MSG_RESULT([yes])
else
if test "x$OPENJDK_TARGET_OS" = "xaix"; then
ADDINFO="Please make sure you use GNU grep, usually found at /opt/freeware/bin."
fi
AC_MSG_ERROR([grep does not handle -Fx correctly. ${ADDINFO}])
fi
])
AC_DEFUN_ONCE([BASIC_SETUP_COMPLEX_TOOLS],
[
BASIC_CHECK_GNU_MAKE
BASIC_CHECK_FIND_DELETE
BASIC_CHECK_TAR
BASIC_CHECK_GREP
# These tools might not be installed by default,
# need hint on how to install them.

View File

@ -68,7 +68,6 @@ LDFLAGS_JDKLIB := @OPENJDK_BUILD_LDFLAGS_JDKLIB@
CFLAGS_JDKEXE := @OPENJDK_BUILD_CFLAGS_JDKEXE@
CXXFLAGS_JDKEXE := @OPENJDK_BUILD_CXXFLAGS_JDKEXE@
LDFLAGS_JDKEXE := @OPENJDK_BUILD_LDFLAGS_JDKEXE@
OPENJDK_TARGET_CPU_JLI_CFLAGS := @OPENJDK_BUILD_CPU_JLI_CFLAGS@
JVM_CFLAGS := @OPENJDK_BUILD_JVM_CFLAGS@
JVM_LDFLAGS := @OPENJDK_BUILD_JVM_LDFLAGS@

View File

@ -815,11 +815,6 @@ AC_DEFUN([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER],
$2CXXFLAGS_JDK="${$2CXXFLAGS_JDK} -D__solaris__"
fi
if test "x$OPENJDK_TARGET_OS" = xsolaris; then
$2CFLAGS_JDK="${$2CFLAGS_JDK} -D__solaris__"
$2CXXFLAGS_JDK="${$2CXXFLAGS_JDK} -D__solaris__"
fi
$2CFLAGS_JDK="${$2CFLAGS_JDK} ${$2EXTRA_CFLAGS}"
$2CXXFLAGS_JDK="${$2CXXFLAGS_JDK} ${$2EXTRA_CXXFLAGS}"
$2LDFLAGS_JDK="${$2LDFLAGS_JDK} ${$2EXTRA_LDFLAGS}"

View File

@ -3564,7 +3564,7 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
# Include these first...
#
# 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
@ -3731,6 +3731,8 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
# Check if build directory is on local disk. If not possible to determine,
# we prefer to claim it's local.
# Argument 1: directory to test
@ -4122,7 +4124,7 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
#
# 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
@ -4237,6 +4239,17 @@ yum_help() {
esac
}
brew_help() {
case $1 in
openjdk)
PKGHANDLER_COMMAND="brew cask install java" ;;
freetype)
PKGHANDLER_COMMAND="brew install freetype" ;;
ccache)
PKGHANDLER_COMMAND="brew install ccache" ;;
esac
}
port_help() {
PKGHANDLER_COMMAND=""
}
@ -4362,7 +4375,7 @@ VALID_JVM_VARIANTS="server client minimal core zero zeroshark custom"
#
# 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
@ -4667,7 +4680,7 @@ VALID_JVM_VARIANTS="server client minimal core zero zeroshark custom"
#
# 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
@ -5167,7 +5180,7 @@ VS_SDK_PLATFORM_NAME_2013=
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
DATE_WHEN_GENERATED=1483542685
DATE_WHEN_GENERATED=1484571183
###############################################################################
#
@ -17544,7 +17557,7 @@ $as_echo "$as_me: The path of OUTPUT_ROOT, which resolves as \"$path\", is inval
# Must be done before we can call HELP_MSG_MISSING_DEPENDENCY.
for ac_prog in apt-get yum port pkgutil pkgadd
for ac_prog in apt-get yum brew port pkgutil pkgadd
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
@ -21209,6 +21222,8 @@ $as_echo "yes" >&6; }
# Test which kind of tar was found
if test "x$($TAR --version | $GREP "GNU tar")" != "x"; then
TAR_TYPE="gnu"
elif test "x$($TAR --version | $GREP "bsdtar")" != "x"; then
TAR_TYPE="bsd"
elif test "x$($TAR -v | $GREP "bsdtar")" != "x"; then
TAR_TYPE="bsd"
elif test "x$OPENJDK_BUILD_OS" = "xsolaris"; then
@ -21238,6 +21253,29 @@ $as_echo "$TAR_TYPE" >&6; }
# Test that grep supports -Fx with a list of pattern which includes null pattern.
# This is a problem for the grep resident on AIX.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that grep ($GREP) -Fx handles empty lines in the pattern list correctly" >&5
$as_echo_n "checking that grep ($GREP) -Fx handles empty lines in the pattern list correctly... " >&6; }
# Multiple subsequent spaces..
STACK_SPACES='aaa bbb ccc'
# ..converted to subsequent newlines, causes STACK_LIST to be a list with some empty
# patterns in it.
STACK_LIST=${STACK_SPACES// /$'\n'}
NEEDLE_SPACES='ccc bbb aaa'
NEEDLE_LIST=${NEEDLE_SPACES// /$'\n'}
RESULT="$($GREP -Fvx "$STACK_LIST" <<< "$NEEDLE_LIST")"
if test "x$RESULT" == "x"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
if test "x$OPENJDK_TARGET_OS" = "xaix"; then
ADDINFO="Please make sure you use GNU grep, usually found at /opt/freeware/bin."
fi
as_fn_error $? "grep does not handle -Fx correctly. ${ADDINFO}" "$LINENO" 5
fi
# These tools might not be installed by default,
# need hint on how to install them.
@ -24359,15 +24397,13 @@ if test "${enable_keep_packaged_modules+set}" = set; then :
fi
if test "x$enable_keep_packaged_modules" = "xyes"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if packaged modules are kept" >&5
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if packaged modules are kept" >&5
$as_echo_n "checking if packaged modules are kept... " >&6; }
if test "x$enable_keep_packaged_modules" = "xyes"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
JLINK_KEEP_PACKAGED_MODULES=true
elif test "x$enable_keep_packaged_modules" = "xno"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if packaged modules are kept" >&5
$as_echo_n "checking if packaged modules are kept... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
JLINK_KEEP_PACKAGED_MODULES=false
@ -24376,6 +24412,8 @@ $as_echo "no" >&6; }
$as_echo "yes (default)" >&6; }
JLINK_KEEP_PACKAGED_MODULES=true
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: error" >&5
$as_echo "error" >&6; }
as_fn_error $? "--enable-keep-packaged-modules accepts no argument" "$LINENO" 5
fi
@ -29942,6 +29980,8 @@ $as_echo "$BOOT_JDK_VERSION" >&6; }
apt_help $MISSING_DEPENDENCY ;;
yum)
yum_help $MISSING_DEPENDENCY ;;
brew)
brew_help $MISSING_DEPENDENCY ;;
port)
port_help $MISSING_DEPENDENCY ;;
pkgutil)
@ -33235,6 +33275,8 @@ done
apt_help $MISSING_DEPENDENCY ;;
yum)
yum_help $MISSING_DEPENDENCY ;;
brew)
brew_help $MISSING_DEPENDENCY ;;
port)
port_help $MISSING_DEPENDENCY ;;
pkgutil)
@ -34534,6 +34576,8 @@ done
apt_help $MISSING_DEPENDENCY ;;
yum)
yum_help $MISSING_DEPENDENCY ;;
brew)
brew_help $MISSING_DEPENDENCY ;;
port)
port_help $MISSING_DEPENDENCY ;;
pkgutil)
@ -48601,6 +48645,8 @@ $as_echo "$as_me: Failed to compile stdio.h. This likely implies missing compile
apt_help $MISSING_DEPENDENCY ;;
yum)
yum_help $MISSING_DEPENDENCY ;;
brew)
brew_help $MISSING_DEPENDENCY ;;
port)
port_help $MISSING_DEPENDENCY ;;
pkgutil)
@ -48762,6 +48808,8 @@ $as_echo "$as_me: The tested number of bits in the target ($TESTED_TARGET_CPU_BI
apt_help $MISSING_DEPENDENCY ;;
yum)
yum_help $MISSING_DEPENDENCY ;;
brew)
brew_help $MISSING_DEPENDENCY ;;
port)
port_help $MISSING_DEPENDENCY ;;
pkgutil)
@ -49897,11 +49945,6 @@ $as_echo "$supports" >&6; }
CXXFLAGS_JDK="${CXXFLAGS_JDK} -D__solaris__"
fi
if test "x$OPENJDK_TARGET_OS" = xsolaris; then
CFLAGS_JDK="${CFLAGS_JDK} -D__solaris__"
CXXFLAGS_JDK="${CXXFLAGS_JDK} -D__solaris__"
fi
CFLAGS_JDK="${CFLAGS_JDK} ${EXTRA_CFLAGS}"
CXXFLAGS_JDK="${CXXFLAGS_JDK} ${EXTRA_CXXFLAGS}"
LDFLAGS_JDK="${LDFLAGS_JDK} ${EXTRA_LDFLAGS}"
@ -50720,11 +50763,6 @@ $as_echo "$supports" >&6; }
OPENJDK_BUILD_CXXFLAGS_JDK="${OPENJDK_BUILD_CXXFLAGS_JDK} -D__solaris__"
fi
if test "x$OPENJDK_TARGET_OS" = xsolaris; then
OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -D__solaris__"
OPENJDK_BUILD_CXXFLAGS_JDK="${OPENJDK_BUILD_CXXFLAGS_JDK} -D__solaris__"
fi
OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} ${OPENJDK_BUILD_EXTRA_CFLAGS}"
OPENJDK_BUILD_CXXFLAGS_JDK="${OPENJDK_BUILD_CXXFLAGS_JDK} ${OPENJDK_BUILD_EXTRA_CXXFLAGS}"
OPENJDK_BUILD_LDFLAGS_JDK="${OPENJDK_BUILD_LDFLAGS_JDK} ${OPENJDK_BUILD_EXTRA_LDFLAGS}"
@ -52844,6 +52882,8 @@ $as_echo "no, missing dependencies" >&6; }
apt_help $MISSING_DEPENDENCY ;;
yum)
yum_help $MISSING_DEPENDENCY ;;
brew)
brew_help $MISSING_DEPENDENCY ;;
port)
port_help $MISSING_DEPENDENCY ;;
pkgutil)
@ -56649,6 +56689,8 @@ fi
apt_help $MISSING_DEPENDENCY ;;
yum)
yum_help $MISSING_DEPENDENCY ;;
brew)
brew_help $MISSING_DEPENDENCY ;;
port)
port_help $MISSING_DEPENDENCY ;;
pkgutil)
@ -56721,6 +56763,8 @@ done
apt_help $MISSING_DEPENDENCY ;;
yum)
yum_help $MISSING_DEPENDENCY ;;
brew)
brew_help $MISSING_DEPENDENCY ;;
port)
port_help $MISSING_DEPENDENCY ;;
pkgutil)
@ -56864,6 +56908,8 @@ done
apt_help $MISSING_DEPENDENCY ;;
yum)
yum_help $MISSING_DEPENDENCY ;;
brew)
brew_help $MISSING_DEPENDENCY ;;
port)
port_help $MISSING_DEPENDENCY ;;
pkgutil)
@ -60683,6 +60729,345 @@ $as_echo "$as_me: Rewriting POTENTIAL_FREETYPE_LIB_PATH to \"$new_path\"" >&6;}
fi
windows_path="$new_path"
if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
unix_path=`$CYGPATH -u "$windows_path"`
new_path="$unix_path"
elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
new_path="$unix_path"
fi
if test "x$path" != "x$new_path"; then
POTENTIAL_FREETYPE_LIB_PATH="$new_path"
{ $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting POTENTIAL_FREETYPE_LIB_PATH to \"$new_path\"" >&5
$as_echo "$as_me: Rewriting POTENTIAL_FREETYPE_LIB_PATH to \"$new_path\"" >&6;}
fi
# Save the first 10 bytes of this path to the storage, so fixpath can work.
all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}")
else
# We're on a unix platform. Hooray! :)
path="$POTENTIAL_FREETYPE_LIB_PATH"
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
# Use eval to expand a potential ~
eval path="$path"
if test ! -f "$path" && test ! -d "$path"; then
as_fn_error $? "The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$path\", is not found." "$LINENO" 5
fi
if test -d "$path"; then
POTENTIAL_FREETYPE_LIB_PATH="`cd "$path"; $THEPWDCMD -L`"
else
dir="`$DIRNAME "$path"`"
base="`$BASENAME "$path"`"
POTENTIAL_FREETYPE_LIB_PATH="`cd "$dir"; $THEPWDCMD -L`/$base"
fi
fi
fi
FREETYPE_INCLUDE_PATH="$POTENTIAL_FREETYPE_INCLUDE_PATH"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for freetype includes" >&5
$as_echo_n "checking for freetype includes... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $FREETYPE_INCLUDE_PATH" >&5
$as_echo "$FREETYPE_INCLUDE_PATH" >&6; }
FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for freetype libraries" >&5
$as_echo_n "checking for freetype libraries... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $FREETYPE_LIB_PATH" >&5
$as_echo "$FREETYPE_LIB_PATH" >&6; }
fi
fi
if test "x$FOUND_FREETYPE" != xyes; then
FREETYPE_BASE_DIR="$SYSROOT/usr/local"
POTENTIAL_FREETYPE_INCLUDE_PATH="$FREETYPE_BASE_DIR/include"
POTENTIAL_FREETYPE_LIB_PATH="$FREETYPE_BASE_DIR/lib"
METHOD="well-known location"
# Let's start with an optimistic view of the world :-)
FOUND_FREETYPE=yes
# First look for the canonical freetype main include file ft2build.h.
if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then
# Oh no! Let's try in the freetype2 directory. This is needed at least at Mac OS X Yosemite.
POTENTIAL_FREETYPE_INCLUDE_PATH="$POTENTIAL_FREETYPE_INCLUDE_PATH/freetype2"
if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then
# Fail.
FOUND_FREETYPE=no
fi
fi
if test "x$FOUND_FREETYPE" = xyes; then
# Include file found, let's continue the sanity check.
{ $as_echo "$as_me:${as_lineno-$LINENO}: Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD" >&5
$as_echo "$as_me: Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD" >&6;}
# Reset to default value
FREETYPE_BASE_NAME=freetype
FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}"
if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME"; then
if test "x$OPENJDK_TARGET_OS" = xmacosx \
&& test -s "$POTENTIAL_FREETYPE_LIB_PATH/${LIBRARY_PREFIX}freetype.6${SHARED_LIBRARY_SUFFIX}"; then
# On Mac OS X Yosemite, the symlink from libfreetype.dylib to libfreetype.6.dylib disappeared. Check
# for the .6 version explicitly.
FREETYPE_BASE_NAME=freetype.6
FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}"
{ $as_echo "$as_me:${as_lineno-$LINENO}: Compensating for missing symlink by using version 6 explicitly" >&5
$as_echo "$as_me: Compensating for missing symlink by using version 6 explicitly" >&6;}
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&5
$as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&6;}
FOUND_FREETYPE=no
fi
else
if test "x$OPENJDK_TARGET_OS" = xwindows; then
# On Windows, we will need both .lib and .dll file.
if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location." >&5
$as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location." >&6;}
FOUND_FREETYPE=no
fi
elif test "x$OPENJDK_TARGET_OS" = xsolaris \
&& test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then
# Found lib in isa dir, use that instead.
POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR"
{ $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead" >&5
$as_echo "$as_me: Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead" >&6;}
fi
fi
fi
if test "x$FOUND_FREETYPE" = xyes; then
# Only process if variable expands to non-empty
if test "x$POTENTIAL_FREETYPE_INCLUDE_PATH" != x; then
if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
# Input might be given as Windows format, start by converting to
# unix format.
path="$POTENTIAL_FREETYPE_INCLUDE_PATH"
new_path=`$CYGPATH -u "$path"`
# Cygwin tries to hide some aspects of the Windows file system, such that binaries are
# named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
# This test is therefore slightly more accurate than "test -f" to check for file precense.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Cannot locate the the path of POTENTIAL_FREETYPE_INCLUDE_PATH" "$LINENO" 5
fi
# Call helper function which possibly converts this using DOS-style short mode.
# If so, the updated path is stored in $new_path.
input_path="$new_path"
# Check if we need to convert this using DOS-style short mode. If the path
# contains just simple characters, use it. Otherwise (spaces, weird characters),
# take no chances and rewrite it.
# Note: m4 eats our [], so we need to use [ and ] instead.
has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]`
if test "x$has_forbidden_chars" != x; then
# Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
shortmode_path=`$CYGPATH -s -m -a "$input_path"`
path_after_shortmode=`$CYGPATH -u "$shortmode_path"`
if test "x$path_after_shortmode" != "x$input_to_shortpath"; then
# Going to short mode and back again did indeed matter. Since short mode is
# case insensitive, let's make it lowercase to improve readability.
shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
# Now convert it back to Unix-style (cygpath)
input_path=`$CYGPATH -u "$shortmode_path"`
new_path="$input_path"
fi
fi
test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/`
if test "x$test_cygdrive_prefix" = x; then
# As a simple fix, exclude /usr/bin since it's not a real path.
if test "x`$ECHO $new_path | $GREP ^/usr/bin/`" = x; then
# The path is in a Cygwin special directory (e.g. /home). We need this converted to
# a path prefixed by /cygdrive for fixpath to work.
new_path="$CYGWIN_ROOT_PATH$input_path"
fi
fi
if test "x$path" != "x$new_path"; then
POTENTIAL_FREETYPE_INCLUDE_PATH="$new_path"
{ $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting POTENTIAL_FREETYPE_INCLUDE_PATH to \"$new_path\"" >&5
$as_echo "$as_me: Rewriting POTENTIAL_FREETYPE_INCLUDE_PATH to \"$new_path\"" >&6;}
fi
elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
path="$POTENTIAL_FREETYPE_INCLUDE_PATH"
has_colon=`$ECHO $path | $GREP ^.:`
new_path="$path"
if test "x$has_colon" = x; then
# Not in mixed or Windows style, start by that.
new_path=`cmd //c echo $path`
fi
input_path="$new_path"
# Check if we need to convert this using DOS-style short mode. If the path
# contains just simple characters, use it. Otherwise (spaces, weird characters),
# take no chances and rewrite it.
# Note: m4 eats our [], so we need to use [ and ] instead.
has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]`
if test "x$has_forbidden_chars" != x; then
# Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
fi
windows_path="$new_path"
if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
unix_path=`$CYGPATH -u "$windows_path"`
new_path="$unix_path"
elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
new_path="$unix_path"
fi
if test "x$path" != "x$new_path"; then
POTENTIAL_FREETYPE_INCLUDE_PATH="$new_path"
{ $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting POTENTIAL_FREETYPE_INCLUDE_PATH to \"$new_path\"" >&5
$as_echo "$as_me: Rewriting POTENTIAL_FREETYPE_INCLUDE_PATH to \"$new_path\"" >&6;}
fi
# Save the first 10 bytes of this path to the storage, so fixpath can work.
all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}")
else
# We're on a unix platform. Hooray! :)
path="$POTENTIAL_FREETYPE_INCLUDE_PATH"
has_space=`$ECHO "$path" | $GREP " "`
if test "x$has_space" != x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
fi
# Use eval to expand a potential ~
eval path="$path"
if test ! -f "$path" && test ! -d "$path"; then
as_fn_error $? "The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as \"$path\", is not found." "$LINENO" 5
fi
if test -d "$path"; then
POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`"
else
dir="`$DIRNAME "$path"`"
base="`$BASENAME "$path"`"
POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$dir"; $THEPWDCMD -L`/$base"
fi
fi
fi
# Only process if variable expands to non-empty
if test "x$POTENTIAL_FREETYPE_LIB_PATH" != x; then
if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
# Input might be given as Windows format, start by converting to
# unix format.
path="$POTENTIAL_FREETYPE_LIB_PATH"
new_path=`$CYGPATH -u "$path"`
# Cygwin tries to hide some aspects of the Windows file system, such that binaries are
# named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
# "foo.exe" is OK but "foo" is an error.
#
# This test is therefore slightly more accurate than "test -f" to check for file precense.
# It is also a way to make sure we got the proper file name for the real test later on.
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$path\", is invalid." >&5
$as_echo "$as_me: The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$path\", is invalid." >&6;}
as_fn_error $? "Cannot locate the the path of POTENTIAL_FREETYPE_LIB_PATH" "$LINENO" 5
fi
# Call helper function which possibly converts this using DOS-style short mode.
# If so, the updated path is stored in $new_path.
input_path="$new_path"
# Check if we need to convert this using DOS-style short mode. If the path
# contains just simple characters, use it. Otherwise (spaces, weird characters),
# take no chances and rewrite it.
# Note: m4 eats our [], so we need to use [ and ] instead.
has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]`
if test "x$has_forbidden_chars" != x; then
# Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
shortmode_path=`$CYGPATH -s -m -a "$input_path"`
path_after_shortmode=`$CYGPATH -u "$shortmode_path"`
if test "x$path_after_shortmode" != "x$input_to_shortpath"; then
# Going to short mode and back again did indeed matter. Since short mode is
# case insensitive, let's make it lowercase to improve readability.
shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
# Now convert it back to Unix-style (cygpath)
input_path=`$CYGPATH -u "$shortmode_path"`
new_path="$input_path"
fi
fi
test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/`
if test "x$test_cygdrive_prefix" = x; then
# As a simple fix, exclude /usr/bin since it's not a real path.
if test "x`$ECHO $new_path | $GREP ^/usr/bin/`" = x; then
# The path is in a Cygwin special directory (e.g. /home). We need this converted to
# a path prefixed by /cygdrive for fixpath to work.
new_path="$CYGWIN_ROOT_PATH$input_path"
fi
fi
if test "x$path" != "x$new_path"; then
POTENTIAL_FREETYPE_LIB_PATH="$new_path"
{ $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting POTENTIAL_FREETYPE_LIB_PATH to \"$new_path\"" >&5
$as_echo "$as_me: Rewriting POTENTIAL_FREETYPE_LIB_PATH to \"$new_path\"" >&6;}
fi
elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
path="$POTENTIAL_FREETYPE_LIB_PATH"
has_colon=`$ECHO $path | $GREP ^.:`
new_path="$path"
if test "x$has_colon" = x; then
# Not in mixed or Windows style, start by that.
new_path=`cmd //c echo $path`
fi
input_path="$new_path"
# Check if we need to convert this using DOS-style short mode. If the path
# contains just simple characters, use it. Otherwise (spaces, weird characters),
# take no chances and rewrite it.
# Note: m4 eats our [], so we need to use [ and ] instead.
has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]`
if test "x$has_forbidden_chars" != x; then
# Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
fi
windows_path="$new_path"
if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
unix_path=`$CYGPATH -u "$windows_path"`
@ -62122,6 +62507,8 @@ $as_echo "$FREETYPE_LIB_PATH" >&6; }
apt_help $MISSING_DEPENDENCY ;;
yum)
yum_help $MISSING_DEPENDENCY ;;
brew)
brew_help $MISSING_DEPENDENCY ;;
port)
port_help $MISSING_DEPENDENCY ;;
pkgutil)
@ -62477,6 +62864,8 @@ $as_echo "$as_me: Using FREETYPE_CFLAGS=$FREETYPE_CFLAGS and FREETYPE_LIBS=$FREE
apt_help $MISSING_DEPENDENCY ;;
yum)
yum_help $MISSING_DEPENDENCY ;;
brew)
brew_help $MISSING_DEPENDENCY ;;
port)
port_help $MISSING_DEPENDENCY ;;
pkgutil)
@ -62682,6 +63071,8 @@ done
apt_help $MISSING_DEPENDENCY ;;
yum)
yum_help $MISSING_DEPENDENCY ;;
brew)
brew_help $MISSING_DEPENDENCY ;;
port)
port_help $MISSING_DEPENDENCY ;;
pkgutil)
@ -62870,6 +63261,8 @@ done
apt_help $MISSING_DEPENDENCY ;;
yum)
yum_help $MISSING_DEPENDENCY ;;
brew)
brew_help $MISSING_DEPENDENCY ;;
port)
port_help $MISSING_DEPENDENCY ;;
pkgutil)
@ -62949,6 +63342,8 @@ $as_echo "$LIBFFI_WORKS" >&6; }
apt_help $MISSING_DEPENDENCY ;;
yum)
yum_help $MISSING_DEPENDENCY ;;
brew)
brew_help $MISSING_DEPENDENCY ;;
port)
port_help $MISSING_DEPENDENCY ;;
pkgutil)
@ -64058,6 +64453,8 @@ done
apt_help $MISSING_DEPENDENCY ;;
yum)
yum_help $MISSING_DEPENDENCY ;;
brew)
brew_help $MISSING_DEPENDENCY ;;
port)
port_help $MISSING_DEPENDENCY ;;
pkgutil)
@ -64142,6 +64539,8 @@ $as_echo "$LIBELF_WORKS" >&6; }
apt_help $MISSING_DEPENDENCY ;;
yum)
yum_help $MISSING_DEPENDENCY ;;
brew)
brew_help $MISSING_DEPENDENCY ;;
port)
port_help $MISSING_DEPENDENCY ;;
pkgutil)

View File

@ -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
@ -25,7 +25,7 @@
AC_DEFUN_ONCE([HELP_SETUP_DEPENDENCY_HELP],
[
AC_CHECK_PROGS(PKGHANDLER, apt-get yum port pkgutil pkgadd)
AC_CHECK_PROGS(PKGHANDLER, apt-get yum brew port pkgutil pkgadd)
])
AC_DEFUN([HELP_MSG_MISSING_DEPENDENCY],
@ -46,6 +46,8 @@ AC_DEFUN([HELP_MSG_MISSING_DEPENDENCY],
apt_help $MISSING_DEPENDENCY ;;
yum)
yum_help $MISSING_DEPENDENCY ;;
brew)
brew_help $MISSING_DEPENDENCY ;;
port)
port_help $MISSING_DEPENDENCY ;;
pkgutil)
@ -147,6 +149,17 @@ yum_help() {
esac
}
brew_help() {
case $1 in
openjdk)
PKGHANDLER_COMMAND="brew cask install java" ;;
freetype)
PKGHANDLER_COMMAND="brew install freetype" ;;
ccache)
PKGHANDLER_COMMAND="brew install ccache" ;;
esac
}
port_help() {
PKGHANDLER_COMMAND=""
}

View File

@ -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
@ -382,18 +382,18 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_JLINK_OPTIONS],
AC_ARG_ENABLE([keep-packaged-modules], [AS_HELP_STRING([--disable-keep-packaged-modules],
[Do not keep packaged modules in jdk image @<:@enable@:>@])])
AC_MSG_CHECKING([if packaged modules are kept])
if test "x$enable_keep_packaged_modules" = "xyes"; then
AC_MSG_CHECKING([if packaged modules are kept])
AC_MSG_RESULT([yes])
JLINK_KEEP_PACKAGED_MODULES=true
elif test "x$enable_keep_packaged_modules" = "xno"; then
AC_MSG_CHECKING([if packaged modules are kept])
AC_MSG_RESULT([no])
JLINK_KEEP_PACKAGED_MODULES=false
elif test "x$enable_keep_packaged_modules" = "x"; then
AC_MSG_RESULT([yes (default)])
JLINK_KEEP_PACKAGED_MODULES=true
else
AC_MSG_RESULT([error])
AC_MSG_ERROR([--enable-keep-packaged-modules accepts no argument])
fi

View File

@ -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
@ -348,6 +348,10 @@ AC_DEFUN_ONCE([LIB_SETUP_FREETYPE],
FREETYPE_BASE_DIR="$SYSROOT/usr/X11"
LIB_CHECK_POTENTIAL_FREETYPE([$FREETYPE_BASE_DIR/include], [$FREETYPE_BASE_DIR/lib], [well-known location])
fi
if test "x$FOUND_FREETYPE" != xyes; then
FREETYPE_BASE_DIR="$SYSROOT/usr/local"
LIB_CHECK_POTENTIAL_FREETYPE([$FREETYPE_BASE_DIR/include], [$FREETYPE_BASE_DIR/lib], [well-known location])
fi
if test "x$OPENJDK_TARGET_OS" = xmacosx; then
if test "x$FOUND_FREETYPE" != xyes; then

View File

@ -274,8 +274,6 @@ JAVADOC_OUTPUTDIR = $(DOCS_IMAGE_DIR)
CONFIGURESUPPORT_OUTPUTDIR:=@CONFIGURESUPPORT_OUTPUTDIR@
BUILDJDK_OUTPUTDIR=$(BUILD_OUTPUT)/buildjdk
BUILD_HOTSPOT=@BUILD_HOTSPOT@
BUILD_FAILURE_HANDLER := @BUILD_FAILURE_HANDLER@
ENABLE_GENERATE_CLASSLIST := @ENABLE_GENERATE_CLASSLIST@
@ -642,7 +640,6 @@ NAWK:=@NAWK@
NICE:=@NICE@
PATCH:=@PATCH@
PRINTF:=@PRINTF@
PWD:=@THEPWDCMD@
RM:=@RM@
RMDIR:=@RMDIR@
SED:=@SED@
@ -778,11 +775,18 @@ OS_VERSION_MICRO:=@OS_VERSION_MICRO@
# Images directory definitions
JDK_IMAGE_SUBDIR:=jdk
JRE_IMAGE_SUBDIR:=jre
JRE_COMPACT1_IMAGE_SUBDIR := jre-compact1
JRE_COMPACT2_IMAGE_SUBDIR := jre-compact2
JRE_COMPACT3_IMAGE_SUBDIR := jre-compact3
# Colon left out to be able to override output dir for bootcycle-images
JDK_IMAGE_DIR=$(IMAGES_OUTPUTDIR)/$(JDK_IMAGE_SUBDIR)
JRE_IMAGE_DIR=$(IMAGES_OUTPUTDIR)/$(JRE_IMAGE_SUBDIR)
JRE_COMPACT1_IMAGE_DIR := $(IMAGES_OUTPUTDIR)/$(JRE_COMPACT1_IMAGE_SUBDIR)
JRE_COMPACT2_IMAGE_DIR := $(IMAGES_OUTPUTDIR)/$(JRE_COMPACT2_IMAGE_SUBDIR)
JRE_COMPACT3_IMAGE_DIR := $(IMAGES_OUTPUTDIR)/$(JRE_COMPACT3_IMAGE_SUBDIR)
# Test image, as above
TEST_IMAGE_SUBDIR:=test
TEST_IMAGE_DIR=$(IMAGES_OUTPUTDIR)/$(TEST_IMAGE_SUBDIR)
@ -818,6 +822,12 @@ else ifneq ($(DEBUG_LEVEL), release)
endif
JDK_BUNDLE_NAME := jdk-$(BASE_NAME)_bin$(DEBUG_PART).tar.gz
JRE_BUNDLE_NAME := jre-$(BASE_NAME)_bin$(DEBUG_PART).tar.gz
JRE_COMPACT1_BUNDLE_NAME := \
jre-$(VERSION_SHORT)+$(VERSION_BUILD)-compact1_$(OPENJDK_TARGET_BUNDLE_PLATFORM)_bin$(DEBUG_PART).tar.gz
JRE_COMPACT2_BUNDLE_NAME := \
jre-$(VERSION_SHORT)+$(VERSION_BUILD)-compact2_$(OPENJDK_TARGET_BUNDLE_PLATFORM)_bin$(DEBUG_PART).tar.gz
JRE_COMPACT3_BUNDLE_NAME := \
jre-$(VERSION_SHORT)+$(VERSION_BUILD)-compact3_$(OPENJDK_TARGET_BUNDLE_PLATFORM)_bin$(DEBUG_PART).tar.gz
JDK_SYMBOLS_BUNDLE_NAME := jdk-$(BASE_NAME)_bin$(DEBUG_PART)-symbols.tar.gz
JRE_SYMBOLS_BUNDLE_NAME := jre-$(BASE_NAME)_bin$(DEBUG_PART)-symbols.tar.gz
ifeq ($(OPENJDK_TARGET_OS), windows)

View File

@ -501,7 +501,7 @@ var getJibProfilesProfiles = function (input, common, data) {
// extra default target.
var openOnlyProfilesExtra = {
"linux-x86-open": {
default_make_targets: "profiles",
default_make_targets: "profiles-bundles",
configure_args: "--with-jvm-variants=client,server"
}
};
@ -587,6 +587,7 @@ var getJibProfilesProfiles = function (input, common, data) {
],
work_dir: input.get("src.full", "install_path") + "/test",
environment: {
"JT_JAVA": common.boot_jdk_home,
"PRODUCT_HOME": input.get(testedProfile + ".jdk", "home_path"),
"TEST_IMAGE_DIR": input.get(testedProfile + ".test", "home_path"),
"TEST_OUTPUT_DIR": input.src_top_dir
@ -710,10 +711,15 @@ var getJibProfilesProfiles = function (input, common, data) {
local: "bundles/\\(jdk.*bin.tar.gz\\)",
remote: "bundles/openjdk/GPL/profile/linux-x86/\\1",
},
jre: {
local: "bundles/\\(jre.*[0-9]_linux-x86_bin.tar.gz\\)",
jdk_symbols: {
local: "bundles/\\(jdk.*bin-symbols.tar.gz\\)",
remote: "bundles/openjdk/GPL/profile/linux-x86/\\1",
},/* The build does not create these
},
jre: {
// This regexp needs to not match the compact* files below
local: "bundles/\\(jre.*[+][0-9]\\{1,\\}_linux-x86_bin.tar.gz\\)",
remote: "bundles/openjdk/GPL/profile/linux-x86/\\1",
},
jre_compact1: {
local: "bundles/\\(jre.*-compact1_linux-x86_bin.tar.gz\\)",
remote: "bundles/openjdk/GPL/profile/linux-x86/\\1",
@ -725,7 +731,7 @@ var getJibProfilesProfiles = function (input, common, data) {
jre_compact3: {
local: "bundles/\\(jre.*-compact3_linux-x86_bin.tar.gz\\)",
remote: "bundles/openjdk/GPL/profile/linux-x86/\\1",
},*/
},
}
},
@ -864,7 +870,7 @@ var getJibProfilesDependencies = function (input, common) {
jtreg: {
server: "javare",
revision: "4.2",
build_number: "b04",
build_number: "b05",
checksum_file: "MD5_VALUES",
file: "jtreg_bin-4.2.zip",
environment_name: "JT_HOME",

View File

@ -394,3 +394,5 @@ f95cc86b6ac22ec1ade5d4f825dc7782adeea228 jdk-9+148
00b19338e505690abe93d5995ed74a473d969c2c jdk-9+149
9205e980062a5c4530b51021c6e274025f4ccbdf jdk-9+150
77f827f5bbad3ef795664bc675f72d98d156b9f8 jdk-9+151
ff8cb43c07c069b1debdee44cb88ca22db1ec757 jdk-9+152
68a8e8658511093b322a46ed04b2a321e1da2a43 jdk-9+153

View File

@ -554,3 +554,5 @@ a82cb5350cad96a0b4de496afebe3ded89f27efa jdk-9+146
30e1996bd55da36183434f24ed964adebf9ca71e jdk-9+149
98fe046473c90204cbc9b34c512b9fc10dfb8479 jdk-9+150
2a2ac7d9f52c8cb2b80077e515b5840b947e640c jdk-9+151
31f1d26c60df7b2e516a4f84160d76ba017d4e09 jdk-9+152
217ba81b9a4ce8698200370175aa2db86a39f66c jdk-9+153

View File

@ -394,3 +394,5 @@ c45db75bfe8bc20bb80b4a009ae3f69c9cd2d885 jdk-9+148
5978df8bfa3894f2b3d07b7256f25f78dffb1f9c jdk-9+149
f85154af719f99a3b4d81b67a8b4c18a650d10f9 jdk-9+150
13c6906bfc861d99dc35a19c80b7a99f0b0ac58d jdk-9+151
7e3da313b1746578da648155e37dd8526e83153d jdk-9+152
1384504d2cd0e55c5e0becaeaf40ab05cae959d6 jdk-9+153

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@ -17,20 +17,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* $Id: DOM2SAX.java,v 1.2.4.1 2005/09/06 11:52:46 pvedula Exp $
*/
package com.sun.org.apache.xalan.internal.xsltc.trax;
import com.sun.org.apache.xalan.internal.xsltc.dom.SAXImpl;
import com.sun.org.apache.xalan.internal.xsltc.runtime.BasisLibrary;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import java.util.Vector;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.xml.sax.ContentHandler;
@ -58,7 +54,7 @@ public class DOM2SAX implements XMLReader, Locator {
private ContentHandler _sax = null;
private LexicalHandler _lex = null;
private SAXImpl _saxImpl = null;
private Map<String, Stack> _nsPrefixes = new HashMap<>();
private Map<String, Stack<String>> _nsPrefixes = new HashMap<>();
public DOM2SAX(Node root) {
_dom = root;
@ -73,7 +69,7 @@ public class DOM2SAX implements XMLReader, Locator {
{
_sax = handler;
if (handler instanceof LexicalHandler) {
_lex = (LexicalHandler) handler;
_lex = (LexicalHandler)handler;
}
if (handler instanceof SAXImpl) {
@ -90,25 +86,22 @@ public class DOM2SAX implements XMLReader, Locator {
throws SAXException
{
boolean pushed = true;
Stack uriStack = _nsPrefixes.get(prefix);
Stack<String> uriStack = _nsPrefixes.get(prefix);
if (uriStack != null) {
if (uriStack.isEmpty()) {
_sax.startPrefixMapping(prefix, uri);
uriStack.push(uri);
}
else {
final String lastUri = (String) uriStack.peek();
} else {
final String lastUri = uriStack.peek();
if (!lastUri.equals(uri)) {
_sax.startPrefixMapping(prefix, uri);
uriStack.push(uri);
}
else {
} else {
pushed = false;
}
}
}
else {
} else {
_sax.startPrefixMapping(prefix, uri);
_nsPrefixes.put(prefix, uriStack = new Stack());
uriStack.push(uri);
@ -123,7 +116,7 @@ public class DOM2SAX implements XMLReader, Locator {
private void endPrefixMapping(String prefix)
throws SAXException
{
final Stack uriStack = _nsPrefixes.get(prefix);
final Stack<String> uriStack = _nsPrefixes.get(prefix);
if (uriStack != null) {
_sax.endPrefixMapping(prefix);
@ -131,22 +124,6 @@ public class DOM2SAX implements XMLReader, Locator {
}
}
/**
* If the DOM was created using a DOM 1.0 API, the local name may be
* null. If so, get the local name from the qualified name before
* generating the SAX event.
*/
private static String getLocalName(Node node) {
final String localName = node.getLocalName();
if (localName == null) {
final String qname = node.getNodeName();
final int col = qname.lastIndexOf(':');
return (col > 0) ? qname.substring(col + 1) : qname;
}
return localName;
}
public void parse(InputSource unused) throws IOException, SAXException {
parse(_dom);
}
@ -173,8 +150,8 @@ public class DOM2SAX implements XMLReader, Locator {
* declarations.
*/
private void parse(Node node) throws IOException, SAXException {
Node first = null;
if (node == null) return;
if (node == null)
return;
switch (node.getNodeType()) {
case Node.ATTRIBUTE_NODE: // handled by ELEMENT_NODE
@ -198,7 +175,6 @@ public class DOM2SAX implements XMLReader, Locator {
_sax.characters(cdata.toCharArray(), 0, cdata.length());
}
break;
case Node.COMMENT_NODE: // should be handled!!!
if (_lex != null) {
final String value = node.getNodeValue();
@ -216,10 +192,9 @@ public class DOM2SAX implements XMLReader, Locator {
}
_sax.endDocument();
break;
case Node.ELEMENT_NODE:
String prefix;
Vector pushedPrefixes = new Vector();
ArrayList<String> pushedPrefixes = new ArrayList<>();
final AttributesImpl attrs = new AttributesImpl();
final NamedNodeMap map = node.getAttributes();
final int length = map.getLength();
@ -235,7 +210,7 @@ public class DOM2SAX implements XMLReader, Locator {
final int colon = qnameAttr.lastIndexOf(':');
prefix = (colon > 0) ? qnameAttr.substring(colon + 1) : EMPTYSTRING;
if (startPrefixMapping(prefix, uriAttr)) {
pushedPrefixes.addElement(prefix);
pushedPrefixes.add(prefix);
}
}
}
@ -248,27 +223,25 @@ public class DOM2SAX implements XMLReader, Locator {
// Ignore NS declarations here
if (!qnameAttr.startsWith(XMLNS_PREFIX)) {
final String uriAttr = attr.getNamespaceURI();
final String localNameAttr = getLocalName(attr);
// Uri may be implicitly declared
if (uriAttr != null) {
final int colon = qnameAttr.lastIndexOf(':');
if (colon > 0) {
prefix = qnameAttr.substring(0, colon);
}
else {
} else {
// If no prefix for this attr, we need to create
// one because we cannot use the default ns
prefix = BasisLibrary.generatePrefix();
qnameAttr = prefix + ':' + qnameAttr;
}
if (startPrefixMapping(prefix, uriAttr)) {
pushedPrefixes.addElement(prefix);
pushedPrefixes.add(prefix);
}
}
// Add attribute to list
attrs.addAttribute(attr.getNamespaceURI(), getLocalName(attr),
attrs.addAttribute(attr.getNamespaceURI(), attr.getLocalName(),
qnameAttr, "CDATA", attr.getNodeValue());
}
}
@ -276,22 +249,21 @@ public class DOM2SAX implements XMLReader, Locator {
// Now process the element itself
final String qname = node.getNodeName();
final String uri = node.getNamespaceURI();
final String localName = getLocalName(node);
final String localName = node.getLocalName();
// Uri may be implicitly declared
// URI may be implicitly declared
if (uri != null) {
final int colon = qname.lastIndexOf(':');
prefix = (colon > 0) ? qname.substring(0, colon) : EMPTYSTRING;
if (startPrefixMapping(prefix, uri)) {
pushedPrefixes.addElement(prefix);
pushedPrefixes.add(prefix);
}
}
// Generate SAX event to start element
if (_saxImpl != null) {
_saxImpl.startElement(uri, localName, qname, attrs, node);
}
else {
} else {
_sax.startElement(uri, localName, qname, attrs);
}
@ -308,15 +280,13 @@ public class DOM2SAX implements XMLReader, Locator {
// Generate endPrefixMapping() for all pushed prefixes
final int nPushedPrefixes = pushedPrefixes.size();
for (int i = 0; i < nPushedPrefixes; i++) {
endPrefixMapping((String) pushedPrefixes.elementAt(i));
endPrefixMapping(pushedPrefixes.get(i));
}
break;
case Node.PROCESSING_INSTRUCTION_NODE:
_sax.processingInstruction(node.getNodeName(),
node.getNodeValue());
break;
case Node.TEXT_NODE:
final String data = node.getNodeValue();
_sax.characters(data.toCharArray(), 0, data.length());
@ -449,36 +419,4 @@ public class DOM2SAX implements XMLReader, Locator {
public String getSystemId() {
return null;
}
// Debugging
private String getNodeTypeFromCode(short code) {
String retval = null;
switch (code) {
case Node.ATTRIBUTE_NODE :
retval = "ATTRIBUTE_NODE"; break;
case Node.CDATA_SECTION_NODE :
retval = "CDATA_SECTION_NODE"; break;
case Node.COMMENT_NODE :
retval = "COMMENT_NODE"; break;
case Node.DOCUMENT_FRAGMENT_NODE :
retval = "DOCUMENT_FRAGMENT_NODE"; break;
case Node.DOCUMENT_NODE :
retval = "DOCUMENT_NODE"; break;
case Node.DOCUMENT_TYPE_NODE :
retval = "DOCUMENT_TYPE_NODE"; break;
case Node.ELEMENT_NODE :
retval = "ELEMENT_NODE"; break;
case Node.ENTITY_NODE :
retval = "ENTITY_NODE"; break;
case Node.ENTITY_REFERENCE_NODE :
retval = "ENTITY_REFERENCE_NODE"; break;
case Node.NOTATION_NODE :
retval = "NOTATION_NODE"; break;
case Node.PROCESSING_INSTRUCTION_NODE :
retval = "PROCESSING_INSTRUCTION_NODE"; break;
case Node.TEXT_NODE:
retval = "TEXT_NODE"; break;
}
return retval;
}
}

View File

@ -1,13 +1,13 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Copyright 1999-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
@ -17,13 +17,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* $Id: SAX2DTM2.java,v 1.2.4.1 2005/09/15 08:15:12 suresh_emailid Exp $
*/
package com.sun.org.apache.xml.internal.dtm.ref.sax2dtm;
import com.sun.org.apache.xml.internal.dtm.*;
import com.sun.org.apache.xml.internal.dtm.ref.*;
import com.sun.org.apache.xml.internal.dtm.DTM;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.dtm.DTMException;
import com.sun.org.apache.xml.internal.dtm.DTMManager;
import com.sun.org.apache.xml.internal.dtm.DTMWSFilter;
import com.sun.org.apache.xml.internal.dtm.ref.DTMDefaultBase;
import com.sun.org.apache.xml.internal.dtm.ref.ExpandedNameTable;
import com.sun.org.apache.xml.internal.dtm.ref.ExtendedType;
import com.sun.org.apache.xml.internal.utils.FastStringBuffer;
import com.sun.org.apache.xml.internal.utils.XMLString;
import com.sun.org.apache.xml.internal.utils.XMLStringDefault;
@ -31,11 +35,12 @@ import com.sun.org.apache.xml.internal.utils.XMLStringFactory;
import com.sun.org.apache.xml.internal.res.XMLMessages;
import com.sun.org.apache.xml.internal.res.XMLErrorResources;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import javax.xml.transform.Source;
import java.util.Vector;
import com.sun.org.apache.xml.internal.utils.SuballocatedIntVector;
import org.xml.sax.*;
import java.util.ArrayList;
import javax.xml.transform.Source;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
/**
* SAX2DTM2 is an optimized version of SAX2DTM which is used in non-incremental situation.
@ -53,10 +58,6 @@ import org.xml.sax.*;
* The design of SAX2DTM2 may limit its extensibilty. If you have a reason to extend the
* SAX2DTM model, please extend from SAX2DTM instead of this class.
* <p>
* TODO: This class is currently only used by XSLTC. We need to investigate the possibility
* of also using it in Xalan-J Interpretive. Xalan's performance is likely to get an instant
* boost if we use SAX2DTM2 instead of SAX2DTM in non-incremental case.
* <p>
* %MK% The code in this class is critical to the XSLTC_DTM performance. Be very careful
* when making changes here!
*/
@ -87,11 +88,10 @@ public class SAX2DTM2 extends SAX2DTM
*/
public DTMAxisIterator setStartNode(int node)
{
//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
if (node == DTMDefaultBase.ROOTNODE)
node = getDocument();
if (_isRestartable)
{
if (_isRestartable) {
_startNode = node;
_currentNode = (node == DTM.NULL) ? DTM.NULL
: _firstch2(makeNodeIdentity(node));
@ -108,8 +108,7 @@ public class SAX2DTM2 extends SAX2DTM
* @return The next node handle in the iteration, or END if no more
* are available.
*/
public int next()
{
public int next() {
if (_currentNode != NULL) {
int node = _currentNode;
_currentNode = _nextsib2(node);
@ -139,13 +138,11 @@ public class SAX2DTM2 extends SAX2DTM
*
* @return A DTMAxisIterator set to the start of the iteration.
*/
public DTMAxisIterator setStartNode(int node)
{
//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
public DTMAxisIterator setStartNode(int node) {
//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
if (node == DTMDefaultBase.ROOTNODE)
node = getDocument();
if (_isRestartable)
{
if (_isRestartable) {
_startNode = node;
if (node != DTM.NULL)
@ -229,8 +226,7 @@ public class SAX2DTM2 extends SAX2DTM
*
* @param nodeType The extended type ID being requested.
*/
public TypedChildrenIterator(int nodeType)
{
public TypedChildrenIterator(int nodeType) {
_nodeType = nodeType;
}
@ -242,17 +238,14 @@ public class SAX2DTM2 extends SAX2DTM
*
* @return A DTMAxisIterator set to the start of the iteration.
*/
public DTMAxisIterator setStartNode(int node)
{
//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
public DTMAxisIterator setStartNode(int node) {
//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
if (node == DTMDefaultBase.ROOTNODE)
node = getDocument();
if (_isRestartable)
{
if (_isRestartable) {
_startNode = node;
_currentNode = (node == DTM.NULL)
? DTM.NULL
: _firstch2(makeNodeIdentity(_startNode));
_currentNode = (node == DTM.NULL) ? DTM.NULL :
_firstch2(makeNodeIdentity(_startNode));
return resetPosition();
}
@ -265,8 +258,7 @@ public class SAX2DTM2 extends SAX2DTM
*
* @return The next node handle in the iteration, or END.
*/
public int next()
{
public int next() {
int node = _currentNode;
if (node == DTM.NULL)
return DTM.NULL;
@ -301,14 +293,12 @@ public class SAX2DTM2 extends SAX2DTM
_currentNode = _nextsib2(node);
return returnNode(makeNodeHandle(node));
}
}
/**
* Return the node at the given position.
*/
public int getNodeByPosition(int position)
{
public int getNodeByPosition(int position) {
if (position <= 0)
return DTM.NULL;
@ -327,8 +317,7 @@ public class SAX2DTM2 extends SAX2DTM
node = _nextsib2(node);
}
return NULL;
}
else {
} else {
while (node != DTM.NULL) {
if (_exptype2(node) >= DTM.NTYPES) {
pos++;
@ -415,13 +404,11 @@ public class SAX2DTM2 extends SAX2DTM
*
* @return A DTMAxisIterator set to the start of the iteration.
*/
public DTMAxisIterator setStartNode(int node)
{
//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
public DTMAxisIterator setStartNode(int node) {
//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
if (node == DTMDefaultBase.ROOTNODE)
node = getDocument();
if (_isRestartable)
{
if (_isRestartable) {
_startNode = node;
_currentNode = makeNodeIdentity(node);
@ -436,8 +423,7 @@ public class SAX2DTM2 extends SAX2DTM
*
* @return The next node handle in the iteration, or END.
*/
public int next()
{
public int next() {
_currentNode = (_currentNode == DTM.NULL) ? DTM.NULL
: _nextsib2(_currentNode);
return returnNode(makeNodeHandle(_currentNode));
@ -460,8 +446,7 @@ public class SAX2DTM2 extends SAX2DTM
*
* @param type The extended type ID being requested.
*/
public TypedFollowingSiblingIterator(int type)
{
public TypedFollowingSiblingIterator(int type) {
_nodeType = type;
}
@ -470,8 +455,7 @@ public class SAX2DTM2 extends SAX2DTM
*
* @return The next node handle in the iteration, or END.
*/
public int next()
{
public int next() {
if (_currentNode == DTM.NULL) {
return DTM.NULL;
}
@ -481,8 +465,7 @@ public class SAX2DTM2 extends SAX2DTM
if (nodeType != DTM.ELEMENT_NODE) {
while ((node = _nextsib2(node)) != DTM.NULL && _exptype2(node) != nodeType) {}
}
else {
} else {
while ((node = _nextsib2(node)) != DTM.NULL && _exptype2(node) < DTM.NTYPES) {}
}
@ -498,8 +481,7 @@ public class SAX2DTM2 extends SAX2DTM
/**
* Iterator that returns attribute nodes (of what nodes?)
*/
public final class AttributeIterator extends InternalAxisIteratorBase
{
public final class AttributeIterator extends InternalAxisIteratorBase {
// assumes caller will pass element nodes
@ -511,13 +493,11 @@ public class SAX2DTM2 extends SAX2DTM
*
* @return A DTMAxisIterator set to the start of the iteration.
*/
public DTMAxisIterator setStartNode(int node)
{
//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
public DTMAxisIterator setStartNode(int node) {
//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
if (node == DTMDefaultBase.ROOTNODE)
node = getDocument();
if (_isRestartable)
{
if (_isRestartable) {
_startNode = node;
_currentNode = getFirstAttributeIdentity(makeNodeIdentity(node));
@ -532,9 +512,7 @@ public class SAX2DTM2 extends SAX2DTM
*
* @return The next node handle in the iteration, or END.
*/
public int next()
{
public int next() {
final int node = _currentNode;
if (node != NULL) {
@ -561,8 +539,7 @@ public class SAX2DTM2 extends SAX2DTM
*
* @param nodeType The extended type ID that is requested.
*/
public TypedAttributeIterator(int nodeType)
{
public TypedAttributeIterator(int nodeType) {
_nodeType = nodeType;
}
@ -576,14 +553,10 @@ public class SAX2DTM2 extends SAX2DTM
*
* @return A DTMAxisIterator set to the start of the iteration.
*/
public DTMAxisIterator setStartNode(int node)
{
if (_isRestartable)
{
public DTMAxisIterator setStartNode(int node) {
if (_isRestartable) {
_startNode = node;
_currentNode = getTypedAttribute(node, _nodeType);
return resetPosition();
}
@ -595,9 +568,7 @@ public class SAX2DTM2 extends SAX2DTM
*
* @return The next node handle in the iteration, or END.
*/
public int next()
{
public int next() {
final int node = _currentNode;
// singleton iterator, since there can only be one attribute of
@ -624,8 +595,7 @@ public class SAX2DTM2 extends SAX2DTM
*
* @return true.
*/
public boolean isReverse()
{
public boolean isReverse() {
return true;
}
@ -637,30 +607,25 @@ public class SAX2DTM2 extends SAX2DTM
*
* @return A DTMAxisIterator set to the start of the iteration.
*/
public DTMAxisIterator setStartNode(int node)
{
//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
public DTMAxisIterator setStartNode(int node) {
//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
if (node == DTMDefaultBase.ROOTNODE)
node = getDocument();
if (_isRestartable)
{
if (_isRestartable) {
_startNode = node;
node = _startNodeID = makeNodeIdentity(node);
if(node == NULL)
{
if(node == NULL) {
_currentNode = node;
return resetPosition();
}
int type = _type2(node);
if(ExpandedNameTable.ATTRIBUTE == type
|| ExpandedNameTable.NAMESPACE == type )
if (ExpandedNameTable.ATTRIBUTE == type ||
ExpandedNameTable.NAMESPACE == type)
{
_currentNode = node;
}
else
{
} else {
// Be careful to handle the Document node properly
_currentNode = _parent2(node);
if(NULL!=_currentNode)
@ -680,18 +645,12 @@ public class SAX2DTM2 extends SAX2DTM
*
* @return The next node handle in the iteration, or END.
*/
public int next()
{
if (_currentNode == _startNodeID || _currentNode == DTM.NULL)
{
public int next() {
if (_currentNode == _startNodeID || _currentNode == DTM.NULL) {
return NULL;
}
else
{
} else {
final int node = _currentNode;
_currentNode = _nextsib2(node);
return returnNode(makeNodeHandle(node));
}
}
@ -714,8 +673,7 @@ public class SAX2DTM2 extends SAX2DTM
*
* @param type The extended type ID being requested.
*/
public TypedPrecedingSiblingIterator(int type)
{
public TypedPrecedingSiblingIterator(int type) {
_nodeType = type;
}
@ -724,8 +682,7 @@ public class SAX2DTM2 extends SAX2DTM
*
* @return The next node handle in the iteration, or END.
*/
public int next()
{
public int next() {
int node = _currentNode;
final int nodeType = _nodeType;
@ -735,8 +692,7 @@ public class SAX2DTM2 extends SAX2DTM
while (node != NULL && node != startNodeID && _exptype2(node) != nodeType) {
node = _nextsib2(node);
}
}
else {
} else {
while (node != NULL && node != startNodeID && _exptype2(node) < DTM.NTYPES) {
node = _nextsib2(node);
}
@ -745,8 +701,7 @@ public class SAX2DTM2 extends SAX2DTM
if (node == DTM.NULL || node == startNodeID) {
_currentNode = NULL;
return NULL;
}
else {
} else {
_currentNode = _nextsib2(node);
return returnNode(makeNodeHandle(node));
}
@ -755,8 +710,7 @@ public class SAX2DTM2 extends SAX2DTM
/**
* Return the index of the last node in this iterator.
*/
public int getLast()
{
public int getLast() {
if (_last != -1)
return _last;
@ -774,8 +728,7 @@ public class SAX2DTM2 extends SAX2DTM
}
node = _nextsib2(node);
}
}
else {
} else {
while (node != NULL && node != startNodeID) {
if (_exptype2(node) >= DTM.NTYPES) {
last++;
@ -860,7 +813,7 @@ public class SAX2DTM2 extends SAX2DTM
*/
public DTMAxisIterator setStartNode(int node)
{
//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
if (node == DTMDefaultBase.ROOTNODE)
node = getDocument();
if (_isRestartable)
@ -1799,9 +1752,7 @@ public class SAX2DTM2 extends SAX2DTM
// %OPT% These values are unlikely to be equal. Storing
// them in a plain Vector is more efficient than storing in the
// DTMStringPool because we can save the cost for hash calculation.
//
// %REVISIT% Do we need a custom class (e.g. StringVector) here?
protected Vector m_values;
protected ArrayList<String> m_values;
// The current index into the m_values Vector.
private int m_valueIndex = 0;
@ -1881,9 +1832,8 @@ public class SAX2DTM2 extends SAX2DTM
m_buildIdIndex = buildIdIndex;
// Some documents do not have attribute nodes. That is why
// we set the initial size of this Vector to be small and set
// the increment to a bigger number.
m_values = new Vector(32, 512);
// we set the initial size of this ArrayList to be small.
m_values = new ArrayList<>(32);
m_maxNodeIndex = 1 << DTMManager.IDENT_DTM_NODE_BITS;
@ -1953,10 +1903,7 @@ public class SAX2DTM2 extends SAX2DTM
* @param identity A node identity, which <em>must not</em> be equal to
* <code>DTM.NULL</code>
*/
public final int _firstch2(int identity)
{
//return m_firstch.elementAt(identity);
public final int _firstch2(int identity) {
if (identity < m_blocksize)
return m_firstch_map0[identity];
else
@ -1969,10 +1916,7 @@ public class SAX2DTM2 extends SAX2DTM
* @param identity A node identity, which <em>must not</em> be equal to
* <code>DTM.NULL</code>
*/
public final int _parent2(int identity)
{
//return m_parent.elementAt(identity);
public final int _parent2(int identity) {
if (identity < m_blocksize)
return m_parent_map0[identity];
else
@ -1985,9 +1929,7 @@ public class SAX2DTM2 extends SAX2DTM
* @param identity A node identity, which <em>must not</em> be equal to
* <code>DTM.NULL</code>
*/
public final int _type2(int identity)
{
//int eType = _exptype2(identity);
public final int _type2(int identity) {
int eType;
if (identity < m_blocksize)
eType = m_exptype_map0[identity];
@ -2006,12 +1948,9 @@ public class SAX2DTM2 extends SAX2DTM
* <p>This one is only used by DOMAdapter.getExpandedTypeID(int), which
* is mostly called from the compiled translets.
*/
public final int getExpandedTypeID2(int nodeHandle)
{
public final int getExpandedTypeID2(int nodeHandle) {
int nodeID = makeNodeIdentity(nodeHandle);
//return (nodeID != NULL) ? _exptype2(nodeID) : NULL;
if (nodeID != NULL) {
if (nodeID < m_blocksize)
return m_exptype_map0[nodeID];
@ -2026,12 +1965,10 @@ public class SAX2DTM2 extends SAX2DTM
* END of DTM base accessor interfaces
*************************************************************************/
/**
* Return the node type from the expanded type
*/
public final int _exptype2Type(int exptype)
{
public final int _exptype2Type(int exptype) {
if (NULL != exptype)
return m_extendedTypes[exptype].getNodeType();
else
@ -2046,16 +1983,14 @@ public class SAX2DTM2 extends SAX2DTM
*
* @return The prefix if there is one, or null.
*/
public int getIdForNamespace(String uri)
{
public int getIdForNamespace(String uri) {
int index = m_values.indexOf(uri);
if (index < 0)
{
m_values.addElement(uri);
if (index < 0) {
m_values.add(uri);
return m_valueIndex++;
}
else
} else {
return index;
}
}
/**
@ -2079,15 +2014,25 @@ public class SAX2DTM2 extends SAX2DTM
* @param attributes The specified or defaulted attributes.
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
* @see org.xml.sax.ContentHandler#startElement
* @see ContentHandler#startElement
*/
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException
{
charactersFlush();
int exName = m_expandedNameTable.getExpandedTypeID(uri, localName, DTM.ELEMENT_NODE);
// in case URI and localName are empty, the input is not using the
// namespaces feature. Then we should take the part after the last
// colon of qName as localName (strip all namespace prefixes)
if ((uri == null || uri.isEmpty()) &&
(localName == null || localName.isEmpty()))
{
final int colon = qName.lastIndexOf(':');
localName = (colon > -1) ? qName.substring(colon + 1) : qName;
}
int exName = m_expandedNameTable.getExpandedTypeID(uri, localName,
DTM.ELEMENT_NODE);
int prefixIndex = (qName.length() != localName.length())
? m_valuesOrPrefixes.stringToIndex(qName) : 0;
@ -2095,7 +2040,7 @@ public class SAX2DTM2 extends SAX2DTM
int elemNode = addNode(DTM.ELEMENT_NODE, exName,
m_parents.peek(), m_previous, prefixIndex, true);
if(m_indexing)
if (m_indexing)
indexNode(exName, elemNode);
m_parents.push(elemNode);
@ -2104,31 +2049,31 @@ public class SAX2DTM2 extends SAX2DTM
int nDecls = m_prefixMappings.size();
String prefix;
if(!m_pastFirstElement)
{
if (!m_pastFirstElement) {
// SPECIAL CASE: Implied declaration at root element
prefix="xml";
prefix = "xml";
String declURL = "http://www.w3.org/XML/1998/namespace";
exName = m_expandedNameTable.getExpandedTypeID(null, prefix, DTM.NAMESPACE_NODE);
m_values.addElement(declURL);
exName = m_expandedNameTable.getExpandedTypeID(null, prefix,
DTM.NAMESPACE_NODE);
m_values.add(declURL);
int val = m_valueIndex++;
addNode(DTM.NAMESPACE_NODE, exName, elemNode,
DTM.NULL, val, false);
m_pastFirstElement=true;
}
for (int i = startDecls; i < nDecls; i += 2)
{
prefix = (String) m_prefixMappings.elementAt(i);
for (int i = startDecls; i < nDecls; i += 2) {
prefix = m_prefixMappings.elementAt(i);
if (prefix == null)
continue;
String declURL = (String) m_prefixMappings.elementAt(i + 1);
String declURL = m_prefixMappings.elementAt(i + 1);
exName = m_expandedNameTable.getExpandedTypeID(null, prefix, DTM.NAMESPACE_NODE);
exName = m_expandedNameTable.getExpandedTypeID(null, prefix,
DTM.NAMESPACE_NODE);
m_values.addElement(declURL);
m_values.add(declURL);
int val = m_valueIndex++;
addNode(DTM.NAMESPACE_NODE, exName, elemNode, DTM.NULL, val, false);
@ -2136,28 +2081,37 @@ public class SAX2DTM2 extends SAX2DTM
int n = attributes.getLength();
for (int i = 0; i < n; i++)
{
for (int i = 0; i < n; i++) {
String attrUri = attributes.getURI(i);
String attrLocalName = attributes.getLocalName(i);
String attrQName = attributes.getQName(i);
String valString = attributes.getValue(i);
// in case URI and localName are empty, the input is not using the
// namespaces feature. Then we should take the part after the last
// colon of qName as localName (strip all namespace prefixes)
// When the URI is empty but localName has colons then we can also
// assume non namespace aware and prefixes can be stripped
if (attrUri == null || attrUri.isEmpty()) {
if (attrLocalName == null || attrLocalName.isEmpty()) {
final int colon = attrQName.lastIndexOf(':');
attrLocalName = (colon > -1) ? attrQName.substring(colon + 1) : attrQName;
} else {
final int colon = attrLocalName.lastIndexOf(':');
attrLocalName = (colon > -1) ? attrLocalName.substring(colon + 1) : attrLocalName;
}
}
int nodeType;
String attrLocalName = attributes.getLocalName(i);
if ((null != attrQName)
&& (attrQName.equals("xmlns")
|| attrQName.startsWith("xmlns:")))
if ((null != attrQName) &&
(attrQName.equals("xmlns") || attrQName.startsWith("xmlns:")))
{
prefix = getPrefix(attrQName, attrUri);
if (declAlreadyDeclared(prefix))
continue; // go to the next attribute.
nodeType = DTM.NAMESPACE_NODE;
}
else
{
} else {
nodeType = DTM.ATTRIBUTE_NODE;
if (m_buildIdIndex && attributes.getType(i).equalsIgnoreCase("ID"))
@ -2166,36 +2120,31 @@ public class SAX2DTM2 extends SAX2DTM
// Bit of a hack... if somehow valString is null, stringToIndex will
// return -1, which will make things very unhappy.
if(null == valString)
if (null == valString)
valString = "";
m_values.addElement(valString);
m_values.add(valString);
int val = m_valueIndex++;
if (attrLocalName.length() != attrQName.length())
{
if (attrLocalName.length() != attrQName.length()) {
prefixIndex = m_valuesOrPrefixes.stringToIndex(attrQName);
int dataIndex = m_data.size();
m_data.addElement(prefixIndex);
m_data.addElement(val);
val = -dataIndex;
}
exName = m_expandedNameTable.getExpandedTypeID(attrUri, attrLocalName, nodeType);
addNode(nodeType, exName, elemNode, DTM.NULL, val,
false);
exName = m_expandedNameTable.getExpandedTypeID(attrUri, attrLocalName,
nodeType);
addNode(nodeType, exName, elemNode, DTM.NULL, val, false);
}
if (null != m_wsfilter)
{
short wsv = m_wsfilter.getShouldStripSpace(makeNodeHandle(elemNode), this);
boolean shouldStrip = (DTMWSFilter.INHERIT == wsv)
? getShouldStripWhitespace()
: (DTMWSFilter.STRIP == wsv);
if (null != m_wsfilter) {
short wsv = m_wsfilter.getShouldStripSpace(makeNodeHandle(elemNode),
this);
boolean shouldStrip = (DTMWSFilter.INHERIT == wsv) ?
getShouldStripWhitespace() :
(DTMWSFilter.STRIP == wsv);
pushShouldStripWhitespace(shouldStrip);
}
@ -2223,7 +2172,7 @@ public class SAX2DTM2 extends SAX2DTM
* empty string if qualified names are not available.
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
* @see org.xml.sax.ContentHandler#endElement
* @see ContentHandler#endElement
*/
public void endElement(String uri, String localName, String qName)
throws SAXException
@ -2257,9 +2206,7 @@ public class SAX2DTM2 extends SAX2DTM
* @param length The number of characters to use from the array.
* @throws SAXException The application may raise an exception.
*/
public void comment(char ch[], int start, int length) throws SAXException
{
public void comment(char ch[], int start, int length) throws SAXException {
if (m_insideDTD) // ignore comments if we're inside the DTD
return;
@ -2267,7 +2214,7 @@ public class SAX2DTM2 extends SAX2DTM
// %OPT% Saving the comment string in a Vector has a lower cost than
// saving it in DTMStringPool.
m_values.addElement(new String(ch, start, length));
m_values.add(new String(ch, start, length));
int dataIndex = m_valueIndex++;
m_previous = addNode(DTM.COMMENT_NODE, DTM.COMMENT_NODE,
@ -2279,13 +2226,10 @@ public class SAX2DTM2 extends SAX2DTM
*
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
* @see org.xml.sax.ContentHandler#startDocument
* @see ContentHandler#startDocument
*/
public void startDocument() throws SAXException
{
int doc = addNode(DTM.DOCUMENT_NODE,
DTM.DOCUMENT_NODE,
public void startDocument() throws SAXException {
int doc = addNode(DTM.DOCUMENT_NODE, DTM.DOCUMENT_NODE,
DTM.NULL, DTM.NULL, 0, true);
m_parents.push(doc);
@ -2299,10 +2243,9 @@ public class SAX2DTM2 extends SAX2DTM
*
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
* @see org.xml.sax.ContentHandler#endDocument
* @see ContentHandler#endDocument
*/
public void endDocument() throws SAXException
{
public void endDocument() throws SAXException {
super.endDocument();
// Add a NULL entry to the end of the node arrays as
@ -2334,16 +2277,15 @@ public class SAX2DTM2 extends SAX2DTM
* @return The index identity of the node that was added.
*/
protected final int addNode(int type, int expandedTypeID,
int parentIndex, int previousSibling,
int dataOrPrefix, boolean canHaveFirstChild)
int parentIndex, int previousSibling,
int dataOrPrefix, boolean canHaveFirstChild)
{
// Common to all nodes:
int nodeIndex = m_size++;
// Have we overflowed a DTM Identity's addressing range?
//if(m_dtmIdent.size() == (nodeIndex>>>DTMManager.IDENT_DTM_NODE_BITS))
if (nodeIndex == m_maxNodeIndex)
{
if (nodeIndex == m_maxNodeIndex) {
addNewDTMID(nodeIndex);
m_maxNodeIndex += (1 << DTMManager.IDENT_DTM_NODE_BITS);
}
@ -2366,8 +2308,7 @@ public class SAX2DTM2 extends SAX2DTM
// is called, to handle successive characters() events.
// Special handling by type: Declare namespaces, attach first child
switch(type)
{
switch(type) {
case DTM.NAMESPACE_NODE:
declareNamespaceInContext(parentIndex,nodeIndex);
break;
@ -2376,8 +2317,7 @@ public class SAX2DTM2 extends SAX2DTM
default:
if (DTM.NULL != previousSibling) {
m_nextsib.setElementAt(nodeIndex,previousSibling);
}
else if (DTM.NULL != parentIndex) {
} else if (DTM.NULL != parentIndex) {
m_firstch.setElementAt(nodeIndex,parentIndex);
}
break;
@ -2390,16 +2330,12 @@ public class SAX2DTM2 extends SAX2DTM
* Check whether accumulated text should be stripped; if not,
* append the appropriate flavor of text/cdata node.
*/
protected final void charactersFlush()
{
if (m_textPendingStart >= 0) // -1 indicates no-text-in-progress
{
protected final void charactersFlush() {
if (m_textPendingStart >= 0) { // -1 indicates no-text-in-progress
int length = m_chars.size() - m_textPendingStart;
boolean doStrip = false;
if (getShouldStripWhitespace())
{
if (getShouldStripWhitespace()) {
doStrip = m_chars.isWhitespace(m_textPendingStart, length);
}
@ -2412,19 +2348,19 @@ public class SAX2DTM2 extends SAX2DTM
// If the offset and length do not exceed the given limits
// (offset < 2^21 and length < 2^10), then save both the offset
// and length in a bitwise encoded value.
if (length <= TEXT_LENGTH_MAX
&& m_textPendingStart <= TEXT_OFFSET_MAX) {
if (length <= TEXT_LENGTH_MAX &&
m_textPendingStart <= TEXT_OFFSET_MAX) {
m_previous = addNode(m_coalescedTextType, DTM.TEXT_NODE,
m_parents.peek(), m_previous,
length + (m_textPendingStart << TEXT_LENGTH_BITS),
false);
m_parents.peek(), m_previous,
length + (m_textPendingStart << TEXT_LENGTH_BITS),
false);
} else {
// Store offset and length in the m_data array if one exceeds
// the given limits. Use a negative dataIndex as an indication.
int dataIndex = m_data.size();
m_previous = addNode(m_coalescedTextType, DTM.TEXT_NODE,
m_parents.peek(), m_previous, -dataIndex, false);
m_parents.peek(), m_previous, -dataIndex, false);
m_data.addElement(m_textPendingStart);
m_data.addElement(length);
@ -2452,7 +2388,7 @@ public class SAX2DTM2 extends SAX2DTM
* none is supplied.
* @throws SAXException Any SAX exception, possibly
* wrapping another exception.
* @see org.xml.sax.ContentHandler#processingInstruction
* @see ContentHandler#processingInstruction
*/
public void processingInstruction(String target, String data)
throws SAXException
@ -2467,7 +2403,7 @@ public class SAX2DTM2 extends SAX2DTM
-dataIndex, false);
m_data.addElement(m_valuesOrPrefixes.stringToIndex(target));
m_values.addElement(data);
m_values.add(data);
m_data.addElement(m_valueIndex++);
}
@ -2865,9 +2801,9 @@ public class SAX2DTM2 extends SAX2DTM
}
if (m_xstrf != null)
return m_xstrf.newstr((String)m_values.elementAt(dataIndex));
return m_xstrf.newstr(m_values.get(dataIndex));
else
return new XMLStringDefault((String)m_values.elementAt(dataIndex));
return new XMLStringDefault(m_values.get(dataIndex));
}
}
@ -2966,7 +2902,7 @@ public class SAX2DTM2 extends SAX2DTM
dataIndex = m_data.elementAt(dataIndex + 1);
}
return (String)m_values.elementAt(dataIndex);
return m_values.get(dataIndex);
}
}
@ -3106,7 +3042,7 @@ public class SAX2DTM2 extends SAX2DTM
dataIndex = m_data.elementAt(dataIndex + 1);
}
String str = (String)m_values.elementAt(dataIndex);
String str = m_values.get(dataIndex);
if(normalize)
FastStringBuffer.sendNormalizedSAXcharacters(str.toCharArray(),
@ -3160,7 +3096,7 @@ public class SAX2DTM2 extends SAX2DTM
dataIndex = m_data.elementAt(dataIndex + 1);
}
return (String)m_values.elementAt(dataIndex);
return m_values.get(dataIndex);
}
}
@ -3202,8 +3138,7 @@ public class SAX2DTM2 extends SAX2DTM
if (uri.length() == 0) {
handler.startElement(name);
return name;
}
else {
} else {
int qnameIndex = m_dataOrQName.elementAt(nodeID);
if (qnameIndex == 0) {
@ -3223,14 +3158,12 @@ public class SAX2DTM2 extends SAX2DTM
String prefix;
if (prefixIndex > 0) {
prefix = qName.substring(0, prefixIndex);
}
else {
} else {
prefix = null;
}
handler.namespaceAfterStartElement(prefix, uri);
return qName;
}
}
/**
@ -3285,7 +3218,7 @@ public class SAX2DTM2 extends SAX2DTM
dataIndex = m_data.elementAt(dataIndex + 1);
}
String nodeValue = (String)m_values.elementAt(dataIndex);
String nodeValue = m_values.get(dataIndex);
handler.namespaceAfterStartElement(nodeName, nodeValue);
@ -3335,7 +3268,6 @@ public class SAX2DTM2 extends SAX2DTM
}
/**
* Copy an Attribute node to a SerializationHandler
*
@ -3347,14 +3279,6 @@ public class SAX2DTM2 extends SAX2DTM
SerializationHandler handler)
throws SAXException
{
/*
final String uri = getNamespaceName(node);
if (uri.length() != 0) {
final String prefix = getPrefix(node);
handler.namespaceAfterStartElement(prefix, uri);
}
handler.addAttribute(getNodeName(node), getNodeValue(node));
*/
final ExtendedType extType = m_extendedTypes[exptype];
final String uri = extType.getNamespace();
final String localName = extType.getLocalName();
@ -3377,7 +3301,7 @@ public class SAX2DTM2 extends SAX2DTM
}
String nodeName = (prefix != null) ? qname : localName;
String nodeValue = (String)m_values.elementAt(valueIndex);
String nodeValue = m_values.get(valueIndex);
handler.addAttribute(uri, localName, nodeName, "CDATA", nodeValue);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -58,7 +58,7 @@ class AltCatalog extends BaseEntry {
}
/**
* Returns the catalog attribute as an URI String.
* Returns the catalog attribute as a URI String.
* @return The value of the catalog attribute
*/
String getCatalogId() {
@ -66,7 +66,7 @@ class AltCatalog extends BaseEntry {
}
/**
* Returns the catalog attribute as an URI.
* Returns the catalog attribute as a URI.
* @return The value of the catalog attribute
*/
URI getCatalogURI() {

View File

@ -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
@ -27,6 +27,7 @@ package javax.xml.catalog;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Objects;
import static javax.xml.catalog.CatalogMessages.ERR_INVALID_ARGUMENT;
/**
* Represents a general Catalog entry.
@ -210,13 +211,12 @@ abstract class BaseEntry {
* @param arg The name of the argument
* @param uri The URI to be verified
* @return The URI created from the specified uri
* @throws IllegalArgumentException if the specified uri is null,
* or an URL can not be created based on the specified base and uri
* @throws NullPointerException if the specified uri is null
* @throws IllegalArgumentException if a URL can not be created based on
* the specified base and uri
*/
URL verifyURI(String arg, URL base, String uri) {
if (uri == null) {
CatalogMessages.reportIAE(new Object[]{uri, arg}, null);
}
CatalogMessages.reportNPEOnNull(arg, uri);
URL url = null;
uri = Normalizer.normalizeURI(uri);
@ -228,32 +228,9 @@ abstract class BaseEntry {
url = new URL(uri);
}
} catch (MalformedURLException e) {
CatalogMessages.reportIAE(new Object[]{uri, arg}, e);
CatalogMessages.reportIAE(ERR_INVALID_ARGUMENT,
new Object[]{uri, arg}, e);
}
return url;
}
/**
* Construct an absolute URI from a relative one, using the current base
* URI.
*
* @param sysid The (possibly relative) system identifier
* @return The system identifier made absolute with respect to the current
* {@link #base}.
*/
protected String makeAbsolute(String sysid) {
URL local = null;
sysid = Util.fixSlashes(sysid);
/**
* try { local = new URL(base, sysid); } catch (MalformedURLException e)
* { catalogManager.debug.message(1, "Malformed URL on system
* identifier", sysid); }
*/
if (local != null) {
return local.toString();
} else {
return sysid;
}
}
}

View File

@ -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
@ -44,7 +44,7 @@ import java.util.stream.Stream;
* <ul>
* <li>Locate the external resources with a public or system identifier;
* </li>
* <li>Locate an alternate URI reference with an URI.
* <li>Locate an alternate URI reference with a URI.
* </li>
* </ul>
* <p>
@ -84,7 +84,7 @@ public interface Catalog {
*
* @param systemId the system identifier of the entity to be matched
*
* @return an URI string if a mapping is found, or null otherwise
* @return a URI string if a mapping is found, or null otherwise
*/
public String matchSystem(String systemId);
@ -108,7 +108,7 @@ public interface Catalog {
*
* @param publicId the public identifier of the entity to be matched
* @see CatalogFeatures.Feature
* @return an URI string if a mapping is found, or null otherwise
* @return a URI string if a mapping is found, or null otherwise
*/
public String matchPublic(String publicId);
@ -134,7 +134,7 @@ public interface Catalog {
*
* @param uri the URI reference of the entity to be matched
*
* @return an URI string if a mapping is found, or null otherwise
* @return a URI string if a mapping is found, or null otherwise
*/
public String matchURI(String uri);

View File

@ -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
@ -56,14 +56,14 @@ import jdk.xml.internal.SecuritySupport;
*
* <tr>
* <td><a name="FILES">FILES</a></td>
* <td>A semicolon-delimited list of catalog files. Relative file paths are
* considered relative to ${user.dir}.
* <td>A semicolon-delimited list of URIs to locate the catalog files.
* The URIs must be absolute and have a URL protocol handler for the URI scheme.
* </td>
* <td>javax.xml.catalog.files</td>
* <td>javax.xml.catalog.files</td>
* <td>javax.xml.catalog.files</td>
* <td>String</td>
* <td>File paths</td>
* <td>URIs</td>
* <td>
* Reads the first catalog as the current catalog; Loads others if no match
* is found in the current catalog including delegate catalogs if any.
@ -170,7 +170,7 @@ import jdk.xml.internal.SecuritySupport;
* Properties set through the Catalog API override those that may have been set
* by system properties and/or in {@code jaxp.properties}. In case of multiple
* interfaces, the latest in a procedure shall take preference. For
* {@link Feature#FILES}, this means that the path(s) specified through the methods
* {@link Feature#FILES}, this means that the URI(s) specified through the methods
* of the {@link CatalogManager} will override any that may have been entered
* through the {@link Builder}.
*
@ -188,7 +188,7 @@ import jdk.xml.internal.SecuritySupport;
* in the following sample code:
* <pre>{@code
CatalogFeatures f = CatalogFeatures.builder()
.with(Feature.FILES, "catalog.xml")
.with(Feature.FILES, "file:///etc/xml/catalog")
.with(Feature.PREFER, "public")
.with(Feature.DEFER, "true")
.with(Feature.RESOLVE, "ignore")
@ -202,14 +202,14 @@ import jdk.xml.internal.SecuritySupport;
* Schema Validation ({@link javax.xml.validation}), and XML Transformation
* ({@link javax.xml.transform}). The features described above can be set through JAXP
* factories or processors that define a setProperty or setAttribute interface.
* For example, the following code snippet sets a path to a catalog file on a SAX
* For example, the following code snippet sets a URI to a catalog file on a SAX
* parser through the {@code javax.xml.catalog.files} property:
* <p>
* <pre>{@code
* SAXParserFactory spf = SAXParserFactory.newInstance();
* spf.setFeature(XMLConstants.USE_CATALOG, true); [1]
* SAXParser parser = spf.newSAXParser();
* parser.setProperty(CatalogFeatures.Feature.FILES.getPropertyName(), "catalog.xml");
* parser.setProperty(CatalogFeatures.Feature.FILES.getPropertyName(), "file:///etc/xml/catalog");
* }</pre>
* <p>
* [1] Note that this statement is not required since the default value of
@ -275,7 +275,7 @@ import jdk.xml.internal.SecuritySupport;
The following XInclude element:
<xi:include href="http://openjdk.java.net/xml/disclaimer.xml"/>
can be resolved using an uri entry:
can be resolved using a URI entry:
<uri name="http://openjdk.java.net/xml/disclaimer.xml" uri="file:///pathto/local/disclaimer.xml"/>
or
<uriSuffix uriSuffix="disclaimer.xml" uri="file:///pathto/local/disclaimer.xml"/>
@ -291,7 +291,7 @@ import jdk.xml.internal.SecuritySupport;
<xsd:import namespace="http://openjdk.java.net/xsd/XSDImport_person"
schemaLocation="http://openjdk.java.net/xsd/XSDImport_person.xsd"/>
can be resolved using an uri entry:
can be resolved using a URI entry:
<uri name="http://openjdk.java.net/xsd/XSDImport_person.xsd" uri="file:///pathto/local/XSDImport_person.xsd"/>
or
<uriSuffix uriSuffix="XSDImport_person.xsd" uri="file:///pathto/local/XSDImport_person.xsd"/>
@ -308,7 +308,7 @@ import jdk.xml.internal.SecuritySupport;
The following include element:
<xsd:include schemaLocation="http://openjdk.java.net/xsd/XSDInclude_person.xsd"/>
can be resolved using an uri entry:
can be resolved using a URI entry:
<uri name="http://openjdk.java.net/xsd/XSDInclude_person.xsd" uri="file:///pathto/local/XSDInclude_person.xsd"/>
or
<uriSuffix uriSuffix="XSDInclude_person.xsd" uri="file:///pathto/local/XSDInclude_person.xsd"/>
@ -323,7 +323,7 @@ import jdk.xml.internal.SecuritySupport;
The following include element:
<xsl:include href="http://openjdk.java.net/xsl/include.xsl"/>
can be resolved using an uri entry:
can be resolved using a URI entry:
<uri name="http://openjdk.java.net/xsl/include.xsl" uri="file:///pathto/local/include.xsl"/>
or
<uriSuffix uriSuffix="include.xsl" uri="file:///pathto/local/include.xsl"/>
@ -338,7 +338,7 @@ import jdk.xml.internal.SecuritySupport;
The document in the following element:
<xsl:variable name="dummy" select="document('http://openjdk.java.net/xsl/list.xml')"/>
can be resolved using an uri entry:
can be resolved using a URI entry:
<uri name="http://openjdk.java.net/xsl/list.xml" uri="file:///pathto/local/list.xml"/>
or
<uriSuffix uriSuffix="list.xml" uri="file:///pathto/local/list.xml"/>
@ -559,7 +559,7 @@ public class CatalogFeatures {
values = new String[Feature.values().length];
states = new State[Feature.values().length];
for (Feature cf : Feature.values()) {
setProperty(cf.ordinal(), State.DEFAULT, cf.defaultValue());
setProperty(cf, State.DEFAULT, cf.defaultValue());
}
//read system properties or jaxp.properties
readSystemProperties();
@ -571,52 +571,27 @@ public class CatalogFeatures {
*/
private void setProperties(Builder builder) {
builder.values.entrySet().stream().forEach((entry) -> {
setProperty(entry.getKey().ordinal(), State.APIPROPERTY, entry.getValue());
setProperty(entry.getKey(), State.APIPROPERTY, entry.getValue());
});
}
/**
* Sets the value of a property by its index, updates only if it shall override.
* Sets the value of a property, updates only if it shall override.
*
* @param index the index of the property
* @param state the state of the property
* @param value the value of the property
* @throws IllegalArgumentException if the value is invalid
*/
private void setProperty(int index, State state, String value) {
private void setProperty(Feature feature, State state, String value) {
int index = feature.ordinal();
if (value != null && value.length() != 0) {
if (index == Feature.PREFER.ordinal()) {
if (!value.equals(PREFER_SYSTEM) && !value.equals(PREFER_PUBLIC)) {
CatalogMessages.reportIAE(new Object[]{value, Feature.PREFER.name()}, null);
}
} else if (index == Feature.DEFER.ordinal()) {
if (!value.equals(DEFER_TRUE) && !value.equals(DEFER_FALSE)) {
CatalogMessages.reportIAE(new Object[]{value, Feature.DEFER.name()}, null);
}
} else if (index == Feature.RESOLVE.ordinal()) {
if (!value.equals(RESOLVE_STRICT) && !value.equals(RESOLVE_CONTINUE)
&& !value.equals(RESOLVE_IGNORE)) {
CatalogMessages.reportIAE(new Object[]{value, Feature.RESOLVE.name()}, null);
}
} else if (index == Feature.FILES.ordinal()) {
try {
String[] catalogFile = value.split(";[ ]*");
for (String temp : catalogFile) {
if (Util.verifyAndGetURI(temp, null) == null) {
CatalogMessages.reportIAE(new Object[]{value, Feature.FILES.name()}, null);
}
}
}catch (MalformedURLException | URISyntaxException | IllegalArgumentException ex) {
CatalogMessages.reportIAE(new Object[]{value, Feature.FILES.name()}, ex);
}
if (state != State.APIPROPERTY) {
Util.validateFeatureInput(feature, value);
}
if (states[index] == null || state.compareTo(states[index]) >= 0) {
values[index] = value;
states[index] = state;
}
} else {
if (state == State.SYSTEMPROPERTY || state == State.JAXPDOTPROPERTIES) {
CatalogMessages.reportIAE(new Object[]{value, Feature.values()[index].name()}, null);
}
}
}
@ -639,13 +614,13 @@ public class CatalogFeatures {
if (cf.hasSystemProperty()) {
String value = SecuritySupport.getSystemProperty(sysPropertyName);
if (value != null && !value.equals("")) {
setProperty(cf.ordinal(), State.SYSTEMPROPERTY, value);
setProperty(cf, State.SYSTEMPROPERTY, value);
return true;
}
value = SecuritySupport.readJAXPProperty(sysPropertyName);
if (value != null && !value.equals("")) {
setProperty(cf.ordinal(), State.JAXPDOTPROPERTIES, value);
setProperty(cf, State.JAXPDOTPROPERTIES, value);
return true;
}
}
@ -685,9 +660,7 @@ public class CatalogFeatures {
* property
*/
public Builder with(Feature feature, String value) {
if (value == null || value.length() == 0) {
CatalogMessages.reportIAE(new Object[]{value, feature.name()}, null);
}
Util.validateFeatureInput(feature, value);
values.put(feature, value);
return this;
}

View File

@ -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
@ -75,7 +75,7 @@ class CatalogImpl extends GroupEntry implements Catalog {
/*
A list of catalog entry files from the input, excluding the current catalog.
Paths in the List are normalized.
URIs in the List are verified during input validation or property retrieval.
*/
List<String> inputFiles;
@ -86,43 +86,44 @@ class CatalogImpl extends GroupEntry implements Catalog {
SAXParser parser;
/**
* Construct a Catalog with specified path.
* Construct a Catalog with specified URI.
*
* @param file The path to a catalog file.
* @param uris the uri(s) to one or more catalogs
* @throws CatalogException If an error happens while parsing the specified
* catalog file.
*/
public CatalogImpl(CatalogFeatures f, String... file) throws CatalogException {
this(null, f, file);
public CatalogImpl(CatalogFeatures f, URI... uris) throws CatalogException {
this(null, f, uris);
}
/**
* Construct a Catalog with specified path.
* Construct a Catalog with specified URI.
*
* @param parent The parent catalog
* @param file The path to a catalog file.
* @param uris the uri(s) to one or more catalogs
* @throws CatalogException If an error happens while parsing the specified
* catalog file.
*/
public CatalogImpl(CatalogImpl parent, CatalogFeatures f, String... file) throws CatalogException {
public CatalogImpl(CatalogImpl parent, CatalogFeatures f, URI... uris) throws CatalogException {
super(CatalogEntryType.CATALOG, parent);
if (f == null) {
throw new NullPointerException(
formatMessage(CatalogMessages.ERR_NULL_ARGUMENT, new Object[]{"CatalogFeatures"}));
}
if (file.length > 0) {
CatalogMessages.reportNPEOnNull("The path to the catalog file", file[0]);
}
init(f);
//Path of catalog files
String[] catalogFile = file;
if (level == 0 && file.length == 0) {
String[] catalogFile = null;
if (level == 0 && uris.length == 0) {
String files = features.get(Feature.FILES);
if (files != null) {
catalogFile = files.split(";[ ]*");
catalogFile = files.split(";");
}
} else {
catalogFile = new String[uris.length];
for (int i=0; i<uris.length; i++) {
catalogFile[i] = uris[i].toASCIIString();
}
}
@ -134,10 +135,10 @@ class CatalogImpl extends GroupEntry implements Catalog {
int start = 0;
URI uri = null;
for (String temp : catalogFile) {
uri = getSystemId(temp);
uri = URI.create(temp);
start++;
if (verifyCatalogFile(uri)) {
systemId = uri.toASCIIString();
systemId = temp;
try {
baseURI = new URL(systemId);
} catch (MalformedURLException e) {
@ -293,29 +294,6 @@ class CatalogImpl extends GroupEntry implements Catalog {
}
}
/**
* Resolves the specified file path to an absolute systemId. If it is
* relative, it shall be resolved using the base or user.dir property if
* base is not specified.
*
* @param file The specified file path
* @return The systemId of the file
* @throws CatalogException if the specified file path can not be converted
* to a system id
*/
private URI getSystemId(String file) {
URI temp = null;
try {
temp = Util.verifyAndGetURI(file, baseURI);
} catch (MalformedURLException | URISyntaxException | IllegalArgumentException e) {
CatalogMessages.reportRunTimeError(CatalogMessages.ERR_INVALID_PATH,
new Object[]{file}, e);
}
return temp;
}
/**
* Returns a SAXParser instance
* @return a SAXParser instance
@ -394,7 +372,7 @@ class CatalogImpl extends GroupEntry implements Catalog {
//Check the input list
if (c == null && inputFiles != null) {
while (c == null && inputFilesIndex < inputFiles.size()) {
c = getCatalog(getSystemId(inputFiles.get(inputFilesIndex++)));
c = getCatalog(URI.create(inputFiles.get(inputFilesIndex++)));
}
}
@ -436,8 +414,8 @@ class CatalogImpl extends GroupEntry implements Catalog {
//loads catalogs from the input list
if (inputFiles != null) {
inputFiles.stream().forEach((file) -> {
getCatalog(getSystemId(file));
inputFiles.stream().forEach((uri) -> {
getCatalog(URI.create(uri));
});
}
}
@ -454,12 +432,11 @@ class CatalogImpl extends GroupEntry implements Catalog {
}
CatalogImpl c = null;
String path = uri.toASCIIString();
if (verifyCatalogFile(uri)) {
c = getLoadedCatalog(path);
c = getLoadedCatalog(uri.toASCIIString());
if (c == null) {
c = new CatalogImpl(this, features, path);
c = new CatalogImpl(this, features, uri);
c.load();
}
}

View File

@ -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
@ -24,6 +24,7 @@
*/
package javax.xml.catalog;
import java.net.URI;
/**
* The Catalog Manager manages the creation of XML Catalogs and Catalog Resolvers.
@ -39,30 +40,36 @@ public final class CatalogManager {
/**
* Creates a {@code Catalog} object using the specified feature settings and
* path to one or more catalog files.
* uri(s) to one or more catalog files.
* <p>
* If {@code paths} is empty, system property {@code javax.xml.catalog.files}
* will be read to locate the initial list of catalog files.
* If {@code uris} is empty, system property {@code javax.xml.catalog.files},
* as defined in {@link CatalogFeatures}, will be read to locate the initial
* list of catalog files.
* <p>
* If more than one catalog files are specified through the paths argument or
* If multiple catalog files are specified through the {@code uris} argument or
* {@code javax.xml.catalog.files} property, the first entry is considered
* the main catalog, while others are treated as alternative catalogs after
* those referenced by the {@code nextCatalog} elements in the main catalog.
* <p>
* As specified in
* <a href="https://www.oasis-open.org/committees/download.php/14809/xml-catalogs.html#s.res.fail">
* XML Catalogs, OASIS Standard V1.1</a>, invalid path entries will be ignored.
* No error will be reported. In case all entries are invalid, the resolver
* will return as no mapping is found.
* XML Catalogs, OASIS Standard V1.1</a>, if a catalog entry is invalid, it
* is ignored. In case all entries are invalid, the resulting Catalog object
* will contain no Catalog elements. Any matching operation using the Catalog
* will return null.
*
* @param features the catalog features
* @param paths path(s) to one or more catalogs.
* @param uris uri(s) to one or more catalogs.
*
* @return an instance of a {@code Catalog}
* @throws IllegalArgumentException if either the URIs are not absolute
* or do not have a URL protocol handler for the URI scheme
* @throws CatalogException If an error occurs while parsing the catalog
* @throws SecurityException if access to the resource is denied by the security manager
*/
public static Catalog catalog(CatalogFeatures features, String... paths) {
CatalogImpl catalog = new CatalogImpl(features, paths);
public static Catalog catalog(CatalogFeatures features, URI... uris) {
Util.validateUrisSyntax(uris);
CatalogImpl catalog = new CatalogImpl(features, uris);
catalog.load();
return catalog;
}
@ -80,30 +87,36 @@ public final class CatalogManager {
/**
* Creates an instance of a {@code CatalogResolver} using the specified feature
* settings and path to one or more catalog files.
* settings and uri(s) to one or more catalog files.
* <p>
* If {@code paths} is empty, system property {@code javax.xml.catalog.files}
* will be read to locate the initial list of catalog files.
* If {@code uris} is empty, system property {@code javax.xml.catalog.files},
* as defined in {@link CatalogFeatures}, will be read to locate the initial
* list of catalog files.
* <p>
* If more than one catalog files are specified through the paths argument or
* If multiple catalog files are specified through the {@code uris} argument or
* {@code javax.xml.catalog.files} property, the first entry is considered
* the main catalog, while others are treated as alternative catalogs after
* those referenced by the {@code nextCatalog} elements in the main catalog.
* <p>
* As specified in
* <a href="https://www.oasis-open.org/committees/download.php/14809/xml-catalogs.html#s.res.fail">
* XML Catalogs, OASIS Standard V1.1</a>, invalid path entries will be ignored.
* No error will be reported. In case all entries are invalid, the resolver
* will return as no mapping is found.
* XML Catalogs, OASIS Standard V1.1</a>, if a catalog entry is invalid, it
* is ignored. In case all entries are invalid, the resulting CatalogResolver
* object will contain no valid catalog. Any resolution operation using the
* resolver therefore will return as no mapping is found. See {@link CatalogResolver}
* for the behavior when no mapping is found.
*
* @param features the catalog features
* @param paths the path(s) to one or more catalogs
* @param uris the uri(s) to one or more catalogs
*
* @return an instance of a {@code CatalogResolver}
* @throws IllegalArgumentException if either the URIs are not absolute
* or do not have a URL protocol handler for the URI scheme
* @throws CatalogException If an error occurs while parsing the catalog
* @throws SecurityException if access to the resource is denied by the security manager
*/
public static CatalogResolver catalogResolver(CatalogFeatures features, String... paths) {
Catalog catalog = catalog(features, paths);
public static CatalogResolver catalogResolver(CatalogFeatures features, URI... uris) {
Catalog catalog = catalog(features, uris);
return new CatalogResolverImpl(catalog);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -24,10 +24,11 @@
*/
package javax.xml.catalog;
import jdk.xml.internal.SecuritySupport;
import java.net.URI;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import jdk.xml.internal.SecuritySupport;
/**
* Catalog Error messages
@ -38,6 +39,8 @@ final class CatalogMessages {
public static final String ERR_INVALID_CATALOG = "InvalidCatalog";
public static final String ERR_INVALID_ENTRY_TYPE = "InvalidEntryType";
public static final String ERR_URI_NOTABSOLUTE = "UriNotAbsolute";
public static final String ERR_URI_NOTVALIDURL = "UriNotValidUrl";
public static final String ERR_INVALID_ARGUMENT = "InvalidArgument";
public static final String ERR_NULL_ARGUMENT = "NullArgument";
public static final String ERR_CIRCULAR_REFERENCE = "CircularReference";
@ -120,7 +123,7 @@ final class CatalogMessages {
* @param name the name of the argument
* @param value the value of the argument
*/
static void reportNPEOnNull(String name, String value) {
static void reportNPEOnNull(String name, Object value) {
if (value == null) {
throw new NullPointerException(
formatMessage(ERR_NULL_ARGUMENT, new Object[]{name}));
@ -132,9 +135,9 @@ final class CatalogMessages {
* @param arguments the arguments for formating the error message
* @param cause the cause if any
*/
static void reportIAE(Object[] arguments, Throwable cause) {
static void reportIAE(String key, Object[] arguments, Throwable cause) {
throw new IllegalArgumentException(
formatMessage(ERR_INVALID_ARGUMENT, arguments), cause);
formatMessage(key, arguments), cause);
}
/**
@ -174,7 +177,7 @@ final class CatalogMessages {
/**
* Returns sanitized URI.
* @param uri an URI to be sanitized
* @param uri a URI to be sanitized
*/
static String sanitize(String uri) {
if (uri == null) {

View File

@ -31,6 +31,8 @@ InvalidEntryType = The entry type ''{0}'' is not valid.
CircularReference = Circular reference is not allowed: ''{0}''.
#errors
UriNotAbsolute = The specified URI ''{0}'' is not absolute.
UriNotValidUrl = The specified URI ''{0}'' is not a valid URL.
InvalidArgument = The specified argument ''{0}'' (case sensitive) for ''{1}'' is not valid.
NullArgument = The argument ''{0}'' can not be null.
InvalidPath = The path ''{0}'' is invalid.

View File

@ -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
@ -25,10 +25,6 @@
package javax.xml.catalog;
import java.io.StringReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.nio.file.Paths;
import javax.xml.catalog.BaseEntry.CatalogEntryType;
import javax.xml.parsers.SAXParser;
import javax.xml.transform.Source;
@ -94,25 +90,6 @@ class CatalogReader extends DefaultHandler implements EntityResolver, URIResolve
this.parser = parser;
}
/**
* Returns when the specified path is valid.
* @param path a path
* @return true if the path is valid, false otherwise
*/
boolean isValidPath(String path) {
boolean valid = true;
try {
Path p = Paths.get(new URI(path));
if (!p.toFile().exists()) {
valid = false;
}
} catch (URISyntaxException ex) {
valid = false;
}
return valid;
}
@Override
public void startElement(String namespaceURI,
String localName,

View File

@ -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
@ -47,7 +47,7 @@ import org.xml.sax.InputSource;
* {@link javax.xml.stream.XMLResolver} and {@link org.w3c.dom.ls.LSResourceResolver}
* however, make no such distinction.
* In consistent with the existing Java API, this CatalogResolver recognizes a
* system identifier as an URI and will search both {@code system} and {@code uri}
* system identifier as a URI and will search both {@code system} and {@code uri}
* entries in a catalog in order to find a matching entry.
* <p>
* The search is started in the current catalog. If a match is found,
@ -137,9 +137,9 @@ public interface CatalogResolver extends EntityResolver, XMLResolver,
* with the specified {@code href} attribute. The {@code href} attribute will
* be used literally, with no attempt to be made absolute to the {@code base}.
* <p>
* If the value is an URN, the {@code href} attribute is recognized as a
* If the value is a URN, the {@code href} attribute is recognized as a
* {@code publicId}, and used to search {@code public} entries.
* If the value is an URI, it is taken as a {@code systemId}, and used to
* If the value is a URI, it is taken as a {@code systemId}, and used to
* search both {@code system} and {@code uri} entries.
*
*
@ -219,7 +219,7 @@ public interface CatalogResolver extends EntityResolver, XMLResolver,
* @param publicId the public identifier of the external entity being
* referenced, or {@code null} if no public identifier was
* supplied or if the resource is not an entity.
* @param systemId the system identifier, an URI reference of the
* @param systemId the system identifier, a URI reference of the
* external resource being referenced
* @param baseUri the absolute base URI, not used by the CatalogResolver
*

View File

@ -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
@ -73,7 +73,7 @@ final class CatalogResolverImpl implements CatalogResolver {
systemId = Normalizer.normalizeURI(Util.getNotNullOrEmpty(systemId));
publicId = Normalizer.normalizePublicId(Normalizer.decodeURN(Util.getNotNullOrEmpty(publicId)));
//check whether systemId is an urn
//check whether systemId is a urn
if (systemId != null && systemId.startsWith(Util.URN)) {
systemId = Normalizer.decodeURN(systemId);
if (publicId != null && !publicId.equals(systemId)) {
@ -123,7 +123,7 @@ final class CatalogResolverImpl implements CatalogResolver {
return null;
}
//check whether uri is an urn
//check whether uri is a urn
if (uri != null && uri.startsWith(Util.URN)) {
String publicId = Normalizer.decodeURN(uri);
if (publicId != null) {
@ -131,7 +131,7 @@ final class CatalogResolverImpl implements CatalogResolver {
}
}
//if no match with a public id, continue search for an URI
//if no match with a public id, continue search for a URI
if (result == null) {
//remove fragment if any.
int hashPos = uri.indexOf("#");

View File

@ -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
@ -25,8 +25,6 @@
package javax.xml.catalog;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -217,7 +215,7 @@ class GroupEntry extends BaseEntry {
* @param systemId The system identifier of the external entity being
* referenced.
*
* @return An URI string if a mapping is found, or null otherwise.
* @return a URI string if a mapping is found, or null otherwise.
*/
public String matchSystem(String systemId) {
systemEntrySearched = true;
@ -285,7 +283,7 @@ class GroupEntry extends BaseEntry {
* @param publicId The public identifier of the external entity being
* referenced.
*
* @return An URI string if a mapping is found, or null otherwise.
* @return a URI string if a mapping is found, or null otherwise.
*/
public String matchPublic(String publicId) {
/*
@ -329,7 +327,7 @@ class GroupEntry extends BaseEntry {
*
* @param uri The URI reference of a resource.
*
* @return An URI string if a mapping is found, or null otherwise.
* @return a URI string if a mapping is found, or null otherwise.
*/
public String matchURI(String uri) {
String match = null;
@ -455,7 +453,7 @@ class GroupEntry extends BaseEntry {
delegateCatalog = getLoadedCatalog(catalogId);
if (delegateCatalog == null) {
if (verifyCatalogFile(catalogURI)) {
delegateCatalog = new CatalogImpl(catalog, features, catalogId);
delegateCatalog = new CatalogImpl(catalog, features, catalogURI);
delegateCatalog.load();
delegateCatalogs.put(catalogId, delegateCatalog);
}
@ -504,7 +502,8 @@ class GroupEntry extends BaseEntry {
}
//Ignore it if it doesn't exist
if (!Files.exists(Paths.get(catalogURI))) {
if (Util.isFileUri(catalogURI) &&
!Util.isFileUriExist(catalogURI, false)) {
return false;
}

View File

@ -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
@ -27,7 +27,7 @@ package javax.xml.catalog;
import java.net.URL;
/**
* Represents an uriEntry entry.
* Represents a uri entry.
*
* @since 9
*/
@ -36,7 +36,7 @@ final class UriEntry extends BaseEntry {
URL uri;
/**
* Construct a group entry.
* Construct a uri entry.
* @param name The name attribute.
* @param uri The uri attribute.
*/

View File

@ -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
@ -25,13 +25,20 @@
package javax.xml.catalog;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Iterator;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import static javax.xml.catalog.CatalogFeatures.DEFER_FALSE;
import static javax.xml.catalog.CatalogFeatures.DEFER_TRUE;
import javax.xml.catalog.CatalogFeatures.Feature;
import static javax.xml.catalog.CatalogFeatures.PREFER_PUBLIC;
import static javax.xml.catalog.CatalogFeatures.PREFER_SYSTEM;
import static javax.xml.catalog.CatalogFeatures.RESOLVE_CONTINUE;
import static javax.xml.catalog.CatalogFeatures.RESOLVE_IGNORE;
import static javax.xml.catalog.CatalogFeatures.RESOLVE_STRICT;
import jdk.xml.internal.SecuritySupport;
/**
@ -39,22 +46,25 @@ import jdk.xml.internal.SecuritySupport;
* @since 9
*/
class Util {
final static String URN = "urn:publicid:";
final static String PUBLICID_PREFIX = "-//";
final static String PUBLICID_PREFIX_ALT = "+//";
final static String SCHEME_FILE = "file";
final static String SCHEME_JAR = "jar";
final static String SCHEME_JARFILE = "jar:file:";
/**
* Finds an entry in the catalog that matches with the publicId or systemId.
*
* The resolution follows the following rules determined by the prefer setting:
* The resolution follows the following rules determined by the prefer
* setting:
*
* prefer "system": attempts to resolve with a system entry;
* attempts to resolve with a public entry when only
* publicId is specified.
* prefer "system": attempts to resolve with a system entry; attempts to
* resolve with a public entry when only publicId is specified.
*
* prefer "public": attempts to resolve with a system entry;
* attempts to resolve with a public entry if no matching
* system entry is found.
* prefer "public": attempts to resolve with a system entry; attempts to
* resolve with a public entry if no matching system entry is found.
*
* If no match is found, continue searching uri entries
*
@ -70,9 +80,9 @@ class Util {
catalog.reset();
if (systemId != null) {
/*
If a system identifier is specified, it is used no matter how
prefer is set.
*/
If a system identifier is specified, it is used no matter how
prefer is set.
*/
resolvedSystemId = catalog.matchSystem(systemId);
}
@ -91,7 +101,7 @@ class Util {
if (resolvedSystemId == null) {
Iterator<Catalog> iter = catalog.catalogs().iterator();
while (iter.hasNext()) {
resolvedSystemId = resolve((CatalogImpl)iter.next(), publicId, systemId);
resolvedSystemId = resolve((CatalogImpl) iter.next(), publicId, systemId);
if (resolvedSystemId != null) {
break;
}
@ -102,73 +112,112 @@ class Util {
return resolvedSystemId;
}
/**
* Resolves the specified file path to an absolute systemId. If it is
* relative, it shall be resolved using the base or user.dir property if
* base is not specified.
*
* @param file The specified file path
* @param baseURI the base URI
* @return The URI
* @throws CatalogException if the specified file path can not be converted
* to a system id
*/
static URI verifyAndGetURI(String file, URL baseURI)
throws MalformedURLException, URISyntaxException, IllegalArgumentException {
URL filepath;
URI temp;
if (file != null && file.length() > 0) {
File f = new File(file);
if (baseURI != null && !f.isAbsolute()) {
filepath = new URL(baseURI, fixSlashes(file));
temp = filepath.toURI();
} else {
temp = resolveURI(file);
}
//Paths.get may throw IllegalArgumentException
Path path = Paths.get(temp);
if (path.toFile().isFile()) {
return temp;
}
static void validateUrisSyntax(URI... uris) {
for (URI uri : uris) {
validateUriSyntax(uri);
}
}
static void validateUrisSyntax(String... uris) {
for (String uri : uris) {
validateUriSyntax(URI.create(uri));
}
return null;
}
/**
* Resolves the specified uri. If the uri is relative, makes it absolute by
* the user.dir directory.
* Validate that the URI must be absolute and a valid URL.
*
* @param uri The specified URI.
* @return The resolved URI
* Note that this method does not verify the existence of the resource. The
* Catalog standard requires that such resources be ignored.
*
* @param uri
* @throws IllegalArgumentException if the uri is not absolute and a valid
* URL
*/
static URI resolveURI(String uri) throws MalformedURLException {
if (uri == null) {
uri = "";
static void validateUriSyntax(URI uri) {
CatalogMessages.reportNPEOnNull("URI input", uri);
if (!uri.isAbsolute()) {
CatalogMessages.reportIAE(CatalogMessages.ERR_URI_NOTABSOLUTE,
new Object[]{uri}, null);
}
URI temp = null;
try {
URL url = new URL(uri);
temp = url.toURI();
} catch (MalformedURLException | URISyntaxException mue) {
File file = new File(uri);
temp = file.toURI();
// check if the scheme was valid
uri.toURL();
} catch (MalformedURLException ex) {
CatalogMessages.reportIAE(CatalogMessages.ERR_URI_NOTVALIDURL,
new Object[]{uri}, null);
}
return temp;
// verify the resource exists where possible
if (isFileUri(uri)) {
if (!isFileUriExist(uri, false)) {
CatalogMessages.reportIAE(CatalogMessages.ERR_URI_NOTVALIDURL,
new Object[]{uri}, null);
}
}
}
/**
* Replace backslashes with forward slashes. (URLs always use forward
* slashes.)
* Checks whether the URI is a file URI, including JAR file.
*
* @param sysid The input system identifier.
* @return The same system identifier with backslashes turned into forward
* slashes.
* @param uri the specified URI.
* @return true if it is a file or JAR file URI, false otherwise
*/
static String fixSlashes(String sysid) {
return sysid.replace('\\', '/');
static boolean isFileUri(URI uri) {
if (SCHEME_FILE.equals(uri.getScheme())
|| SCHEME_JAR.equals(uri.getScheme())) {
return true;
}
return false;
}
/**
* Verifies whether the file resource exists.
*
* @param uri the URI to locate the resource
* @param openJarFile a flag to indicate whether a JAR file should be
* opened. This operation may be expensive.
* @return true if the resource exists, false otherwise.
*/
static boolean isFileUriExist(URI uri, boolean openJarFile) {
if (uri != null && uri.isAbsolute()) {
if (null != uri.getScheme()) {
switch (uri.getScheme()) {
case SCHEME_FILE:
String path = uri.getPath();
File f1 = new File(path);
if (f1.isFile()) {
return true;
}
break;
case SCHEME_JAR:
String tempUri = uri.toString();
int pos = tempUri.indexOf("!");
if (pos < 0) {
return false;
}
if (openJarFile) {
String jarFile = tempUri.substring(SCHEME_JARFILE.length(), pos);
String entryName = tempUri.substring(pos + 2);
try {
JarFile jf = new JarFile(jarFile);
JarEntry je = jf.getJarEntry(entryName);
if (je != null) {
return true;
}
} catch (IOException ex) {
return false;
}
} else {
return true;
}
break;
}
}
}
return false;
}
/**
@ -187,11 +236,12 @@ class Util {
}
/**
* Checks whether the specified string is null or empty, returns the original
* string with leading and trailing spaces removed if not.
* Checks whether the specified string is null or empty, returns the
* original string with leading and trailing spaces removed if not.
*
* @param test the string to be tested
* @return the original string with leading and trailing spaces removed,
* or null if it is null or empty
* @return the original string with leading and trailing spaces removed, or
* null if it is null or empty
*
*/
static String getNotNullOrEmpty(String test) {
@ -206,4 +256,39 @@ class Util {
}
}
}
/**
* Validates the input for features.
*
* @param f the feature
* @param value the value
* @throws IllegalArgumentException if the value is invalid for the feature
*/
static void validateFeatureInput(Feature f, String value) {
CatalogMessages.reportNPEOnNull(f.name(), value);
if (value.length() == 0) {
CatalogMessages.reportIAE(CatalogMessages.ERR_INVALID_ARGUMENT,
new Object[]{value, f.name()}, null);
}
if (f == Feature.PREFER) {
if (!value.equals(PREFER_SYSTEM) && !value.equals(PREFER_PUBLIC)) {
CatalogMessages.reportIAE(CatalogMessages.ERR_INVALID_ARGUMENT,
new Object[]{value, Feature.PREFER.name()}, null);
}
} else if (f == Feature.DEFER) {
if (!value.equals(DEFER_TRUE) && !value.equals(DEFER_FALSE)) {
CatalogMessages.reportIAE(CatalogMessages.ERR_INVALID_ARGUMENT,
new Object[]{value, Feature.DEFER.name()}, null);
}
} else if (f == Feature.RESOLVE) {
if (!value.equals(RESOLVE_STRICT) && !value.equals(RESOLVE_CONTINUE)
&& !value.equals(RESOLVE_IGNORE)) {
CatalogMessages.reportIAE(CatalogMessages.ERR_INVALID_ARGUMENT,
new Object[]{value, Feature.RESOLVE.name()}, null);
}
} else if (f == Feature.FILES) {
Util.validateUrisSyntax(value.split(";"));
}
}
}

View File

@ -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
@ -81,7 +81,7 @@ public class SpecifyCatalogTest {
@Test
public void specifyCatalogViaSysProps() {
setSystemProperty(FEATURE_FILES,
getCatalogPath("specifyCatalog-sysProps.xml"));
getCatalogPath("specifyCatalog-sysProps.xml").toASCIIString());
checkResolutionOnEntityResolver(catalogResolver((String[]) null),
"http://local/base/dtd/docSysPropsSys.dtd");
@ -107,6 +107,6 @@ public class SpecifyCatalogTest {
}
private static CatalogFeatures createFeature(String catalogName) {
return builder().with(FILES, getCatalogPath(catalogName)).build();
return builder().with(FILES, getCatalogPath(catalogName).toASCIIString()).build();
}
}

View File

@ -0,0 +1 @@
<dummy />

View File

@ -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
@ -25,17 +25,16 @@ package catalog;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.xml.catalog.CatalogFeatures;
import javax.xml.catalog.CatalogManager;
import javax.xml.catalog.CatalogResolver;
import jaxp.library.JAXPTestUtilities;
/*
@ -115,20 +114,20 @@ final class CatalogTestUtils {
}
// Gets the paths of the specified catalogs.
private static String[] getCatalogPaths(String... catalogNames) {
private static URI[] getCatalogPaths(String... catalogNames) {
return catalogNames == null
? null
: Stream.of(catalogNames).map(
catalogName -> getCatalogPath(catalogName)).collect(
Collectors.toList()).toArray(new String[0]);
Collectors.toList()).toArray(new URI[0]);
}
// Gets the paths of the specified catalogs.
static String getCatalogPath(String catalogName) {
static URI getCatalogPath(String catalogName) {
return catalogName == null
? null
: JAXPTestUtilities.getPathByClassName(CatalogTestUtils.class, "catalogFiles")
+ catalogName;
: Paths.get(JAXPTestUtilities.getPathByClassName(CatalogTestUtils.class, "catalogFiles")
+ catalogName).toUri();
}
/* ********** jaxp.properties ********** */

View File

@ -0,0 +1,141 @@
/*
* 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
* 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 jaxp.library;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* This class consists exclusively of static utility methods that are useful
* for creating and manipulating JAR files.
*/
public final class JarUtils {
private JarUtils() { }
/**
* Creates a JAR file.
*
* Equivalent to {@code jar cfm <jarfile> <manifest> -C <dir> file...}
*
* The input files are resolved against the given directory. Any input
* files that are directories are processed recursively.
*/
public static void createJarFile(Path jarfile, Manifest man, Path dir, Path... file)
throws IOException
{
// create the target directory
Path parent = jarfile.getParent();
if (parent != null)
Files.createDirectories(parent);
List<Path> entries = new ArrayList<>();
for (Path entry : file) {
Files.find(dir.resolve(entry), Integer.MAX_VALUE,
(p, attrs) -> attrs.isRegularFile())
.map(e -> dir.relativize(e))
.forEach(entries::add);
}
try (OutputStream out = Files.newOutputStream(jarfile);
JarOutputStream jos = new JarOutputStream(out))
{
if (man != null) {
JarEntry je = new JarEntry(JarFile.MANIFEST_NAME);
jos.putNextEntry(je);
man.write(jos);
jos.closeEntry();
}
for (Path entry : entries) {
String name = toJarEntryName(entry);
jos.putNextEntry(new JarEntry(name));
Files.copy(dir.resolve(entry), jos);
jos.closeEntry();
}
}
}
/**
* Creates a JAR file.
*
* Equivalent to {@code jar cf <jarfile> -C <dir> file...}
*
* The input files are resolved against the given directory. Any input
* files that are directories are processed recursively.
*/
public static void createJarFile(Path jarfile, Path dir, Path... file)
throws IOException
{
createJarFile(jarfile, null, dir, file);
}
/**
* Creates a JAR file.
*
* Equivalent to {@code jar cf <jarfile> -C <dir> file...}
*
* The input files are resolved against the given directory. Any input
* files that are directories are processed recursively.
*/
public static void createJarFile(Path jarfile, Path dir, String... input)
throws IOException
{
Path[] paths = Stream.of(input).map(Paths::get).toArray(Path[]::new);
createJarFile(jarfile, dir, paths);
}
/**
* Creates a JAR file from the contents of a directory.
*
* Equivalent to {@code jar cf <jarfile> -C <dir> .}
*/
public static void createJarFile(Path jarfile, Path dir) throws IOException {
createJarFile(jarfile, dir, Paths.get("."));
}
/**
* Map a file path to the equivalent name in a JAR file
*/
private static String toJarEntryName(Path file) {
Path normalized = file.normalize();
return normalized.subpath(0, normalized.getNameCount()) // drop root
.toString()
.replace(File.separatorChar, '/');
}
}

View File

@ -0,0 +1,177 @@
/*
* 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.
*
* 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 jaxp.library;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpContext;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.URI;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* A simple HTTP Server
*/
public class SimpleHttpServer {
HttpServer _httpserver;
ExecutorService _executor;
String _address;
String _context, _docroot;
int _port;
public SimpleHttpServer(String context, String docroot) {
//let the system pick up an ephemeral port in a bind operation
this(0, context, docroot);
}
public SimpleHttpServer(int port, String context, String docroot) {
_port = port;
_context = context;
_docroot = docroot;
}
public void start() {
MyHttpHandler handler = new MyHttpHandler(_docroot);
InetSocketAddress addr = new InetSocketAddress(_port);
try {
_httpserver = HttpServer.create(addr, 0);
} catch (IOException ex) {
throw new RuntimeException("cannot create httpserver", ex);
}
//TestHandler is mapped to /test
HttpContext ctx = _httpserver.createContext(_context, handler);
_executor = Executors.newCachedThreadPool();
_httpserver.setExecutor(_executor);
_httpserver.start();
_address = "http://localhost:" + _httpserver.getAddress().getPort();
}
public void stop() {
_httpserver.stop(2);
_executor.shutdown();
}
public String getAddress() {
return _address;
}
static class MyHttpHandler implements HttpHandler {
String _docroot;
public MyHttpHandler(String docroot) {
_docroot = docroot;
}
public void handle(HttpExchange t)
throws IOException {
InputStream is = t.getRequestBody();
Headers map = t.getRequestHeaders();
Headers rmap = t.getResponseHeaders();
OutputStream os = t.getResponseBody();
URI uri = t.getRequestURI();
String path = uri.getPath();
while (is.read() != -1) ;
is.close();
File f = new File(_docroot, path);
if (!f.exists()) {
notfound(t, path);
return;
}
String method = t.getRequestMethod();
if (method.equals("HEAD")) {
rmap.set("Content-Length", Long.toString(f.length()));
t.sendResponseHeaders(200, -1);
t.close();
} else if (!method.equals("GET")) {
t.sendResponseHeaders(405, -1);
t.close();
return;
}
if (path.endsWith(".html") || path.endsWith(".htm")) {
rmap.set("Content-Type", "text/html");
} else {
rmap.set("Content-Type", "text/plain");
}
t.sendResponseHeaders (200, f.length());
FileInputStream fis = new FileInputStream(f);
int count = 0;
try {
byte[] buf = new byte[16 * 1024];
int len;
while ((len = fis.read(buf)) != -1) {
os.write(buf, 0, len);
count += len;
}
} catch (IOException e) {
e.printStackTrace();
}
fis.close();
os.close();
}
void moved(HttpExchange t) throws IOException {
Headers req = t.getRequestHeaders();
Headers map = t.getResponseHeaders();
URI uri = t.getRequestURI();
String host = req.getFirst("Host");
String location = "http://" + host + uri.getPath() + "/";
map.set("Content-Type", "text/html");
map.set("Location", location);
t.sendResponseHeaders(301, -1);
t.close();
}
void notfound(HttpExchange t, String p) throws IOException {
t.getResponseHeaders().set("Content-Type", "text/html");
t.sendResponseHeaders(404, 0);
OutputStream os = t.getResponseBody();
String s = "<h2>File not found</h2>";
s = s + p + "<p>";
os.write(s.getBytes());
os.close();
t.close();
}
}
}

View File

@ -0,0 +1,76 @@
/*
* 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.
*
* 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 catalog;
import java.net.URI;
import javax.xml.catalog.CatalogFeatures;
import javax.xml.catalog.CatalogManager;
import javax.xml.catalog.CatalogResolver;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
import org.xml.sax.InputSource;
import static jaxp.library.JAXPTestUtilities.tryRunWithAllPerm;
/*
* @test
* @bug 8171243
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true catalog.CatalogAccessTest
* @summary the Catalog API grants no privilege to external resources. This test
* verifies that SecurityException will be thrown if access to resources is denied
* by the security manager.
*/
@Listeners({jaxp.library.BasePolicy.class})
public class CatalogAccessTest {
static final CatalogFeatures FEATURES = CatalogFeatures.builder().
with(CatalogFeatures.Feature.PREFER, "system").build();
/*
* Verifies that the SecurityException is thrown if access to the resource is
* denied by the security manager.
*/
@Test(dataProvider = "accessTest", expectedExceptions = SecurityException.class)
public void testSecurity(String cfile, String sysId, String pubId) throws Exception {
CatalogResolver cr = CatalogManager.catalogResolver(FEATURES, URI.create(cfile));
InputSource is = cr.resolveEntity(pubId, sysId);
Assert.fail("Failed to throw SecurityException");
}
/*
DataProvider: used for SecurityException testing
Data columns:
catalog uri, systemId, publicId
*/
@DataProvider(name = "accessTest")
Object[][] getDataForAccessTest() throws Exception {
String systemId = "http://www.sys00test.com/rewrite.dtd";
String publicId = "PUB-404";
String urlFile = tryRunWithAllPerm(() ->
getClass().getResource("rewriteSystem_id.xml").toExternalForm());
return new Object[][]{
{urlFile, systemId, publicId}
};
}
}

View File

@ -0,0 +1,282 @@
/*
* 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.
*
* 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 catalog;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import static java.nio.file.StandardOpenOption.APPEND;
import static java.nio.file.StandardOpenOption.CREATE;
import javax.xml.catalog.Catalog;
import javax.xml.catalog.CatalogException;
import javax.xml.catalog.CatalogFeatures;
import javax.xml.catalog.CatalogManager;
import javax.xml.catalog.CatalogResolver;
import static jaxp.library.JAXPTestUtilities.getSystemProperty;
import jaxp.library.JarUtils;
import jaxp.library.SimpleHttpServer;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
import org.xml.sax.InputSource;
/*
* @test
* @bug 8151154 8171243
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm catalog.CatalogFileInputTest
* @summary Verifies that the Catalog API accepts valid URIs only;
Verifies that the CatalogFeatures' builder throws
* IllegalArgumentException on invalid file inputs.
* This test was splitted from CatalogTest.java due to
* JDK-8168968, it has to only run without SecurityManager
* because an ACE will be thrown for invalid path.
*/
@Listeners({jaxp.library.FilePolicy.class, jaxp.library.NetAccessPolicy.class})
public class CatalogFileInputTest extends CatalogSupportBase {
static final CatalogFeatures FEATURES = CatalogFeatures.builder().
with(CatalogFeatures.Feature.PREFER, "system").build();
static String USER_DIR = getSystemProperty("user.dir");
static String CLS_DIR = getSystemProperty("test.classes");
static String SRC_DIR = System.getProperty("test.src");
static String JAR_CONTENT = "META-INF";
final static String SCHEME_JARFILE = "jar:";
static final String REMOTE_FILE_LOCATION = "/jar/META-INF";
static final String DOCROOT = SRC_DIR;
static final String TESTCONTEXT = REMOTE_FILE_LOCATION; //mapped to local file path
SimpleHttpServer _httpserver;
String _remoteFilePath;
/*
* Initializing fields
*/
@BeforeClass
public void setUpClass() throws Exception {
super.setUp();
// set up HttpServer
_httpserver = new SimpleHttpServer(TESTCONTEXT, DOCROOT);
_httpserver.start();
_remoteFilePath = _httpserver.getAddress() + REMOTE_FILE_LOCATION;
}
@AfterClass
protected void tearDown() throws Exception {
if (_httpserver != null) {
_httpserver.stop();
}
}
/*
* Verifies that the Catalog can be created with file system paths including JAR
* and http URL, and used to resolve a systemId as expected.
*/
@Test(dataProvider = "acceptedURI")
public void testMatch(String uri, String sysId, String pubId,
String expectedId, String msg) throws Exception {
CatalogResolver cr = CatalogManager.catalogResolver(FEATURES, URI.create(uri));
InputSource is = cr.resolveEntity(pubId, sysId);
Assert.assertNotNull(is, msg);
Assert.assertEquals(expectedId, is.getSystemId(), msg);
}
@Test(dataProvider = "invalidCatalog")
public void testEmptyCatalog(String uri, String publicId, String msg) {
Catalog c = CatalogManager.catalog(FEATURES, uri != null? URI.create(uri) : null);
Assert.assertNull(c.matchSystem(publicId), msg);
}
@Test(dataProvider = "invalidCatalog", expectedExceptions = CatalogException.class)
public void testCatalogResolverWEmptyCatalog(String uri, String publicId, String msg) {
CatalogResolver cr = CatalogManager.catalogResolver(
CatalogFeatures.builder().with(CatalogFeatures.Feature.RESOLVE, "strict").build(),
uri != null? URI.create(uri) : null);
InputSource is = cr.resolveEntity(publicId, "");
}
@Test(dataProvider = "invalidCatalog")
public void testCatalogResolverWEmptyCatalog1(String uri, String publicId, String msg) {
CatalogResolver cr = CatalogManager.catalogResolver(
CatalogFeatures.builder().with(CatalogFeatures.Feature.RESOLVE, "continue").build(),
uri != null? URI.create(uri) : null);
Assert.assertNull(cr.resolveEntity(publicId, ""), msg);
}
@Test(dataProvider = "invalidInput", expectedExceptions = IllegalArgumentException.class)
public void testFileInput(String file) {
CatalogFeatures features = CatalogFeatures.builder()
.with(CatalogFeatures.Feature.FILES, file)
.build();
}
@Test(dataProvider = "invalidInput", expectedExceptions = IllegalArgumentException.class)
public void testInvalidUri(String file) {
CatalogResolver cr = CatalogManager.catalogResolver(FEATURES, file != null? URI.create(file) : null);
}
@Test(dataProvider = "invalidInput", expectedExceptions = IllegalArgumentException.class)
public void testInvalidUri1(String file) {
Catalog c = CatalogManager.catalog(FEATURES, file != null? URI.create(file) : null);
System.err.println("Catalog =" + c);
}
@Test(expectedExceptions = NullPointerException.class)
public void testNullFileInput() {
CatalogFeatures features = CatalogFeatures.builder()
.with(CatalogFeatures.Feature.FILES, null)
.build();
}
@Test(expectedExceptions = NullPointerException.class)
public void testNullUri() {
URI uri = null;
CatalogResolver cr = CatalogManager.catalogResolver(FEATURES, uri);
}
@Test(expectedExceptions = NullPointerException.class)
public void testNullUri1() {
URI uri = null;
Catalog c = CatalogManager.catalog(FEATURES, uri);
}
String systemId = "http://www.sys00test.com/rewrite.dtd";
String publicId = "PUB-404";
String expected = "http://www.groupxmlbase.com/dtds/rewrite.dtd";
String errMsg = "Relative rewriteSystem with xml:base at group level failed";
/*
DataProvider: used to verify CatalogResolver's resolveEntity function.
Data columns:
catalog, systemId, publicId, expectedUri, msg
*/
@DataProvider(name = "acceptedURI")
Object[][] getData() throws Exception {
String filename = "rewriteSystem_id.xml";
String urlFile = getClass().getResource(filename).toExternalForm();
String urlHttp = _remoteFilePath + "/jax-ws-catalog.xml";
String remoteXSD = _remoteFilePath + "/catalog/ws-addr.xsd";
File file = new File(CLS_DIR + "/JDK8171243.jar!/META-INF/jax-ws-catalog.xml");
String jarPath = SCHEME_JARFILE + file.toURI().toString();
String xsd = jarPath.substring(0, jarPath.lastIndexOf("/")) + "/catalog/ws-addr.xsd";
// create JAR file
try {
JarUtils.createJarFile(Paths.get(CLS_DIR + "/JDK8171243.jar"),
Paths.get(SRC_DIR + "/jar"), JAR_CONTENT);
} catch (IOException ex) {
Assert.fail("Failed to create JAR: " + ex.getMessage());
}
return new Object[][]{
// URL
{urlFile, systemId, publicId, expected, errMsg},
{urlHttp, "http://www.w3.org/2006/03/addressing/ws-addr.xsd", "", remoteXSD, "http test failed."},
// JAR file
{jarPath, "http://www.w3.org/2006/03/addressing/ws-addr.xsd", "", xsd, "jar file test failed."},
};
}
/*
* DataProvider: invalid catalog result in empty catalog
* Note: the difference from invalidInput is that invalidInput is syntactically
* rejected with an IAE.
*/
@DataProvider(name = "invalidCatalog")
public Object[][] getInvalidCatalog() throws Exception {
String catalogUri = getClass().getResource("catalog_invalid.xml").toExternalForm();
return new Object[][]{
{catalogUri, "-//W3C//DTD XHTML 1.0 Strict//EN",
"The catalog is invalid, attempting to match the public entry shall return null."}
};
}
/*
* DataProvider: a list of invalid inputs, expects IAE
* Note: exclude null since NPE would have been expected
*/
@DataProvider(name = "invalidInput")
public Object[][] getFiles() throws Exception {
String filename = "rewriteSystem_id.xml";
copyFile(Paths.get(SRC_DIR + "/" + filename), Paths.get(filename));
String absolutePath = getClass().getResource(filename).getFile();
return new Object[][]{
{""},
{"file:a/b\\c"},
{"file:/../../.."},
{"c:/te:t"},
{"c:/te?t"},
{"c/te*t"},
{"in|valid.txt"},
{"shema:invalid.txt"},
// relative file path
{filename},
// absolute file path
{absolutePath}
};
}
/*
DataProvider: a list of invalid inputs
*/
@DataProvider(name = "nullTest")
public Object[][] getNull() throws Exception {
return new Object[][]{
{null},
};
}
void copyFile(Path src, Path target) throws Exception {
try (InputStream in = Files.newInputStream(src);
BufferedReader reader
= new BufferedReader(new InputStreamReader(in));
OutputStream out = new BufferedOutputStream(
Files.newOutputStream(target, CREATE, APPEND));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out))) {
String line = null;
while ((line = reader.readLine()) != null) {
bw.write(line);
}
} catch (IOException x) {
throw new Exception(x.getMessage());
}
}
}

View File

@ -1,66 +0,0 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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 catalog;
import javax.xml.catalog.CatalogFeatures;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/*
* @test
* @bug 8151154
* @run testng/othervm catalog.CatalogInvalidPathTest
* @summary Verifies that the CatalogFeatures' builder throws
* IllegalArgumentException on invalid file inputs.
* This test was splitted from CatalogTest.java due to
* JDK-8168968, it has to only run without SecurityManager
* because an ACE will be thrown for invalid path.
*/
public class CatalogInvalidPathTest {
/*
DataProvider: for testing the verification of file paths by
the CatalogFeatures builder
*/
@DataProvider(name = "invalidPaths")
public Object[][] getFiles() {
return new Object[][]{
{null},
{""},
{"file:a/b\\c"},
{"file:/../../.."},
{"c:/te:t"},
{"c:/te?t"},
{"c/te*t"},
{"in|valid.txt"},
{"shema:invalid.txt"},
};
}
@Test(dataProvider = "invalidPaths", expectedExceptions = IllegalArgumentException.class)
public void testFileInput(String file) {
CatalogFeatures features = CatalogFeatures.builder()
.with(CatalogFeatures.Feature.FILES, file)
.build();
}
}

View File

@ -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
@ -35,6 +35,13 @@ import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.nio.file.Paths;
import java.security.CodeSource;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.Policy;
import java.security.ProtectionDomain;
import javax.xml.XMLConstants;
import javax.xml.catalog.CatalogFeatures;
import javax.xml.catalog.CatalogResolver;
@ -133,8 +140,8 @@ public class CatalogSupportBase {
dtd_system = filepath + "system.dtd";
dtd_systemResolved = "<!ENTITY system \"resolved by an EntityHandler, rather than a Catalog\">";
xml_catalog = filepath + "CatalogSupport.xml";
xml_bogus_catalog = filepath + "CatalogSupport_bogus.xml";
xml_catalog = Paths.get(filepath + "CatalogSupport.xml").toUri().toASCIIString();
xml_bogus_catalog = Paths.get(filepath + "CatalogSupport_bogus.xml").toUri().toASCIIString();
xml_xInclude = "<?xml version=\"1.0\"?>\n" +
"<xinclude:include xmlns:xinclude=\"http://www.w3.org/2001/XInclude\"\n" +
@ -997,4 +1004,35 @@ public class CatalogSupportBase {
return null;
}
}
/**
* Simple policy implementation that grants a set of permissions to all code
* sources and protection domains.
*/
static class SimplePolicy extends Policy {
private final Permissions perms;
public SimplePolicy(Permission... permissions) {
perms = new Permissions();
for (Permission permission : permissions) {
perms.add(permission);
}
}
@Override
public PermissionCollection getPermissions(CodeSource cs) {
return perms;
}
@Override
public PermissionCollection getPermissions(ProtectionDomain pd) {
return perms;
}
@Override
public boolean implies(ProtectionDomain pd, Permission p) {
return perms.implies(p);
}
}
}

View File

@ -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
@ -22,17 +22,14 @@
*/
package catalog;
import static jaxp.library.JAXPTestUtilities.clearSystemProperty;
import static jaxp.library.JAXPTestUtilities.setSystemProperty;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.URI;
import java.nio.file.Paths;
import javax.xml.XMLConstants;
import javax.xml.catalog.Catalog;
import javax.xml.catalog.CatalogException;
@ -55,7 +52,8 @@ import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import static jaxp.library.JAXPTestUtilities.clearSystemProperty;
import static jaxp.library.JAXPTestUtilities.setSystemProperty;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
@ -95,10 +93,10 @@ public class CatalogTest extends CatalogSupportBase {
* CatalogException is thrown.
*/
@Test(dataProvider = "getFeatures", expectedExceptions = CatalogException.class)
public void testCircularRef(CatalogFeatures cf, String xml) {
public void testCircularRef(CatalogFeatures cf, String xml) throws Exception {
CatalogResolver catalogResolver = CatalogManager.catalogResolver(
cf,
getClass().getResource(xml).getFile());
getClass().getResource(xml).toURI());
catalogResolver.resolve("anyuri", "");
}
@ -108,14 +106,14 @@ public class CatalogTest extends CatalogSupportBase {
*/
@DataProvider(name = "getFeatures")
public Object[][] getFeatures() {
String self = "catalogReferCircle-itself.xml";
String left = "catalogReferCircle-left.xml";
return new Object[][]{
{CatalogFeatures.builder().with(CatalogFeatures.Feature.DEFER, "false").build(),
"catalogReferCircle-itself.xml"},
{CatalogFeatures.defaults(), "catalogReferCircle-itself.xml"},
{CatalogFeatures.builder().with(CatalogFeatures.Feature.DEFER, "false").build(),
"catalogReferCircle-left.xml"},
{CatalogFeatures.defaults(), "catalogReferCircle-left.xml"},};
{CatalogFeatures.builder().with(CatalogFeatures.Feature.DEFER, "false").build(), self},
{CatalogFeatures.defaults(), self},
{CatalogFeatures.builder().with(CatalogFeatures.Feature.DEFER, "false").build(), left},
{CatalogFeatures.defaults(), left}
};
}
/*
@ -134,7 +132,7 @@ public class CatalogTest extends CatalogSupportBase {
* Expected: the parser returns the expected string.
*/
@Test(dataProvider = "supportXMLResolver")
public void supportEntityResolver(String catalogFile, String xml, String expected) throws Exception {
public void supportEntityResolver(URI catalogFile, String xml, String expected) throws Exception {
String xmlSource = getClass().getResource(xml).getFile();
CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile);
@ -150,7 +148,7 @@ public class CatalogTest extends CatalogSupportBase {
* Expected: the parser returns the expected string.
*/
@Test(dataProvider = "supportXMLResolver")
public void supportXMLResolver(String catalogFile, String xml, String expected) throws Exception {
public void supportXMLResolver(URI catalogFile, String xml, String expected) throws Exception {
String xmlSource = getClass().getResource(xml).getFile();
CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile);
@ -159,7 +157,7 @@ public class CatalogTest extends CatalogSupportBase {
xifactory.setProperty(XMLInputFactory.IS_COALESCING, true);
xifactory.setProperty(XMLInputFactory.RESOLVER, cr);
File file = new File(xmlSource);
String systemId = file.toURI().toString();
String systemId = file.toURI().toASCIIString();
InputStream entityxml = new FileInputStream(file);
XMLStreamReader streamReader = xifactory.createXMLStreamReader(systemId, entityxml);
String result = null;
@ -183,7 +181,7 @@ public class CatalogTest extends CatalogSupportBase {
* Fail: throws Exception if references are not resolved (by the CatalogResolver)
*/
@Test(dataProvider = "supportLSResourceResolver")
public void supportLSResourceResolver(String catalogFile, Source schemaSource) throws SAXException {
public void supportLSResourceResolver(URI catalogFile, Source schemaSource) throws SAXException {
CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile);
@ -199,7 +197,7 @@ public class CatalogTest extends CatalogSupportBase {
* Fail: throws Exception if references are not resolved (by the CatalogResolver)
*/
@Test(dataProvider = "supportLSResourceResolver1")
public void supportLSResourceResolver1(String catalogFile, Source source) throws Exception {
public void supportLSResourceResolver1(URI catalogFile, Source source) throws Exception {
CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile);
@ -215,7 +213,7 @@ public class CatalogTest extends CatalogSupportBase {
* Fail: throws Exception if references are not resolved (by the CatalogResolver)
*/
@Test(dataProvider = "supportURIResolver")
public void supportURIResolver(String catalogFile, Source xsl, Source xml, String expected) throws Exception {
public void supportURIResolver(URI catalogFile, Source xsl, Source xml, String expected) throws Exception {
CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile);
@ -235,9 +233,9 @@ public class CatalogTest extends CatalogSupportBase {
catalog filepath, xml source file, expected result
*/
@DataProvider(name = "supportXMLResolver")
public Object[][] supportXMLResolver() {
String catalogFile = getClass().getResource("catalog.xml").getFile();
String catalogFileUri = getClass().getResource("catalog_uri.xml").getFile();
public Object[][] supportXMLResolver() throws Exception {
URI catalogFile = getClass().getResource("catalog.xml").toURI();
URI catalogFileUri = getClass().getResource("catalog_uri.xml").toURI();
return new Object[][]{
{catalogFile, "system.xml", "Test system entry"},
@ -263,9 +261,9 @@ public class CatalogTest extends CatalogSupportBase {
catalog filepath, schema source file
*/
@DataProvider(name = "supportLSResourceResolver")
public Object[][] supportLSResourceResolver() {
String catalogFile = getClass().getResource("CatalogSupport.xml").getFile();
String catalogFileUri = getClass().getResource("CatalogSupport_uri.xml").getFile();
public Object[][] supportLSResourceResolver() throws Exception {
URI catalogFile = getClass().getResource("CatalogSupport.xml").toURI();
URI catalogFileUri = getClass().getResource("CatalogSupport_uri.xml").toURI();
/*
* XMLSchema.xsd has a reference to XMLSchema.dtd which in turn refers to
@ -287,9 +285,9 @@ public class CatalogTest extends CatalogSupportBase {
catalog filepath, source file
*/
@DataProvider(name = "supportLSResourceResolver1")
public Object[][] supportLSResourceResolver1() {
String catalogFile = getClass().getResource("CatalogSupport.xml").getFile();
String catalogFileUri = getClass().getResource("CatalogSupport_uri.xml").getFile();
public Object[][] supportLSResourceResolver1() throws Exception {
URI catalogFile = getClass().getResource("CatalogSupport.xml").toURI();
URI catalogFileUri = getClass().getResource("CatalogSupport_uri.xml").toURI();
/*
* val_test.xml has a reference to system.dtd and val_test.xsd
@ -310,9 +308,9 @@ public class CatalogTest extends CatalogSupportBase {
catalog filepath, xsl source, xml source file
*/
@DataProvider(name = "supportURIResolver")
public Object[][] supportURIResolver() {
String catalogFile = getClass().getResource("CatalogSupport.xml").getFile();
String catalogFileUri = getClass().getResource("CatalogSupport_uri.xml").getFile();
public Object[][] supportURIResolver() throws Exception {
URI catalogFile = getClass().getResource("CatalogSupport.xml").toURI();
URI catalogFileUri = getClass().getResource("CatalogSupport_uri.xml").toURI();
SAXSource xslSource = new SAXSource(new InputSource(new File(xsl_doc).toURI().toASCIIString()));
/*
@ -353,8 +351,9 @@ public class CatalogTest extends CatalogSupportBase {
* other cases in that test.
*/
@Test(dataProvider = "resolveUri")
public void testMatch1(String cFile, String href, String expectedFile, String expectedUri, String msg) {
String catalogFile = getClass().getResource(cFile).getFile();
public void testMatch1(String cFile, String href, String expectedFile,
String expectedUri, String msg) throws Exception {
URI catalogFile = getClass().getResource(cFile).toURI();
CatalogResolver cur = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile);
Source source = cur.resolve(href, null);
Assert.assertNotNull(source, "Source returned is null");
@ -368,15 +367,16 @@ public class CatalogTest extends CatalogSupportBase {
*/
@Test(dataProvider = "hierarchyOfCatFilesData")
public void hierarchyOfCatFiles2(String systemId, String expectedUri) {
String file1 = getClass().getResource("first_cat.xml").getFile();
String file2 = getClass().getResource("second_cat.xml").getFile();
String file1 = getClass().getResource("first_cat.xml").toExternalForm();
String file2 = getClass().getResource("second_cat.xml").toExternalForm();
String files = file1 + ";" + file2;
try {
setSystemProperty(KEY_FILES, files);
CatalogResolver catalogResolver = CatalogManager.catalogResolver(CatalogFeatures.defaults());
String sysId = catalogResolver.resolveEntity(null, systemId).getSystemId();
Assert.assertEquals(sysId, Paths.get(filepath + expectedUri).toUri().toString().replace("///", "/"), "System ID match not right");
Assert.assertEquals(sysId, Paths.get(filepath + expectedUri).toUri().toString().replace("///", "/"),
"System ID match not right");
} finally {
clearSystemProperty(KEY_FILES);
}
@ -390,8 +390,9 @@ public class CatalogTest extends CatalogSupportBase {
* expected.
*/
@Test(dataProvider = "resolveEntity")
public void testMatch1(String cfile, String prefer, String sysId, String pubId, String expectedUri, String expectedFile, String msg) {
String catalogFile = getClass().getResource(cfile).getFile();
public void testMatch1(String cfile, String prefer, String sysId, String pubId,
String expectedUri, String expectedFile, String msg) throws Exception {
URI catalogFile = getClass().getResource(cfile).toURI();
CatalogFeatures features = CatalogFeatures.builder().with(CatalogFeatures.Feature.PREFER, prefer).build();
CatalogResolver catalogResolver = CatalogManager.catalogResolver(features, catalogFile);
InputSource is = catalogResolver.resolveEntity(pubId, sysId);
@ -406,9 +407,12 @@ public class CatalogTest extends CatalogSupportBase {
* results as expected.
*/
@Test(dataProvider = "matchWithPrefer")
public void matchWithPrefer(String prefer, String cfile, String publicId, String systemId, String expected) {
String catalogFile = getClass().getResource(cfile).getFile();
Catalog c = CatalogManager.catalog(CatalogFeatures.builder().with(CatalogFeatures.Feature.PREFER, prefer).build(), catalogFile);
public void matchWithPrefer(String prefer, String cfile, String publicId,
String systemId, String expected) throws Exception {
URI catalogFile = getClass().getResource(cfile).toURI();
Catalog c = CatalogManager.catalog(
CatalogFeatures.builder().with(CatalogFeatures.Feature.PREFER, prefer).build(),
catalogFile);
String result;
if (publicId != null && publicId.length() > 0) {
result = c.matchPublic(publicId);
@ -430,8 +434,9 @@ public class CatalogTest extends CatalogSupportBase {
* system entry is found.
*/
@Test(dataProvider = "resolveWithPrefer")
public void resolveWithPrefer(String prefer, String cfile, String publicId, String systemId, String expected) {
String catalogFile = getClass().getResource(cfile).getFile();
public void resolveWithPrefer(String prefer, String cfile, String publicId,
String systemId, String expected) throws Exception {
URI catalogFile = getClass().getResource(cfile).toURI();
CatalogFeatures f = CatalogFeatures.builder().with(CatalogFeatures.Feature.PREFER, prefer).with(CatalogFeatures.Feature.RESOLVE, "ignore").build();
CatalogResolver catalogResolver = CatalogManager.catalogResolver(f, catalogFile);
String result = catalogResolver.resolveEntity(publicId, systemId).getSystemId();
@ -445,8 +450,8 @@ public class CatalogTest extends CatalogSupportBase {
* be loaded is determined by the defer attribute.
*/
@Test(dataProvider = "invalidAltCatalogs", expectedExceptions = CatalogException.class)
public void testDeferAltCatalogs(String file) {
String catalogFile = getClass().getResource(file).getFile();
public void testDeferAltCatalogs(String file) throws Exception {
URI catalogFile = getClass().getResource(file).toURI();
CatalogFeatures features = CatalogFeatures.builder().with(CatalogFeatures.Feature.DEFER, "true").build();
/*
Since the defer attribute is set to false in the specified catalog file,
@ -462,8 +467,8 @@ public class CatalogTest extends CatalogSupportBase {
* PREFER from Features API taking precedence over catalog file
*/
@Test
public void testJDK8146237() {
String catalogFile = getClass().getResource("JDK8146237_catalog.xml").getFile();
public void testJDK8146237() throws Exception {
URI catalogFile = getClass().getResource("JDK8146237_catalog.xml").toURI();
try {
CatalogFeatures features = CatalogFeatures.builder().with(CatalogFeatures.Feature.PREFER, "system").build();
@ -482,8 +487,8 @@ public class CatalogTest extends CatalogSupportBase {
Verifies that the resulting systemId does not contain duplicate slashes
*/
@Test
public void testRewriteSystem() {
String catalog = getClass().getResource("rewriteCatalog.xml").getFile();
public void testRewriteSystem() throws Exception {
URI catalog = getClass().getResource("rewriteCatalog.xml").toURI();
try {
CatalogResolver resolver = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalog);
@ -500,8 +505,8 @@ public class CatalogTest extends CatalogSupportBase {
Verifies that the resulting systemId does not contain duplicate slashes
*/
@Test
public void testRewriteUri() {
String catalog = getClass().getResource("rewriteCatalog.xml").getFile();
public void testRewriteUri() throws Exception {
URI catalog = getClass().getResource("rewriteCatalog.xml").toURI();
try {
@ -519,18 +524,18 @@ public class CatalogTest extends CatalogSupportBase {
*/
@Test(expectedExceptions = NullPointerException.class)
public void testFeatureNull() {
CatalogResolver resolver = CatalogManager.catalogResolver(null, "");
CatalogResolver resolver = CatalogManager.catalogResolver(null, null);
}
/*
@bug 8144966
Verifies that passing null as the path will result in a NPE.
Verifies that passing null as the URI will result in a NPE.
*/
@Test(expectedExceptions = NullPointerException.class)
public void testPathNull() {
String path = null;
CatalogResolver resolver = CatalogManager.catalogResolver(CatalogFeatures.defaults(), path);
URI uri = null;
CatalogResolver resolver = CatalogManager.catalogResolver(CatalogFeatures.defaults(), uri);
}
/*
@ -540,10 +545,11 @@ public class CatalogTest extends CatalogSupportBase {
that matches the expected value.
*/
@Test(dataProvider = "catalog")
public void testCatalogResolver(String test, String expected, String catalogFile, String xml, SAXParser saxParser) {
String catalog = null;
public void testCatalogResolver(String test, String expected, String catalogFile,
String xml, SAXParser saxParser) throws Exception {
URI catalog = null;
if (catalogFile != null) {
catalog = getClass().getResource(catalogFile).getFile();
catalog = getClass().getResource(catalogFile).toURI();
}
String url = getClass().getResource(xml).getFile();
try {
@ -565,8 +571,8 @@ public class CatalogTest extends CatalogSupportBase {
catalog is provided, the resolver will throw an exception by default.
*/
@Test
public void testInvalidCatalog() {
String catalog = getClass().getResource("catalog_invalid.xml").getFile();
public void testInvalidCatalog() throws Exception {
URI catalog = getClass().getResource("catalog_invalid.xml").toURI();
String test = "testInvalidCatalog";
try {
@ -590,7 +596,7 @@ public class CatalogTest extends CatalogSupportBase {
*/
@Test
public void testIgnoreInvalidCatalog() {
String catalog = getClass().getResource("catalog_invalid.xml").getFile();
String catalog = getClass().getResource("catalog_invalid.xml").toExternalForm();
CatalogFeatures f = CatalogFeatures.builder()
.with(Feature.FILES, catalog)
.with(Feature.PREFER, "public")
@ -600,7 +606,7 @@ public class CatalogTest extends CatalogSupportBase {
String test = "testInvalidCatalog";
try {
CatalogResolver resolver = CatalogManager.catalogResolver(f, "");
CatalogResolver resolver = CatalogManager.catalogResolver(f);
String actualSystemId = resolver.resolveEntity(null, "http://remote/xml/dtd/sys/alice/docAlice.dtd").getSystemId();
System.out.println("testIgnoreInvalidCatalog: expected [null]");
System.out.println("testIgnoreInvalidCatalog: expected [null]");

View File

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Created-By: 9-ea (Oracle Corporation)

View File

@ -0,0 +1,137 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
W3C XML Schema defined in the Web Services Addressing 1.0 specification
http://www.w3.org/TR/ws-addr-core
Copyright © 2005 World Wide Web Consortium,
(Massachusetts Institute of Technology, European Research Consortium for
Informatics and Mathematics, Keio University). All Rights Reserved. This
work is distributed under the W3C® Software License [1] 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.
[1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
$Id: ws-addr.xsd,v 1.2 2008/07/23 13:38:16 plehegar Exp $
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.w3.org/2005/08/addressing" targetNamespace="http://www.w3.org/2005/08/addressing" blockDefault="#all" elementFormDefault="qualified" finalDefault="" attributeFormDefault="unqualified">
<!-- Constructs from the WS-Addressing Core -->
<xs:element name="EndpointReference" type="tns:EndpointReferenceType"/>
<xs:complexType name="EndpointReferenceType" mixed="false">
<xs:sequence>
<xs:element name="Address" type="tns:AttributedURIType"/>
<xs:element ref="tns:ReferenceParameters" minOccurs="0"/>
<xs:element ref="tns:Metadata" minOccurs="0"/>
<xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:anyAttribute namespace="##other" processContents="lax"/>
</xs:complexType>
<xs:element name="ReferenceParameters" type="tns:ReferenceParametersType"/>
<xs:complexType name="ReferenceParametersType" mixed="false">
<xs:sequence>
<xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:anyAttribute namespace="##other" processContents="lax"/>
</xs:complexType>
<xs:element name="Metadata" type="tns:MetadataType"/>
<xs:complexType name="MetadataType" mixed="false">
<xs:sequence>
<xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:anyAttribute namespace="##other" processContents="lax"/>
</xs:complexType>
<xs:element name="MessageID" type="tns:AttributedURIType"/>
<xs:element name="RelatesTo" type="tns:RelatesToType"/>
<xs:complexType name="RelatesToType" mixed="false">
<xs:simpleContent>
<xs:extension base="xs:anyURI">
<xs:attribute name="RelationshipType" type="tns:RelationshipTypeOpenEnum" use="optional" default="http://www.w3.org/2005/08/addressing/reply"/>
<xs:anyAttribute namespace="##other" processContents="lax"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name="RelationshipTypeOpenEnum">
<xs:union memberTypes="tns:RelationshipType xs:anyURI"/>
</xs:simpleType>
<xs:simpleType name="RelationshipType">
<xs:restriction base="xs:anyURI">
<xs:enumeration value="http://www.w3.org/2005/08/addressing/reply"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="ReplyTo" type="tns:EndpointReferenceType"/>
<xs:element name="From" type="tns:EndpointReferenceType"/>
<xs:element name="FaultTo" type="tns:EndpointReferenceType"/>
<xs:element name="To" type="tns:AttributedURIType"/>
<xs:element name="Action" type="tns:AttributedURIType"/>
<xs:complexType name="AttributedURIType" mixed="false">
<xs:simpleContent>
<xs:extension base="xs:anyURI">
<xs:anyAttribute namespace="##other" processContents="lax"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<!-- Constructs from the WS-Addressing SOAP binding -->
<xs:attribute name="IsReferenceParameter" type="xs:boolean"/>
<xs:simpleType name="FaultCodesOpenEnumType">
<xs:union memberTypes="tns:FaultCodesType xs:QName"/>
</xs:simpleType>
<xs:simpleType name="FaultCodesType">
<xs:restriction base="xs:QName">
<xs:enumeration value="tns:InvalidAddressingHeader"/>
<xs:enumeration value="tns:InvalidAddress"/>
<xs:enumeration value="tns:InvalidEPR"/>
<xs:enumeration value="tns:InvalidCardinality"/>
<xs:enumeration value="tns:MissingAddressInEPR"/>
<xs:enumeration value="tns:DuplicateMessageID"/>
<xs:enumeration value="tns:ActionMismatch"/>
<xs:enumeration value="tns:MessageAddressingHeaderRequired"/>
<xs:enumeration value="tns:DestinationUnreachable"/>
<xs:enumeration value="tns:ActionNotSupported"/>
<xs:enumeration value="tns:EndpointUnavailable"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="RetryAfter" type="tns:AttributedUnsignedLongType"/>
<xs:complexType name="AttributedUnsignedLongType" mixed="false">
<xs:simpleContent>
<xs:extension base="xs:unsignedLong">
<xs:anyAttribute namespace="##other" processContents="lax"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name="ProblemHeaderQName" type="tns:AttributedQNameType"/>
<xs:complexType name="AttributedQNameType" mixed="false">
<xs:simpleContent>
<xs:extension base="xs:QName">
<xs:anyAttribute namespace="##other" processContents="lax"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name="ProblemIRI" type="tns:AttributedURIType"/>
<xs:element name="ProblemAction" type="tns:ProblemActionType"/>
<xs:complexType name="ProblemActionType" mixed="false">
<xs:sequence>
<xs:element ref="tns:Action" minOccurs="0"/>
<xs:element name="SoapAction" minOccurs="0" type="xs:anyURI"/>
</xs:sequence>
<xs:anyAttribute namespace="##other" processContents="lax"/>
</xs:complexType>
</xs:schema>

View File

@ -0,0 +1,4 @@
<?xml version='1.0' encoding='UTF-8'?>
<catalog prefer="system" xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<system systemId="http://www.w3.org/2006/03/addressing/ws-addr.xsd" uri="./catalog/ws-addr.xsd"/>
</catalog>

View File

@ -37,6 +37,7 @@ import java.io.StringWriter;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
@ -74,11 +75,30 @@ import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
* @run testng/othervm -DrunSecMngr=true transform.TransformerTest
* @run testng/othervm transform.TransformerTest
* @summary Transformer Tests
* @bug 6272879 6305029 6505031 8150704 8162598 8169112 8169772
* @bug 6272879 6305029 6505031 8150704 8162598 8169112 8169631 8169772
*/
@Listeners({jaxp.library.FilePolicy.class})
public class TransformerTest {
// some global constants
private static final String LINE_SEPARATOR =
getSystemProperty("line.separator");
private static final String NAMESPACES =
"http://xml.org/sax/features/namespaces";
private static final String NAMESPACE_PREFIXES =
"http://xml.org/sax/features/namespace-prefixes";
private static abstract class TestTemplate {
protected void printSnippet(String title, String snippet) {
StringBuilder div = new StringBuilder();
for (int i = 0; i < title.length(); i++)
div.append("=");
System.out.println(title + "\n" + div + "\n" + snippet + "\n");
}
}
/**
* Reads the contents of the given file into a string.
* WARNING: this method adds a final line feed even if the last line of the file doesn't contain one.
@ -101,44 +121,7 @@ public class TransformerTest {
}
}
/**
* Utility method for testBug8162598().
* Provides a convenient way to check/assert the expected namespaces
* of a Node and its siblings.
*
* @param test
* The node to check
* @param nstest
* Expected namespace of the node
* @param nsb
* Expected namespace of the first sibling
* @param nsc
* Expected namespace of the first sibling of the first sibling
*/
private void checkNodeNS8162598(Node test, String nstest, String nsb, String nsc) {
String testNodeName = test.getNodeName();
if (nstest == null) {
Assert.assertNull(test.getNamespaceURI(), "unexpected namespace for " + testNodeName);
} else {
Assert.assertEquals(test.getNamespaceURI(), nstest, "unexpected namespace for " + testNodeName);
}
Node b = test.getChildNodes().item(0);
if (nsb == null) {
Assert.assertNull(b.getNamespaceURI(), "unexpected namespace for " + testNodeName + "->b");
} else {
Assert.assertEquals(b.getNamespaceURI(), nsb, "unexpected namespace for " + testNodeName + "->b");
}
Node c = b.getChildNodes().item(0);
if (nsc == null) {
Assert.assertNull(c.getNamespaceURI(), "unexpected namespace for " + testNodeName + "->b->c");
} else {
Assert.assertEquals(c.getNamespaceURI(), nsc, "unexpected namespace for " + testNodeName + "->b->c");
}
}
private class XMLReaderFor6305029 implements XMLReader {
private static final String NAMESPACES = "http://xml.org/sax/features/namespaces";
private static final String NAMESPACE_PREFIXES = "http://xml.org/sax/features/namespace-prefixes";
private boolean namespaces = true;
private boolean namespacePrefixes = false;
private EntityResolver resolver;
@ -235,8 +218,6 @@ public class TransformerTest {
*/
@Test
public final void testBug6272879() throws IOException, TransformerException {
final String LINE_SEPARATOR = getSystemProperty("line.separator");
final String xsl =
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" + LINE_SEPARATOR +
"<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">" + LINE_SEPARATOR +
@ -349,9 +330,125 @@ public class TransformerTest {
Assert.assertTrue(s.contains("map1key1value") && s.contains("map2key1value"));
}
private static class Test8169631 extends TestTemplate {
private final static String xsl =
"<?xml version=\"1.0\"?>" + LINE_SEPARATOR +
"<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">" + LINE_SEPARATOR +
" <xsl:template match=\"/\">" + LINE_SEPARATOR +
" <xsl:variable name=\"Counter\" select=\"count(//row)\"/>" + LINE_SEPARATOR +
" <xsl:variable name=\"AttribCounter\" select=\"count(//@attrib)\"/>" + LINE_SEPARATOR +
" <Counter><xsl:value-of select=\"$Counter\"/></Counter>" + LINE_SEPARATOR +
" <AttribCounter><xsl:value-of select=\"$AttribCounter\"/></AttribCounter>" + LINE_SEPARATOR +
" </xsl:template>" + LINE_SEPARATOR +
"</xsl:stylesheet>" + LINE_SEPARATOR;
private final static String sourceXml =
"<?xml version=\"1.0\"?>" + LINE_SEPARATOR +
"<envelope xmlns=\"http://www.sap.com/myns\" xmlns:sap=\"http://www.sap.com/myns\">" + LINE_SEPARATOR +
" <sap:row sap:attrib=\"a\">1</sap:row>" + LINE_SEPARATOR +
" <row attrib=\"b\">2</row>" + LINE_SEPARATOR +
" <row sap:attrib=\"c\">3</row>" + LINE_SEPARATOR +
"</envelope>" + LINE_SEPARATOR;
/**
* Utility method to print out transformation result and check values.
*
* @param type
* Text describing type of transformation
* @param result
* Resulting output of transformation
* @param elementCount
* Counter of elements to check
* @param attribCount
* Counter of attributes to check
*/
private void verifyResult(String type, String result, int elementCount,
int attribCount)
{
printSnippet("Result of transformation from " + type + ":",
result);
Assert.assertEquals(
result.contains("<Counter>" + elementCount + "</Counter>"),
true, "Result of transformation from " + type +
" should have count of " + elementCount + " elements.");
Assert.assertEquals(
result.contains("<AttribCounter>" + attribCount +
"</AttribCounter>"), true, "Result of transformation from " +
type + " should have count of "+ attribCount + " attributes.");
}
public void run() throws IOException, TransformerException,
SAXException, ParserConfigurationException
{
printSnippet("Source:", sourceXml);
printSnippet("Stylesheet:", xsl);
// create default transformer (namespace aware)
TransformerFactory tf1 = TransformerFactory.newInstance();
ByteArrayInputStream bais = new ByteArrayInputStream(xsl.getBytes());
Transformer t1 = tf1.newTransformer(new StreamSource(bais));
// test transformation from stream source with namespace support
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bais = new ByteArrayInputStream(sourceXml.getBytes());
t1.transform(new StreamSource(bais), new StreamResult(baos));
verifyResult("StreamSource with namespace support", baos.toString(), 0, 1);
// test transformation from DOM source with namespace support
bais.reset();
baos.reset();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc = dbf.newDocumentBuilder().parse(new InputSource(bais));
t1.transform(new DOMSource(doc), new StreamResult(baos));
verifyResult("DOMSource with namespace support", baos.toString(), 0, 1);
// test transformation from DOM source without namespace support
bais.reset();
baos.reset();
dbf.setNamespaceAware(false);
doc = dbf.newDocumentBuilder().parse(new InputSource(bais));
t1.transform(new DOMSource(doc), new StreamResult(baos));
verifyResult("DOMSource without namespace support", baos.toString(), 3, 3);
// test transformation from SAX source with namespace support
bais.reset();
baos.reset();
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
XMLReader xmlr = spf.newSAXParser().getXMLReader();
SAXSource saxS = new SAXSource(xmlr, new InputSource(bais));
t1.transform(saxS, new StreamResult(baos));
verifyResult("SAXSource with namespace support", baos.toString(), 0, 1);
// test transformation from SAX source without namespace support
bais.reset();
baos.reset();
spf.setNamespaceAware(false);
xmlr = spf.newSAXParser().getXMLReader();
saxS = new SAXSource(xmlr, new InputSource(bais));
t1.transform(saxS, new StreamResult(baos));
verifyResult("SAXSource without namespace support", baos.toString(), 3, 3);
}
}
/*
* @bug 8169631
* @summary Test combinations of namespace awareness settings on
* XSL transformations
*/
@Test
public final void testBug8169631() throws IOException, SAXException,
TransformerException, ParserConfigurationException
{
new Test8169631().run();
}
/*
* @bug 8150704
* @summary Test that XSL transformation with lots of temporary result trees will not run out of DTM IDs.
* @summary Test that XSL transformation with lots of temporary result
* trees will not run out of DTM IDs.
*/
@Test
public final void testBug8150704() throws TransformerException, IOException {
@ -375,16 +472,8 @@ public class TransformerTest {
System.out.println("Passed.");
}
/*
* @bug 8162598
* @summary Test XSLTC handling of namespaces, especially empty namespace definitions to reset the
* default namespace
*/
@Test
public final void testBug8162598() throws IOException, TransformerException {
final String LINE_SEPARATOR = getSystemProperty("line.separator");
final String xsl =
private static class Test8162598 extends TestTemplate {
private static final String xsl =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + LINE_SEPARATOR +
"<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">" + LINE_SEPARATOR +
" <xsl:template match=\"/\">" + LINE_SEPARATOR +
@ -402,39 +491,85 @@ public class TransformerTest {
" </xsl:template>" + LINE_SEPARATOR +
"</xsl:stylesheet>";
private static final String sourceXml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><aaa></aaa>" + LINE_SEPARATOR;
/**
* Utility method for testBug8162598().
* Provides a convenient way to check/assert the expected namespaces
* of a Node and its siblings.
*
* @param test
* The node to check
* @param nstest
* Expected namespace of the node
* @param nsb
* Expected namespace of the first sibling
* @param nsc
* Expected namespace of the first sibling of the first sibling
*/
final String sourceXml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><aaa></aaa>" + LINE_SEPARATOR;
private void checkNodeNS(Node test, String nstest, String nsb, String nsc) {
String testNodeName = test.getNodeName();
if (nstest == null) {
Assert.assertNull(test.getNamespaceURI(), "unexpected namespace for " + testNodeName);
} else {
Assert.assertEquals(test.getNamespaceURI(), nstest, "unexpected namespace for " + testNodeName);
}
Node b = test.getChildNodes().item(0);
if (nsb == null) {
Assert.assertNull(b.getNamespaceURI(), "unexpected namespace for " + testNodeName + "->b");
} else {
Assert.assertEquals(b.getNamespaceURI(), nsb, "unexpected namespace for " + testNodeName + "->b");
}
Node c = b.getChildNodes().item(0);
if (nsc == null) {
Assert.assertNull(c.getNamespaceURI(), "unexpected namespace for " + testNodeName + "->b->c");
} else {
Assert.assertEquals(c.getNamespaceURI(), nsc, "unexpected namespace for " + testNodeName + "->b->c");
}
}
System.out.println("Stylesheet:");
System.out.println("=============================");
System.out.println(xsl);
System.out.println();
public void run() throws IOException, TransformerException {
printSnippet("Source:", sourceXml);
System.out.println("Source before transformation:");
System.out.println("=============================");
System.out.println(sourceXml);
System.out.println();
printSnippet("Stylesheet:", xsl);
// transform to DOM result
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer(new StreamSource(new ByteArrayInputStream(xsl.getBytes())));
DOMResult result = new DOMResult();
t.transform(new StreamSource(new ByteArrayInputStream(sourceXml.getBytes())), result);
Document document = (Document)result.getNode();
// transform to DOM result
TransformerFactory tf = TransformerFactory.newInstance();
ByteArrayInputStream bais = new ByteArrayInputStream(xsl.getBytes());
Transformer t = tf.newTransformer(new StreamSource(bais));
DOMResult result = new DOMResult();
bais = new ByteArrayInputStream(sourceXml.getBytes());
t.transform(new StreamSource(bais), result);
Document document = (Document)result.getNode();
System.out.println("Result after transformation:");
System.out.println("============================");
OutputFormat format = new OutputFormat();
format.setIndenting(true);
new XMLSerializer(System.out, format).serialize(document);
System.out.println();
checkNodeNS8162598(document.getElementsByTagName("test1").item(0), "ns2", "ns2", null);
checkNodeNS8162598(document.getElementsByTagName("test2").item(0), "ns1", "ns2", null);
checkNodeNS8162598(document.getElementsByTagName("test3").item(0), null, null, null);
checkNodeNS8162598(document.getElementsByTagName("test4").item(0), null, null, null);
checkNodeNS8162598(document.getElementsByTagName("test5").item(0), "ns1", "ns1", null);
Assert.assertNull(document.getElementsByTagName("test6").item(0).getNamespaceURI(), "unexpected namespace for test6");
System.out.println("Result after transformation:");
System.out.println("============================");
OutputFormat format = new OutputFormat();
format.setIndenting(true);
new XMLSerializer(System.out, format).serialize(document);
System.out.println();
checkNodeNS(document.getElementsByTagName("test1").item(0), "ns2", "ns2", null);
checkNodeNS(document.getElementsByTagName("test2").item(0), "ns1", "ns2", null);
checkNodeNS(document.getElementsByTagName("test3").item(0), null, null, null);
checkNodeNS(document.getElementsByTagName("test4").item(0), null, null, null);
checkNodeNS(document.getElementsByTagName("test5").item(0), "ns1", "ns1", null);
Assert.assertNull(document.getElementsByTagName("test6").item(0).getNamespaceURI(),
"unexpected namespace for test6");
}
}
/*
* @bug 8162598
* @summary Test XSLTC handling of namespaces, especially empty namespace
* definitions to reset the default namespace
*/
@Test
public final void testBug8162598() throws IOException,
TransformerException
{
new Test8162598().run();
}
/**

View File

@ -397,3 +397,5 @@ c8c9c334743caf8155c9809b6b4ac315d3a66476 jdk-9+148
72554d319b474b3636c7d02fe3c110254d111b1a jdk-9+149
77e4e30d9d111272cd4a45a2203e8f570d40b12e jdk-9+150
c48b4d4768b1c2b8fe5d1a844ca13732e5dfbe2a jdk-9+151
6f8fb1cf7e5f61c40dcc3654f9a623c505f6de1f jdk-9+152
7a532a9a227137155b905341d4b99939db51220e jdk-9+153

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -47,13 +47,13 @@ public abstract class DetailImpl extends FaultElementImpl implements Detail {
public DetailEntry addDetailEntry(Name name) throws SOAPException {
DetailEntry entry = createDetailEntry(name);
addNode(entry);
return (DetailEntry) circumventBug5034339(entry);
return entry;
}
public DetailEntry addDetailEntry(QName qname) throws SOAPException {
DetailEntry entry = createDetailEntry(qname);
addNode(entry);
return (DetailEntry) circumventBug5034339(entry);
return entry;
}
protected SOAPElement addElement(Name name) throws SOAPException {
@ -119,28 +119,4 @@ public abstract class DetailImpl extends FaultElementImpl implements Detail {
return true;
}
//overriding this method since the only two uses of this method
// are in ElementImpl and DetailImpl
//whereas the original base impl does the correct job for calls to it inside ElementImpl
// But it would not work for DetailImpl.
protected SOAPElement circumventBug5034339(SOAPElement element) {
Name elementName = element.getElementName();
if (!isNamespaceQualified(elementName)) {
String prefix = elementName.getPrefix();
String defaultNamespace = getNamespaceURI(prefix);
if (defaultNamespace != null) {
Name newElementName =
NameImpl.create(
elementName.getLocalName(),
elementName.getPrefix(),
defaultNamespace);
SOAPElement newElement = createDetailEntry(newElementName);
replaceChild(newElement, element);
return newElement;
}
}
return element;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -127,8 +127,11 @@ public class ElementImpl
}
public SOAPElement addChildElement(String localName) throws SOAPException {
return (SOAPElement) addChildElement(
NameImpl.createFromUnqualifiedName(localName));
String nsUri = getNamespaceURI("");
Name name = (nsUri == null || nsUri.isEmpty())
? NameImpl.createFromUnqualifiedName(localName)
: NameImpl.createFromQualifiedName(localName, nsUri);
return addChildElement(name);
}
public SOAPElement addChildElement(String localName, String prefix)
@ -372,13 +375,13 @@ public class ElementImpl
protected SOAPElement addElement(Name name) throws SOAPException {
SOAPElement newElement = createElement(name);
addNode(newElement);
return circumventBug5034339(newElement);
return newElement;
}
protected SOAPElement addElement(QName name) throws SOAPException {
SOAPElement newElement = createElement(name);
addNode(newElement);
return circumventBug5034339(newElement);
return newElement;
}
protected SOAPElement createElement(Name name) {
@ -1226,26 +1229,6 @@ public class ElementImpl
return !"".equals(name.getNamespaceURI());
}
protected SOAPElement circumventBug5034339(SOAPElement element) {
Name elementName = element.getElementName();
if (!isNamespaceQualified(elementName)) {
String prefix = elementName.getPrefix();
String defaultNamespace = getNamespaceURI(prefix);
if (defaultNamespace != null) {
Name newElementName =
NameImpl.create(
elementName.getLocalName(),
elementName.getPrefix(),
defaultNamespace);
SOAPElement newElement = createElement(newElementName);
replaceChild(newElement, element);
return newElement;
}
}
return element;
}
//TODO: This is a temporary SAAJ workaround for optimizing XWS
// should be removed once the corresponding JAXP bug is fixed
// It appears the bug will be fixed in JAXP 1.4 (not by Appserver 9 timeframe)

View File

@ -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,8 +25,10 @@
package com.sun.xml.internal.messaging.saaj.util.stax;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Arrays;
import java.util.List;
import java.util.LinkedList;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
@ -42,6 +44,17 @@ import org.w3c.dom.Node;
/**
* SaajStaxWriter builds a SAAJ SOAPMessage by using XMLStreamWriter interface.
*
* <p>
* Defers creation of SOAPElement until all the aspects of the name of the element are known.
* In some cases, the namespace uri is indicated only by the {@link #writeNamespace(String, String)} call.
* After opening an element ({@code writeStartElement}, {@code writeEmptyElement} methods), all attributes
* and namespace assignments are retained within {@link DeferredElement} object ({@code deferredElement} field).
* As soon as any other method than {@code writeAttribute}, {@code writeNamespace}, {@code writeDefaultNamespace}
* or {@code setNamespace} is called, the contents of {@code deferredElement} is transformed into new SOAPElement
* (which is appropriately inserted into the SOAPMessage under construction).
* This mechanism is necessary to fix JDK-8159058 issue.
* </p>
*
* @author shih-chang.chen@oracle.com
*/
public class SaajStaxWriter implements XMLStreamWriter {
@ -49,6 +62,7 @@ public class SaajStaxWriter implements XMLStreamWriter {
protected SOAPMessage soap;
protected String envURI;
protected SOAPElement currentElement;
protected DeferredElement deferredElement;
static final protected String Envelope = "Envelope";
static final protected String Header = "Header";
@ -58,6 +72,7 @@ public class SaajStaxWriter implements XMLStreamWriter {
public SaajStaxWriter(final SOAPMessage msg, String uri) throws SOAPException {
soap = msg;
this.envURI = uri;
this.deferredElement = new DeferredElement();
}
public SOAPMessage getSOAPMessage() {
@ -70,11 +85,8 @@ public class SaajStaxWriter implements XMLStreamWriter {
@Override
public void writeStartElement(final String localName) throws XMLStreamException {
try {
currentElement = currentElement.addChildElement(localName);
} catch (SOAPException e) {
throw new XMLStreamException(e);
}
currentElement = deferredElement.flushTo(currentElement);
deferredElement.setLocalName(localName);
}
@Override
@ -84,8 +96,10 @@ public class SaajStaxWriter implements XMLStreamWriter {
@Override
public void writeStartElement(final String prefix, final String ln, final String ns) throws XMLStreamException {
try {
if (envURI.equals(ns)) {
currentElement = deferredElement.flushTo(currentElement);
if (envURI.equals(ns)) {
try {
if (Envelope.equals(ln)) {
currentElement = getEnvelope();
fixPrefix(prefix);
@ -99,13 +113,16 @@ public class SaajStaxWriter implements XMLStreamWriter {
fixPrefix(prefix);
return;
}
} catch (SOAPException e) {
throw new XMLStreamException(e);
}
currentElement = (prefix == null) ?
currentElement.addChildElement(new QName(ns, ln)) :
currentElement.addChildElement(ln, prefix, ns);
} catch (SOAPException e) {
throw new XMLStreamException(e);
}
deferredElement.setLocalName(ln);
deferredElement.setNamespaceUri(ns);
deferredElement.setPrefix(prefix);
}
private void fixPrefix(final String prfx) throws XMLStreamException {
@ -136,11 +153,13 @@ public class SaajStaxWriter implements XMLStreamWriter {
@Override
public void writeEndElement() throws XMLStreamException {
currentElement = deferredElement.flushTo(currentElement);
if (currentElement != null) currentElement = currentElement.getParentElement();
}
@Override
public void writeEndDocument() throws XMLStreamException {
currentElement = deferredElement.flushTo(currentElement);
}
@Override
@ -158,19 +177,14 @@ public class SaajStaxWriter implements XMLStreamWriter {
@Override
public void writeAttribute(final String prefix, final String ns, final String ln, final String value) throws XMLStreamException {
try {
if (ns == null) {
if (prefix == null && xmlns.equals(ln)) {
currentElement.addNamespaceDeclaration("", value);
} else {
currentElement.setAttributeNS("", ln, value);
}
if (ns == null && prefix == null && xmlns.equals(ln)) {
writeNamespace("", value);
} else {
if (deferredElement.isInitialized()) {
deferredElement.addAttribute(prefix, ns, ln, value);
} else {
QName name = (prefix == null) ? new QName(ns, ln) : new QName(ns, ln, prefix);
currentElement.addAttribute(name, value);
addAttibuteToElement(currentElement, prefix, ns, ln, value);
}
} catch (SOAPException e) {
throw new XMLStreamException(e);
}
}
@ -181,16 +195,16 @@ public class SaajStaxWriter implements XMLStreamWriter {
@Override
public void writeNamespace(String prefix, final String uri) throws XMLStreamException {
// make prefix default if null or "xmlns" (according to javadoc)
if (prefix == null || "xmlns".equals(prefix)) {
prefix = "";
}
try {
currentElement.addNamespaceDeclaration(prefix, uri);
} catch (SOAPException e) {
throw new XMLStreamException(e);
String thePrefix = prefix == null || "xmlns".equals(prefix) ? "" : prefix;
if (deferredElement.isInitialized()) {
deferredElement.addNamespaceDeclaration(thePrefix, uri);
} else {
try {
currentElement.addNamespaceDeclaration(thePrefix, uri);
} catch (SOAPException e) {
throw new XMLStreamException(e);
}
}
}
@ -201,35 +215,40 @@ public class SaajStaxWriter implements XMLStreamWriter {
@Override
public void writeComment(final String data) throws XMLStreamException {
currentElement = deferredElement.flushTo(currentElement);
Comment c = soap.getSOAPPart().createComment(data);
currentElement.appendChild(c);
}
@Override
public void writeProcessingInstruction(final String target) throws XMLStreamException {
currentElement = deferredElement.flushTo(currentElement);
Node n = soap.getSOAPPart().createProcessingInstruction(target, "");
currentElement.appendChild(n);
}
@Override
public void writeProcessingInstruction(final String target, final String data) throws XMLStreamException {
currentElement = deferredElement.flushTo(currentElement);
Node n = soap.getSOAPPart().createProcessingInstruction(target, data);
currentElement.appendChild(n);
}
@Override
public void writeCData(final String data) throws XMLStreamException {
currentElement = deferredElement.flushTo(currentElement);
Node n = soap.getSOAPPart().createCDATASection(data);
currentElement.appendChild(n);
}
@Override
public void writeDTD(final String dtd) throws XMLStreamException {
//TODO ... Don't do anything here
currentElement = deferredElement.flushTo(currentElement);
}
@Override
public void writeEntityRef(final String name) throws XMLStreamException {
currentElement = deferredElement.flushTo(currentElement);
Node n = soap.getSOAPPart().createEntityReference(name);
currentElement.appendChild(n);
}
@ -257,6 +276,7 @@ public class SaajStaxWriter implements XMLStreamWriter {
@Override
public void writeCharacters(final String text) throws XMLStreamException {
currentElement = deferredElement.flushTo(currentElement);
try {
currentElement.addTextNode(text);
} catch (SOAPException e) {
@ -266,6 +286,7 @@ public class SaajStaxWriter implements XMLStreamWriter {
@Override
public void writeCharacters(final char[] text, final int start, final int len) throws XMLStreamException {
currentElement = deferredElement.flushTo(currentElement);
char[] chr = (start == 0 && len == text.length) ? text : Arrays.copyOfRange(text, start, start + len);
try {
currentElement.addTextNode(new String(chr));
@ -281,10 +302,16 @@ public class SaajStaxWriter implements XMLStreamWriter {
@Override
public void setPrefix(final String prefix, final String uri) throws XMLStreamException {
try {
this.currentElement.addNamespaceDeclaration(prefix, uri);
} catch (SOAPException e) {
throw new XMLStreamException(e);
// TODO: this in fact is not what would be expected from XMLStreamWriter
// (e.g. XMLStreamWriter for writing to output stream does not write anything as result of
// this method, it just rememebers that given prefix is associated with the given uri
// for the scope; to actually declare the prefix assignment in the resulting XML, one
// needs to call writeNamespace(...) method
// Kept for backwards compatibility reasons - this might be worth of further investigation.
if (deferredElement.isInitialized()) {
deferredElement.addNamespaceDeclaration(prefix, uri);
} else {
throw new XMLStreamException("Namespace not associated with any element");
}
}
@ -331,4 +358,209 @@ public class SaajStaxWriter implements XMLStreamWriter {
}
};
}
static void addAttibuteToElement(SOAPElement element, String prefix, String ns, String ln, String value)
throws XMLStreamException {
try {
if (ns == null) {
element.setAttributeNS("", ln, value);
} else {
QName name = prefix == null ? new QName(ns, ln) : new QName(ns, ln, prefix);
element.addAttribute(name, value);
}
} catch (SOAPException e) {
throw new XMLStreamException(e);
}
}
/**
* Holds details of element that needs to be deferred in order to manage namespace assignments correctly.
*
* <p>
* An instance of can be set with all the aspects of the element name (local name, prefix, namespace uri).
* Attributes and namespace declarations (special case of attribute) can be added.
* Namespace declarations are handled so that the element namespace is updated if it is implied by the namespace
* declaration and the namespace was not set to non-{@code null} value previously.
* </p>
*
* <p>
* The state of this object can be {@link #flushTo(SOAPElement) flushed} to SOAPElement - new SOAPElement will
* be added a child element; the new element will have exactly the shape as represented by the state of this
* object. Note that the {@link #flushTo(SOAPElement)} method does nothing
* (and returns the argument immediately) if the state of this object is not initialized
* (i.e. local name is null).
* </p>
*
* @author ondrej.cerny@oracle.com
*/
static class DeferredElement {
private String prefix;
private String localName;
private String namespaceUri;
private final List<NamespaceDeclaration> namespaceDeclarations;
private final List<AttributeDeclaration> attributeDeclarations;
DeferredElement() {
this.namespaceDeclarations = new LinkedList<NamespaceDeclaration>();
this.attributeDeclarations = new LinkedList<AttributeDeclaration>();
reset();
}
/**
* Set prefix of the element.
* @param prefix namespace prefix
*/
public void setPrefix(final String prefix) {
this.prefix = prefix;
}
/**
* Set local name of the element.
*
* <p>
* This method initializes the element.
* </p>
*
* @param localName local name {@code not null}
*/
public void setLocalName(final String localName) {
if (localName == null) {
throw new IllegalArgumentException("localName can not be null");
}
this.localName = localName;
}
/**
* Set namespace uri.
*
* @param namespaceUri namespace uri
*/
public void setNamespaceUri(final String namespaceUri) {
this.namespaceUri = namespaceUri;
}
/**
* Adds namespace prefix assignment to the element.
*
* @param prefix prefix (not {@code null})
* @param namespaceUri namespace uri
*/
public void addNamespaceDeclaration(final String prefix, final String namespaceUri) {
if (null == this.namespaceUri && null != namespaceUri && prefix.equals(emptyIfNull(this.prefix))) {
this.namespaceUri = namespaceUri;
}
this.namespaceDeclarations.add(new NamespaceDeclaration(prefix, namespaceUri));
}
/**
* Adds attribute to the element.
* @param prefix prefix
* @param ns namespace
* @param ln local name
* @param value value
*/
public void addAttribute(final String prefix, final String ns, final String ln, final String value) {
if (ns == null && prefix == null && xmlns.equals(ln)) {
this.addNamespaceDeclaration(prefix, value);
} else {
this.attributeDeclarations.add(new AttributeDeclaration(prefix, ns, ln, value));
}
}
/**
* Flushes state of this element to the {@code target} element.
*
* <p>
* If this element is initialized then it is added with all the namespace declarations and attributes
* to the {@code target} element as a child. The state of this element is reset to uninitialized.
* The newly added element object is returned.
* </p>
* <p>
* If this element is not initialized then the {@code target} is returned immediately, nothing else is done.
* </p>
*
* @param target target element
* @return {@code target} or new element
* @throws XMLStreamException on error
*/
public SOAPElement flushTo(final SOAPElement target) throws XMLStreamException {
try {
if (this.localName != null) {
// add the element appropriately (based on namespace declaration)
final SOAPElement newElement;
if (this.namespaceUri == null) {
// add element with inherited scope
newElement = target.addChildElement(this.localName);
} else if (prefix == null) {
newElement = target.addChildElement(new QName(this.namespaceUri, this.localName));
} else {
newElement = target.addChildElement(this.localName, this.prefix, this.namespaceUri);
}
// add namespace declarations
for (NamespaceDeclaration namespace : this.namespaceDeclarations) {
target.addNamespaceDeclaration(namespace.prefix, namespace.namespaceUri);
}
// add attribute declarations
for (AttributeDeclaration attribute : this.attributeDeclarations) {
addAttibuteToElement(newElement,
attribute.prefix, attribute.namespaceUri, attribute.localName, attribute.value);
}
// reset state
this.reset();
return newElement;
} else {
return target;
}
// else after reset state -> not initialized
} catch (SOAPException e) {
throw new XMLStreamException(e);
}
}
/**
* Is the element initialized?
* @return boolean indicating whether it was initialized after last flush
*/
public boolean isInitialized() {
return this.localName != null;
}
private void reset() {
this.localName = null;
this.prefix = null;
this.namespaceUri = null;
this.namespaceDeclarations.clear();
this.attributeDeclarations.clear();
}
private static String emptyIfNull(String s) {
return s == null ? "" : s;
}
}
static class NamespaceDeclaration {
final String prefix;
final String namespaceUri;
NamespaceDeclaration(String prefix, String namespaceUri) {
this.prefix = prefix;
this.namespaceUri = namespaceUri;
}
}
static class AttributeDeclaration {
final String prefix;
final String namespaceUri;
final String localName;
final String value;
AttributeDeclaration(String prefix, String namespaceUri, String localName, String value) {
this.prefix = prefix;
this.namespaceUri = namespaceUri;
this.localName = localName;
this.value = value;
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 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,8 +25,10 @@
package com.sun.xml.internal.ws.api.message.saaj;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Arrays;
import java.util.List;
import java.util.LinkedList;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
@ -42,6 +44,17 @@ import org.w3c.dom.Node;
/**
* SaajStaxWriter builds a SAAJ SOAPMessage by using XMLStreamWriter interface.
*
* <p>
* Defers creation of SOAPElement until all the aspects of the name of the element are known.
* In some cases, the namespace uri is indicated only by the {@link #writeNamespace(String, String)} call.
* After opening an element ({@code writeStartElement}, {@code writeEmptyElement} methods), all attributes
* and namespace assignments are retained within {@link DeferredElement} object ({@code deferredElement} field).
* As soon as any other method than {@code writeAttribute}, {@code writeNamespace}, {@code writeDefaultNamespace}
* or {@code setNamespace} is called, the contents of {@code deferredElement} is transformed into new SOAPElement
* (which is appropriately inserted into the SOAPMessage under construction).
* This mechanism is necessary to fix JDK-8159058 issue.
* </p>
*
* @author shih-chang.chen@oracle.com
*/
public class SaajStaxWriter implements XMLStreamWriter {
@ -49,6 +62,7 @@ public class SaajStaxWriter implements XMLStreamWriter {
protected SOAPMessage soap;
protected String envURI;
protected SOAPElement currentElement;
protected DeferredElement deferredElement;
static final protected String Envelope = "Envelope";
static final protected String Header = "Header";
@ -58,6 +72,7 @@ public class SaajStaxWriter implements XMLStreamWriter {
public SaajStaxWriter(final SOAPMessage msg, String uri) throws SOAPException {
soap = msg;
this.envURI = uri;
this.deferredElement = new DeferredElement();
}
public SOAPMessage getSOAPMessage() {
@ -70,11 +85,8 @@ public class SaajStaxWriter implements XMLStreamWriter {
@Override
public void writeStartElement(final String localName) throws XMLStreamException {
try {
currentElement = currentElement.addChildElement(localName);
} catch (SOAPException e) {
throw new XMLStreamException(e);
}
currentElement = deferredElement.flushTo(currentElement);
deferredElement.setLocalName(localName);
}
@Override
@ -84,8 +96,10 @@ public class SaajStaxWriter implements XMLStreamWriter {
@Override
public void writeStartElement(final String prefix, final String ln, final String ns) throws XMLStreamException {
try {
if (envURI.equals(ns)) {
currentElement = deferredElement.flushTo(currentElement);
if (envURI.equals(ns)) {
try {
if (Envelope.equals(ln)) {
currentElement = getEnvelope();
fixPrefix(prefix);
@ -99,13 +113,16 @@ public class SaajStaxWriter implements XMLStreamWriter {
fixPrefix(prefix);
return;
}
} catch (SOAPException e) {
throw new XMLStreamException(e);
}
currentElement = (prefix == null) ?
currentElement.addChildElement(new QName(ns, ln)) :
currentElement.addChildElement(ln, prefix, ns);
} catch (SOAPException e) {
throw new XMLStreamException(e);
}
deferredElement.setLocalName(ln);
deferredElement.setNamespaceUri(ns);
deferredElement.setPrefix(prefix);
}
private void fixPrefix(final String prfx) throws XMLStreamException {
@ -136,11 +153,13 @@ public class SaajStaxWriter implements XMLStreamWriter {
@Override
public void writeEndElement() throws XMLStreamException {
currentElement = deferredElement.flushTo(currentElement);
if (currentElement != null) currentElement = currentElement.getParentElement();
}
@Override
public void writeEndDocument() throws XMLStreamException {
currentElement = deferredElement.flushTo(currentElement);
}
@Override
@ -158,19 +177,14 @@ public class SaajStaxWriter implements XMLStreamWriter {
@Override
public void writeAttribute(final String prefix, final String ns, final String ln, final String value) throws XMLStreamException {
try {
if (ns == null) {
if (prefix == null && xmlns.equals(ln)) {
currentElement.addNamespaceDeclaration("", value);
} else {
currentElement.setAttributeNS("", ln, value);
}
if (ns == null && prefix == null && xmlns.equals(ln)) {
writeNamespace("", value);
} else {
if (deferredElement.isInitialized()) {
deferredElement.addAttribute(prefix, ns, ln, value);
} else {
QName name = (prefix == null) ? new QName(ns, ln) : new QName(ns, ln, prefix);
currentElement.addAttribute(name, value);
addAttibuteToElement(currentElement, prefix, ns, ln, value);
}
} catch (SOAPException e) {
throw new XMLStreamException(e);
}
}
@ -181,16 +195,16 @@ public class SaajStaxWriter implements XMLStreamWriter {
@Override
public void writeNamespace(String prefix, final String uri) throws XMLStreamException {
// make prefix default if null or "xmlns" (according to javadoc)
if (prefix == null || "xmlns".equals(prefix)) {
prefix = "";
}
try {
currentElement.addNamespaceDeclaration(prefix, uri);
} catch (SOAPException e) {
throw new XMLStreamException(e);
String thePrefix = prefix == null || "xmlns".equals(prefix) ? "" : prefix;
if (deferredElement.isInitialized()) {
deferredElement.addNamespaceDeclaration(thePrefix, uri);
} else {
try {
currentElement.addNamespaceDeclaration(thePrefix, uri);
} catch (SOAPException e) {
throw new XMLStreamException(e);
}
}
}
@ -201,35 +215,40 @@ public class SaajStaxWriter implements XMLStreamWriter {
@Override
public void writeComment(final String data) throws XMLStreamException {
currentElement = deferredElement.flushTo(currentElement);
Comment c = soap.getSOAPPart().createComment(data);
currentElement.appendChild(c);
}
@Override
public void writeProcessingInstruction(final String target) throws XMLStreamException {
currentElement = deferredElement.flushTo(currentElement);
Node n = soap.getSOAPPart().createProcessingInstruction(target, "");
currentElement.appendChild(n);
}
@Override
public void writeProcessingInstruction(final String target, final String data) throws XMLStreamException {
currentElement = deferredElement.flushTo(currentElement);
Node n = soap.getSOAPPart().createProcessingInstruction(target, data);
currentElement.appendChild(n);
}
@Override
public void writeCData(final String data) throws XMLStreamException {
currentElement = deferredElement.flushTo(currentElement);
Node n = soap.getSOAPPart().createCDATASection(data);
currentElement.appendChild(n);
}
@Override
public void writeDTD(final String dtd) throws XMLStreamException {
//TODO ... Don't do anything here
currentElement = deferredElement.flushTo(currentElement);
}
@Override
public void writeEntityRef(final String name) throws XMLStreamException {
currentElement = deferredElement.flushTo(currentElement);
Node n = soap.getSOAPPart().createEntityReference(name);
currentElement.appendChild(n);
}
@ -257,6 +276,7 @@ public class SaajStaxWriter implements XMLStreamWriter {
@Override
public void writeCharacters(final String text) throws XMLStreamException {
currentElement = deferredElement.flushTo(currentElement);
try {
currentElement.addTextNode(text);
} catch (SOAPException e) {
@ -266,6 +286,7 @@ public class SaajStaxWriter implements XMLStreamWriter {
@Override
public void writeCharacters(final char[] text, final int start, final int len) throws XMLStreamException {
currentElement = deferredElement.flushTo(currentElement);
char[] chr = (start == 0 && len == text.length) ? text : Arrays.copyOfRange(text, start, start + len);
try {
currentElement.addTextNode(new String(chr));
@ -281,10 +302,16 @@ public class SaajStaxWriter implements XMLStreamWriter {
@Override
public void setPrefix(final String prefix, final String uri) throws XMLStreamException {
try {
this.currentElement.addNamespaceDeclaration(prefix, uri);
} catch (SOAPException e) {
throw new XMLStreamException(e);
// TODO: this in fact is not what would be expected from XMLStreamWriter
// (e.g. XMLStreamWriter for writing to output stream does not write anything as result of
// this method, it just rememebers that given prefix is associated with the given uri
// for the scope; to actually declare the prefix assignment in the resulting XML, one
// needs to call writeNamespace(...) method
// Kept for backwards compatibility reasons - this might be worth of further investigation.
if (deferredElement.isInitialized()) {
deferredElement.addNamespaceDeclaration(prefix, uri);
} else {
throw new XMLStreamException("Namespace not associated with any element");
}
}
@ -315,12 +342,12 @@ public class SaajStaxWriter implements XMLStreamWriter {
return currentElement.lookupPrefix(namespaceURI);
}
public Iterator getPrefixes(final String namespaceURI) {
return new Iterator() {
return new Iterator<String>() {
String prefix = getPrefix(namespaceURI);
public boolean hasNext() {
return (prefix != null);
}
public Object next() {
public String next() {
if (!hasNext()) throw new java.util.NoSuchElementException();
String next = prefix;
prefix = null;
@ -331,4 +358,209 @@ public class SaajStaxWriter implements XMLStreamWriter {
}
};
}
static void addAttibuteToElement(SOAPElement element, String prefix, String ns, String ln, String value)
throws XMLStreamException {
try {
if (ns == null) {
element.setAttributeNS("", ln, value);
} else {
QName name = prefix == null ? new QName(ns, ln) : new QName(ns, ln, prefix);
element.addAttribute(name, value);
}
} catch (SOAPException e) {
throw new XMLStreamException(e);
}
}
/**
* Holds details of element that needs to be deferred in order to manage namespace assignments correctly.
*
* <p>
* An instance of can be set with all the aspects of the element name (local name, prefix, namespace uri).
* Attributes and namespace declarations (special case of attribute) can be added.
* Namespace declarations are handled so that the element namespace is updated if it is implied by the namespace
* declaration and the namespace was not set to non-{@code null} value previously.
* </p>
*
* <p>
* The state of this object can be {@link #flushTo(SOAPElement) flushed} to SOAPElement - new SOAPElement will
* be added a child element; the new element will have exactly the shape as represented by the state of this
* object. Note that the {@link #flushTo(SOAPElement)} method does nothing
* (and returns the argument immediately) if the state of this object is not initialized
* (i.e. local name is null).
* </p>
*
* @author ondrej.cerny@oracle.com
*/
static class DeferredElement {
private String prefix;
private String localName;
private String namespaceUri;
private final List<NamespaceDeclaration> namespaceDeclarations;
private final List<AttributeDeclaration> attributeDeclarations;
DeferredElement() {
this.namespaceDeclarations = new LinkedList<NamespaceDeclaration>();
this.attributeDeclarations = new LinkedList<AttributeDeclaration>();
reset();
}
/**
* Set prefix of the element.
* @param prefix namespace prefix
*/
public void setPrefix(final String prefix) {
this.prefix = prefix;
}
/**
* Set local name of the element.
*
* <p>
* This method initializes the element.
* </p>
*
* @param localName local name {@code not null}
*/
public void setLocalName(final String localName) {
if (localName == null) {
throw new IllegalArgumentException("localName can not be null");
}
this.localName = localName;
}
/**
* Set namespace uri.
*
* @param namespaceUri namespace uri
*/
public void setNamespaceUri(final String namespaceUri) {
this.namespaceUri = namespaceUri;
}
/**
* Adds namespace prefix assignment to the element.
*
* @param prefix prefix (not {@code null})
* @param namespaceUri namespace uri
*/
public void addNamespaceDeclaration(final String prefix, final String namespaceUri) {
if (null == this.namespaceUri && null != namespaceUri && prefix.equals(emptyIfNull(this.prefix))) {
this.namespaceUri = namespaceUri;
}
this.namespaceDeclarations.add(new NamespaceDeclaration(prefix, namespaceUri));
}
/**
* Adds attribute to the element.
* @param prefix prefix
* @param ns namespace
* @param ln local name
* @param value value
*/
public void addAttribute(final String prefix, final String ns, final String ln, final String value) {
if (ns == null && prefix == null && xmlns.equals(ln)) {
this.addNamespaceDeclaration(prefix, value);
} else {
this.attributeDeclarations.add(new AttributeDeclaration(prefix, ns, ln, value));
}
}
/**
* Flushes state of this element to the {@code target} element.
*
* <p>
* If this element is initialized then it is added with all the namespace declarations and attributes
* to the {@code target} element as a child. The state of this element is reset to uninitialized.
* The newly added element object is returned.
* </p>
* <p>
* If this element is not initialized then the {@code target} is returned immediately, nothing else is done.
* </p>
*
* @param target target element
* @return {@code target} or new element
* @throws XMLStreamException on error
*/
public SOAPElement flushTo(final SOAPElement target) throws XMLStreamException {
try {
if (this.localName != null) {
// add the element appropriately (based on namespace declaration)
final SOAPElement newElement;
if (this.namespaceUri == null) {
// add element with inherited scope
newElement = target.addChildElement(this.localName);
} else if (prefix == null) {
newElement = target.addChildElement(new QName(this.namespaceUri, this.localName));
} else {
newElement = target.addChildElement(this.localName, this.prefix, this.namespaceUri);
}
// add namespace declarations
for (NamespaceDeclaration namespace : this.namespaceDeclarations) {
target.addNamespaceDeclaration(namespace.prefix, namespace.namespaceUri);
}
// add attribute declarations
for (AttributeDeclaration attribute : this.attributeDeclarations) {
addAttibuteToElement(newElement,
attribute.prefix, attribute.namespaceUri, attribute.localName, attribute.value);
}
// reset state
this.reset();
return newElement;
} else {
return target;
}
// else after reset state -> not initialized
} catch (SOAPException e) {
throw new XMLStreamException(e);
}
}
/**
* Is the element initialized?
* @return boolean indicating whether it was initialized after last flush
*/
public boolean isInitialized() {
return this.localName != null;
}
private void reset() {
this.localName = null;
this.prefix = null;
this.namespaceUri = null;
this.namespaceDeclarations.clear();
this.attributeDeclarations.clear();
}
private static String emptyIfNull(String s) {
return s == null ? "" : s;
}
}
static class NamespaceDeclaration {
final String prefix;
final String namespaceUri;
NamespaceDeclaration(String prefix, String namespaceUri) {
this.prefix = prefix;
this.namespaceUri = namespaceUri;
}
}
static class AttributeDeclaration {
final String prefix;
final String namespaceUri;
final String localName;
final String value;
AttributeDeclaration(String prefix, String namespaceUri, String localName, String value) {
this.prefix = prefix;
this.namespaceUri = namespaceUri;
this.localName = localName;
this.value = value;
}
}
}

View File

@ -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
@ -33,6 +33,7 @@ import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
@ -332,13 +333,13 @@ public class XmlUtil {
* (com.sun.org.apache.xml.internal) for modular runtime.
*/
private static EntityResolver createCatalogResolver(ArrayList<URL> urls) throws Exception {
// Prepare array of catalog paths
String[] paths = urls.stream()
.map(u -> u.toExternalForm())
.toArray(c -> new String[c]);
// Prepare array of catalog URIs
URI[] uris = urls.stream()
.map(u -> URI.create(u.toExternalForm()))
.toArray(URI[]::new);
//Create CatalogResolver with new JDK9+ API
return (EntityResolver) CatalogManager.catalogResolver(catalogFeatures, paths);
return (EntityResolver) CatalogManager.catalogResolver(catalogFeatures, uris);
}
// Cache CatalogFeatures instance for future usages.

View File

@ -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
@ -777,13 +777,13 @@ public class Options
* Adds a new catalog file.
*/
public void addCatalog(File catalogFile) throws IOException {
String newUrl = catalogFile.getPath();
URI newUrl = catalogFile.toURI();
if (!catalogUrls.contains(newUrl)) {
catalogUrls.add(newUrl);
}
try {
entityResolver = CatalogManager.catalogResolver(catalogFeatures,
catalogUrls.toArray(new String[0]));
catalogUrls.stream().toArray(URI[]::new));
} catch (Exception ex) {
entityResolver = null;
}
@ -791,7 +791,7 @@ public class Options
// Since javax.xml.catalog is unmodifiable we need to track catalog
// URLs added and create new catalog each time addCatalog is called
private final ArrayList<String> catalogUrls = new ArrayList<String>();
private final ArrayList<URI> catalogUrls = new ArrayList<>();
// Cache CatalogFeatures instance for future usages.
// Resolve feature is set to "continue" value for backward compatibility.

View File

@ -394,3 +394,5 @@ c41140100bf1e5c10c7b8f3bde91c16eff7485f5 jdk-9+147
5a846396a24c7aff01d6a8feaa7afc0a6369f04d jdk-9+149
71e198ef3839045e829a879af1d709be16ab0f88 jdk-9+150
d27bab22ff62823902d93d1d35ca397cfd50d059 jdk-9+151
a20f2cf90762673e1bc4980fd6597e70a2578045 jdk-9+152
1c4411322327aea3f91011ec3977a12a05b09629 jdk-9+153

View File

@ -37,6 +37,5 @@ $(eval $(call SetupJavaCompilation,BUILD_JIGSAW_TOOLS, \
build/tools/jigsaw, \
BIN := $(TOOLS_CLASSES_DIR), \
ADD_JAVAC_FLAGS := \
--add-exports jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED \
--add-exports java.base/jdk.internal.module=ALL-UNNAMED \
))

View File

@ -39,7 +39,6 @@ TOOL_GENGRAPHS := $(BUILD_JAVA) -esa -ea -cp $(TOOLS_CLASSES_DIR) \
build.tools.jigsaw.GenGraphs
TOOL_MODULESUMMARY := $(BUILD_JAVA) -esa -ea -cp $(TOOLS_CLASSES_DIR) \
--add-exports jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED \
build.tools.jigsaw.ModuleSummary
TOOL_ADD_PACKAGES_ATTRIBUTE := $(BUILD_JAVA) $(JAVA_FLAGS_SMALL) \

View File

@ -436,15 +436,15 @@ sequence.fallback=latin-1,latin-2,latin-7,cyrillic-iso8859-5,greek,latin-5,latin
filename.-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/arial.ttf
filename.-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/ariali.ttf
filename.-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/arialb.ttf
filename.-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/arialbd.ttf
filename.-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/arialbi.ttf
filename.-monotype-courier_new-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/cour.ttf
filename.-monotype-courier_new-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/couri.ttf
filename.-monotype-courier_new-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/courb.ttf
filename.-monotype-courier_new-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/courbd.ttf
filename.-monotype-courier_new-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/courbi.ttf
filename.-monotype-times_new_roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/times.ttf
filename.-monotype-times_new_roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/timesi.ttf
filename.-monotype-times_new_roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/timesb.ttf
filename.-monotype-times_new_roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/timesbd.ttf
filename.-monotype-times_new_roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/timesbi.ttf
filename.-monotype-angsana_new-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/angsa.ttf

View File

@ -222,6 +222,8 @@ endif
# applies to debug builds.
ifeq ($(TOOLCHAIN_TYPE), gcc)
BUILD_LIBAWT_debug_mem.c_CFLAGS := -w
# This option improves performance of MaskFill in Java2D by 20% for some gcc
LIBAWT_CFLAGS += -fgcse-after-reload
endif
$(eval $(call SetupNativeCompilation,BUILD_LIBAWT, \

View File

@ -69,6 +69,10 @@ class HttpsURLConnection extends HttpURLConnection
/**
* Returns the server's X.509 certificate chain, or null if
* the server did not authenticate.
* <P>
* Note: The returned value may not be a valid certificate chain
* and should not be relied on for trust decisions.
*
* @return the server certificate chain
*/
public abstract Certificate[] getServerCertificates()

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1994, 2016, 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
@ -1962,6 +1962,9 @@ public class File
name = sb.toString();
}
// Normalize the path component
name = fs.normalize(name);
File f = new File(dir, name);
if (!name.equals(f.getName()) || f.isInvalid()) {
if (System.getSecurityManager() != null)

View File

@ -508,8 +508,9 @@ public final class Class<T> implements java.io.Serializable,
public T newInstance()
throws InstantiationException, IllegalAccessException
{
if (System.getSecurityManager() != null) {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), false);
}
// NOTE: the following code may not be strictly correct under
@ -1223,38 +1224,27 @@ public final class Class<T> implements java.io.Serializable,
// Perform access check
final Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
enclosingCandidate.checkMemberAccess(Member.DECLARED,
Reflection.getCallerClass(), true);
// Client is ok to access declared methods but j.l.Class might not be.
Method[] candidates = AccessController.doPrivileged(
new PrivilegedAction<>() {
@Override
public Method[] run() {
return enclosingCandidate.getDeclaredMethods();
}
});
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
enclosingCandidate.checkMemberAccess(sm, Member.DECLARED,
Reflection.getCallerClass(), true);
}
Method[] candidates = enclosingCandidate.privateGetDeclaredMethods(false);
/*
* Loop over all declared methods; match method name,
* number of and type of parameters, *and* return
* type. Matching return type is also necessary
* because of covariant returns, etc.
*/
for(Method m: candidates) {
if (m.getName().equals(enclosingInfo.getName()) ) {
Class<?>[] candidateParamClasses = m.getParameterTypes();
if (candidateParamClasses.length == parameterClasses.length) {
boolean matches = true;
for(int i = 0; i < candidateParamClasses.length; i++) {
if (!candidateParamClasses[i].equals(parameterClasses[i])) {
matches = false;
break;
}
}
if (matches) { // finally, check return type
if (m.getReturnType().equals(returnType) )
return m;
}
ReflectionFactory fact = getReflectionFactory();
for (Method m : candidates) {
if (m.getName().equals(enclosingInfo.getName()) &&
arrayContentsEq(parameterClasses,
fact.getExecutableSharedParameterTypes(m))) {
// finally, check return type
if (m.getReturnType().equals(returnType)) {
return fact.copyMethod(m);
}
}
}
@ -1390,33 +1380,23 @@ public final class Class<T> implements java.io.Serializable,
// Perform access check
final Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
enclosingCandidate.checkMemberAccess(Member.DECLARED,
Reflection.getCallerClass(), true);
// Client is ok to access declared methods but j.l.Class might not be.
Constructor<?>[] candidates = AccessController.doPrivileged(
new PrivilegedAction<>() {
@Override
public Constructor<?>[] run() {
return enclosingCandidate.getDeclaredConstructors();
}
});
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
enclosingCandidate.checkMemberAccess(sm, Member.DECLARED,
Reflection.getCallerClass(), true);
}
Constructor<?>[] candidates = enclosingCandidate
.privateGetDeclaredConstructors(false);
/*
* Loop over all declared constructors; match number
* of and type of parameters.
*/
for(Constructor<?> c: candidates) {
Class<?>[] candidateParamClasses = c.getParameterTypes();
if (candidateParamClasses.length == parameterClasses.length) {
boolean matches = true;
for(int i = 0; i < candidateParamClasses.length; i++) {
if (!candidateParamClasses[i].equals(parameterClasses[i])) {
matches = false;
break;
}
}
if (matches)
return c;
ReflectionFactory fact = getReflectionFactory();
for (Constructor<?> c : candidates) {
if (arrayContentsEq(parameterClasses,
fact.getExecutableSharedParameterTypes(c))) {
return fact.copyConstructor(c);
}
}
@ -1446,9 +1426,13 @@ public final class Class<T> implements java.io.Serializable,
public Class<?> getDeclaringClass() throws SecurityException {
final Class<?> candidate = getDeclaringClass0();
if (candidate != null)
candidate.checkPackageAccess(
if (candidate != null) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
candidate.checkPackageAccess(sm,
ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
}
}
return candidate;
}
@ -1496,9 +1480,13 @@ public final class Class<T> implements java.io.Serializable,
enclosingCandidate = enclosingClass;
}
if (enclosingCandidate != null)
enclosingCandidate.checkPackageAccess(
if (enclosingCandidate != null) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
enclosingCandidate.checkPackageAccess(sm,
ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
}
}
return enclosingCandidate;
}
@ -1688,7 +1676,10 @@ public final class Class<T> implements java.io.Serializable,
*/
@CallerSensitive
public Class<?>[] getClasses() {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), false);
}
// Privileged so this implementation can look at DECLARED classes,
// something the caller might not have privilege to do. The code here
@ -1754,7 +1745,10 @@ public final class Class<T> implements java.io.Serializable,
*/
@CallerSensitive
public Field[] getFields() throws SecurityException {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true);
}
return copyFields(privateGetPublicFields(null));
}
@ -1841,7 +1835,10 @@ public final class Class<T> implements java.io.Serializable,
*/
@CallerSensitive
public Method[] getMethods() throws SecurityException {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true);
}
return copyMethods(privateGetPublicMethods());
}
@ -1877,7 +1874,10 @@ public final class Class<T> implements java.io.Serializable,
*/
@CallerSensitive
public Constructor<?>[] getConstructors() throws SecurityException {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true);
}
return copyConstructors(privateGetDeclaredConstructors(true));
}
@ -1928,7 +1928,10 @@ public final class Class<T> implements java.io.Serializable,
public Field getField(String name)
throws NoSuchFieldException, SecurityException {
Objects.requireNonNull(name);
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true);
}
Field field = getField0(name);
if (field == null) {
throw new NoSuchFieldException(name);
@ -2034,10 +2037,13 @@ public final class Class<T> implements java.io.Serializable,
public Method getMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
Objects.requireNonNull(name);
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true);
}
Method method = getMethod0(name, parameterTypes);
if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
throw new NoSuchMethodException(methodToString(name, parameterTypes));
}
return getReflectionFactory().copyMethod(method);
}
@ -2092,8 +2098,12 @@ public final class Class<T> implements java.io.Serializable,
*/
@CallerSensitive
public Constructor<T> getConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
throws NoSuchMethodException, SecurityException
{
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true);
}
return getReflectionFactory().copyConstructor(
getConstructor0(parameterTypes, Member.PUBLIC));
}
@ -2136,7 +2146,10 @@ public final class Class<T> implements java.io.Serializable,
*/
@CallerSensitive
public Class<?>[] getDeclaredClasses() throws SecurityException {
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), false);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), false);
}
return getDeclaredClasses0();
}
@ -2185,7 +2198,10 @@ public final class Class<T> implements java.io.Serializable,
*/
@CallerSensitive
public Field[] getDeclaredFields() throws SecurityException {
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true);
}
return copyFields(privateGetDeclaredFields(false));
}
@ -2244,7 +2260,10 @@ public final class Class<T> implements java.io.Serializable,
*/
@CallerSensitive
public Method[] getDeclaredMethods() throws SecurityException {
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true);
}
return copyMethods(privateGetDeclaredMethods(false));
}
@ -2289,7 +2308,10 @@ public final class Class<T> implements java.io.Serializable,
*/
@CallerSensitive
public Constructor<?>[] getDeclaredConstructors() throws SecurityException {
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true);
}
return copyConstructors(privateGetDeclaredConstructors(false));
}
@ -2338,7 +2360,10 @@ public final class Class<T> implements java.io.Serializable,
public Field getDeclaredField(String name)
throws NoSuchFieldException, SecurityException {
Objects.requireNonNull(name);
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true);
}
Field field = searchFields(privateGetDeclaredFields(false), name);
if (field == null) {
throw new NoSuchFieldException(name);
@ -2399,10 +2424,13 @@ public final class Class<T> implements java.io.Serializable,
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
Objects.requireNonNull(name);
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true);
}
Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
throw new NoSuchMethodException(methodToString(name, parameterTypes));
}
return getReflectionFactory().copyMethod(method);
}
@ -2448,8 +2476,13 @@ public final class Class<T> implements java.io.Serializable,
*/
@CallerSensitive
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
throws NoSuchMethodException, SecurityException
{
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true);
}
return getReflectionFactory().copyConstructor(
getConstructor0(parameterTypes, Member.DECLARED));
}
@ -2697,51 +2730,49 @@ public final class Class<T> implements java.io.Serializable,
*
* <p> Default policy: allow all clients access with normal Java access
* control.
*
* <p> NOTE: should only be called if a SecurityManager is installed
*/
private void checkMemberAccess(int which, Class<?> caller, boolean checkProxyInterfaces) {
final SecurityManager s = System.getSecurityManager();
if (s != null) {
/* Default policy allows access to all {@link Member#PUBLIC} members,
* as well as access to classes that have the same class loader as the caller.
* In all other cases, it requires RuntimePermission("accessDeclaredMembers")
* permission.
*/
final ClassLoader ccl = ClassLoader.getClassLoader(caller);
private void checkMemberAccess(SecurityManager sm, int which,
Class<?> caller, boolean checkProxyInterfaces) {
/* Default policy allows access to all {@link Member#PUBLIC} members,
* as well as access to classes that have the same class loader as the caller.
* In all other cases, it requires RuntimePermission("accessDeclaredMembers")
* permission.
*/
final ClassLoader ccl = caller.getClassLoader0();
if (which != Member.PUBLIC) {
final ClassLoader cl = getClassLoader0();
if (which != Member.PUBLIC) {
if (ccl != cl) {
s.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
}
if (ccl != cl) {
sm.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
}
this.checkPackageAccess(ccl, checkProxyInterfaces);
}
this.checkPackageAccess(sm, ccl, checkProxyInterfaces);
}
/*
* Checks if a client loaded in ClassLoader ccl is allowed to access this
* class under the current package access policy. If access is denied,
* throw a SecurityException.
*
* NOTE: this method should only be called if a SecurityManager is active
*/
private void checkPackageAccess(final ClassLoader ccl, boolean checkProxyInterfaces) {
final SecurityManager s = System.getSecurityManager();
if (s != null) {
final ClassLoader cl = getClassLoader0();
private void checkPackageAccess(SecurityManager sm, final ClassLoader ccl,
boolean checkProxyInterfaces) {
final ClassLoader cl = getClassLoader0();
if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
String name = this.getName();
int i = name.lastIndexOf('.');
if (i != -1) {
// skip the package access check on a proxy class in default proxy package
String pkg = name.substring(0, i);
if (!Proxy.isProxyClass(this) || ReflectUtil.isNonPublicProxyClass(this)) {
s.checkPackageAccess(pkg);
}
if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
String pkg = this.getPackageName();
if (pkg != null && !pkg.isEmpty()) {
// skip the package access check on a proxy class in default proxy package
if (!Proxy.isProxyClass(this) || ReflectUtil.isNonPublicProxyClass(this)) {
sm.checkPackageAccess(pkg);
}
}
// check package access on the proxy interfaces
if (checkProxyInterfaces && Proxy.isProxyClass(this)) {
ReflectUtil.checkProxyPackageAccess(ccl, this.getInterfaces());
}
}
// check package access on the proxy interfaces
if (checkProxyInterfaces && Proxy.isProxyClass(this)) {
ReflectUtil.checkProxyPackageAccess(ccl, this.getInterfaces());
}
}
@ -2755,11 +2786,9 @@ public final class Class<T> implements java.io.Serializable,
while (c.isArray()) {
c = c.getComponentType();
}
String baseName = c.getName();
int index = baseName.lastIndexOf('.');
if (index != -1) {
name = baseName.substring(0, index).replace('.', '/')
+"/"+name;
String baseName = c.getPackageName();
if (baseName != null && !baseName.isEmpty()) {
name = baseName.replace('.', '/') + "/" + name;
}
} else {
name = name.substring(1);
@ -3233,7 +3262,7 @@ public final class Class<T> implements java.io.Serializable,
return constructor;
}
}
throw new NoSuchMethodException(getName() + ".<init>" + argumentTypesToString(parameterTypes));
throw new NoSuchMethodException(methodToString("<init>", parameterTypes));
}
//
@ -3294,8 +3323,11 @@ public final class Class<T> implements java.io.Serializable,
private native Constructor<T>[] getDeclaredConstructors0(boolean publicOnly);
private native Class<?>[] getDeclaredClasses0();
private static String argumentTypesToString(Class<?>[] argTypes) {
StringJoiner sj = new StringJoiner(", ", "(", ")");
/**
* Helper method to get the method name from arguments.
*/
private String methodToString(String name, Class<?>[] argTypes) {
StringJoiner sj = new StringJoiner(", ", getName() + "." + name + "(", ")");
if (argTypes != null) {
for (int i = 0; i < argTypes.length; i++) {
Class<?> c = argTypes[i];

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1995, 2016, 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
@ -25,18 +25,30 @@
package java.lang;
import java.security.*;
import java.lang.RuntimePermission;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleDescriptor.Exports;
import java.lang.module.ModuleDescriptor.Opens;
import java.lang.reflect.Layer;
import java.lang.reflect.Member;
import java.lang.reflect.Module;
import java.io.FileDescriptor;
import java.io.File;
import java.io.FilePermission;
import java.util.PropertyPermission;
import java.lang.RuntimePermission;
import java.net.SocketPermission;
import java.net.NetPermission;
import java.util.Hashtable;
import java.net.InetAddress;
import java.lang.reflect.*;
import java.net.URL;
import java.net.SocketPermission;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
import java.security.Security;
import java.security.SecurityPermission;
import java.util.HashSet;
import java.util.Objects;
import java.util.PropertyPermission;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jdk.internal.reflect.CallerSensitive;
import sun.security.util.SecurityConstants;
@ -1415,46 +1427,108 @@ class SecurityManager {
}
}
if (packages == null)
if (packages == null) {
packages = new String[0];
}
return packages;
}
// The non-exported packages of the modules in the boot layer that are
// loaded by the platform class loader or its ancestors. A non-exported
// package is a package that either is not exported at all by its containing
// module or is exported in a qualified fashion by its containing module.
private static final Set<String> nonExportedPkgs;
static {
// Get the modules in the boot layer
Stream<Module> bootLayerModules = Layer.boot().modules().stream();
// Filter out the modules loaded by the boot or platform loader
PrivilegedAction<Set<Module>> pa = () ->
bootLayerModules.filter(SecurityManager::isBootOrPlatformModule)
.collect(Collectors.toSet());
Set<Module> modules = AccessController.doPrivileged(pa);
// Filter out the non-exported packages
nonExportedPkgs = modules.stream()
.map(Module::getDescriptor)
.map(SecurityManager::nonExportedPkgs)
.flatMap(Set::stream)
.collect(Collectors.toSet());
}
/**
* Throws a <code>SecurityException</code> if the
* calling thread is not allowed to access the package specified by
* the argument.
* Returns true if the module's loader is the boot or platform loader.
*/
private static boolean isBootOrPlatformModule(Module m) {
return m.getClassLoader() == null ||
m.getClassLoader() == ClassLoader.getPlatformClassLoader();
}
/**
* Returns the non-exported packages of the specified module.
*/
private static Set<String> nonExportedPkgs(ModuleDescriptor md) {
// start with all packages in the module
Set<String> pkgs = new HashSet<>(md.packages());
// remove the non-qualified exported packages
md.exports().stream()
.filter(p -> !p.isQualified())
.map(Exports::source)
.forEach(pkgs::remove);
// remove the non-qualified open packages
md.opens().stream()
.filter(p -> !p.isQualified())
.map(Opens::source)
.forEach(pkgs::remove);
return pkgs;
}
/**
* Throws a {@code SecurityException} if the calling thread is not allowed
* to access the specified package.
* <p>
* This method is used by the <code>loadClass</code> method of class
* loaders.
* This method is called by the {@code loadClass} method of class loaders.
* <p>
* This method first gets a list of
* restricted packages by obtaining a comma-separated list from
* a call to
* <code>java.security.Security.getProperty("package.access")</code>,
* and checks to see if <code>pkg</code> starts with or equals
* any of the restricted packages. If it does, then
* <code>checkPermission</code> gets called with the
* <code>RuntimePermission("accessClassInPackage."+pkg)</code>
* permission.
* This method checks if the specified package starts with or equals
* any of the packages in the {@code package.access} Security Property.
* An implementation may also check the package against an additional
* list of restricted packages as noted below. If the package is restricted,
* {@link #checkPermission(Permission)} is called with a
* {@code RuntimePermission("accessClassInPackage."+pkg)} permission.
* <p>
* If this method is overridden, then
* <code>super.checkPackageAccess</code> should be called
* as the first line in the overridden method.
* If this method is overridden, then {@code super.checkPackageAccess}
* should be called as the first line in the overridden method.
*
* @implNote
* This implementation also restricts all non-exported packages of modules
* loaded by {@linkplain ClassLoader#getPlatformClassLoader
* the platform class loader} or its ancestors. A "non-exported package"
* refers to a package that is not exported to all modules. Specifically,
* it refers to a package that either is not exported at all by its
* containing module or is exported in a qualified fashion by its
* containing module.
*
* @param pkg the package name.
* @exception SecurityException if the calling thread does not have
* @throws SecurityException if the calling thread does not have
* permission to access the specified package.
* @exception NullPointerException if the package name argument is
* <code>null</code>.
* @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
* loadClass
* @throws NullPointerException if the package name argument is
* {@code null}.
* @see java.lang.ClassLoader#loadClass(String, boolean) loadClass
* @see java.security.Security#getProperty getProperty
* @see #checkPermission(java.security.Permission) checkPermission
* @see #checkPermission(Permission) checkPermission
*/
public void checkPackageAccess(String pkg) {
if (pkg == null) {
throw new NullPointerException("package name can't be null");
Objects.requireNonNull(pkg, "package name can't be null");
// check if pkg is not exported to all modules
if (nonExportedPkgs.contains(pkg)) {
checkPermission(
new RuntimePermission("accessClassInPackage." + pkg));
return;
}
String[] restrictedPkgs;
@ -1512,36 +1586,48 @@ class SecurityManager {
}
/**
* Throws a <code>SecurityException</code> if the
* calling thread is not allowed to define classes in the package
* specified by the argument.
* Throws a {@code SecurityException} if the calling thread is not
* allowed to define classes in the specified package.
* <p>
* This method is used by the <code>loadClass</code> method of some
* This method is called by the {@code loadClass} method of some
* class loaders.
* <p>
* This method first gets a list of restricted packages by
* obtaining a comma-separated list from a call to
* <code>java.security.Security.getProperty("package.definition")</code>,
* and checks to see if <code>pkg</code> starts with or equals
* any of the restricted packages. If it does, then
* <code>checkPermission</code> gets called with the
* <code>RuntimePermission("defineClassInPackage."+pkg)</code>
* permission.
* This method checks if the specified package starts with or equals
* any of the packages in the {@code package.definition} Security
* Property. An implementation may also check the package against an
* additional list of restricted packages as noted below. If the package
* is restricted, {@link #checkPermission(Permission)} is called with a
* {@code RuntimePermission("defineClassInPackage."+pkg)} permission.
* <p>
* If this method is overridden, then
* <code>super.checkPackageDefinition</code> should be called
* as the first line in the overridden method.
* If this method is overridden, then {@code super.checkPackageDefinition}
* should be called as the first line in the overridden method.
*
* @implNote
* This implementation also restricts all non-exported packages of modules
* loaded by {@linkplain ClassLoader#getPlatformClassLoader
* the platform class loader} or its ancestors. A "non-exported package"
* refers to a package that is not exported to all modules. Specifically,
* it refers to a package that either is not exported at all by its
* containing module or is exported in a qualified fashion by its
* containing module.
*
* @param pkg the package name.
* @exception SecurityException if the calling thread does not have
* @throws SecurityException if the calling thread does not have
* permission to define classes in the specified package.
* @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
* @throws NullPointerException if the package name argument is
* {@code null}.
* @see java.lang.ClassLoader#loadClass(String, boolean)
* @see java.security.Security#getProperty getProperty
* @see #checkPermission(java.security.Permission) checkPermission
* @see #checkPermission(Permission) checkPermission
*/
public void checkPackageDefinition(String pkg) {
if (pkg == null) {
throw new NullPointerException("package name can't be null");
Objects.requireNonNull(pkg, "package name can't be null");
// check if pkg is not exported to all modules
if (nonExportedPkgs.contains(pkg)) {
checkPermission(
new RuntimePermission("defineClassInPackage." + pkg));
return;
}
String[] pkgs;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1994, 2016, 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
@ -310,12 +310,13 @@ public final class System {
* @see SecurityManager#checkPermission
* @see java.lang.RuntimePermission
*/
public static
void setSecurityManager(final SecurityManager s) {
try {
s.checkPackageAccess("java.lang");
} catch (Exception e) {
// no-op
public static void setSecurityManager(final SecurityManager s) {
if (s != null) {
try {
s.checkPackageAccess("java.lang");
} catch (Exception e) {
// no-op
}
}
setSecurityManager0(s);
}

View File

@ -28,6 +28,8 @@ package java.lang.invoke;
import static java.lang.invoke.MethodHandleStatics.*;
import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
import jdk.internal.vm.annotation.Stable;
/**
* A {@code CallSite} is a holder for a variable {@link MethodHandle},
* which is called its {@code target}.
@ -215,19 +217,36 @@ public class CallSite {
public abstract MethodHandle dynamicInvoker();
/*non-public*/ MethodHandle makeDynamicInvoker() {
MethodHandle getTarget = GET_TARGET.bindArgumentL(0, this);
MethodHandle getTarget = getTargetHandle().bindArgumentL(0, this);
MethodHandle invoker = MethodHandles.exactInvoker(this.type());
return MethodHandles.foldArguments(invoker, getTarget);
}
private static final MethodHandle GET_TARGET;
private static final MethodHandle THROW_UCS;
static {
private static @Stable MethodHandle GET_TARGET;
private static MethodHandle getTargetHandle() {
MethodHandle handle = GET_TARGET;
if (handle != null) {
return handle;
}
try {
GET_TARGET = IMPL_LOOKUP.
findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class));
THROW_UCS = IMPL_LOOKUP.
findStatic(CallSite.class, "uninitializedCallSite", MethodType.methodType(Object.class, Object[].class));
return GET_TARGET = IMPL_LOOKUP.
findVirtual(CallSite.class, "getTarget",
MethodType.methodType(MethodHandle.class));
} catch (ReflectiveOperationException e) {
throw newInternalError(e);
}
}
private static @Stable MethodHandle THROW_UCS;
private static MethodHandle uninitializedCallSiteHandle() {
MethodHandle handle = THROW_UCS;
if (handle != null) {
return handle;
}
try {
return THROW_UCS = IMPL_LOOKUP.
findStatic(CallSite.class, "uninitializedCallSite",
MethodType.methodType(Object.class, Object[].class));
} catch (ReflectiveOperationException e) {
throw newInternalError(e);
}
@ -242,7 +261,7 @@ public class CallSite {
MethodType basicType = targetType.basicType();
MethodHandle invoker = basicType.form().cachedMethodHandle(MethodTypeForm.MH_UNINIT_CS);
if (invoker == null) {
invoker = THROW_UCS.asType(basicType);
invoker = uninitializedCallSiteHandle().asType(basicType);
invoker = basicType.form().setCachedMethodHandle(MethodTypeForm.MH_UNINIT_CS, invoker);
}
// unchecked view is OK since no values will be received or returned
@ -250,12 +269,16 @@ public class CallSite {
}
// unsafe stuff:
private static final long TARGET_OFFSET;
private static final long CONTEXT_OFFSET;
static {
private static @Stable long TARGET_OFFSET;
private static long getTargetOffset() {
long offset = TARGET_OFFSET;
if (offset > 0) {
return offset;
}
try {
TARGET_OFFSET = UNSAFE.objectFieldOffset(CallSite.class.getDeclaredField("target"));
CONTEXT_OFFSET = UNSAFE.objectFieldOffset(CallSite.class.getDeclaredField("context"));
offset = TARGET_OFFSET = UNSAFE.objectFieldOffset(CallSite.class.getDeclaredField("target"));
assert(offset > 0);
return offset;
} catch (Exception ex) { throw newInternalError(ex); }
}
@ -265,7 +288,7 @@ public class CallSite {
}
/*package-private*/
MethodHandle getTargetVolatile() {
return (MethodHandle) UNSAFE.getObjectVolatile(this, TARGET_OFFSET);
return (MethodHandle) UNSAFE.getObjectVolatile(this, getTargetOffset());
}
/*package-private*/
void setTargetVolatile(MethodHandle newTarget) {
@ -324,7 +347,7 @@ public class CallSite {
final int NON_SPREAD_ARG_COUNT = 3; // (caller, name, type)
if (NON_SPREAD_ARG_COUNT + argv.length > MethodType.MAX_MH_ARITY)
throw new BootstrapMethodError("too many bootstrap method arguments");
MethodType bsmType = bootstrapMethod.type();
MethodType invocationType = MethodType.genericMethodType(NON_SPREAD_ARG_COUNT + argv.length);
MethodHandle typedBSM = bootstrapMethod.asType(invocationType);
MethodHandle spreader = invocationType.invokers().spreadInvoker(NON_SPREAD_ARG_COUNT);

View File

@ -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
@ -846,8 +846,11 @@ public class MethodHandles {
// that does not bluntly restrict classes under packages within
// java.base from looking up MethodHandles or VarHandles.
if (allowedModes == ALL_MODES && lookupClass.getClassLoader() == null) {
if ((name.startsWith("java.") && !name.startsWith("java.util.concurrent.")) ||
(name.startsWith("sun.") && !name.startsWith("sun.invoke."))) {
if ((name.startsWith("java.") &&
!name.equals("java.lang.Thread") &&
!name.startsWith("java.util.concurrent.")) ||
(name.startsWith("sun.") &&
!name.startsWith("sun.invoke."))) {
throw newIllegalArgumentException("illegal lookupClass: " + lookupClass);
}
}

View File

@ -1128,7 +1128,7 @@ class MethodType implements java.io.Serializable {
public String toMethodDescriptorString() {
String desc = methodDescriptor;
if (desc == null) {
desc = BytecodeDescriptor.unparse(this);
desc = BytecodeDescriptor.unparseMethod(this.rtype, this.ptypes);
methodDescriptor = desc;
}
return desc;
@ -1256,7 +1256,7 @@ s.writeObject(this.parameterArray());
private final ReferenceQueue<T> stale;
public ConcurrentWeakInternSet() {
this.map = new ConcurrentHashMap<>();
this.map = new ConcurrentHashMap<>(512);
this.stale = new ReferenceQueue<>();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 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
@ -155,11 +155,12 @@ class SocketInputStream extends FileInputStream
}
// bounds check
if (length <= 0 || off < 0 || off + length > b.length) {
if (length <= 0 || off < 0 || length > b.length - off) {
if (length == 0) {
return 0;
}
throw new ArrayIndexOutOfBoundsException();
throw new ArrayIndexOutOfBoundsException("length == " + length
+ " off == " + off + " buffer length == " + b.length);
}
boolean gotReset = false;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 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
@ -97,11 +97,13 @@ class SocketOutputStream extends FileOutputStream
*/
private void socketWrite(byte b[], int off, int len) throws IOException {
if (len <= 0 || off < 0 || off + len > b.length) {
if (len <= 0 || off < 0 || len > b.length - off) {
if (len == 0) {
return;
}
throw new ArrayIndexOutOfBoundsException();
throw new ArrayIndexOutOfBoundsException("len == " + len
+ " off == " + off + " buffer length == " + b.length);
}
FileDescriptor fd = impl.acquireFD();

View File

@ -1556,9 +1556,6 @@ public final class URL implements java.io.Serializable {
path = file;
}
if (port == -1) {
port = 0;
}
// Set the object fields.
this.protocol = protocol;
this.host = host;

View File

@ -115,8 +115,8 @@ public class URLClassLoader extends SecureClassLoader implements Closeable {
if (security != null) {
security.checkCreateClassLoader();
}
this.ucp = new URLClassPath(urls);
this.acc = AccessController.getContext();
this.ucp = new URLClassPath(urls, acc);
}
URLClassLoader(String name, URL[] urls, ClassLoader parent,
@ -127,8 +127,8 @@ public class URLClassLoader extends SecureClassLoader implements Closeable {
if (security != null) {
security.checkCreateClassLoader();
}
this.ucp = new URLClassPath(urls);
this.acc = acc;
this.ucp = new URLClassPath(urls, acc);
}
/**
@ -159,8 +159,8 @@ public class URLClassLoader extends SecureClassLoader implements Closeable {
if (security != null) {
security.checkCreateClassLoader();
}
this.ucp = new URLClassPath(urls);
this.acc = AccessController.getContext();
this.ucp = new URLClassPath(urls, acc);
}
URLClassLoader(URL[] urls, AccessControlContext acc) {
@ -170,8 +170,8 @@ public class URLClassLoader extends SecureClassLoader implements Closeable {
if (security != null) {
security.checkCreateClassLoader();
}
this.ucp = new URLClassPath(urls);
this.acc = acc;
this.ucp = new URLClassPath(urls, acc);
}
/**
@ -203,8 +203,8 @@ public class URLClassLoader extends SecureClassLoader implements Closeable {
if (security != null) {
security.checkCreateClassLoader();
}
this.ucp = new URLClassPath(urls, factory);
this.acc = AccessController.getContext();
this.ucp = new URLClassPath(urls, factory, acc);
}
@ -238,8 +238,8 @@ public class URLClassLoader extends SecureClassLoader implements Closeable {
if (security != null) {
security.checkCreateClassLoader();
}
this.ucp = new URLClassPath(urls);
this.acc = AccessController.getContext();
this.ucp = new URLClassPath(urls, acc);
}
/**
@ -271,8 +271,8 @@ public class URLClassLoader extends SecureClassLoader implements Closeable {
if (security != null) {
security.checkCreateClassLoader();
}
this.ucp = new URLClassPath(urls, factory);
this.acc = AccessController.getContext();
this.ucp = new URLClassPath(urls, factory, acc);
}
/* A map (used as a set) to keep track of closeable local resources

View File

@ -30,8 +30,10 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.security.PrivilegedAction;
import java.util.Hashtable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Date;
import java.util.Iterator;
import java.util.Locale;
import java.util.Objects;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
@ -231,7 +233,7 @@ public abstract class URLConnection {
*/
protected boolean allowUserInteraction = defaultAllowUserInteraction;
private static boolean defaultUseCaches = true;
private static volatile boolean defaultUseCaches = true;
/**
* If {@code true}, the protocol is allowed to use caching
@ -243,12 +245,18 @@ public abstract class URLConnection {
* <p>
* Its default value is the value given in the last invocation of the
* {@code setDefaultUseCaches} method.
* <p>
* The default setting may be overridden per protocol with
* {@link #setDefaultUseCaches(String,boolean)}.
*
* @see java.net.URLConnection#setUseCaches(boolean)
* @see java.net.URLConnection#getUseCaches()
* @see java.net.URLConnection#setDefaultUseCaches(boolean)
*/
protected boolean useCaches = defaultUseCaches;
protected boolean useCaches;
private static final ConcurrentHashMap<String,Boolean> defaultCaching =
new ConcurrentHashMap<>();
/**
* Some protocols support skipping the fetching of the object unless
@ -460,6 +468,11 @@ public abstract class URLConnection {
*/
protected URLConnection(URL url) {
this.url = url;
if (url == null) {
this.useCaches = defaultUseCaches;
} else {
this.useCaches = getDefaultUseCaches(url.getProtocol());
}
}
/**
@ -981,7 +994,8 @@ public abstract class URLConnection {
* is true, the connection is allowed to use whatever caches it can.
* If false, caches are to be ignored.
* The default value comes from DefaultUseCaches, which defaults to
* true.
* true. A default value can also be set per-protocol using
* {@link #setDefaultUseCaches(String,boolean)}.
*
* @param usecaches a {@code boolean} indicating whether
* or not to allow caching
@ -1032,9 +1046,10 @@ public abstract class URLConnection {
* Returns the default value of a {@code URLConnection}'s
* {@code useCaches} flag.
* <p>
* Ths default is "sticky", being a part of the static state of all
* This default is "sticky", being a part of the static state of all
* URLConnections. This flag applies to the next, and all following
* URLConnections that are created.
* URLConnections that are created. This default value can be over-ridden
* per protocol using {@link #setDefaultUseCaches(String,boolean)}
*
* @return the default value of a {@code URLConnection}'s
* {@code useCaches} flag.
@ -1046,7 +1061,8 @@ public abstract class URLConnection {
/**
* Sets the default value of the {@code useCaches} field to the
* specified value.
* specified value. This default value can be over-ridden
* per protocol using {@link #setDefaultUseCaches(String,boolean)}
*
* @param defaultusecaches the new value.
* @see #getDefaultUseCaches()
@ -1055,6 +1071,43 @@ public abstract class URLConnection {
defaultUseCaches = defaultusecaches;
}
/**
* Sets the default value of the {@code useCaches} field for the named
* protocol to the given value. This value overrides any default setting
* set by {@link #setDefaultUseCaches(boolean)} for the given protocol.
* Successive calls to this method change the setting and affect the
* default value for all future connections of that protocol. The protocol
* name is case insensitive.
*
* @param protocol the protocol to set the default for
* @param defaultVal whether caching is enabled by default for the given protocol
* @since 9
*/
public static void setDefaultUseCaches(String protocol, boolean defaultVal) {
protocol = protocol.toLowerCase(Locale.US);
defaultCaching.put(protocol, defaultVal);
}
/**
* Returns the default value of the {@code useCaches} flag for the given protocol. If
* {@link #setDefaultUseCaches(String,boolean)} was called for the given protocol,
* then that value is returned. Otherwise, if {@link #setDefaultUseCaches(boolean)}
* was called, then that value is returned. If neither method was called,
* the return value is {@code true}. The protocol name is case insensitive.
*
* @param protocol the protocol whose defaultUseCaches setting is required
* @return the default value of the {@code useCaches} flag for the given protocol.
* @since 9
*/
public static boolean getDefaultUseCaches(String protocol) {
Boolean protoDefault = defaultCaching.get(protocol.toLowerCase(Locale.US));
if (protoDefault != null) {
return protoDefault.booleanValue();
} else {
return defaultUseCaches;
}
}
/**
* Sets the general request property. If a property with the key already
* exists, overwrite its value with the new value.

View File

@ -161,9 +161,9 @@ public abstract class URLStreamHandler {
(spec.charAt(start + 1) == '/')) {
start += 2;
i = spec.indexOf('/', start);
if (i < 0) {
if (i < 0 || i > limit) {
i = spec.indexOf('?', start);
if (i < 0)
if (i < 0 || i > limit)
i = limit;
}
@ -171,8 +171,14 @@ public abstract class URLStreamHandler {
int ind = authority.indexOf('@');
if (ind != -1) {
userInfo = authority.substring(0, ind);
host = authority.substring(ind+1);
if (ind != authority.lastIndexOf('@')) {
// more than one '@' in authority. This is not server based
userInfo = null;
host = null;
} else {
userInfo = authority.substring(0, ind);
host = authority.substring(ind+1);
}
} else {
userInfo = null;
}

View File

@ -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
@ -4354,6 +4354,11 @@ public class Collections {
private Object readResolve() {
return EMPTY_SET;
}
@Override
public int hashCode() {
return 0;
}
}
/**
@ -4786,6 +4791,10 @@ public class Collections {
public boolean removeIf(Predicate<? super E> filter) {
throw new UnsupportedOperationException();
}
@Override
public int hashCode() {
return Objects.hashCode(element);
}
}
/**
@ -4848,6 +4857,10 @@ public class Collections {
public Spliterator<E> spliterator() {
return singletonSpliterator(element);
}
@Override
public int hashCode() {
return 31 + Objects.hashCode(element);
}
}
/**
@ -4970,6 +4983,11 @@ public class Collections {
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
throw new UnsupportedOperationException();
}
@Override
public int hashCode() {
return Objects.hashCode(k) ^ Objects.hashCode(v);
}
}
// Miscellaneous

View File

@ -82,17 +82,19 @@ import sun.util.calendar.ZoneInfo;
* well; for example, the time scale used by the satellite-based
* global positioning system (GPS) is synchronized to UTC but is
* <i>not</i> adjusted for leap seconds. An interesting source of
* further information is the U.S. Naval Observatory, particularly
* the Directorate of Time at:
* further information is the United States Naval Observatory (USNO):
* <blockquote><pre>
* <a href="http://www.usno.navy.mil">http://www.usno.navy.mil</a>
* <a href="http://www.usno.navy.mil/USNO">http://www.usno.navy.mil/USNO</a>
* </pre></blockquote>
* <p>
* and their definitions of "Systems of Time" at:
* and the material regarding "Systems of Time" at:
* <blockquote><pre>
* <a href="http://www.usno.navy.mil/USNO/time/master-clock/systems-of-time">http://www.usno.navy.mil/USNO/time/master-clock/systems-of-time</a>
* </pre></blockquote>
* <p>
* which has descriptions of various different time systems including
* UT, UT1, and UTC.
* <p>
* In all methods of class {@code Date} that accept or return
* year, month, date, hours, minutes, and seconds values, the
* following representations are used:

View File

@ -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
@ -35,6 +35,7 @@ import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import jdk.internal.vm.annotation.Stable;
/**
* Container class for immutable collections. Not part of the public API.
@ -105,6 +106,11 @@ class ImmutableCollections {
return null; // but the compiler doesn't know this
}
@Override
public Iterator<E> iterator() {
return Collections.emptyIterator();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
throw new InvalidObjectException("not serial proxy");
}
@ -112,9 +118,26 @@ class ImmutableCollections {
private Object writeReplace() {
return new CollSer(CollSer.IMM_LIST);
}
@Override
public boolean contains(Object o) {
Objects.requireNonNull(o);
return false;
}
@Override
public boolean containsAll(Collection<?> o) {
return o.isEmpty(); // implicit nullcheck of o
}
@Override
public int hashCode() {
return 1;
}
}
static final class List1<E> extends AbstractImmutableList<E> {
@Stable
private final E e0;
List1(E e0) {
@ -129,7 +152,6 @@ class ImmutableCollections {
@Override
public E get(int index) {
Objects.checkIndex(index, 1);
// assert index == 0
return e0;
}
@ -140,10 +162,22 @@ class ImmutableCollections {
private Object writeReplace() {
return new CollSer(CollSer.IMM_LIST, e0);
}
@Override
public boolean contains(Object o) {
return o.equals(e0); // implicit nullcheck of o
}
@Override
public int hashCode() {
return 31 + e0.hashCode();
}
}
static final class List2<E> extends AbstractImmutableList<E> {
@Stable
private final E e0;
@Stable
private final E e1;
List2(E e0, E e1) {
@ -166,6 +200,17 @@ class ImmutableCollections {
}
}
@Override
public boolean contains(Object o) {
return o.equals(e0) || o.equals(e1); // implicit nullcheck of o
}
@Override
public int hashCode() {
int hash = 31 + e0.hashCode();
return 31 * hash + e1.hashCode();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
throw new InvalidObjectException("not serial proxy");
}
@ -176,6 +221,7 @@ class ImmutableCollections {
}
static final class ListN<E> extends AbstractImmutableList<E> {
@Stable
private final E[] elements;
@SafeVarargs
@ -200,6 +246,25 @@ class ImmutableCollections {
return elements[index];
}
@Override
public boolean contains(Object o) {
for (E e : elements) {
if (o.equals(e)) { // implicit nullcheck of o
return true;
}
}
return false;
}
@Override
public int hashCode() {
int hash = 1;
for (E e : elements) {
hash = 31 * hash + e.hashCode();
}
return hash;
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
throw new InvalidObjectException("not serial proxy");
}
@ -238,7 +303,13 @@ class ImmutableCollections {
@Override
public boolean contains(Object o) {
return super.contains(Objects.requireNonNull(o));
Objects.requireNonNull(o);
return false;
}
@Override
public boolean containsAll(Collection<?> o) {
return o.isEmpty(); // implicit nullcheck of o
}
@Override
@ -253,9 +324,15 @@ class ImmutableCollections {
private Object writeReplace() {
return new CollSer(CollSer.IMM_SET);
}
@Override
public int hashCode() {
return 0;
}
}
static final class Set1<E> extends AbstractImmutableSet<E> {
@Stable
private final E e0;
Set1(E e0) {
@ -269,7 +346,7 @@ class ImmutableCollections {
@Override
public boolean contains(Object o) {
return super.contains(Objects.requireNonNull(o));
return o.equals(e0); // implicit nullcheck of o
}
@Override
@ -284,17 +361,21 @@ class ImmutableCollections {
private Object writeReplace() {
return new CollSer(CollSer.IMM_SET, e0);
}
@Override
public int hashCode() {
return e0.hashCode();
}
}
static final class Set2<E> extends AbstractImmutableSet<E> {
private final E e0;
private final E e1;
@Stable
final E e0;
@Stable
final E e1;
Set2(E e0, E e1) {
Objects.requireNonNull(e0);
Objects.requireNonNull(e1);
if (e0.equals(e1)) {
if (e0.equals(Objects.requireNonNull(e1))) { // implicit nullcheck of e0
throw new IllegalArgumentException("duplicate element: " + e0);
}
@ -314,7 +395,12 @@ class ImmutableCollections {
@Override
public boolean contains(Object o) {
return super.contains(Objects.requireNonNull(o));
return o.equals(e0) || o.equals(e1); // implicit nullcheck of o
}
@Override
public int hashCode() {
return e0.hashCode() + e1.hashCode();
}
@Override
@ -358,8 +444,10 @@ class ImmutableCollections {
* @param <E> the element type
*/
static final class SetN<E> extends AbstractImmutableSet<E> {
private final E[] elements;
private final int size;
@Stable
final E[] elements;
@Stable
final int size;
@SafeVarargs
@SuppressWarnings("unchecked")
@ -368,8 +456,8 @@ class ImmutableCollections {
elements = (E[])new Object[EXPAND_FACTOR * input.length];
for (int i = 0; i < input.length; i++) {
E e = Objects.requireNonNull(input[i]);
int idx = probe(e);
E e = input[i];
int idx = probe(e); // implicit nullcheck of e
if (idx >= 0) {
throw new IllegalArgumentException("duplicate element: " + e);
} else {
@ -385,8 +473,7 @@ class ImmutableCollections {
@Override
public boolean contains(Object o) {
Objects.requireNonNull(o);
return probe(o) >= 0;
return probe(o) >= 0; // implicit nullcheck of o
}
@Override
@ -414,8 +501,21 @@ class ImmutableCollections {
};
}
@Override
public int hashCode() {
int h = 0;
for (E e : elements) {
if (e != null) {
h += e.hashCode();
}
}
return h;
}
// returns index at which element is present; or if absent,
// (-i - 1) where i is location where element should be inserted
// (-i - 1) where i is location where element should be inserted.
// Callers are relying on this method to perform an implicit nullcheck
// of pe
private int probe(Object pe) {
int idx = Math.floorMod(pe.hashCode() ^ SALT, elements.length);
while (true) {
@ -481,12 +581,14 @@ class ImmutableCollections {
@Override
public boolean containsKey(Object o) {
return super.containsKey(Objects.requireNonNull(o));
Objects.requireNonNull(o);
return false;
}
@Override
public boolean containsValue(Object o) {
return super.containsValue(Objects.requireNonNull(o));
Objects.requireNonNull(o);
return false;
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
@ -496,10 +598,17 @@ class ImmutableCollections {
private Object writeReplace() {
return new CollSer(CollSer.IMM_MAP);
}
@Override
public int hashCode() {
return 0;
}
}
static final class Map1<K,V> extends AbstractImmutableMap<K,V> {
@Stable
private final K k0;
@Stable
private final V v0;
Map1(K k0, V v0) {
@ -514,12 +623,12 @@ class ImmutableCollections {
@Override
public boolean containsKey(Object o) {
return super.containsKey(Objects.requireNonNull(o));
return o.equals(k0); // implicit nullcheck of o
}
@Override
public boolean containsValue(Object o) {
return super.containsValue(Objects.requireNonNull(o));
return o.equals(v0); // implicit nullcheck of o
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
@ -529,6 +638,11 @@ class ImmutableCollections {
private Object writeReplace() {
return new CollSer(CollSer.IMM_MAP, k0, v0);
}
@Override
public int hashCode() {
return k0.hashCode() ^ v0.hashCode();
}
}
/**
@ -541,12 +655,13 @@ class ImmutableCollections {
* @param <V> the value type
*/
static final class MapN<K,V> extends AbstractImmutableMap<K,V> {
private final Object[] table; // pairs of key, value
private final int size; // number of pairs
@Stable
final Object[] table; // pairs of key, value
@Stable
final int size; // number of pairs
MapN(Object... input) {
Objects.requireNonNull(input);
if ((input.length & 1) != 0) {
if ((input.length & 1) != 0) { // implicit nullcheck of input
throw new InternalError("length is odd");
}
size = input.length >> 1;
@ -573,12 +688,30 @@ class ImmutableCollections {
@Override
public boolean containsKey(Object o) {
return probe(Objects.requireNonNull(o)) >= 0;
return probe(o) >= 0; // implicit nullcheck of o
}
@Override
public boolean containsValue(Object o) {
return super.containsValue(Objects.requireNonNull(o));
for (int i = 1; i < table.length; i += 2) {
Object v = table[i];
if (v != null && o.equals(v)) { // implicit nullcheck of o
return true;
}
}
return false;
}
@Override
public int hashCode() {
int hash = 0;
for (int i = 0; i < table.length; i += 2) {
Object k = table[i];
if (k != null) {
hash += k.hashCode() ^ table[i + 1].hashCode();
}
}
return hash;
}
@Override
@ -638,7 +771,9 @@ class ImmutableCollections {
}
// returns index at which the probe key is present; or if absent,
// (-i - 1) where i is location where element should be inserted
// (-i - 1) where i is location where element should be inserted.
// Callers are relying on this method to perform an implicit nullcheck
// of pk.
private int probe(Object pk) {
int idx = Math.floorMod(pk.hashCode() ^ SALT, table.length >> 1) << 1;
while (true) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,6 +25,8 @@
package java.util;
import jdk.internal.vm.annotation.Stable;
/**
* An immutable container for a key and a value, suitable for use
* in creating and populating {@code Map} instances.
@ -48,7 +50,9 @@ package java.util;
* @since 9
*/
final class KeyValueHolder<K,V> implements Map.Entry<K,V> {
@Stable
final K key;
@Stable
final V value;
KeyValueHolder(K k, V v) {

View File

@ -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
@ -1027,8 +1027,7 @@ public interface List<E> extends Collection<E> {
@SafeVarargs
@SuppressWarnings("varargs")
static <E> List<E> of(E... elements) {
Objects.requireNonNull(elements);
switch (elements.length) {
switch (elements.length) { // implicit null check of elements
case 0:
return ImmutableCollections.List0.instance();
case 1:

View File

@ -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
@ -1602,8 +1602,7 @@ public interface Map<K, V> {
@SafeVarargs
@SuppressWarnings("varargs")
static <K, V> Map<K, V> ofEntries(Entry<? extends K, ? extends V>... entries) {
Objects.requireNonNull(entries);
if (entries.length == 0) {
if (entries.length == 0) { // implicit null check of entries
return ImmutableCollections.Map0.instance();
} else if (entries.length == 1) {
return new ImmutableCollections.Map1<>(entries[0].getKey(),

View File

@ -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
@ -43,6 +43,7 @@ package java.util;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
@ -365,7 +366,7 @@ public abstract class ResourceBundle {
@Override
public ResourceBundle getBundle(String baseName, Locale locale, Module module) {
// use the given module as the caller to bypass the access check
return getBundleImpl(module, module, getLoader(module),
return getBundleImpl(module, module,
baseName, locale, Control.INSTANCE);
}
@ -537,63 +538,19 @@ public abstract class ResourceBundle {
return locale;
}
/*
* Automatic determination of the ClassLoader to be used to load
* resources on behalf of the client.
*/
private static ClassLoader getLoader(Class<?> caller) {
ClassLoader cl = caller == null ? null : caller.getClassLoader();
if (cl == null) {
// When the caller's loader is the boot class loader, cl is null
// here. In that case, ClassLoader.getSystemClassLoader() may
// return the same class loader that the application is
// using. We therefore use a wrapper ClassLoader to create a
// separate scope for bundles loaded on behalf of the Java
// runtime so that these bundles cannot be returned from the
// cache to the application (5048280).
cl = RBClassLoader.INSTANCE;
}
return cl;
}
private static ClassLoader getLoader(Module module) {
PrivilegedAction<ClassLoader> pa = module::getClassLoader;
return AccessController.doPrivileged(pa);
}
/**
* A wrapper of ClassLoader.getSystemClassLoader().
* @param module a non-null-screened module form the {@link CacheKey#getModule()}.
* @return the ClassLoader to use in {@link Control#needsReload}
* and {@link Control#newBundle}
*/
private static class RBClassLoader extends ClassLoader {
private static final RBClassLoader INSTANCE = AccessController.doPrivileged(
new PrivilegedAction<RBClassLoader>() {
public RBClassLoader run() {
return new RBClassLoader();
}
});
private RBClassLoader() {
}
public Class<?> loadClass(String name) throws ClassNotFoundException {
ClassLoader loader = ClassLoader.getSystemClassLoader();
if (loader != null) {
return loader.loadClass(name);
}
return Class.forName(name);
}
public URL getResource(String name) {
ClassLoader loader = ClassLoader.getSystemClassLoader();
if (loader != null) {
return loader.getResource(name);
}
return ClassLoader.getSystemResource(name);
}
public InputStream getResourceAsStream(String name) {
ClassLoader loader = ClassLoader.getSystemClassLoader();
if (loader != null) {
return loader.getResourceAsStream(name);
}
return ClassLoader.getSystemResourceAsStream(name);
}
private static ClassLoader getLoaderForControl(Module module) {
ClassLoader loader = getLoader(module);
return loader == null ? ClassLoader.getSystemClassLoader() : loader;
}
/**
@ -610,23 +567,23 @@ public abstract class ResourceBundle {
/**
* Key used for cached resource bundles. The key checks the base
* name, the locale, the class loader, and the caller module
* name, the locale, the bundle module, and the caller module
* to determine if the resource is a match to the requested one.
* The loader may be null, but the base name, the locale and
* module must have a non-null value.
* The base name, the locale and both modules must have a non-null value.
*/
private static class CacheKey implements Cloneable {
private static final class CacheKey {
// These four are the actual keys for lookup in Map.
private String name;
private Locale locale;
private KeyElementReference<ClassLoader> loaderRef;
private KeyElementReference<Module> moduleRef;
private KeyElementReference<Module> callerRef;
private final String name;
private volatile Locale locale;
private final KeyElementReference<Module> moduleRef;
private final KeyElementReference<Module> callerRef;
// this is the part of hashCode that pertains to module and callerModule
// which can be GCed..
private final int modulesHash;
// bundle format which is necessary for calling
// Control.needsReload().
private String format;
private volatile String format;
// These time values are in CacheKey so that NONEXISTENT_BUNDLE
// doesn't need to be cloned for caching.
@ -639,63 +596,55 @@ public abstract class ResourceBundle {
private volatile long expirationTime;
// Placeholder for an error report by a Throwable
private Throwable cause;
// Hash code value cache to avoid recalculating the hash code
// of this instance.
private int hashCodeCache;
private volatile Throwable cause;
// ResourceBundleProviders for loading ResourceBundles
private ServiceLoader<ResourceBundleProvider> providers;
private boolean providersChecked;
private volatile ServiceLoader<ResourceBundleProvider> providers;
private volatile boolean providersChecked;
// Boolean.TRUE if the factory method caller provides a ResourceBundleProvier.
private Boolean callerHasProvider;
private volatile Boolean callerHasProvider;
CacheKey(String baseName, Locale locale, ClassLoader loader, Module module, Module caller) {
CacheKey(String baseName, Locale locale, Module module, Module caller) {
Objects.requireNonNull(module);
Objects.requireNonNull(caller);
this.name = baseName;
this.locale = locale;
if (loader == null) {
this.loaderRef = null;
} else {
this.loaderRef = new KeyElementReference<>(loader, referenceQueue, this);
}
this.moduleRef = new KeyElementReference<>(module, referenceQueue, this);
this.callerRef = new KeyElementReference<>(caller, referenceQueue, this);
this.modulesHash = module.hashCode() ^ caller.hashCode();
}
calculateHashCode();
CacheKey(CacheKey src) {
// Create References to src's modules
this.moduleRef = new KeyElementReference<>(
Objects.requireNonNull(src.getModule()), referenceQueue, this);
this.callerRef = new KeyElementReference<>(
Objects.requireNonNull(src.getCallerModule()), referenceQueue, this);
// Copy fields from src. ResourceBundleProviders related fields
// and "cause" should not be copied.
this.name = src.name;
this.locale = src.locale;
this.modulesHash = src.modulesHash;
this.format = src.format;
this.loadTime = src.loadTime;
this.expirationTime = src.expirationTime;
}
String getName() {
return name;
}
CacheKey setName(String baseName) {
if (!this.name.equals(baseName)) {
this.name = baseName;
calculateHashCode();
}
return this;
}
Locale getLocale() {
return locale;
}
CacheKey setLocale(Locale locale) {
if (!this.locale.equals(locale)) {
this.locale = locale;
calculateHashCode();
}
this.locale = locale;
return this;
}
ClassLoader getLoader() {
return (loaderRef != null) ? loaderRef.get() : null;
}
Module getModule() {
return moduleRef.get();
}
@ -728,7 +677,7 @@ public abstract class ResourceBundle {
try {
final CacheKey otherEntry = (CacheKey)other;
//quick check to see if they are not equal
if (hashCodeCache != otherEntry.hashCodeCache) {
if (modulesHash != otherEntry.modulesHash) {
return false;
}
//are the names the same?
@ -739,24 +688,11 @@ public abstract class ResourceBundle {
if (!locale.equals(otherEntry.locale)) {
return false;
}
//are refs (both non-null) or (both null)?
if (loaderRef == null) {
return otherEntry.loaderRef == null;
}
ClassLoader loader = getLoader();
// are modules and callerModules the same and non-null?
Module module = getModule();
Module caller = getCallerModule();
return (otherEntry.loaderRef != null)
// with a null reference we can no longer find
// out which class loader or module was referenced; so
// treat it as unequal
&& (loader != null)
&& (loader == otherEntry.getLoader())
&& (module != null)
&& (module.equals(otherEntry.getModule()))
&& (caller != null)
&& (caller.equals(otherEntry.getCallerModule()));
return ((module != null) && (module.equals(otherEntry.getModule())) &&
(caller != null) && (caller.equals(otherEntry.getCallerModule())));
} catch (NullPointerException | ClassCastException e) {
}
return false;
@ -764,51 +700,7 @@ public abstract class ResourceBundle {
@Override
public int hashCode() {
return hashCodeCache;
}
private void calculateHashCode() {
hashCodeCache = name.hashCode() << 3;
hashCodeCache ^= locale.hashCode();
ClassLoader loader = getLoader();
if (loader != null) {
hashCodeCache ^= loader.hashCode();
}
Module module = getModule();
if (module != null) {
hashCodeCache ^= module.hashCode();
}
Module caller = getCallerModule();
if (caller != null) {
hashCodeCache ^= caller.hashCode();
}
}
@Override
public Object clone() {
try {
CacheKey clone = (CacheKey) super.clone();
if (loaderRef != null) {
clone.loaderRef = new KeyElementReference<>(getLoader(),
referenceQueue, clone);
}
clone.moduleRef = new KeyElementReference<>(getModule(),
referenceQueue, clone);
clone.callerRef = new KeyElementReference<>(getCallerModule(),
referenceQueue, clone);
// Clear the reference to ResourceBundleProviders and the flag
clone.providers = null;
clone.providersChecked = false;
// Clear the reference to a Throwable
clone.cause = null;
// Clear callerHasProvider
clone.callerHasProvider = null;
return clone;
} catch (CloneNotSupportedException e) {
//this should never happen
throw new InternalError(e);
}
return (name.hashCode() << 3) ^ locale.hashCode() ^ modulesHash;
}
String getFormat() {
@ -845,8 +737,12 @@ public abstract class ResourceBundle {
l = "\"\"";
}
}
return "CacheKey[" + name + ", lc=" + l + ", ldr=" + getLoader()
+ "(format=" + format + ")]";
return "CacheKey[" + name +
", locale=" + l +
", module=" + getModule() +
", callerModule=" + getCallerModule() +
", format=" + format +
"]";
}
}
@ -1568,7 +1464,7 @@ public abstract class ResourceBundle {
Locale locale,
Class<?> caller,
Control control) {
return getBundleImpl(baseName, locale, caller, getLoader(caller), control);
return getBundleImpl(baseName, locale, caller, caller.getClassLoader(), control);
}
/**
@ -1587,26 +1483,25 @@ public abstract class ResourceBundle {
Class<?> caller,
ClassLoader loader,
Control control) {
if (caller != null && caller.getModule().isNamed()) {
Module module = caller.getModule();
ClassLoader ml = getLoader(module);
// get resource bundles for a named module only
// if loader is the module's class loader
if (loader == ml || (ml == null && loader == RBClassLoader.INSTANCE)) {
return getBundleImpl(module, module, loader, baseName, locale, control);
}
}
// find resource bundles from unnamed module
Module unnamedModule = loader != null
? loader.getUnnamedModule()
: ClassLoader.getSystemClassLoader().getUnnamedModule();
if (caller == null) {
throw new InternalError("null caller");
}
Module callerModule = caller.getModule();
return getBundleImpl(callerModule, unnamedModule, loader, baseName, locale, control);
// get resource bundles for a named module only if loader is the module's class loader
if (callerModule.isNamed() && loader == getLoader(callerModule)) {
return getBundleImpl(callerModule, callerModule, baseName, locale, control);
}
// find resource bundles from unnamed module of given class loader
// Java agent can add to the bootclasspath e.g. via
// java.lang.instrument.Instrumentation and load classes in unnamed module.
// It may call RB::getBundle that will end up here with loader == null.
Module unnamedModule = loader != null
? loader.getUnnamedModule()
: BootLoader.getUnnamedModule();
return getBundleImpl(callerModule, unnamedModule, baseName, locale, control);
}
private static ResourceBundle getBundleFromModule(Class<?> caller,
@ -1622,12 +1517,11 @@ public abstract class ResourceBundle {
sm.checkPermission(GET_CLASSLOADER_PERMISSION);
}
}
return getBundleImpl(callerModule, module, getLoader(module), baseName, locale, control);
return getBundleImpl(callerModule, module, baseName, locale, control);
}
private static ResourceBundle getBundleImpl(Module callerModule,
Module module,
ClassLoader loader,
String baseName,
Locale locale,
Control control) {
@ -1636,10 +1530,10 @@ public abstract class ResourceBundle {
}
// We create a CacheKey here for use by this call. The base name
// loader, and module will never change during the bundle loading
// and modules will never change during the bundle loading
// process. We have to make sure that the locale is set before
// using it as a cache key.
CacheKey cacheKey = new CacheKey(baseName, locale, loader, module, callerModule);
CacheKey cacheKey = new CacheKey(baseName, locale, module, callerModule);
ResourceBundle bundle = null;
// Quick lookup of the cache.
@ -1708,6 +1602,11 @@ public abstract class ResourceBundle {
bundle = baseBundle;
}
// keep callerModule and module reachable for as long as we are operating
// with WeakReference(s) to them (in CacheKey)...
Reference.reachabilityFence(callerModule);
Reference.reachabilityFence(module);
return bundle;
}
@ -1745,7 +1644,7 @@ public abstract class ResourceBundle {
}
// Before we do the real loading work, see whether we need to
// do some housekeeping: If references to class loaders or
// do some housekeeping: If references to modules or
// resource bundles have been nulled out, remove all related
// information from the cache.
Object ref;
@ -1781,31 +1680,24 @@ public abstract class ResourceBundle {
}
if (bundle != NONEXISTENT_BUNDLE) {
CacheKey constKey = (CacheKey) cacheKey.clone();
trace("findBundle: %d %s %s formats: %s%n", index, candidateLocales, cacheKey, formats);
try {
if (module.isNamed()) {
bundle = loadBundle(cacheKey, formats, control, module, callerModule);
} else {
bundle = loadBundle(cacheKey, formats, control, expiredBundle);
}
if (bundle != null) {
if (bundle.parent == null) {
bundle.setParent(parent);
}
bundle.locale = targetLocale;
bundle = putBundleInCache(cacheKey, bundle, control);
return bundle;
}
// Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle
// instance for the locale.
putBundleInCache(cacheKey, NONEXISTENT_BUNDLE, control);
} finally {
if (constKey.getCause() instanceof InterruptedException) {
Thread.currentThread().interrupt();
}
if (module.isNamed()) {
bundle = loadBundle(cacheKey, formats, control, module, callerModule);
} else {
bundle = loadBundle(cacheKey, formats, control, expiredBundle);
}
if (bundle != null) {
if (bundle.parent == null) {
bundle.setParent(parent);
}
bundle.locale = targetLocale;
bundle = putBundleInCache(cacheKey, bundle, control);
return bundle;
}
// Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle
// instance for the locale.
putBundleInCache(cacheKey, NONEXISTENT_BUNDLE, control);
}
return parent;
}
@ -1991,12 +1883,20 @@ public abstract class ResourceBundle {
// specified by the getFormats() value.
Locale targetLocale = cacheKey.getLocale();
Module module = cacheKey.getModule();
if (module == null) {
// should not happen
throw new InternalError(
"Module for cache key: " + cacheKey + " has been GCed.");
}
ClassLoader loader = getLoaderForControl(module);
ResourceBundle bundle = null;
for (String format : formats) {
try {
// ResourceBundle.Control.newBundle may be overridden
bundle = control.newBundle(cacheKey.getName(), targetLocale, format,
cacheKey.getLoader(), reload);
loader, reload);
} catch (LinkageError | Exception error) {
// We need to handle the LinkageError case due to
// inconsistent case-sensitivity in ClassLoader.
@ -2138,12 +2038,15 @@ public abstract class ResourceBundle {
if (!bundle.expired && expirationTime >= 0 &&
expirationTime <= System.currentTimeMillis()) {
try {
bundle.expired = control.needsReload(key.getName(),
key.getLocale(),
key.getFormat(),
key.getLoader(),
bundle,
key.loadTime);
Module module = cacheKey.getModule();
bundle.expired =
module == null || // already GCed
control.needsReload(key.getName(),
key.getLocale(),
key.getFormat(),
getLoaderForControl(module),
bundle,
key.loadTime);
} catch (Exception e) {
cacheKey.setCause(e);
}
@ -2185,7 +2088,7 @@ public abstract class ResourceBundle {
Control control) {
setExpirationTime(cacheKey, control);
if (cacheKey.expirationTime != Control.TTL_DONT_CACHE) {
CacheKey key = (CacheKey) cacheKey.clone();
CacheKey key = new CacheKey(cacheKey);
BundleReference bundleRef = new BundleReference(bundle, referenceQueue, key);
bundle.cacheKey = key;
@ -2231,7 +2134,7 @@ public abstract class ResourceBundle {
/**
* Removes all resource bundles from the cache that have been loaded
* by the caller's module using the caller's class loader.
* by the caller's module.
*
* @since 1.6
* @see ResourceBundle.Control#getTimeToLive(String,Locale)
@ -2239,47 +2142,29 @@ public abstract class ResourceBundle {
@CallerSensitive
public static final void clearCache() {
Class<?> caller = Reflection.getCallerClass();
clearCache(getLoader(caller), caller.getModule());
cacheList.keySet().removeIf(
key -> key.getCallerModule() == caller.getModule()
);
}
/**
* Removes all resource bundles from the cache that have been loaded
* by the caller's module using the given class loader.
* by the given class loader.
*
* @param loader the class loader
* @exception NullPointerException if <code>loader</code> is null
* @since 1.6
* @see ResourceBundle.Control#getTimeToLive(String,Locale)
*/
@CallerSensitive
public static final void clearCache(ClassLoader loader) {
Objects.requireNonNull(loader);
clearCache(loader, Reflection.getCallerClass().getModule());
}
/**
* Removes all resource bundles from the cache that have been loaded by the
* given {@code module}.
*
* @param module the module
* @throws NullPointerException
* if {@code module} is {@code null}
* @throws SecurityException
* if the caller doesn't have the permission to
* {@linkplain Module#getClassLoader() get the class loader}
* of the given {@code module}
* @since 9
* @see ResourceBundle.Control#getTimeToLive(String,Locale)
*/
public static final void clearCache(Module module) {
clearCache(module.getClassLoader(), module);
}
private static void clearCache(ClassLoader loader, Module module) {
Set<CacheKey> set = cacheList.keySet();
set.stream()
.filter((key) -> (key.getLoader() == loader && key.getModule() == module))
.forEach(set::remove);
cacheList.keySet().removeIf(
key -> {
Module m;
return (m = key.getModule()) != null &&
getLoader(m) == loader;
}
);
}
/**

View File

@ -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
@ -689,8 +689,7 @@ public interface Set<E> extends Collection<E> {
@SafeVarargs
@SuppressWarnings("varargs")
static <E> Set<E> of(E... elements) {
Objects.requireNonNull(elements);
switch (elements.length) {
switch (elements.length) { // implicit null check of elements
case 0:
return ImmutableCollections.Set0.instance();
case 1:

View File

@ -185,7 +185,14 @@ public class ForkJoinWorkerThread extends Thread {
static final class InnocuousForkJoinWorkerThread extends ForkJoinWorkerThread {
/** The ThreadGroup for all InnocuousForkJoinWorkerThreads */
private static final ThreadGroup innocuousThreadGroup =
ThreadLocalRandom.createThreadGroup("InnocuousForkJoinWorkerThreadGroup");
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<>() {
public ThreadGroup run() {
ThreadGroup group = Thread.currentThread().getThreadGroup();
for (ThreadGroup p; (p = group.getParent()) != null; )
group = p;
return new ThreadGroup(group, "InnocuousForkJoinWorkerThreadGroup");
}});
/** An AccessControlContext supporting no privileges */
private static final AccessControlContext INNOCUOUS_ACC =
@ -215,6 +222,5 @@ public class ForkJoinWorkerThread extends Thread {
public void setContextClassLoader(ClassLoader cl) {
throw new SecurityException("setContextClassLoader");
}
}
}

View File

@ -985,34 +985,6 @@ public class ThreadLocalRandom extends Random {
U.putObjectRelease(thread, INHERITEDACCESSCONTROLCONTEXT, acc);
}
/**
* Returns a new group with the system ThreadGroup (the
* topmost, parent-less group) as parent. Uses Unsafe to
* traverse Thread.group and ThreadGroup.parent fields.
*/
static final ThreadGroup createThreadGroup(String name) {
if (name == null)
throw new NullPointerException();
try {
long tg = U.objectFieldOffset
(Thread.class.getDeclaredField("group"));
long gp = U.objectFieldOffset
(ThreadGroup.class.getDeclaredField("parent"));
ThreadGroup group = (ThreadGroup)
U.getObject(Thread.currentThread(), tg);
while (group != null) {
ThreadGroup parent = (ThreadGroup)U.getObject(group, gp);
if (parent == null)
return new ThreadGroup(group, name);
group = parent;
}
} catch (ReflectiveOperationException e) {
throw new Error(e);
}
// fall through if null as cannot-happen safeguard
throw new Error("Cannot create ThreadGroup");
}
// Serialization support
private static final long serialVersionUID = -5851777807851030925L;
@ -1087,17 +1059,17 @@ public class ThreadLocalRandom extends Random {
static {
try {
SEED = U.objectFieldOffset
(Thread.class.getDeclaredField("threadLocalRandomSeed"));
(Thread.class.getDeclaredField("threadLocalRandomSeed"));
PROBE = U.objectFieldOffset
(Thread.class.getDeclaredField("threadLocalRandomProbe"));
(Thread.class.getDeclaredField("threadLocalRandomProbe"));
SECONDARY = U.objectFieldOffset
(Thread.class.getDeclaredField("threadLocalRandomSecondarySeed"));
(Thread.class.getDeclaredField("threadLocalRandomSecondarySeed"));
THREADLOCALS = U.objectFieldOffset
(Thread.class.getDeclaredField("threadLocals"));
(Thread.class.getDeclaredField("threadLocals"));
INHERITABLETHREADLOCALS = U.objectFieldOffset
(Thread.class.getDeclaredField("inheritableThreadLocals"));
(Thread.class.getDeclaredField("inheritableThreadLocals"));
INHERITEDACCESSCONTROLCONTEXT = U.objectFieldOffset
(Thread.class.getDeclaredField("inheritedAccessControlContext"));
(Thread.class.getDeclaredField("inheritedAccessControlContext"));
} catch (ReflectiveOperationException e) {
throw new Error(e);
}
@ -1123,7 +1095,7 @@ public class ThreadLocalRandom extends Random {
// at end of <clinit> to survive static initialization circularity
static {
if (java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Boolean>() {
new java.security.PrivilegedAction<>() {
public Boolean run() {
return Boolean.getBoolean("java.util.secureRandomSeed");
}})) {

View File

@ -40,6 +40,7 @@ import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Objects;
import java.util.function.IntBinaryOperator;
import java.util.function.IntUnaryOperator;
import jdk.internal.misc.Unsafe;
@ -411,7 +412,17 @@ public abstract class AtomicIntegerFieldUpdater<T> {
if (!Modifier.isVolatile(modifiers))
throw new IllegalArgumentException("Must be volatile type");
this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass;
// Access to protected field members is restricted to receivers only
// of the accessing class, or one of its subclasses, and the
// accessing class must in turn be a subclass (or package sibling)
// of the protected member's defining class.
// If the updater refers to a protected field of a declaring class
// outside the current package, the receiver argument will be
// narrowed to the type of the accessing class.
this.cclass = (Modifier.isProtected(modifiers) &&
tclass.isAssignableFrom(caller) &&
!isSamePackage(tclass, caller))
? caller : tclass;
this.tclass = tclass;
this.offset = U.objectFieldOffset(field);
}
@ -432,6 +443,15 @@ public abstract class AtomicIntegerFieldUpdater<T> {
return false;
}
/**
* Returns true if the two classes have the same class loader and
* package qualifier
*/
private static boolean isSamePackage(Class<?> class1, Class<?> class2) {
return class1.getClassLoader() == class2.getClassLoader()
&& Objects.equals(class1.getPackageName(), class2.getPackageName());
}
/**
* Checks that target argument is instance of cclass. On
* failure, throws cause.

View File

@ -40,6 +40,7 @@ import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Objects;
import java.util.function.LongBinaryOperator;
import java.util.function.LongUnaryOperator;
import jdk.internal.misc.Unsafe;
@ -409,7 +410,17 @@ public abstract class AtomicLongFieldUpdater<T> {
if (!Modifier.isVolatile(modifiers))
throw new IllegalArgumentException("Must be volatile type");
this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass;
// Access to protected field members is restricted to receivers only
// of the accessing class, or one of its subclasses, and the
// accessing class must in turn be a subclass (or package sibling)
// of the protected member's defining class.
// If the updater refers to a protected field of a declaring class
// outside the current package, the receiver argument will be
// narrowed to the type of the accessing class.
this.cclass = (Modifier.isProtected(modifiers) &&
tclass.isAssignableFrom(caller) &&
!isSamePackage(tclass, caller))
? caller : tclass;
this.tclass = tclass;
this.offset = U.objectFieldOffset(field);
}
@ -540,7 +551,17 @@ public abstract class AtomicLongFieldUpdater<T> {
if (!Modifier.isVolatile(modifiers))
throw new IllegalArgumentException("Must be volatile type");
this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass;
// Access to protected field members is restricted to receivers only
// of the accessing class, or one of its subclasses, and the
// accessing class must in turn be a subclass (or package sibling)
// of the protected member's defining class.
// If the updater refers to a protected field of a declaring class
// outside the current package, the receiver argument will be
// narrowed to the type of the accessing class.
this.cclass = (Modifier.isProtected(modifiers) &&
tclass.isAssignableFrom(caller) &&
!isSamePackage(tclass, caller))
? caller : tclass;
this.tclass = tclass;
this.offset = U.objectFieldOffset(field);
}
@ -621,4 +642,13 @@ public abstract class AtomicLongFieldUpdater<T> {
} while (acl != null);
return false;
}
/**
* Returns true if the two classes have the same class loader and
* package qualifier
*/
static boolean isSamePackage(Class<?> class1, Class<?> class2) {
return class1.getClassLoader() == class2.getClassLoader()
&& Objects.equals(class1.getPackageName(), class2.getPackageName());
}
}

View File

@ -40,6 +40,7 @@ import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Objects;
import java.util.function.BinaryOperator;
import java.util.function.UnaryOperator;
import jdk.internal.misc.Unsafe;
@ -351,7 +352,17 @@ public abstract class AtomicReferenceFieldUpdater<T,V> {
if (!Modifier.isVolatile(modifiers))
throw new IllegalArgumentException("Must be volatile type");
this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass;
// Access to protected field members is restricted to receivers only
// of the accessing class, or one of its subclasses, and the
// accessing class must in turn be a subclass (or package sibling)
// of the protected member's defining class.
// If the updater refers to a protected field of a declaring class
// outside the current package, the receiver argument will be
// narrowed to the type of the accessing class.
this.cclass = (Modifier.isProtected(modifiers) &&
tclass.isAssignableFrom(caller) &&
!isSamePackage(tclass, caller))
? caller : tclass;
this.tclass = tclass;
this.vclass = vclass;
this.offset = U.objectFieldOffset(field);
@ -373,6 +384,15 @@ public abstract class AtomicReferenceFieldUpdater<T,V> {
return false;
}
/**
* Returns true if the two classes have the same class loader and
* package qualifier
*/
private static boolean isSamePackage(Class<?> class1, Class<?> class2) {
return class1.getClassLoader() == class2.getClassLoader()
&& Objects.equals(class1.getPackageName(), class2.getPackageName());
}
/**
* Checks that target argument is instance of cclass. On
* failure, throws cause.

View File

@ -41,7 +41,6 @@ import java.util.Arrays;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.DoubleBinaryOperator;
import java.util.function.LongBinaryOperator;
import jdk.internal.misc.Unsafe;
/**
* A package-local class holding common representation and mechanics
@ -191,7 +190,7 @@ abstract class Striped64 extends Number {
* Duplicated from ThreadLocalRandom because of packaging restrictions.
*/
static final int getProbe() {
return U.getInt(Thread.currentThread(), PROBE);
return (int) THREAD_PROBE.get(Thread.currentThread());
}
/**
@ -203,7 +202,7 @@ abstract class Striped64 extends Number {
probe ^= probe << 13; // xorshift
probe ^= probe >>> 17;
probe ^= probe << 5;
U.putInt(Thread.currentThread(), PROBE, probe);
THREAD_PROBE.set(Thread.currentThread(), probe);
return probe;
}
@ -373,18 +372,28 @@ abstract class Striped64 extends Number {
}
}
// Unsafe and VarHandle mechanics
private static final Unsafe U = Unsafe.getUnsafe();
// VarHandle mechanics
private static final VarHandle BASE;
private static final VarHandle CELLSBUSY;
private static final long PROBE;
private static final VarHandle THREAD_PROBE;
static {
try {
MethodHandles.Lookup l = MethodHandles.lookup();
BASE = l.findVarHandle(Striped64.class, "base", long.class);
CELLSBUSY = l.findVarHandle(Striped64.class, "cellsBusy", int.class);
PROBE = U.objectFieldOffset
(Thread.class.getDeclaredField("threadLocalRandomProbe"));
BASE = l.findVarHandle(Striped64.class,
"base", long.class);
CELLSBUSY = l.findVarHandle(Striped64.class,
"cellsBusy", int.class);
l = java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<>() {
public MethodHandles.Lookup run() {
try {
return MethodHandles.privateLookupIn(Thread.class, MethodHandles.lookup());
} catch (ReflectiveOperationException e) {
throw new Error(e);
}
}});
THREAD_PROBE = l.findVarHandle(Thread.class,
"threadLocalRandomProbe", int.class);
} catch (ReflectiveOperationException e) {
throw new Error(e);
}

View File

@ -425,11 +425,11 @@ public class LockSupport {
static {
try {
PARKBLOCKER = U.objectFieldOffset
(Thread.class.getDeclaredField("parkBlocker"));
(Thread.class.getDeclaredField("parkBlocker"));
SECONDARY = U.objectFieldOffset
(Thread.class.getDeclaredField("threadLocalRandomSecondarySeed"));
(Thread.class.getDeclaredField("threadLocalRandomSecondarySeed"));
TID = U.objectFieldOffset
(Thread.class.getDeclaredField("tid"));
(Thread.class.getDeclaredField("tid"));
} catch (ReflectiveOperationException e) {
throw new Error(e);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -120,6 +120,9 @@ public class HandshakeCompletedEvent extends EventObject
* Note: This method can be used only when using certificate-based
* cipher suites; using it with non-certificate-based cipher suites,
* such as Kerberos, will throw an SSLPeerUnverifiedException.
* <P>
* Note: The returned value may not be a valid certificate chain
* and should not be relied on for trust decisions.
*
* @return an ordered array of the peer certificates,
* with the peer's own certificate first followed by
@ -140,6 +143,9 @@ public class HandshakeCompletedEvent extends EventObject
* Note: This method can be used only when using certificate-based
* cipher suites; using it with non-certificate-based cipher suites,
* such as Kerberos, will throw an SSLPeerUnverifiedException.
* <P>
* Note: The returned value may not be a valid certificate chain
* and should not be relied on for trust decisions.
*
* <p><em>Note: this method exists for compatibility with previous
* releases. New applications should use

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 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
@ -104,6 +104,9 @@ class HttpsURLConnection extends HttpURLConnection
* Note: This method can be used only when using certificate-based
* cipher suites; using it with non-certificate-based cipher suites,
* such as Kerberos, will throw an SSLPeerUnverifiedException.
* <P>
* Note: The returned value may not be a valid certificate chain
* and should not be relied on for trust decisions.
*
* @return an ordered array of server certificates,
* with the peer's own certificate first followed by

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -219,6 +219,9 @@ public interface SSLSession {
* Note: This method can be used only when using certificate-based
* cipher suites; using it with non-certificate-based cipher suites,
* such as Kerberos, will throw an SSLPeerUnverifiedException.
* <P>
* Note: The returned value may not be a valid certificate chain
* and should not be relied on for trust decisions.
*
* @return an ordered array of peer certificates,
* with the peer's own certificate first followed by any
@ -259,6 +262,9 @@ public interface SSLSession {
* Note: This method can be used only when using certificate-based
* cipher suites; using it with non-certificate-based cipher suites,
* such as Kerberos, will throw an SSLPeerUnverifiedException.
* <P>
* Note: The returned value may not be a valid certificate chain
* and should not be relied on for trust decisions.
*
* <p><em>Note: this method exists for compatibility with previous
* releases. New applications should use

View File

@ -38,6 +38,7 @@ import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
import java.security.AccessControlContext;
import java.security.AccessControlException;
import java.security.AccessController;
import java.security.CodeSigner;
@ -83,6 +84,7 @@ public class URLClassPath {
private static final String JAVA_VERSION;
private static final boolean DEBUG;
private static final boolean DISABLE_JAR_CHECKING;
private static final boolean DISABLE_ACC_CHECKING;
static {
Properties props = GetPropertyAction.privilegedGetProperties();
@ -90,6 +92,9 @@ public class URLClassPath {
DEBUG = (props.getProperty("sun.misc.URLClassPath.debug") != null);
String p = props.getProperty("sun.misc.URLClassPath.disableJarChecking");
DISABLE_JAR_CHECKING = p != null ? p.equals("true") || p.equals("") : false;
p = props.getProperty("jdk.net.URLClassPath.disableRestrictedPermissions");
DISABLE_ACC_CHECKING = p != null ? p.equals("true") || p.equals("") : false;
}
/* The original search path of URLs. */
@ -110,6 +115,11 @@ public class URLClassPath {
/* Whether this URLClassLoader has been closed yet */
private boolean closed = false;
/* The context to be used when loading classes and resources. If non-null
* this is the context that was captured during the creation of the
* URLClassLoader. null implies no additional security restrictions. */
private final AccessControlContext acc;
/**
* Creates a new URLClassPath for the given URLs. The URLs will be
* searched in the order specified for classes and resources. A URL
@ -119,8 +129,12 @@ public class URLClassPath {
* @param urls the directory and JAR file URLs to search for classes
* and resources
* @param factory the URLStreamHandlerFactory to use when creating new URLs
* @param acc the context to be used when loading classes and resources, may
* be null
*/
public URLClassPath(URL[] urls, URLStreamHandlerFactory factory) {
public URLClassPath(URL[] urls,
URLStreamHandlerFactory factory,
AccessControlContext acc) {
for (int i = 0; i < urls.length; i++) {
path.add(urls[i]);
}
@ -128,10 +142,22 @@ public class URLClassPath {
if (factory != null) {
jarHandler = factory.createURLStreamHandler("jar");
}
if (DISABLE_ACC_CHECKING)
this.acc = null;
else
this.acc = acc;
}
/**
* Constructs a URLClassPath with no additional security restrictions.
* Used by code that implements the class path.
*/
public URLClassPath(URL[] urls) {
this(urls, null);
this(urls, null, null);
}
public URLClassPath(URL[] urls, AccessControlContext acc) {
this(urls, null, acc);
}
public synchronized List<IOException> closeLoaders() {
@ -356,6 +382,14 @@ public class URLClassPath {
} catch (IOException e) {
// Silently ignore for now...
continue;
} catch (SecurityException se) {
// Always silently ignore. The context, if there is one, that
// this URLClassPath was given during construction will never
// have permission to access the URL.
if (DEBUG) {
System.err.println("Failed to access " + url + ", " + se );
}
continue;
}
// Finally, add the Loader to the search path.
loaders.add(loader);
@ -378,7 +412,7 @@ public class URLClassPath {
&& file != null && (file.indexOf("!/") == file.length() - 2)) {
// extract the nested URL
URL nestedUrl = new URL(file.substring(0, file.length() - 2));
return new JarLoader(nestedUrl, jarHandler, lmap);
return new JarLoader(nestedUrl, jarHandler, lmap, acc);
} else if (file != null && file.endsWith("/")) {
if ("file".equals(protocol)) {
return new FileLoader(url);
@ -386,10 +420,10 @@ public class URLClassPath {
return new Loader(url);
}
} else {
return new JarLoader(url, jarHandler, lmap);
return new JarLoader(url, jarHandler, lmap, acc);
}
}
});
}, acc);
} catch (java.security.PrivilegedActionException pae) {
throw (IOException)pae.getException();
}
@ -585,10 +619,11 @@ public class URLClassPath {
*/
static class JarLoader extends Loader {
private JarFile jar;
private URL csu;
private final URL csu;
private JarIndex index;
private URLStreamHandler handler;
private HashMap<String, Loader> lmap;
private final HashMap<String, Loader> lmap;
private final AccessControlContext acc;
private boolean closed = false;
private static final JavaUtilZipFileAccess zipAccess =
SharedSecrets.getJavaUtilZipFileAccess();
@ -598,13 +633,15 @@ public class URLClassPath {
* a JAR file.
*/
JarLoader(URL url, URLStreamHandler jarHandler,
HashMap<String, Loader> loaderMap)
HashMap<String, Loader> loaderMap,
AccessControlContext acc)
throws IOException
{
super(new URL("jar", "", -1, url + "!/", jarHandler));
csu = url;
handler = jarHandler;
lmap = loaderMap;
this.acc = acc;
ensureOpen();
}
@ -663,8 +700,7 @@ public class URLClassPath {
}
return null;
}
}
);
}, acc);
} catch (java.security.PrivilegedActionException pae) {
throw (IOException)pae.getException();
}
@ -859,9 +895,9 @@ public class URLClassPath {
new PrivilegedExceptionAction<>() {
public JarLoader run() throws IOException {
return new JarLoader(url, handler,
lmap);
lmap, acc);
}
});
}, acc);
/* this newly opened jar file has its own index,
* merge it into the parent's index, taking into

View File

@ -0,0 +1,312 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.internal.module;
import java.io.PrintStream;
import java.lang.module.Configuration;
import java.lang.module.ResolvedModule;
import java.net.URI;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayDeque;
import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;
import static java.util.stream.Collectors.*;
/**
* A Builder to compute ModuleHashes from a given configuration
*/
public class ModuleHashesBuilder {
private final Configuration configuration;
private final Set<String> hashModuleCandidates;
/**
* Constructs a ModuleHashesBuilder that finds the packaged modules
* from the location of ModuleReference found from the given Configuration.
*
* @param config Configuration for building module hashes
* @param modules the candidate modules to be hashed
*/
public ModuleHashesBuilder(Configuration config, Set<String> modules) {
this.configuration = config;
this.hashModuleCandidates = modules;
}
/**
* Returns a map of a module M to ModuleHashes for the modules
* that depend upon M directly or indirectly.
*
* The key for each entry in the returned map is a module M that has
* no outgoing edges to any of the candidate modules to be hashed
* i.e. M is a leaf node in a connected subgraph containing M and
* other candidate modules from the module graph filtering
* the outgoing edges from M to non-candidate modules.
*/
public Map<String, ModuleHashes> computeHashes(Set<String> roots) {
// build a graph containing the the packaged modules and
// its transitive dependences matching --hash-modules
Graph.Builder<String> builder = new Graph.Builder<>();
Deque<ResolvedModule> deque = new ArrayDeque<>(configuration.modules());
Set<ResolvedModule> visited = new HashSet<>();
while (!deque.isEmpty()) {
ResolvedModule rm = deque.pop();
if (!visited.contains(rm)) {
visited.add(rm);
builder.addNode(rm.name());
for (ResolvedModule dm : rm.reads()) {
if (!visited.contains(dm)) {
deque.push(dm);
}
builder.addEdge(rm.name(), dm.name());
}
}
}
// each node in a transposed graph is a matching packaged module
// in which the hash of the modules that depend upon it is recorded
Graph<String> transposedGraph = builder.build().transpose();
// traverse the modules in topological order that will identify
// the modules to record the hashes - it is the first matching
// module and has not been hashed during the traversal.
Set<String> mods = new HashSet<>();
Map<String, ModuleHashes> hashes = new HashMap<>();
builder.build()
.orderedNodes()
.filter(mn -> roots.contains(mn) && !mods.contains(mn))
.forEach(mn -> {
// Compute hashes of the modules that depend on mn directly and
// indirectly excluding itself.
Set<String> ns = transposedGraph.dfs(mn)
.stream()
.filter(n -> !n.equals(mn) && hashModuleCandidates.contains(n))
.collect(toSet());
mods.add(mn);
mods.addAll(ns);
if (!ns.isEmpty()) {
Map<String, Path> moduleToPath = ns.stream()
.collect(toMap(Function.identity(), this::moduleToPath));
hashes.put(mn, ModuleHashes.generate(moduleToPath, "SHA-256"));
}
});
return hashes;
}
private Path moduleToPath(String name) {
ResolvedModule rm = configuration.findModule(name).orElseThrow(
() -> new InternalError("Selected module " + name + " not on module path"));
URI uri = rm.reference().location().get();
Path path = Paths.get(uri);
String fn = path.getFileName().toString();
if (!fn.endsWith(".jar") && !fn.endsWith(".jmod")) {
throw new UnsupportedOperationException(path + " is not a modular JAR or jmod file");
}
return path;
}
/*
* Utilty class
*/
static class Graph<T> {
private final Set<T> nodes;
private final Map<T, Set<T>> edges;
public Graph(Set<T> nodes, Map<T, Set<T>> edges) {
this.nodes = Collections.unmodifiableSet(nodes);
this.edges = Collections.unmodifiableMap(edges);
}
public Set<T> nodes() {
return nodes;
}
public Map<T, Set<T>> edges() {
return edges;
}
public Set<T> adjacentNodes(T u) {
return edges.get(u);
}
public boolean contains(T u) {
return nodes.contains(u);
}
/**
* Returns nodes sorted in topological order.
*/
public Stream<T> orderedNodes() {
TopoSorter<T> sorter = new TopoSorter<>(this);
return sorter.result.stream();
}
/**
* Traverse this graph and performs the given action in topological order
*/
public void ordered(Consumer<T> action) {
TopoSorter<T> sorter = new TopoSorter<>(this);
sorter.ordered(action);
}
/**
* Traverses this graph and performs the given action in reverse topological order
*/
public void reverse(Consumer<T> action) {
TopoSorter<T> sorter = new TopoSorter<>(this);
sorter.reverse(action);
}
/**
* Returns a transposed graph from this graph
*/
public Graph<T> transpose() {
Builder<T> builder = new Builder<>();
nodes.stream().forEach(builder::addNode);
// reverse edges
edges.keySet().forEach(u -> {
edges.get(u).stream()
.forEach(v -> builder.addEdge(v, u));
});
return builder.build();
}
/**
* Returns all nodes reachable from the given root.
*/
public Set<T> dfs(T root) {
return dfs(Set.of(root));
}
/**
* Returns all nodes reachable from the given set of roots.
*/
public Set<T> dfs(Set<T> roots) {
Deque<T> deque = new LinkedList<>(roots);
Set<T> visited = new HashSet<>();
while (!deque.isEmpty()) {
T u = deque.pop();
if (!visited.contains(u)) {
visited.add(u);
if (contains(u)) {
adjacentNodes(u).stream()
.filter(v -> !visited.contains(v))
.forEach(deque::push);
}
}
}
return visited;
}
public void printGraph(PrintStream out) {
out.println("graph for " + nodes);
nodes.stream()
.forEach(u -> adjacentNodes(u).stream()
.forEach(v -> out.format(" %s -> %s%n", u, v)));
}
static class Builder<T> {
final Set<T> nodes = new HashSet<>();
final Map<T, Set<T>> edges = new HashMap<>();
public void addNode(T node) {
if (nodes.contains(node)) {
return;
}
nodes.add(node);
edges.computeIfAbsent(node, _e -> new HashSet<>());
}
public void addEdge(T u, T v) {
addNode(u);
addNode(v);
edges.get(u).add(v);
}
public Graph<T> build() {
return new Graph<T>(nodes, edges);
}
}
}
/**
* Topological sort
*/
private static class TopoSorter<T> {
final Deque<T> result = new LinkedList<>();
final Deque<T> nodes;
final Graph<T> graph;
TopoSorter(Graph<T> graph) {
this.graph = graph;
this.nodes = new LinkedList<>(graph.nodes);
sort();
}
public void ordered(Consumer<T> action) {
result.iterator().forEachRemaining(action);
}
public void reverse(Consumer<T> action) {
result.descendingIterator().forEachRemaining(action);
}
private void sort() {
Deque<T> visited = new LinkedList<>();
Deque<T> done = new LinkedList<>();
T node;
while ((node = nodes.poll()) != null) {
if (!visited.contains(node)) {
visit(node, visited, done);
}
}
}
private void visit(T node, Deque<T> visited, Deque<T> done) {
if (visited.contains(node)) {
if (!done.contains(node)) {
throw new IllegalArgumentException("Cyclic detected: " +
node + " " + graph.edges().get(node));
}
return;
}
visited.add(node);
graph.edges().get(node).stream()
.forEach(x -> visit(x, visited, done));
done.add(node);
result.addLast(node);
}
}
}

View File

@ -29,6 +29,7 @@ import java.io.*;
import java.util.*;
import java.util.jar.*;
import java.util.zip.*;
import static sun.security.action.GetPropertyAction.privilegedGetProperty;
/**
* This class is used to maintain mappings from packages, classes
@ -72,7 +73,7 @@ public class JarIndex {
* be added to the index. Otherwise, just the directory names are added.
*/
private static final boolean metaInfFilenames =
"true".equals(System.getProperty("sun.misc.JarIndex.metaInfFilenames"));
"true".equals(privilegedGetProperty("sun.misc.JarIndex.metaInfFilenames"));
/**
* Constructs a new, empty jar index.

View File

@ -249,7 +249,6 @@ module java.base {
jdk.crypto.token;
exports sun.security.jca to
java.smartcardio,
java.xml.crypto,
jdk.crypto.ec,
jdk.crypto.token,
jdk.naming.dns;
@ -279,6 +278,7 @@ module java.base {
java.security.jgss,
java.security.sasl,
java.smartcardio,
java.xml.crypto,
jdk.crypto.ec,
jdk.crypto.token,
jdk.jartool,
@ -290,6 +290,8 @@ module java.base {
jdk.crypto.token,
jdk.jartool,
jdk.security.auth;
exports sun.security.validator to
jdk.jartool;
exports sun.text.resources to
jdk.localedata;
exports sun.util.cldr to
@ -308,7 +310,6 @@ module java.base {
// JDK-internal service types
uses jdk.internal.logger.DefaultLoggerFinder;
uses sun.security.ssl.ClientKeyExchangeService;
uses sun.security.util.AuthResourcesProvider;
uses sun.text.spi.JavaTimeDateTimePatternProvider;
uses sun.util.spi.CalendarProvider;
uses sun.util.locale.provider.LocaleDataMetaInfo;
@ -320,6 +321,4 @@ module java.base {
provides java.nio.file.spi.FileSystemProvider with
jdk.internal.jrtfs.JrtFileSystemProvider;
provides sun.security.util.AuthResourcesProvider with
sun.security.util.AuthResourcesProviderImpl;
}

View File

@ -96,7 +96,7 @@ public final class ReflectUtil {
final Class<?> declaringClass = m.getDeclaringClass();
checkPackageAccess(declaringClass);
privateCheckPackageAccess(sm, declaringClass);
if (Modifier.isPublic(m.getModifiers()) &&
Modifier.isPublic(declaringClass.getModifiers()))
@ -114,9 +114,27 @@ public final class ReflectUtil {
* also check the package access on the proxy interfaces.
*/
public static void checkPackageAccess(Class<?> clazz) {
checkPackageAccess(clazz.getName());
SecurityManager s = System.getSecurityManager();
if (s != null) {
privateCheckPackageAccess(s, clazz);
}
}
/**
* NOTE: should only be called if a SecurityManager is installed
*/
private static void privateCheckPackageAccess(SecurityManager s, Class<?> clazz) {
while (clazz.isArray()) {
clazz = clazz.getComponentType();
}
String pkg = clazz.getPackageName();
if (pkg != null && !pkg.isEmpty()) {
s.checkPackageAccess(pkg);
}
if (isNonPublicProxyClass(clazz)) {
checkProxyPackageAccess(clazz);
privateCheckProxyPackageAccess(s, clazz);
}
}
@ -195,15 +213,21 @@ public final class ReflectUtil {
public static void checkProxyPackageAccess(Class<?> clazz) {
SecurityManager s = System.getSecurityManager();
if (s != null) {
// check proxy interfaces if the given class is a proxy class
if (Proxy.isProxyClass(clazz)) {
for (Class<?> intf : clazz.getInterfaces()) {
checkPackageAccess(intf);
}
}
privateCheckProxyPackageAccess(s, clazz);
}
}
/**
* NOTE: should only be called if a SecurityManager is installed
*/
private static void privateCheckProxyPackageAccess(SecurityManager s, Class<?> clazz) {
// check proxy interfaces if the given class is a proxy class
if (Proxy.isProxyClass(clazz)) {
for (Class<?> intf : clazz.getInterfaces()) {
privateCheckPackageAccess(s, intf);
}
}
}
/**
* Access check on the interfaces that a proxy class implements and throw
* {@code SecurityException} if it accesses a restricted package from
@ -220,7 +244,7 @@ public final class ReflectUtil {
for (Class<?> intf : interfaces) {
ClassLoader cl = intf.getClassLoader();
if (needsPackageAccessCheck(ccl, cl)) {
checkPackageAccess(intf);
privateCheckPackageAccess(sm, intf);
}
}
}
@ -236,10 +260,11 @@ public final class ReflectUtil {
* package that bypasses checkPackageAccess.
*/
public static boolean isNonPublicProxyClass(Class<?> cls) {
String name = cls.getName();
int i = name.lastIndexOf('.');
String pkg = (i != -1) ? name.substring(0, i) : "";
return Proxy.isProxyClass(cls) && !pkg.startsWith(PROXY_PACKAGE);
if (!Proxy.isProxyClass(cls)) {
return false;
}
String pkg = cls.getPackageName();
return pkg == null || !pkg.startsWith(PROXY_PACKAGE);
}
/**
@ -255,7 +280,7 @@ public final class ReflectUtil {
// check if it is a valid proxy instance
if (proxy == null || !Proxy.isProxyClass(proxy.getClass())) {
throw new IllegalArgumentException("Not a Proxy instance");
}
}
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalArgumentException("Can't handle static method");
}

View File

@ -331,9 +331,8 @@ public final class ConfigFile extends Configuration {
if (debugConfig != null) {
debugConfig.println(fnfe.toString());
}
throw new IOException(ResourcesMgr.getString
("Configuration.Error.No.such.file.or.directory",
"sun.security.util.AuthResources"));
throw new IOException(ResourcesMgr.getAuthResourceString
("Configuration.Error.No.such.file.or.directory"));
}
}
@ -661,8 +660,8 @@ public final class ConfigFile extends Configuration {
}
private IOException ioException(String resourceKey, Object... args) {
MessageFormat form = new MessageFormat(ResourcesMgr.getString
(resourceKey, "sun.security.util.AuthResources"));
MessageFormat form = new MessageFormat(
ResourcesMgr.getAuthResourceString(resourceKey));
return new IOException(form.format(args));
}
}

View File

@ -322,19 +322,20 @@ abstract class DSA extends SignatureSpi {
} else {
// first decode the signature.
try {
DerInputStream in = new DerInputStream(signature, offset,
length);
// Enforce strict DER checking for signatures
DerInputStream in =
new DerInputStream(signature, offset, length, false);
DerValue[] values = in.getSequence(2);
// check number of components in the read sequence
// and trailing data
if ((values.length != 2) || (in.available() != 0)) {
throw new IOException("Invalid encoding for signature");
}
r = values[0].getBigInteger();
s = values[1].getBigInteger();
// Check for trailing signature data
if (in.available() != 0) {
throw new IOException("Incorrect signature length");
}
} catch (IOException e) {
throw new SignatureException("invalid encoding for signature");
throw new SignatureException("Invalid encoding for signature", e);
}
}
@ -427,13 +428,49 @@ abstract class DSA extends SignatureSpi {
return t5.mod(q);
}
// NOTE: This following impl is defined in FIPS 186-4 AppendixB.2.1.
protected BigInteger generateK(BigInteger q) {
// Implementation defined in FIPS 186-4 AppendixB.2.1.
SecureRandom random = getSigningRandom();
byte[] kValue = new byte[(q.bitLength() + 7)/8 + 8];
random.nextBytes(kValue);
return new BigInteger(1, kValue).mod(q.subtract(BigInteger.ONE)).add(BigInteger.ONE);
BigInteger k = new BigInteger(1, kValue).mod(
q.subtract(BigInteger.ONE)).add(BigInteger.ONE);
// Using an equivalent exponent of fixed length (same as q or 1 bit
// less than q) to keep the kG timing relatively constant.
//
// Note that this is an extra step on top of the approach defined in
// FIPS 186-4 AppendixB.2.1 so as to make a fixed length K.
k = k.add(q).divide(BigInteger.TWO);
// An alternative implementation based on FIPS 186-4 AppendixB2.2
// with fixed-length K.
//
// Please keep it here as we may need to switch to it in the future.
//
// SecureRandom random = getSigningRandom();
// byte[] kValue = new byte[(q.bitLength() + 7)/8];
// BigInteger d = q.subtract(BigInteger.TWO);
// BigInteger k;
// do {
// random.nextBytes(kValue);
// BigInteger c = new BigInteger(1, kValue);
// if (c.compareTo(d) <= 0) {
// k = c.add(BigInteger.ONE);
// // Using an equivalent exponent of fixed length to keep
// // the g^k timing relatively constant.
// //
// // Note that this is an extra step on top of the approach
// // defined in FIPS 186-4 AppendixB.2.2 so as to make a
// // fixed length K.
// if (k.bitLength() >= q.bitLength()) {
// break;
// }
// }
// } while (true);
return k;
}
// Use the application-specified SecureRandom Object if provided.

View File

@ -34,6 +34,7 @@ import java.lang.reflect.Constructor;
import javax.security.auth.Subject;
import sun.security.provider.PolicyParser.PrincipalEntry;
import sun.security.util.ResourcesMgr;
/**
* <p> This <code>SubjectCodeSource</code> class contains
@ -47,15 +48,6 @@ class SubjectCodeSource extends CodeSource implements java.io.Serializable {
private static final long serialVersionUID = 6039418085604715275L;
private static final java.util.ResourceBundle rb =
java.security.AccessController.doPrivileged
(new java.security.PrivilegedAction<java.util.ResourceBundle>() {
public java.util.ResourceBundle run() {
return (java.util.ResourceBundle.getBundle
("sun.security.util.AuthResources"));
}
});
private Subject subject;
private LinkedList<PrincipalEntry> principals;
private static final Class<?>[] PARAMS = { String.class };
@ -391,7 +383,7 @@ class SubjectCodeSource extends CodeSource implements java.io.Serializable {
ListIterator<PrincipalEntry> li = principals.listIterator();
while (li.hasNext()) {
PrincipalEntry pppe = li.next();
returnMe = returnMe + rb.getString("NEWLINE") +
returnMe = returnMe + ResourcesMgr.getAuthResourceString("NEWLINE") +
pppe.getPrincipalClass() + " " +
pppe.getPrincipalName();
}

View File

@ -226,9 +226,10 @@ public abstract class RSASignature extends SignatureSpi {
* Decode the signature data. Verify that the object identifier matches
* and return the message digest.
*/
public static byte[] decodeSignature(ObjectIdentifier oid, byte[] signature)
public static byte[] decodeSignature(ObjectIdentifier oid, byte[] sig)
throws IOException {
DerInputStream in = new DerInputStream(signature);
// Enforce strict DER checking for signatures
DerInputStream in = new DerInputStream(sig, 0, sig.length, false);
DerValue[] values = in.getSequence(2);
if ((values.length != 2) || (in.available() != 0)) {
throw new IOException("SEQUENCE length error");

View File

@ -673,8 +673,11 @@ final class ClientHandshaker extends Handshaker {
} else {
// we wanted to resume, but the server refused
//
// Invalidate the session in case of reusing next time.
session.invalidate();
// Invalidate the session for initial handshake in case
// of reusing next time.
if (isInitialHandshake) {
session.invalidate();
}
session = null;
if (!enableNewSession) {
throw new SSLException("New session creation is disabled");

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2004, 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
@ -818,6 +818,11 @@ final class X509KeyManagerImpl extends X509ExtendedKeyManager
checker.init(false);
} catch (CertPathValidatorException cpve) {
// unlikely to happen
if (useDebug) {
debug.println(
"Cannot initialize algorithm constraints checker: " + cpve);
}
return false;
}
@ -828,6 +833,11 @@ final class X509KeyManagerImpl extends X509ExtendedKeyManager
// We don't care about the unresolved critical extensions.
checker.check(cert, Collections.<String>emptySet());
} catch (CertPathValidatorException cpve) {
if (useDebug) {
debug.println("Certificate (" + cert +
") does not conform to algorithm constraints: " + cpve);
}
return false;
}
}

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