OpenJDK / amber / amber
changeset 43150:1c9922f121ff
Merge
author | duke |
---|---|
date | Wed, 05 Jul 2017 22:42:01 +0200 |
parents | 047a57b0839a dca22f522449 |
children | d7034ff7f8e2 |
files | jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogInvalidPathTest.java jdk/test/java/rmi/registry/readTest/readTest.java jdk/test/java/rmi/registry/readTest/readTest.sh jdk/test/java/rmi/testlibrary/REGISTRY.java jdk/test/lib/security/SecurityTools.java jdk/test/tools/jar/mmrjar/ConcealedPackage.java jdk/test/tools/jmod/hashes/src/m1/module-info.java jdk/test/tools/jmod/hashes/src/m1/org/m1/Main.java jdk/test/tools/jmod/hashes/src/m2/module-info.java jdk/test/tools/jmod/hashes/src/m2/org/m2/Util.java jdk/test/tools/jmod/hashes/src/m3/module-info.java jdk/test/tools/jmod/hashes/src/m3/org/m3/Name.java jdk/test/tools/jmod/hashes/src/org.bar/module-info.java jdk/test/tools/jmod/hashes/src/org.foo/module-info.java |
diffstat | 249 files changed, 10882 insertions(+), 5561 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags-top-repo Tue Jan 17 07:41:04 2017 +0100 +++ b/.hgtags-top-repo Wed Jul 05 22:42:01 2017 +0200 @@ -394,3 +394,4 @@ b119012d1c2ab2570fe8718633840d0c1f1f441d jdk-9+149 6234069ff9789f7582e1faa32cb6283cbd1a5a2d jdk-9+150 71a766d4c18041a7f833ee22823125b02e1a7f1e jdk-9+151 +ef056360ddf3977d7d2ddbeb456a4d612d19ea05 jdk-9+152
--- a/common/autoconf/basics.m4 Tue Jan 17 07:41:04 2017 +0100 +++ b/common/autoconf/basics.m4 Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ # 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_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.
--- a/common/autoconf/buildjdk-spec.gmk.in Tue Jan 17 07:41:04 2017 +0100 +++ b/common/autoconf/buildjdk-spec.gmk.in Wed Jul 05 22:42:01 2017 +0200 @@ -68,7 +68,6 @@ 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@
--- a/common/autoconf/flags.m4 Tue Jan 17 07:41:04 2017 +0100 +++ b/common/autoconf/flags.m4 Wed Jul 05 22:42:01 2017 +0200 @@ -815,11 +815,6 @@ $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}"
--- a/common/autoconf/generated-configure.sh Tue Jan 17 07:41:04 2017 +0100 +++ b/common/autoconf/generated-configure.sh Wed Jul 05 22:42:01 2017 +0200 @@ -3564,7 +3564,7 @@ # 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 @@ + + # 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 @@ # -# 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 @@ 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 @@ # -# 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 @@ # -# 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 @@ #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 @@ # 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 @@ # 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 @@ + # 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 @@ fi + { $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}: 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: 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 "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 @@ apt_help $MISSING_DEPENDENCY ;; yum) yum_help $MISSING_DEPENDENCY ;; + brew) + brew_help $MISSING_DEPENDENCY ;; port) port_help $MISSING_DEPENDENCY ;; pkgutil) @@ -33235,6 +33275,8 @@ apt_help $MISSING_DEPENDENCY ;; yum) yum_help $MISSING_DEPENDENCY ;; + brew) + brew_help $MISSING_DEPENDENCY ;; port) port_help $MISSING_DEPENDENCY ;; pkgutil) @@ -34534,6 +34576,8 @@ apt_help $MISSING_DEPENDENCY ;; yum) yum_help $MISSING_DEPENDENCY ;; + brew) + brew_help $MISSING_DEPENDENCY ;; port) port_help $MISSING_DEPENDENCY ;; pkgutil) @@ -48601,6 +48645,8 @@ apt_help $MISSING_DEPENDENCY ;; yum) yum_help $MISSING_DEPENDENCY ;; + brew) + brew_help $MISSING_DEPENDENCY ;; port) port_help $MISSING_DEPENDENCY ;; pkgutil) @@ -48762,6 +48808,8 @@ apt_help $MISSING_DEPENDENCY ;; yum) yum_help $MISSING_DEPENDENCY ;; + brew) + brew_help $MISSING_DEPENDENCY ;; port) port_help $MISSING_DEPENDENCY ;; pkgutil) @@ -49897,11 +49945,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 @@ 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 @@ apt_help $MISSING_DEPENDENCY ;; yum) yum_help $MISSING_DEPENDENCY ;; + brew) + brew_help $MISSING_DEPENDENCY ;; port) port_help $MISSING_DEPENDENCY ;; pkgutil) @@ -56649,6 +56689,8 @@ apt_help $MISSING_DEPENDENCY ;; yum) yum_help $MISSING_DEPENDENCY ;; + brew) + brew_help $MISSING_DEPENDENCY ;; port) port_help $MISSING_DEPENDENCY ;; pkgutil) @@ -56721,6 +56763,8 @@ apt_help $MISSING_DEPENDENCY ;; yum) yum_help $MISSING_DEPENDENCY ;; + brew) + brew_help $MISSING_DEPENDENCY ;; port) port_help $MISSING_DEPENDENCY ;; pkgutil) @@ -56864,6 +56908,8 @@ apt_help $MISSING_DEPENDENCY ;; yum) yum_help $MISSING_DEPENDENCY ;; + brew) + brew_help $MISSING_DEPENDENCY ;; port) port_help $MISSING_DEPENDENCY ;; pkgutil) @@ -60741,11 +60787,8 @@ fi fi - - if test "x$OPENJDK_TARGET_OS" = xmacosx; then - if test "x$FOUND_FREETYPE" != xyes; then - # Due to changes in OSX 10.11 XQuartz now installs to /opt/X11 - FREETYPE_BASE_DIR="$SYSROOT/opt/X11" + 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" @@ -61082,15 +61125,15 @@ $as_echo "$FREETYPE_LIB_PATH" >&6; } fi - fi - fi - - if test "x$FOUND_FREETYPE" != xyes; then - FREETYPE_BASE_DIR="$SYSROOT/usr" - if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then + fi + + if test "x$OPENJDK_TARGET_OS" = xmacosx; then + if test "x$FOUND_FREETYPE" != xyes; then + # Due to changes in OSX 10.11 XQuartz now installs to /opt/X11 + FREETYPE_BASE_DIR="$SYSROOT/opt/X11" POTENTIAL_FREETYPE_INCLUDE_PATH="$FREETYPE_BASE_DIR/include" - POTENTIAL_FREETYPE_LIB_PATH="$FREETYPE_BASE_DIR/lib/x86_64-linux-gnu" + POTENTIAL_FREETYPE_LIB_PATH="$FREETYPE_BASE_DIR/lib" METHOD="well-known location" # Let's start with an optimistic view of the world :-) @@ -61424,10 +61467,15 @@ $as_echo "$FREETYPE_LIB_PATH" >&6; } fi - else + fi + fi + + if test "x$FOUND_FREETYPE" != xyes; then + FREETYPE_BASE_DIR="$SYSROOT/usr" + if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then POTENTIAL_FREETYPE_INCLUDE_PATH="$FREETYPE_BASE_DIR/include" - POTENTIAL_FREETYPE_LIB_PATH="$FREETYPE_BASE_DIR/lib/i386-linux-gnu" + POTENTIAL_FREETYPE_LIB_PATH="$FREETYPE_BASE_DIR/lib/x86_64-linux-gnu" METHOD="well-known location" # Let's start with an optimistic view of the world :-) @@ -61761,10 +61809,10 @@ $as_echo "$FREETYPE_LIB_PATH" >&6; } fi - if test "x$FOUND_FREETYPE" != xyes; then + else POTENTIAL_FREETYPE_INCLUDE_PATH="$FREETYPE_BASE_DIR/include" - POTENTIAL_FREETYPE_LIB_PATH="$FREETYPE_BASE_DIR/lib32" + POTENTIAL_FREETYPE_LIB_PATH="$FREETYPE_BASE_DIR/lib/i386-linux-gnu" METHOD="well-known location" # Let's start with an optimistic view of the world :-) @@ -62098,6 +62146,343 @@ $as_echo "$FREETYPE_LIB_PATH" >&6; } fi + if test "x$FOUND_FREETYPE" != xyes; then + + POTENTIAL_FREETYPE_INCLUDE_PATH="$FREETYPE_BASE_DIR/include" + POTENTIAL_FREETYPE_LIB_PATH="$FREETYPE_BASE_DIR/lib32" + 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"` + 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 fi fi @@ -62122,6 +62507,8 @@ apt_help $MISSING_DEPENDENCY ;; yum) yum_help $MISSING_DEPENDENCY ;; + brew) + brew_help $MISSING_DEPENDENCY ;; port) port_help $MISSING_DEPENDENCY ;; pkgutil) @@ -62477,6 +62864,8 @@ apt_help $MISSING_DEPENDENCY ;; yum) yum_help $MISSING_DEPENDENCY ;; + brew) + brew_help $MISSING_DEPENDENCY ;; port) port_help $MISSING_DEPENDENCY ;; pkgutil) @@ -62682,6 +63071,8 @@ apt_help $MISSING_DEPENDENCY ;; yum) yum_help $MISSING_DEPENDENCY ;; + brew) + brew_help $MISSING_DEPENDENCY ;; port) port_help $MISSING_DEPENDENCY ;; pkgutil) @@ -62870,6 +63261,8 @@ apt_help $MISSING_DEPENDENCY ;; yum) yum_help $MISSING_DEPENDENCY ;; + brew) + brew_help $MISSING_DEPENDENCY ;; port) port_help $MISSING_DEPENDENCY ;; pkgutil) @@ -62949,6 +63342,8 @@ apt_help $MISSING_DEPENDENCY ;; yum) yum_help $MISSING_DEPENDENCY ;; + brew) + brew_help $MISSING_DEPENDENCY ;; port) port_help $MISSING_DEPENDENCY ;; pkgutil) @@ -64058,6 +64453,8 @@ apt_help $MISSING_DEPENDENCY ;; yum) yum_help $MISSING_DEPENDENCY ;; + brew) + brew_help $MISSING_DEPENDENCY ;; port) port_help $MISSING_DEPENDENCY ;; pkgutil) @@ -64142,6 +64539,8 @@ apt_help $MISSING_DEPENDENCY ;; yum) yum_help $MISSING_DEPENDENCY ;; + brew) + brew_help $MISSING_DEPENDENCY ;; port) port_help $MISSING_DEPENDENCY ;; pkgutil)
--- a/common/autoconf/help.m4 Tue Jan 17 07:41:04 2017 +0100 +++ b/common/autoconf/help.m4 Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ apt_help $MISSING_DEPENDENCY ;; yum) yum_help $MISSING_DEPENDENCY ;; + brew) + brew_help $MISSING_DEPENDENCY ;; port) port_help $MISSING_DEPENDENCY ;; pkgutil) @@ -147,6 +149,17 @@ 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="" }
--- a/common/autoconf/jdk-options.m4 Tue Jan 17 07:41:04 2017 +0100 +++ b/common/autoconf/jdk-options.m4 Wed Jul 05 22:42:01 2017 +0200 @@ -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_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
--- a/common/autoconf/lib-freetype.m4 Tue Jan 17 07:41:04 2017 +0100 +++ b/common/autoconf/lib-freetype.m4 Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ 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
--- a/common/autoconf/spec.gmk.in Tue Jan 17 07:41:04 2017 +0100 +++ b/common/autoconf/spec.gmk.in Wed Jul 05 22:42:01 2017 +0200 @@ -274,8 +274,6 @@ 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 @@ NICE:=@NICE@ PATCH:=@PATCH@ PRINTF:=@PRINTF@ -PWD:=@THEPWDCMD@ RM:=@RM@ RMDIR:=@RMDIR@ SED:=@SED@ @@ -778,11 +775,18 @@ # 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 @@ 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)
--- a/common/conf/jib-profiles.js Tue Jan 17 07:41:04 2017 +0100 +++ b/common/conf/jib-profiles.js Wed Jul 05 22:42:01 2017 +0200 @@ -501,7 +501,7 @@ // 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 @@ ], 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 @@ local: "bundles/\\(jdk.*bin.tar.gz\\)", remote: "bundles/openjdk/GPL/profile/linux-x86/\\1", }, + jdk_symbols: { + local: "bundles/\\(jdk.*bin-symbols.tar.gz\\)", + remote: "bundles/openjdk/GPL/profile/linux-x86/\\1", + }, jre: { - local: "bundles/\\(jre.*[0-9]_linux-x86_bin.tar.gz\\)", + // 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", - },/* The build does not create these + }, jre_compact1: { local: "bundles/\\(jre.*-compact1_linux-x86_bin.tar.gz\\)", remote: "bundles/openjdk/GPL/profile/linux-x86/\\1", @@ -725,7 +731,7 @@ jre_compact3: { local: "bundles/\\(jre.*-compact3_linux-x86_bin.tar.gz\\)", remote: "bundles/openjdk/GPL/profile/linux-x86/\\1", - },*/ + }, } }, @@ -864,7 +870,7 @@ 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",
--- a/corba/.hgtags Tue Jan 17 07:41:04 2017 +0100 +++ b/corba/.hgtags Wed Jul 05 22:42:01 2017 +0200 @@ -394,3 +394,4 @@ 00b19338e505690abe93d5995ed74a473d969c2c jdk-9+149 9205e980062a5c4530b51021c6e274025f4ccbdf jdk-9+150 77f827f5bbad3ef795664bc675f72d98d156b9f8 jdk-9+151 +ff8cb43c07c069b1debdee44cb88ca22db1ec757 jdk-9+152
--- a/hotspot/.hgtags Tue Jan 17 07:41:04 2017 +0100 +++ b/hotspot/.hgtags Wed Jul 05 22:42:01 2017 +0200 @@ -554,3 +554,4 @@ 30e1996bd55da36183434f24ed964adebf9ca71e jdk-9+149 98fe046473c90204cbc9b34c512b9fc10dfb8479 jdk-9+150 2a2ac7d9f52c8cb2b80077e515b5840b947e640c jdk-9+151 +31f1d26c60df7b2e516a4f84160d76ba017d4e09 jdk-9+152
--- a/jaxp/.hgtags Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxp/.hgtags Wed Jul 05 22:42:01 2017 +0200 @@ -394,3 +394,4 @@ 5978df8bfa3894f2b3d07b7256f25f78dffb1f9c jdk-9+149 f85154af719f99a3b4d81b67a8b4c18a650d10f9 jdk-9+150 13c6906bfc861d99dc35a19c80b7a99f0b0ac58d jdk-9+151 +7e3da313b1746578da648155e37dd8526e83153d jdk-9+152
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/DOM2SAX.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/DOM2SAX.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ 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 @@ { _sax = handler; if (handler instanceof LexicalHandler) { - _lex = (LexicalHandler) handler; + _lex = (LexicalHandler)handler; } if (handler instanceof SAXImpl) { @@ -90,25 +86,22 @@ 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 @@ 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 @@ } } - /** - * 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 @@ * 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 @@ _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 @@ } _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 @@ 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 @@ // 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 @@ // 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 @@ // 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 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; - } }
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/ref/sax2dtm/SAX2DTM.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/ref/sax2dtm/SAX2DTM.java Wed Jul 05 22:42:01 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -17,14 +17,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* - * $Id: SAX2DTM.java,v 1.2.4.1 2005/09/15 08:15:11 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.DTMManager; +import com.sun.org.apache.xml.internal.dtm.DTMWSFilter; +import com.sun.org.apache.xml.internal.dtm.ref.DTMDefaultBaseIterators; +import com.sun.org.apache.xml.internal.dtm.ref.DTMManagerDefault; +import com.sun.org.apache.xml.internal.dtm.ref.DTMStringPool; +import com.sun.org.apache.xml.internal.dtm.ref.DTMTreeWalker; +import com.sun.org.apache.xml.internal.dtm.ref.IncrementalSAXSource; +import com.sun.org.apache.xml.internal.dtm.ref.NodeLocator; import com.sun.org.apache.xml.internal.res.XMLErrorResources; import com.sun.org.apache.xml.internal.res.XMLMessages; import com.sun.org.apache.xml.internal.utils.FastStringBuffer; @@ -36,13 +40,23 @@ import com.sun.org.apache.xml.internal.utils.WrappedRuntimeException; import com.sun.org.apache.xml.internal.utils.XMLString; import com.sun.org.apache.xml.internal.utils.XMLStringFactory; +import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Vector; import javax.xml.transform.Source; import javax.xml.transform.SourceLocator; -import org.xml.sax.*; -import org.xml.sax.ext.*; +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.DTDHandler; +import org.xml.sax.EntityResolver; +import org.xml.sax.ErrorHandler; +import org.xml.sax.InputSource; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import org.xml.sax.ext.DeclHandler; +import org.xml.sax.ext.LexicalHandler; /** * This class implements a DTM that tends to be optimized more for speed than @@ -82,7 +96,6 @@ * * Made protected rather than private so SAX2RTFDTM can access it. */ - //private FastStringBuffer m_chars = new FastStringBuffer(13, 13); protected FastStringBuffer m_chars; /** This vector holds offset and length data. @@ -102,8 +115,7 @@ /** Namespace support, only relevent at construction time. * Made protected rather than private so SAX2RTFDTM can access it. */ - transient protected java.util.Vector m_prefixMappings = - new java.util.Vector(); + transient protected Vector<String> m_prefixMappings = new Vector<>(); /** Namespace support, only relevent at construction time. * Made protected rather than private so SAX2RTFDTM can access it. @@ -164,7 +176,7 @@ * Vector of entities. Each record is composed of four Strings: * publicId, systemID, notationName, and name. */ - private Vector m_entities = null; + private ArrayList<String> m_entities = null; /** m_entities public ID offset. */ private static final int ENTITY_FIELD_PUBLICID = 0; @@ -196,13 +208,15 @@ */ protected boolean m_useSourceLocationProperty = false; - /** Made protected for access by SAX2RTFDTM. + /** Made protected for access by SAX2RTFDTM. */ protected StringVector m_sourceSystemId; - /** Made protected for access by SAX2RTFDTM. + + /** Made protected for access by SAX2RTFDTM. */ protected IntVector m_sourceLine; - /** Made protected for access by SAX2RTFDTM. + + /** Made protected for access by SAX2RTFDTM. */ protected IntVector m_sourceColumn; @@ -252,23 +266,19 @@ boolean usePrevsib, boolean newNameTable) { - super(mgr, source, dtmIdentity, whiteSpaceFilter, xstringfactory, doIndexing, blocksize, usePrevsib, newNameTable); // %OPT% Use smaller sizes for all internal storage units when // the blocksize is small. This reduces the cost of creating an RTF. - if (blocksize <= 64) - { + if (blocksize <= 64) { m_data = new SuballocatedIntVector(blocksize, DEFAULT_NUMBLOCKS_SMALL); m_dataOrQName = new SuballocatedIntVector(blocksize, DEFAULT_NUMBLOCKS_SMALL); m_valuesOrPrefixes = new DTMStringPool(16); m_chars = new FastStringBuffer(7, 10); m_contextIndexes = new IntStack(4); m_parents = new IntStack(4); - } - else - { + } else { m_data = new SuballocatedIntVector(blocksize, DEFAULT_NUMBLOCKS); m_dataOrQName = new SuballocatedIntVector(blocksize, DEFAULT_NUMBLOCKS); m_valuesOrPrefixes = new DTMStringPool(); @@ -289,7 +299,7 @@ // m_useSourceLocationProperty=com.sun.org.apache.xalan.internal.processor.TransformerFactoryImpl.m_source_location; m_useSourceLocationProperty = mgr.getSource_location(); m_sourceSystemId = (m_useSourceLocationProperty) ? new StringVector() : null; - m_sourceLine = (m_useSourceLocationProperty) ? new IntVector() : null; + m_sourceLine = (m_useSourceLocationProperty) ? new IntVector() : null; m_sourceColumn = (m_useSourceLocationProperty) ? new IntVector() : null; } @@ -297,8 +307,7 @@ * Set whether information about document source location * should be maintained or not. */ - public void setUseSourceLocation(boolean useSourceLocation) - { + public void setUseSourceLocation(boolean useSourceLocation) { m_useSourceLocationProperty = useSourceLocation; } @@ -309,17 +318,14 @@ * * @return The data or qualified name, or DTM.NULL. */ - protected int _dataOrQName(int identity) - { - + protected int _dataOrQName(int identity) { if (identity < m_size) return m_dataOrQName.elementAt(identity); // Check to see if the information requested has been processed, and, // if not, advance the iterator until we the information has been // processed. - while (true) - { + while (true) { boolean isMore = nextNode(); if (!isMore) @@ -332,8 +338,7 @@ /** * Ask the CoRoutine parser to doTerminate and clear the reference. */ - public void clearCoRoutine() - { + public void clearCoRoutine() { clearCoRoutine(true); } @@ -344,11 +349,8 @@ * @param callDoTerminate true of doTerminate should be called on the * coRoutine parser. */ - public void clearCoRoutine(boolean callDoTerminate) - { - - if (null != m_incrementalSAXSource) - { + public void clearCoRoutine(boolean callDoTerminate) { + if (null != m_incrementalSAXSource) { if (callDoTerminate) m_incrementalSAXSource.deliverMoreNodes(false); @@ -368,9 +370,7 @@ * @param incrementalSAXSource The parser that we want to recieve events from * on demand. */ - public void setIncrementalSAXSource(IncrementalSAXSource incrementalSAXSource) - { - + public void setIncrementalSAXSource(IncrementalSAXSource incrementalSAXSource) { // Establish coroutine link so we can request more data // // Note: It's possible that some versions of IncrementalSAXSource may @@ -406,11 +406,9 @@ * Note that IncrementalSAXSource_Filter is package private, hence * it can be statically referenced using instanceof (CR 6537912). */ - public ContentHandler getContentHandler() - { - - if (m_incrementalSAXSource.getClass() - .getName().equals("com.sun.org.apache.xml.internal.dtm.ref.IncrementalSAXSource_Filter")) + public ContentHandler getContentHandler() { + if (m_incrementalSAXSource.getClass().getName() + .equals("com.sun.org.apache.xml.internal.dtm.ref.IncrementalSAXSource_Filter")) return (ContentHandler) m_incrementalSAXSource; else return this; @@ -429,11 +427,9 @@ * Note that IncrementalSAXSource_Filter is package private, hence * it can be statically referenced using instanceof (CR 6537912). */ - public LexicalHandler getLexicalHandler() - { - - if (m_incrementalSAXSource.getClass() - .getName().equals("com.sun.org.apache.xml.internal.dtm.ref.IncrementalSAXSource_Filter")) + public LexicalHandler getLexicalHandler() { + if (m_incrementalSAXSource.getClass().getName() + .equals("com.sun.org.apache.xml.internal.dtm.ref.IncrementalSAXSource_Filter")) return (LexicalHandler) m_incrementalSAXSource; else return this; @@ -444,8 +440,7 @@ * * @return null if this model doesn't respond to SAX entity ref events. */ - public EntityResolver getEntityResolver() - { + public EntityResolver getEntityResolver() { return this; } @@ -454,8 +449,7 @@ * * @return null if this model doesn't respond to SAX dtd events. */ - public DTDHandler getDTDHandler() - { + public DTDHandler getDTDHandler() { return this; } @@ -464,8 +458,7 @@ * * @return null if this model doesn't respond to SAX error events. */ - public ErrorHandler getErrorHandler() - { + public ErrorHandler getErrorHandler() { return this; } @@ -474,8 +467,7 @@ * * @return null if this model doesn't respond to SAX Decl events. */ - public DeclHandler getDeclHandler() - { + public DeclHandler getDeclHandler() { return this; } @@ -485,8 +477,7 @@ * transformation and the parse run simultaneously. Guidance to the * DTMManager. */ - public boolean needsTwoThreads() - { + public boolean needsTwoThreads() { return null != m_incrementalSAXSource; } @@ -509,9 +500,8 @@ */ public void dispatchCharactersEvents(int nodeHandle, ContentHandler ch, boolean normalize) - throws SAXException + throws SAXException { - int identity = makeNodeIdentity(nodeHandle); if (identity == DTM.NULL) @@ -519,8 +509,7 @@ int type = _type(identity); - if (isTextType(type)) - { + if (isTextType(type)) { int dataIndex = m_dataOrQName.elementAt(identity); int offset = m_data.elementAt(dataIndex); int length = m_data.elementAt(dataIndex + 1); @@ -529,13 +518,10 @@ m_chars.sendNormalizedSAXcharacters(ch, offset, length); else m_chars.sendSAXcharacters(ch, offset, length); - } - else - { + } else { int firstChild = _firstch(identity); - if (DTM.NULL != firstChild) - { + if (DTM.NULL != firstChild) { int offset = -1; int length = 0; int startNode = identity; @@ -545,12 +531,10 @@ do { type = _type(identity); - if (isTextType(type)) - { + if (isTextType(type)) { int dataIndex = _dataOrQName(identity); - if (-1 == offset) - { + if (-1 == offset) { offset = m_data.elementAt(dataIndex); } @@ -560,36 +544,31 @@ identity = getNextNodeIdentity(identity); } while (DTM.NULL != identity && (_parent(identity) >= startNode)); - if (length > 0) - { + if (length > 0) { if(normalize) m_chars.sendNormalizedSAXcharacters(ch, offset, length); else m_chars.sendSAXcharacters(ch, offset, length); } - } - else if(type != DTM.ELEMENT_NODE) - { + } else if(type != DTM.ELEMENT_NODE) { int dataIndex = _dataOrQName(identity); - if (dataIndex < 0) - { + if (dataIndex < 0) { dataIndex = -dataIndex; dataIndex = m_data.elementAt(dataIndex + 1); } String str = m_valuesOrPrefixes.indexToString(dataIndex); - if(normalize) - FastStringBuffer.sendNormalizedSAXcharacters(str.toCharArray(), - 0, str.length(), ch); - else - ch.characters(str.toCharArray(), 0, str.length()); + if(normalize) + FastStringBuffer.sendNormalizedSAXcharacters(str.toCharArray(), + 0, str.length(), ch); + else + ch.characters(str.toCharArray(), 0, str.length()); } } } - /** * Given a node handle, return its DOM-style node name. This will * include names such as #text or #document. @@ -599,39 +578,29 @@ * %REVIEW% Document when empty string is possible... * %REVIEW-COMMENT% It should never be empty, should it? */ - public String getNodeName(int nodeHandle) - { - + public String getNodeName(int nodeHandle) { int expandedTypeID = getExpandedTypeID(nodeHandle); // If just testing nonzero, no need to shift... int namespaceID = m_expandedNameTable.getNamespaceID(expandedTypeID); - if (0 == namespaceID) - { + if (0 == namespaceID) { // Don't retrieve name until/unless needed // String name = m_expandedNameTable.getLocalName(expandedTypeID); int type = getNodeType(nodeHandle); - if (type == DTM.NAMESPACE_NODE) - { + if (type == DTM.NAMESPACE_NODE) { if (null == m_expandedNameTable.getLocalName(expandedTypeID)) return "xmlns"; else return "xmlns:" + m_expandedNameTable.getLocalName(expandedTypeID); - } - else if (0 == m_expandedNameTable.getLocalNameID(expandedTypeID)) - { + } else if (0 == m_expandedNameTable.getLocalNameID(expandedTypeID)) { return m_fixednames[type]; - } - else + } else return m_expandedNameTable.getLocalName(expandedTypeID); - } - else - { + } else { int qnameIndex = m_dataOrQName.elementAt(makeNodeIdentity(nodeHandle)); - if (qnameIndex < 0) - { + if (qnameIndex < 0) { qnameIndex = -qnameIndex; qnameIndex = m_data.elementAt(qnameIndex); } @@ -648,27 +617,21 @@ * @param nodeHandle the id of the node. * @return String Name of this node, which may be an empty string. */ - public String getNodeNameX(int nodeHandle) - { - + public String getNodeNameX(int nodeHandle) { int expandedTypeID = getExpandedTypeID(nodeHandle); int namespaceID = m_expandedNameTable.getNamespaceID(expandedTypeID); - if (0 == namespaceID) - { + if (namespaceID == 0) { String name = m_expandedNameTable.getLocalName(expandedTypeID); if (name == null) return ""; else return name; - } - else - { + } else { int qnameIndex = m_dataOrQName.elementAt(makeNodeIdentity(nodeHandle)); - if (qnameIndex < 0) - { + if (qnameIndex < 0) { qnameIndex = -qnameIndex; qnameIndex = m_data.elementAt(qnameIndex); } @@ -686,11 +649,9 @@ * @return <code>true</code> if the attribute was specified; * <code>false</code> if it was defaulted. */ - public boolean isAttributeSpecified(int attributeHandle) - { - + public boolean isAttributeSpecified(int attributeHandle) { // I'm not sure if I want to do anything with this... - return true; // ?? + return true; // ?? } /** @@ -701,9 +662,7 @@ * * @return the system identifier String object, or null if there is none. */ - public String getDocumentTypeDeclarationSystemIdentifier() - { - + public String getDocumentTypeDeclarationSystemIdentifier() { /** @todo: implement this com.sun.org.apache.xml.internal.dtm.DTMDefaultBase abstract method */ error(XMLMessages.createXMLMessage(XMLErrorResources.ER_METHOD_NOT_SUPPORTED, null));//"Not yet supported!"); @@ -717,14 +676,11 @@ * @param identity The node identity (index). * @return identity+1, or DTM.NULL. */ - protected int getNextNodeIdentity(int identity) - { - + protected int getNextNodeIdentity(int identity) { identity += 1; - while (identity >= m_size) - { - if (null == m_incrementalSAXSource) + while (identity >= m_size) { + if (m_incrementalSAXSource == null) return DTM.NULL; nextNode(); @@ -739,10 +695,10 @@ * @param nodeHandle The node ID. * @param ch A non-null reference to a ContentHandler. * - * @throws org.xml.sax.SAXException + * @throws SAXException */ - public void dispatchToEvents(int nodeHandle, org.xml.sax.ContentHandler ch) - throws org.xml.sax.SAXException + public void dispatchToEvents(int nodeHandle, ContentHandler ch) + throws SAXException { DTMTreeWalker treeWalker = m_walker; @@ -1087,28 +1043,22 @@ * @return String containing the URI of the Unparsed Entity, or an * empty string if no such entity exists. */ - public String getUnparsedEntityURI(String name) - { - + public String getUnparsedEntityURI(String name) { String url = ""; - if (null == m_entities) + if (null == m_entities) { return url; + } int n = m_entities.size(); - for (int i = 0; i < n; i += ENTITY_FIELDS_PER) - { - String ename = (String) m_entities.elementAt(i + ENTITY_FIELD_NAME); + for (int i = 0; i < n; i += ENTITY_FIELDS_PER) { + String ename = m_entities.get(i + ENTITY_FIELD_NAME); - if (null != ename && ename.equals(name)) - { - String nname = (String) m_entities.elementAt(i - + ENTITY_FIELD_NOTATIONNAME); + if (null != ename && ename.equals(name)) { + String nname = m_entities.get(i + ENTITY_FIELD_NOTATIONNAME); - if (null != nname) - { - + if (null != nname) { // The draft says: "The XSLT processor may use the public // identifier to generate a URI for the entity instead of the URI // specified in the system identifier. If the XSLT processor does @@ -1118,11 +1068,10 @@ // the resource containing the entity declaration as the base // URI [RFC2396]." // So I'm falling a bit short here. - url = (String) m_entities.elementAt(i + ENTITY_FIELD_SYSTEMID); + url = m_entities.get(i + ENTITY_FIELD_SYSTEMID); - if (null == url) - { - url = (String) m_entities.elementAt(i + ENTITY_FIELD_PUBLICID); + if (null == url) { + url = m_entities.get(i + ENTITY_FIELD_PUBLICID); } } @@ -1400,26 +1349,18 @@ * * @return The prefix if there is one, or null. */ - public String getPrefix(String qname, String uri) - { - + public String getPrefix(String qname, String uri) { String prefix; int uriIndex = -1; - if (null != uri && uri.length() > 0) - { + if (null != uri && uri.length() > 0) { + do { + uriIndex = m_prefixMappings.indexOf(uri, ++uriIndex); + } while ((uriIndex & 0x01) == 0); - do - { - uriIndex = m_prefixMappings.indexOf(uri, ++uriIndex); - } while ( (uriIndex & 0x01) == 0); - - if (uriIndex >= 0) - { - prefix = (String) m_prefixMappings.elementAt(uriIndex - 1); - } - else if (null != qname) - { + if (uriIndex >= 0) { + prefix = m_prefixMappings.elementAt(uriIndex - 1); + } else if (null != qname) { int indexOfNSSep = qname.indexOf(':'); if (qname.equals("xmlns")) @@ -1429,33 +1370,24 @@ else prefix = (indexOfNSSep > 0) ? qname.substring(0, indexOfNSSep) : null; - } - else - { + } else { prefix = null; } - } - else if (null != qname) - { + } else if (null != qname) { int indexOfNSSep = qname.indexOf(':'); - if (indexOfNSSep > 0) - { + if (indexOfNSSep > 0) { if (qname.startsWith("xmlns:")) prefix = qname.substring(indexOfNSSep + 1); else prefix = qname.substring(0, indexOfNSSep); - } - else - { + } else { if (qname.equals("xmlns")) prefix = ""; else prefix = null; } - } - else - { + } else { prefix = null; } @@ -1470,38 +1402,31 @@ * * @return The prefix if there is one, or null. */ - public int getIdForNamespace(String uri) - { - + public int getIdForNamespace(String uri) { return m_valuesOrPrefixes.stringToIndex(uri); - } - /** + /** * Get a prefix either from the qname or from the uri mapping, or just make * one up! * * @return The prefix if there is one, or null. */ - public String getNamespaceURI(String prefix) - { - + public String getNamespaceURI(String prefix) { String uri = ""; int prefixIndex = m_contextIndexes.peek() - 1 ; - if(null == prefix) + if (null == prefix) { prefix = ""; + } - do - { - prefixIndex = m_prefixMappings.indexOf(prefix, ++prefixIndex); - } while ( (prefixIndex >= 0) && (prefixIndex & 0x01) == 0x01); + do { + prefixIndex = m_prefixMappings.indexOf(prefix, ++prefixIndex); + } while ((prefixIndex >= 0) && (prefixIndex & 0x01) == 0x01); - if (prefixIndex > -1) - { - uri = (String) m_prefixMappings.elementAt(prefixIndex + 1); - } - + if (prefixIndex > -1) { + uri = m_prefixMappings.elementAt(prefixIndex + 1); + } return uri; } @@ -1578,7 +1503,7 @@ * default behaviour. * @throws SAXException Any SAX exception, possibly * wrapping another exception. - * @see org.xml.sax.EntityResolver#resolveEntity + * @see EntityResolver#resolveEntity * * @throws SAXException */ @@ -1605,7 +1530,7 @@ * @param systemId The notation system identifier. * @throws SAXException Any SAX exception, possibly * wrapping another exception. - * @see org.xml.sax.DTDHandler#notationDecl + * @see DTDHandler#notationDecl * * @throws SAXException */ @@ -1630,41 +1555,35 @@ * @param notationName The name of the associated notation. * @throws SAXException Any SAX exception, possibly * wrapping another exception. - * @see org.xml.sax.DTDHandler#unparsedEntityDecl + * @see DTDHandler#unparsedEntityDecl * * @throws SAXException */ - public void unparsedEntityDecl( - String name, String publicId, String systemId, String notationName) - throws SAXException + public void unparsedEntityDecl(String name, String publicId, String systemId, + String notationName) throws SAXException { - - if (null == m_entities) - { - m_entities = new Vector(); + if (null == m_entities) { + m_entities = new ArrayList<>(); } - try - { + try { systemId = SystemIDResolver.getAbsoluteURI(systemId, getDocumentBaseURI()); - } - catch (Exception e) - { - throw new org.xml.sax.SAXException(e); + } catch (Exception e) { + throw new SAXException(e); } // private static final int ENTITY_FIELD_PUBLICID = 0; - m_entities.addElement(publicId); + m_entities.add(publicId); // private static final int ENTITY_FIELD_SYSTEMID = 1; - m_entities.addElement(systemId); + m_entities.add(systemId); // private static final int ENTITY_FIELD_NOTATIONNAME = 2; - m_entities.addElement(notationName); + m_entities.add(notationName); // private static final int ENTITY_FIELD_NAME = 3; - m_entities.addElement(name); + m_entities.add(name); } //////////////////////////////////////////////////////////////////// @@ -1679,8 +1598,8 @@ * with other document events.</p> * * @param locator A locator for all SAX document events. - * @see org.xml.sax.ContentHandler#setDocumentLocator - * @see org.xml.sax.Locator + * @see ContentHandler#setDocumentLocator + * @see Locator */ public void setDocumentLocator(Locator locator) { @@ -1693,7 +1612,7 @@ * * @throws SAXException Any SAX exception, possibly * wrapping another exception. - * @see org.xml.sax.ContentHandler#startDocument + * @see ContentHandler#startDocument */ public void startDocument() throws SAXException { @@ -1716,7 +1635,7 @@ * * @throws SAXException Any SAX exception, possibly * wrapping another exception. - * @see org.xml.sax.ContentHandler#endDocument + * @see ContentHandler#endDocument */ public void endDocument() throws SAXException { @@ -1754,7 +1673,7 @@ * @param uri The Namespace URI mapped to the prefix. * @throws SAXException Any SAX exception, possibly * wrapping another exception. - * @see org.xml.sax.ContentHandler#startPrefixMapping + * @see ContentHandler#startPrefixMapping */ public void startPrefixMapping(String prefix, String uri) throws SAXException @@ -1780,7 +1699,7 @@ * @param prefix The Namespace prefix being declared. * @throws SAXException Any SAX exception, possibly * wrapping another exception. - * @see org.xml.sax.ContentHandler#endPrefixMapping + * @see ContentHandler#endPrefixMapping */ public void endPrefixMapping(String prefix) throws SAXException { @@ -1815,16 +1734,13 @@ * @return true if the declaration has already been declared in the * current context. */ - protected boolean declAlreadyDeclared(String prefix) - { - + protected boolean declAlreadyDeclared(String prefix) { int startDecls = m_contextIndexes.peek(); - java.util.Vector prefixMappings = m_prefixMappings; + Vector<String> prefixMappings = m_prefixMappings; int nDecls = prefixMappings.size(); - for (int i = startDecls; i < nDecls; i += 2) - { - String prefixDecl = (String) prefixMappings.elementAt(i); + for (int i = startDecls; i < nDecls; i += 2) { + String prefixDecl = prefixMappings.elementAt(i); if (prefixDecl == null) continue; @@ -1836,7 +1752,7 @@ return false; } - boolean m_pastFirstElement=false; + boolean m_pastFirstElement=false; /** * Receive notification of the start of an element. @@ -1857,35 +1773,38 @@ * @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 { - if (DEBUG) - { - System.out.println("startElement: uri: " + uri + ", localname: " - + localName + ", qname: "+qName+", atts: " + attributes); + if (DEBUG) { + System.out.println("startElement: uri: " + uri + + ", localname: " + localName + + ", qname: "+qName+", atts: " + attributes); - boolean DEBUG_ATTRS=true; - if(DEBUG_ATTRS & attributes!=null) - { - int n = attributes.getLength(); - if(n==0) - System.out.println("\tempty attribute list"); - else for (int i = 0; i < n; i++) - System.out.println("\t attr: uri: " + attributes.getURI(i) + - ", localname: " + attributes.getLocalName(i) + - ", qname: " + attributes.getQName(i) + - ", type: " + attributes.getType(i) + - ", value: " + attributes.getValue(i) - ); - } - } + boolean DEBUG_ATTRS=true; + if (DEBUG_ATTRS & attributes!=null) { + int n = attributes.getLength(); + if (n==0) { + System.out.println("\tempty attribute list"); + } else for (int i = 0; i < n; i++) { + System.out.println("\t attr: uri: " + attributes.getURI(i) + + ", localname: " + attributes.getLocalName(i) + + ", qname: " + attributes.getQName(i) + + ", type: " + attributes.getType(i) + + ", value: " + attributes.getValue(i)); + } + } + } charactersFlush(); + if ((localName == null || localName.isEmpty()) && + (uri == null || uri.isEmpty())) { + localName = qName; + } + int exName = m_expandedNameTable.getExpandedTypeID(uri, localName, DTM.ELEMENT_NODE); String prefix = getPrefix(qName, uri); int prefixIndex = (null != prefix) @@ -1894,20 +1813,18 @@ 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); int startDecls = m_contextIndexes.peek(); int nDecls = m_prefixMappings.size(); int prev = DTM.NULL; - 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); int val = m_valuesOrPrefixes.stringToIndex(declURL); @@ -1916,14 +1833,13 @@ 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); @@ -1935,8 +1851,7 @@ int n = attributes.getLength(); - for (int i = 0; i < n; i++) - { + for (int i = 0; i < n; i++) { String attrUri = attributes.getURI(i); String attrQName = attributes.getQName(i); String valString = attributes.getValue(i); @@ -1947,17 +1862,13 @@ String attrLocalName = attributes.getLocalName(i); - if ((null != attrQName) - && (attrQName.equals("xmlns") - || attrQName.startsWith("xmlns:"))) - { + if ((null != attrQName) && + (attrQName.equals("xmlns") || attrQName.startsWith("xmlns:"))) { if (declAlreadyDeclared(prefix)) continue; // go to the next attribute. nodeType = DTM.NAMESPACE_NODE; - } - else - { + } else { nodeType = DTM.ATTRIBUTE_NODE; if (attributes.getType(i).equalsIgnoreCase("ID")) @@ -1966,15 +1877,13 @@ // 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 = ""; int val = m_valuesOrPrefixes.stringToIndex(valString); //String attrLocalName = attributes.getLocalName(i); - if (null != prefix) - { - + if (null != prefix) { prefixIndex = m_valuesOrPrefixes.stringToIndex(attrQName); int dataIndex = m_data.size(); @@ -1993,8 +1902,7 @@ if (DTM.NULL != prev) m_nextsib.setElementAt(DTM.NULL,prev); - if (null != m_wsfilter) - { + if (null != m_wsfilter) { short wsv = m_wsfilter.getShouldStripSpace(makeNodeHandle(elemNode), this); boolean shouldStrip = (DTMWSFilter.INHERIT == wsv) ? getShouldStripWhitespace() @@ -2026,7 +1934,7 @@ * 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 @@ -2074,7 +1982,7 @@ * character array. * @throws SAXException Any SAX exception, possibly * wrapping another exception. - * @see org.xml.sax.ContentHandler#characters + * @see ContentHandler#characters */ public void characters(char ch[], int start, int length) throws SAXException { @@ -2109,7 +2017,7 @@ * character array. * @throws SAXException Any SAX exception, possibly * wrapping another exception. - * @see org.xml.sax.ContentHandler#ignorableWhitespace + * @see ContentHandler#ignorableWhitespace */ public void ignorableWhitespace(char ch[], int start, int length) throws SAXException @@ -2133,7 +2041,7 @@ * 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 @@ -2163,7 +2071,7 @@ * @param name The name of the skipped entity. * @throws SAXException Any SAX exception, possibly * wrapping another exception. - * @see org.xml.sax.ContentHandler#processingInstruction + * @see ContentHandler#processingInstruction */ public void skippedEntity(String name) throws SAXException { @@ -2187,8 +2095,8 @@ * @param e The warning information encoded as an exception. * @throws SAXException Any SAX exception, possibly * wrapping another exception. - * @see org.xml.sax.ErrorHandler#warning - * @see org.xml.sax.SAXParseException + * @see ErrorHandler#warning + * @see SAXParseException */ public void warning(SAXParseException e) throws SAXException { @@ -2208,8 +2116,8 @@ * @param e The warning information encoded as an exception. * @throws SAXException Any SAX exception, possibly * wrapping another exception. - * @see org.xml.sax.ErrorHandler#warning - * @see org.xml.sax.SAXParseException + * @see ErrorHandler#warning + * @see SAXParseException */ public void error(SAXParseException e) throws SAXException { @@ -2230,8 +2138,8 @@ * @param e The error information encoded as an exception. * @throws SAXException Any SAX exception, possibly * wrapping another exception. - * @see org.xml.sax.ErrorHandler#fatalError - * @see org.xml.sax.SAXParseException + * @see ErrorHandler#fatalError + * @see SAXParseException */ public void fatalError(SAXParseException e) throws SAXException { @@ -2299,7 +2207,7 @@ * @param value The replacement text of the entity. * @throws SAXException The application may raise an exception. * @see #externalEntityDecl - * @see org.xml.sax.DTDHandler#unparsedEntityDecl + * @see DTDHandler#unparsedEntityDecl */ public void internalEntityDecl(String name, String value) throws SAXException @@ -2321,7 +2229,7 @@ * @param systemId The declared system identifier of the entity. * @throws SAXException The application may raise an exception. * @see #internalEntityDecl - * @see org.xml.sax.DTDHandler#unparsedEntityDecl + * @see DTDHandler#unparsedEntityDecl */ public void externalEntityDecl( String name, String publicId, String systemId) throws SAXException @@ -2386,15 +2294,15 @@ * properly nested within start/end entity events.</p> * * <p>Note that skipped entities will be reported through the - * {@link org.xml.sax.ContentHandler#skippedEntity skippedEntity} + * {@link ContentHandler#skippedEntity skippedEntity} * event, which is part of the ContentHandler interface.</p> * * @param name The name of the entity. If it is a parameter * entity, the name will begin with '%'. * @throws SAXException The application may raise an exception. * @see #endEntity - * @see org.xml.sax.ext.DeclHandler#internalEntityDecl - * @see org.xml.sax.ext.DeclHandler#externalEntityDecl + * @see DeclHandler#internalEntityDecl + * @see DeclHandler#externalEntityDecl */ public void startEntity(String name) throws SAXException { @@ -2419,7 +2327,7 @@ * Report the start of a CDATA section. * * <p>The contents of the CDATA section will be reported through - * the regular {@link org.xml.sax.ContentHandler#characters + * the regular {@link ContentHandler#characters * characters} event.</p> * * @throws SAXException The application may raise an exception.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/ref/sax2dtm/SAX2DTM2.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/dtm/ref/sax2dtm/SAX2DTM2.java Wed Jul 05 22:42:01 2017 +0200 @@ -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.res.XMLMessages; import com.sun.org.apache.xml.internal.res.XMLErrorResources; import com.sun.org.apache.xml.internal.serializer.SerializationHandler; - +import com.sun.org.apache.xml.internal.utils.SuballocatedIntVector; +import java.util.ArrayList; import javax.xml.transform.Source; -import java.util.Vector; -import com.sun.org.apache.xml.internal.utils.SuballocatedIntVector; -import org.xml.sax.*; +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 @@ * 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 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 @@ * @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 @@ * * @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 @@ * * @param nodeType The extended type ID being requested. */ - public TypedChildrenIterator(int nodeType) - { + public TypedChildrenIterator(int nodeType) { _nodeType = nodeType; } @@ -242,17 +238,14 @@ * * @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 @@ * * @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 @@ _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 @@ node = _nextsib2(node); } return NULL; - } - else { + } else { while (node != DTM.NULL) { if (_exptype2(node) >= DTM.NTYPES) { pos++; @@ -415,13 +404,11 @@ * * @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 @@ * * @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 @@ * * @param type The extended type ID being requested. */ - public TypedFollowingSiblingIterator(int type) - { + public TypedFollowingSiblingIterator(int type) { _nodeType = type; } @@ -470,8 +455,7 @@ * * @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 @@ 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,9 +481,68 @@ /** * 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 + + /** + * Set start to END should 'close' the iterator, + * i.e. subsequent call to next() should return END. + * + * @param node Sets the root of the iteration. + * + * @return A DTMAxisIterator set to the start of the iteration. + */ + public DTMAxisIterator setStartNode(int node) { + //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily + if (node == DTMDefaultBase.ROOTNODE) + node = getDocument(); + if (_isRestartable) { + _startNode = node; + _currentNode = getFirstAttributeIdentity(makeNodeIdentity(node)); + + return resetPosition(); + } + + return this; + } + + /** + * Get the next node in the iteration. + * + * @return The next node handle in the iteration, or END. + */ + public int next() { + final int node = _currentNode; + + if (node != NULL) { + _currentNode = getNextAttributeIdentity(node); + return returnNode(makeNodeHandle(node)); + } + + return NULL; + } + } // end of AttributeIterator + + /** + * Iterator that returns attribute nodes of a given type + */ + public final class TypedAttributeIterator extends InternalAxisIteratorBase { + /** The extended type ID that was requested. */ + private final int _nodeType; + + /** + * Constructor TypedAttributeIterator + * + * + * @param nodeType The extended type ID that is requested. + */ + public TypedAttributeIterator(int nodeType) { + _nodeType = nodeType; + } + // assumes caller will pass element nodes /** @@ -511,356 +553,267 @@ * * @return A DTMAxisIterator set to the start of the iteration. */ + public DTMAxisIterator setStartNode(int node) { + if (_isRestartable) { + _startNode = node; + _currentNode = getTypedAttribute(node, _nodeType); + return resetPosition(); + } + + return this; + } + + /** + * Get the next node in the iteration. + * + * @return The next node handle in the iteration, or END. + */ + public int next() { + final int node = _currentNode; + + // singleton iterator, since there can only be one attribute of + // a given type. + _currentNode = NULL; + + return returnNode(node); + } + } // end of TypedAttributeIterator + + /** + * Iterator that returns preceding siblings of a given node + */ + public class PrecedingSiblingIterator extends InternalAxisIteratorBase + { + + /** + * The node identity of _startNode for this iterator + */ + protected int _startNodeID; + + /** + * True if this iterator has a reversed axis. + * + * @return true. + */ + public boolean isReverse() { + return true; + } + + /** + * Set start to END should 'close' the iterator, + * i.e. subsequent call to next() should return END. + * + * @param node Sets the root of the iteration. + * + * @return A DTMAxisIterator set to the start of the iteration. + */ + public DTMAxisIterator setStartNode(int node) { + //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily + if (node == DTMDefaultBase.ROOTNODE) + node = getDocument(); + if (_isRestartable) { + _startNode = node; + node = _startNodeID = makeNodeIdentity(node); + + if(node == NULL) { + _currentNode = node; + return resetPosition(); + } + + int type = _type2(node); + if (ExpandedNameTable.ATTRIBUTE == type || + ExpandedNameTable.NAMESPACE == type) + { + _currentNode = node; + } else { + // Be careful to handle the Document node properly + _currentNode = _parent2(node); + if(NULL!=_currentNode) + _currentNode = _firstch2(_currentNode); + else + _currentNode = node; + } + + return resetPosition(); + } + + return this; + } + + /** + * Get the next node in the iteration. + * + * @return The next node handle in the iteration, or END. + */ + public int next() { + if (_currentNode == _startNodeID || _currentNode == DTM.NULL) { + return NULL; + } else { + final int node = _currentNode; + _currentNode = _nextsib2(node); + return returnNode(makeNodeHandle(node)); + } + } + } // end of PrecedingSiblingIterator + + /** + * Iterator that returns preceding siblings of a given type for + * a given node + */ + public final class TypedPrecedingSiblingIterator + extends PrecedingSiblingIterator + { + + /** The extended type ID that was requested. */ + private final int _nodeType; + + /** + * Constructor TypedPrecedingSiblingIterator + * + * + * @param type The extended type ID being requested. + */ + public TypedPrecedingSiblingIterator(int type) { + _nodeType = type; + } + + /** + * Get the next node in the iteration. + * + * @return The next node handle in the iteration, or END. + */ + public int next() { + int node = _currentNode; + + final int nodeType = _nodeType; + final int startNodeID = _startNodeID; + + if (nodeType != DTM.ELEMENT_NODE) { + while (node != NULL && node != startNodeID && _exptype2(node) != nodeType) { + node = _nextsib2(node); + } + } else { + while (node != NULL && node != startNodeID && _exptype2(node) < DTM.NTYPES) { + node = _nextsib2(node); + } + } + + if (node == DTM.NULL || node == startNodeID) { + _currentNode = NULL; + return NULL; + } else { + _currentNode = _nextsib2(node); + return returnNode(makeNodeHandle(node)); + } + } + + /** + * Return the index of the last node in this iterator. + */ + public int getLast() { + if (_last != -1) + return _last; + + setMark(); + + int node = _currentNode; + final int nodeType = _nodeType; + final int startNodeID = _startNodeID; + + int last = 0; + if (nodeType != DTM.ELEMENT_NODE) { + while (node != NULL && node != startNodeID) { + if (_exptype2(node) == nodeType) { + last++; + } + node = _nextsib2(node); + } + } else { + while (node != NULL && node != startNodeID) { + if (_exptype2(node) >= DTM.NTYPES) { + last++; + } + node = _nextsib2(node); + } + } + + gotoMark(); + + return (_last = last); + } + } // end of TypedPrecedingSiblingIterator + + /** + * Iterator that returns preceding nodes of a given node. + * This includes the node set {root+1, start-1}, but excludes + * all ancestors, attributes, and namespace nodes. + */ + public class PrecedingIterator extends InternalAxisIteratorBase + { + + /** The max ancestors, but it can grow... */ + private final int _maxAncestors = 8; + + /** + * The stack of start node + ancestors up to the root of the tree, + * which we must avoid. + */ + protected int[] _stack = new int[_maxAncestors]; + + /** (not sure yet... -sb) */ + protected int _sp, _oldsp; + + protected int _markedsp, _markedNode, _markedDescendant; + + /* _currentNode precedes candidates. This is the identity, not the handle! */ + + /** + * True if this iterator has a reversed axis. + * + * @return true since this iterator is a reversed axis. + */ + public boolean isReverse() + { + return true; + } + + /** + * Returns a deep copy of this iterator. The cloned iterator is not reset. + * + * @return a deep copy of this iterator. + */ + public DTMAxisIterator cloneIterator() + { + _isRestartable = false; + + try + { + final PrecedingIterator clone = (PrecedingIterator) super.clone(); + final int[] stackCopy = new int[_stack.length]; + System.arraycopy(_stack, 0, stackCopy, 0, _stack.length); + + clone._stack = stackCopy; + + // return clone.reset(); + return clone; + } + catch (CloneNotSupportedException e) + { + throw new DTMException(XMLMessages.createXMLMessage(XMLErrorResources.ER_ITERATOR_CLONE_NOT_SUPPORTED, null)); //"Iterator clone not supported."); + } + } + + /** + * Set start to END should 'close' the iterator, + * i.e. subsequent call to next() should return END. + * + * @param node Sets the root of the iteration. + * + * @return A DTMAxisIterator set to the start of the iteration. + */ public DTMAxisIterator setStartNode(int node) { -//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily - if (node == DTMDefaultBase.ROOTNODE) - node = getDocument(); - if (_isRestartable) - { - _startNode = node; - _currentNode = getFirstAttributeIdentity(makeNodeIdentity(node)); - - return resetPosition(); - } - - return this; - } - - /** - * Get the next node in the iteration. - * - * @return The next node handle in the iteration, or END. - */ - public int next() - { - - final int node = _currentNode; - - if (node != NULL) { - _currentNode = getNextAttributeIdentity(node); - return returnNode(makeNodeHandle(node)); - } - - return NULL; - } - } // end of AttributeIterator - - /** - * Iterator that returns attribute nodes of a given type - */ - public final class TypedAttributeIterator extends InternalAxisIteratorBase - { - - /** The extended type ID that was requested. */ - private final int _nodeType; - - /** - * Constructor TypedAttributeIterator - * - * - * @param nodeType The extended type ID that is requested. - */ - public TypedAttributeIterator(int nodeType) - { - _nodeType = nodeType; - } - - // assumes caller will pass element nodes - - /** - * Set start to END should 'close' the iterator, - * i.e. subsequent call to next() should return END. - * - * @param node Sets the root of the iteration. - * - * @return A DTMAxisIterator set to the start of the iteration. - */ - public DTMAxisIterator setStartNode(int node) - { - if (_isRestartable) - { - _startNode = node; - - _currentNode = getTypedAttribute(node, _nodeType); - - return resetPosition(); - } - - return this; - } - - /** - * Get the next node in the iteration. - * - * @return The next node handle in the iteration, or END. - */ - public int next() - { - - final int node = _currentNode; - - // singleton iterator, since there can only be one attribute of - // a given type. - _currentNode = NULL; - - return returnNode(node); - } - } // end of TypedAttributeIterator - - /** - * Iterator that returns preceding siblings of a given node - */ - public class PrecedingSiblingIterator extends InternalAxisIteratorBase - { - - /** - * The node identity of _startNode for this iterator - */ - protected int _startNodeID; - - /** - * True if this iterator has a reversed axis. - * - * @return true. - */ - public boolean isReverse() - { - return true; - } - - /** - * Set start to END should 'close' the iterator, - * i.e. subsequent call to next() should return END. - * - * @param node Sets the root of the iteration. - * - * @return A DTMAxisIterator set to the start of the iteration. - */ - public DTMAxisIterator setStartNode(int node) - { -//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily - if (node == DTMDefaultBase.ROOTNODE) - node = getDocument(); - if (_isRestartable) - { - _startNode = node; - node = _startNodeID = makeNodeIdentity(node); - - if(node == NULL) - { - _currentNode = node; - return resetPosition(); - } - - int type = _type2(node); - if(ExpandedNameTable.ATTRIBUTE == type - || ExpandedNameTable.NAMESPACE == type ) - { - _currentNode = node; - } - else - { - // Be careful to handle the Document node properly - _currentNode = _parent2(node); - if(NULL!=_currentNode) - _currentNode = _firstch2(_currentNode); - else - _currentNode = node; - } - - return resetPosition(); - } - - return this; - } - - /** - * Get the next node in the iteration. - * - * @return The next node handle in the iteration, or END. - */ - public int next() - { - - if (_currentNode == _startNodeID || _currentNode == DTM.NULL) - { - return NULL; - } - else - { - final int node = _currentNode; - _currentNode = _nextsib2(node); - - return returnNode(makeNodeHandle(node)); - } - } - } // end of PrecedingSiblingIterator - - /** - * Iterator that returns preceding siblings of a given type for - * a given node - */ - public final class TypedPrecedingSiblingIterator - extends PrecedingSiblingIterator - { - - /** The extended type ID that was requested. */ - private final int _nodeType; - - /** - * Constructor TypedPrecedingSiblingIterator - * - * - * @param type The extended type ID being requested. - */ - public TypedPrecedingSiblingIterator(int type) - { - _nodeType = type; - } - - /** - * Get the next node in the iteration. - * - * @return The next node handle in the iteration, or END. - */ - public int next() - { - int node = _currentNode; - - final int nodeType = _nodeType; - final int startNodeID = _startNodeID; - - if (nodeType != DTM.ELEMENT_NODE) { - while (node != NULL && node != startNodeID && _exptype2(node) != nodeType) { - node = _nextsib2(node); - } - } - else { - while (node != NULL && node != startNodeID && _exptype2(node) < DTM.NTYPES) { - node = _nextsib2(node); - } - } - - if (node == DTM.NULL || node == startNodeID) { - _currentNode = NULL; - return NULL; - } - else { - _currentNode = _nextsib2(node); - return returnNode(makeNodeHandle(node)); - } - } - - /** - * Return the index of the last node in this iterator. - */ - public int getLast() - { - if (_last != -1) - return _last; - - setMark(); - - int node = _currentNode; - final int nodeType = _nodeType; - final int startNodeID = _startNodeID; - - int last = 0; - if (nodeType != DTM.ELEMENT_NODE) { - while (node != NULL && node != startNodeID) { - if (_exptype2(node) == nodeType) { - last++; - } - node = _nextsib2(node); - } - } - else { - while (node != NULL && node != startNodeID) { - if (_exptype2(node) >= DTM.NTYPES) { - last++; - } - node = _nextsib2(node); - } - } - - gotoMark(); - - return (_last = last); - } - } // end of TypedPrecedingSiblingIterator - - /** - * Iterator that returns preceding nodes of a given node. - * This includes the node set {root+1, start-1}, but excludes - * all ancestors, attributes, and namespace nodes. - */ - public class PrecedingIterator extends InternalAxisIteratorBase - { - - /** The max ancestors, but it can grow... */ - private final int _maxAncestors = 8; - - /** - * The stack of start node + ancestors up to the root of the tree, - * which we must avoid. - */ - protected int[] _stack = new int[_maxAncestors]; - - /** (not sure yet... -sb) */ - protected int _sp, _oldsp; - - protected int _markedsp, _markedNode, _markedDescendant; - - /* _currentNode precedes candidates. This is the identity, not the handle! */ - - /** - * True if this iterator has a reversed axis. - * - * @return true since this iterator is a reversed axis. - */ - public boolean isReverse() - { - return true; - } - - /** - * Returns a deep copy of this iterator. The cloned iterator is not reset. - * - * @return a deep copy of this iterator. - */ - public DTMAxisIterator cloneIterator() - { - _isRestartable = false; - - try - { - final PrecedingIterator clone = (PrecedingIterator) super.clone(); - final int[] stackCopy = new int[_stack.length]; - System.arraycopy(_stack, 0, stackCopy, 0, _stack.length); - - clone._stack = stackCopy; - - // return clone.reset(); - return clone; - } - catch (CloneNotSupportedException e) - { - throw new DTMException(XMLMessages.createXMLMessage(XMLErrorResources.ER_ITERATOR_CLONE_NOT_SUPPORTED, null)); //"Iterator clone not supported."); - } - } - - /** - * Set start to END should 'close' the iterator, - * i.e. subsequent call to next() should return END. - * - * @param node Sets the root of the iteration. - * - * @return A DTMAxisIterator set to the start of the iteration. - */ - 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 @@ // %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 @@ 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 @@ * @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 @@ * @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 @@ * @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 @@ * <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 @@ * 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 @@ * * @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 { + return index; } - else - return index; } /** @@ -2079,15 +2014,25 @@ * @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 @@ 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 @@ 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); - - exName = m_expandedNameTable.getExpandedTypeID(null, prefix, DTM.NAMESPACE_NODE); - - m_values.addElement(declURL); + String declURL = m_prefixMappings.elementAt(i + 1); + + 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); @@ -2136,28 +2081,37 @@ 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 @@ // 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 @@ * 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 @@ * @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 @@ // %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 @@ * * @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 @@ * * @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 @@ * @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 @@ // 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 @@ 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 @@ * 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 @@ // 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 @@ * 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 @@ -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 @@ } 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 @@ dataIndex = m_data.elementAt(dataIndex + 1); } - return (String)m_values.elementAt(dataIndex); + return m_values.get(dataIndex); } } @@ -3106,7 +3042,7 @@ 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 @@ dataIndex = m_data.elementAt(dataIndex + 1); } - return (String)m_values.elementAt(dataIndex); + return m_values.get(dataIndex); } } @@ -3202,8 +3138,7 @@ if (uri.length() == 0) { handler.startElement(name); return name; - } - else { + } else { int qnameIndex = m_dataOrQName.elementAt(nodeID); if (qnameIndex == 0) { @@ -3223,14 +3158,12 @@ String prefix; if (prefixIndex > 0) { prefix = qName.substring(0, prefixIndex); - } - else { + } else { prefix = null; } handler.namespaceAfterStartElement(prefix, uri); return qName; } - } /** @@ -3285,7 +3218,7 @@ 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 @@ } - /** * Copy an Attribute node to a SerializationHandler * @@ -3347,14 +3279,6 @@ 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 @@ } 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); }
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/AltCatalog.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/AltCatalog.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ } /** - * 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 @@ } /** - * Returns the catalog attribute as an URI. + * Returns the catalog attribute as a URI. * @return The value of the catalog attribute */ URI getCatalogURI() {
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/BaseEntry.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/BaseEntry.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ 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 @@ * @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 @@ 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; - } - } }
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/Catalog.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/Catalog.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ * <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 @@ * * @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 @@ * * @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 @@ * * @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);
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogFeatures.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogFeatures.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ * * <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 @@ * 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 @@ * 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 @@ * 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 @@ 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 @@ <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 @@ 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 @@ 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 @@ 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 @@ 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 @@ */ 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 @@ 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 @@ * 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; }
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogImpl.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogImpl.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ /* 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 @@ 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 @@ 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) { @@ -294,29 +295,6 @@ } /** - * 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 * @throws CatalogException if constructing a SAXParser failed @@ -394,7 +372,7 @@ //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 @@ //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 @@ } 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(); } }
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogManager.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogManager.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ /** * 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 @@ /** * 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); } }
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogMessages.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogMessages.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ 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 @@ * @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 @@ * @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 @@ /** * 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) {
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogMessages.properties Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogMessages.properties Wed Jul 05 22:42:01 2017 +0200 @@ -31,6 +31,8 @@ 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.
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogReader.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogReader.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ 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,
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogResolver.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogResolver.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ * {@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 @@ * 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 @@ * @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 *
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogResolverImpl.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogResolverImpl.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ 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 @@ 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 @@ } } - //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("#");
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/GroupEntry.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/GroupEntry.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ * @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 @@ * @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 @@ * * @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 @@ 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 @@ } //Ignore it if it doesn't exist - if (!Files.exists(Paths.get(catalogURI))) { + if (Util.isFileUri(catalogURI) && + !Util.isFileUriExist(catalogURI, false)) { return false; }
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/UriEntry.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/UriEntry.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ import java.net.URL; /** - * Represents an uriEntry entry. + * Represents a uri entry. * * @since 9 */ @@ -36,7 +36,7 @@ URL uri; /** - * Construct a group entry. + * Construct a uri entry. * @param name The name attribute. * @param uri The uri attribute. */
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/Util.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/Util.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ * @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 @@ 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 @@ 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 @@ 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); + static void validateUrisSyntax(URI... uris) { + for (URI uri : uris) { + validateUriSyntax(uri); + } + } - 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(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 @@ } /** - * 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 @@ } } } + + /** + * 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(";")); + } + } }
--- a/jaxp/test/javax/xml/jaxp/functional/catalog/SpecifyCatalogTest.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/SpecifyCatalogTest.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ @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 @@ } private static CatalogFeatures createFeature(String catalogName) { - return builder().with(FILES, getCatalogPath(catalogName)).build(); + return builder().with(FILES, getCatalogPath(catalogName).toASCIIString()).build(); } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/functional/catalog/catalogFiles/dummy.xml Wed Jul 05 22:42:01 2017 +0200 @@ -0,0 +1,1 @@ +<dummy />
--- a/jaxp/test/javax/xml/jaxp/libs/catalog/CatalogTestUtils.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxp/test/javax/xml/jaxp/libs/catalog/CatalogTestUtils.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ 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 @@ } // 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 ********** */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JarUtils.java Wed Jul 05 22:42:01 2017 +0200 @@ -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, '/'); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/SimpleHttpServer.java Wed Jul 05 22:42:01 2017 +0200 @@ -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(); + } + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogAccessTest.java Wed Jul 05 22:42:01 2017 +0200 @@ -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} + }; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogFileInputTest.java Wed Jul 05 22:42:01 2017 +0200 @@ -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()); + } + } +}
--- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogInvalidPathTest.java Tue Jan 17 07:41:04 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -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(); - } -}
--- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupportBase.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupportBase.java Wed Jul 05 22:42:01 2017 +0200 @@ -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.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 @@ 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 @@ 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); + } + } }
--- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java Wed Jul 05 22:42:01 2017 +0200 @@ -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.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 @@ * 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 @@ */ @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 @@ * 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 @@ * 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 @@ 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 @@ * 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 @@ * 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 @@ * 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ * 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 @@ */ @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 @@ * 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 @@ * 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 @@ * 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 @@ * 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 @@ * 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 @@ 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 @@ 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 @@ */ @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 @@ 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 @@ 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 @@ */ @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 @@ 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]");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/jar/META-INF/MANIFEST.MF Wed Jul 05 22:42:01 2017 +0200 @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Created-By: 9-ea (Oracle Corporation) +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/jar/META-INF/catalog/ws-addr.xsd Wed Jul 05 22:42:01 2017 +0200 @@ -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>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/jar/META-INF/jax-ws-catalog.xml Wed Jul 05 22:42:01 2017 +0200 @@ -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> \ No newline at end of file
--- a/jaxp/test/javax/xml/jaxp/unittest/transform/TransformerTest.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxp/test/javax/xml/jaxp/unittest/transform/TransformerTest.java Wed Jul 05 22:42:01 2017 +0200 @@ -37,6 +37,7 @@ 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 @@ * @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 @@ } } - /** - * 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 @@ */ @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 @@ 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 @@ 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 @@ " </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(); } /**
--- a/jaxws/.hgtags Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxws/.hgtags Wed Jul 05 22:42:01 2017 +0200 @@ -397,3 +397,4 @@ 72554d319b474b3636c7d02fe3c110254d111b1a jdk-9+149 77e4e30d9d111272cd4a45a2203e8f570d40b12e jdk-9+150 c48b4d4768b1c2b8fe5d1a844ca13732e5dfbe2a jdk-9+151 +6f8fb1cf7e5f61c40dcc3654f9a623c505f6de1f jdk-9+152
--- a/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/messaging/saaj/soap/impl/DetailImpl.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/messaging/saaj/soap/impl/DetailImpl.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 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 @@ 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; - } - }
--- a/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/messaging/saaj/soap/impl/ElementImpl.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/messaging/saaj/soap/impl/ElementImpl.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 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 @@ 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 @@ 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)
--- a/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/messaging/saaj/util/stax/SaajStaxWriter.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/messaging/saaj/util/stax/SaajStaxWriter.java Wed Jul 05 22:42:01 2017 +0200 @@ -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.Iterator; import java.util.Arrays; -import java.util.Iterator; +import java.util.List; +import java.util.LinkedList; import javax.xml.namespace.NamespaceContext; import javax.xml.namespace.QName; @@ -42,6 +44,17 @@ /** * 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 @@ 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 SaajStaxWriter(final SOAPMessage msg, String uri) throws SOAPException { soap = msg; this.envURI = uri; + this.deferredElement = new DeferredElement(); } public SOAPMessage getSOAPMessage() { @@ -70,11 +85,8 @@ @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 @@ @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 @@ 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 @@ @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 @@ @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 @@ @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 @@ @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 @@ @Override public void writeCharacters(final String text) throws XMLStreamException { + currentElement = deferredElement.flushTo(currentElement); try { currentElement.addTextNode(text); } catch (SOAPException e) { @@ -266,6 +286,7 @@ @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 @@ @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 @@ } }; } + + 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; + } + } }
--- a/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/api/message/saaj/SaajStaxWriter.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/api/message/saaj/SaajStaxWriter.java Wed Jul 05 22:42:01 2017 +0200 @@ -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.Iterator; import java.util.Arrays; -import java.util.Iterator; +import java.util.List; +import java.util.LinkedList; import javax.xml.namespace.NamespaceContext; import javax.xml.namespace.QName; @@ -42,6 +44,17 @@ /** * 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 @@ 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 SaajStaxWriter(final SOAPMessage msg, String uri) throws SOAPException { soap = msg; this.envURI = uri; + this.deferredElement = new DeferredElement(); } public SOAPMessage getSOAPMessage() { @@ -70,11 +85,8 @@ @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 @@ @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 @@ 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 @@ @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 @@ @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 @@ @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 @@ @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 @@ @Override public void writeCharacters(final String text) throws XMLStreamException { + currentElement = deferredElement.flushTo(currentElement); try { currentElement.addTextNode(text); } catch (SOAPException e) { @@ -266,6 +286,7 @@ @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 @@ @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 @@ 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 @@ } }; } + + 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; + } + } }
--- a/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java Wed Jul 05 22:42:01 2017 +0200 @@ -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.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 @@ * (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.
--- a/jaxws/src/jdk.xml.bind/share/classes/com/sun/tools/internal/xjc/Options.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jaxws/src/jdk.xml.bind/share/classes/com/sun/tools/internal/xjc/Options.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ * 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 @@ // 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.
--- a/jdk/.hgtags Tue Jan 17 07:41:04 2017 +0100 +++ b/jdk/.hgtags Wed Jul 05 22:42:01 2017 +0200 @@ -394,3 +394,4 @@ 5a846396a24c7aff01d6a8feaa7afc0a6369f04d jdk-9+149 71e198ef3839045e829a879af1d709be16ab0f88 jdk-9+150 d27bab22ff62823902d93d1d35ca397cfd50d059 jdk-9+151 +a20f2cf90762673e1bc4980fd6597e70a2578045 jdk-9+152
--- a/jdk/make/data/fontconfig/solaris.fontconfig.properties Tue Jan 17 07:41:04 2017 +0100 +++ b/jdk/make/data/fontconfig/solaris.fontconfig.properties Wed Jul 05 22:42:01 2017 +0200 @@ -436,15 +436,15 @@ 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
--- a/jdk/make/lib/Awt2dLibraries.gmk Tue Jan 17 07:41:04 2017 +0100 +++ b/jdk/make/lib/Awt2dLibraries.gmk Wed Jul 05 22:42:01 2017 +0200 @@ -222,6 +222,8 @@ # 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, \
--- a/jdk/src/java.base/share/classes/java/io/File.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jdk/src/java.base/share/classes/java/io/File.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ 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)
--- a/jdk/src/java.base/share/classes/java/lang/Class.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jdk/src/java.base/share/classes/java/lang/Class.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ -2477,7 +2477,7 @@ * <ul> * * <li> If the {@code name} begins with a {@code '/'} - * (<tt>'\u002f'</tt>), then the absolute name of the resource is the + * (<code>'\u002f'</code>), then the absolute name of the resource is the * portion of the {@code name} following the {@code '/'}. * * <li> Otherwise, the absolute name is of the following form: @@ -2488,7 +2488,7 @@ * * <p> Where the {@code modified_package_name} is the package name of this * object with {@code '/'} substituted for {@code '.'} - * (<tt>'\u002e'</tt>). + * (<code>'\u002e'</code>). * * </ul> * @@ -2570,7 +2570,7 @@ * <ul> * * <li> If the {@code name} begins with a {@code '/'} - * (<tt>'\u002f'</tt>), then the absolute name of the resource is the + * (<code>'\u002f'</code>), then the absolute name of the resource is the * portion of the {@code name} following the {@code '/'}. * * <li> Otherwise, the absolute name is of the following form: @@ -2581,7 +2581,7 @@ * * <p> Where the {@code modified_package_name} is the package name of this * object with {@code '/'} substituted for {@code '.'} - * (<tt>'\u002e'</tt>). + * (<code>'\u002e'</code>). * * </ul> *
--- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Wed Jul 05 22:42:01 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, 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 @@ -70,34 +70,34 @@ /** * A class loader is an object that is responsible for loading classes. The - * class <tt>ClassLoader</tt> is an abstract class. Given the <a + * class {@code ClassLoader} is an abstract class. Given the <a * href="#name">binary name</a> of a class, a class loader should attempt to * locate or generate data that constitutes a definition for the class. A * typical strategy is to transform the name into a file name and then read a * "class file" of that name from a file system. * - * <p> Every {@link Class <tt>Class</tt>} object contains a {@link - * Class#getClassLoader() reference} to the <tt>ClassLoader</tt> that defined + * <p> Every {@link java.lang.Class Class} object contains a {@link + * Class#getClassLoader() reference} to the {@code ClassLoader} that defined * it. * - * <p> <tt>Class</tt> objects for array classes are not created by class + * <p> {@code Class} objects for array classes are not created by class * loaders, but are created automatically as required by the Java runtime. * The class loader for an array class, as returned by {@link * Class#getClassLoader()} is the same as the class loader for its element * type; if the element type is a primitive type, then the array class has no * class loader. * - * <p> Applications implement subclasses of <tt>ClassLoader</tt> in order to + * <p> Applications implement subclasses of {@code ClassLoader} in order to * extend the manner in which the Java virtual machine dynamically loads * classes. * * <p> Class loaders may typically be used by security managers to indicate * security domains. * - * <p> The <tt>ClassLoader</tt> class uses a delegation model to search for - * classes and resources. Each instance of <tt>ClassLoader</tt> has an + * <p> The {@code ClassLoader} class uses a delegation model to search for + * classes and resources. Each instance of {@code ClassLoader} has an * associated parent class loader. When requested to find a class or - * resource, a <tt>ClassLoader</tt> instance will delegate the search for the + * resource, a {@code ClassLoader} instance will delegate the search for the * class or resource to its parent class loader before attempting to find the * class or resource itself. * @@ -105,15 +105,15 @@ * <em>{@linkplain #isRegisteredAsParallelCapable() parallel capable}</em> class * loaders and are required to register themselves at their class initialization * time by invoking the {@link - * #registerAsParallelCapable <tt>ClassLoader.registerAsParallelCapable</tt>} - * method. Note that the <tt>ClassLoader</tt> class is registered as parallel + * #registerAsParallelCapable ClassLoader.registerAsParallelCapable} + * method. Note that the {@code ClassLoader} class is registered as parallel * capable by default. However, its subclasses still need to register themselves * if they are parallel capable. * In environments in which the delegation model is not strictly * hierarchical, class loaders need to be parallel capable, otherwise class * loading can lead to deadlocks because the loader lock is held for the * duration of the class loading process (see {@link #loadClass - * <tt>loadClass</tt>} methods). + * loadClass} methods). * * <h3> <a name="builtinLoaders">Run-time Built-in Class Loaders</a></h3> * @@ -143,13 +143,13 @@ * However, some classes may not originate from a file; they may originate * from other sources, such as the network, or they could be constructed by an * application. The method {@link #defineClass(String, byte[], int, int) - * <tt>defineClass</tt>} converts an array of bytes into an instance of class - * <tt>Class</tt>. Instances of this newly defined class can be created using - * {@link Class#newInstance <tt>Class.newInstance</tt>}. + * defineClass} converts an array of bytes into an instance of class + * {@code Class}. Instances of this newly defined class can be created using + * {@link Class#newInstance Class.newInstance}. * * <p> The methods and constructors of objects created by a class loader may * reference other classes. To determine the class(es) referred to, the Java - * virtual machine invokes the {@link #loadClass <tt>loadClass</tt>} method of + * virtual machine invokes the {@link #loadClass loadClass} method of * the class loader that originally created the class. * * <p> For example, an application could create a network class loader to @@ -162,9 +162,9 @@ * </pre></blockquote> * * <p> The network class loader subclass must define the methods {@link - * #findClass <tt>findClass</tt>} and <tt>loadClassData</tt> to load a class + * #findClass findClass} and {@code loadClassData} to load a class * from the network. Once it has downloaded the bytes that make up the class, - * it should use the method {@link #defineClass <tt>defineClass</tt>} to + * it should use the method {@link #defineClass defineClass} to * create a class instance. A sample implementation is: * * <blockquote><pre> @@ -392,7 +392,7 @@ * * <p> If there is a security manager, its {@link * SecurityManager#checkCreateClassLoader() - * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in + * checkCreateClassLoader} method is invoked. This may result in * a security exception. </p> * * @param parent @@ -400,7 +400,7 @@ * * @throws SecurityException * If a security manager exists and its - * <tt>checkCreateClassLoader</tt> method doesn't allow creation + * {@code checkCreateClassLoader} method doesn't allow creation * of a new class loader. * * @since 1.2 @@ -410,18 +410,18 @@ } /** - * Creates a new class loader using the <tt>ClassLoader</tt> returned by + * Creates a new class loader using the {@code ClassLoader} returned by * the method {@link #getSystemClassLoader() - * <tt>getSystemClassLoader()</tt>} as the parent class loader. + * getSystemClassLoader()} as the parent class loader. * * <p> If there is a security manager, its {@link * SecurityManager#checkCreateClassLoader() - * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in + * checkCreateClassLoader} method is invoked. This may result in * a security exception. </p> * * @throws SecurityException * If a security manager exists and its - * <tt>checkCreateClassLoader</tt> method doesn't allow creation + * {@code checkCreateClassLoader} method doesn't allow creation * of a new class loader. */ protected ClassLoader() { @@ -458,13 +458,13 @@ * This method searches for classes in the same manner as the {@link * #loadClass(String, boolean)} method. It is invoked by the Java virtual * machine to resolve class references. Invoking this method is equivalent - * to invoking {@link #loadClass(String, boolean) <tt>loadClass(name, - * false)</tt>}. + * to invoking {@link #loadClass(String, boolean) loadClass(name, + * false)}. * * @param name * The <a href="#name">binary name</a> of the class * - * @return The resulting <tt>Class</tt> object + * @return The resulting {@code Class} object * * @throws ClassNotFoundException * If the class was not found @@ -483,8 +483,8 @@ * <li><p> Invoke {@link #findLoadedClass(String)} to check if the class * has already been loaded. </p></li> * - * <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method - * on the parent class loader. If the parent is <tt>null</tt> the class + * <li><p> Invoke the {@link #loadClass(String) loadClass} method + * on the parent class loader. If the parent is {@code null} the class * loader built-in to the virtual machine is used, instead. </p></li> * * <li><p> Invoke the {@link #findClass(String)} method to find the @@ -493,23 +493,23 @@ * </ol> * * <p> If the class was found using the above steps, and the - * <tt>resolve</tt> flag is true, this method will then invoke the {@link - * #resolveClass(Class)} method on the resulting <tt>Class</tt> object. + * {@code resolve} flag is true, this method will then invoke the {@link + * #resolveClass(Class)} method on the resulting {@code Class} object. * - * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link + * <p> Subclasses of {@code ClassLoader} are encouraged to override {@link * #findClass(String)}, rather than this method. </p> * * <p> Unless overridden, this method synchronizes on the result of - * {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method + * {@link #getClassLoadingLock getClassLoadingLock} method * during the entire class loading process. * * @param name * The <a href="#name">binary name</a> of the class * * @param resolve - * If <tt>true</tt> then resolve the class + * If {@code true} then resolve the class * - * @return The resulting <tt>Class</tt> object + * @return The resulting {@code Class} object * * @throws ClassNotFoundException * If the class could not be found @@ -606,7 +606,7 @@ * @return the lock for class loading operations * * @throws NullPointerException - * If registered as parallel capable and <tt>className</tt> is null + * If registered as parallel capable and {@code className} is null * * @see #loadClass(String, boolean) * @@ -667,14 +667,14 @@ * Finds the class with the specified <a href="#name">binary name</a>. * This method should be overridden by class loader implementations that * follow the delegation model for loading classes, and will be invoked by - * the {@link #loadClass <tt>loadClass</tt>} method after checking the + * the {@link #loadClass loadClass} method after checking the * parent class loader for the requested class. The default implementation - * throws a <tt>ClassNotFoundException</tt>. + * throws a {@code ClassNotFoundException}. * * @param name * The <a href="#name">binary name</a> of the class * - * @return The resulting <tt>Class</tt> object + * @return The resulting {@code Class} object * * @throws ClassNotFoundException * If the class could not be found @@ -722,32 +722,32 @@ /** - * Converts an array of bytes into an instance of class <tt>Class</tt>. - * Before the <tt>Class</tt> can be used it must be resolved. This method + * Converts an array of bytes into an instance of class {@code Class}. + * Before the {@code Class} can be used it must be resolved. This method * is deprecated in favor of the version that takes a <a * href="#name">binary name</a> as its first argument, and is more secure. * * @param b * The bytes that make up the class data. The bytes in positions - * <tt>off</tt> through <tt>off+len-1</tt> should have the format + * {@code off} through {@code off+len-1} should have the format * of a valid class file as defined by * <cite>The Java™ Virtual Machine Specification</cite>. * * @param off - * The start offset in <tt>b</tt> of the class data + * The start offset in {@code b} of the class data * * @param len * The length of the class data * - * @return The <tt>Class</tt> object that was created from the specified + * @return The {@code Class} object that was created from the specified * class data * * @throws ClassFormatError * If the data did not contain a valid class * * @throws IndexOutOfBoundsException - * If either <tt>off</tt> or <tt>len</tt> is negative, or if - * <tt>off+len</tt> is greater than <tt>b.length</tt>. + * If either {@code off} or {@code len} is negative, or if + * {@code off+len} is greater than {@code b.length}. * * @throws SecurityException * If an attempt is made to add this class to a package that @@ -994,11 +994,11 @@ * #defineClass(String, byte[], int, int, ProtectionDomain)}. * * <p> An invocation of this method of the form - * <i>cl</i><tt>.defineClass(</tt><i>name</i><tt>,</tt> - * <i>bBuffer</i><tt>,</tt> <i>pd</i><tt>)</tt> yields exactly the same + * <i>cl</i>{@code .defineClass(}<i>name</i>{@code ,} + * <i>bBuffer</i>{@code ,} <i>pd</i>{@code )} yields exactly the same * result as the statements * - *<p> <tt> + *<p> <code> * ...<br> * byte[] temp = new byte[bBuffer.{@link * java.nio.ByteBuffer#remaining remaining}()];<br> @@ -1007,16 +1007,16 @@ * return {@link #defineClass(String, byte[], int, int, ProtectionDomain) * cl.defineClass}(name, temp, 0, * temp.length, pd);<br> - * </tt></p> + * </code></p> * * @param name * The expected <a href="#name">binary name</a>. of the class, or - * <tt>null</tt> if not known + * {@code null} if not known * * @param b * The bytes that make up the class data. The bytes from positions - * <tt>b.position()</tt> through <tt>b.position() + b.limit() -1 - * </tt> should have the format of a valid class file as defined by + * {@code b.position()} through {@code b.position() + b.limit() -1 + * } should have the format of a valid class file as defined by * <cite>The Java™ Virtual Machine Specification</cite>. * * @param protectionDomain @@ -1158,7 +1158,7 @@ /** * Links the specified class. This (misleadingly named) method may be - * used by a class loader to link a class. If the class <tt>c</tt> has + * used by a class loader to link a class. If the class {@code c} has * already been linked, then this method simply returns. Otherwise, the * class is linked as described in the "Execution" chapter of * <cite>The Java™ Language Specification</cite>. @@ -1167,7 +1167,7 @@ * The class to link * * @throws NullPointerException - * If <tt>c</tt> is <tt>null</tt>. + * If {@code c} is {@code null}. * * @see #defineClass(String, byte[], int, int) */ @@ -1182,16 +1182,16 @@ * loading it if necessary. * * <p> This method loads the class through the system class loader (see - * {@link #getSystemClassLoader()}). The <tt>Class</tt> object returned - * might have more than one <tt>ClassLoader</tt> associated with it. - * Subclasses of <tt>ClassLoader</tt> need not usually invoke this method, + * {@link #getSystemClassLoader()}). The {@code Class} object returned + * might have more than one {@code ClassLoader} associated with it. + * Subclasses of {@code ClassLoader} need not usually invoke this method, * because most class loaders need to override just {@link * #findClass(String)}. </p> * * @param name * The <a href="#name">binary name</a> of the class * - * @return The <tt>Class</tt> object for the specified <tt>name</tt> + * @return The {@code Class} object for the specified {@code name} * * @throws ClassNotFoundException * If the class could not be found @@ -1222,12 +1222,12 @@ * Returns the class with the given <a href="#name">binary name</a> if this * loader has been recorded by the Java virtual machine as an initiating * loader of a class with that <a href="#name">binary name</a>. Otherwise - * <tt>null</tt> is returned. + * {@code null} is returned. * * @param name * The <a href="#name">binary name</a> of the class * - * @return The <tt>Class</tt> object, or <tt>null</tt> if the class has + * @return The {@code Class} object, or {@code null} if the class has * not been loaded * * @since 1.1 @@ -1245,7 +1245,7 @@ * class. * * @param c - * The <tt>Class</tt> object + * The {@code Class} object * * @param signers * The signers for the class @@ -1306,11 +1306,11 @@ * (images, audio, text, etc) that can be accessed by class code in a way * that is independent of the location of the code. * - * <p> The name of a resource is a '<tt>/</tt>'-separated path name that + * <p> The name of a resource is a '{@code /}'-separated path name that * identifies the resource. * * <p> This method will first search the parent class loader for the - * resource; if the parent is <tt>null</tt> the path of the class loader + * resource; if the parent is {@code null} the path of the class loader * built-in to the virtual machine is searched. That failing, this method * will invoke {@link #findResource(String)} to find the resource. </p> * @@ -1362,7 +1362,7 @@ * (images, audio, text, etc) that can be accessed by class code in a way * that is independent of the location of the code. * - * <p> The name of a resource is a <tt>/</tt>-separated path name that + * <p> The name of a resource is a {@code /}-separated path name that * identifies the resource. * * <p> The delegation order for searching is described in the documentation @@ -1389,7 +1389,7 @@ * @param name * The resource name * - * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for + * @return An enumeration of {@link java.net.URL URL} objects for * the resource. If no resources could be found, the enumeration * will be empty. Resources for which a {@code URL} cannot be * constructed, are in package that is not opened unconditionally, @@ -1505,7 +1505,7 @@ } /** - * Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects + * Returns an enumeration of {@link java.net.URL URL} objects * representing all the resources with the given name. Class loader * implementations should override this method to specify where to load * resources from. @@ -1520,7 +1520,7 @@ * @param name * The resource name * - * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for + * @return An enumeration of {@link java.net.URL URL} objects for * the resource. If no resources could be found, the enumeration * will be empty. Resources for which a {@code URL} cannot be * constructed, are in a package that is not opened unconditionally, @@ -1594,7 +1594,7 @@ * @param name * The resource name * - * @return A {@link java.net.URL <tt>URL</tt>} to the resource; {@code + * @return A {@link java.net.URL URL} to the resource; {@code * null} if the resource could not be found, a URL could not be * constructed to locate the resource, the resource is in a package * that is not opened unconditionally or access to the resource is @@ -1609,8 +1609,8 @@ /** * Finds all resources of the specified name from the search path used to * load classes. The resources thus found are returned as an - * {@link java.util.Enumeration <tt>Enumeration</tt>} of {@link - * java.net.URL <tt>URL</tt>} objects. + * {@link java.util.Enumeration Enumeration} of {@link + * java.net.URL URL} objects. * * <p> The search order is described in the documentation for {@link * #getSystemResource(String)}. </p> @@ -1625,7 +1625,7 @@ * @param name * The resource name * - * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for + * @return An enumeration of {@link java.net.URL URL} objects for * the resource. If no resources could be found, the enumeration * will be empty. Resources for which a {@code URL} cannot be * constructed, are in a package that is not opened unconditionally, @@ -1714,11 +1714,11 @@ /** * Returns the parent class loader for delegation. Some implementations may - * use <tt>null</tt> to represent the bootstrap class loader. This method - * will return <tt>null</tt> in such implementations if this class loader's + * use {@code null} to represent the bootstrap class loader. This method + * will return {@code null} in such implementations if this class loader's * parent is the bootstrap class loader. * - * @return The parent <tt>ClassLoader</tt> + * @return The parent {@code ClassLoader} * * @throws SecurityException * If a security manager is present, and the caller's class loader @@ -1785,7 +1785,7 @@ /** * Returns the system class loader for delegation. This is the default - * delegation parent for new <tt>ClassLoader</tt> instances, and is + * delegation parent for new {@code ClassLoader} instances, and is * typically the class loader used to start the application. * * <p> This method is first invoked early in the runtime's startup @@ -1797,12 +1797,12 @@ * <p> The default system class loader is an implementation-dependent * instance of this class. * - * <p> If the system property "<tt>java.system.class.loader</tt>" is defined + * <p> If the system property "{@code java.system.class.loader}" is defined * when this method is first invoked then the value of that property is * taken to be the name of a class that will be returned as the system * class loader. The class is loaded using the default system class loader * and must define a public constructor that takes a single parameter of - * type <tt>ClassLoader</tt> which is used as the delegation parent. An + * type {@code ClassLoader} which is used as the delegation parent. An * instance is then created using this constructor with the default system * class loader as the parameter. The resulting class loader is defined * to be the system class loader. During construction, the class loader @@ -1825,7 +1825,7 @@ * the application module path then the class path defaults to * the current working directory. * - * @return The system <tt>ClassLoader</tt> for delegation + * @return The system {@code ClassLoader} for delegation * * @throws SecurityException * If a security manager is present, and the caller's class loader @@ -1835,11 +1835,11 @@ * * @throws IllegalStateException * If invoked recursively during the construction of the class - * loader specified by the "<tt>java.system.class.loader</tt>" + * loader specified by the "{@code java.system.class.loader}" * property. * * @throws Error - * If the system property "<tt>java.system.class.loader</tt>" + * If the system property "{@code java.system.class.loader}" * is defined but the named class could not be loaded, the * provider class does not define the required constructor, or an * exception is thrown by that constructor when it is invoked. The @@ -2249,9 +2249,9 @@ /** * Returns the absolute path name of a native library. The VM invokes this * method to locate the native libraries that belong to classes loaded with - * this class loader. If this method returns <tt>null</tt>, the VM + * this class loader. If this method returns {@code null}, the VM * searches the library along the path specified as the - * "<tt>java.library.path</tt>" property. + * "{@code java.library.path}" property. * * @param libname * The library name @@ -2270,12 +2270,12 @@ /** * The inner class NativeLibrary denotes a loaded native library instance. * Every classloader contains a vector of loaded native libraries in the - * private field <tt>nativeLibraries</tt>. The native libraries loaded - * into the system are entered into the <tt>systemNativeLibraries</tt> + * private field {@code nativeLibraries}. The native libraries loaded + * into the system are entered into the {@code systemNativeLibraries} * vector. * * <p> Every native library requires a particular version of JNI. This is - * denoted by the private <tt>jniVersion</tt> field. This field is set by + * denoted by the private {@code jniVersion} field. This field is set by * the VM when it loads the library, and used by the VM to pass the correct * version of JNI to the native methods. </p> * @@ -2592,8 +2592,8 @@ * #setClassAssertionStatus(String, boolean)}. * * @param enabled - * <tt>true</tt> if classes loaded by this class loader will - * henceforth have assertions enabled by default, <tt>false</tt> + * {@code true} if classes loaded by this class loader will + * henceforth have assertions enabled by default, {@code false} * if they will have assertions disabled by default. * * @since 1.4 @@ -2614,16 +2614,16 @@ * any of its "subpackages". * * <p> A subpackage of a package named p is any package whose name begins - * with "<tt>p.</tt>". For example, <tt>javax.swing.text</tt> is a - * subpackage of <tt>javax.swing</tt>, and both <tt>java.util</tt> and - * <tt>java.lang.reflect</tt> are subpackages of <tt>java</tt>. + * with "{@code p.}". For example, {@code javax.swing.text} is a + * subpackage of {@code javax.swing}, and both {@code java.util} and + * {@code java.lang.reflect} are subpackages of {@code java}. * * <p> In the event that multiple package defaults apply to a given class, * the package default pertaining to the most specific package takes - * precedence over the others. For example, if <tt>javax.lang</tt> and - * <tt>javax.lang.reflect</tt> both have package defaults associated with + * precedence over the others. For example, if {@code javax.lang} and + * {@code javax.lang.reflect} both have package defaults associated with * them, the latter package default applies to classes in - * <tt>javax.lang.reflect</tt>. + * {@code javax.lang.reflect}. * * <p> Package defaults take precedence over the class loader's default * assertion status, and may be overridden on a per-class basis by invoking @@ -2631,15 +2631,15 @@ * * @param packageName * The name of the package whose package default assertion status - * is to be set. A <tt>null</tt> value indicates the unnamed + * is to be set. A {@code null} value indicates the unnamed * package that is "current" * (see section 7.4.2 of * <cite>The Java™ Language Specification</cite>.) * * @param enabled - * <tt>true</tt> if classes loaded by this classloader and + * {@code true} if classes loaded by this classloader and * belonging to the named package or any of its subpackages will - * have assertions enabled by default, <tt>false</tt> if they will + * have assertions enabled by default, {@code false} if they will * have assertions disabled by default. * * @since 1.4 @@ -2670,8 +2670,8 @@ * assertion status is to be set. * * @param enabled - * <tt>true</tt> if the named class is to have assertions - * enabled when (and if) it is initialized, <tt>false</tt> if the + * {@code true} if the named class is to have assertions + * enabled when (and if) it is initialized, {@code false} if the * class is to have assertions disabled. * * @since 1.4 @@ -2687,7 +2687,7 @@ /** * Sets the default assertion status for this class loader to - * <tt>false</tt> and discards any package defaults or class assertion + * {@code false} and discards any package defaults or class assertion * status settings associated with the class loader. This method is * provided so that class loaders can be made to ignore any command line or * persistent assertion status settings and "start with a clean slate."
--- a/jdk/src/java.base/share/classes/java/net/URLConnection.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jdk/src/java.base/share/classes/java/net/URLConnection.java Wed Jul 05 22:42:01 2017 +0200 @@ -30,8 +30,10 @@ 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 @@ */ 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 @@ * <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 @@ */ protected URLConnection(URL url) { this.url = url; + if (url == null) { + this.useCaches = defaultUseCaches; + } else { + this.useCaches = getDefaultUseCaches(url.getProtocol()); + } } /** @@ -981,7 +994,8 @@ * 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 @@ * 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 @@ /** * 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 @@ 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.
--- a/jdk/src/java.base/share/classes/java/util/Collections.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jdk/src/java.base/share/classes/java/util/Collections.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ private Object readResolve() { return EMPTY_SET; } + + @Override + public int hashCode() { + return 0; + } } /** @@ -4786,6 +4791,10 @@ public boolean removeIf(Predicate<? super E> filter) { throw new UnsupportedOperationException(); } + @Override + public int hashCode() { + return Objects.hashCode(element); + } } /** @@ -4848,6 +4857,10 @@ public Spliterator<E> spliterator() { return singletonSpliterator(element); } + @Override + public int hashCode() { + return 31 + Objects.hashCode(element); + } } /** @@ -4970,6 +4983,11 @@ BiFunction<? super V, ? super V, ? extends V> remappingFunction) { throw new UnsupportedOperationException(); } + + @Override + public int hashCode() { + return Objects.hashCode(k) ^ Objects.hashCode(v); + } } // Miscellaneous
--- a/jdk/src/java.base/share/classes/java/util/Date.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jdk/src/java.base/share/classes/java/util/Date.java Wed Jul 05 22:42:01 2017 +0200 @@ -82,17 +82,19 @@ * 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:
--- a/jdk/src/java.base/share/classes/java/util/ImmutableCollections.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jdk/src/java.base/share/classes/java/util/ImmutableCollections.java Wed Jul 05 22:42:01 2017 +0200 @@ -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.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 @@ 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 @@ 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 @@ @Override public E get(int index) { Objects.checkIndex(index, 1); - // assert index == 0 return e0; } @@ -140,10 +162,22 @@ 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 @@ } } + @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 @@ } static final class ListN<E> extends AbstractImmutableList<E> { + @Stable private final E[] elements; @SafeVarargs @@ -200,6 +246,25 @@ 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 @@ @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 @@ 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 @@ @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 @@ 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 @@ @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 @@ * @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 @@ 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 @@ @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 @@ }; } + @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 @@ @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 @@ 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 @@ @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 @@ private Object writeReplace() { return new CollSer(CollSer.IMM_MAP, k0, v0); } + + @Override + public int hashCode() { + return k0.hashCode() ^ v0.hashCode(); + } } /** @@ -541,12 +655,13 @@ * @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 @@ @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 @@ } // 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) {
--- a/jdk/src/java.base/share/classes/java/util/KeyValueHolder.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jdk/src/java.base/share/classes/java/util/KeyValueHolder.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ * @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) {
--- a/jdk/src/java.base/share/classes/java/util/List.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jdk/src/java.base/share/classes/java/util/List.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ @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:
--- a/jdk/src/java.base/share/classes/java/util/Map.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jdk/src/java.base/share/classes/java/util/Map.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ @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(),
--- a/jdk/src/java.base/share/classes/java/util/Set.java Tue Jan 17 07:41:04 2017 +0100 +++ b/jdk/src/java.base/share/classes/java/util/Set.java Wed Jul 05 22:42:01 2017 +0200 @@ -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 @@ @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:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleHashesBuilder.java Wed Jul 05 22:42:01 2017 +0200 @@ -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;