Merge jdk7-b114
authorlana
Tue, 12 Oct 2010 12:51:48 -0700
changeset 2864e250cef36ea0
parent 2794 621be994f8d9
parent 2863 4a513df0df12
child 2865 0613978371d8
child 2959 2278f3ff5f95
child 2980 7713900ff391
Merge
make/common/Rules-SCCS.gmk
test/sun/net/www/http/ChunkedInputStream/ChunkedCharEncoding.sh
     1.1 --- a/make/Makefile	Thu Oct 07 15:12:19 2010 -0700
     1.2 +++ b/make/Makefile	Tue Oct 12 12:51:48 2010 -0700
     1.3 @@ -75,7 +75,6 @@
     1.4  import_fastdebug  -- copy in the fastdebug components \n\
     1.5  import_debug      -- copy in the debug components \n\
     1.6  modules           -- build the jdk and jre module images (experimental) \n\
     1.7 -sccs_get          -- make sure all SCCS files are up-to-date (need SCCS) \n\
     1.8  create_links      -- create softlinks in Solaris 32bit build to 64bit dirs \n\
     1.9  "
    1.10  
    1.11 @@ -278,21 +277,6 @@
    1.12  $(OUTPUTDIR) $(TEMPDIR):
    1.13  	$(MKDIR) -p $@
    1.14  
    1.15 -# cleanup everything. If the workspace is not being built by the control
    1.16 -# workspace, and if it is a Teamware workspace, then see if there are
    1.17 -# any files which are not under SCCS control.
    1.18 -clean clobber:: 
    1.19 -ifndef EXTERNALSANITYCONTROL
    1.20 -	@if [ -d $(TOPDIR)/Codemgr_wsdata ]; then \
    1.21 -	  $(ECHO) '\nPerforming workspace scan for remnant files.\n' \
    1.22 -		'  Any files listed below are not under SCCS control in the workspace\n' \
    1.23 -		'  and you should review them and possibly remove them manually:' ; \
    1.24 -	  $(FIND) $(TOPDIR)/make $(TOPDIR)/src -type f | \
    1.25 -		$(SED) 's+SCCS/[ps]\.++' | $(SORT) | $(UNIQ) -c | $(NAWK) '$$1<2 {print $$2;}' ; \
    1.26 -	  $(ECHO) 'End of workspace scan.' ; \
    1.27 -	fi
    1.28 -endif
    1.29 -
    1.30  # this should be the last rule in this file:
    1.31  all::
    1.32  	@if [ -r $(WARNING_FILE) ]; then \
    1.33 @@ -341,16 +325,70 @@
    1.34  include $(BUILDDIR)/common/internal/BinaryPlugs.gmk
    1.35  
    1.36  #
    1.37 -# Get top level sccs_get rule
    1.38 +# Test rule
    1.39  #
    1.40 -include $(BUILDDIR)/common/Rules-SCCS.gmk
    1.41  
    1.42 +.NOTPARALLEL: test_run
    1.43 +
    1.44 +test:
    1.45 +	$(MAKE) test_run
    1.46 +
    1.47 +test_run: test_clean test_start test_summary
    1.48 +
    1.49 +test_start:
    1.50 +	@$(ECHO) "Tests started at `$(DATE)`"
    1.51 +
    1.52 +test_clean:
    1.53 +	$(RM) $(OUTPUTDIR)/test_failures.txt $(OUTPUTDIR)/test_log.txt
    1.54 +
    1.55 +test_summary: $(OUTPUTDIR)/test_failures.txt
    1.56 +	@$(ECHO) "#################################################"
    1.57 +	@$(ECHO) "Tests completed at `$(DATE)`"
    1.58 +	@( $(EGREP) '^TEST STATS:' $(OUTPUTDIR)/test_log.txt \
    1.59 +          || $(ECHO) "No TEST STATS seen in log" )
    1.60 +	@$(ECHO) "For complete details see: $(OUTPUTDIR)/test_log.txt"
    1.61 +	@$(ECHO) "#################################################"
    1.62 +	@if [ -s $< ] ; then                                           \
    1.63 +          $(ECHO) "ERROR: Test failure count: `$(CAT) $< | $(WC) -l`"; \
    1.64 +          $(CAT) $<;                                                   \
    1.65 +          exit 1;                                                      \
    1.66 +        else                                                           \
    1.67 +          $(ECHO) "Success! No failures detected";                     \
    1.68 +        fi
    1.69 +
    1.70 +# Get failure list from log
    1.71 +$(OUTPUTDIR)/test_failures.txt: $(OUTPUTDIR)/test_log.txt
    1.72 +	@$(RM) $@
    1.73 +	@( $(EGREP) '^FAILED:' $< || $(ECHO) "" ) | $(NAWK) 'length>0' > $@
    1.74 +
    1.75 +# Get log file of all tests run
    1.76 +JDK_TO_TEST := $(shell 							\
    1.77 +  if [ -d "$(ABS_OUTPUTDIR)/j2sdk-image" ] ; then 			\
    1.78 +    $(ECHO) "$(ABS_OUTPUTDIR)/j2sdk-image"; 				\
    1.79 +  elif [ -d "$(ABS_OUTPUTDIR)/bin" ] ; then 				\
    1.80 +    $(ECHO) "$(ABS_OUTPUTDIR)"; 					\
    1.81 +  elif [ "$(PRODUCT_HOME)" != "" -a -d "$(PRODUCT_HOME)/bin" ] ; then 	\
    1.82 +    $(ECHO) "$(PRODUCT_HOME)"; 						\
    1.83 +  fi 									\
    1.84 +)
    1.85 +
    1.86 +TEST_TARGETS=jdk_all
    1.87 +$(OUTPUTDIR)/test_log.txt:
    1.88 +	$(RM) $@
    1.89 +	( $(CD) ../test &&                                              \
    1.90 +          $(MAKE) NO_STOPPING=- PRODUCT_HOME=$(JDK_TO_TEST) $(TEST_TARGETS) \
    1.91 +        ) | tee $@
    1.92 +
    1.93 +#
    1.94  # JPRT rules
    1.95 +#
    1.96 +
    1.97  include jprt.gmk
    1.98  
    1.99  #
   1.100  # Phonies to avoid accidents.
   1.101  #
   1.102  .PHONY: all build clean clobber optimized debug fastdebug create_links \
   1.103 -	import import_product import_fastdebug import_debug
   1.104 +	import import_product import_fastdebug import_debug \
   1.105 +	test test_run test_start test_clean test_summary
   1.106  
     2.1 --- a/make/common/Cscope.gmk	Thu Oct 07 15:12:19 2010 -0700
     2.2 +++ b/make/common/Cscope.gmk	Tue Oct 12 12:51:48 2010 -0700
     2.3 @@ -76,7 +76,7 @@
     2.4  # What files should we include?  A simple rule might be just those files under
     2.5  # SCM control, however this would miss files we create like the opcodes and
     2.6  # CClassHeaders.  The following attempts to find everything that is *useful*.
     2.7 -# (.del files are created by sccsrm, demo directories contain many .java files
     2.8 +# (demo directories contain many .java files
     2.9  # that probably aren't useful for development, and the pkgarchive may contain
    2.10  # duplicates of files within the source hierarchy).  The ordering of the .raw
    2.11  # file is an attempt to make cscope display the most relevant files first.
     3.1 --- a/make/common/Defs.gmk	Thu Oct 07 15:12:19 2010 -0700
     3.2 +++ b/make/common/Defs.gmk	Tue Oct 12 12:51:48 2010 -0700
     3.3 @@ -334,7 +334,7 @@
     3.4  DOCSDIRSUFFIX       =
     3.5  
     3.6  # The MESSAGE, WARNING and ERROR files are used to store sanityck and 
     3.7 -# SCCS check messages, warnings and errors. 
     3.8 +# warnings and errors. 
     3.9  ifndef ERROR_FILE
    3.10    ERROR_FILE   = $(OUTPUTDIR)/sanityCheckErrors.txt
    3.11  endif
    3.12 @@ -634,38 +634,6 @@
    3.13  
    3.14  VERSION_DEFINES = -DRELEASE='"$(RELEASE)"'
    3.15  
    3.16 -# Note: As a rule, GNU Make rules should not appear in any of the 
    3.17 -# Defs*.gmk files. These were added for Kestrel-Solaris and do address
    3.18 -# a TeamWare bug. They should be moved elsewhere for Merlin.
    3.19 -# 
    3.20 -#  Override gnumake built-in rules which do sccs get operations badly.
    3.21 -#  (They put the checked out code in the current directory, not in the
    3.22 -#  directory of the original file.) 
    3.23 -# Since this is a symptom of a teamware failure, complain and die on the spot.
    3.24 -
    3.25 -# This message immediately goes to stdout and the build terminates.
    3.26 -define SCCS-trouble
    3.27 -$(error  \
    3.28 -"ERROR: File $@ referenced while building in $(CURRENT_DIRECTORY) \
    3.29 - is out of date with respect to its SCCS file $<. \
    3.30 - This can happen from an unresolved Teamware conflict, a file movement, or \
    3.31 - a failure in which SCCS files are updated but the 'sccs get' was not done. \
    3.32 - You should double check for other out of date files in your workspace. \
    3.33 - Or run: cd $(TOPDIR) && $(MAKE) sccs_get")
    3.34 -endef
    3.35 -
    3.36 -%:: s.%
    3.37 -	@$(SCCS-trouble)
    3.38 -%:: SCCS/s.%
    3.39 -	@$(SCCS-trouble)
    3.40 -	@$(ECHO) "         is out of date with respect to its SCCS file." >> $(WARNING_FILE)
    3.41 -	@$(ECHO) "         This file may be from an unresolved Teamware conflict." >> $(WARNING_FILE)
    3.42 -	@$(ECHO) "         This is also a symptom of a Teamware bringover/putback failure" >> $(WARNING_FILE)
    3.43 -	@$(ECHO) "         in which SCCS files are updated but not checked out." >> $(WARNING_FILE)
    3.44 -	@$(ECHO) "         Check for other out of date files in your workspace." >> $(WARNING_FILE)
    3.45 -	@$(ECHO) "" >> $(WARNING_FILE)
    3.46 -	@#exit 666
    3.47 -
    3.48  ifdef INSANE
    3.49    export INSANE
    3.50  endif
     4.1 --- a/make/common/Rules-SCCS.gmk	Thu Oct 07 15:12:19 2010 -0700
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,70 +0,0 @@
     4.4 -#
     4.5 -# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
     4.6 -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.7 -#
     4.8 -# This code is free software; you can redistribute it and/or modify it
     4.9 -# under the terms of the GNU General Public License version 2 only, as
    4.10 -# published by the Free Software Foundation.  Oracle designates this
    4.11 -# particular file as subject to the "Classpath" exception as provided
    4.12 -# by Oracle in the LICENSE file that accompanied this code.
    4.13 -#
    4.14 -# This code is distributed in the hope that it will be useful, but WITHOUT
    4.15 -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    4.16 -# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    4.17 -# version 2 for more details (a copy is included in the LICENSE file that
    4.18 -# accompanied this code).
    4.19 -#
    4.20 -# You should have received a copy of the GNU General Public License version
    4.21 -# 2 along with this work; if not, write to the Free Software Foundation,
    4.22 -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    4.23 -#
    4.24 -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    4.25 -# or visit www.oracle.com if you need additional information or have any
    4.26 -# questions.
    4.27 -#
    4.28 -
    4.29 -#
    4.30 -# Only get these rules if SCCS is available
    4.31 -#
    4.32 -
    4.33 -ifdef SCCS
    4.34 -
    4.35 -# SCCS command to extract out latest source
    4.36 -SCCS_GET=$(SCCS) get -s
    4.37 -
    4.38 -#
    4.39 -# Make sure all files in workspace are fresh
    4.40 -#
    4.41 -TEMP_ALL_FILES=$(JDK_TOPDIR)/temp_filelist
    4.42 -$(TEMP_ALL_FILES): $(JDK_TOPDIR)/Codemgr_wsdata/nametable
    4.43 -	$(prep-target)
    4.44 -	@$(CUT) -d' ' -f1 $< \
    4.45 -	    | $(GREP) -v '^VERSION' \
    4.46 -	    | $(GREP) -v '^deleted_files' \
    4.47 -	    | $(GREP) -v '^Codemgr_wsdata' > $@
    4.48 -
    4.49 -sccs_get: $(TEMP_ALL_FILES)
    4.50 -	@$(PRINTF) "Workspace has %d files\n"  `$(CAT) $< | $(WC) -l`
    4.51 -	@count=0; \
    4.52 -	for i in `$(CAT) $<` ; do \
    4.53 -	    f=$(JDK_TOPDIR)/$$i; \
    4.54 -	    count=`$(EXPR) $$count '+' 1`; \
    4.55 -	    if [ `$(EXPR) $$count '%' 100` = 0 ] ; then \
    4.56 -		$(PRINTF) "\rChecked $$count files"; \
    4.57 -	    fi; \
    4.58 -	    if [ ! -f $$f ] ; then \
    4.59 -		$(PRINTF) "\r$(SCCS_GET) $$f\n"; \
    4.60 -		(cd `$(DIRNAME) $$f` && $(SCCS_GET) `$(BASENAME) $$f`); \
    4.61 -	    elif /usr/bin/test $$f -ot `$(DIRNAME) $$f`/SCCS/s.`$(BASENAME) $$f` ; then \
    4.62 -		$(PRINTF) "\r$(SCCS_GET) $$f\n"; \
    4.63 -		(cd `$(DIRNAME) $$f` && $(SCCS_GET) `$(BASENAME) $$f`); \
    4.64 -	    fi; \
    4.65 -	done; \
    4.66 -	$(PRINTF) "\rChecked $$count files\n"
    4.67 -
    4.68 -#
    4.69 -# Phonies to avoid accidents.
    4.70 -#
    4.71 -.PHONY: sccs_get
    4.72 -
    4.73 -endif
     5.1 --- a/make/common/shared/Defs-utils.gmk	Thu Oct 07 15:12:19 2010 -0700
     5.2 +++ b/make/common/shared/Defs-utils.gmk	Tue Oct 12 12:51:48 2010 -0700
     5.3 @@ -33,7 +33,7 @@
     5.4  #            UTILS_COMMAND_PATH
     5.5  #         /usr/bin/ 
     5.6  #            UTILS_USR_BIN_PATH
     5.7 -#         /usr/ccs/bin/ (sccs, m4, lex, yacc, as, ar, strip, mcs)
     5.8 +#         /usr/ccs/bin/ (m4, lex, yacc, as, ar, strip, mcs)
     5.9  #            UTILS_CCS_BIN_PATH
    5.10  #         Dev Tools: zip, unzip, etc that we may have special versions of
    5.11  #            UTILS_DEVTOOL_PATH
    5.12 @@ -117,7 +117,6 @@
    5.13  RMDIR          = $(UTILS_COMMAND_PATH)rmdir
    5.14  RPM            = $(UTILS_COMMAND_PATH)rpm
    5.15  RPMBUILD       = $(UTILS_COMMAND_PATH)rpmbuild
    5.16 -SCCS           = $(UTILS_CCS_BIN_PATH)sccs
    5.17  SED            = $(UTILS_COMMAND_PATH)sed
    5.18  SH             = $(UTILS_COMMAND_PATH)sh
    5.19  SHOWREV        = $(UTILS_USR_BIN_PATH)showrev
    5.20 @@ -183,7 +182,7 @@
    5.21    NAWK           = $(USRBIN_PATH)gawk
    5.22    # Intrinsic unix command, with backslash-escaped character interpretation
    5.23    ECHO           = /bin/echo -e
    5.24 -  # These are really in UTILS_USR_BIN_PATH on Linux (only sccs is not)
    5.25 +  # These are really in UTILS_USR_BIN_PATH on Linux
    5.26    AR             = $(UTILS_USR_BIN_PATH)ar
    5.27    AS             = $(UTILS_USR_BIN_PATH)as
    5.28    LD             = $(UTILS_USR_BIN_PATH)ld
     6.1 --- a/make/common/shared/Defs.gmk	Thu Oct 07 15:12:19 2010 -0700
     6.2 +++ b/make/common/shared/Defs.gmk	Tue Oct 12 12:51:48 2010 -0700
     6.3 @@ -219,7 +219,7 @@
     6.4    PRODUCT_NAME = Java(TM)
     6.5    PRODUCT_SUFFIX = SE Runtime Environment
     6.6    JDK_RC_PLATFORM_NAME = Platform SE
     6.7 -  COMPANY_NAME = Oracle
     6.8 +  COMPANY_NAME = Oracle Corporation
     6.9  endif
    6.10  
    6.11  RUNTIME_NAME = $(PRODUCT_NAME) $(PRODUCT_SUFFIX)
     7.1 --- a/make/java/java/FILES_java.gmk	Thu Oct 07 15:12:19 2010 -0700
     7.2 +++ b/make/java/java/FILES_java.gmk	Tue Oct 12 12:51:48 2010 -0700
     7.3 @@ -284,6 +284,7 @@
     7.4      java/util/concurrent/CancellationException.java \
     7.5      java/util/concurrent/CompletionService.java \
     7.6      java/util/concurrent/ConcurrentHashMap.java \
     7.7 +    java/util/concurrent/ConcurrentLinkedDeque.java \
     7.8      java/util/concurrent/ConcurrentLinkedQueue.java \
     7.9      java/util/concurrent/ConcurrentMap.java \
    7.10      java/util/concurrent/ConcurrentNavigableMap.java \
     8.1 --- a/make/jprt.properties	Thu Oct 07 15:12:19 2010 -0700
     8.2 +++ b/make/jprt.properties	Tue Oct 12 12:51:48 2010 -0700
     8.3 @@ -25,43 +25,265 @@
     8.4  
     8.5  # Properties for jprt
     8.6  
     8.7 -# Use whatever release that the submitted job requests
     8.8 +# At submit time, the release supplied will be in jprt.submit.release
     8.9 +#    and will be one of the official release names defined in jprt.
    8.10 +#    jprt supports property value expansion using ${property.name} syntax.
    8.11 +
    8.12 +# This tells jprt what default release we want to build
    8.13  jprt.tools.default.release=${jprt.submit.release}
    8.14  
    8.15  # The different build flavors we want, we override here so we just get these 2
    8.16  jprt.build.flavors=product,fastdebug
    8.17  
    8.18 -# Standard test target for everybody
    8.19 -jprt.test.targets=*-*-*-jvm98
    8.20 +# Define the Windows we want (temporary)
    8.21 +jprt.my.windows.i586.jdk7b107=windows_i586_5.0
    8.22 +jprt.my.windows.i586.jdk7temp=windows_i586_5.0
    8.23 +jprt.my.windows.i586.jdk7=windows_i586_5.1
    8.24 +jprt.my.windows.i586=${jprt.my.windows.i586.${jprt.tools.default.release}}
    8.25  
    8.26 -# Test targets in test/Makefile (some longer running tests only test c2)
    8.27 -jprt.make.rule.test.targets=    \
    8.28 -   *-product-*-jdk_beans1,      \
    8.29 -   *-product-*-jdk_beans2,      \
    8.30 -   *-product-*-jdk_beans3,      \
    8.31 -   *-product-*-jdk_io,          \
    8.32 -   *-product-*-jdk_lang,        \
    8.33 -   *-product-*-jdk_management1, \
    8.34 -   *-product-*-jdk_management2, \
    8.35 -   *-product-*-jdk_math,        \
    8.36 -   *-product-*-jdk_misc,        \
    8.37 -   *-product-*-jdk_net,         \
    8.38 -   *-product-*-jdk_nio1,        \
    8.39 -   *-product-*-jdk_nio2,        \
    8.40 -   *-product-*-jdk_nio3,        \
    8.41 -   *-product-*-jdk_security1,   \
    8.42 -   *-product-*-jdk_security2,   \
    8.43 -   *-product-*-jdk_security3,   \
    8.44 -   *-product-*-jdk_text,        \
    8.45 -   *-product-*-jdk_tools1,      \
    8.46 -   *-product-*-jdk_tools2,      \
    8.47 -   *-product-*-jdk_util
    8.48 +# Standard list of jprt build targets for this source tree
    8.49 +jprt.build.targets= 						\
    8.50 +    solaris_sparc_5.10-{product|fastdebug}, 			\
    8.51 +    solaris_sparcv9_5.10-{product|fastdebug}, 			\
    8.52 +    solaris_i586_5.10-{product|fastdebug}, 			\
    8.53 +    solaris_x64_5.10-{product|fastdebug}, 			\
    8.54 +    linux_i586_2.6-{product|fastdebug}, 			\
    8.55 +    linux_x64_2.6-{product|fastdebug}, 				\
    8.56 +    ${jprt.my.windows.i586}-{product|fastdebug}, 		\
    8.57 +    windows_x64_5.2-{product|fastdebug}
    8.58  
    8.59 -# Some of these are crashing Xvfb or windows manager, need dedicated DISPLAY per test batch
    8.60 -jprt2.make.rule.test.targets=    \
    8.61 -   *-product-*-jdk_awt,         \
    8.62 -   *-product-*-jdk_rmi,         \
    8.63 -   *-product-*-jdk_swing,       \
    8.64 +# Standard vm test target
    8.65 +jprt.test.targets=						\
    8.66 +    solaris_sparc_5.10-product-c1-jvm98, 			\
    8.67 +    solaris_sparcv9_5.10-product-c2-jvm98, 			\
    8.68 +    solaris_i586_5.10-product-c1-jvm98, 			\
    8.69 +    solaris_x64_5.10-product-c2-jvm98, 				\
    8.70 +    linux_i586_2.6-product-{c1|c2}-jvm98, 			\
    8.71 +    linux_x64_2.6-product-c2-jvm98, 				\
    8.72 +    ${jprt.my.windows.i586}-product-c1-jvm98, 			\
    8.73 +    windows_x64_5.2-product-c2-jvm98
    8.74 +
    8.75 +# User can select the test set with jprt submit "-testset name" option
    8.76 +jprt.my.test.set=${jprt.test.set}
    8.77 +
    8.78 +# Default jdk test targets in test/Makefile (no fastdebug & limited c2)
    8.79 +jprt.make.rule.default.test.targets=				\
    8.80 +    								\
    8.81 +    solaris_sparc_5.10-product-c1-jdk_beans1, 			\
    8.82 +    solaris_sparcv9_5.10-product-c2-jdk_beans1, 		\
    8.83 +    solaris_i586_5.10-product-c1-jdk_beans1, 			\
    8.84 +    solaris_x64_5.10-product-c2-jdk_beans1, 			\
    8.85 +    linux_i586_2.6-product-{c1|c2}-jdk_beans1, 			\
    8.86 +    linux_x64_2.6-product-c2-jdk_beans1, 			\
    8.87 +    ${jprt.my.windows.i586}-product-c1-jdk_beans1, 		\
    8.88 +    windows_x64_5.2-product-c2-jdk_beans1, 			\
    8.89 +    								\
    8.90 +    solaris_sparc_5.10-product-c1-jdk_io, 			\
    8.91 +    solaris_sparcv9_5.10-product-c2-jdk_io, 			\
    8.92 +    solaris_i586_5.10-product-c1-jdk_io, 			\
    8.93 +    solaris_x64_5.10-product-c2-jdk_io, 			\
    8.94 +    linux_i586_2.6-product-{c1|c2}-jdk_io, 			\
    8.95 +    linux_x64_2.6-product-c2-jdk_io, 				\
    8.96 +    ${jprt.my.windows.i586}-product-c1-jdk_io, 			\
    8.97 +    windows_x64_5.2-product-c2-jdk_io, 				\
    8.98 +    								\
    8.99 +    solaris_sparc_5.10-product-c1-jdk_lang, 			\
   8.100 +    solaris_sparcv9_5.10-product-c2-jdk_lang, 			\
   8.101 +    solaris_i586_5.10-product-c1-jdk_lang, 			\
   8.102 +    solaris_x64_5.10-product-c2-jdk_lang, 			\
   8.103 +    linux_i586_2.6-product-{c1|c2}-jdk_lang, 			\
   8.104 +    linux_x64_2.6-product-c2-jdk_lang, 				\
   8.105 +    ${jprt.my.windows.i586}-product-c1-jdk_lang, 		\
   8.106 +    windows_x64_5.2-product-c2-jdk_lang, 			\
   8.107 +    								\
   8.108 +    solaris_sparc_5.10-product-c1-jdk_math, 			\
   8.109 +    solaris_sparcv9_5.10-product-c2-jdk_math, 			\
   8.110 +    solaris_i586_5.10-product-c1-jdk_math, 			\
   8.111 +    solaris_x64_5.10-product-c2-jdk_math, 			\
   8.112 +    linux_i586_2.6-product-{c1|c2}-jdk_math, 			\
   8.113 +    linux_x64_2.6-product-c2-jdk_math, 				\
   8.114 +    ${jprt.my.windows.i586}-product-c1-jdk_math, 		\
   8.115 +    windows_x64_5.2-product-c2-jdk_math, 			\
   8.116 +    								\
   8.117 +    solaris_sparc_5.10-product-c1-jdk_misc, 			\
   8.118 +    solaris_sparcv9_5.10-product-c2-jdk_misc, 			\
   8.119 +    solaris_i586_5.10-product-c1-jdk_misc, 			\
   8.120 +    solaris_x64_5.10-product-c2-jdk_misc, 			\
   8.121 +    linux_i586_2.6-product-{c1|c2}-jdk_misc, 			\
   8.122 +    linux_x64_2.6-product-c2-jdk_misc, 				\
   8.123 +    ${jprt.my.windows.i586}-product-c1-jdk_misc, 		\
   8.124 +    windows_x64_5.2-product-c2-jdk_misc, 			\
   8.125 +    								\
   8.126 +    solaris_sparc_5.10-product-c1-jdk_net, 			\
   8.127 +    solaris_sparcv9_5.10-product-c2-jdk_net, 			\
   8.128 +    solaris_i586_5.10-product-c1-jdk_net, 			\
   8.129 +    solaris_x64_5.10-product-c2-jdk_net, 			\
   8.130 +    linux_i586_2.6-product-{c1|c2}-jdk_net, 			\
   8.131 +    linux_x64_2.6-product-c2-jdk_net, 				\
   8.132 +    ${jprt.my.windows.i586}-product-c1-jdk_net, 		\
   8.133 +    windows_x64_5.2-product-c2-jdk_net, 			\
   8.134 +    								\
   8.135 +    solaris_sparc_5.10-product-c1-jdk_nio1, 			\
   8.136 +    solaris_sparcv9_5.10-product-c2-jdk_nio1, 			\
   8.137 +    solaris_i586_5.10-product-c1-jdk_nio1, 			\
   8.138 +    solaris_x64_5.10-product-c2-jdk_nio1, 			\
   8.139 +    linux_i586_2.6-product-{c1|c2}-jdk_nio1, 			\
   8.140 +    linux_x64_2.6-product-c2-jdk_nio1, 				\
   8.141 +    ${jprt.my.windows.i586}-product-c1-jdk_nio1, 		\
   8.142 +    windows_x64_5.2-product-c2-jdk_nio1, 			\
   8.143 +    								\
   8.144 +    solaris_sparc_5.10-product-c1-jdk_nio2, 			\
   8.145 +    solaris_sparcv9_5.10-product-c2-jdk_nio2, 			\
   8.146 +    solaris_i586_5.10-product-c1-jdk_nio2, 			\
   8.147 +    solaris_x64_5.10-product-c2-jdk_nio2, 			\
   8.148 +    linux_i586_2.6-product-{c1|c2}-jdk_nio2, 			\
   8.149 +    linux_x64_2.6-product-c2-jdk_nio2, 				\
   8.150 +    ${jprt.my.windows.i586}-product-c1-jdk_nio2, 		\
   8.151 +    windows_x64_5.2-product-c2-jdk_nio2, 			\
   8.152 +    								\
   8.153 +    solaris_sparc_5.10-product-c1-jdk_nio3, 			\
   8.154 +    solaris_sparcv9_5.10-product-c2-jdk_nio3, 			\
   8.155 +    solaris_i586_5.10-product-c1-jdk_nio3, 			\
   8.156 +    solaris_x64_5.10-product-c2-jdk_nio3, 			\
   8.157 +    linux_i586_2.6-product-{c1|c2}-jdk_nio3, 			\
   8.158 +    linux_x64_2.6-product-c2-jdk_nio3, 				\
   8.159 +    ${jprt.my.windows.i586}-product-c1-jdk_nio3, 		\
   8.160 +    windows_x64_5.2-product-c2-jdk_nio3, 			\
   8.161 +    								\
   8.162 +    solaris_sparc_5.10-product-c1-jdk_security1, 		\
   8.163 +    solaris_sparcv9_5.10-product-c2-jdk_security1, 		\
   8.164 +    solaris_i586_5.10-product-c1-jdk_security1, 		\
   8.165 +    solaris_x64_5.10-product-c2-jdk_security1, 			\
   8.166 +    linux_i586_2.6-product-{c1|c2}-jdk_security1, 		\
   8.167 +    linux_x64_2.6-product-c2-jdk_security1, 			\
   8.168 +    ${jprt.my.windows.i586}-product-c1-jdk_security1, 		\
   8.169 +    windows_x64_5.2-product-c2-jdk_security1, 			\
   8.170 +    								\
   8.171 +    solaris_sparc_5.10-product-c1-jdk_text, 			\
   8.172 +    solaris_sparcv9_5.10-product-c2-jdk_text, 			\
   8.173 +    solaris_i586_5.10-product-c1-jdk_text, 			\
   8.174 +    solaris_x64_5.10-product-c2-jdk_text, 			\
   8.175 +    linux_i586_2.6-product-{c1|c2}-jdk_text, 			\
   8.176 +    linux_x64_2.6-product-c2-jdk_text, 				\
   8.177 +    ${jprt.my.windows.i586}-product-c1-jdk_text, 		\
   8.178 +    windows_x64_5.2-product-c2-jdk_text, 			\
   8.179 +    								\
   8.180 +    solaris_sparc_5.10-product-c1-jdk_tools1, 			\
   8.181 +    solaris_sparcv9_5.10-product-c2-jdk_tools1, 		\
   8.182 +    solaris_i586_5.10-product-c1-jdk_tools1, 			\
   8.183 +    solaris_x64_5.10-product-c2-jdk_tools1, 			\
   8.184 +    linux_i586_2.6-product-{c1|c2}-jdk_tools1, 			\
   8.185 +    linux_x64_2.6-product-c2-jdk_tools1, 			\
   8.186 +    ${jprt.my.windows.i586}-product-c1-jdk_tools1, 		\
   8.187 +    windows_x64_5.2-product-c2-jdk_tools1, 			\
   8.188 +    								\
   8.189 +    solaris_sparc_5.10-product-c1-jdk_util, 			\
   8.190 +    solaris_sparcv9_5.10-product-c2-jdk_util, 			\
   8.191 +    solaris_i586_5.10-product-c1-jdk_util, 			\
   8.192 +    solaris_x64_5.10-product-c2-jdk_util, 			\
   8.193 +    linux_i586_2.6-product-{c1|c2}-jdk_util, 			\
   8.194 +    linux_x64_2.6-product-c2-jdk_util, 				\
   8.195 +    ${jprt.my.windows.i586}-product-c1-jdk_util, 		\
   8.196 +    windows_x64_5.2-product-c2-jdk_util
   8.197 +
   8.198 +# All jdk test targets in test/Makefile (still no fastdebug & limited c2)
   8.199 +jprt.make.rule.all.test.targets=    				\
   8.200 +    								\
   8.201 +   ${jprt.make.rule.default.test.targets}, 			\
   8.202 +    								\
   8.203 +    solaris_sparc_5.10-product-c1-jdk_awt, 			\
   8.204 +    solaris_sparcv9_5.10-product-c2-jdk_awt, 			\
   8.205 +    solaris_i586_5.10-product-c1-jdk_awt, 			\
   8.206 +    solaris_x64_5.10-product-c2-jdk_awt, 			\
   8.207 +    linux_i586_2.6-product-{c1|c2}-jdk_awt, 			\
   8.208 +    linux_x64_2.6-product-c2-jdk_awt, 				\
   8.209 +    ${jprt.my.windows.i586}-product-c1-jdk_awt, 		\
   8.210 +    windows_x64_5.2-product-c2-jdk_awt, 			\
   8.211 +    								\
   8.212 +    solaris_sparc_5.10-product-c1-jdk_beans2, 			\
   8.213 +    solaris_sparcv9_5.10-product-c2-jdk_beans2, 		\
   8.214 +    solaris_i586_5.10-product-c1-jdk_beans2, 			\
   8.215 +    solaris_x64_5.10-product-c2-jdk_beans2, 			\
   8.216 +    linux_i586_2.6-product-{c1|c2}-jdk_beans2, 			\
   8.217 +    linux_x64_2.6-product-c2-jdk_beans2, 			\
   8.218 +    ${jprt.my.windows.i586}-product-c1-jdk_beans2, 		\
   8.219 +    windows_x64_5.2-product-c2-jdk_beans2, 			\
   8.220 +    								\
   8.221 +    solaris_sparc_5.10-product-c1-jdk_beans3, 			\
   8.222 +    solaris_sparcv9_5.10-product-c2-jdk_beans3, 		\
   8.223 +    solaris_i586_5.10-product-c1-jdk_beans3, 			\
   8.224 +    solaris_x64_5.10-product-c2-jdk_beans3, 			\
   8.225 +    linux_i586_2.6-product-{c1|c2}-jdk_beans3, 			\
   8.226 +    linux_x64_2.6-product-c2-jdk_beans3, 			\
   8.227 +    ${jprt.my.windows.i586}-product-c1-jdk_beans3, 		\
   8.228 +    windows_x64_5.2-product-c2-jdk_beans3, 			\
   8.229 +    								\
   8.230 +    solaris_sparc_5.10-product-c1-jdk_management1, 		\
   8.231 +    solaris_sparcv9_5.10-product-c2-jdk_management1, 		\
   8.232 +    solaris_i586_5.10-product-c1-jdk_management1, 		\
   8.233 +    solaris_x64_5.10-product-c2-jdk_management1, 		\
   8.234 +    linux_i586_2.6-product-{c1|c2}-jdk_management1, 		\
   8.235 +    linux_x64_2.6-product-c2-jdk_management1, 			\
   8.236 +    ${jprt.my.windows.i586}-product-c1-jdk_management1, 	\
   8.237 +    windows_x64_5.2-product-c2-jdk_management1, 		\
   8.238 +    								\
   8.239 +    solaris_sparc_5.10-product-c1-jdk_management2, 		\
   8.240 +    solaris_sparcv9_5.10-product-c2-jdk_management2, 		\
   8.241 +    solaris_i586_5.10-product-c1-jdk_management2, 		\
   8.242 +    solaris_x64_5.10-product-c2-jdk_management2, 		\
   8.243 +    linux_i586_2.6-product-{c1|c2}-jdk_management2, 		\
   8.244 +    linux_x64_2.6-product-c2-jdk_management2, 			\
   8.245 +    ${jprt.my.windows.i586}-product-c1-jdk_management2, 	\
   8.246 +    windows_x64_5.2-product-c2-jdk_management2, 		\
   8.247 +    								\
   8.248 +    solaris_sparc_5.10-product-c1-jdk_rmi, 			\
   8.249 +    solaris_sparcv9_5.10-product-c2-jdk_rmi, 			\
   8.250 +    solaris_i586_5.10-product-c1-jdk_rmi, 			\
   8.251 +    solaris_x64_5.10-product-c2-jdk_rmi, 			\
   8.252 +    linux_i586_2.6-product-{c1|c2}-jdk_rmi, 			\
   8.253 +    linux_x64_2.6-product-c2-jdk_rmi, 				\
   8.254 +    ${jprt.my.windows.i586}-product-c1-jdk_rmi, 		\
   8.255 +    windows_x64_5.2-product-c2-jdk_rmi, 			\
   8.256 +    								\
   8.257 +    solaris_sparc_5.10-product-c1-jdk_security2, 		\
   8.258 +    solaris_sparcv9_5.10-product-c2-jdk_security2, 		\
   8.259 +    solaris_i586_5.10-product-c1-jdk_security2, 		\
   8.260 +    solaris_x64_5.10-product-c2-jdk_security2, 			\
   8.261 +    linux_i586_2.6-product-{c1|c2}-jdk_security2, 		\
   8.262 +    linux_x64_2.6-product-c2-jdk_security2, 			\
   8.263 +    ${jprt.my.windows.i586}-product-c1-jdk_security2, 		\
   8.264 +    windows_x64_5.2-product-c2-jdk_security2, 			\
   8.265 +    								\
   8.266 +    solaris_sparc_5.10-product-c1-jdk_security3, 		\
   8.267 +    solaris_sparcv9_5.10-product-c2-jdk_security3, 		\
   8.268 +    solaris_i586_5.10-product-c1-jdk_security3, 		\
   8.269 +    solaris_x64_5.10-product-c2-jdk_security3, 			\
   8.270 +    linux_i586_2.6-product-{c1|c2}-jdk_security3, 		\
   8.271 +    linux_x64_2.6-product-c2-jdk_security3, 			\
   8.272 +    ${jprt.my.windows.i586}-product-c1-jdk_security3, 		\
   8.273 +    windows_x64_5.2-product-c2-jdk_security3, 			\
   8.274 +    								\
   8.275 +    solaris_sparc_5.10-product-c1-jdk_swing, 			\
   8.276 +    solaris_sparcv9_5.10-product-c2-jdk_swing, 			\
   8.277 +    solaris_i586_5.10-product-c1-jdk_swing, 			\
   8.278 +    solaris_x64_5.10-product-c2-jdk_swing, 			\
   8.279 +    linux_i586_2.6-product-{c1|c2}-jdk_swing, 			\
   8.280 +    linux_x64_2.6-product-c2-jdk_swing, 			\
   8.281 +    ${jprt.my.windows.i586}-product-c1-jdk_swing, 		\
   8.282 +    windows_x64_5.2-product-c2-jdk_swing, 			\
   8.283 +    								\
   8.284 +    solaris_sparc_5.10-product-c1-jdk_tools2, 			\
   8.285 +    solaris_sparcv9_5.10-product-c2-jdk_tools2, 		\
   8.286 +    solaris_i586_5.10-product-c1-jdk_tools2, 			\
   8.287 +    solaris_x64_5.10-product-c2-jdk_tools2, 			\
   8.288 +    linux_i586_2.6-product-{c1|c2}-jdk_tools2, 			\
   8.289 +    linux_x64_2.6-product-c2-jdk_tools2, 			\
   8.290 +    ${jprt.my.windows.i586}-product-c1-jdk_tools2, 		\
   8.291 +    windows_x64_5.2-product-c2-jdk_tools2
   8.292 +
   8.293 +# Select list to use (allow for testset to be empty too)
   8.294 +jprt.make.rule..test.targets=${jprt.make.rule.default.test.targets} 
   8.295 +jprt.make.rule.test.targets=${jprt.make.rule.${jprt.my.test.set}.test.targets} 
   8.296  
   8.297  # Directories to be excluded from the source bundles
   8.298  jprt.bundle.exclude.src.dirs=build dist webrev
     9.1 --- a/make/mkdemo/Makefile	Thu Oct 07 15:12:19 2010 -0700
     9.2 +++ b/make/mkdemo/Makefile	Tue Oct 12 12:51:48 2010 -0700
     9.3 @@ -31,7 +31,7 @@
     9.4  PRODUCT = demos
     9.5  include $(BUILDDIR)/common/Defs.gmk
     9.6  
     9.7 -SUBDIRS            = jni
     9.8 +SUBDIRS            = jni nio
     9.9  SUBDIRS_desktop    = applets jfc
    9.10  SUBDIRS_management = management
    9.11  SUBDIRS_misc       = scripting
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/make/mkdemo/nio/Makefile	Tue Oct 12 12:51:48 2010 -0700
    10.3 @@ -0,0 +1,39 @@
    10.4 +#
    10.5 +# Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
    10.6 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    10.7 +#
    10.8 +# This code is free software; you can redistribute it and/or modify it
    10.9 +# under the terms of the GNU General Public License version 2 only, as
   10.10 +# published by the Free Software Foundation.  Oracle designates this
   10.11 +# particular file as subject to the "Classpath" exception as provided
   10.12 +# by Oracle in the LICENSE file that accompanied this code.
   10.13 +#
   10.14 +# This code is distributed in the hope that it will be useful, but WITHOUT
   10.15 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   10.16 +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   10.17 +# version 2 for more details (a copy is included in the LICENSE file that
   10.18 +# accompanied this code).
   10.19 +#
   10.20 +# You should have received a copy of the GNU General Public License version
   10.21 +# 2 along with this work; if not, write to the Free Software Foundation,
   10.22 +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   10.23 +#
   10.24 +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   10.25 +# or visit www.oracle.com if you need additional information or have any
   10.26 +# questions.
   10.27 +#
   10.28 +
   10.29 +#
   10.30 +# Makefile for building the jfc demos
   10.31 +#
   10.32 +
   10.33 +BUILDDIR = ../..
   10.34 +PRODUCT = demos
   10.35 +include $(BUILDDIR)/common/Defs.gmk
   10.36 +
   10.37 +SUBDIRS = zipfs
   10.38 +include $(BUILDDIR)/common/Subdirs.gmk
   10.39 +
   10.40 +all build clean clobber::
   10.41 +	$(SUBDIRS-loop)
   10.42 +
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/make/mkdemo/nio/zipfs/Makefile	Tue Oct 12 12:51:48 2010 -0700
    11.3 @@ -0,0 +1,44 @@
    11.4 +#
    11.5 +# Copyright (c) 1997, 2002, Oracle and/or its affiliates. All rights reserved.
    11.6 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    11.7 +#
    11.8 +# This code is free software; you can redistribute it and/or modify it
    11.9 +# under the terms of the GNU General Public License version 2 only, as
   11.10 +# published by the Free Software Foundation.  Oracle designates this
   11.11 +# particular file as subject to the "Classpath" exception as provided
   11.12 +# by Oracle in the LICENSE file that accompanied this code.
   11.13 +#
   11.14 +# This code is distributed in the hope that it will be useful, but WITHOUT
   11.15 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   11.16 +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   11.17 +# version 2 for more details (a copy is included in the LICENSE file that
   11.18 +# accompanied this code).
   11.19 +#
   11.20 +# You should have received a copy of the GNU General Public License version
   11.21 +# 2 along with this work; if not, write to the Free Software Foundation,
   11.22 +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   11.23 +#
   11.24 +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   11.25 +# or visit www.oracle.com if you need additional information or have any
   11.26 +# questions.
   11.27 +#
   11.28 +
   11.29 +#
   11.30 +# Makefile to build the ZipFileSystem demo.
   11.31 +#
   11.32 +
   11.33 +BUILDDIR = ../../..
   11.34 +PRODUCT = demo/zipfs
   11.35 +DEMONAME = zipfs
   11.36 +include $(BUILDDIR)/common/Defs.gmk
   11.37 +
   11.38 +DEMO_ROOT       = $(SHARE_SRC)/demo/nio/$(DEMONAME)
   11.39 +DEMO_TOPFILES   = ./README.txt
   11.40 +DEMO_SRCDIR     = $(DEMO_ROOT)
   11.41 +DEMO_DESTDIR    = $(DEMODIR)/nio/$(DEMONAME)
   11.42 +
   11.43 +#
   11.44 +# Demo jar building rules.
   11.45 +#
   11.46 +include $(BUILDDIR)/common/Demo.gmk
   11.47 +
    12.1 --- a/make/sun/cmm/lcms/Makefile	Thu Oct 07 15:12:19 2010 -0700
    12.2 +++ b/make/sun/cmm/lcms/Makefile	Tue Oct 12 12:51:48 2010 -0700
    12.3 @@ -80,7 +80,12 @@
    12.4  vpath %.c   $(SHARE_SRC)/native/sun/java2d
    12.5  
    12.6  ifeq ($(PLATFORM), windows)
    12.7 -OTHER_CFLAGS += -DCMS_IS_WINDOWS_ -Dsqrtf=sqrt
    12.8 +OTHER_CFLAGS += -DCMS_IS_WINDOWS_
    12.9 +
   12.10 +ifeq ($(COMPILER_VERSION), VS2003)
   12.11 +OTHER_CFLAGS += -Dsqrtf=sqrt
   12.12 +endif
   12.13 +
   12.14  OTHER_LDLIBS = $(OBJDIR)/../../../sun.awt/awt/$(OBJDIRNAME)/awt.lib
   12.15  OTHER_INCLUDES += -I$(SHARE_SRC)/native/sun/java2d \
   12.16                    -I$(SHARE_SRC)/native/sun/awt/debug
    13.1 --- a/src/share/classes/com/sun/rowset/CachedRowSetImpl.java	Thu Oct 07 15:12:19 2010 -0700
    13.2 +++ b/src/share/classes/com/sun/rowset/CachedRowSetImpl.java	Tue Oct 12 12:51:48 2010 -0700
    13.3 @@ -525,7 +525,7 @@
    13.4  
    13.5          iMatchColumns = new Vector(10);
    13.6          for(int i = 0; i < 10 ; i++) {
    13.7 -           iMatchColumns.add(i,new Integer(-1));
    13.8 +           iMatchColumns.add(i,Integer.valueOf(-1));
    13.9          }
   13.10  
   13.11          strMatchColumns = new Vector(10);
   13.12 @@ -889,7 +889,12 @@
   13.13                      success = false;
   13.14                  } else {
   13.15                      tWriter = (TransactionalWriter)rowSetWriter;
   13.16 -                    ((CachedRowSetWriter)tWriter).commit(this, updateOnInsert);
   13.17 +                    if (tWriter instanceof CachedRowSetWriter) {
   13.18 +                        ((CachedRowSetWriter)tWriter).commit(this, updateOnInsert);
   13.19 +                    } else {
   13.20 +                        tWriter.commit();
   13.21 +                    }
   13.22 +
   13.23                      success = true;
   13.24                  }
   13.25              }
   13.26 @@ -1294,7 +1299,7 @@
   13.27          tMap = new TreeMap();
   13.28  
   13.29          for (int i = 0; i<numRows; i++) {
   13.30 -            tMap.put(new Integer(i), rvh.get(i));
   13.31 +            tMap.put(Integer.valueOf(i), rvh.get(i));
   13.32          }
   13.33  
   13.34          return (tMap.values());
   13.35 @@ -1806,7 +1811,7 @@
   13.36              return (byte)0;
   13.37          }
   13.38          try {
   13.39 -            return ((new Byte(value.toString())).byteValue());
   13.40 +            return ((Byte.valueOf(value.toString())).byteValue());
   13.41          } catch (NumberFormatException ex) {
   13.42              throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.bytefail").toString(),
   13.43                    new Object[] {value.toString().trim(), columnIndex}));
   13.44 @@ -1850,7 +1855,7 @@
   13.45          }
   13.46  
   13.47          try {
   13.48 -            return ((new Short(value.toString().trim())).shortValue());
   13.49 +            return ((Short.valueOf(value.toString().trim())).shortValue());
   13.50          } catch (NumberFormatException ex) {
   13.51              throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.shortfail").toString(),
   13.52                    new Object[] {value.toString().trim(), columnIndex}));
   13.53 @@ -1893,7 +1898,7 @@
   13.54          }
   13.55  
   13.56          try {
   13.57 -            return ((new Integer(value.toString().trim())).intValue());
   13.58 +            return ((Integer.valueOf(value.toString().trim())).intValue());
   13.59          } catch (NumberFormatException ex) {
   13.60              throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.intfail").toString(),
   13.61                    new Object[] {value.toString().trim(), columnIndex}));
   13.62 @@ -1936,7 +1941,7 @@
   13.63              return (long)0;
   13.64          }
   13.65          try {
   13.66 -            return ((new Long(value.toString().trim())).longValue());
   13.67 +            return ((Long.valueOf(value.toString().trim())).longValue());
   13.68          } catch (NumberFormatException ex) {
   13.69              throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.longfail").toString(),
   13.70                    new Object[] {value.toString().trim(), columnIndex}));
   13.71 @@ -4014,18 +4019,18 @@
   13.72          try {
   13.73              switch (trgType) {
   13.74                  case java.sql.Types.BIT:
   13.75 -                    Integer i = new Integer(srcObj.toString().trim());
   13.76 -                    return i.equals(new Integer((int)0)) ?
   13.77 -                    new Boolean(false) :
   13.78 -                        new Boolean(true);
   13.79 +                    Integer i = Integer.valueOf(srcObj.toString().trim());
   13.80 +                    return i.equals(Integer.valueOf((int)0)) ?
   13.81 +                    Boolean.valueOf(false) :
   13.82 +                        Boolean.valueOf(true);
   13.83                  case java.sql.Types.TINYINT:
   13.84 -                    return new Byte(srcObj.toString().trim());
   13.85 +                    return Byte.valueOf(srcObj.toString().trim());
   13.86                  case java.sql.Types.SMALLINT:
   13.87 -                    return new Short(srcObj.toString().trim());
   13.88 +                    return Short.valueOf(srcObj.toString().trim());
   13.89                  case java.sql.Types.INTEGER:
   13.90 -                    return new Integer(srcObj.toString().trim());
   13.91 +                    return Integer.valueOf(srcObj.toString().trim());
   13.92                  case java.sql.Types.BIGINT:
   13.93 -                    return new Long(srcObj.toString().trim());
   13.94 +                    return Long.valueOf(srcObj.toString().trim());
   13.95                  case java.sql.Types.NUMERIC:
   13.96                  case java.sql.Types.DECIMAL:
   13.97                      return new BigDecimal(srcObj.toString().trim());
   13.98 @@ -4037,7 +4042,7 @@
   13.99                  case java.sql.Types.CHAR:
  13.100                  case java.sql.Types.VARCHAR:
  13.101                  case java.sql.Types.LONGVARCHAR:
  13.102 -                    return new String(srcObj.toString());
  13.103 +                    return srcObj.toString();
  13.104                  default:
  13.105                      throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()+ trgType);
  13.106              }
  13.107 @@ -4134,7 +4139,7 @@
  13.108                  case java.sql.Types.CHAR:
  13.109                  case java.sql.Types.VARCHAR:
  13.110                  case java.sql.Types.LONGVARCHAR:
  13.111 -                    return new String(srcObj.toString());
  13.112 +                    return srcObj.toString();
  13.113                  default:
  13.114                      throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());
  13.115              }
  13.116 @@ -4181,12 +4186,12 @@
  13.117          try {
  13.118              switch (trgType) {
  13.119                  case java.sql.Types.BIT:
  13.120 -                    Integer i = new Integer(srcObj.toString().trim());
  13.121 -                    return i.equals(new Integer((int)0)) ?
  13.122 -                    new Boolean(false) :
  13.123 -                        new Boolean(true);
  13.124 +                    Integer i = Integer.valueOf(srcObj.toString().trim());
  13.125 +                    return i.equals(Integer.valueOf((int)0)) ?
  13.126 +                    Boolean.valueOf(false) :
  13.127 +                        Boolean.valueOf(true);
  13.128                  case java.sql.Types.BOOLEAN:
  13.129 -                    return new Boolean(srcObj.toString().trim());
  13.130 +                    return Boolean.valueOf(srcObj.toString().trim());
  13.131                  default:
  13.132                      throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()+ trgType);
  13.133              }
  13.134 @@ -4260,7 +4265,7 @@
  13.135          checkIndex(columnIndex);
  13.136          // make sure the cursor is on a valid row
  13.137          checkCursor();
  13.138 -        Object obj = convertBoolean(new Boolean(x),
  13.139 +        Object obj = convertBoolean(Boolean.valueOf(x),
  13.140          java.sql.Types.BIT,
  13.141          RowSetMD.getColumnType(columnIndex));
  13.142  
  13.143 @@ -4296,7 +4301,7 @@
  13.144          // make sure the cursor is on a valid row
  13.145          checkCursor();
  13.146  
  13.147 -        Object obj = convertNumeric(new Byte(x),
  13.148 +        Object obj = convertNumeric(Byte.valueOf(x),
  13.149          java.sql.Types.TINYINT,
  13.150          RowSetMD.getColumnType(columnIndex));
  13.151  
  13.152 @@ -4332,7 +4337,7 @@
  13.153          // make sure the cursor is on a valid row
  13.154          checkCursor();
  13.155  
  13.156 -        Object obj = convertNumeric(new Short(x),
  13.157 +        Object obj = convertNumeric(Short.valueOf(x),
  13.158          java.sql.Types.SMALLINT,
  13.159          RowSetMD.getColumnType(columnIndex));
  13.160  
  13.161 @@ -4367,7 +4372,7 @@
  13.162          checkIndex(columnIndex);
  13.163          // make sure the cursor is on a valid row
  13.164          checkCursor();
  13.165 -        Object obj = convertNumeric(new Integer(x),
  13.166 +        Object obj = convertNumeric(Integer.valueOf(x),
  13.167          java.sql.Types.INTEGER,
  13.168          RowSetMD.getColumnType(columnIndex));
  13.169  
  13.170 @@ -4403,7 +4408,7 @@
  13.171          // make sure the cursor is on a valid row
  13.172          checkCursor();
  13.173  
  13.174 -        Object obj = convertNumeric(new Long(x),
  13.175 +        Object obj = convertNumeric(Long.valueOf(x),
  13.176          java.sql.Types.BIGINT,
  13.177          RowSetMD.getColumnType(columnIndex));
  13.178  
  13.179 @@ -6429,7 +6434,7 @@
  13.180          if (tabName == null)
  13.181              throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.tablename").toString());
  13.182          else
  13.183 -            tableName = new String(tabName);
  13.184 +            tableName = tabName;
  13.185      }
  13.186  
  13.187      /**
  13.188 @@ -6940,7 +6945,7 @@
  13.189           }
  13.190  
  13.191           for( int i = 0;i < columnIdxes.length ;i++) {
  13.192 -            iMatchColumns.set(i,new Integer(-1));
  13.193 +            iMatchColumns.set(i,Integer.valueOf(-1));
  13.194           }
  13.195      }
  13.196  
  13.197 @@ -7049,7 +7054,7 @@
  13.198             }
  13.199          }
  13.200          for(int i = 0 ;i < columnIdxes.length; i++) {
  13.201 -           iMatchColumns.add(i,new Integer(columnIdxes[i]));
  13.202 +           iMatchColumns.add(i,Integer.valueOf(columnIdxes[i]));
  13.203          }
  13.204      }
  13.205  
  13.206 @@ -7104,7 +7109,7 @@
  13.207              throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols1").toString());
  13.208          } else {
  13.209              // set iMatchColumn
  13.210 -            iMatchColumns.set(0, new Integer(columnIdx));
  13.211 +            iMatchColumns.set(0, Integer.valueOf(columnIdx));
  13.212              //strMatchColumn = null;
  13.213          }
  13.214      }
  13.215 @@ -7126,7 +7131,7 @@
  13.216       */
  13.217      public void setMatchColumn(String columnName) throws SQLException {
  13.218          // validate, if col is ok to be set
  13.219 -        if(columnName.equals(null) || ((columnName = columnName.trim()) == "" )) {
  13.220 +        if(columnName == null || (columnName= columnName.trim()).equals("") ) {
  13.221              throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols2").toString());
  13.222          } else {
  13.223              // set strMatchColumn
  13.224 @@ -7151,13 +7156,13 @@
  13.225       */
  13.226      public void unsetMatchColumn(int columnIdx) throws SQLException {
  13.227          // check if we are unsetting the SAME column
  13.228 -        if(! iMatchColumns.get(0).equals(new Integer(columnIdx) )  ) {
  13.229 +        if(! iMatchColumns.get(0).equals(Integer.valueOf(columnIdx) )  ) {
  13.230              throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch").toString());
  13.231          } else if(strMatchColumns.get(0) != null) {
  13.232              throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch1").toString());
  13.233          } else {
  13.234                  // that is, we are unsetting it.
  13.235 -               iMatchColumns.set(0, new Integer(-1));
  13.236 +               iMatchColumns.set(0, Integer.valueOf(-1));
  13.237          }
  13.238      }
  13.239  
    14.1 --- a/src/share/classes/com/sun/rowset/FilteredRowSetImpl.java	Thu Oct 07 15:12:19 2010 -0700
    14.2 +++ b/src/share/classes/com/sun/rowset/FilteredRowSetImpl.java	Tue Oct 12 12:51:48 2010 -0700
    14.3 @@ -499,7 +499,7 @@
    14.4  
    14.5       if(onInsertRow) {
    14.6          if(p != null) {
    14.7 -           bool = p.evaluate(new Integer(x),columnIndex);
    14.8 +           bool = p.evaluate(Integer.valueOf(x),columnIndex);
    14.9  
   14.10             if(!bool) {
   14.11                throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
   14.12 @@ -566,7 +566,7 @@
   14.13  
   14.14        if(onInsertRow) {
   14.15           if(p != null) {
   14.16 -            bool = p.evaluate(new Boolean(x) , columnIndex);
   14.17 +            bool = p.evaluate(Boolean.valueOf(x) , columnIndex);
   14.18  
   14.19              if(!bool) {
   14.20                 throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
   14.21 @@ -634,7 +634,7 @@
   14.22  
   14.23        if(onInsertRow) {
   14.24           if(p != null) {
   14.25 -            bool = p.evaluate(new Byte(x),columnIndex);
   14.26 +            bool = p.evaluate(Byte.valueOf(x),columnIndex);
   14.27  
   14.28              if(!bool) {
   14.29                  throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
   14.30 @@ -703,7 +703,7 @@
   14.31  
   14.32        if(onInsertRow) {
   14.33           if(p != null) {
   14.34 -            bool = p.evaluate(new Short(x), columnIndex);
   14.35 +            bool = p.evaluate(Short.valueOf(x), columnIndex);
   14.36  
   14.37              if(!bool) {
   14.38                 throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
   14.39 @@ -771,7 +771,7 @@
   14.40  
   14.41        if(onInsertRow) {
   14.42           if(p != null) {
   14.43 -            bool = p.evaluate(new Long(x), columnIndex);
   14.44 +            bool = p.evaluate(Long.valueOf(x), columnIndex);
   14.45  
   14.46              if(!bool) {
   14.47                 throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
   14.48 @@ -1106,12 +1106,12 @@
   14.49     public void updateBytes(int columnIndex , byte []x) throws SQLException {
   14.50  
   14.51        boolean bool;
   14.52 -      String val = new String();
   14.53 +      String val = "";
   14.54  
   14.55        Byte [] obj_arr = new Byte[x.length];
   14.56  
   14.57        for(int i = 0; i < x.length; i++) {
   14.58 -         obj_arr[i] = new Byte(x[i]);
   14.59 +         obj_arr[i] = Byte.valueOf(x[i]);
   14.60           val = val.concat(obj_arr[i].toString());
   14.61       }
   14.62  
    15.1 --- a/src/share/classes/com/sun/rowset/JdbcRowSetImpl.java	Thu Oct 07 15:12:19 2010 -0700
    15.2 +++ b/src/share/classes/com/sun/rowset/JdbcRowSetImpl.java	Tue Oct 12 12:51:48 2010 -0700
    15.3 @@ -215,7 +215,7 @@
    15.4  
    15.5          iMatchColumns = new Vector(10);
    15.6          for(int i = 0; i < 10 ; i++) {
    15.7 -           iMatchColumns.add(i,new Integer(-1));
    15.8 +           iMatchColumns.add(i,Integer.valueOf(-1));
    15.9          }
   15.10  
   15.11          strMatchColumns = new Vector(10);
   15.12 @@ -288,7 +288,7 @@
   15.13  
   15.14          iMatchColumns = new Vector(10);
   15.15          for(int i = 0; i < 10 ; i++) {
   15.16 -           iMatchColumns.add(i,new Integer(-1));
   15.17 +           iMatchColumns.add(i,Integer.valueOf(-1));
   15.18          }
   15.19  
   15.20          strMatchColumns = new Vector(10);
   15.21 @@ -375,7 +375,7 @@
   15.22  
   15.23          iMatchColumns = new Vector(10);
   15.24          for(int i = 0; i < 10 ; i++) {
   15.25 -           iMatchColumns.add(i,new Integer(-1));
   15.26 +           iMatchColumns.add(i,Integer.valueOf(-1));
   15.27          }
   15.28  
   15.29          strMatchColumns = new Vector(10);
   15.30 @@ -465,7 +465,7 @@
   15.31  
   15.32          iMatchColumns = new Vector(10);
   15.33          for(int i = 0; i < 10 ; i++) {
   15.34 -           iMatchColumns.add(i,new Integer(-1));
   15.35 +           iMatchColumns.add(i,Integer.valueOf(-1));
   15.36          }
   15.37  
   15.38          strMatchColumns = new Vector(10);
   15.39 @@ -3754,7 +3754,7 @@
   15.40           }
   15.41  
   15.42           for( int i = 0;i < columnIdxes.length ;i++) {
   15.43 -            iMatchColumns.set(i,new Integer(-1));
   15.44 +            iMatchColumns.set(i,Integer.valueOf(-1));
   15.45           }
   15.46      }
   15.47  
   15.48 @@ -3863,7 +3863,7 @@
   15.49             }
   15.50          }
   15.51          for(int i = 0 ;i < columnIdxes.length; i++) {
   15.52 -           iMatchColumns.add(i,new Integer(columnIdxes[i]));
   15.53 +           iMatchColumns.add(i,Integer.valueOf(columnIdxes[i]));
   15.54          }
   15.55      }
   15.56  
   15.57 @@ -3918,7 +3918,7 @@
   15.58              throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.matchcols1").toString());
   15.59          } else {
   15.60              // set iMatchColumn
   15.61 -            iMatchColumns.set(0, new Integer(columnIdx));
   15.62 +            iMatchColumns.set(0, Integer.valueOf(columnIdx));
   15.63              //strMatchColumn = null;
   15.64          }
   15.65      }
   15.66 @@ -3940,7 +3940,7 @@
   15.67       */
   15.68      public void setMatchColumn(String columnName) throws SQLException {
   15.69          // validate, if col is ok to be set
   15.70 -        if(columnName.equals(null) || ((columnName = columnName.trim()) == "" )) {
   15.71 +        if(columnName == null || (columnName= columnName.trim()).equals("")) {
   15.72              throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.matchcols2").toString());
   15.73          } else {
   15.74              // set strMatchColumn
   15.75 @@ -3965,13 +3965,13 @@
   15.76       */
   15.77      public void unsetMatchColumn(int columnIdx) throws SQLException {
   15.78          // check if we are unsetting the SAME column
   15.79 -        if(! iMatchColumns.get(0).equals(new Integer(columnIdx) )  ) {
   15.80 +        if(! iMatchColumns.get(0).equals(Integer.valueOf(columnIdx) )  ) {
   15.81              throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.unsetmatch").toString());
   15.82          } else if(strMatchColumns.get(0) != null) {
   15.83              throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.usecolname").toString());
   15.84          } else {
   15.85                  // that is, we are unsetting it.
   15.86 -               iMatchColumns.set(0, new Integer(-1));
   15.87 +               iMatchColumns.set(0, Integer.valueOf(-1));
   15.88          }
   15.89      }
   15.90  
    16.1 --- a/src/share/classes/com/sun/rowset/JoinRowSetImpl.java	Thu Oct 07 15:12:19 2010 -0700
    16.2 +++ b/src/share/classes/com/sun/rowset/JoinRowSetImpl.java	Tue Oct 12 12:51:48 2010 -0700
    16.3 @@ -33,6 +33,8 @@
    16.4  import java.util.*;
    16.5  
    16.6  import javax.sql.rowset.*;
    16.7 +import javax.sql.rowset.spi.SyncProvider;
    16.8 +import javax.sql.rowset.spi.SyncProviderException;
    16.9  
   16.10  /**
   16.11   * The standard implementation of the <code>JoinRowSet</code>
   16.12 @@ -550,7 +552,7 @@
   16.13                 // This 'if' will be removed after all joins are implemented.
   16.14                 throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.notsupported").toString());
   16.15             } else {
   16.16 -              Integer Intgr = new Integer(JoinRowSet.INNER_JOIN);
   16.17 +              Integer Intgr = Integer.valueOf(JoinRowSet.INNER_JOIN);
   16.18                vecJoinType.add(Intgr);
   16.19             }
   16.20         } else {
   16.21 @@ -874,8 +876,8 @@
   16.22  
   16.23         String strWhereClause = "Select ";
   16.24         String whereClause;
   16.25 -       String tabName= null;
   16.26 -       String strTabName = null;
   16.27 +       String tabName= "";
   16.28 +       String strTabName = "";
   16.29         int sz,cols;
   16.30         int j;
   16.31         CachedRowSetImpl crs;
   16.32 @@ -889,8 +891,6 @@
   16.33         // tableNameX.(rowsetX.getMatchColumnName()) ==
   16.34         // tableNameZ.(rowsetZ.getMatchColumnName()));
   16.35  
   16.36 -       tabName = new String();
   16.37 -       strTabName  = new String();
   16.38         sz = vecRowSetsInJOIN.size();
   16.39         for(int i=0;i<sz; i++) {
   16.40            crs = (CachedRowSetImpl)vecRowSetsInJOIN.get(i);
   16.41 @@ -4311,6 +4311,27 @@
   16.42           return crsInternal.createCopySchema();
   16.43       }
   16.44  
   16.45 +     /**
   16.46 +      * {@inheritDoc}
   16.47 +      */
   16.48 +     public void setSyncProvider(String providerStr) throws SQLException {
   16.49 +         crsInternal.setSyncProvider(providerStr);
   16.50 +     }
   16.51 +
   16.52 +     /**
   16.53 +      * {@inheritDoc}
   16.54 +      */
   16.55 +     public void acceptChanges() throws SyncProviderException {
   16.56 +         crsInternal.acceptChanges();
   16.57 +     }
   16.58 +
   16.59 +     /**
   16.60 +      * {@inheritDoc}
   16.61 +      */
   16.62 +     public SyncProvider getSyncProvider() throws SQLException {
   16.63 +        return crsInternal.getSyncProvider();
   16.64 +     }
   16.65 +
   16.66      /**
   16.67       * This method re populates the resBundle
   16.68       * during the deserialization process
    17.1 --- a/src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java	Thu Oct 07 15:12:19 2010 -0700
    17.2 +++ b/src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java	Tue Oct 12 12:51:48 2010 -0700
    17.3 @@ -338,11 +338,11 @@
    17.4              if (crs.rowDeleted()) {
    17.5                  // The row has been deleted.
    17.6                  if (conflict = (deleteOriginalRow(crs, this.crsResolve)) == true) {
    17.7 -                       status.add(rows, new Integer(SyncResolver.DELETE_ROW_CONFLICT));
    17.8 +                       status.add(rows, Integer.valueOf(SyncResolver.DELETE_ROW_CONFLICT));
    17.9                  } else {
   17.10                        // delete happened without any occurrence of conflicts
   17.11                        // so update status accordingly
   17.12 -                       status.add(rows, new Integer(SyncResolver.NO_ROW_CONFLICT));
   17.13 +                       status.add(rows, Integer.valueOf(SyncResolver.NO_ROW_CONFLICT));
   17.14                  }
   17.15  
   17.16             } else if (crs.rowInserted()) {
   17.17 @@ -350,20 +350,20 @@
   17.18  
   17.19                  pstmtIns = con.prepareStatement(insertCmd);
   17.20                  if ( (conflict = insertNewRow(crs, pstmtIns, this.crsResolve)) == true) {
   17.21 -                          status.add(rows, new Integer(SyncResolver.INSERT_ROW_CONFLICT));
   17.22 +                          status.add(rows, Integer.valueOf(SyncResolver.INSERT_ROW_CONFLICT));
   17.23                  } else {
   17.24                        // insert happened without any occurrence of conflicts
   17.25                        // so update status accordingly
   17.26 -                       status.add(rows, new Integer(SyncResolver.NO_ROW_CONFLICT));
   17.27 +                       status.add(rows, Integer.valueOf(SyncResolver.NO_ROW_CONFLICT));
   17.28                  }
   17.29              } else  if (crs.rowUpdated()) {
   17.30                    // The row has been updated.
   17.31                         if ( conflict = (updateOriginalRow(crs)) == true) {
   17.32 -                             status.add(rows, new Integer(SyncResolver.UPDATE_ROW_CONFLICT));
   17.33 +                             status.add(rows, Integer.valueOf(SyncResolver.UPDATE_ROW_CONFLICT));
   17.34                 } else {
   17.35                        // update happened without any occurrence of conflicts
   17.36                        // so update status accordingly
   17.37 -                      status.add(rows, new Integer(SyncResolver.NO_ROW_CONFLICT));
   17.38 +                      status.add(rows, Integer.valueOf(SyncResolver.NO_ROW_CONFLICT));
   17.39                 }
   17.40  
   17.41              } else {
   17.42 @@ -375,7 +375,7 @@
   17.43                  *  that is fine.
   17.44                  **/
   17.45                  int icolCount = crs.getMetaData().getColumnCount();
   17.46 -                status.add(rows, new Integer(SyncResolver.NO_ROW_CONFLICT));
   17.47 +                status.add(rows, Integer.valueOf(SyncResolver.NO_ROW_CONFLICT));
   17.48  
   17.49                  this.crsResolve.moveToInsertRow();
   17.50                  for(int cols=0;cols<iColCount;cols++) {
   17.51 @@ -398,7 +398,7 @@
   17.52        boolean boolConf = false;
   17.53        for (int j=1;j<status.size();j++){
   17.54            // ignore status for index = 0 which is set to null
   17.55 -          if(! ((status.get(j)).equals(new Integer(SyncResolver.NO_ROW_CONFLICT)))) {
   17.56 +          if(! ((status.get(j)).equals(Integer.valueOf(SyncResolver.NO_ROW_CONFLICT)))) {
   17.57                // there is at least one conflict which needs to be resolved
   17.58                boolConf = true;
   17.59               break;
   17.60 @@ -541,7 +541,7 @@
   17.61                  // how many fields need to be updated
   17.62                  int colsNotChanged = 0;
   17.63                  Vector cols = new Vector();
   17.64 -                String updateExec = new String(updateCmd);
   17.65 +                String updateExec = updateCmd;
   17.66                  Object orig;
   17.67                  Object curr;
   17.68                  Object rsval;
   17.69 @@ -652,7 +652,7 @@
   17.70                            updateExec += ", ";
   17.71                           }
   17.72                          updateExec += crs.getMetaData().getColumnName(i);
   17.73 -                        cols.add(new Integer(i));
   17.74 +                        cols.add(Integer.valueOf(i));
   17.75                          updateExec += " = ? ";
   17.76                          first = false;
   17.77  
   17.78 @@ -698,7 +698,7 @@
   17.79                                      updateExec += ", ";
   17.80                                   }
   17.81                                  updateExec += crs.getMetaData().getColumnName(i);
   17.82 -                                cols.add(new Integer(i));
   17.83 +                                cols.add(Integer.valueOf(i));
   17.84                                  updateExec += " = ? ";
   17.85                                  flag = false;
   17.86                               } else {
   17.87 @@ -1184,7 +1184,7 @@
   17.88         // trim all the leading and trailing whitespaces,
   17.89         // white spaces can never be catalog, schema or a table name.
   17.90  
   17.91 -        String cmd = new String();
   17.92 +        String cmd = "";
   17.93  
   17.94          catalog = catalog.trim();
   17.95          schema = schema.trim();
    18.1 --- a/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java	Thu Oct 07 15:12:19 2010 -0700
    18.2 +++ b/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java	Tue Oct 12 12:51:48 2010 -0700
    18.3 @@ -248,7 +248,7 @@
    18.4              String strProvider = strProviderInstance.substring(0, (caller.getSyncProvider()).toString().indexOf("@"));
    18.5  
    18.6              propString("sync-provider-name", strProvider);
    18.7 -            propString("sync-provider-vendor", "Sun Microsystems Inc.");
    18.8 +            propString("sync-provider-vendor", "Oracle Corporation");
    18.9              propString("sync-provider-version", "1.0");
   18.10              propInteger("sync-provider-grade", caller.getSyncProvider().getProviderGrade());
   18.11              propInteger("data-source-lock", caller.getSyncProvider().getDataSourceLock());
   18.12 @@ -387,7 +387,7 @@
   18.13                      if (caller.wasNull())
   18.14                          writeNull();
   18.15                      else
   18.16 -                        writeInteger(caller.getInt(idx));
   18.17 +                        writeInteger(i);
   18.18                      break;
   18.19                  case java.sql.Types.BIGINT:
   18.20                      long l = caller.getLong(idx);
   18.21 @@ -574,7 +574,7 @@
   18.22      }
   18.23  
   18.24      private void writeBoolean(boolean b) throws java.io.IOException {
   18.25 -        writer.write(new Boolean(b).toString());
   18.26 +        writer.write(Boolean.valueOf(b).toString());
   18.27      }
   18.28  
   18.29      private void writeFloat(float f) throws java.io.IOException {
   18.30 @@ -641,7 +641,7 @@
   18.31              return null;
   18.32          }
   18.33          char []charStr = s.toCharArray();
   18.34 -        String specialStr = new String();
   18.35 +        String specialStr = "";
   18.36  
   18.37          for(int i = 0; i < charStr.length; i++) {
   18.38              if(charStr[i] == '&') {
    19.1 --- a/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java	Thu Oct 07 15:12:19 2010 -0700
    19.2 +++ b/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java	Tue Oct 12 12:51:48 2010 -0700
    19.3 @@ -441,9 +441,9 @@
    19.4          updates = new Vector();
    19.5  
    19.6          // start out with the empty string
    19.7 -        columnValue = new String("");
    19.8 -        propertyValue = new String("");
    19.9 -        metaDataValue = new String("");
   19.10 +        columnValue = "";
   19.11 +        propertyValue = "";
   19.12 +        metaDataValue = "";
   19.13  
   19.14          nullVal = false;
   19.15          idx = 0;
   19.16 @@ -481,21 +481,21 @@
   19.17          items = properties.length;
   19.18  
   19.19          for (i=0;i<items;i++) {
   19.20 -            propMap.put(properties[i], new Integer(i));
   19.21 +            propMap.put(properties[i], Integer.valueOf(i));
   19.22          }
   19.23  
   19.24          colDefMap = new HashMap();
   19.25          items = colDef.length;
   19.26  
   19.27          for (i=0;i<items;i++) {
   19.28 -            colDefMap.put(colDef[i], new Integer(i));
   19.29 +            colDefMap.put(colDef[i], Integer.valueOf(i));
   19.30          }
   19.31  
   19.32          dataMap = new HashMap();
   19.33          items = data.length;
   19.34  
   19.35          for (i=0;i<items;i++) {
   19.36 -            dataMap.put(data[i], new Integer(i));
   19.37 +            dataMap.put(data[i], Integer.valueOf(i));
   19.38          }
   19.39  
   19.40          //Initialize connection map here
   19.41 @@ -686,7 +686,7 @@
   19.42              }
   19.43  
   19.44              // propertyValue need to be reset to an empty string
   19.45 -            propertyValue = new String("");
   19.46 +            propertyValue = "";
   19.47              setTag(-1);
   19.48              break;
   19.49          case METADATA:
   19.50 @@ -710,7 +710,7 @@
   19.51  
   19.52                  }
   19.53                  // metaDataValue needs to be reset to an empty string
   19.54 -                metaDataValue = new String("");
   19.55 +                metaDataValue = "";
   19.56              }
   19.57              setTag(-1);
   19.58              break;
   19.59 @@ -736,7 +736,7 @@
   19.60                          insertValue(tempStr);
   19.61                      }
   19.62                      // columnValue now need to be reset to the empty string
   19.63 -                    columnValue = new String("");
   19.64 +                    columnValue = "";
   19.65                  } catch (SQLException ex) {
   19.66                      throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errinsert").toString(), ex.getMessage()));
   19.67                  }
   19.68 @@ -981,7 +981,7 @@
   19.69  
   19.70      private boolean getBooleanValue(String s) {
   19.71  
   19.72 -        return new Boolean(s).booleanValue();
   19.73 +        return Boolean.valueOf(s).booleanValue();
   19.74      }
   19.75  
   19.76      private java.math.BigDecimal getBigDecimalValue(String s) {
   19.77 @@ -1316,7 +1316,7 @@
   19.78                **/
   19.79  
   19.80              tempUpdate = tempUpdate.concat(new String(ch,start,len));
   19.81 -            upd[0] = new Integer(idx);
   19.82 +            upd[0] = Integer.valueOf(idx);
   19.83              upd[1] = tempUpdate;
   19.84              //updates.add(upd);
   19.85  
    20.1 --- a/src/share/classes/com/sun/rowset/providers/RIOptimisticProvider.java	Thu Oct 07 15:12:19 2010 -0700
    20.2 +++ b/src/share/classes/com/sun/rowset/providers/RIOptimisticProvider.java	Tue Oct 12 12:51:48 2010 -0700
    20.3 @@ -93,14 +93,14 @@
    20.4      private CachedRowSetWriter writer;
    20.5  
    20.6      /**
    20.7 -     * The unique provider indentifier.
    20.8 +     * The unique provider identifier.
    20.9       */
   20.10      private String providerID = "com.sun.rowset.providers.RIOptimisticProvider";
   20.11  
   20.12      /**
   20.13       * The vendor name of this SyncProvider implementation
   20.14       */
   20.15 -    private String vendorName = "Sun Microsystems Inc.";
   20.16 +    private String vendorName = "Oracle Corporation";
   20.17  
   20.18      /**
   20.19       * The version number of this SyncProvider implementation
   20.20 @@ -236,8 +236,8 @@
   20.21      }
   20.22  
   20.23      /**
   20.24 -     * Returns the vendor name of the Reference Implemntation Optimistic
   20.25 -     * Syncchronication Provider
   20.26 +     * Returns the vendor name of the Reference Implementation Optimistic
   20.27 +     * Synchronization Provider
   20.28       *
   20.29       * @return the <code>String</code> detailing the vendor name of this
   20.30       *      SyncProvider
    21.1 --- a/src/share/classes/com/sun/rowset/providers/RIXMLProvider.java	Thu Oct 07 15:12:19 2010 -0700
    21.2 +++ b/src/share/classes/com/sun/rowset/providers/RIXMLProvider.java	Tue Oct 12 12:51:48 2010 -0700
    21.3 @@ -1,5 +1,5 @@
    21.4  /*
    21.5 - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
    21.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
    21.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    21.8   *
    21.9   * This code is free software; you can redistribute it and/or modify it
   21.10 @@ -85,7 +85,7 @@
   21.11      /**
   21.12       * The vendor name of this SyncProvider implementation.
   21.13       */
   21.14 -    private String vendorName = "Sun Microsystems Inc.";
   21.15 +    private String vendorName = "Oracle Corporation";
   21.16  
   21.17      /**
   21.18       * The version number of this SyncProvider implementation.
    22.1 --- a/src/share/classes/com/sun/servicetag/Installer.java	Thu Oct 07 15:12:19 2010 -0700
    22.2 +++ b/src/share/classes/com/sun/servicetag/Installer.java	Tue Oct 12 12:51:48 2010 -0700
    22.3 @@ -43,7 +43,8 @@
    22.4          "servicetag.dir.path";
    22.5      private static String SVCTAG_ENABLE_REGISTRATION =
    22.6          "servicetag.registration.enabled";
    22.7 -    private final static String SUN_VENDOR = "Sun Microsystems";
    22.8 +    private final static String ORACLE = "Oracle";
    22.9 +    private final static String SUN = "Sun Microsystems";
   22.10      private final static String REGISTRATION_XML = "registration.xml";
   22.11      private final static String SERVICE_TAG_FILE = "servicetag";
   22.12      private final static String REGISTRATION_HTML_NAME = "register";
   22.13 @@ -84,9 +85,10 @@
   22.14  
   22.15      // Implementation of ServiceTag.getJavaServiceTag(String) method
   22.16      static ServiceTag getJavaServiceTag(String source) throws IOException {
   22.17 -        if (!System.getProperty("java.vendor").startsWith(SUN_VENDOR)) {
   22.18 +        String vendor = System.getProperty("java.vendor", "");
   22.19 +        if (!vendor.startsWith(SUN) && !vendor.startsWith(ORACLE)) {
   22.20              // Products bundling this implementation may run on
   22.21 -            // Mac OS which is not a Sun JDK
   22.22 +            // Mac OS which is not a Sun/Oracle JDK
   22.23              return null;
   22.24          }
   22.25          boolean cleanup = false;
   22.26 @@ -365,7 +367,7 @@
   22.27                                        props.getProperty("servicetag.parent.name"),
   22.28                                        props.getProperty("servicetag.parent.urn"),
   22.29                                        getProductDefinedId(),
   22.30 -                                      SUN_VENDOR,
   22.31 +                                      System.getProperty("java.vendor"),
   22.32                                        System.getProperty("os.arch"),
   22.33                                        getZoneName(),
   22.34                                        svcTagSource);
    23.1 --- a/src/share/classes/com/sun/servicetag/RegistrationData.java	Thu Oct 07 15:12:19 2010 -0700
    23.2 +++ b/src/share/classes/com/sun/servicetag/RegistrationData.java	Tue Oct 12 12:51:48 2010 -0700
    23.3 @@ -80,12 +80,12 @@
    23.4   *       <tr>
    23.5   *          <td><tt>systemManufacturer</tt></td>
    23.6   *          <td>System manufacturer</td>
    23.7 - *          <td> e.g. Sun Microsystems</td>
    23.8 + *          <td> e.g. Oracle Corporation</td>
    23.9   *       </tr>
   23.10   *       <tr>
   23.11   *          <td><tt>cpuManufacturer</tt></td>
   23.12   *          <td>CPU manufacturer</td>
   23.13 - *          <td> e.g. Sun Microsystems</td>
   23.14 + *          <td> e.g. Oracle Corporation</td>
   23.15   *       </tr>
   23.16   *       <tr>
   23.17   *          <td><tt>serialNumber</tt></td>
    24.1 --- a/src/share/classes/com/sun/servicetag/Registry.java	Thu Oct 07 15:12:19 2010 -0700
    24.2 +++ b/src/share/classes/com/sun/servicetag/Registry.java	Tue Oct 12 12:51:48 2010 -0700
    24.3 @@ -90,7 +90,7 @@
    24.4                  stclient = getWindowsStClientFile();
    24.5              } else {
    24.6                  if (isVerbose()) {
    24.7 -                    System.out.println("Running on non-Sun JDK");
    24.8 +                    System.out.println("Running on unsupported platform");
    24.9                  }
   24.10              }
   24.11              initialized = true;
    25.1 --- a/src/share/classes/com/sun/servicetag/SolarisSystemEnvironment.java	Thu Oct 07 15:12:19 2010 -0700
    25.2 +++ b/src/share/classes/com/sun/servicetag/SolarisSystemEnvironment.java	Tue Oct 12 12:51:48 2010 -0700
    25.3 @@ -44,6 +44,7 @@
    25.4   * Solaris implementation of the SystemEnvironment class.
    25.5   */
    25.6  class SolarisSystemEnvironment extends SystemEnvironment {
    25.7 +    private static final String ORACLE = "Oracle Corporation";
    25.8      SolarisSystemEnvironment() {
    25.9          setHostId(getCommandOutput("/usr/bin/hostid"));
   25.10          setSystemModel(getCommandOutput("/usr/bin/uname", "-i"));
   25.11 @@ -59,7 +60,7 @@
   25.12      private String getSolarisCpuManufacturer() {
   25.13          // not fully accurate, this could be another manufacturer (fujitsu for example)
   25.14          if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) {
   25.15 -            return "Sun Microsystems, Inc";
   25.16 +            return ORACLE;
   25.17          }
   25.18  
   25.19          // if we're here, then we'll try smbios (type 4)
   25.20 @@ -73,7 +74,7 @@
   25.21      private String getSolarisSystemManufacturer() {
   25.22          // not fully accurate, this could be another manufacturer (fujitsu for example)
   25.23          if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) {
   25.24 -            return "Sun Microsystems, Inc";
   25.25 +            return ORACLE;
   25.26          }
   25.27  
   25.28          // if we're here, then we'll try smbios (type 1)
   25.29 @@ -117,7 +118,7 @@
   25.30      // ID    SIZE TYPE
   25.31      // 1     150  SMB_TYPE_SYSTEM (system information)
   25.32      //
   25.33 -    //   Manufacturer: Sun Microsystems
   25.34 +    //   Manufacturer: Oracle Corporation
   25.35      //   Product: Sun Fire X4600
   25.36      //   Version: To Be Filled By O.E.M.
   25.37      //   Serial Number: 00:14:4F:45:0C:2A
    26.1 --- a/src/share/classes/java/awt/Dialog.java	Thu Oct 07 15:12:19 2010 -0700
    26.2 +++ b/src/share/classes/java/awt/Dialog.java	Tue Oct 12 12:51:48 2010 -0700
    26.3 @@ -1068,7 +1068,7 @@
    26.4                      modalityPushed();
    26.5                      try {
    26.6                          EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
    26.7 -                        secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 5000);
    26.8 +                        secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 0);
    26.9                          if (!secondaryLoop.enter()) {
   26.10                              secondaryLoop = null;
   26.11                          }
    27.1 --- a/src/share/classes/java/awt/KeyboardFocusManager.java	Thu Oct 07 15:12:19 2010 -0700
    27.2 +++ b/src/share/classes/java/awt/KeyboardFocusManager.java	Tue Oct 12 12:51:48 2010 -0700
    27.3 @@ -142,6 +142,9 @@
    27.4                  public void removeLastFocusRequest(Component heavyweight) {
    27.5                      KeyboardFocusManager.removeLastFocusRequest(heavyweight);
    27.6                  }
    27.7 +                public void setMostRecentFocusOwner(Window window, Component component) {
    27.8 +                    KeyboardFocusManager.setMostRecentFocusOwner(window, component);
    27.9 +                }
   27.10              }
   27.11          );
   27.12      }
    28.1 --- a/src/share/classes/java/awt/event/ActionEvent.java	Thu Oct 07 15:12:19 2010 -0700
    28.2 +++ b/src/share/classes/java/awt/event/ActionEvent.java	Tue Oct 12 12:51:48 2010 -0700
    28.3 @@ -51,7 +51,7 @@
    28.4   * in the range from {@code ACTION_FIRST} to {@code ACTION_LAST}.
    28.5   *
    28.6   * @see ActionListener
    28.7 - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/eventmodel.html">Tutorial: Java 1.1 Event Model</a>
    28.8 + * @see <a href="http://java.sun.com/docs/books/tutorial/uiswing/events/actionlistener.html">Tutorial: How to Write an Action Listener</a>
    28.9   *
   28.10   * @author Carl Quinn
   28.11   * @since 1.1
    29.1 --- a/src/share/classes/java/awt/image/SampleModel.java	Thu Oct 07 15:12:19 2010 -0700
    29.2 +++ b/src/share/classes/java/awt/image/SampleModel.java	Tue Oct 12 12:51:48 2010 -0700
    29.3 @@ -937,14 +937,22 @@
    29.4                              int iArray[], DataBuffer data) {
    29.5          int pixels[];
    29.6          int Offset=0;
    29.7 +        int x1 = x + w;
    29.8 +        int y1 = y + h;
    29.9 +
   29.10 +        if (x < 0 || x1 < x || x1 > width ||
   29.11 +            y < 0 || y1 < y || y1 > height)
   29.12 +        {
   29.13 +            throw new ArrayIndexOutOfBoundsException("Invalid coordinates.");
   29.14 +        }
   29.15  
   29.16          if (iArray != null)
   29.17              pixels = iArray;
   29.18          else
   29.19              pixels = new int[w * h];
   29.20  
   29.21 -        for(int i=y; i<(h+y); i++) {
   29.22 -            for (int j=x; j<(w+x); j++) {
   29.23 +        for(int i=y; i<y1; i++) {
   29.24 +            for (int j=x; j<x1; j++) {
   29.25                  pixels[Offset++] = getSample(j, i, b, data);
   29.26              }
   29.27          }
   29.28 @@ -978,14 +986,22 @@
   29.29                                DataBuffer data) {
   29.30          float pixels[];
   29.31          int   Offset=0;
   29.32 +        int x1 = x + w;
   29.33 +        int y1 = y + h;
   29.34 +
   29.35 +        if (x < 0 || x1 < x || x1 > width ||
   29.36 +            y < 0 || y1 < y || y1 > height)
   29.37 +        {
   29.38 +            throw new ArrayIndexOutOfBoundsException("Invalid coordinates");
   29.39 +        }
   29.40  
   29.41          if (fArray != null)
   29.42              pixels = fArray;
   29.43          else
   29.44              pixels = new float[w * h];
   29.45  
   29.46 -        for (int i=y; i<(h+y); i++) {
   29.47 -            for (int j=x; j<(w+x); j++) {
   29.48 +        for (int i=y; i<y1; i++) {
   29.49 +            for (int j=x; j<x1; j++) {
   29.50                  pixels[Offset++] = getSampleFloat(j, i, b, data);
   29.51              }
   29.52          }
   29.53 @@ -1019,14 +1035,22 @@
   29.54                                 DataBuffer data) {
   29.55          double pixels[];
   29.56          int    Offset=0;
   29.57 +        int x1 = x + w;
   29.58 +        int y1 = y + h;
   29.59 +
   29.60 +        if (x < 0 || x1 < x || x1 > width ||
   29.61 +            y < 0 || y1 < y || y1 > height)
   29.62 +        {
   29.63 +            throw new ArrayIndexOutOfBoundsException("Invalid coordinates");
   29.64 +        }
   29.65  
   29.66          if (dArray != null)
   29.67              pixels = dArray;
   29.68          else
   29.69              pixels = new double[w * h];
   29.70  
   29.71 -        for (int i=y; i<(y+h); i++) {
   29.72 -            for (int j=x; j<(x+w); j++) {
   29.73 +        for (int i=y; i<y1; i++) {
   29.74 +            for (int j=x; j<x1; j++) {
   29.75                  pixels[Offset++] = getSampleDouble(j, i, b, data);
   29.76              }
   29.77          }
    30.1 --- a/src/share/classes/java/beans/EventSetDescriptor.java	Thu Oct 07 15:12:19 2010 -0700
    30.2 +++ b/src/share/classes/java/beans/EventSetDescriptor.java	Tue Oct 12 12:51:48 2010 -0700
    30.3 @@ -176,8 +176,9 @@
    30.4          setRemoveListenerMethod(getMethod(sourceClass, removeListenerMethodName, 1));
    30.5  
    30.6          // Be more forgiving of not finding the getListener method.
    30.7 -        if (getListenerMethodName != null) {
    30.8 -            setGetListenerMethod(Introspector.findInstanceMethod(sourceClass, getListenerMethodName));
    30.9 +        Method method = Introspector.findMethod(sourceClass, getListenerMethodName, 0);
   30.10 +        if (method != null) {
   30.11 +            setGetListenerMethod(method);
   30.12          }
   30.13      }
   30.14  
    31.1 --- a/src/share/classes/java/beans/IndexedPropertyDescriptor.java	Thu Oct 07 15:12:19 2010 -0700
    31.2 +++ b/src/share/classes/java/beans/IndexedPropertyDescriptor.java	Tue Oct 12 12:51:48 2010 -0700
    31.3 @@ -189,11 +189,13 @@
    31.4                      indexedReadMethodName = Introspector.GET_PREFIX + getBaseName();
    31.5                  }
    31.6              }
    31.7 -            indexedReadMethod = Introspector.findInstanceMethod(cls, indexedReadMethodName, int.class);
    31.8 +
    31.9 +            Class[] args = { int.class };
   31.10 +            indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args);
   31.11              if (indexedReadMethod == null) {
   31.12                  // no "is" method, so look for a "get" method.
   31.13                  indexedReadMethodName = Introspector.GET_PREFIX + getBaseName();
   31.14 -                indexedReadMethod = Introspector.findInstanceMethod(cls, indexedReadMethodName, int.class);
   31.15 +                indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args);
   31.16              }
   31.17              setIndexedReadMethod0(indexedReadMethod);
   31.18          }
   31.19 @@ -265,7 +267,9 @@
   31.20              if (indexedWriteMethodName == null) {
   31.21                  indexedWriteMethodName = Introspector.SET_PREFIX + getBaseName();
   31.22              }
   31.23 -            indexedWriteMethod = Introspector.findInstanceMethod(cls, indexedWriteMethodName, int.class, type);
   31.24 +
   31.25 +            Class[] args = (type == null) ? null : new Class[] { int.class, type };
   31.26 +            indexedWriteMethod = Introspector.findMethod(cls, indexedWriteMethodName, 2, args);
   31.27              if (indexedWriteMethod != null) {
   31.28                  if (!indexedWriteMethod.getReturnType().equals(void.class)) {
   31.29                      indexedWriteMethod = null;
    32.1 --- a/src/share/classes/java/beans/Introspector.java	Thu Oct 07 15:12:19 2010 -0700
    32.2 +++ b/src/share/classes/java/beans/Introspector.java	Tue Oct 12 12:51:48 2010 -0700
    32.3 @@ -28,7 +28,6 @@
    32.4  import com.sun.beans.WeakCache;
    32.5  import com.sun.beans.finder.BeanInfoFinder;
    32.6  import com.sun.beans.finder.ClassFinder;
    32.7 -import com.sun.beans.finder.MethodFinder;
    32.8  
    32.9  import java.lang.ref.Reference;
   32.10  import java.lang.ref.SoftReference;
   32.11 @@ -843,8 +842,8 @@
   32.12                  Method read = result.getReadMethod();
   32.13  
   32.14                  if (read == null && write != null) {
   32.15 -                    read = findInstanceMethod(result.getClass0(),
   32.16 -                                              GET_PREFIX + NameGenerator.capitalize(result.getName()));
   32.17 +                    read = findMethod(result.getClass0(),
   32.18 +                                      GET_PREFIX + NameGenerator.capitalize(result.getName()), 0);
   32.19                      if (read != null) {
   32.20                          try {
   32.21                              result.setReadMethod(read);
   32.22 @@ -854,9 +853,9 @@
   32.23                      }
   32.24                  }
   32.25                  if (write == null && read != null) {
   32.26 -                    write = findInstanceMethod(result.getClass0(),
   32.27 -                                               SET_PREFIX + NameGenerator.capitalize(result.getName()),
   32.28 -                                               FeatureDescriptor.getReturnType(result.getClass0(), read));
   32.29 +                    write = findMethod(result.getClass0(),
   32.30 +                                       SET_PREFIX + NameGenerator.capitalize(result.getName()), 1,
   32.31 +                                       new Class[] { FeatureDescriptor.getReturnType(result.getClass0(), read) });
   32.32                      if (write != null) {
   32.33                          try {
   32.34                              result.setWriteMethod(write);
   32.35 @@ -1280,27 +1279,90 @@
   32.36      // Package private support methods.
   32.37      //======================================================================
   32.38  
   32.39 -    static Method findMethod(Class<?> type, String name, int args) {
   32.40 -        for (Method method : type.getMethods()) {
   32.41 -            if (method.getName().equals(name) && (args == method.getParameterTypes().length)) {
   32.42 -                try {
   32.43 -                    return MethodFinder.findAccessibleMethod(method);
   32.44 +    /**
   32.45 +     * Internal support for finding a target methodName with a given
   32.46 +     * parameter list on a given class.
   32.47 +     */
   32.48 +    private static Method internalFindMethod(Class start, String methodName,
   32.49 +                                                 int argCount, Class args[]) {
   32.50 +        // For overriden methods we need to find the most derived version.
   32.51 +        // So we start with the given class and walk up the superclass chain.
   32.52 +
   32.53 +        Method method = null;
   32.54 +
   32.55 +        for (Class cl = start; cl != null; cl = cl.getSuperclass()) {
   32.56 +            Method methods[] = getPublicDeclaredMethods(cl);
   32.57 +            for (int i = 0; i < methods.length; i++) {
   32.58 +                method = methods[i];
   32.59 +                if (method == null) {
   32.60 +                    continue;
   32.61                  }
   32.62 -                catch (NoSuchMethodException exception) {
   32.63 -                    // continue search for a method with the specified count of parameters
   32.64 +
   32.65 +                // make sure method signature matches.
   32.66 +                Class params[] = FeatureDescriptor.getParameterTypes(start, method);
   32.67 +                if (method.getName().equals(methodName) &&
   32.68 +                    params.length == argCount) {
   32.69 +                    if (args != null) {
   32.70 +                        boolean different = false;
   32.71 +                        if (argCount > 0) {
   32.72 +                            for (int j = 0; j < argCount; j++) {
   32.73 +                                if (params[j] != args[j]) {
   32.74 +                                    different = true;
   32.75 +                                    continue;
   32.76 +                                }
   32.77 +                            }
   32.78 +                            if (different) {
   32.79 +                                continue;
   32.80 +                            }
   32.81 +                        }
   32.82 +                    }
   32.83 +                    return method;
   32.84                  }
   32.85              }
   32.86          }
   32.87 -        return null;
   32.88 +        method = null;
   32.89 +
   32.90 +        // Now check any inherited interfaces.  This is necessary both when
   32.91 +        // the argument class is itself an interface, and when the argument
   32.92 +        // class is an abstract class.
   32.93 +        Class ifcs[] = start.getInterfaces();
   32.94 +        for (int i = 0 ; i < ifcs.length; i++) {
   32.95 +            // Note: The original implementation had both methods calling
   32.96 +            // the 3 arg method. This is preserved but perhaps it should
   32.97 +            // pass the args array instead of null.
   32.98 +            method = internalFindMethod(ifcs[i], methodName, argCount, null);
   32.99 +            if (method != null) {
  32.100 +                break;
  32.101 +            }
  32.102 +        }
  32.103 +        return method;
  32.104      }
  32.105  
  32.106 -    static Method findInstanceMethod(Class<?> type, String name, Class<?>... args) {
  32.107 -        try {
  32.108 -            return MethodFinder.findInstanceMethod(type, name, args);
  32.109 -        }
  32.110 -        catch (NoSuchMethodException exception) {
  32.111 +    /**
  32.112 +     * Find a target methodName on a given class.
  32.113 +     */
  32.114 +    static Method findMethod(Class cls, String methodName, int argCount) {
  32.115 +        return findMethod(cls, methodName, argCount, null);
  32.116 +    }
  32.117 +
  32.118 +    /**
  32.119 +     * Find a target methodName with specific parameter list on a given class.
  32.120 +     * <p>
  32.121 +     * Used in the contructors of the EventSetDescriptor,
  32.122 +     * PropertyDescriptor and the IndexedPropertyDescriptor.
  32.123 +     * <p>
  32.124 +     * @param cls The Class object on which to retrieve the method.
  32.125 +     * @param methodName Name of the method.
  32.126 +     * @param argCount Number of arguments for the desired method.
  32.127 +     * @param args Array of argument types for the method.
  32.128 +     * @return the method or null if not found
  32.129 +     */
  32.130 +    static Method findMethod(Class cls, String methodName, int argCount,
  32.131 +                             Class args[]) {
  32.132 +        if (methodName == null) {
  32.133              return null;
  32.134          }
  32.135 +        return internalFindMethod(cls, methodName, argCount, args);
  32.136      }
  32.137  
  32.138      /**
    33.1 --- a/src/share/classes/java/beans/MethodDescriptor.java	Thu Oct 07 15:12:19 2010 -0700
    33.2 +++ b/src/share/classes/java/beans/MethodDescriptor.java	Tue Oct 12 12:51:48 2010 -0700
    33.3 @@ -90,13 +90,13 @@
    33.4                          // Find methods for up to 2 params. We are guessing here.
    33.5                          // This block should never execute unless the classloader
    33.6                          // that loaded the argument classes disappears.
    33.7 -                        method = Introspector.findMethod(cls, name, i);
    33.8 +                        method = Introspector.findMethod(cls, name, i, null);
    33.9                          if (method != null) {
   33.10                              break;
   33.11                          }
   33.12                      }
   33.13                  } else {
   33.14 -                    method = Statement.getMethod(cls, name, params);
   33.15 +                    method = Introspector.findMethod(cls, name, params.length, params);
   33.16                  }
   33.17                  setMethod(method);
   33.18              }
    34.1 --- a/src/share/classes/java/beans/PropertyDescriptor.java	Thu Oct 07 15:12:19 2010 -0700
    34.2 +++ b/src/share/classes/java/beans/PropertyDescriptor.java	Tue Oct 12 12:51:48 2010 -0700
    34.3 @@ -112,7 +112,8 @@
    34.4          // If this class or one of its base classes allow PropertyChangeListener,
    34.5          // then we assume that any properties we discover are "bound".
    34.6          // See Introspector.getTargetPropertyInfo() method.
    34.7 -        this.bound = null != Introspector.findInstanceMethod(beanClass, "addPropertyChangeListener", PropertyChangeListener.class);
    34.8 +        Class[] args = { PropertyChangeListener.class };
    34.9 +        this.bound = null != Introspector.findMethod(beanClass, "addPropertyChangeListener", args.length, args);
   34.10      }
   34.11  
   34.12      /**
   34.13 @@ -223,10 +224,10 @@
   34.14              // property type is.  For booleans, there can be "is" and "get"
   34.15              // methods.  If an "is" method exists, this is the official
   34.16              // reader method so look for this one first.
   34.17 -            readMethod = Introspector.findInstanceMethod(cls, readMethodName);
   34.18 +            readMethod = Introspector.findMethod(cls, readMethodName, 0);
   34.19              if (readMethod == null) {
   34.20                  readMethodName = Introspector.GET_PREFIX + getBaseName();
   34.21 -                readMethod = Introspector.findInstanceMethod(cls, readMethodName);
   34.22 +                readMethod = Introspector.findMethod(cls, readMethodName, 0);
   34.23              }
   34.24              try {
   34.25                  setReadMethod(readMethod);
   34.26 @@ -291,7 +292,8 @@
   34.27                  writeMethodName = Introspector.SET_PREFIX + getBaseName();
   34.28              }
   34.29  
   34.30 -            writeMethod = Introspector.findInstanceMethod(cls, writeMethodName, type);
   34.31 +            Class[] args = (type == null) ? null : new Class[] { type };
   34.32 +            writeMethod = Introspector.findMethod(cls, writeMethodName, 1, args);
   34.33              if (writeMethod != null) {
   34.34                  if (!writeMethod.getReturnType().equals(void.class)) {
   34.35                      writeMethod = null;
    35.1 --- a/src/share/classes/java/lang/System.java	Thu Oct 07 15:12:19 2010 -0700
    35.2 +++ b/src/share/classes/java/lang/System.java	Tue Oct 12 12:51:48 2010 -0700
    35.3 @@ -1101,22 +1101,12 @@
    35.4          lineSeparator = props.getProperty("line.separator");
    35.5          sun.misc.Version.init();
    35.6  
    35.7 -        // Workaround until DownloadManager initialization is revisited.
    35.8 -        // Make JavaLangAccess available early enough for internal
    35.9 -        // Shutdown hooks to be registered
   35.10 -        setJavaLangAccess();
   35.11 -
   35.12          // Gets and removes system properties that configure the Integer
   35.13          // cache used to support the object identity semantics of autoboxing.
   35.14          // At this time, the size of the cache may be controlled by the
   35.15          // vm option -XX:AutoBoxCacheMax=<size>.
   35.16          Integer.getAndRemoveCacheProperties();
   35.17  
   35.18 -        // Load the zip library now in order to keep java.util.zip.ZipFile
   35.19 -        // from trying to use itself to load this library later.
   35.20 -        loadLibrary("zip");
   35.21 -
   35.22 -
   35.23          FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
   35.24          FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
   35.25          FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
   35.26 @@ -1124,6 +1114,10 @@
   35.27          setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
   35.28          setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true));
   35.29  
   35.30 +        // Load the zip library now in order to keep java.util.zip.ZipFile
   35.31 +        // from trying to use itself to load this library later.
   35.32 +        loadLibrary("zip");
   35.33 +
   35.34          // Setup Java signal handlers for HUP, TERM, and INT (where available).
   35.35          Terminator.setup();
   35.36  
   35.37 @@ -1153,6 +1147,9 @@
   35.38          // way as other threads; we must do it ourselves here.
   35.39          Thread current = Thread.currentThread();
   35.40          current.getThreadGroup().add(current);
   35.41 +
   35.42 +        // register shared secrets
   35.43 +        setJavaLangAccess();
   35.44      }
   35.45  
   35.46      private static void setJavaLangAccess() {
    36.1 --- a/src/share/classes/java/net/InetAddress.java	Thu Oct 07 15:12:19 2010 -0700
    36.2 +++ b/src/share/classes/java/net/InetAddress.java	Tue Oct 12 12:51:48 2010 -0700
    36.3 @@ -677,19 +677,20 @@
    36.4  
    36.5      static InetAddressImpl  impl;
    36.6  
    36.7 -    private static HashMap          lookupTable = new HashMap();
    36.8 +    private static HashMap<String, InetAddress[]> lookupTable
    36.9 +        = new HashMap<String, InetAddress[]>();
   36.10  
   36.11      /**
   36.12       * Represents a cache entry
   36.13       */
   36.14      static final class CacheEntry {
   36.15  
   36.16 -        CacheEntry(Object address, long expiration) {
   36.17 -            this.address = address;
   36.18 +        CacheEntry(InetAddress[] addresses, long expiration) {
   36.19 +            this.addresses = addresses;
   36.20              this.expiration = expiration;
   36.21          }
   36.22  
   36.23 -        Object address;
   36.24 +        InetAddress[] addresses;
   36.25          long expiration;
   36.26      }
   36.27  
   36.28 @@ -698,7 +699,7 @@
   36.29       * at creation time.
   36.30       */
   36.31      static final class Cache {
   36.32 -        private LinkedHashMap cache;
   36.33 +        private LinkedHashMap<String, CacheEntry> cache;
   36.34          private Type type;
   36.35  
   36.36          enum Type {Positive, Negative};
   36.37 @@ -708,7 +709,7 @@
   36.38           */
   36.39          public Cache(Type type) {
   36.40              this.type = type;
   36.41 -            cache = new LinkedHashMap();
   36.42 +            cache = new LinkedHashMap<String, CacheEntry>();
   36.43          }
   36.44  
   36.45          private int getPolicy() {
   36.46 @@ -724,7 +725,7 @@
   36.47           * entry then for this host then the entry will be
   36.48           * replaced.
   36.49           */
   36.50 -        public Cache put(String host, Object address) {
   36.51 +        public Cache put(String host, InetAddress[] addresses) {
   36.52              int policy = getPolicy();
   36.53              if (policy == InetAddressCachePolicy.NEVER) {
   36.54                  return this;
   36.55 @@ -736,12 +737,10 @@
   36.56  
   36.57                  // As we iterate in insertion order we can
   36.58                  // terminate when a non-expired entry is found.
   36.59 -                LinkedList expired = new LinkedList();
   36.60 -                Iterator i = cache.keySet().iterator();
   36.61 +                LinkedList<String> expired = new LinkedList<String>();
   36.62                  long now = System.currentTimeMillis();
   36.63 -                while (i.hasNext()) {
   36.64 -                    String key = (String)i.next();
   36.65 -                    CacheEntry entry = (CacheEntry)cache.get(key);
   36.66 +                for (String key : cache.keySet()) {
   36.67 +                    CacheEntry entry = cache.get(key);
   36.68  
   36.69                      if (entry.expiration >= 0 && entry.expiration < now) {
   36.70                          expired.add(key);
   36.71 @@ -750,9 +749,8 @@
   36.72                      }
   36.73                  }
   36.74  
   36.75 -                i = expired.iterator();
   36.76 -                while (i.hasNext()) {
   36.77 -                    cache.remove(i.next());
   36.78 +                for (String key : expired) {
   36.79 +                    cache.remove(key);
   36.80                  }
   36.81              }
   36.82  
   36.83 @@ -766,7 +764,7 @@
   36.84              } else {
   36.85                  expiration = System.currentTimeMillis() + (policy * 1000);
   36.86              }
   36.87 -            CacheEntry entry = new CacheEntry(address, expiration);
   36.88 +            CacheEntry entry = new CacheEntry(addresses, expiration);
   36.89              cache.put(host, entry);
   36.90              return this;
   36.91          }
   36.92 @@ -780,7 +778,7 @@
   36.93              if (policy == InetAddressCachePolicy.NEVER) {
   36.94                  return null;
   36.95              }
   36.96 -            CacheEntry entry = (CacheEntry)cache.get(host);
   36.97 +            CacheEntry entry = cache.get(host);
   36.98  
   36.99              // check if entry has expired
  36.100              if (entry != null && policy != InetAddressCachePolicy.FOREVER) {
  36.101 @@ -814,42 +812,41 @@
  36.102      }
  36.103  
  36.104      /*
  36.105 -     * Cache the given hostname and address.
  36.106 +     * Cache the given hostname and addresses.
  36.107       */
  36.108 -    private static void cacheAddress(String hostname, Object address,
  36.109 -                                     boolean success) {
  36.110 +    private static void cacheAddresses(String hostname,
  36.111 +                                       InetAddress[] addresses,
  36.112 +                                       boolean success) {
  36.113          hostname = hostname.toLowerCase();
  36.114          synchronized (addressCache) {
  36.115              cacheInitIfNeeded();
  36.116              if (success) {
  36.117 -                addressCache.put(hostname, address);
  36.118 +                addressCache.put(hostname, addresses);
  36.119              } else {
  36.120 -                negativeCache.put(hostname, address);
  36.121 +                negativeCache.put(hostname, addresses);
  36.122              }
  36.123          }
  36.124      }
  36.125  
  36.126      /*
  36.127       * Lookup hostname in cache (positive & negative cache). If
  36.128 -     * found return address, null if not found.
  36.129 +     * found return addresses, null if not found.
  36.130       */
  36.131 -    private static Object getCachedAddress(String hostname) {
  36.132 +    private static InetAddress[] getCachedAddresses(String hostname) {
  36.133          hostname = hostname.toLowerCase();
  36.134  
  36.135          // search both positive & negative caches
  36.136  
  36.137          synchronized (addressCache) {
  36.138 -            CacheEntry entry;
  36.139 -
  36.140              cacheInitIfNeeded();
  36.141  
  36.142 -            entry = addressCache.get(hostname);
  36.143 +            CacheEntry entry = addressCache.get(hostname);
  36.144              if (entry == null) {
  36.145                  entry = negativeCache.get(hostname);
  36.146              }
  36.147  
  36.148              if (entry != null) {
  36.149 -                return entry.address;
  36.150 +                return entry.addresses;
  36.151              }
  36.152          }
  36.153  
  36.154 @@ -911,7 +908,7 @@
  36.155  
  36.156      static {
  36.157          // create the impl
  36.158 -        impl = (new InetAddressImplFactory()).create();
  36.159 +        impl = InetAddressImplFactory.create();
  36.160  
  36.161          // get name service if provided and requested
  36.162          String provider = null;;
  36.163 @@ -931,7 +928,7 @@
  36.164          }
  36.165  
  36.166          // if not designate any name services provider,
  36.167 -        // creat a default one
  36.168 +        // create a default one
  36.169          if (nameServices.size() == 0) {
  36.170              NameService ns = createNSProvider("default");
  36.171              nameServices.add(ns);
  36.172 @@ -939,7 +936,7 @@
  36.173      }
  36.174  
  36.175      /**
  36.176 -     * Create an InetAddress based on the provided host name and IP address
  36.177 +     * Creates an InetAddress based on the provided host name and IP address.
  36.178       * No name service is checked for the validity of the address.
  36.179       *
  36.180       * <p> The host name can either be a machine name, such as
  36.181 @@ -1067,13 +1064,13 @@
  36.182  
  36.183          boolean ipv6Expected = false;
  36.184          if (host.charAt(0) == '[') {
  36.185 -            // This is supposed to be an IPv6 litteral
  36.186 +            // This is supposed to be an IPv6 literal
  36.187              if (host.length() > 2 && host.charAt(host.length()-1) == ']') {
  36.188                  host = host.substring(1, host.length() -1);
  36.189                  ipv6Expected = true;
  36.190              } else {
  36.191                  // This was supposed to be a IPv6 address, but it's not!
  36.192 -                throw new UnknownHostException(host);
  36.193 +                throw new UnknownHostException(host + ": invalid IPv6 address");
  36.194              }
  36.195          }
  36.196  
  36.197 @@ -1180,8 +1177,6 @@
  36.198          throws UnknownHostException  {
  36.199          /* If it gets here it is presumed to be a hostname */
  36.200          /* Cache.get can return: null, unknownAddress, or InetAddress[] */
  36.201 -        Object obj = null;
  36.202 -        Object objcopy = null;
  36.203  
  36.204          /* make sure the connection to the host is allowed, before we
  36.205           * give out a hostname
  36.206 @@ -1193,26 +1188,23 @@
  36.207              }
  36.208          }
  36.209  
  36.210 -        obj = getCachedAddress(host);
  36.211 +        InetAddress[] addresses = getCachedAddresses(host);
  36.212  
  36.213          /* If no entry in cache, then do the host lookup */
  36.214 -        if (obj == null) {
  36.215 -            obj = getAddressFromNameService(host);
  36.216 +        if (addresses == null) {
  36.217 +            addresses = getAddressesFromNameService(host);
  36.218          }
  36.219  
  36.220 -        if (obj == unknown_array)
  36.221 +        if (addresses == unknown_array)
  36.222              throw new UnknownHostException(host);
  36.223  
  36.224 -        /* Make a copy of the InetAddress array */
  36.225 -        objcopy = ((InetAddress [])obj).clone();
  36.226 -
  36.227 -        return (InetAddress [])objcopy;
  36.228 +        return addresses.clone();
  36.229      }
  36.230  
  36.231 -    private static Object getAddressFromNameService(String host)
  36.232 +    private static InetAddress[] getAddressesFromNameService(String host)
  36.233          throws UnknownHostException
  36.234      {
  36.235 -        Object obj = null;
  36.236 +        InetAddress[] addresses = null;
  36.237          boolean success = false;
  36.238          UnknownHostException ex = null;
  36.239  
  36.240 @@ -1226,16 +1218,16 @@
  36.241          //    would be blocked until the host is removed
  36.242          //    from the lookupTable. Then this thread
  36.243          //    should try to look up the addressCache.
  36.244 -        //     i) if it found the address in the
  36.245 +        //     i) if it found the addresses in the
  36.246          //        addressCache, checkLookupTable()  would
  36.247 -        //        return the address.
  36.248 -        //     ii) if it didn't find the address in the
  36.249 +        //        return the addresses.
  36.250 +        //     ii) if it didn't find the addresses in the
  36.251          //         addressCache for any reason,
  36.252          //         it should add the host in the
  36.253          //         lookupTable and return null so the
  36.254          //         following code would do  a lookup itself.
  36.255 -        if ((obj = checkLookupTable(host)) == null) {
  36.256 -            // This is the first thread which looks up the address
  36.257 +        if ((addresses = checkLookupTable(host)) == null) {
  36.258 +            // This is the first thread which looks up the addresses
  36.259              // this host or the cache entry for this host has been
  36.260              // expired so this thread should do the lookup.
  36.261              for (NameService nameService : nameServices) {
  36.262 @@ -1246,26 +1238,26 @@
  36.263                       * allocating space when the lookup fails.
  36.264                       */
  36.265  
  36.266 -                    obj = nameService.lookupAllHostAddr(host);
  36.267 +                    addresses = nameService.lookupAllHostAddr(host);
  36.268                      success = true;
  36.269                      break;
  36.270                  } catch (UnknownHostException uhe) {
  36.271                      if (host.equalsIgnoreCase("localhost")) {
  36.272                          InetAddress[] local = new InetAddress[] { impl.loopbackAddress() };
  36.273 -                        obj = local;
  36.274 +                        addresses = local;
  36.275                          success = true;
  36.276                          break;
  36.277                      }
  36.278                      else {
  36.279 -                        obj  = unknown_array;
  36.280 +                        addresses = unknown_array;
  36.281                          success = false;
  36.282                          ex = uhe;
  36.283                      }
  36.284                  }
  36.285              }
  36.286  
  36.287 -            // Cache the address.
  36.288 -            cacheAddress(host, obj, success);
  36.289 +            // Cache the addresses.
  36.290 +            cacheAddresses(host, addresses, success);
  36.291              // Delete the host from the lookupTable, and
  36.292              // notify all threads waiting for the monitor
  36.293              // for lookupTable.
  36.294 @@ -1274,13 +1266,13 @@
  36.295                  throw ex;
  36.296          }
  36.297  
  36.298 -        return obj;
  36.299 +        return addresses;
  36.300      }
  36.301  
  36.302  
  36.303 -    private static Object checkLookupTable(String host) {
  36.304 -        // make sure obj  is null.
  36.305 -        Object obj = null;
  36.306 +    private static InetAddress[] checkLookupTable(String host) {
  36.307 +        // make sure addresses is null.
  36.308 +        InetAddress[] addresses = null;
  36.309  
  36.310          synchronized (lookupTable) {
  36.311              // If the host isn't in the lookupTable, add it in the
  36.312 @@ -1288,11 +1280,11 @@
  36.313              // the lookup.
  36.314              if (lookupTable.containsKey(host) == false) {
  36.315                  lookupTable.put(host, null);
  36.316 -                return obj;
  36.317 +                return addresses;
  36.318              }
  36.319  
  36.320              // If the host is in the lookupTable, it means that another
  36.321 -            // thread is trying to look up the address of this host.
  36.322 +            // thread is trying to look up the addresses of this host.
  36.323              // This thread should wait.
  36.324              while (lookupTable.containsKey(host)) {
  36.325                  try {
  36.326 @@ -1302,18 +1294,18 @@
  36.327              }
  36.328          }
  36.329  
  36.330 -        // The other thread has finished looking up the address of
  36.331 -        // the host. This thread should retry to get the address
  36.332 -        // from the addressCache. If it doesn't get the address from
  36.333 -        // the cache,  it will try to look up the address itself.
  36.334 -        obj = getCachedAddress(host);
  36.335 -        if (obj == null) {
  36.336 +        // The other thread has finished looking up the addresses of
  36.337 +        // the host. This thread should retry to get the addresses
  36.338 +        // from the addressCache. If it doesn't get the addresses from
  36.339 +        // the cache, it will try to look up the addresses itself.
  36.340 +        addresses = getCachedAddresses(host);
  36.341 +        if (addresses == null) {
  36.342              synchronized (lookupTable) {
  36.343                  lookupTable.put(host, null);
  36.344              }
  36.345          }
  36.346  
  36.347 -        return obj;
  36.348 +        return addresses;
  36.349      }
  36.350  
  36.351      private static void updateLookupTable(String host) {
  36.352 @@ -1396,15 +1388,20 @@
  36.353                          cachedLocalHost = null;
  36.354                  }
  36.355  
  36.356 -                // we are calling getAddressFromNameService directly
  36.357 +                // we are calling getAddressesFromNameService directly
  36.358                  // to avoid getting localHost from cache
  36.359                  if (ret == null) {
  36.360                      InetAddress[] localAddrs;
  36.361                      try {
  36.362                          localAddrs =
  36.363 -                            (InetAddress[]) InetAddress.getAddressFromNameService(local);
  36.364 +                            InetAddress.getAddressesFromNameService(local);
  36.365                      } catch (UnknownHostException uhe) {
  36.366 -                        throw new UnknownHostException(local + ": " + uhe.getMessage());
  36.367 +                        // Rethrow with a more informative error message.
  36.368 +                        UnknownHostException uhe2 =
  36.369 +                            new UnknownHostException(local + ": " +
  36.370 +                                                     uhe.getMessage());
  36.371 +                        uhe2.initCause(uhe);
  36.372 +                        throw uhe2;
  36.373                      }
  36.374                      cachedLocalHost = localAddrs[0];
  36.375                      cacheTime = now;
  36.376 @@ -1434,8 +1431,8 @@
  36.377      /*
  36.378       * Load and instantiate an underlying impl class
  36.379       */
  36.380 -    static Object loadImpl(String implName) {
  36.381 -        Object impl;
  36.382 +    static InetAddressImpl loadImpl(String implName) {
  36.383 +        Object impl = null;
  36.384  
  36.385          /*
  36.386           * Property "impl.prefix" will be prepended to the classname
  36.387 @@ -1446,7 +1443,6 @@
  36.388           */
  36.389          String prefix = AccessController.doPrivileged(
  36.390                        new GetPropertyAction("impl.prefix", ""));
  36.391 -        impl = null;
  36.392          try {
  36.393              impl = Class.forName("java.net." + prefix + implName).newInstance();
  36.394          } catch (ClassNotFoundException e) {
  36.395 @@ -1471,7 +1467,7 @@
  36.396              }
  36.397          }
  36.398  
  36.399 -        return impl;
  36.400 +        return (InetAddressImpl) impl;
  36.401      }
  36.402  
  36.403      private void readObjectNoData (ObjectInputStream s) throws
  36.404 @@ -1498,13 +1494,8 @@
  36.405  class InetAddressImplFactory {
  36.406  
  36.407      static InetAddressImpl create() {
  36.408 -        Object o;
  36.409 -        if (isIPv6Supported()) {
  36.410 -            o = InetAddress.loadImpl("Inet6AddressImpl");
  36.411 -        } else {
  36.412 -            o = InetAddress.loadImpl("Inet4AddressImpl");
  36.413 -        }
  36.414 -        return (InetAddressImpl)o;
  36.415 +        return InetAddress.loadImpl(isIPv6Supported() ?
  36.416 +                                    "Inet6AddressImpl" : "Inet4AddressImpl");
  36.417      }
  36.418  
  36.419      static native boolean isIPv6Supported();
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/src/share/classes/java/nio/file/FileSystemLoopException.java	Tue Oct 12 12:51:48 2010 -0700
    37.3 @@ -0,0 +1,50 @@
    37.4 +/*
    37.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
    37.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    37.7 + *
    37.8 + * This code is free software; you can redistribute it and/or modify it
    37.9 + * under the terms of the GNU General Public License version 2 only, as
   37.10 + * published by the Free Software Foundation.  Oracle designates this
   37.11 + * particular file as subject to the "Classpath" exception as provided
   37.12 + * by Oracle in the LICENSE file that accompanied this code.
   37.13 + *
   37.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   37.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   37.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   37.17 + * version 2 for more details (a copy is included in the LICENSE file that
   37.18 + * accompanied this code).
   37.19 + *
   37.20 + * You should have received a copy of the GNU General Public License version
   37.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   37.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   37.23 + *
   37.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   37.25 + * or visit www.oracle.com if you need additional information or have any
   37.26 + * questions.
   37.27 + */
   37.28 +
   37.29 +package java.nio.file;
   37.30 +
   37.31 +/**
   37.32 + * Checked exception thrown when a file system loop, or cycle, is encountered.
   37.33 + *
   37.34 + * @since 1.7
   37.35 + * @see Files#walkFileTree
   37.36 + */
   37.37 +
   37.38 +public class FileSystemLoopException
   37.39 +    extends FileSystemException
   37.40 +{
   37.41 +    private static final long serialVersionUID = 4843039591949217617L;
   37.42 +
   37.43 +    /**
   37.44 +     * Constructs an instance of this class.
   37.45 +     *
   37.46 +     * @param   file
   37.47 +     *          a string identifying the file causing the cycle or {@code null} if
   37.48 +     *          not known
   37.49 +     */
   37.50 +    public FileSystemLoopException(String file) {
   37.51 +        super(file);
   37.52 +    }
   37.53 +}
    38.1 --- a/src/share/classes/java/nio/file/FileTreeWalker.java	Thu Oct 07 15:12:19 2010 -0700
    38.2 +++ b/src/share/classes/java/nio/file/FileTreeWalker.java	Tue Oct 12 12:51:48 2010 -0700
    38.3 @@ -38,7 +38,6 @@
    38.4  
    38.5  class FileTreeWalker {
    38.6      private final boolean followLinks;
    38.7 -    private final boolean detectCycles;
    38.8      private final LinkOption[] linkOptions;
    38.9      private final FileVisitor<? super Path> visitor;
   38.10      private final int maxDepth;
   38.11 @@ -48,17 +47,15 @@
   38.12                     int maxDepth)
   38.13      {
   38.14          boolean fl = false;
   38.15 -        boolean dc = false;
   38.16          for (FileVisitOption option: options) {
   38.17 +            // will throw NPE if options contains null
   38.18              switch (option) {
   38.19 -                case FOLLOW_LINKS  : fl = true; break;
   38.20 -                case DETECT_CYCLES : dc = true; break;
   38.21 +                case FOLLOW_LINKS : fl = true; break;
   38.22                  default:
   38.23                      throw new AssertionError("Should not get here");
   38.24              }
   38.25          }
   38.26          this.followLinks = fl;
   38.27 -        this.detectCycles = fl | dc;
   38.28          this.linkOptions = (fl) ? new LinkOption[0] :
   38.29              new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
   38.30          this.visitor = visitor;
   38.31 @@ -68,13 +65,11 @@
   38.32      /**
   38.33       * Walk file tree starting at the given file
   38.34       */
   38.35 -    void walk(Path start) {
   38.36 +    void walk(Path start) throws IOException {
   38.37          FileVisitResult result = walk(start,
   38.38                                        0,
   38.39                                        new ArrayList<AncestorDirectory>());
   38.40 -        if (result == null) {
   38.41 -            throw new NullPointerException("Visitor returned 'null'");
   38.42 -        }
   38.43 +        Objects.nonNull(result, "FileVisitor returned null");
   38.44      }
   38.45  
   38.46      /**
   38.47 @@ -88,11 +83,8 @@
   38.48      private FileVisitResult walk(Path file,
   38.49                                   int depth,
   38.50                                   List<AncestorDirectory> ancestors)
   38.51 +        throws IOException
   38.52      {
   38.53 -        // depth check
   38.54 -        if (depth > maxDepth)
   38.55 -            return FileVisitResult.CONTINUE;
   38.56 -
   38.57          // if attributes are cached then use them if possible
   38.58          BasicFileAttributes attrs = null;
   38.59          if ((depth > 0) &&
   38.60 @@ -137,13 +129,13 @@
   38.61              return visitor.visitFileFailed(file, exc);
   38.62          }
   38.63  
   38.64 -        // file is not a directory so invoke visitFile method
   38.65 -        if (!attrs.isDirectory()) {
   38.66 +        // at maximum depth or file is not a directory
   38.67 +        if (depth >= maxDepth || !attrs.isDirectory()) {
   38.68              return visitor.visitFile(file, attrs);
   38.69          }
   38.70  
   38.71 -        // check for cycles
   38.72 -        if (detectCycles) {
   38.73 +        // check for cycles when following links
   38.74 +        if (followLinks) {
   38.75              Object key = attrs.fileKey();
   38.76  
   38.77              // if this directory and ancestor has a file key then we compare
   38.78 @@ -153,19 +145,23 @@
   38.79                  if (key != null && ancestorKey != null) {
   38.80                      if (key.equals(ancestorKey)) {
   38.81                          // cycle detected
   38.82 -                        return visitor.visitFile(file, attrs);
   38.83 +                        return visitor.visitFileFailed(file,
   38.84 +                            new FileSystemLoopException(file.toString()));
   38.85                      }
   38.86                  } else {
   38.87 +                    boolean isSameFile = false;
   38.88                      try {
   38.89 -                        if (file.isSameFile(ancestor.file())) {
   38.90 -                            // cycle detected
   38.91 -                            return visitor.visitFile(file, attrs);
   38.92 -                        }
   38.93 +                        isSameFile = file.isSameFile(ancestor.file());
   38.94                      } catch (IOException x) {
   38.95                          // ignore
   38.96                      } catch (SecurityException x) {
   38.97                          // ignore
   38.98                      }
   38.99 +                    if (isSameFile) {
  38.100 +                        // cycle detected
  38.101 +                        return visitor.visitFileFailed(file,
  38.102 +                            new FileSystemLoopException(file.toString()));
  38.103 +                    }
  38.104                  }
  38.105              }
  38.106  
  38.107 @@ -181,7 +177,7 @@
  38.108              try {
  38.109                  stream = file.newDirectoryStream();
  38.110              } catch (IOException x) {
  38.111 -                return visitor.preVisitDirectoryFailed(file, x);
  38.112 +                return visitor.visitFileFailed(file, x);
  38.113              } catch (SecurityException x) {
  38.114                  // ignore, as per spec
  38.115                  return FileVisitResult.CONTINUE;
  38.116 @@ -192,20 +188,14 @@
  38.117  
  38.118              // invoke preVisitDirectory and then visit each entry
  38.119              try {
  38.120 -                result = visitor.preVisitDirectory(file);
  38.121 +                result = visitor.preVisitDirectory(file, attrs);
  38.122                  if (result != FileVisitResult.CONTINUE) {
  38.123                      return result;
  38.124                  }
  38.125  
  38.126 -                // if an I/O occurs during iteration then a CME is thrown. We
  38.127 -                // need to distinguish this from a CME thrown by the visitor.
  38.128 -                boolean inAction = false;
  38.129 -
  38.130                  try {
  38.131                      for (Path entry: stream) {
  38.132 -                        inAction = true;
  38.133                          result = walk(entry, depth+1, ancestors);
  38.134 -                        inAction = false;
  38.135  
  38.136                          // returning null will cause NPE to be thrown
  38.137                          if (result == null || result == FileVisitResult.TERMINATE)
  38.138 @@ -215,17 +205,9 @@
  38.139                          if (result == FileVisitResult.SKIP_SIBLINGS)
  38.140                              break;
  38.141                      }
  38.142 -                } catch (ConcurrentModificationException x) {
  38.143 -                    // if CME thrown because the iteration failed then remember
  38.144 -                    // the IOException so that it is notified to postVisitDirectory
  38.145 -                    if (!inAction) {
  38.146 -                        // iteration failed
  38.147 -                        Throwable t = x.getCause();
  38.148 -                        if (t instanceof IOException)
  38.149 -                            ioe = (IOException)t;
  38.150 -                    }
  38.151 -                    if (ioe == null)
  38.152 -                        throw x;
  38.153 +                } catch (DirectoryIteratorException e) {
  38.154 +                    // IOException will be notified to postVisitDirectory
  38.155 +                    ioe = e.getCause();
  38.156                  }
  38.157              } finally {
  38.158                  try {
  38.159 @@ -238,7 +220,7 @@
  38.160  
  38.161          } finally {
  38.162              // remove key from trail if doing cycle detection
  38.163 -            if (detectCycles) {
  38.164 +            if (followLinks) {
  38.165                  ancestors.remove(ancestors.size()-1);
  38.166              }
  38.167          }
    39.1 --- a/src/share/classes/java/nio/file/FileVisitOption.java	Thu Oct 07 15:12:19 2010 -0700
    39.2 +++ b/src/share/classes/java/nio/file/FileVisitOption.java	Tue Oct 12 12:51:48 2010 -0700
    39.3 @@ -37,9 +37,5 @@
    39.4      /**
    39.5       * Follow symbolic links.
    39.6       */
    39.7 -    FOLLOW_LINKS,
    39.8 -    /**
    39.9 -     * Detect cycles in the file tree.
   39.10 -     */
   39.11 -    DETECT_CYCLES;
   39.12 +    FOLLOW_LINKS;
   39.13  }
    40.1 --- a/src/share/classes/java/nio/file/FileVisitor.java	Thu Oct 07 15:12:19 2010 -0700
    40.2 +++ b/src/share/classes/java/nio/file/FileVisitor.java	Tue Oct 12 12:51:48 2010 -0700
    40.3 @@ -40,33 +40,28 @@
    40.4   *     Path start = ...
    40.5   *     Files.walkFileTree(start, new SimpleFileVisitor&lt;Path&gt;() {
    40.6   *         &#64;Override
    40.7 - *         public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
    40.8 - *             try {
    40.9 - *                 file.delete();
   40.10 - *             } catch (IOException exc) {
   40.11 - *                 // failed to delete, do error handling here
   40.12 - *             }
   40.13 + *         public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
   40.14 + *             throws IOException
   40.15 + *         {
   40.16 + *             file.delete();
   40.17   *             return FileVisitResult.CONTINUE;
   40.18   *         }
   40.19   *         &#64;Override
   40.20 - *         public FileVisitResult postVisitDirectory(Path dir, IOException e) {
   40.21 - *             if (e == null) {
   40.22 - *                 try {
   40.23 - *                     dir.delete();
   40.24 - *                 } catch (IOException exc) {
   40.25 - *                     // failed to delete, do error handling here
   40.26 - *                 }
   40.27 - *             } else {
   40.28 + *         public FileVisitResult postVisitDirectory(Path dir, IOException e)
   40.29 + *             throws IOException
   40.30 + *         {
   40.31 + *             if (e != null) {
   40.32   *                 // directory iteration failed
   40.33 + *                 throw e;
   40.34   *             }
   40.35 + *             dir.delete();
   40.36   *             return FileVisitResult.CONTINUE;
   40.37   *         }
   40.38   *     });
   40.39   * </pre>
   40.40 - * <p> Furthermore, suppose we want to copy a file tree rooted at a source
   40.41 - * directory to a target location. In that case, symbolic links should be
   40.42 - * followed and the target directory should be created before the entries in
   40.43 - * the directory are copied.
   40.44 + * <p> Furthermore, suppose we want to copy a file tree to a target location.
   40.45 + * In that case, symbolic links should be followed and the target directory
   40.46 + * should be created before the entries in the directory are copied.
   40.47   * <pre>
   40.48   *     final Path source = ...
   40.49   *     final Path target = ...
   40.50 @@ -74,25 +69,21 @@
   40.51   *     Files.walkFileTree(source, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
   40.52   *         new SimpleFileVisitor&lt;Path&gt;() {
   40.53   *             &#64;Override
   40.54 - *             public FileVisitResult preVisitDirectory(Path dir) {
   40.55 + *             public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
   40.56 + *                 throws IOException
   40.57 + *             {
   40.58   *                 try {
   40.59   *                     dir.copyTo(target.resolve(source.relativize(dir)));
   40.60   *                 } catch (FileAlreadyExistsException e) {
   40.61   *                      // ignore
   40.62 - *                 } catch (IOException e) {
   40.63 - *                     // copy failed, do error handling here
   40.64 - *                     // skip rest of directory and descendants
   40.65 - *                     return SKIP_SUBTREE;
   40.66   *                 }
   40.67   *                 return CONTINUE;
   40.68   *             }
   40.69   *             &#64;Override
   40.70 - *             public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
   40.71 - *                 try {
   40.72 - *                     file.copyTo(target.resolve(source.relativize(file)));
   40.73 - *                 } catch (IOException e) {
   40.74 - *                     // copy failed, do error handling here
   40.75 - *                 }
   40.76 + *             public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
   40.77 + *                 throws IOException
   40.78 + *             {
   40.79 + *                 file.copyTo(target.resolve(source.relativize(file)));
   40.80   *                 return CONTINUE;
   40.81   *             }
   40.82   *         });
   40.83 @@ -114,22 +105,16 @@
   40.84       *
   40.85       * @param   dir
   40.86       *          a reference to the directory
   40.87 +     * @param   attrs
   40.88 +     *          the directory's basic attributes
   40.89       *
   40.90       * @return  the visit result
   40.91 +     *
   40.92 +     * @throws  IOException
   40.93 +     *          if an I/O error occurs
   40.94       */
   40.95 -    FileVisitResult preVisitDirectory(T dir);
   40.96 -
   40.97 -    /**
   40.98 -     * Invoked for a directory that could not be opened.
   40.99 -     *
  40.100 -     * @param   dir
  40.101 -     *          a reference to the directory
  40.102 -     * @param   exc
  40.103 -     *          the I/O exception thrown from the attempt to open the directory
  40.104 -     *
  40.105 -     * @return  the visit result
  40.106 -     */
  40.107 -    FileVisitResult preVisitDirectoryFailed(T dir, IOException exc);
  40.108 +    FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
  40.109 +        throws IOException;
  40.110  
  40.111      /**
  40.112       * Invoked for a file in a directory.
  40.113 @@ -140,21 +125,30 @@
  40.114       *          the file's basic attributes
  40.115       *
  40.116       * @return  the visit result
  40.117 +     *
  40.118 +     * @throws  IOException
  40.119 +     *          if an I/O error occurs
  40.120       */
  40.121 -    FileVisitResult visitFile(T file, BasicFileAttributes attrs);
  40.122 +    FileVisitResult visitFile(T file, BasicFileAttributes attrs)
  40.123 +        throws IOException;
  40.124  
  40.125      /**
  40.126 -     * Invoked for a file when its basic file attributes could not be read.
  40.127 +     * Invoked for a file that could not be visited. This method is invoked
  40.128 +     * if the file's attributes could not be read, the file is a directory
  40.129 +     * that could not be opened, and other reasons.
  40.130       *
  40.131       * @param   file
  40.132       *          a reference to the file
  40.133       * @param   exc
  40.134 -     *          the I/O exception thrown from the attempt to read the file
  40.135 -     *          attributes
  40.136 +     *          the I/O exception that prevented the file from being visited
  40.137       *
  40.138       * @return  the visit result
  40.139 +     *
  40.140 +     * @throws  IOException
  40.141 +     *          if an I/O error occurs
  40.142       */
  40.143 -    FileVisitResult visitFileFailed(T file, IOException exc);
  40.144 +    FileVisitResult visitFileFailed(T file, IOException exc)
  40.145 +        throws IOException;
  40.146  
  40.147      /**
  40.148       * Invoked for a directory after entries in the directory, and all of their
  40.149 @@ -171,6 +165,10 @@
  40.150       *          of the directory to complete prematurely
  40.151       *
  40.152       * @return  the visit result
  40.153 +     *
  40.154 +     * @throws  IOException
  40.155 +     *          if an I/O error occurs
  40.156       */
  40.157 -    FileVisitResult postVisitDirectory(T dir, IOException exc);
  40.158 +    FileVisitResult postVisitDirectory(T dir, IOException exc)
  40.159 +        throws IOException;
  40.160  }
    41.1 --- a/src/share/classes/java/nio/file/Files.java	Thu Oct 07 15:12:19 2010 -0700
    41.2 +++ b/src/share/classes/java/nio/file/Files.java	Tue Oct 12 12:51:48 2010 -0700
    41.3 @@ -135,9 +135,9 @@
    41.4       * FileVisitor} invoked for each file encountered. File tree traversal
    41.5       * completes when all accessible files in the tree have been visited, or a
    41.6       * visit method returns a result of {@link FileVisitResult#TERMINATE
    41.7 -     * TERMINATE}. Where a visit method terminates due an uncaught error or
    41.8 -     * runtime exception then the traversal is terminated and the error or
    41.9 -     * exception is propagated to the caller of this method.
   41.10 +     * TERMINATE}. Where a visit method terminates due an {@code IOException},
   41.11 +     * an uncaught error, or runtime exception, then the traversal is terminated
   41.12 +     * and the error or exception is propagated to the caller of this method.
   41.13       *
   41.14       * <p> For each file encountered this method attempts to gets its {@link
   41.15       * java.nio.file.attribute.BasicFileAttributes}. If the file is not a
   41.16 @@ -146,12 +146,10 @@
   41.17       * due to an I/O exception, then the {@link FileVisitor#visitFileFailed
   41.18       * visitFileFailed} method is invoked with the I/O exception.
   41.19       *
   41.20 -     * <p> Where the file is a directory, this method attempts to open it by
   41.21 -     * invoking its {@link Path#newDirectoryStream newDirectoryStream} method.
   41.22 -     * Where the directory could not be opened, due to an {@code IOException},
   41.23 -     * then the {@link FileVisitor#preVisitDirectoryFailed preVisitDirectoryFailed}
   41.24 -     * method is invoked with the I/O exception, after which, the file tree walk
   41.25 -     * continues, by default, at the next <em>sibling</em> of the directory.
   41.26 +     * <p> Where the file is a directory, and the directory could not be opened,
   41.27 +     * then the {@code visitFileFailed} method is invoked with the I/O exception,
   41.28 +     * after which, the file tree walk continues, by default, at the next
   41.29 +     * <em>sibling</em> of the directory.
   41.30       *
   41.31       * <p> Where the directory is opened successfully, then the entries in the
   41.32       * directory, and their <em>descendants</em> are visited. When all entries
   41.33 @@ -171,26 +169,25 @@
   41.34       * method is invoked as specified above).
   41.35       *
   41.36       * <p> If the {@code options} parameter contains the {@link
   41.37 -     * FileVisitOption#DETECT_CYCLES DETECT_CYCLES} or {@link
   41.38 -     * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} options then this method keeps
   41.39 +     * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then this method keeps
   41.40       * track of directories visited so that cycles can be detected. A cycle
   41.41       * arises when there is an entry in a directory that is an ancestor of the
   41.42       * directory. Cycle detection is done by recording the {@link
   41.43       * java.nio.file.attribute.BasicFileAttributes#fileKey file-key} of directories,
   41.44       * or if file keys are not available, by invoking the {@link Path#isSameFile
   41.45       * isSameFile} method to test if a directory is the same file as an
   41.46 -     * ancestor. When a cycle is detected the {@link FileVisitor#visitFile
   41.47 -     * visitFile} is invoked with the attributes of the directory. The {@link
   41.48 -     * java.nio.file.attribute.BasicFileAttributes#isDirectory isDirectory}
   41.49 -     * method may be used to test if the file is a directory and that a cycle is
   41.50 -     * detected. The {@code preVisitDirectory} and {@code postVisitDirectory}
   41.51 -     * methods are not invoked.
   41.52 +     * ancestor. When a cycle is detected it is treated as an I/O error, and the
   41.53 +     * {@link FileVisitor#visitFileFailed visitFileFailed} method is invoked with
   41.54 +     * an instance of {@link FileSystemLoopException}.
   41.55       *
   41.56       * <p> The {@code maxDepth} parameter is the maximum number of levels of
   41.57       * directories to visit. A value of {@code 0} means that only the starting
   41.58       * file is visited, unless denied by the security manager. A value of
   41.59       * {@link Integer#MAX_VALUE MAX_VALUE} may be used to indicate that all
   41.60 -     * levels should be visited.
   41.61 +     * levels should be visited. The {@code visitFile} method is invoked for all
   41.62 +     * files, including directories, encountered at {@code maxDepth}, unless the
   41.63 +     * basic file attributes cannot be read, in which case the {@code
   41.64 +     * visitFileFailed} method is invoked.
   41.65       *
   41.66       * <p> If a visitor returns a result of {@code null} then {@code
   41.67       * NullPointerException} is thrown.
   41.68 @@ -215,11 +212,14 @@
   41.69       *          In the case of the default provider, the {@link
   41.70       *          SecurityManager#checkRead(String) checkRead} method is invoked
   41.71       *          to check read access to the directory.
   41.72 +     * @throws  IOException
   41.73 +     *          If an I/O error is thrown by a visitor method
   41.74       */
   41.75      public static void walkFileTree(Path start,
   41.76                                      Set<FileVisitOption> options,
   41.77                                      int maxDepth,
   41.78                                      FileVisitor<? super Path> visitor)
   41.79 +        throws IOException
   41.80      {
   41.81          if (maxDepth < 0)
   41.82              throw new IllegalArgumentException("'maxDepth' is negative");
   41.83 @@ -245,8 +245,12 @@
   41.84       *          In the case of the default provider, the {@link
   41.85       *          SecurityManager#checkRead(String) checkRead} method is invoked
   41.86       *          to check read access to the directory.
   41.87 +     * @throws  IOException
   41.88 +     *          If an I/O error is thrown by a visitor method
   41.89       */
   41.90 -    public static void walkFileTree(Path start, FileVisitor<? super Path> visitor) {
   41.91 +    public static void walkFileTree(Path start, FileVisitor<? super Path> visitor)
   41.92 +        throws IOException
   41.93 +    {
   41.94          walkFileTree(start,
   41.95                       EnumSet.noneOf(FileVisitOption.class),
   41.96                       Integer.MAX_VALUE,
    42.1 --- a/src/share/classes/java/nio/file/SimpleFileVisitor.java	Thu Oct 07 15:12:19 2010 -0700
    42.2 +++ b/src/share/classes/java/nio/file/SimpleFileVisitor.java	Tue Oct 12 12:51:48 2010 -0700
    42.3 @@ -27,7 +27,7 @@
    42.4  
    42.5  import java.nio.file.attribute.BasicFileAttributes;
    42.6  import java.io.IOException;
    42.7 -import java.io.IOError;
    42.8 +import java.util.Objects;
    42.9  
   42.10  /**
   42.11   * A simple visitor of files with default behavior to visit all files and to
   42.12 @@ -48,70 +48,47 @@
   42.13      }
   42.14  
   42.15      /**
   42.16 -     * Throws NullPointerException if obj is null.
   42.17 -     */
   42.18 -    private static void checkNotNull(Object obj) {
   42.19 -        if (obj == null)
   42.20 -            throw new NullPointerException();
   42.21 -    }
   42.22 -
   42.23 -    /**
   42.24       * Invoked for a directory before entries in the directory are visited.
   42.25       *
   42.26       * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
   42.27       * CONTINUE}.
   42.28       */
   42.29      @Override
   42.30 -    public FileVisitResult preVisitDirectory(T dir) {
   42.31 -        checkNotNull(dir);
   42.32 +    public FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
   42.33 +        throws IOException
   42.34 +    {
   42.35 +        Objects.nonNull(dir);
   42.36 +        Objects.nonNull(attrs);
   42.37          return FileVisitResult.CONTINUE;
   42.38      }
   42.39  
   42.40      /**
   42.41 -     * Invoked for a directory that could not be opened.
   42.42 -     *
   42.43 -     * <p> Unless overridden, this method throws {@link IOError} with the I/O
   42.44 -     * exception as cause.
   42.45 -     *
   42.46 -     * @throws  IOError
   42.47 -     *          with the I/O exception thrown when the attempt to open the
   42.48 -     *          directory failed
   42.49 -     */
   42.50 -    @Override
   42.51 -    public FileVisitResult preVisitDirectoryFailed(T dir, IOException exc) {
   42.52 -        checkNotNull(dir);
   42.53 -        checkNotNull(exc);
   42.54 -        throw new IOError(exc);
   42.55 -    }
   42.56 -
   42.57 -    /**
   42.58       * Invoked for a file in a directory.
   42.59       *
   42.60       * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
   42.61       * CONTINUE}.
   42.62       */
   42.63      @Override
   42.64 -    public FileVisitResult visitFile(T file, BasicFileAttributes attrs) {
   42.65 -        checkNotNull(file);
   42.66 -        checkNotNull(attrs);
   42.67 +    public FileVisitResult visitFile(T file, BasicFileAttributes attrs)
   42.68 +        throws IOException
   42.69 +    {
   42.70 +        Objects.nonNull(file);
   42.71 +        Objects.nonNull(attrs);
   42.72          return FileVisitResult.CONTINUE;
   42.73      }
   42.74  
   42.75      /**
   42.76 -     * Invoked for a file when its basic file attributes could not be read.
   42.77 +     * Invoked for a file that could not be visited.
   42.78       *
   42.79 -     * <p> Unless overridden, this method throws {@link IOError} with the I/O
   42.80 -     * exception as cause.
   42.81 -     *
   42.82 -     * @throws  IOError
   42.83 -     *          with the I/O exception thrown when the attempt to read the file
   42.84 -     *          attributes failed
   42.85 +     * <p> Unless overridden, this method re-throws the I/O exception that prevented
   42.86 +     * the file from being visited.
   42.87       */
   42.88      @Override
   42.89 -    public FileVisitResult visitFileFailed(T file, IOException exc) {
   42.90 -        checkNotNull(file);
   42.91 -        checkNotNull(exc);
   42.92 -        throw new IOError(exc);
   42.93 +    public FileVisitResult visitFileFailed(T file, IOException exc)
   42.94 +        throws IOException
   42.95 +    {
   42.96 +        Objects.nonNull(file);
   42.97 +        throw exc;
   42.98      }
   42.99  
  42.100      /**
  42.101 @@ -120,18 +97,16 @@
  42.102       *
  42.103       * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
  42.104       * CONTINUE} if the directory iteration completes without an I/O exception;
  42.105 -     * otherwise this method throws {@link IOError} with the I/O exception as
  42.106 -     * cause.
  42.107 -     *
  42.108 -     * @throws  IOError
  42.109 -     *          with the I/O exception thrown when iteration of the directory
  42.110 -     *          completed prematurely due to an I/O error
  42.111 +     * otherwise this method re-throws the I/O exception that caused the iteration
  42.112 +     * of the directory to terminate prematurely.
  42.113       */
  42.114      @Override
  42.115 -    public FileVisitResult postVisitDirectory(T dir, IOException exc) {
  42.116 -        checkNotNull(dir);
  42.117 +    public FileVisitResult postVisitDirectory(T dir, IOException exc)
  42.118 +        throws IOException
  42.119 +    {
  42.120 +        Objects.nonNull(dir);
  42.121          if (exc != null)
  42.122 -            throw new IOError(exc);
  42.123 +            throw exc;
  42.124          return FileVisitResult.CONTINUE;
  42.125      }
  42.126  }
    43.1 --- a/src/share/classes/java/sql/DatabaseMetaData.java	Thu Oct 07 15:12:19 2010 -0700
    43.2 +++ b/src/share/classes/java/sql/DatabaseMetaData.java	Tue Oct 12 12:51:48 2010 -0700
    43.3 @@ -3643,7 +3643,7 @@
    43.4  
    43.5      /**
    43.6       * Retrieves whether a generated key will always be returned if the column
    43.7 -     * name(s) or indexe(s) specified for the auto generated key column(s)
    43.8 +     * name(s) or index(es) specified for the auto generated key column(s)
    43.9       * are valid and the statement succeeds.  The key that is returned may or
   43.10       * may not be based on the column(s) for the auto generated key.
   43.11       * Consult your JDBC driver documentation for additional details.
    44.1 --- a/src/share/classes/java/sql/Statement.java	Thu Oct 07 15:12:19 2010 -0700
    44.2 +++ b/src/share/classes/java/sql/Statement.java	Tue Oct 12 12:51:48 2010 -0700
    44.3 @@ -1051,9 +1051,9 @@
    44.4  
    44.5      /**
    44.6       * Returns a value indicating whether this {@code Statement} will be
    44.7 -     * closed when all dependent objects such as resultsets are closed.
    44.8 +     * closed when all its dependent result sets are closed.
    44.9       * @return {@code true} if the {@code Statement} will be closed when all
   44.10 -     * of its dependent objects are closed; {@code false} otherwise
   44.11 +     * of its dependent result sets are closed; {@code false} otherwise
   44.12       * @throws SQLException if this method is called on a closed
   44.13       * {@code Statement}
   44.14       * @since 1.7
    45.1 --- a/src/share/classes/java/util/Locale.java	Thu Oct 07 15:12:19 2010 -0700
    45.2 +++ b/src/share/classes/java/util/Locale.java	Tue Oct 12 12:51:48 2010 -0700
    45.3 @@ -569,6 +569,9 @@
    45.4       * @exception NullPointerException thrown if any argument is null.
    45.5       */
    45.6      public Locale(String language, String country, String variant) {
    45.7 +        if (language== null || country == null || variant == null) {
    45.8 +            throw new NullPointerException();
    45.9 +        }
   45.10          _baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), "", country, variant);
   45.11          _extensions = getCompatibilityExtensions(language, "", country, variant);
   45.12      }
    46.1 --- a/src/share/classes/java/util/ResourceBundle.java	Thu Oct 07 15:12:19 2010 -0700
    46.2 +++ b/src/share/classes/java/util/ResourceBundle.java	Tue Oct 12 12:51:48 2010 -0700
    46.3 @@ -293,16 +293,6 @@
    46.4          = new ConcurrentHashMap<CacheKey, BundleReference>(INITIAL_CACHE_SIZE);
    46.5  
    46.6      /**
    46.7 -     * This ConcurrentMap is used to keep multiple threads from loading the
    46.8 -     * same bundle concurrently.  The table entries are <CacheKey, Thread>
    46.9 -     * where CacheKey is the key for the bundle that is under construction
   46.10 -     * and Thread is the thread that is constructing the bundle.
   46.11 -     * This list is manipulated in findBundleInCache and putBundleInCache.
   46.12 -     */
   46.13 -    private static final ConcurrentMap<CacheKey, Thread> underConstruction
   46.14 -        = new ConcurrentHashMap<CacheKey, Thread>();
   46.15 -
   46.16 -    /**
   46.17       * Queue for reference objects referring to class loaders or bundles.
   46.18       */
   46.19      private static final ReferenceQueue referenceQueue = new ReferenceQueue();
   46.20 @@ -1381,7 +1371,7 @@
   46.21          boolean expiredBundle = false;
   46.22  
   46.23          // First, look up the cache to see if it's in the cache, without
   46.24 -        // declaring beginLoading.
   46.25 +        // attempting to load bundle.
   46.26          cacheKey.setLocale(targetLocale);
   46.27          ResourceBundle bundle = findBundleInCache(cacheKey, control);
   46.28          if (isValidBundle(bundle)) {
   46.29 @@ -1408,56 +1398,25 @@
   46.30              CacheKey constKey = (CacheKey) cacheKey.clone();
   46.31  
   46.32              try {
   46.33 -                // Try declaring loading. If beginLoading() returns true,
   46.34 -                // then we can proceed. Otherwise, we need to take a look
   46.35 -                // at the cache again to see if someone else has loaded
   46.36 -                // the bundle and put it in the cache while we've been
   46.37 -                // waiting for other loading work to complete.
   46.38 -                while (!beginLoading(constKey)) {
   46.39 -                    bundle = findBundleInCache(cacheKey, control);
   46.40 -                    if (bundle == null) {
   46.41 -                        continue;
   46.42 +                bundle = loadBundle(cacheKey, formats, control, expiredBundle);
   46.43 +                if (bundle != null) {
   46.44 +                    if (bundle.parent == null) {
   46.45 +                        bundle.setParent(parent);
   46.46                      }
   46.47 -                    if (bundle == NONEXISTENT_BUNDLE) {
   46.48 -                        // If the bundle is NONEXISTENT_BUNDLE, the bundle doesn't exist.
   46.49 -                        return parent;
   46.50 -                    }
   46.51 -                    expiredBundle = bundle.expired;
   46.52 -                    if (!expiredBundle) {
   46.53 -                        if (bundle.parent == parent) {
   46.54 -                            return bundle;
   46.55 -                        }
   46.56 -                        BundleReference bundleRef = cacheList.get(cacheKey);
   46.57 -                        if (bundleRef != null && bundleRef.get() == bundle) {
   46.58 -                            cacheList.remove(cacheKey, bundleRef);
   46.59 -                        }
   46.60 -                    }
   46.61 +                    bundle.locale = targetLocale;
   46.62 +                    bundle = putBundleInCache(cacheKey, bundle, control);
   46.63 +                    return bundle;
   46.64                  }
   46.65  
   46.66 -                try {
   46.67 -                    bundle = loadBundle(cacheKey, formats, control, expiredBundle);
   46.68 -                    if (bundle != null) {
   46.69 -                        if (bundle.parent == null) {
   46.70 -                            bundle.setParent(parent);
   46.71 -                        }
   46.72 -                        bundle.locale = targetLocale;
   46.73 -                        bundle = putBundleInCache(cacheKey, bundle, control);
   46.74 -                        return bundle;
   46.75 -                    }
   46.76 -
   46.77 -                    // Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle
   46.78 -                    // instance for the locale.
   46.79 -                    putBundleInCache(cacheKey, NONEXISTENT_BUNDLE, control);
   46.80 -                } finally {
   46.81 -                    endLoading(constKey);
   46.82 -                }
   46.83 +                // Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle
   46.84 +                // instance for the locale.
   46.85 +                putBundleInCache(cacheKey, NONEXISTENT_BUNDLE, control);
   46.86              } finally {
   46.87                  if (constKey.getCause() instanceof InterruptedException) {
   46.88                      Thread.currentThread().interrupt();
   46.89                  }
   46.90              }
   46.91          }
   46.92 -        assert underConstruction.get(cacheKey) != Thread.currentThread();
   46.93          return parent;
   46.94      }
   46.95  
   46.96 @@ -1465,7 +1424,6 @@
   46.97                                                     List<String> formats,
   46.98                                                     Control control,
   46.99                                                     boolean reload) {
  46.100 -        assert underConstruction.get(cacheKey) == Thread.currentThread();
  46.101  
  46.102          // Here we actually load the bundle in the order of formats
  46.103          // specified by the getFormats() value.
  46.104 @@ -1498,7 +1456,6 @@
  46.105                  break;
  46.106              }
  46.107          }
  46.108 -        assert underConstruction.get(cacheKey) == Thread.currentThread();
  46.109  
  46.110          return bundle;
  46.111      }
  46.112 @@ -1530,57 +1487,6 @@
  46.113      }
  46.114  
  46.115      /**
  46.116 -     * Declares the beginning of actual resource bundle loading. This method
  46.117 -     * returns true if the declaration is successful and the current thread has
  46.118 -     * been put in underConstruction. If someone else has already begun
  46.119 -     * loading, this method waits until that loading work is complete and
  46.120 -     * returns false.
  46.121 -     */
  46.122 -    private static final boolean beginLoading(CacheKey constKey) {
  46.123 -        Thread me = Thread.currentThread();
  46.124 -        Thread worker;
  46.125 -        // We need to declare by putting the current Thread (me) to
  46.126 -        // underConstruction that we are working on loading the specified
  46.127 -        // resource bundle. If we are already working the loading, it means
  46.128 -        // that the resource loading requires a recursive call. In that case,
  46.129 -        // we have to proceed. (4300693)
  46.130 -        if (((worker = underConstruction.putIfAbsent(constKey, me)) == null)
  46.131 -            || worker == me) {
  46.132 -            return true;
  46.133 -        }
  46.134 -
  46.135 -        // If someone else is working on the loading, wait until
  46.136 -        // the Thread finishes the bundle loading.
  46.137 -        synchronized (worker) {
  46.138 -            while (underConstruction.get(constKey) == worker) {
  46.139 -                try {
  46.140 -                    worker.wait();
  46.141 -                } catch (InterruptedException e) {
  46.142 -                    // record the interruption
  46.143 -                    constKey.setCause(e);
  46.144 -                }
  46.145 -            }
  46.146 -        }
  46.147 -        return false;
  46.148 -    }
  46.149 -
  46.150 -    /**
  46.151 -     * Declares the end of the bundle loading. This method calls notifyAll
  46.152 -     * for those who are waiting for this completion.
  46.153 -     */
  46.154 -    private static final void endLoading(CacheKey constKey) {
  46.155 -        // Remove this Thread from the underConstruction map and wake up
  46.156 -        // those who have been waiting for me to complete this bundle
  46.157 -        // loading.
  46.158 -        Thread me = Thread.currentThread();
  46.159 -        assert (underConstruction.get(constKey) == me);
  46.160 -        underConstruction.remove(constKey);
  46.161 -        synchronized (me) {
  46.162 -            me.notifyAll();
  46.163 -        }
  46.164 -    }
  46.165 -
  46.166 -    /**
  46.167       * Throw a MissingResourceException with proper message
  46.168       */
  46.169      private static final void throwMissingResourceException(String baseName,
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java	Tue Oct 12 12:51:48 2010 -0700
    47.3 @@ -0,0 +1,1445 @@
    47.4 +/*
    47.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    47.6 + *
    47.7 + * This code is free software; you can redistribute it and/or modify it
    47.8 + * under the terms of the GNU General Public License version 2 only, as
    47.9 + * published by the Free Software Foundation.  Oracle designates this
   47.10 + * particular file as subject to the "Classpath" exception as provided
   47.11 + * by Oracle in the LICENSE file that accompanied this code.
   47.12 + *
   47.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
   47.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   47.15 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   47.16 + * version 2 for more details (a copy is included in the LICENSE file that
   47.17 + * accompanied this code).
   47.18 + *
   47.19 + * You should have received a copy of the GNU General Public License version
   47.20 + * 2 along with this work; if not, write to the Free Software Foundation,
   47.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   47.22 + *
   47.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   47.24 + * or visit www.oracle.com if you need additional information or have any
   47.25 + * questions.
   47.26 + */
   47.27 +
   47.28 +/*
   47.29 + * This file is available under and governed by the GNU General Public
   47.30 + * License version 2 only, as published by the Free Software Foundation.
   47.31 + * However, the following notice accompanied the original version of this
   47.32 + * file:
   47.33 + *
   47.34 + * Written by Doug Lea and Martin Buchholz with assistance from members of
   47.35 + * JCP JSR-166 Expert Group and released to the public domain, as explained
   47.36 + * at http://creativecommons.org/licenses/publicdomain
   47.37 + */
   47.38 +
   47.39 +package java.util.concurrent;
   47.40 +
   47.41 +import java.util.AbstractCollection;
   47.42 +import java.util.ArrayList;
   47.43 +import java.util.Collection;
   47.44 +import java.util.ConcurrentModificationException;
   47.45 +import java.util.Deque;
   47.46 +import java.util.Iterator;
   47.47 +import java.util.NoSuchElementException;
   47.48 +import java.util.Queue;
   47.49 +
   47.50 +/**
   47.51 + * An unbounded concurrent {@linkplain Deque deque} based on linked nodes.
   47.52 + * Concurrent insertion, removal, and access operations execute safely
   47.53 + * across multiple threads.
   47.54 + * A {@code ConcurrentLinkedDeque} is an appropriate choice when
   47.55 + * many threads will share access to a common collection.
   47.56 + * Like most other concurrent collection implementations, this class
   47.57 + * does not permit the use of {@code null} elements.
   47.58 + *
   47.59 + * <p>Iterators are <i>weakly consistent</i>, returning elements
   47.60 + * reflecting the state of the deque at some point at or since the
   47.61 + * creation of the iterator.  They do <em>not</em> throw {@link
   47.62 + * java.util.ConcurrentModificationException
   47.63 + * ConcurrentModificationException}, and may proceed concurrently with
   47.64 + * other operations.
   47.65 + *
   47.66 + * <p>Beware that, unlike in most collections, the {@code size}
   47.67 + * method is <em>NOT</em> a constant-time operation. Because of the
   47.68 + * asynchronous nature of these deques, determining the current number
   47.69 + * of elements requires a traversal of the elements.
   47.70 + *
   47.71 + * <p>This class and its iterator implement all of the <em>optional</em>
   47.72 + * methods of the {@link Deque} and {@link Iterator} interfaces.
   47.73 + *
   47.74 + * <p>Memory consistency effects: As with other concurrent collections,
   47.75 + * actions in a thread prior to placing an object into a
   47.76 + * {@code ConcurrentLinkedDeque}
   47.77 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
   47.78 + * actions subsequent to the access or removal of that element from
   47.79 + * the {@code ConcurrentLinkedDeque} in another thread.
   47.80 + *
   47.81 + * <p>This class is a member of the
   47.82 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
   47.83 + * Java Collections Framework</a>.
   47.84 + *
   47.85 + * @since 1.7
   47.86 + * @author Doug Lea
   47.87 + * @author Martin Buchholz
   47.88 + * @param <E> the type of elements held in this collection
   47.89 + */
   47.90 +
   47.91 +public class ConcurrentLinkedDeque<E>
   47.92 +    extends AbstractCollection<E>
   47.93 +    implements Deque<E>, java.io.Serializable {
   47.94 +
   47.95 +    /*
   47.96 +     * This is an implementation of a concurrent lock-free deque
   47.97 +     * supporting interior removes but not interior insertions, as
   47.98 +     * required to support the entire Deque interface.
   47.99 +     *
  47.100 +     * We extend the techniques developed for ConcurrentLinkedQueue and
  47.101 +     * LinkedTransferQueue (see the internal docs for those classes).
  47.102 +     * Understanding the ConcurrentLinkedQueue implementation is a
  47.103 +     * prerequisite for understanding the implementation of this class.
  47.104 +     *
  47.105 +     * The data structure is a symmetrical doubly-linked "GC-robust"
  47.106 +     * linked list of nodes.  We minimize the number of volatile writes
  47.107 +     * using two techniques: advancing multiple hops with a single CAS
  47.108 +     * and mixing volatile and non-volatile writes of the same memory
  47.109 +     * locations.
  47.110 +     *
  47.111 +     * A node contains the expected E ("item") and links to predecessor
  47.112 +     * ("prev") and successor ("next") nodes:
  47.113 +     *
  47.114 +     * class Node<E> { volatile Node<E> prev, next; volatile E item; }
  47.115 +     *
  47.116 +     * A node p is considered "live" if it contains a non-null item
  47.117 +     * (p.item != null).  When an item is CASed to null, the item is
  47.118 +     * atomically logically deleted from the collection.
  47.119 +     *
  47.120 +     * At any time, there is precisely one "first" node with a null
  47.121 +     * prev reference that terminates any chain of prev references
  47.122 +     * starting at a live node.  Similarly there is precisely one
  47.123 +     * "last" node terminating any chain of next references starting at
  47.124 +     * a live node.  The "first" and "last" nodes may or may not be live.
  47.125 +     * The "first" and "last" nodes are always mutually reachable.
  47.126 +     *
  47.127 +     * A new element is added atomically by CASing the null prev or
  47.128 +     * next reference in the first or last node to a fresh node
  47.129 +     * containing the element.  The element's node atomically becomes
  47.130 +     * "live" at that point.
  47.131 +     *
  47.132 +     * A node is considered "active" if it is a live node, or the
  47.133 +     * first or last node.  Active nodes cannot be unlinked.
  47.134 +     *
  47.135 +     * A "self-link" is a next or prev reference that is the same node:
  47.136 +     *   p.prev == p  or  p.next == p
  47.137 +     * Self-links are used in the node unlinking process.  Active nodes
  47.138 +     * never have self-links.
  47.139 +     *
  47.140 +     * A node p is active if and only if:
  47.141 +     *
  47.142 +     * p.item != null ||
  47.143 +     * (p.prev == null && p.next != p) ||
  47.144 +     * (p.next == null && p.prev != p)
  47.145 +     *
  47.146 +     * The deque object has two node references, "head" and "tail".
  47.147 +     * The head and tail are only approximations to the first and last
  47.148 +     * nodes of the deque.  The first node can always be found by
  47.149 +     * following prev pointers from head; likewise for tail.  However,
  47.150 +     * it is permissible for head and tail to be referring to deleted
  47.151 +     * nodes that have been unlinked and so may not be reachable from
  47.152 +     * any live node.
  47.153 +     *
  47.154 +     * There are 3 stages of node deletion;
  47.155 +     * "logical deletion", "unlinking", and "gc-unlinking".
  47.156 +     *
  47.157 +     * 1. "logical deletion" by CASing item to null atomically removes
  47.158 +     * the element from the collection, and makes the containing node
  47.159 +     * eligible for unlinking.
  47.160 +     *
  47.161 +     * 2. "unlinking" makes a deleted node unreachable from active
  47.162 +     * nodes, and thus eventually reclaimable by GC.  Unlinked nodes
  47.163 +     * may remain reachable indefinitely from an iterator.
  47.164 +     *
  47.165 +     * Physical node unlinking is merely an optimization (albeit a
  47.166 +     * critical one), and so can be performed at our convenience.  At
  47.167 +     * any time, the set of live nodes maintained by prev and next
  47.168 +     * links are identical, that is, the live nodes found via next
  47.169 +     * links from the first node is equal to the elements found via
  47.170 +     * prev links from the last node.  However, this is not true for
  47.171 +     * nodes that have already been logically deleted - such nodes may
  47.172 +     * be reachable in one direction only.
  47.173 +     *
  47.174 +     * 3. "gc-unlinking" takes unlinking further by making active
  47.175 +     * nodes unreachable from deleted nodes, making it easier for the
  47.176 +     * GC to reclaim future deleted nodes.  This step makes the data
  47.177 +     * structure "gc-robust", as first described in detail by Boehm
  47.178 +     * (http://portal.acm.org/citation.cfm?doid=503272.503282).
  47.179 +     *
  47.180 +     * GC-unlinked nodes may remain reachable indefinitely from an
  47.181 +     * iterator, but unlike unlinked nodes, are never reachable from
  47.182 +     * head or tail.
  47.183 +     *
  47.184 +     * Making the data structure GC-robust will eliminate the risk of
  47.185 +     * unbounded memory retention with conservative GCs and is likely
  47.186 +     * to improve performance with generational GCs.
  47.187 +     *
  47.188 +     * When a node is dequeued at either end, e.g. via poll(), we would
  47.189 +     * like to break any references from the node to active nodes.  We
  47.190 +     * develop further the use of self-links that was very effective in
  47.191 +     * other concurrent collection classes.  The idea is to replace
  47.192 +     * prev and next pointers with special values that are interpreted
  47.193 +     * to mean off-the-list-at-one-end.  These are approximations, but
  47.194 +     * good enough to preserve the properties we want in our
  47.195 +     * traversals, e.g. we guarantee that a traversal will never visit
  47.196 +     * the same element twice, but we don't guarantee whether a
  47.197 +     * traversal that runs out of elements will be able to see more
  47.198 +     * elements later after enqueues at that end.  Doing gc-unlinking
  47.199 +     * safely is particularly tricky, since any node can be in use
  47.200 +     * indefinitely (for example by an iterator).  We must ensure that
  47.201 +     * the nodes pointed at by head/tail never get gc-unlinked, since
  47.202 +     * head/tail are needed to get "back on track" by other nodes that
  47.203 +     * are gc-unlinked.  gc-unlinking accounts for much of the
  47.204 +     * implementation complexity.
  47.205 +     *
  47.206 +     * Since neither unlinking nor gc-unlinking are necessary for
  47.207 +     * correctness, there are many implementation choices regarding
  47.208 +     * frequency (eagerness) of these operations.  Since volatile
  47.209 +     * reads are likely to be much cheaper than CASes, saving CASes by
  47.210 +     * unlinking multiple adjacent nodes at a time may be a win.
  47.211 +     * gc-unlinking can be performed rarely and still be effective,
  47.212 +     * since it is most important that long chains of deleted nodes
  47.213 +     * are occasionally broken.
  47.214 +     *
  47.215 +     * The actual representation we use is that p.next == p means to
  47.216 +     * goto the first node (which in turn is reached by following prev
  47.217 +     * pointers from head), and p.next == null && p.prev == p means
  47.218 +     * that the iteration is at an end and that p is a (final static)
  47.219 +     * dummy node, NEXT_TERMINATOR, and not the last active node.
  47.220 +     * Finishing the iteration when encountering such a TERMINATOR is
  47.221 +     * good enough for read-only traversals, so such traversals can use
  47.222 +     * p.next == null as the termination condition.  When we need to
  47.223 +     * find the last (active) node, for enqueueing a new node, we need
  47.224 +     * to check whether we have reached a TERMINATOR node; if so,
  47.225 +     * restart traversal from tail.
  47.226 +     *
  47.227 +     * The implementation is completely directionally symmetrical,
  47.228 +     * except that most public methods that iterate through the list
  47.229 +     * follow next pointers ("forward" direction).
  47.230 +     *
  47.231 +     * We believe (without full proof) that all single-element deque
  47.232 +     * operations (e.g., addFirst, peekLast, pollLast) are linearizable
  47.233 +     * (see Herlihy and Shavit's book).  However, some combinations of
  47.234 +     * operations are known not to be linearizable.  In particular,
  47.235 +     * when an addFirst(A) is racing with pollFirst() removing B, it is
  47.236 +     * possible for an observer iterating over the elements to observe
  47.237 +     * A B C and subsequently observe A C, even though no interior
  47.238 +     * removes are ever performed.  Nevertheless, iterators behave
  47.239 +     * reasonably, providing the "weakly consistent" guarantees.
  47.240 +     *
  47.241 +     * Empirically, microbenchmarks suggest that this class adds about
  47.242 +     * 40% overhead relative to ConcurrentLinkedQueue, which feels as
  47.243 +     * good as we can hope for.
  47.244 +     */
  47.245 +
  47.246 +    private static final long serialVersionUID = 876323262645176354L;
  47.247 +
  47.248 +    /**
  47.249 +     * A node from which the first node on list (that is, the unique node p
  47.250 +     * with p.prev == null && p.next != p) can be reached in O(1) time.
  47.251 +     * Invariants:
  47.252 +     * - the first node is always O(1) reachable from head via prev links
  47.253 +     * - all live nodes are reachable from the first node via succ()
  47.254 +     * - head != null
  47.255 +     * - (tmp = head).next != tmp || tmp != head
  47.256 +     * - head is never gc-unlinked (but may be unlinked)
  47.257 +     * Non-invariants:
  47.258 +     * - head.item may or may not be null
  47.259 +     * - head may not be reachable from the first or last node, or from tail
  47.260 +     */
  47.261 +    private transient volatile Node<E> head;
  47.262 +
  47.263 +    /**
  47.264 +     * A node from which the last node on list (that is, the unique node p
  47.265 +     * with p.next == null && p.prev != p) can be reached in O(1) time.
  47.266 +     * Invariants:
  47.267 +     * - the last node is always O(1) reachable from tail via next links
  47.268 +     * - all live nodes are reachable from the last node via pred()
  47.269 +     * - tail != null
  47.270 +     * - tail is never gc-unlinked (but may be unlinked)
  47.271 +     * Non-invariants:
  47.272 +     * - tail.item may or may not be null
  47.273 +     * - tail may not be reachable from the first or last node, or from head
  47.274 +     */
  47.275 +    private transient volatile Node<E> tail;
  47.276 +
  47.277 +    private final static Node<Object> PREV_TERMINATOR, NEXT_TERMINATOR;
  47.278 +
  47.279 +    static {
  47.280 +        PREV_TERMINATOR = new Node<Object>(null);
  47.281 +        PREV_TERMINATOR.next = PREV_TERMINATOR;
  47.282 +        NEXT_TERMINATOR = new Node<Object>(null);
  47.283 +        NEXT_TERMINATOR.prev = NEXT_TERMINATOR;
  47.284 +    }
  47.285 +
  47.286 +    @SuppressWarnings("unchecked")
  47.287 +    Node<E> prevTerminator() {
  47.288 +        return (Node<E>) PREV_TERMINATOR;
  47.289 +    }
  47.290 +
  47.291 +    @SuppressWarnings("unchecked")
  47.292 +    Node<E> nextTerminator() {
  47.293 +        return (Node<E>) NEXT_TERMINATOR;
  47.294 +    }
  47.295 +
  47.296 +    static final class Node<E> {
  47.297 +        volatile Node<E> prev;
  47.298 +        volatile E item;
  47.299 +        volatile Node<E> next;
  47.300 +
  47.301 +        /**
  47.302 +         * Constructs a new node.  Uses relaxed write because item can
  47.303 +         * only be seen after publication via casNext or casPrev.
  47.304 +         */
  47.305 +        Node(E item) {
  47.306 +            UNSAFE.putObject(this, itemOffset, item);
  47.307 +        }
  47.308 +
  47.309 +        boolean casItem(E cmp, E val) {
  47.310 +            return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
  47.311 +        }
  47.312 +
  47.313 +        void lazySetNext(Node<E> val) {
  47.314 +            UNSAFE.putOrderedObject(this, nextOffset, val);
  47.315 +        }
  47.316 +
  47.317 +        boolean casNext(Node<E> cmp, Node<E> val) {
  47.318 +            return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
  47.319 +        }
  47.320 +
  47.321 +        void lazySetPrev(Node<E> val) {
  47.322 +            UNSAFE.putOrderedObject(this, prevOffset, val);
  47.323 +        }
  47.324 +
  47.325 +        boolean casPrev(Node<E> cmp, Node<E> val) {
  47.326 +            return UNSAFE.compareAndSwapObject(this, prevOffset, cmp, val);
  47.327 +        }
  47.328 +
  47.329 +        // Unsafe mechanics
  47.330 +
  47.331 +        private static final sun.misc.Unsafe UNSAFE =
  47.332 +            sun.misc.Unsafe.getUnsafe();
  47.333 +        private static final long prevOffset =
  47.334 +            objectFieldOffset(UNSAFE, "prev", Node.class);
  47.335 +        private static final long itemOffset =
  47.336 +            objectFieldOffset(UNSAFE, "item", Node.class);
  47.337 +        private static final long nextOffset =
  47.338 +            objectFieldOffset(UNSAFE, "next", Node.class);
  47.339 +    }
  47.340 +
  47.341 +    /**
  47.342 +     * Links e as first element.
  47.343 +     */
  47.344 +    private void linkFirst(E e) {
  47.345 +        checkNotNull(e);
  47.346 +        final Node<E> newNode = new Node<E>(e);
  47.347 +
  47.348 +        restartFromHead:
  47.349 +        for (;;)
  47.350 +            for (Node<E> h = head, p = h, q;;) {
  47.351 +                if ((q = p.prev) != null &&
  47.352 +                    (q = (p = q).prev) != null)
  47.353 +                    // Check for head updates every other hop.
  47.354 +                    // If p == q, we are sure to follow head instead.
  47.355 +                    p = (h != (h = head)) ? h : q;
  47.356 +                else if (p.next == p) // PREV_TERMINATOR
  47.357 +                    continue restartFromHead;
  47.358 +                else {
  47.359 +                    // p is first node
  47.360 +                    newNode.lazySetNext(p); // CAS piggyback
  47.361 +                    if (p.casPrev(null, newNode)) {
  47.362 +                        // Successful CAS is the linearization point
  47.363 +                        // for e to become an element of this deque,
  47.364 +                        // and for newNode to become "live".
  47.365 +                        if (p != h) // hop two nodes at a time
  47.366 +                            casHead(h, newNode);  // Failure is OK.
  47.367 +                        return;
  47.368 +                    }
  47.369 +                    // Lost CAS race to another thread; re-read prev
  47.370 +                }
  47.371 +            }
  47.372 +    }
  47.373 +
  47.374 +    /**
  47.375 +     * Links e as last element.
  47.376 +     */
  47.377 +    private void linkLast(E e) {
  47.378 +        checkNotNull(e);
  47.379 +        final Node<E> newNode = new Node<E>(e);
  47.380 +
  47.381 +        restartFromTail:
  47.382 +        for (;;)
  47.383 +            for (Node<E> t = tail, p = t, q;;) {
  47.384 +                if ((q = p.next) != null &&
  47.385 +                    (q = (p = q).next) != null)
  47.386 +                    // Check for tail updates every other hop.
  47.387 +                    // If p == q, we are sure to follow tail instead.
  47.388 +                    p = (t != (t = tail)) ? t : q;
  47.389 +                else if (p.prev == p) // NEXT_TERMINATOR
  47.390 +                    continue restartFromTail;
  47.391 +                else {
  47.392 +                    // p is last node
  47.393 +                    newNode.lazySetPrev(p); // CAS piggyback
  47.394 +                    if (p.casNext(null, newNode)) {
  47.395 +                        // Successful CAS is the linearization point
  47.396 +                        // for e to become an element of this deque,
  47.397 +                        // and for newNode to become "live".
  47.398 +                        if (p != t) // hop two nodes at a time
  47.399 +                            casTail(t, newNode);  // Failure is OK.
  47.400 +                        return;
  47.401 +                    }
  47.402 +                    // Lost CAS race to another thread; re-read next
  47.403 +                }
  47.404 +            }
  47.405 +    }
  47.406 +
  47.407 +    private final static int HOPS = 2;
  47.408 +
  47.409 +    /**
  47.410 +     * Unlinks non-null node x.
  47.411 +     */
  47.412 +    void unlink(Node<E> x) {
  47.413 +        // assert x != null;
  47.414 +        // assert x.item == null;
  47.415 +        // assert x != PREV_TERMINATOR;
  47.416 +        // assert x != NEXT_TERMINATOR;
  47.417 +
  47.418 +        final Node<E> prev = x.prev;
  47.419 +        final Node<E> next = x.next;
  47.420 +        if (prev == null) {
  47.421 +            unlinkFirst(x, next);
  47.422 +        } else if (next == null) {
  47.423 +            unlinkLast(x, prev);
  47.424 +        } else {
  47.425 +            // Unlink interior node.
  47.426 +            //
  47.427 +            // This is the common case, since a series of polls at the
  47.428 +            // same end will be "interior" removes, except perhaps for
  47.429 +            // the first one, since end nodes cannot be unlinked.
  47.430 +            //
  47.431 +            // At any time, all active nodes are mutually reachable by
  47.432 +            // following a sequence of either next or prev pointers.
  47.433 +            //
  47.434 +            // Our strategy is to find the unique active predecessor
  47.435 +            // and successor of x.  Try to fix up their links so that
  47.436 +            // they point to each other, leaving x unreachable from
  47.437 +            // active nodes.  If successful, and if x has no live
  47.438 +            // predecessor/successor, we additionally try to gc-unlink,
  47.439 +            // leaving active nodes unreachable from x, by rechecking
  47.440 +            // that the status of predecessor and successor are
  47.441 +            // unchanged and ensuring that x is not reachable from
  47.442 +            // tail/head, before setting x's prev/next links to their
  47.443 +            // logical approximate replacements, self/TERMINATOR.
  47.444 +            Node<E> activePred, activeSucc;
  47.445 +            boolean isFirst, isLast;
  47.446 +            int hops = 1;
  47.447 +
  47.448 +            // Find active predecessor
  47.449 +            for (Node<E> p = prev; ; ++hops) {
  47.450 +                if (p.item != null) {
  47.451 +                    activePred = p;
  47.452 +                    isFirst = false;
  47.453 +                    break;
  47.454 +                }
  47.455 +                Node<E> q = p.prev;
  47.456 +                if (q == null) {
  47.457 +                    if (p.next == p)
  47.458 +                        return;
  47.459 +                    activePred = p;
  47.460 +                    isFirst = true;
  47.461 +                    break;
  47.462 +                }
  47.463 +                else if (p == q)
  47.464 +                    return;
  47.465 +                else
  47.466 +                    p = q;
  47.467 +            }
  47.468 +
  47.469 +            // Find active successor
  47.470 +            for (Node<E> p = next; ; ++hops) {
  47.471 +                if (p.item != null) {
  47.472 +                    activeSucc = p;
  47.473 +                    isLast = false;
  47.474 +                    break;
  47.475 +                }
  47.476 +                Node<E> q = p.next;
  47.477 +                if (q == null) {
  47.478 +                    if (p.prev == p)
  47.479 +                        return;
  47.480 +                    activeSucc = p;
  47.481 +                    isLast = true;
  47.482 +                    break;
  47.483 +                }
  47.484 +                else if (p == q)
  47.485 +                    return;
  47.486 +                else
  47.487 +                    p = q;
  47.488 +            }
  47.489 +
  47.490 +            // TODO: better HOP heuristics
  47.491 +            if (hops < HOPS
  47.492 +                // always squeeze out interior deleted nodes
  47.493 +                && (isFirst | isLast))
  47.494 +                return;
  47.495 +
  47.496 +            // Squeeze out deleted nodes between activePred and
  47.497 +            // activeSucc, including x.
  47.498 +            skipDeletedSuccessors(activePred);
  47.499 +            skipDeletedPredecessors(activeSucc);
  47.500 +
  47.501 +            // Try to gc-unlink, if possible
  47.502 +            if ((isFirst | isLast) &&
  47.503 +
  47.504 +                // Recheck expected state of predecessor and successor
  47.505 +                (activePred.next == activeSucc) &&
  47.506 +                (activeSucc.prev == activePred) &&
  47.507 +                (isFirst ? activePred.prev == null : activePred.item != null) &&
  47.508 +                (isLast  ? activeSucc.next == null : activeSucc.item != null)) {
  47.509 +
  47.510 +                updateHead(); // Ensure x is not reachable from head
  47.511 +                updateTail(); // Ensure x is not reachable from tail
  47.512 +
  47.513 +                // Finally, actually gc-unlink
  47.514 +                x.lazySetPrev(isFirst ? prevTerminator() : x);
  47.515 +                x.lazySetNext(isLast  ? nextTerminator() : x);
  47.516 +            }
  47.517 +        }
  47.518 +    }
  47.519 +
  47.520 +    /**
  47.521 +     * Unlinks non-null first node.
  47.522 +     */
  47.523 +    private void unlinkFirst(Node<E> first, Node<E> next) {
  47.524 +        // assert first != null;
  47.525 +        // assert next != null;
  47.526 +        // assert first.item == null;
  47.527 +        for (Node<E> o = null, p = next, q;;) {
  47.528 +            if (p.item != null || (q = p.next) == null) {
  47.529 +                if (o != null && p.prev != p && first.casNext(next, p)) {
  47.530 +                    skipDeletedPredecessors(p);
  47.531 +                    if (first.prev == null &&
  47.532 +                        (p.next == null || p.item != null) &&
  47.533 +                        p.prev == first) {
  47.534 +
  47.535 +                        updateHead(); // Ensure o is not reachable from head
  47.536 +                        updateTail(); // Ensure o is not reachable from tail
  47.537 +
  47.538 +                        // Finally, actually gc-unlink
  47.539 +                        o.lazySetNext(o);
  47.540 +                        o.lazySetPrev(prevTerminator());
  47.541 +                    }
  47.542 +                }
  47.543 +                return;
  47.544 +            }
  47.545 +            else if (p == q)
  47.546 +                return;
  47.547 +            else {
  47.548 +                o = p;
  47.549 +                p = q;
  47.550 +            }
  47.551 +        }
  47.552 +    }
  47.553 +
  47.554 +    /**
  47.555 +     * Unlinks non-null last node.
  47.556 +     */
  47.557 +    private void unlinkLast(Node<E> last, Node<E> prev) {
  47.558 +        // assert last != null;
  47.559 +        // assert prev != null;
  47.560 +        // assert last.item == null;
  47.561 +        for (Node<E> o = null, p = prev, q;;) {
  47.562 +            if (p.item != null || (q = p.prev) == null) {
  47.563 +                if (o != null && p.next != p && last.casPrev(prev, p)) {
  47.564 +                    skipDeletedSuccessors(p);
  47.565 +                    if (last.next == null &&
  47.566 +                        (p.prev == null || p.item != null) &&
  47.567 +                        p.next == last) {
  47.568 +
  47.569 +                        updateHead(); // Ensure o is not reachable from head
  47.570 +                        updateTail(); // Ensure o is not reachable from tail
  47.571 +
  47.572 +                        // Finally, actually gc-unlink
  47.573 +                        o.lazySetPrev(o);
  47.574 +                        o.lazySetNext(nextTerminator());
  47.575 +                    }
  47.576 +                }
  47.577 +                return;
  47.578 +            }
  47.579 +            else if (p == q)
  47.580 +                return;
  47.581 +            else {
  47.582 +                o = p;
  47.583 +                p = q;
  47.584 +            }
  47.585 +        }
  47.586 +    }
  47.587 +
  47.588 +    /**
  47.589 +     * Guarantees that any node which was unlinked before a call to
  47.590 +     * this method will be unreachable from head after it returns.
  47.591 +     * Does not guarantee to eliminate slack, only that head will
  47.592 +     * point to a node that was active while this method was running.
  47.593 +     */
  47.594 +    private final void updateHead() {
  47.595 +        // Either head already points to an active node, or we keep
  47.596 +        // trying to cas it to the first node until it does.
  47.597 +        Node<E> h, p, q;
  47.598 +        restartFromHead:
  47.599 +        while ((h = head).item == null && (p = h.prev) != null) {
  47.600 +            for (;;) {
  47.601 +                if ((q = p.prev) == null ||
  47.602 +                    (q = (p = q).prev) == null) {
  47.603 +                    // It is possible that p is PREV_TERMINATOR,
  47.604 +                    // but if so, the CAS is guaranteed to fail.
  47.605 +                    if (casHead(h, p))
  47.606 +                        return;
  47.607 +                    else
  47.608 +                        continue restartFromHead;
  47.609 +                }
  47.610 +                else if (h != head)
  47.611 +                    continue restartFromHead;
  47.612 +                else
  47.613 +                    p = q;
  47.614 +            }
  47.615 +        }
  47.616 +    }
  47.617 +
  47.618 +    /**
  47.619 +     * Guarantees that any node which was unlinked before a call to
  47.620 +     * this method will be unreachable from tail after it returns.
  47.621 +     * Does not guarantee to eliminate slack, only that tail will
  47.622 +     * point to a node that was active while this method was running.
  47.623 +     */
  47.624 +    private final void updateTail() {
  47.625 +        // Either tail already points to an active node, or we keep
  47.626 +        // trying to cas it to the last node until it does.
  47.627 +        Node<E> t, p, q;
  47.628 +        restartFromTail:
  47.629 +        while ((t = tail).item == null && (p = t.next) != null) {
  47.630 +            for (;;) {
  47.631 +                if ((q = p.next) == null ||
  47.632 +                    (q = (p = q).next) == null) {
  47.633 +                    // It is possible that p is NEXT_TERMINATOR,
  47.634 +                    // but if so, the CAS is guaranteed to fail.
  47.635 +                    if (casTail(t, p))
  47.636 +                        return;
  47.637 +                    else
  47.638 +                        continue restartFromTail;
  47.639 +                }
  47.640 +                else if (t != tail)
  47.641 +                    continue restartFromTail;
  47.642 +                else
  47.643 +                    p = q;
  47.644 +            }
  47.645 +        }
  47.646 +    }
  47.647 +
  47.648 +    private void skipDeletedPredecessors(Node<E> x) {
  47.649 +        whileActive:
  47.650 +        do {
  47.651 +            Node<E> prev = x.prev;
  47.652 +            // assert prev != null;
  47.653 +            // assert x != NEXT_TERMINATOR;
  47.654 +            // assert x != PREV_TERMINATOR;
  47.655 +            Node<E> p = prev;
  47.656 +            findActive:
  47.657 +            for (;;) {
  47.658 +                if (p.item != null)
  47.659 +                    break findActive;
  47.660 +                Node<E> q = p.prev;
  47.661 +                if (q == null) {
  47.662 +                    if (p.next == p)
  47.663 +                        continue whileActive;
  47.664 +                    break findActive;
  47.665 +                }
  47.666 +                else if (p == q)
  47.667 +                    continue whileActive;
  47.668 +                else
  47.669 +                    p = q;
  47.670 +            }
  47.671 +
  47.672 +            // found active CAS target
  47.673 +            if (prev == p || x.casPrev(prev, p))
  47.674 +                return;
  47.675 +
  47.676 +        } while (x.item != null || x.next == null);
  47.677 +    }
  47.678 +
  47.679 +    private void skipDeletedSuccessors(Node<E> x) {
  47.680 +        whileActive:
  47.681 +        do {
  47.682 +            Node<E> next = x.next;
  47.683 +            // assert next != null;
  47.684 +            // assert x != NEXT_TERMINATOR;
  47.685 +            // assert x != PREV_TERMINATOR;
  47.686 +            Node<E> p = next;
  47.687 +            findActive:
  47.688 +            for (;;) {
  47.689 +                if (p.item != null)
  47.690 +                    break findActive;
  47.691 +                Node<E> q = p.next;
  47.692 +                if (q == null) {
  47.693 +                    if (p.prev == p)
  47.694 +                        continue whileActive;
  47.695 +                    break findActive;
  47.696 +                }
  47.697 +                else if (p == q)
  47.698 +                    continue whileActive;
  47.699 +                else
  47.700 +                    p = q;
  47.701 +            }
  47.702 +
  47.703 +            // found active CAS target
  47.704 +            if (next == p || x.casNext(next, p))
  47.705 +                return;
  47.706 +
  47.707 +        } while (x.item != null || x.prev == null);
  47.708 +    }
  47.709 +
  47.710 +    /**
  47.711 +     * Returns the successor of p, or the first node if p.next has been
  47.712 +     * linked to self, which will only be true if traversing with a
  47.713 +     * stale pointer that is now off the list.
  47.714 +     */
  47.715 +    final Node<E> succ(Node<E> p) {
  47.716 +        // TODO: should we skip deleted nodes here?
  47.717 +        Node<E> q = p.next;
  47.718 +        return (p == q) ? first() : q;
  47.719 +    }
  47.720 +
  47.721 +    /**
  47.722 +     * Returns the predecessor of p, or the last node if p.prev has been
  47.723 +     * linked to self, which will only be true if traversing with a
  47.724 +     * stale pointer that is now off the list.
  47.725 +     */
  47.726 +    final Node<E> pred(Node<E> p) {
  47.727 +        Node<E> q = p.prev;
  47.728 +        return (p == q) ? last() : q;
  47.729 +    }
  47.730 +
  47.731 +    /**
  47.732 +     * Returns the first node, the unique node p for which:
  47.733 +     *     p.prev == null && p.next != p
  47.734 +     * The returned node may or may not be logically deleted.
  47.735 +     * Guarantees that head is set to the returned node.
  47.736 +     */
  47.737 +    Node<E> first() {
  47.738 +        restartFromHead:
  47.739 +        for (;;)
  47.740 +            for (Node<E> h = head, p = h, q;;) {
  47.741 +                if ((q = p.prev) != null &&
  47.742 +                    (q = (p = q).prev) != null)
  47.743 +                    // Check for head updates every other hop.
  47.744 +                    // If p == q, we are sure to follow head instead.
  47.745 +                    p = (h != (h = head)) ? h : q;
  47.746 +                else if (p == h
  47.747 +                         // It is possible that p is PREV_TERMINATOR,
  47.748 +                         // but if so, the CAS is guaranteed to fail.
  47.749 +                         || casHead(h, p))
  47.750 +                    return p;
  47.751 +                else
  47.752 +                    continue restartFromHead;
  47.753 +            }
  47.754 +    }
  47.755 +
  47.756 +    /**
  47.757 +     * Returns the last node, the unique node p for which:
  47.758 +     *     p.next == null && p.prev != p
  47.759 +     * The returned node may or may not be logically deleted.
  47.760 +     * Guarantees that tail is set to the returned node.
  47.761 +     */
  47.762 +    Node<E> last() {
  47.763 +        restartFromTail:
  47.764 +        for (;;)
  47.765 +            for (Node<E> t = tail, p = t, q;;) {
  47.766 +                if ((q = p.next) != null &&
  47.767 +                    (q = (p = q).next) != null)
  47.768 +                    // Check for tail updates every other hop.
  47.769 +                    // If p == q, we are sure to follow tail instead.
  47.770 +                    p = (t != (t = tail)) ? t : q;
  47.771 +                else if (p == t
  47.772 +                         // It is possible that p is NEXT_TERMINATOR,
  47.773 +                         // but if so, the CAS is guaranteed to fail.
  47.774 +                         || casTail(t, p))
  47.775 +                    return p;
  47.776 +                else
  47.777 +                    continue restartFromTail;
  47.778 +            }
  47.779 +    }
  47.780 +
  47.781 +    // Minor convenience utilities
  47.782 +
  47.783 +    /**
  47.784 +     * Throws NullPointerException if argument is null.
  47.785 +     *
  47.786 +     * @param v the element
  47.787 +     */
  47.788 +    private static void checkNotNull(Object v) {
  47.789 +        if (v == null)
  47.790 +            throw new NullPointerException();
  47.791 +    }
  47.792 +
  47.793 +    /**
  47.794 +     * Returns element unless it is null, in which case throws
  47.795 +     * NoSuchElementException.
  47.796 +     *
  47.797 +     * @param v the element
  47.798 +     * @return the element
  47.799 +     */
  47.800 +    private E screenNullResult(E v) {
  47.801 +        if (v == null)
  47.802 +            throw new NoSuchElementException();
  47.803 +        return v;
  47.804 +    }
  47.805 +
  47.806 +    /**
  47.807 +     * Creates an array list and fills it with elements of this list.
  47.808 +     * Used by toArray.
  47.809 +     *
  47.810 +     * @return the arrayList
  47.811 +     */
  47.812 +    private ArrayList<E> toArrayList() {
  47.813 +        ArrayList<E> list = new ArrayList<E>();
  47.814 +        for (Node<E> p = first(); p != null; p = succ(p)) {
  47.815 +            E item = p.item;
  47.816 +            if (item != null)
  47.817 +                list.add(item);
  47.818 +        }
  47.819 +        return list;
  47.820 +    }
  47.821 +
  47.822 +    /**
  47.823 +     * Constructs an empty deque.
  47.824 +     */
  47.825 +    public ConcurrentLinkedDeque() {
  47.826 +        head = tail = new Node<E>(null);
  47.827 +    }
  47.828 +
  47.829 +    /**
  47.830 +     * Constructs a deque initially containing the elements of
  47.831 +     * the given collection, added in traversal order of the
  47.832 +     * collection's iterator.
  47.833 +     *
  47.834 +     * @param c the collection of elements to initially contain
  47.835 +     * @throws NullPointerException if the specified collection or any
  47.836 +     *         of its elements are null
  47.837 +     */
  47.838 +    public ConcurrentLinkedDeque(Collection<? extends E> c) {
  47.839 +        // Copy c into a private chain of Nodes
  47.840 +        Node<E> h = null, t = null;
  47.841 +        for (E e : c) {
  47.842 +            checkNotNull(e);
  47.843 +            Node<E> newNode = new Node<E>(e);
  47.844 +            if (h == null)
  47.845 +                h = t = newNode;
  47.846 +            else {
  47.847 +                t.lazySetNext(newNode);
  47.848 +                newNode.lazySetPrev(t);
  47.849 +                t = newNode;
  47.850 +            }
  47.851 +        }
  47.852 +        initHeadTail(h, t);
  47.853 +    }
  47.854 +
  47.855 +    /**
  47.856 +     * Initializes head and tail, ensuring invariants hold.
  47.857 +     */
  47.858 +    private void initHeadTail(Node<E> h, Node<E> t) {
  47.859 +        if (h == t) {
  47.860 +            if (h == null)
  47.861 +                h = t = new Node<E>(null);
  47.862 +            else {
  47.863 +                // Avoid edge case of a single Node with non-null item.
  47.864 +                Node<E> newNode = new Node<E>(null);
  47.865 +                t.lazySetNext(newNode);
  47.866 +                newNode.lazySetPrev(t);
  47.867 +                t = newNode;
  47.868 +            }
  47.869 +        }
  47.870 +        head = h;
  47.871 +        tail = t;
  47.872 +    }
  47.873 +
  47.874 +    /**
  47.875 +     * Inserts the specified element at the front of this deque.
  47.876 +     *
  47.877 +     * @throws NullPointerException {@inheritDoc}
  47.878 +     */
  47.879 +    public void addFirst(E e) {
  47.880 +        linkFirst(e);
  47.881 +    }
  47.882 +
  47.883 +    /**
  47.884 +     * Inserts the specified element at the end of this deque.
  47.885 +     *
  47.886 +     * <p>This method is equivalent to {@link #add}.
  47.887 +     *
  47.888 +     * @throws NullPointerException {@inheritDoc}
  47.889 +     */
  47.890 +    public void addLast(E e) {
  47.891 +        linkLast(e);
  47.892 +    }
  47.893 +
  47.894 +    /**
  47.895 +     * Inserts the specified element at the front of this deque.
  47.896 +     *
  47.897 +     * @return {@code true} always
  47.898 +     * @throws NullPointerException {@inheritDoc}
  47.899 +     */
  47.900 +    public boolean offerFirst(E e) {
  47.901 +        linkFirst(e);
  47.902 +        return true;
  47.903 +    }
  47.904 +
  47.905 +    /**
  47.906 +     * Inserts the specified element at the end of this deque.
  47.907 +     *
  47.908 +     * <p>This method is equivalent to {@link #add}.
  47.909 +     *
  47.910 +     * @return {@code true} always
  47.911 +     * @throws NullPointerException {@inheritDoc}
  47.912 +     */
  47.913 +    public boolean offerLast(E e) {
  47.914 +        linkLast(e);
  47.915 +        return true;
  47.916 +    }
  47.917 +
  47.918 +    public E peekFirst() {
  47.919 +        for (Node<E> p = first(); p != null; p = succ(p)) {
  47.920 +            E item = p.item;
  47.921 +            if (item != null)
  47.922 +                return item;
  47.923 +        }
  47.924 +        return null;
  47.925 +    }
  47.926 +
  47.927 +    public E peekLast() {
  47.928 +        for (Node<E> p = last(); p != null; p = pred(p)) {
  47.929 +            E item = p.item;
  47.930 +            if (item != null)
  47.931 +                return item;
  47.932 +        }
  47.933 +        return null;
  47.934 +    }
  47.935 +
  47.936 +    /**
  47.937 +     * @throws NoSuchElementException {@inheritDoc}
  47.938 +     */
  47.939 +    public E getFirst() {
  47.940 +        return screenNullResult(peekFirst());
  47.941 +    }
  47.942 +
  47.943 +    /**
  47.944 +     * @throws NoSuchElementException {@inheritDoc}
  47.945 +     */
  47.946 +    public E getLast()  {
  47.947 +        return screenNullResult(peekLast());
  47.948 +    }
  47.949 +
  47.950 +    public E pollFirst() {
  47.951 +        for (Node<E> p = first(); p != null; p = succ(p)) {
  47.952 +            E item = p.item;
  47.953 +            if (item != null && p.casItem(item, null)) {
  47.954 +                unlink(p);
  47.955 +                return item;
  47.956 +            }
  47.957 +        }
  47.958 +        return null;
  47.959 +    }
  47.960 +
  47.961 +    public E pollLast() {
  47.962 +        for (Node<E> p = last(); p != null; p = pred(p)) {
  47.963 +            E item = p.item;
  47.964 +            if (item != null && p.casItem(item, null)) {
  47.965 +                unlink(p);
  47.966 +                return item;
  47.967 +            }
  47.968 +        }
  47.969 +        return null;
  47.970 +    }
  47.971 +
  47.972 +    /**
  47.973 +     * @throws NoSuchElementException {@inheritDoc}
  47.974 +     */
  47.975 +    public E removeFirst() {
  47.976 +        return screenNullResult(pollFirst());
  47.977 +    }
  47.978 +
  47.979 +    /**
  47.980 +     * @throws NoSuchElementException {@inheritDoc}
  47.981 +     */
  47.982 +    public E removeLast() {
  47.983 +        return screenNullResult(pollLast());
  47.984 +    }
  47.985 +
  47.986 +    // *** Queue and stack methods ***
  47.987 +
  47.988 +    /**
  47.989 +     * Inserts the specified element at the tail of this deque.
  47.990 +     *
  47.991 +     * @return {@code true} (as specified by {@link Queue#offer})
  47.992 +     * @throws NullPointerException if the specified element is null
  47.993 +     */
  47.994 +    public boolean offer(E e) {
  47.995 +        return offerLast(e);
  47.996 +    }
  47.997 +
  47.998 +    /**
  47.999 +     * Inserts the specified element at the tail of this deque.
 47.1000 +     *
 47.1001 +     * @return {@code true} (as specified by {@link Collection#add})
 47.1002 +     * @throws NullPointerException if the specified element is null
 47.1003 +     */
 47.1004 +    public boolean add(E e) {
 47.1005 +        return offerLast(e);
 47.1006 +    }
 47.1007 +
 47.1008 +    public E poll()           { return pollFirst(); }
 47.1009 +    public E remove()         { return removeFirst(); }
 47.1010 +    public E peek()           { return peekFirst(); }
 47.1011 +    public E element()        { return getFirst(); }
 47.1012 +    public void push(E e)     { addFirst(e); }
 47.1013 +    public E pop()            { return removeFirst(); }
 47.1014 +
 47.1015 +    /**
 47.1016 +     * Removes the first element {@code e} such that
 47.1017 +     * {@code o.equals(e)}, if such an element exists in this deque.
 47.1018 +     * If the deque does not contain the element, it is unchanged.
 47.1019 +     *
 47.1020 +     * @param o element to be removed from this deque, if present
 47.1021 +     * @return {@code true} if the deque contained the specified element
 47.1022 +     * @throws NullPointerException if the specified element is {@code null}
 47.1023 +     */
 47.1024 +    public boolean removeFirstOccurrence(Object o) {
 47.1025 +        checkNotNull(o);
 47.1026 +        for (Node<E> p = first(); p != null; p = succ(p)) {
 47.1027 +            E item = p.item;
 47.1028 +            if (item != null && o.equals(item) && p.casItem(item, null)) {
 47.1029 +                unlink(p);
 47.1030 +                return true;
 47.1031 +            }
 47.1032 +        }
 47.1033 +        return false;
 47.1034 +    }
 47.1035 +
 47.1036 +    /**
 47.1037 +     * Removes the last element {@code e} such that
 47.1038 +     * {@code o.equals(e)}, if such an element exists in this deque.
 47.1039 +     * If the deque does not contain the element, it is unchanged.
 47.1040 +     *
 47.1041 +     * @param o element to be removed from this deque, if present
 47.1042 +     * @return {@code true} if the deque contained the specified element
 47.1043 +     * @throws NullPointerException if the specified element is {@code null}
 47.1044 +     */
 47.1045 +    public boolean removeLastOccurrence(Object o) {
 47.1046 +        checkNotNull(o);
 47.1047 +        for (Node<E> p = last(); p != null; p = pred(p)) {
 47.1048 +            E item = p.item;
 47.1049 +            if (item != null && o.equals(item) && p.casItem(item, null)) {
 47.1050 +                unlink(p);
 47.1051 +                return true;
 47.1052 +            }
 47.1053 +        }
 47.1054 +        return false;
 47.1055 +    }
 47.1056 +
 47.1057 +    /**
 47.1058 +     * Returns {@code true} if this deque contains at least one
 47.1059 +     * element {@code e} such that {@code o.equals(e)}.
 47.1060 +     *
 47.1061 +     * @param o element whose presence in this deque is to be tested
 47.1062 +     * @return {@code true} if this deque contains the specified element
 47.1063 +     */
 47.1064 +    public boolean contains(Object o) {
 47.1065 +        if (o == null) return false;
 47.1066 +        for (Node<E> p = first(); p != null; p = succ(p)) {
 47.1067 +            E item = p.item;
 47.1068 +            if (item != null && o.equals(item))
 47.1069 +                return true;
 47.1070 +        }
 47.1071 +        return false;
 47.1072 +    }
 47.1073 +
 47.1074 +    /**
 47.1075 +     * Returns {@code true} if this collection contains no elements.
 47.1076 +     *
 47.1077 +     * @return {@code true} if this collection contains no elements
 47.1078 +     */
 47.1079 +    public boolean isEmpty() {
 47.1080 +        return peekFirst() == null;
 47.1081 +    }
 47.1082 +
 47.1083 +    /**
 47.1084 +     * Returns the number of elements in this deque.  If this deque
 47.1085 +     * contains more than {@code Integer.MAX_VALUE} elements, it
 47.1086 +     * returns {@code Integer.MAX_VALUE}.
 47.1087 +     *
 47.1088 +     * <p>Beware that, unlike in most collections, this method is
 47.1089 +     * <em>NOT</em> a constant-time operation. Because of the
 47.1090 +     * asynchronous nature of these deques, determining the current
 47.1091 +     * number of elements requires traversing them all to count them.
 47.1092 +     * Additionally, it is possible for the size to change during
 47.1093 +     * execution of this method, in which case the returned result
 47.1094 +     * will be inaccurate. Thus, this method is typically not very
 47.1095 +     * useful in concurrent applications.
 47.1096 +     *
 47.1097 +     * @return the number of elements in this deque
 47.1098 +     */
 47.1099 +    public int size() {
 47.1100 +        int count = 0;
 47.1101 +        for (Node<E> p = first(); p != null; p = succ(p))
 47.1102 +            if (p.item != null)
 47.1103 +                // Collection.size() spec says to max out
 47.1104 +                if (++count == Integer.MAX_VALUE)
 47.1105 +                    break;
 47.1106 +        return count;
 47.1107 +    }
 47.1108 +
 47.1109 +    /**
 47.1110 +     * Removes the first element {@code e} such that
 47.1111 +     * {@code o.equals(e)}, if such an element exists in this deque.
 47.1112 +     * If the deque does not contain the element, it is unchanged.
 47.1113 +     *
 47.1114 +     * @param o element to be removed from this deque, if present
 47.1115 +     * @return {@code true} if the deque contained the specified element
 47.1116 +     * @throws NullPointerException if the specified element is {@code null}
 47.1117 +     */
 47.1118 +    public boolean remove(Object o) {
 47.1119 +        return removeFirstOccurrence(o);
 47.1120 +    }
 47.1121 +
 47.1122 +    /**
 47.1123 +     * Appends all of the elements in the specified collection to the end of
 47.1124 +     * this deque, in the order that they are returned by the specified
 47.1125 +     * collection's iterator.  Attempts to {@code addAll} of a deque to
 47.1126 +     * itself result in {@code IllegalArgumentException}.
 47.1127 +     *
 47.1128 +     * @param c the elements to be inserted into this deque
 47.1129 +     * @return {@code true} if this deque changed as a result of the call
 47.1130 +     * @throws NullPointerException if the specified collection or any
 47.1131 +     *         of its elements are null
 47.1132 +     * @throws IllegalArgumentException if the collection is this deque
 47.1133 +     */
 47.1134 +    public boolean addAll(Collection<? extends E> c) {
 47.1135 +        if (c == this)
 47.1136 +            // As historically specified in AbstractQueue#addAll
 47.1137 +            throw new IllegalArgumentException();
 47.1138 +
 47.1139 +        // Copy c into a private chain of Nodes
 47.1140 +        Node<E> beginningOfTheEnd = null, last = null;
 47.1141 +        for (E e : c) {
 47.1142 +            checkNotNull(e);
 47.1143 +            Node<E> newNode = new Node<E>(e);
 47.1144 +            if (beginningOfTheEnd == null)
 47.1145 +                beginningOfTheEnd = last = newNode;
 47.1146 +            else {
 47.1147 +                last.lazySetNext(newNode);
 47.1148 +                newNode.lazySetPrev(last);
 47.1149 +                last = newNode;
 47.1150 +            }
 47.1151 +        }
 47.1152 +        if (beginningOfTheEnd == null)
 47.1153 +            return false;
 47.1154 +
 47.1155 +        // Atomically append the chain at the tail of this collection
 47.1156 +        restartFromTail:
 47.1157 +        for (;;)
 47.1158 +            for (Node<E> t = tail, p = t, q;;) {
 47.1159 +                if ((q = p.next) != null &&
 47.1160 +                    (q = (p = q).next) != null)
 47.1161 +                    // Check for tail updates every other hop.
 47.1162 +                    // If p == q, we are sure to follow tail instead.
 47.1163 +                    p = (t != (t = tail)) ? t : q;
 47.1164 +                else if (p.prev == p) // NEXT_TERMINATOR
 47.1165 +                    continue restartFromTail;
 47.1166 +                else {
 47.1167 +                    // p is last node
 47.1168 +                    beginningOfTheEnd.lazySetPrev(p); // CAS piggyback
 47.1169 +                    if (p.casNext(null, beginningOfTheEnd)) {
 47.1170 +                        // Successful CAS is the linearization point
 47.1171 +                        // for all elements to be added to this queue.
 47.1172 +                        if (!casTail(t, last)) {
 47.1173 +                            // Try a little harder to update tail,
 47.1174 +                            // since we may be adding many elements.
 47.1175 +                            t = tail;
 47.1176 +                            if (last.next == null)
 47.1177 +                                casTail(t, last);
 47.1178 +                        }
 47.1179 +                        return true;
 47.1180 +                    }
 47.1181 +                    // Lost CAS race to another thread; re-read next
 47.1182 +                }
 47.1183 +            }
 47.1184 +    }
 47.1185 +
 47.1186 +    /**
 47.1187 +     * Removes all of the elements from this deque.
 47.1188 +     */
 47.1189 +    public void clear() {
 47.1190 +        while (pollFirst() != null)
 47.1191 +            ;
 47.1192 +    }
 47.1193 +
 47.1194 +    /**
 47.1195 +     * Returns an array containing all of the elements in this deque, in
 47.1196 +     * proper sequence (from first to last element).
 47.1197 +     *
 47.1198 +     * <p>The returned array will be "safe" in that no references to it are
 47.1199 +     * maintained by this deque.  (In other words, this method must allocate
 47.1200 +     * a new array).  The caller is thus free to modify the returned array.
 47.1201 +     *
 47.1202 +     * <p>This method acts as bridge between array-based and collection-based
 47.1203 +     * APIs.
 47.1204 +     *
 47.1205 +     * @return an array containing all of the elements in this deque
 47.1206 +     */
 47.1207 +    public Object[] toArray() {
 47.1208 +        return toArrayList().toArray();
 47.1209 +    }
 47.1210 +
 47.1211 +    /**
 47.1212 +     * Returns an array containing all of the elements in this deque,
 47.1213 +     * in proper sequence (from first to last element); the runtime
 47.1214 +     * type of the returned array is that of the specified array.  If
 47.1215 +     * the deque fits in the specified array, it is returned therein.
 47.1216 +     * Otherwise, a new array is allocated with the runtime type of
 47.1217 +     * the specified array and the size of this deque.
 47.1218 +     *
 47.1219 +     * <p>If this deque fits in the specified array with room to spare
 47.1220 +     * (i.e., the array has more elements than this deque), the element in
 47.1221 +     * the array immediately following the end of the deque is set to
 47.1222 +     * {@code null}.
 47.1223 +     *
 47.1224 +     * <p>Like the {@link #toArray()} method, this method acts as
 47.1225 +     * bridge between array-based and collection-based APIs.  Further,
 47.1226 +     * this method allows precise control over the runtime type of the
 47.1227 +     * output array, and may, under certain circumstances, be used to
 47.1228 +     * save allocation costs.
 47.1229 +     *
 47.1230 +     * <p>Suppose {@code x} is a deque known to contain only strings.
 47.1231 +     * The following code can be used to dump the deque into a newly
 47.1232 +     * allocated array of {@code String}:
 47.1233 +     *
 47.1234 +     * <pre>
 47.1235 +     *     String[] y = x.toArray(new String[0]);</pre>
 47.1236 +     *
 47.1237 +     * Note that {@code toArray(new Object[0])} is identical in function to
 47.1238 +     * {@code toArray()}.
 47.1239 +     *
 47.1240 +     * @param a the array into which the elements of the deque are to
 47.1241 +     *          be stored, if it is big enough; otherwise, a new array of the
 47.1242 +     *          same runtime type is allocated for this purpose
 47.1243 +     * @return an array containing all of the elements in this deque
 47.1244 +     * @throws ArrayStoreException if the runtime type of the specified array
 47.1245 +     *         is not a supertype of the runtime type of every element in
 47.1246 +     *         this deque
 47.1247 +     * @throws NullPointerException if the specified array is null
 47.1248 +     */
 47.1249 +    public <T> T[] toArray(T[] a) {
 47.1250 +        return toArrayList().toArray(a);
 47.1251 +    }
 47.1252 +
 47.1253 +    /**
 47.1254 +     * Returns an iterator over the elements in this deque in proper sequence.
 47.1255 +     * The elements will be returned in order from first (head) to last (tail).
 47.1256 +     *
 47.1257 +     * <p>The returned {@code Iterator} is a "weakly consistent" iterator that
 47.1258 +     * will never throw {@link java.util.ConcurrentModificationException
 47.1259 +     * ConcurrentModificationException},
 47.1260 +     * and guarantees to traverse elements as they existed upon
 47.1261 +     * construction of the iterator, and may (but is not guaranteed to)
 47.1262 +     * reflect any modifications subsequent to construction.
 47.1263 +     *
 47.1264 +     * @return an iterator over the elements in this deque in proper sequence
 47.1265 +     */
 47.1266 +    public Iterator<E> iterator() {
 47.1267 +        return new Itr();
 47.1268 +    }
 47.1269 +
 47.1270 +    /**
 47.1271 +     * Returns an iterator over the elements in this deque in reverse
 47.1272 +     * sequential order.  The elements will be returned in order from
 47.1273 +     * last (tail) to first (head).
 47.1274 +     *
 47.1275 +     * <p>The returned {@code Iterator} is a "weakly consistent" iterator that
 47.1276 +     * will never throw {@link java.util.ConcurrentModificationException
 47.1277 +     * ConcurrentModificationException},
 47.1278 +     * and guarantees to traverse elements as they existed upon
 47.1279 +     * construction of the iterator, and may (but is not guaranteed to)
 47.1280 +     * reflect any modifications subsequent to construction.
 47.1281 +     *
 47.1282 +     * @return an iterator over the elements in this deque in reverse order
 47.1283 +     */
 47.1284 +    public Iterator<E> descendingIterator() {
 47.1285 +        return new DescendingItr();
 47.1286 +    }
 47.1287 +
 47.1288 +    private abstract class AbstractItr implements Iterator<E> {
 47.1289 +        /**
 47.1290 +         * Next node to return item for.
 47.1291 +         */
 47.1292 +        private Node<E> nextNode;
 47.1293 +
 47.1294 +        /**
 47.1295 +         * nextItem holds on to item fields because once we claim
 47.1296 +         * that an element exists in hasNext(), we must return it in
 47.1297 +         * the following next() call even if it was in the process of
 47.1298 +         * being removed when hasNext() was called.
 47.1299 +         */
 47.1300 +        private E nextItem;
 47.1301 +
 47.1302 +        /**
 47.1303 +         * Node returned by most recent call to next. Needed by remove.
 47.1304 +         * Reset to null if this element is deleted by a call to remove.
 47.1305 +         */
 47.1306 +        private Node<E> lastRet;
 47.1307 +
 47.1308 +        abstract Node<E> startNode();
 47.1309 +        abstract Node<E> nextNode(Node<E> p);
 47.1310 +
 47.1311 +        AbstractItr() {
 47.1312 +            advance();
 47.1313 +        }
 47.1314 +
 47.1315 +        /**
 47.1316 +         * Sets nextNode and nextItem to next valid node, or to null
 47.1317 +         * if no such.
 47.1318 +         */
 47.1319 +        private void advance() {
 47.1320 +            lastRet = nextNode;
 47.1321 +
 47.1322 +            Node<E> p = (nextNode == null) ? startNode() : nextNode(nextNode);
 47.1323 +            for (;; p = nextNode(p)) {
 47.1324 +                if (p == null) {
 47.1325 +                    // p might be active end or TERMINATOR node; both are OK
 47.1326 +                    nextNode = null;
 47.1327 +                    nextItem = null;
 47.1328 +                    break;
 47.1329 +                }
 47.1330 +                E item = p.item;
 47.1331 +                if (item != null) {
 47.1332 +                    nextNode = p;
 47.1333 +                    nextItem = item;
 47.1334 +                    break;
 47.1335 +                }
 47.1336 +            }
 47.1337 +        }
 47.1338 +
 47.1339 +        public boolean hasNext() {
 47.1340 +            return nextItem != null;
 47.1341 +        }
 47.1342 +
 47.1343 +        public E next() {
 47.1344 +            E item = nextItem;
 47.1345 +            if (item == null) throw new NoSuchElementException();
 47.1346 +            advance();
 47.1347 +            return item;
 47.1348 +        }
 47.1349 +
 47.1350 +        public void remove() {
 47.1351 +            Node<E> l = lastRet;
 47.1352 +            if (l == null) throw new IllegalStateException();
 47.1353 +            l.item = null;
 47.1354 +            unlink(l);
 47.1355 +            lastRet = null;
 47.1356 +        }
 47.1357 +    }
 47.1358 +
 47.1359 +    /** Forward iterator */
 47.1360 +    private class Itr extends AbstractItr {
 47.1361 +        Node<E> startNode() { return first(); }
 47.1362 +        Node<E> nextNode(Node<E> p) { return succ(p); }
 47.1363 +    }
 47.1364 +
 47.1365 +    /** Descending iterator */
 47.1366 +    private class DescendingItr extends AbstractItr {
 47.1367 +        Node<E> startNode() { return last(); }
 47.1368 +        Node<E> nextNode(Node<E> p) { return pred(p); }
 47.1369 +    }
 47.1370 +
 47.1371 +    /**
 47.1372 +     * Saves the state to a stream (that is, serializes it).
 47.1373 +     *
 47.1374 +     * @serialData All of the elements (each an {@code E}) in
 47.1375 +     * the proper order, followed by a null
 47.1376 +     * @param s the stream
 47.1377 +     */
 47.1378 +    private void writeObject(java.io.ObjectOutputStream s)
 47.1379 +        throws java.io.IOException {
 47.1380 +
 47.1381 +        // Write out any hidden stuff
 47.1382 +        s.defaultWriteObject();
 47.1383 +
 47.1384 +        // Write out all elements in the proper order.
 47.1385 +        for (Node<E> p = first(); p != null; p = succ(p)) {
 47.1386 +            E item = p.item;
 47.1387 +            if (item != null)
 47.1388 +                s.writeObject(item);
 47.1389 +        }
 47.1390 +
 47.1391 +        // Use trailing null as sentinel
 47.1392 +        s.writeObject(null);
 47.1393 +    }
 47.1394 +
 47.1395 +    /**
 47.1396 +     * Reconstitutes the instance from a stream (that is, deserializes it).
 47.1397 +     * @param s the stream
 47.1398 +     */
 47.1399 +    private void readObject(java.io.ObjectInputStream s)
 47.1400 +        throws java.io.IOException, ClassNotFoundException {
 47.1401 +        s.defaultReadObject();
 47.1402 +
 47.1403 +        // Read in elements until trailing null sentinel found
 47.1404 +        Node<E> h = null, t = null;
 47.1405 +        Object item;
 47.1406 +        while ((item = s.readObject()) != null) {
 47.1407 +            @SuppressWarnings("unchecked")
 47.1408 +            Node<E> newNode = new Node<E>((E) item);
 47.1409 +            if (h == null)
 47.1410 +                h = t = newNode;
 47.1411 +            else {
 47.1412 +                t.lazySetNext(newNode);
 47.1413 +                newNode.lazySetPrev(t);
 47.1414 +                t = newNode;
 47.1415 +            }
 47.1416 +        }
 47.1417 +        initHeadTail(h, t);
 47.1418 +    }
 47.1419 +
 47.1420 +    // Unsafe mechanics
 47.1421 +
 47.1422 +    private static final sun.misc.Unsafe UNSAFE =
 47.1423 +        sun.misc.Unsafe.getUnsafe();
 47.1424 +    private static final long headOffset =
 47.1425 +        objectFieldOffset(UNSAFE, "head", ConcurrentLinkedDeque.class);
 47.1426 +    private static final long tailOffset =
 47.1427 +        objectFieldOffset(UNSAFE, "tail", ConcurrentLinkedDeque.class);
 47.1428 +
 47.1429 +    private boolean casHead(Node<E> cmp, Node<E> val) {
 47.1430 +        return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
 47.1431 +    }
 47.1432 +
 47.1433 +    private boolean casTail(Node<E> cmp, Node<E> val) {
 47.1434 +        return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val);
 47.1435 +    }
 47.1436 +
 47.1437 +    static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
 47.1438 +                                  String field, Class<?> klazz) {
 47.1439 +        try {
 47.1440 +            return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
 47.1441 +        } catch (NoSuchFieldException e) {
 47.1442 +            // Convert Exception to corresponding Error
 47.1443 +            NoSuchFieldError error = new NoSuchFieldError(field);
 47.1444 +            error.initCause(e);
 47.1445 +            throw error;
 47.1446 +        }
 47.1447 +    }
 47.1448 +}
    48.1 --- a/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java	Thu Oct 07 15:12:19 2010 -0700
    48.2 +++ b/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java	Tue Oct 12 12:51:48 2010 -0700
    48.3 @@ -28,9 +28,9 @@
    48.4   * However, the following notice accompanied the original version of this
    48.5   * file:
    48.6   *
    48.7 - * Written by Doug Lea with assistance from members of JCP JSR-166
    48.8 - * Expert Group and released to the public domain, as explained at
    48.9 - * http://creativecommons.org/licenses/publicdomain
   48.10 + * Written by Doug Lea and Martin Buchholz with assistance from members of
   48.11 + * JCP JSR-166 Expert Group and released to the public domain, as explained
   48.12 + * at http://creativecommons.org/licenses/publicdomain
   48.13   */
   48.14  
   48.15  package java.util.concurrent;
   48.16 @@ -53,7 +53,8 @@
   48.17   * operations obtain elements at the head of the queue.
   48.18   * A {@code ConcurrentLinkedQueue} is an appropriate choice when
   48.19   * many threads will share access to a common collection.
   48.20 - * This queue does not permit {@code null} elements.
   48.21 + * Like most other concurrent collection implementations, this class
   48.22 + * does not permit the use of {@code null} elements.
   48.23   *
   48.24   * <p>This implementation employs an efficient &quot;wait-free&quot;
   48.25   * algorithm based on one described in <a
   48.26 @@ -61,14 +62,20 @@
   48.27   * Fast, and Practical Non-Blocking and Blocking Concurrent Queue
   48.28   * Algorithms</a> by Maged M. Michael and Michael L. Scott.
   48.29   *
   48.30 + * <p>Iterators are <i>weakly consistent</i>, returning elements
   48.31 + * reflecting the state of the queue at some point at or since the
   48.32 + * creation of the iterator.  They do <em>not</em> throw {@link
   48.33 + * ConcurrentModificationException}, and may proceed concurrently with
   48.34 + * other operations.  Elements contained in the queue since the creation
   48.35 + * of the iterator will be returned exactly once.
   48.36 + *
   48.37   * <p>Beware that, unlike in most collections, the {@code size} method
   48.38   * is <em>NOT</em> a constant-time operation. Because of the
   48.39   * asynchronous nature of these queues, determining the current number
   48.40   * of elements requires a traversal of the elements.
   48.41   *
   48.42 - * <p>This class and its iterator implement all of the
   48.43 - * <em>optional</em> methods of the {@link Collection} and {@link
   48.44 - * Iterator} interfaces.
   48.45 + * <p>This class and its iterator implement all of the <em>optional</em>
   48.46 + * methods of the {@link Queue} and {@link Iterator} interfaces.
   48.47   *
   48.48   * <p>Memory consistency effects: As with other concurrent
   48.49   * collections, actions in a thread prior to placing an object into a
   48.50 @@ -132,9 +139,10 @@
   48.51       *
   48.52       * Both head and tail are permitted to lag.  In fact, failing to
   48.53       * update them every time one could is a significant optimization
   48.54 -     * (fewer CASes). This is controlled by local "hops" variables
   48.55 -     * that only trigger helping-CASes after experiencing multiple
   48.56 -     * lags.
   48.57 +     * (fewer CASes). As with LinkedTransferQueue (see the internal
   48.58 +     * documentation for that class), we use a slack threshold of two;
   48.59 +     * that is, we update head/tail when the current pointer appears
   48.60 +     * to be two or more steps away from the first/last node.
   48.61       *
   48.62       * Since head and tail are updated concurrently and independently,
   48.63       * it is possible for tail to lag behind head (why not)?
   48.64 @@ -148,8 +156,8 @@
   48.65       * this is merely an optimization.
   48.66       *
   48.67       * When constructing a Node (before enqueuing it) we avoid paying
   48.68 -     * for a volatile write to item by using lazySet instead of a
   48.69 -     * normal write.  This allows the cost of enqueue to be
   48.70 +     * for a volatile write to item by using Unsafe.putObject instead
   48.71 +     * of a normal write.  This allows the cost of enqueue to be
   48.72       * "one-and-a-half" CASes.
   48.73       *
   48.74       * Both head and tail may or may not point to a Node with a
   48.75 @@ -161,38 +169,25 @@
   48.76       */
   48.77  
   48.78      private static class Node<E> {
   48.79 -        private volatile E item;
   48.80 -        private volatile Node<E> next;
   48.81 +        volatile E item;
   48.82 +        volatile Node<E> next;
   48.83  
   48.84 +        /**
   48.85 +         * Constructs a new node.  Uses relaxed write because item can
   48.86 +         * only be seen after publication via casNext.
   48.87 +         */
   48.88          Node(E item) {
   48.89 -            // Piggyback on imminent casNext()
   48.90 -            lazySetItem(item);
   48.91 -        }
   48.92 -
   48.93 -        E getItem() {
   48.94 -            return item;
   48.95 +            UNSAFE.putObject(this, itemOffset, item);
   48.96          }
   48.97  
   48.98          boolean casItem(E cmp, E val) {
   48.99              return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
  48.100          }
  48.101  
  48.102 -        void setItem(E val) {
  48.103 -            item = val;
  48.104 -        }
  48.105 -
  48.106 -        void lazySetItem(E val) {
  48.107 -            UNSAFE.putOrderedObject(this, itemOffset, val);
  48.108 -        }
  48.109 -
  48.110          void lazySetNext(Node<E> val) {
  48.111              UNSAFE.putOrderedObject(this, nextOffset, val);
  48.112          }
  48.113  
  48.114 -        Node<E> getNext() {
  48.115 -            return next;
  48.116 -        }
  48.117 -
  48.118          boolean casNext(Node<E> cmp, Node<E> val) {
  48.119              return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
  48.120          }
  48.121 @@ -219,7 +214,7 @@
  48.122       * - it is permitted for tail to lag behind head, that is, for tail
  48.123       *   to not be reachable from head!
  48.124       */
  48.125 -    private transient volatile Node<E> head = new Node<E>(null);
  48.126 +    private transient volatile Node<E> head;
  48.127  
  48.128      /**
  48.129       * A node from which the last node on list (that is, the unique
  48.130 @@ -233,25 +228,41 @@
  48.131       *   to not be reachable from head!
  48.132       * - tail.next may or may not be self-pointing to tail.
  48.133       */
  48.134 -    private transient volatile Node<E> tail = head;
  48.135 +    private transient volatile Node<E> tail;
  48.136  
  48.137  
  48.138      /**
  48.139       * Creates a {@code ConcurrentLinkedQueue} that is initially empty.
  48.140       */
  48.141 -    public ConcurrentLinkedQueue() {}
  48.142 +    public ConcurrentLinkedQueue() {
  48.143 +        head = tail = new Node<E>(null);
  48.144 +    }
  48.145  
  48.146      /**
  48.147       * Creates a {@code ConcurrentLinkedQueue}
  48.148       * initially containing the elements of the given collection,
  48.149       * added in traversal order of the collection's iterator.
  48.150 +     *
  48.151       * @param c the collection of elements to initially contain
  48.152       * @throws NullPointerException if the specified collection or any
  48.153       *         of its elements are null
  48.154       */
  48.155      public ConcurrentLinkedQueue(Collection<? extends E> c) {
  48.156 -        for (E e : c)
  48.157 -            add(e);
  48.158 +        Node<E> h = null, t = null;
  48.159 +        for (E e : c) {
  48.160 +            checkNotNull(e);
  48.161 +            Node<E> newNode = new Node<E>(e);
  48.162 +            if (h == null)
  48.163 +                h = t = newNode;
  48.164 +            else {
  48.165 +                t.lazySetNext(newNode);
  48.166 +                t = newNode;
  48.167 +            }
  48.168 +        }
  48.169 +        if (h == null)
  48.170 +            h = t = new Node<E>(null);
  48.171 +        head = h;
  48.172 +        tail = t;
  48.173      }
  48.174  
  48.175      // Have to override just to update the javadoc
  48.176 @@ -267,13 +278,6 @@
  48.177      }
  48.178  
  48.179      /**
  48.180 -     * We don't bother to update head or tail pointers if fewer than
  48.181 -     * HOPS links from "true" location.  We assume that volatile
  48.182 -     * writes are significantly more expensive than volatile reads.
  48.183 -     */
  48.184 -    private static final int HOPS = 1;
  48.185 -
  48.186 -    /**
  48.187       * Try to CAS head to p. If successful, repoint old head to itself
  48.188       * as sentinel for succ(), below.
  48.189       */
  48.190 @@ -288,7 +292,7 @@
  48.191       * stale pointer that is now off the list.
  48.192       */
  48.193      final Node<E> succ(Node<E> p) {
  48.194 -        Node<E> next = p.getNext();
  48.195 +        Node<E> next = p.next;
  48.196          return (p == next) ? head : next;
  48.197      }
  48.198  
  48.199 @@ -299,68 +303,75 @@
  48.200       * @throws NullPointerException if the specified element is null
  48.201       */
  48.202      public boolean offer(E e) {
  48.203 -        if (e == null) throw new NullPointerException();
  48.204 -        Node<E> n = new Node<E>(e);
  48.205 -        retry:
  48.206 +        checkNotNull(e);
  48.207 +        final Node<E> newNode = new Node<E>(e);
  48.208 +
  48.209 +        for (Node<E> t = tail, p = t;;) {
  48.210 +            Node<E> q = p.next;
  48.211 +            if (q == null) {
  48.212 +                // p is last node
  48.213 +                if (p.casNext(null, newNode)) {
  48.214 +                    // Successful CAS is the linearization point
  48.215 +                    // for e to become an element of this queue,
  48.216 +                    // and for newNode to become "live".
  48.217 +                    if (p != t) // hop two nodes at a time
  48.218 +                        casTail(t, newNode);  // Failure is OK.
  48.219 +                    return true;
  48.220 +                }
  48.221 +                // Lost CAS race to another thread; re-read next
  48.222 +            }
  48.223 +            else if (p == q)
  48.224 +                // We have fallen off list.  If tail is unchanged, it
  48.225 +                // will also be off-list, in which case we need to
  48.226 +                // jump to head, from which all live nodes are always
  48.227 +                // reachable.  Else the new tail is a better bet.
  48.228 +                p = (t != (t = tail)) ? t : head;
  48.229 +            else
  48.230 +                // Check for tail updates after two hops.
  48.231 +                p = (p != t && t != (t = tail)) ? t : q;
  48.232 +        }
  48.233 +    }
  48.234 +
  48.235 +    public E poll() {
  48.236 +        restartFromHead:
  48.237          for (;;) {
  48.238 -            Node<E> t = tail;
  48.239 -            Node<E> p = t;
  48.240 -            for (int hops = 0; ; hops++) {
  48.241 -                Node<E> next = succ(p);
  48.242 -                if (next != null) {
  48.243 -                    if (hops > HOPS && t != tail)
  48.244 -                        continue retry;
  48.245 -                    p = next;
  48.246 -                } else if (p.casNext(null, n)) {
  48.247 -                    if (hops >= HOPS)
  48.248 -                        casTail(t, n);  // Failure is OK.
  48.249 -                    return true;
  48.250 -                } else {
  48.251 -                    p = succ(p);
  48.252 +            for (Node<E> h = head, p = h, q;;) {
  48.253 +                E item = p.item;
  48.254 +
  48.255 +                if (item != null && p.casItem(item, null)) {
  48.256 +                    // Successful CAS is the linearization point
  48.257 +                    // for item to be removed from this queue.
  48.258 +                    if (p != h) // hop two nodes at a time
  48.259 +                        updateHead(h, ((q = p.next) != null) ? q : p);
  48.260 +                    return item;
  48.261                  }
  48.262 +                else if ((q = p.next) == null) {
  48.263 +                    updateHead(h, p);
  48.264 +                    return null;
  48.265 +                }
  48.266 +                else if (p == q)
  48.267 +                    continue restartFromHead;
  48.268 +                else
  48.269 +                    p = q;
  48.270              }
  48.271          }
  48.272      }
  48.273  
  48.274 -    public E poll() {
  48.275 -        Node<E> h = head;
  48.276 -        Node<E> p = h;
  48.277 -        for (int hops = 0; ; hops++) {
  48.278 -            E item = p.getItem();
  48.279 -
  48.280 -            if (item != null && p.casItem(item, null)) {
  48.281 -                if (hops >= HOPS) {
  48.282 -                    Node<E> q = p.getNext();
  48.283 -                    updateHead(h, (q != null) ? q : p);
  48.284 +    public E peek() {
  48.285 +        restartFromHead:
  48.286 +        for (;;) {
  48.287 +            for (Node<E> h = head, p = h, q;;) {
  48.288 +                E item = p.item;
  48.289 +                if (item != null || (q = p.next) == null) {
  48.290 +                    updateHead(h, p);
  48.291 +                    return item;
  48.292                  }
  48.293 -                return item;
  48.294 +                else if (p == q)
  48.295 +                    continue restartFromHead;
  48.296 +                else
  48.297 +                    p = q;
  48.298              }
  48.299 -            Node<E> next = succ(p);
  48.300 -            if (next == null) {
  48.301 -                updateHead(h, p);
  48.302 -                break;
  48.303 -            }
  48.304 -            p = next;
  48.305          }
  48.306 -        return null;
  48.307 -    }
  48.308 -
  48.309 -    public E peek() {
  48.310 -        Node<E> h = head;
  48.311 -        Node<E> p = h;
  48.312 -        E item;
  48.313 -        for (;;) {
  48.314 -            item = p.getItem();
  48.315 -            if (item != null)
  48.316 -                break;
  48.317 -            Node<E> next = succ(p);
  48.318 -            if (next == null) {
  48.319 -                break;
  48.320 -            }
  48.321 -            p = next;
  48.322 -        }
  48.323 -        updateHead(h, p);
  48.324 -        return item;
  48.325      }
  48.326  
  48.327      /**
  48.328 @@ -372,24 +383,20 @@
  48.329       * of losing a race to a concurrent poll().
  48.330       */
  48.331      Node<E> first() {
  48.332 -        Node<E> h = head;
  48.333 -        Node<E> p = h;
  48.334 -        Node<E> result;
  48.335 +        restartFromHead:
  48.336          for (;;) {
  48.337 -            E item = p.getItem();
  48.338 -            if (item != null) {
  48.339 -                result = p;
  48.340 -                break;
  48.341 +            for (Node<E> h = head, p = h, q;;) {
  48.342 +                boolean hasItem = (p.item != null);
  48.343 +                if (hasItem || (q = p.next) == null) {
  48.344 +                    updateHead(h, p);
  48.345 +                    return hasItem ? p : null;
  48.346 +                }
  48.347 +                else if (p == q)
  48.348 +                    continue restartFromHead;
  48.349 +                else
  48.350 +                    p = q;
  48.351              }
  48.352 -            Node<E> next = succ(p);
  48.353 -            if (next == null) {
  48.354 -                result = null;
  48.355 -                break;
  48.356 -            }
  48.357 -            p = next;
  48.358          }
  48.359 -        updateHead(h, p);
  48.360 -        return result;
  48.361      }
  48.362  
  48.363      /**
  48.364 @@ -410,18 +417,20 @@
  48.365       * <em>NOT</em> a constant-time operation. Because of the
  48.366       * asynchronous nature of these queues, determining the current
  48.367       * number of elements requires an O(n) traversal.
  48.368 +     * Additionally, if elements are added or removed during execution
  48.369 +     * of this method, the returned result may be inaccurate.  Thus,
  48.370 +     * this method is typically not very useful in concurrent
  48.371 +     * applications.
  48.372       *
  48.373       * @return the number of elements in this queue
  48.374       */
  48.375      public int size() {
  48.376          int count = 0;
  48.377 -        for (Node<E> p = first(); p != null; p = succ(p)) {
  48.378 -            if (p.getItem() != null) {
  48.379 -                // Collections.size() spec says to max out
  48.380 +        for (Node<E> p = first(); p != null; p = succ(p))
  48.381 +            if (p.item != null)
  48.382 +                // Collection.size() spec says to max out
  48.383                  if (++count == Integer.MAX_VALUE)
  48.384                      break;
  48.385 -            }
  48.386 -        }
  48.387          return count;
  48.388      }
  48.389  
  48.390 @@ -436,9 +445,8 @@
  48.391      public boolean contains(Object o) {
  48.392          if (o == null) return false;
  48.393          for (Node<E> p = first(); p != null; p = succ(p)) {
  48.394 -            E item = p.getItem();
  48.395 -            if (item != null &&
  48.396 -                o.equals(item))
  48.397 +            E item = p.item;
  48.398 +            if (item != null && o.equals(item))
  48.399                  return true;
  48.400          }
  48.401          return false;
  48.402 @@ -459,7 +467,7 @@
  48.403          if (o == null) return false;
  48.404          Node<E> pred = null;
  48.405          for (Node<E> p = first(); p != null; p = succ(p)) {
  48.406 -            E item = p.getItem();
  48.407 +            E item = p.item;
  48.408              if (item != null &&
  48.409                  o.equals(item) &&
  48.410                  p.casItem(item, null)) {
  48.411 @@ -474,6 +482,69 @@
  48.412      }
  48.413  
  48.414      /**
  48.415 +     * Appends all of the elements in the specified collection to the end of
  48.416 +     * this queue, in the order that they are returned by the specified
  48.417 +     * collection's iterator.  Attempts to {@code addAll} of a queue to
  48.418 +     * itself result in {@code IllegalArgumentException}.
  48.419 +     *
  48.420 +     * @param c the elements to be inserted into this queue
  48.421 +     * @return {@code true} if this queue changed as a result of the call
  48.422 +     * @throws NullPointerException if the specified collection or any
  48.423 +     *         of its elements are null
  48.424 +     * @throws IllegalArgumentException if the collection is this queue
  48.425 +     */
  48.426 +    public boolean addAll(Collection<? extends E> c) {
  48.427 +        if (c == this)
  48.428 +            // As historically specified in AbstractQueue#addAll
  48.429 +            throw new IllegalArgumentException();
  48.430 +
  48.431 +        // Copy c into a private chain of Nodes
  48.432 +        Node<E> beginningOfTheEnd = null, last = null;
  48.433 +        for (E e : c) {
  48.434 +            checkNotNull(e);
  48.435 +            Node<E> newNode = new Node<E>(e);
  48.436 +            if (beginningOfTheEnd == null)
  48.437 +                beginningOfTheEnd = last = newNode;
  48.438 +            else {
  48.439 +                last.lazySetNext(newNode);
  48.440 +                last = newNode;
  48.441 +            }
  48.442 +        }
  48.443 +        if (beginningOfTheEnd == null)
  48.444 +            return false;
  48.445 +
  48.446 +        // Atomically append the chain at the tail of this collection
  48.447 +        for (Node<E> t = tail, p = t;;) {
  48.448 +            Node<E> q = p.next;
  48.449 +            if (q == null) {
  48.450 +                // p is last node
  48.451 +                if (p.casNext(null, beginningOfTheEnd)) {
  48.452 +                    // Successful CAS is the linearization point
  48.453 +                    // for all elements to be added to this queue.
  48.454 +                    if (!casTail(t, last)) {
  48.455 +                        // Try a little harder to update tail,
  48.456 +                        // since we may be adding many elements.
  48.457 +                        t = tail;
  48.458 +                        if (last.next == null)
  48.459 +                            casTail(t, last);
  48.460 +                    }
  48.461 +                    return true;
  48.462 +                }
  48.463 +                // Lost CAS race to another thread; re-read next
  48.464 +            }
  48.465 +            else if (p == q)
  48.466 +                // We have fallen off list.  If tail is unchanged, it
  48.467 +                // will also be off-list, in which case we need to
  48.468 +                // jump to head, from which all live nodes are always
  48.469 +                // reachable.  Else the new tail is a better bet.
  48.470 +                p = (t != (t = tail)) ? t : head;
  48.471 +            else
  48.472 +                // Check for tail updates after two hops.
  48.473 +                p = (p != t && t != (t = tail)) ? t : q;
  48.474 +        }
  48.475 +    }
  48.476 +
  48.477 +    /**
  48.478       * Returns an array containing all of the elements in this queue, in
  48.479       * proper sequence.
  48.480       *
  48.481 @@ -490,7 +561,7 @@
  48.482          // Use ArrayList to deal with resizing.
  48.483          ArrayList<E> al = new ArrayList<E>();
  48.484          for (Node<E> p = first(); p != null; p = succ(p)) {
  48.485 -            E item = p.getItem();
  48.486 +            E item = p.item;
  48.487              if (item != null)
  48.488                  al.add(item);
  48.489          }
  48.490 @@ -539,7 +610,7 @@
  48.491          int k = 0;
  48.492          Node<E> p;
  48.493          for (p = first(); p != null && k < a.length; p = succ(p)) {
  48.494 -            E item = p.getItem();
  48.495 +            E item = p.item;
  48.496              if (item != null)
  48.497                  a[k++] = (T)item;
  48.498          }
  48.499 @@ -552,7 +623,7 @@
  48.500          // If won't fit, use ArrayList version
  48.501          ArrayList<E> al = new ArrayList<E>();
  48.502          for (Node<E> q = first(); q != null; q = succ(q)) {
  48.503 -            E item = q.getItem();
  48.504 +            E item = q.item;
  48.505              if (item != null)
  48.506                  al.add(item);
  48.507          }
  48.508 @@ -561,7 +632,9 @@
  48.509  
  48.510      /**
  48.511       * Returns an iterator over the elements in this queue in proper sequence.
  48.512 -     * The returned iterator is a "weakly consistent" iterator that
  48.513 +     * The elements will be returned in order from first (head) to last (tail).
  48.514 +     *
  48.515 +     * <p>The returned {@code Iterator} is a "weakly consistent" iterator that
  48.516       * will never throw {@link java.util.ConcurrentModificationException
  48.517       * ConcurrentModificationException},
  48.518       * and guarantees to traverse elements as they existed upon
  48.519 @@ -620,7 +693,7 @@
  48.520                      nextItem = null;
  48.521                      return x;
  48.522                  }
  48.523 -                E item = p.getItem();
  48.524 +                E item = p.item;
  48.525                  if (item != null) {
  48.526                      nextNode = p;
  48.527                      nextItem = item;
  48.528 @@ -648,13 +721,13 @@
  48.529              Node<E> l = lastRet;
  48.530              if (l == null) throw new IllegalStateException();
  48.531              // rely on a future traversal to relink.
  48.532 -            l.setItem(null);
  48.533 +            l.item = null;
  48.534              lastRet = null;
  48.535          }
  48.536      }
  48.537  
  48.538      /**
  48.539 -     * Save the state to a stream (that is, serialize it).
  48.540 +     * Saves the state to a stream (that is, serializes it).
  48.541       *
  48.542       * @serialData All of the elements (each an {@code E}) in
  48.543       * the proper order, followed by a null
  48.544 @@ -668,7 +741,7 @@
  48.545  
  48.546          // Write out all elements in the proper order.
  48.547          for (Node<E> p = first(); p != null; p = succ(p)) {
  48.548 -            Object item = p.getItem();
  48.549 +            Object item = p.item;
  48.550              if (item != null)
  48.551                  s.writeObject(item);
  48.552          }
  48.553 @@ -678,25 +751,40 @@
  48.554      }
  48.555  
  48.556      /**
  48.557 -     * Reconstitute the Queue instance from a stream (that is,
  48.558 -     * deserialize it).
  48.559 +     * Reconstitutes the instance from a stream (that is, deserializes it).
  48.560       * @param s the stream
  48.561       */
  48.562      private void readObject(java.io.ObjectInputStream s)
  48.563          throws java.io.IOException, ClassNotFoundException {
  48.564 -        // Read in capacity, and any hidden stuff
  48.565          s.defaultReadObject();
  48.566 -        head = new Node<E>(null);
  48.567 -        tail = head;
  48.568 -        // Read in all elements and place in queue
  48.569 -        for (;;) {
  48.570 +
  48.571 +        // Read in elements until trailing null sentinel found
  48.572 +        Node<E> h = null, t = null;
  48.573 +        Object item;
  48.574 +        while ((item = s.readObject()) != null) {
  48.575              @SuppressWarnings("unchecked")
  48.576 -            E item = (E)s.readObject();
  48.577 -            if (item == null)
  48.578 -                break;
  48.579 -            else
  48.580 -                offer(item);
  48.581 +            Node<E> newNode = new Node<E>((E) item);
  48.582 +            if (h == null)
  48.583 +                h = t = newNode;
  48.584 +            else {
  48.585 +                t.lazySetNext(newNode);
  48.586 +                t = newNode;
  48.587 +            }
  48.588          }
  48.589 +        if (h == null)
  48.590 +            h = t = new Node<E>(null);
  48.591 +        head = h;
  48.592 +        tail = t;
  48.593 +    }
  48.594 +
  48.595 +    /**
  48.596 +     * Throws NullPointerException if argument is null.
  48.597 +     *
  48.598 +     * @param v the element
  48.599 +     */
  48.600 +    private static void checkNotNull(Object v) {
  48.601 +        if (v == null)
  48.602 +            throw new NullPointerException();
  48.603      }
  48.604  
  48.605      // Unsafe mechanics
  48.606 @@ -715,10 +803,6 @@
  48.607          return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
  48.608      }
  48.609  
  48.610 -    private void lazySetHead(Node<E> val) {
  48.611 -        UNSAFE.putOrderedObject(this, headOffset, val);
  48.612 -    }
  48.613 -
  48.614      static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
  48.615                                    String field, Class<?> klazz) {
  48.616          try {
    49.1 --- a/src/share/classes/java/util/concurrent/ForkJoinPool.java	Thu Oct 07 15:12:19 2010 -0700
    49.2 +++ b/src/share/classes/java/util/concurrent/ForkJoinPool.java	Tue Oct 12 12:51:48 2010 -0700
    49.3 @@ -42,7 +42,6 @@
    49.4  import java.util.List;
    49.5  import java.util.concurrent.AbstractExecutorService;
    49.6  import java.util.concurrent.Callable;
    49.7 -import java.util.concurrent.CountDownLatch;
    49.8  import java.util.concurrent.ExecutorService;
    49.9  import java.util.concurrent.Future;
   49.10  import java.util.concurrent.RejectedExecutionException;
   49.11 @@ -823,15 +822,13 @@
   49.12                                     (workerCounts & RUNNING_COUNT_MASK) <= 1);
   49.13                  long startTime = untimed? 0 : System.nanoTime();
   49.14                  Thread.interrupted();         // clear/ignore interrupt
   49.15 -                if (eventCount != ec || w.runState != 0 ||
   49.16 -                    runState >= TERMINATING)  // recheck after clear
   49.17 -                    break;
   49.18 +                if (eventCount != ec || w.isTerminating())
   49.19 +                    break;                    // recheck after clear
   49.20                  if (untimed)
   49.21                      LockSupport.park(w);
   49.22                  else {
   49.23                      LockSupport.parkNanos(w, SHRINK_RATE_NANOS);
   49.24 -                    if (eventCount != ec || w.runState != 0 ||
   49.25 -                        runState >= TERMINATING)
   49.26 +                    if (eventCount != ec || w.isTerminating())
   49.27                          break;
   49.28                      if (System.nanoTime() - startTime >= SHRINK_RATE_NANOS)
   49.29                          tryShutdownUnusedWorker(ec);
   49.30 @@ -899,16 +896,23 @@
   49.31                       UNSAFE.compareAndSwapInt(this, workerCountsOffset, wc,
   49.32                                                wc + (ONE_RUNNING|ONE_TOTAL))) {
   49.33                  ForkJoinWorkerThread w = null;
   49.34 +                Throwable fail = null;
   49.35                  try {
   49.36                      w = factory.newThread(this);
   49.37 -                } finally { // adjust on null or exceptional factory return
   49.38 -                    if (w == null) {
   49.39 -                        decrementWorkerCounts(ONE_RUNNING, ONE_TOTAL);
   49.40 -                        tryTerminate(false); // handle failure during shutdown
   49.41 -                    }
   49.42 +                } catch (Throwable ex) {
   49.43 +                    fail = ex;
   49.44                  }
   49.45 -                if (w == null)
   49.46 +                if (w == null) { // null or exceptional factory return
   49.47 +                    decrementWorkerCounts(ONE_RUNNING, ONE_TOTAL);
   49.48 +                    tryTerminate(false); // handle failure during shutdown
   49.49 +                    // If originating from an external caller,
   49.50 +                    // propagate exception, else ignore
   49.51 +                    if (fail != null && runState < TERMINATING &&
   49.52 +                        !(Thread.currentThread() instanceof
   49.53 +                          ForkJoinWorkerThread))
   49.54 +                        UNSAFE.throwException(fail);
   49.55                      break;
   49.56 +                }
   49.57                  w.start(recordWorker(w), ueh);
   49.58                  if ((workerCounts >>> TOTAL_COUNT_SHIFT) >= pc) {
   49.59                      int c; // advance event count
   49.60 @@ -997,8 +1001,12 @@
   49.61          boolean active = w.active;
   49.62          boolean inactivate = false;
   49.63          int pc = parallelism;
   49.64 -        int rs;
   49.65 -        while (w.runState == 0 && (rs = runState) < TERMINATING) {
   49.66 +        while (w.runState == 0) {
   49.67 +            int rs = runState;
   49.68 +            if (rs >= TERMINATING) { // propagate shutdown
   49.69 +                w.shutdown();
   49.70 +                break;
   49.71 +            }
   49.72              if ((inactivate || (active && (rs & ACTIVE_COUNT_MASK) >= pc)) &&
   49.73                  UNSAFE.compareAndSwapInt(this, runStateOffset, rs, rs - 1))
   49.74                  inactivate = active = w.active = false;
   49.75 @@ -1126,6 +1134,7 @@
   49.76          return true;
   49.77      }
   49.78  
   49.79 +
   49.80      /**
   49.81       * Actions on transition to TERMINATING
   49.82       *
   49.83 @@ -1149,7 +1158,7 @@
   49.84                      if (passes > 0 && !w.isTerminated()) {
   49.85                          w.cancelTasks();
   49.86                          LockSupport.unpark(w);
   49.87 -                        if (passes > 1) {
   49.88 +                        if (passes > 1 && !w.isInterrupted()) {
   49.89                              try {
   49.90                                  w.interrupt();
   49.91                              } catch (SecurityException ignore) {
   49.92 @@ -1726,6 +1735,13 @@
   49.93      }
   49.94  
   49.95      /**
   49.96 +     * Returns true if terminating or terminated. Used by ForkJoinWorkerThread.
   49.97 +     */
   49.98 +    final boolean isAtLeastTerminating() {
   49.99 +        return runState >= TERMINATING;
  49.100 +    }
  49.101 +
  49.102 +    /**
  49.103       * Returns {@code true} if this pool has been shut down.
  49.104       *
  49.105       * @return {@code true} if this pool has been shut down
    50.1 --- a/src/share/classes/java/util/concurrent/ForkJoinTask.java	Thu Oct 07 15:12:19 2010 -0700
    50.2 +++ b/src/share/classes/java/util/concurrent/ForkJoinTask.java	Tue Oct 12 12:51:48 2010 -0700
    50.3 @@ -55,10 +55,10 @@
    50.4   * start other subtasks.  As indicated by the name of this class,
    50.5   * many programs using {@code ForkJoinTask} employ only methods
    50.6   * {@link #fork} and {@link #join}, or derivatives such as {@link
    50.7 - * #invokeAll}.  However, this class also provides a number of other
    50.8 - * methods that can come into play in advanced usages, as well as
    50.9 - * extension mechanics that allow support of new forms of fork/join
   50.10 - * processing.
   50.11 + * #invokeAll(ForkJoinTask...) invokeAll}.  However, this class also
   50.12 + * provides a number of other methods that can come into play in
   50.13 + * advanced usages, as well as extension mechanics that allow
   50.14 + * support of new forms of fork/join processing.
   50.15   *
   50.16   * <p>A {@code ForkJoinTask} is a lightweight form of {@link Future}.
   50.17   * The efficiency of {@code ForkJoinTask}s stems from a set of
   50.18 @@ -250,7 +250,7 @@
   50.19          int s;         // the odd construction reduces lock bias effects
   50.20          while ((s = status) >= 0) {
   50.21              try {
   50.22 -                synchronized(this) {
   50.23 +                synchronized (this) {
   50.24                      if (UNSAFE.compareAndSwapInt(this, statusOffset, s,SIGNAL))
   50.25                          wait();
   50.26                  }
   50.27 @@ -270,7 +270,7 @@
   50.28          int s;
   50.29          if ((s = status) >= 0) {
   50.30              try {
   50.31 -                synchronized(this) {
   50.32 +                synchronized (this) {
   50.33                      if (UNSAFE.compareAndSwapInt(this, statusOffset, s,SIGNAL))
   50.34                          wait(millis, 0);
   50.35                  }
   50.36 @@ -288,7 +288,7 @@
   50.37      private void externalAwaitDone() {
   50.38          int s;
   50.39          while ((s = status) >= 0) {
   50.40 -            synchronized(this) {
   50.41 +            synchronized (this) {
   50.42                  if (UNSAFE.compareAndSwapInt(this, statusOffset, s, SIGNAL)){
   50.43                      boolean interrupted = false;
   50.44                      while (status >= 0) {
   50.45 @@ -669,11 +669,34 @@
   50.46          setCompletion(NORMAL);
   50.47      }
   50.48  
   50.49 +    /**
   50.50 +     * Waits if necessary for the computation to complete, and then
   50.51 +     * retrieves its result.
   50.52 +     *
   50.53 +     * @return the computed result
   50.54 +     * @throws CancellationException if the computation was cancelled
   50.55 +     * @throws ExecutionException if the computation threw an
   50.56 +     * exception
   50.57 +     * @throws InterruptedException if the current thread is not a
   50.58 +     * member of a ForkJoinPool and was interrupted while waiting
   50.59 +     */
   50.60      public final V get() throws InterruptedException, ExecutionException {
   50.61 -        quietlyJoin();
   50.62 -        if (Thread.interrupted())
   50.63 -            throw new InterruptedException();
   50.64 -        int s = status;
   50.65 +        int s;
   50.66 +        if (Thread.currentThread() instanceof ForkJoinWorkerThread) {
   50.67 +            quietlyJoin();
   50.68 +            s = status;
   50.69 +        }
   50.70 +        else {
   50.71 +            while ((s = status) >= 0) {
   50.72 +                synchronized (this) { // interruptible form of awaitDone
   50.73 +                    if (UNSAFE.compareAndSwapInt(this, statusOffset,
   50.74 +                                                 s, SIGNAL)) {
   50.75 +                        while (status >= 0)
   50.76 +                            wait();
   50.77 +                    }
   50.78 +                }
   50.79 +            }
   50.80 +        }
   50.81          if (s < NORMAL) {
   50.82              Throwable ex;
   50.83              if (s == CANCELLED)
   50.84 @@ -684,6 +707,20 @@
   50.85          return getRawResult();
   50.86      }
   50.87  
   50.88 +    /**
   50.89 +     * Waits if necessary for at most the given time for the computation
   50.90 +     * to complete, and then retrieves its result, if available.
   50.91 +     *
   50.92 +     * @param timeout the maximum time to wait
   50.93 +     * @param unit the time unit of the timeout argument
   50.94 +     * @return the computed result
   50.95 +     * @throws CancellationException if the computation was cancelled
   50.96 +     * @throws ExecutionException if the computation threw an
   50.97 +     * exception
   50.98 +     * @throws InterruptedException if the current thread is not a
   50.99 +     * member of a ForkJoinPool and was interrupted while waiting
  50.100 +     * @throws TimeoutException if the wait timed out
  50.101 +     */
  50.102      public final V get(long timeout, TimeUnit unit)
  50.103          throws InterruptedException, ExecutionException, TimeoutException {
  50.104          Thread t = Thread.currentThread();
  50.105 @@ -725,7 +762,7 @@
  50.106                          long ms = nt / 1000000;
  50.107                          int ns = (int) (nt % 1000000);
  50.108                          try {
  50.109 -                            synchronized(this) {
  50.110 +                            synchronized (this) {
  50.111                                  if (status >= 0)
  50.112                                      wait(ms, ns);
  50.113                              }
    51.1 --- a/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java	Thu Oct 07 15:12:19 2010 -0700
    51.2 +++ b/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java	Tue Oct 12 12:51:48 2010 -0700
    51.3 @@ -778,11 +778,20 @@
    51.4  
    51.5      // status check methods used mainly by ForkJoinPool
    51.6      final boolean isRunning()     { return runState == 0; }
    51.7 -    final boolean isTerminating() { return (runState & TERMINATING) != 0; }
    51.8      final boolean isTerminated()  { return (runState & TERMINATED) != 0; }
    51.9      final boolean isSuspended()   { return (runState & SUSPENDED) != 0; }
   51.10      final boolean isTrimmed()     { return (runState & TRIMMED) != 0; }
   51.11  
   51.12 +    final boolean isTerminating() {
   51.13 +        if ((runState & TERMINATING) != 0)
   51.14 +            return true;
   51.15 +        if (pool.isAtLeastTerminating()) { // propagate pool state
   51.16 +            shutdown();
   51.17 +            return true;
   51.18 +        }
   51.19 +        return false;
   51.20 +    }
   51.21 +
   51.22      /**
   51.23       * Sets state to TERMINATING. Does NOT unpark or interrupt
   51.24       * to wake up if currently blocked. Callers must do so if desired.
    52.1 --- a/src/share/classes/java/util/concurrent/RecursiveAction.java	Thu Oct 07 15:12:19 2010 -0700
    52.2 +++ b/src/share/classes/java/util/concurrent/RecursiveAction.java	Tue Oct 12 12:51:48 2010 -0700
    52.3 @@ -138,7 +138,7 @@
    52.4   *        if (right.tryUnfork()) // directly calculate if not stolen
    52.5   *          sum += right.atLeaf(right.lo, right.hi);
    52.6   *       else {
    52.7 - *          right.helpJoin();
    52.8 + *          right.join();
    52.9   *          sum += right.result;
   52.10   *        }
   52.11   *        right = right.next;
    53.1 --- a/src/share/classes/java/util/logging/LogManager.java	Thu Oct 07 15:12:19 2010 -0700
    53.2 +++ b/src/share/classes/java/util/logging/LogManager.java	Tue Oct 12 12:51:48 2010 -0700
    53.3 @@ -690,6 +690,11 @@
    53.4       * Note that since untrusted code may create loggers with
    53.5       * arbitrary names this method should not be relied on to
    53.6       * find Loggers for security sensitive logging.
    53.7 +     * It is also important to note that the Logger associated with the
    53.8 +     * String {@code name} may be garbage collected at any time if there
    53.9 +     * is no strong reference to the Logger. The caller of this method
   53.10 +     * must check the return value for null in order to properly handle
   53.11 +     * the case where the Logger has been garbage collected.
   53.12       * <p>
   53.13       * @param name name of the logger
   53.14       * @return  matching logger or null if none is found
   53.15 @@ -713,6 +718,14 @@
   53.16       * <p>
   53.17       * Note:  Loggers may be added dynamically as new classes are loaded.
   53.18       * This method only reports on the loggers that are currently registered.
   53.19 +     * It is also important to note that this method only returns the name
   53.20 +     * of a Logger, not a strong reference to the Logger itself.
   53.21 +     * The returned String does nothing to prevent the Logger from being
   53.22 +     * garbage collected. In particular, if the returned name is passed
   53.23 +     * to {@code LogManager.getLogger()}, then the caller must check the
   53.24 +     * return value from {@code LogManager.getLogger()} for null to properly
   53.25 +     * handle the case where the Logger has been garbage collected in the
   53.26 +     * time since its name was returned by this method.
   53.27       * <p>
   53.28       * @return  enumeration of logger name strings
   53.29       */
    54.1 --- a/src/share/classes/java/util/logging/Logger.java	Thu Oct 07 15:12:19 2010 -0700
    54.2 +++ b/src/share/classes/java/util/logging/Logger.java	Tue Oct 12 12:51:48 2010 -0700
    54.3 @@ -42,7 +42,10 @@
    54.4   * <p>
    54.5   * Logger objects may be obtained by calls on one of the getLogger
    54.6   * factory methods.  These will either create a new Logger or
    54.7 - * return a suitable existing Logger.
    54.8 + * return a suitable existing Logger. It is important to note that
    54.9 + * the Logger returned by one of the {@code getLogger} factory methods
   54.10 + * may be garbage collected at any time if a strong reference to the
   54.11 + * Logger is not kept.
   54.12   * <p>
   54.13   * Logging messages will be forwarded to registered Handler
   54.14   * objects, which can forward the messages to a variety of
   54.15 @@ -210,7 +213,9 @@
   54.16       * who are making serious use of the logging package (for example
   54.17       * in products) should create and use their own Logger objects,
   54.18       * with appropriate names, so that logging can be controlled on a
   54.19 -     * suitable per-Logger granularity.
   54.20 +     * suitable per-Logger granularity. Developers also need to keep a
   54.21 +     * strong reference to their Logger objects to prevent them from
   54.22 +     * being garbage collected.
   54.23       * <p>
   54.24       * @deprecated Initialization of this field is prone to deadlocks.
   54.25       * The field must be initialized by the Logger class initialization
   54.26 @@ -287,6 +292,15 @@
   54.27       * based on the LogManager configuration and it will configured
   54.28       * to also send logging output to its parent's Handlers.  It will
   54.29       * be registered in the LogManager global namespace.
   54.30 +     * <p>
   54.31 +     * Note: The LogManager may only retain a weak reference to the newly
   54.32 +     * created Logger. It is important to understand that a previously
   54.33 +     * created Logger with the given name may be garbage collected at any
   54.34 +     * time if there is no strong reference to the Logger. In particular,
   54.35 +     * this means that two back-to-back calls like
   54.36 +     * {@code getLogger("MyLogger").log(...)} may use different Logger
   54.37 +     * objects named "MyLogger" if there is no strong reference to the
   54.38 +     * Logger named "MyLogger" elsewhere in the program.
   54.39       *
   54.40       * @param   name            A name for the logger.  This should
   54.41       *                          be a dot-separated name and should normally
   54.42 @@ -311,6 +325,15 @@
   54.43       * output to its parent's Handlers.  It will be registered in
   54.44       * the LogManager global namespace.
   54.45       * <p>
   54.46 +     * Note: The LogManager may only retain a weak reference to the newly
   54.47 +     * created Logger. It is important to understand that a previously
   54.48 +     * created Logger with the given name may be garbage collected at any
   54.49 +     * time if there is no strong reference to the Logger. In particular,
   54.50 +     * this means that two back-to-back calls like
   54.51 +     * {@code getLogger("MyLogger", ...).log(...)} may use different Logger
   54.52 +     * objects named "MyLogger" if there is no strong reference to the
   54.53 +     * Logger named "MyLogger" elsewhere in the program.
   54.54 +     * <p>
   54.55       * If the named Logger already exists and does not yet have a
   54.56       * localization resource bundle then the given resource bundle
   54.57       * name is used.  If the named Logger already exists and has
    55.1 --- a/src/share/classes/javax/sql/rowset/BaseRowSet.java	Thu Oct 07 15:12:19 2010 -0700
    55.2 +++ b/src/share/classes/javax/sql/rowset/BaseRowSet.java	Tue Oct 12 12:51:48 2010 -0700
    55.3 @@ -1,5 +1,5 @@
    55.4  /*
    55.5 - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
    55.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
    55.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    55.8   *
    55.9   * This code is free software; you can redistribute it and/or modify it
   55.10 @@ -734,7 +734,7 @@
   55.11                   throw new SQLException("Set initParams() before setCommand");
   55.12              }
   55.13              params.clear();
   55.14 -            command = new String(cmd);
   55.15 +            command = cmd;
   55.16          }
   55.17  
   55.18      }
   55.19 @@ -797,7 +797,7 @@
   55.20              throw new SQLException("Invalid url string detected. " +
   55.21              "Cannot be of length less than 1");
   55.22          } else {
   55.23 -            URL = new String(url);
   55.24 +            URL = url;
   55.25          }
   55.26  
   55.27          dataSource = null;
   55.28 @@ -854,7 +854,7 @@
   55.29          } else if (name.equals("")) {
   55.30             throw new SQLException("DataSource name cannot be empty string");
   55.31          } else {
   55.32 -           dataSource = new String(name);
   55.33 +           dataSource = name;
   55.34          }
   55.35  
   55.36          URL = null;
   55.37 @@ -889,7 +889,7 @@
   55.38          {
   55.39             username = null;
   55.40          } else {
   55.41 -           username = new String(name);
   55.42 +           username = name;
   55.43          }
   55.44      }
   55.45  
   55.46 @@ -924,7 +924,7 @@
   55.47          {
   55.48             password = null;
   55.49          } else {
   55.50 -           password = new String(pass);
   55.51 +           password = pass;
   55.52          }
   55.53      }
   55.54  
   55.55 @@ -1563,13 +1563,13 @@
   55.56  
   55.57          nullVal = new Object[2];
   55.58          nullVal[0] = null;
   55.59 -        nullVal[1] = new Integer(sqlType);
   55.60 +        nullVal[1] = Integer.valueOf(sqlType);
   55.61  
   55.62         if (params == null){
   55.63              throw new SQLException("Set initParams() before setNull");
   55.64         }
   55.65  
   55.66 -        params.put(new Integer(parameterIndex - 1), nullVal);
   55.67 +        params.put(Integer.valueOf(parameterIndex - 1), nullVal);
   55.68      }
   55.69  
   55.70      /**
   55.71 @@ -1644,14 +1644,14 @@
   55.72  
   55.73          nullVal = new Object[3];
   55.74          nullVal[0] = null;
   55.75 -        nullVal[1] = new Integer(sqlType);
   55.76 -        nullVal[2] = new String(typeName);
   55.77 +        nullVal[1] = Integer.valueOf(sqlType);
   55.78 +        nullVal[2] = typeName;
   55.79  
   55.80         if(params == null){
   55.81              throw new SQLException("Set initParams() before setNull");
   55.82         }
   55.83  
   55.84 -        params.put(new Integer(parameterIndex - 1), nullVal);
   55.85 +        params.put(Integer.valueOf(parameterIndex - 1), nullVal);
   55.86      }
   55.87  
   55.88  
   55.89 @@ -1686,7 +1686,7 @@
   55.90              throw new SQLException("Set initParams() before setNull");
   55.91         }
   55.92  
   55.93 -        params.put(new Integer(parameterIndex - 1), new Boolean(x));
   55.94 +        params.put(Integer.valueOf(parameterIndex - 1), Boolean.valueOf(x));
   55.95      }
   55.96  
   55.97      /**
   55.98 @@ -1720,7 +1720,7 @@
   55.99              throw new SQLException("Set initParams() before setByte");
  55.100         }
  55.101  
  55.102 -        params.put(new Integer(parameterIndex - 1), new Byte(x));
  55.103 +        params.put(Integer.valueOf(parameterIndex - 1), Byte.valueOf(x));
  55.104      }
  55.105  
  55.106      /**
  55.107 @@ -1754,7 +1754,7 @@
  55.108               throw new SQLException("Set initParams() before setShort");
  55.109          }
  55.110  
  55.111 -        params.put(new Integer(parameterIndex - 1), new Short(x));
  55.112 +        params.put(Integer.valueOf(parameterIndex - 1), Short.valueOf(x));
  55.113      }
  55.114  
  55.115      /**
  55.116 @@ -1786,7 +1786,7 @@
  55.117          if(params == null){
  55.118               throw new SQLException("Set initParams() before setInt");
  55.119          }
  55.120 -        params.put(new Integer(parameterIndex - 1), new Integer(x));
  55.121 +        params.put(Integer.valueOf(parameterIndex - 1), Integer.valueOf(x));
  55.122      }
  55.123  
  55.124      /**
  55.125 @@ -1818,7 +1818,7 @@
  55.126          if(params == null){
  55.127               throw new SQLException("Set initParams() before setLong");
  55.128          }
  55.129 -        params.put(new Integer(parameterIndex - 1), new Long(x));
  55.130 +        params.put(Integer.valueOf(parameterIndex - 1), Long.valueOf(x));
  55.131      }
  55.132  
  55.133      /**
  55.134 @@ -1850,7 +1850,7 @@
  55.135          if(params == null){
  55.136               throw new SQLException("Set initParams() before setFloat");
  55.137          }
  55.138 -        params.put(new Integer(parameterIndex - 1), new Float(x));
  55.139 +        params.put(Integer.valueOf(parameterIndex - 1), new Float(x));
  55.140      }
  55.141  
  55.142      /**
  55.143 @@ -1882,7 +1882,7 @@
  55.144          if(params == null){
  55.145               throw new SQLException("Set initParams() before setDouble");
  55.146          }
  55.147 -        params.put(new Integer(parameterIndex - 1), new Double(x));
  55.148 +        params.put(Integer.valueOf(parameterIndex - 1), new Double(x));
  55.149      }
  55.150  
  55.151      /**
  55.152 @@ -1914,7 +1914,7 @@
  55.153          if(params == null){
  55.154               throw new SQLException("Set initParams() before setBigDecimal");
  55.155          }
  55.156 -        params.put(new Integer(parameterIndex - 1), x);
  55.157 +        params.put(Integer.valueOf(parameterIndex - 1), x);
  55.158      }
  55.159  
  55.160      /**
  55.161 @@ -1948,7 +1948,7 @@
  55.162          if(params == null){
  55.163               throw new SQLException("Set initParams() before setString");
  55.164          }
  55.165 -        params.put(new Integer(parameterIndex - 1), x);
  55.166 +        params.put(Integer.valueOf(parameterIndex - 1), x);
  55.167      }
  55.168  
  55.169      /**
  55.170 @@ -1982,7 +1982,7 @@
  55.171          if(params == null){
  55.172               throw new SQLException("Set initParams() before setBytes");
  55.173          }
  55.174 -        params.put(new Integer(parameterIndex - 1), x);
  55.175 +        params.put(Integer.valueOf(parameterIndex - 1), x);
  55.176      }
  55.177  
  55.178      /**
  55.179 @@ -2024,7 +2024,7 @@
  55.180          if(params == null){
  55.181               throw new SQLException("Set initParams() before setDate");
  55.182          }
  55.183 -        params.put(new Integer(parameterIndex - 1), x);
  55.184 +        params.put(Integer.valueOf(parameterIndex - 1), x);
  55.185      }
  55.186  
  55.187      /**
  55.188 @@ -2069,7 +2069,7 @@
  55.189               throw new SQLException("Set initParams() before setTime");
  55.190          }
  55.191  
  55.192 -        params.put(new Integer(parameterIndex - 1), x);
  55.193 +        params.put(Integer.valueOf(parameterIndex - 1), x);
  55.194      }
  55.195  
  55.196      /**
  55.197 @@ -2112,7 +2112,7 @@
  55.198               throw new SQLException("Set initParams() before setTimestamp");
  55.199          }
  55.200  
  55.201 -        params.put(new Integer(parameterIndex - 1), x);
  55.202 +        params.put(Integer.valueOf(parameterIndex - 1), x);
  55.203      }
  55.204  
  55.205      /**
  55.206 @@ -2185,14 +2185,14 @@
  55.207  
  55.208          asciiStream = new Object[3];
  55.209          asciiStream[0] = x;
  55.210 -        asciiStream[1] = new Integer(length);
  55.211 -        asciiStream[2] = new Integer(ASCII_STREAM_PARAM);
  55.212 +        asciiStream[1] = Integer.valueOf(length);
  55.213 +        asciiStream[2] = Integer.valueOf(ASCII_STREAM_PARAM);
  55.214  
  55.215          if(params == null){
  55.216               throw new SQLException("Set initParams() before setAsciiStream");
  55.217          }
  55.218  
  55.219 -        params.put(new Integer(parameterIndex - 1), asciiStream);
  55.220 +        params.put(Integer.valueOf(parameterIndex - 1), asciiStream);
  55.221      }
  55.222  
  55.223    /**
  55.224 @@ -2290,13 +2290,13 @@
  55.225  
  55.226          binaryStream = new Object[3];
  55.227          binaryStream[0] = x;
  55.228 -        binaryStream[1] = new Integer(length);
  55.229 -        binaryStream[2] = new Integer(BINARY_STREAM_PARAM);
  55.230 +        binaryStream[1] = Integer.valueOf(length);
  55.231 +        binaryStream[2] = Integer.valueOf(BINARY_STREAM_PARAM);
  55.232          if(params == null){
  55.233               throw new SQLException("Set initParams() before setBinaryStream");
  55.234          }
  55.235  
  55.236 -        params.put(new Integer(parameterIndex - 1), binaryStream);
  55.237 +        params.put(Integer.valueOf(parameterIndex - 1), binaryStream);
  55.238      }
  55.239  
  55.240  
  55.241 @@ -2396,12 +2396,12 @@
  55.242  
  55.243          unicodeStream = new Object[3];
  55.244          unicodeStream[0] = x;
  55.245 -        unicodeStream[1] = new Integer(length);
  55.246 -        unicodeStream[2] = new Integer(UNICODE_STREAM_PARAM);
  55.247 +        unicodeStream[1] = Integer.valueOf(length);
  55.248 +        unicodeStream[2] = Integer.valueOf(UNICODE_STREAM_PARAM);
  55.249          if(params == null){
  55.250               throw new SQLException("Set initParams() before setUnicodeStream");
  55.251          }
  55.252 -        params.put(new Integer(parameterIndex - 1), unicodeStream);
  55.253 +        params.put(Integer.valueOf(parameterIndex - 1), unicodeStream);
  55.254      }
  55.255  
  55.256      /**
  55.257 @@ -2475,11 +2475,11 @@
  55.258  
  55.259          charStream = new Object[2];
  55.260          charStream[0] = reader;
  55.261 -        charStream[1] = new Integer(length);
  55.262 +        charStream[1] = Integer.valueOf(length);
  55.263          if(params == null){
  55.264               throw new SQLException("Set initParams() before setCharacterStream");
  55.265          }
  55.266 -        params.put(new Integer(parameterIndex - 1), charStream);
  55.267 +        params.put(Integer.valueOf(parameterIndex - 1), charStream);
  55.268      }
  55.269  
  55.270     /**
  55.271 @@ -2591,12 +2591,12 @@
  55.272  
  55.273          obj = new Object[3];
  55.274          obj[0] = x;
  55.275 -        obj[1] = new Integer(targetSqlType);
  55.276 -        obj[2] = new Integer(scale);
  55.277 +        obj[1] = Integer.valueOf(targetSqlType);
  55.278 +        obj[2] = Integer.valueOf(scale);
  55.279          if(params == null){
  55.280               throw new SQLException("Set initParams() before setObject");
  55.281          }
  55.282 -        params.put(new Integer(parameterIndex - 1), obj);
  55.283 +        params.put(Integer.valueOf(parameterIndex - 1), obj);
  55.284      }
  55.285  
  55.286      /**
  55.287 @@ -2654,11 +2654,11 @@
  55.288  
  55.289          obj = new Object[2];
  55.290          obj[0] = x;
  55.291 -        obj[1] = new Integer(targetSqlType);
  55.292 +        obj[1] = Integer.valueOf(targetSqlType);
  55.293          if (params == null){
  55.294               throw new SQLException("Set initParams() before setObject");
  55.295          }
  55.296 -        params.put(new Integer(parameterIndex - 1), obj);
  55.297 +        params.put(Integer.valueOf(parameterIndex - 1), obj);
  55.298      }
  55.299  
  55.300      /**
  55.301 @@ -2726,7 +2726,7 @@
  55.302          if (params == null) {
  55.303               throw new SQLException("Set initParams() before setObject");
  55.304          }
  55.305 -        params.put(new Integer(parameterIndex - 1), x);
  55.306 +        params.put(Integer.valueOf(parameterIndex - 1), x);
  55.307      }
  55.308  
  55.309      /**
  55.310 @@ -2773,7 +2773,7 @@
  55.311          if (params == null) {
  55.312               throw new SQLException("Set initParams() before setRef");
  55.313          }
  55.314 -        params.put(new Integer(parameterIndex - 1), new SerialRef(ref));
  55.315 +        params.put(Integer.valueOf(parameterIndex - 1), new SerialRef(ref));
  55.316      }
  55.317  
  55.318      /**
  55.319 @@ -2817,7 +2817,7 @@
  55.320          if(params == null){
  55.321               throw new SQLException("Set initParams() before setBlob");
  55.322          }
  55.323 -        params.put(new Integer(parameterIndex - 1), new SerialBlob(x));
  55.324 +        params.put(Integer.valueOf(parameterIndex - 1), new SerialBlob(x));
  55.325      }
  55.326  
  55.327      /**
  55.328 @@ -2862,7 +2862,7 @@
  55.329          if(params == null){
  55.330               throw new SQLException("Set initParams() before setClob");
  55.331          }
  55.332 -        params.put(new Integer(parameterIndex - 1), new SerialClob(x));
  55.333 +        params.put(Integer.valueOf(parameterIndex - 1), new SerialClob(x));
  55.334      }
  55.335  
  55.336      /**
  55.337 @@ -2910,7 +2910,7 @@
  55.338          if (params == null){
  55.339               throw new SQLException("Set initParams() before setArray");
  55.340          }
  55.341 -        params.put(new Integer(parameterIndex - 1), new SerialArray(array));
  55.342 +        params.put(Integer.valueOf(parameterIndex - 1), new SerialArray(array));
  55.343      }
  55.344  
  55.345      /**
  55.346 @@ -2975,7 +2975,7 @@
  55.347          if(params == null){
  55.348               throw new SQLException("Set initParams() before setDate");
  55.349          }
  55.350 -        params.put(new Integer(parameterIndex - 1), date);
  55.351 +        params.put(Integer.valueOf(parameterIndex - 1), date);
  55.352      }
  55.353  
  55.354      /**
  55.355 @@ -3041,7 +3041,7 @@
  55.356          if(params == null){
  55.357               throw new SQLException("Set initParams() before setTime");
  55.358          }
  55.359 -        params.put(new Integer(parameterIndex - 1), time);
  55.360 +        params.put(Integer.valueOf(parameterIndex - 1), time);
  55.361      }
  55.362  
  55.363      /**
  55.364 @@ -3107,7 +3107,7 @@
  55.365          if(params == null){
  55.366               throw new SQLException("Set initParams() before setTimestamp");
  55.367          }
  55.368 -        params.put(new Integer(parameterIndex - 1), timestamp);
  55.369 +        params.put(Integer.valueOf(parameterIndex - 1), timestamp);
  55.370      }
  55.371  
  55.372      /**
  55.373 @@ -3181,7 +3181,7 @@
  55.374  
  55.375              Object[] paramsArray = new Object[params.size()];
  55.376              for (int i = 0; i < params.size(); i++) {
  55.377 -               paramsArray[i] = params.get(new Integer(i));
  55.378 +               paramsArray[i] = params.get(Integer.valueOf(i));
  55.379                 if (paramsArray[i] == null) {
  55.380                   throw new SQLException("missing parameter: " + (i + 1));
  55.381                 } //end if
    56.1 --- a/src/share/classes/javax/sql/rowset/CachedRowSet.java	Thu Oct 07 15:12:19 2010 -0700
    56.2 +++ b/src/share/classes/javax/sql/rowset/CachedRowSet.java	Tue Oct 12 12:51:48 2010 -0700
    56.3 @@ -39,7 +39,7 @@
    56.4   * <code>CachedRowSet</code> must implement.
    56.5   * <P>
    56.6   * The reference implementation of the <code>CachedRowSet</code> interface provided
    56.7 - * by Sun Microsystems is a standard implementation. Developers may use this implementation
    56.8 + * by Oracle Corporation is a standard implementation. Developers may use this implementation
    56.9   * just as it is, they may extend it, or they may choose to write their own implementations
   56.10   * of this interface.
   56.11   * <P>
   56.12 @@ -1623,4 +1623,3 @@
   56.13      public boolean previousPage() throws SQLException;
   56.14  
   56.15  }
   56.16 -
    57.1 --- a/src/share/classes/javax/sql/rowset/RowSetMetaDataImpl.java	Thu Oct 07 15:12:19 2010 -0700
    57.2 +++ b/src/share/classes/javax/sql/rowset/RowSetMetaDataImpl.java	Tue Oct 12 12:51:48 2010 -0700
    57.3 @@ -1,5 +1,5 @@
    57.4  /*
    57.5 - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
    57.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
    57.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    57.8   *
    57.9   * This code is free software; you can redistribute it and/or modify it
   57.10 @@ -306,9 +306,9 @@
   57.11      public void setColumnLabel(int columnIndex, String label) throws SQLException {
   57.12          checkColRange(columnIndex);
   57.13          if (label != null) {
   57.14 -            colInfo[columnIndex].columnLabel = new String(label);
   57.15 +            colInfo[columnIndex].columnLabel = label;
   57.16          } else {
   57.17 -            colInfo[columnIndex].columnLabel = new String("");
   57.18 +            colInfo[columnIndex].columnLabel = "";
   57.19          }
   57.20      }
   57.21  
   57.22 @@ -326,9 +326,9 @@
   57.23      public void setColumnName(int columnIndex, String columnName) throws SQLException {
   57.24          checkColRange(columnIndex);
   57.25          if (columnName != null) {
   57.26 -            colInfo[columnIndex].columnName = new String(columnName);
   57.27 +            colInfo[columnIndex].columnName = columnName;
   57.28          } else {
   57.29 -            colInfo[columnIndex].columnName = new String("");
   57.30 +            colInfo[columnIndex].columnName = "";
   57.31          }
   57.32      }
   57.33  
   57.34 @@ -348,9 +348,9 @@
   57.35      public void setSchemaName(int columnIndex, String schemaName) throws SQLException {
   57.36          checkColRange(columnIndex);
   57.37          if (schemaName != null ) {
   57.38 -            colInfo[columnIndex].schemaName = new String(schemaName);
   57.39 +            colInfo[columnIndex].schemaName = schemaName;
   57.40          } else {
   57.41 -            colInfo[columnIndex].schemaName = new String("");
   57.42 +            colInfo[columnIndex].schemaName = "";
   57.43          }
   57.44      }
   57.45  
   57.46 @@ -411,9 +411,9 @@
   57.47      public void setTableName(int columnIndex, String tableName) throws SQLException {
   57.48          checkColRange(columnIndex);
   57.49          if (tableName != null) {
   57.50 -            colInfo[columnIndex].tableName = new String(tableName);
   57.51 +            colInfo[columnIndex].tableName = tableName;
   57.52          } else {
   57.53 -            colInfo[columnIndex].tableName = new String("");
   57.54 +            colInfo[columnIndex].tableName = "";
   57.55          }
   57.56      }
   57.57  
   57.58 @@ -432,9 +432,9 @@
   57.59      public void setCatalogName(int columnIndex, String catalogName) throws SQLException {
   57.60          checkColRange(columnIndex);
   57.61          if (catalogName != null)
   57.62 -            colInfo[columnIndex].catName = new String(catalogName);
   57.63 +            colInfo[columnIndex].catName = catalogName;
   57.64          else
   57.65 -            colInfo[columnIndex].catName = new String("");
   57.66 +            colInfo[columnIndex].catName = "";
   57.67      }
   57.68  
   57.69      /**
   57.70 @@ -474,9 +474,9 @@
   57.71          throws SQLException {
   57.72          checkColRange(columnIndex);
   57.73          if (typeName != null) {
   57.74 -            colInfo[columnIndex].colTypeName = new String(typeName);
   57.75 +            colInfo[columnIndex].colTypeName = typeName;
   57.76          } else {
   57.77 -            colInfo[columnIndex].colTypeName = new String("");
   57.78 +            colInfo[columnIndex].colTypeName = "";
   57.79          }
   57.80      }
   57.81  
   57.82 @@ -827,7 +827,7 @@
   57.83       *         or the given column number is out of bounds
   57.84       */
   57.85      public String getColumnClassName(int columnIndex) throws SQLException {
   57.86 -        String className = (new String()).getClass().getName();
   57.87 +        String className = String.class.getName();
   57.88  
   57.89          int sqlType = getColumnType(columnIndex);
   57.90  
   57.91 @@ -835,65 +835,62 @@
   57.92  
   57.93          case Types.NUMERIC:
   57.94          case Types.DECIMAL:
   57.95 -            className = (new java.math.BigDecimal(0)).getClass().getName ();
   57.96 +            className = java.math.BigDecimal.class.getName();
   57.97              break;
   57.98  
   57.99          case Types.BIT:
  57.100 -            className = (new Boolean(false)).getClass().getName ();
  57.101 +            className = java.lang.Boolean.class.getName();
  57.102              break;
  57.103  
  57.104          case Types.TINYINT:
  57.105 -            className = (new Byte("0")).getClass().getName ();
  57.106 +            className = java.lang.Byte.class.getName();
  57.107              break;
  57.108  
  57.109          case Types.SMALLINT:
  57.110 -            className = (new Short("0")).getClass().getName ();
  57.111 +            className = java.lang.Short.class.getName();
  57.112              break;
  57.113  
  57.114          case Types.INTEGER:
  57.115 -            className = (new Integer(0)).getClass().getName ();
  57.116 +            className = java.lang.Integer.class.getName();
  57.117              break;
  57.118  
  57.119          case Types.BIGINT:
  57.120 -            className = (new Long(0)).getClass().getName ();
  57.121 +            className = java.lang.Long.class.getName();
  57.122              break;
  57.123  
  57.124          case Types.REAL:
  57.125 -            className = (new Float(0)).getClass().getName ();
  57.126 +            className = java.lang.Float.class.getName();
  57.127              break;
  57.128  
  57.129          case Types.FLOAT:
  57.130          case Types.DOUBLE:
  57.131 -            className = (new Double(0)).getClass().getName();
  57.132 +            className = java.lang.Double.class.getName();
  57.133              break;
  57.134  
  57.135          case Types.BINARY:
  57.136          case Types.VARBINARY:
  57.137          case Types.LONGVARBINARY:
  57.138 -            byte[] b = {};
  57.139 -            className = (b.getClass()).getName();
  57.140 +            className = "byte[]";
  57.141              break;
  57.142  
  57.143          case Types.DATE:
  57.144 -            className = (new java.sql.Date(123456)).getClass().getName ();
  57.145 +            className = java.sql.Date.class.getName();
  57.146              break;
  57.147  
  57.148          case Types.TIME:
  57.149 -            className = (new java.sql.Time(123456)).getClass().getName ();
  57.150 +            className = java.sql.Time.class.getName();
  57.151              break;
  57.152  
  57.153          case Types.TIMESTAMP:
  57.154 -            className = (new java.sql.Timestamp(123456)).getClass().getName ();
  57.155 +            className = java.sql.Timestamp.class.getName();
  57.156              break;
  57.157  
  57.158          case Types.BLOB:
  57.159 -            byte[] blob = {};
  57.160 -            className = (blob.getClass()).getName();
  57.161 +            className = java.sql.Blob.class.getName();
  57.162              break;
  57.163  
  57.164          case Types.CLOB:
  57.165 -            char[] c = {};
  57.166 -            className = (c.getClass()).getName();
  57.167 +            className = java.sql.Clob.class.getName();
  57.168              break;
  57.169          }
  57.170  
    58.1 --- a/src/share/classes/javax/sql/rowset/RowSetProvider.java	Thu Oct 07 15:12:19 2010 -0700
    58.2 +++ b/src/share/classes/javax/sql/rowset/RowSetProvider.java	Tue Oct 12 12:51:48 2010 -0700
    58.3 @@ -29,7 +29,6 @@
    58.4  import java.security.PrivilegedAction;
    58.5  import java.sql.SQLException;
    58.6  import java.util.ServiceLoader;
    58.7 -import javax.sql.rowset.RowSetFactory;
    58.8  
    58.9  /**
   58.10   * A factory API that enables applications to obtain a
   58.11 @@ -82,15 +81,15 @@
   58.12       * the <code>RowSetFactory</code> implementation class to load:</p>
   58.13       * <ul>
   58.14       * <li>
   58.15 -     * The System property {@code javax.sql.rowset.RowsetFactory}.  For example:
   58.16 +     * The System property {@code javax.sql.rowset.RowSetFactory}.  For example:
   58.17       * <ul>
   58.18       * <li>
   58.19 -     * -Djavax.sql.rowset.RowsetFactory=com.sun.rowset.RowSetFactoryImpl
   58.20 +     * -Djavax.sql.rowset.RowSetFactory=com.sun.rowset.RowSetFactoryImpl
   58.21       * </li>
   58.22       * </ul>
   58.23       * <li>
   58.24 -     * The ServiceLocator API. The ServiceLocator API will look
   58.25 -     * for a classname in the file
   58.26 +     * The {@link ServiceLoader} API. The {@code ServiceLoader} API will look
   58.27 +     * for a class name in the file
   58.28       * {@code META-INF/services/javax.sql.rowset.RowSetFactory}
   58.29       * in jars available to the runtime. For example, to have the the RowSetFactory
   58.30       * implementation {@code com.sun.rowset.RowSetFactoryImpl } loaded, the
   58.31 @@ -271,7 +270,7 @@
   58.32      /**
   58.33       * Returns the requested System Property.  If a {@code SecurityException}
   58.34       * occurs, just return NULL
   58.35 -     * @param propName - System property to retreive
   58.36 +     * @param propName - System property to retrieve
   58.37       * @return The System property value or NULL if the property does not exist
   58.38       * or a {@code SecurityException} occurs.
   58.39       */
    59.1 --- a/src/share/classes/javax/sql/rowset/WebRowSet.java	Thu Oct 07 15:12:19 2010 -0700
    59.2 +++ b/src/share/classes/javax/sql/rowset/WebRowSet.java	Tue Oct 12 12:51:48 2010 -0700
    59.3 @@ -1,5 +1,5 @@
    59.4  /*
    59.5 - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
    59.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
    59.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    59.8   *
    59.9   * This code is free software; you can redistribute it and/or modify it
   59.10 @@ -115,7 +115,7 @@
   59.11   *      &lt;<font color=red>url</font>&gt;jdbc:thin:oracle&lt;<font color=red>/url</font>&gt;
   59.12   *      &lt;<font color=red>sync-provider</font>&gt;
   59.13   *              &lt;<font color=red>sync-provider-name</font>&gt;.com.rowset.provider.RIOptimisticProvider&lt;<font color=red>/sync-provider-name</font>&gt;
   59.14 - *              &lt;<font color=red>sync-provider-vendor</font>&gt;Sun Microsystems&lt;<font color=red>/sync-provider-vendor</font>&gt;
   59.15 + *              &lt;<font color=red>sync-provider-vendor</font>&gt;Oracle Corporation&lt;<font color=red>/sync-provider-vendor</font>&gt;
   59.16   *              &lt;<font color=red>sync-provider-version</font>&gt;1.0&lt;<font color=red>/sync-provider-name</font>&gt;
   59.17   *              &lt;<font color=red>sync-provider-grade</font>&gt;LOW&lt;<font color=red>/sync-provider-grade</font>&gt;
   59.18   *              &lt;<font color=red>data-source-lock</font>&gt;NONE&lt;<font color=red>/data-source-lock</font>&gt;
   59.19 @@ -489,7 +489,7 @@
   59.20       * tags and their valid values for a <code>WebRowSet</code> implementation.
   59.21       */
   59.22      public static String PUBLIC_XML_SCHEMA =
   59.23 -        "--//Sun Microsystems, Inc.//XSD Schema//EN";
   59.24 +        "--//Oracle Corporation//XSD Schema//EN";
   59.25  
   59.26      /**
   59.27       * The URL for the XML Schema definition file that defines the XML tags and
    60.1 --- a/src/share/classes/javax/sql/rowset/rowset.properties	Thu Oct 07 15:12:19 2010 -0700
    60.2 +++ b/src/share/classes/javax/sql/rowset/rowset.properties	Tue Oct 12 12:51:48 2010 -0700
    60.3 @@ -3,10 +3,10 @@
    60.4  
    60.5  # Optimistic synchonriztaion provider
    60.6  rowset.provider.classname.0=com.sun.rowset.providers.RIOptimisticProvider
    60.7 -rowset.provider.vendor.0=Sun Microsystems Inc
    60.8 +rowset.provider.vendor.0=Oracle Corporation
    60.9  rowset.provider.version.0=1.0
   60.10  
   60.11  # XML Provider using standard XML schema
   60.12  rowset.provider.classname.1=com.sun.rowset.providers.RIXMLProvider
   60.13 -rowset.provider.vendor.1=Sun Microsystems Inc.
   60.14 +rowset.provider.vendor.1=Oracle Corporation
   60.15  rowset.provider.version.1=1.0
    61.1 --- a/src/share/classes/javax/sql/rowset/serial/SQLOutputImpl.java	Thu Oct 07 15:12:19 2010 -0700
    61.2 +++ b/src/share/classes/javax/sql/rowset/serial/SQLOutputImpl.java	Tue Oct 12 12:51:48 2010 -0700
    61.3 @@ -1,5 +1,5 @@
    61.4  /*
    61.5 - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
    61.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
    61.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    61.8   *
    61.9   * This code is free software; you can redistribute it and/or modify it
   61.10 @@ -137,7 +137,7 @@
   61.11       *        values of a UDT to the database.
   61.12       */
   61.13      public void writeBoolean(boolean x) throws SQLException {
   61.14 -        attribs.add(new Boolean(x));
   61.15 +        attribs.add(Boolean.valueOf(x));
   61.16      }
   61.17  
   61.18      /**
   61.19 @@ -151,7 +151,7 @@
   61.20       *        values of a UDT to the database.
   61.21       */
   61.22      public void writeByte(byte x) throws SQLException {
   61.23 -        attribs.add(new Byte(x));
   61.24 +        attribs.add(Byte.valueOf(x));
   61.25      }
   61.26  
   61.27      /**
   61.28 @@ -165,7 +165,7 @@
   61.29       *        values of a UDT to the database.
   61.30       */
   61.31      public void writeShort(short x) throws SQLException {
   61.32 -        attribs.add(new Short(x));
   61.33 +        attribs.add(Short.valueOf(x));
   61.34      }
   61.35  
   61.36      /**
   61.37 @@ -179,7 +179,7 @@
   61.38       *        values of a UDT to the database.
   61.39       */
   61.40      public void writeInt(int x) throws SQLException {
   61.41 -        attribs.add(new Integer(x));
   61.42 +        attribs.add(Integer.valueOf(x));
   61.43      }
   61.44  
   61.45      /**
   61.46 @@ -193,7 +193,7 @@
   61.47       *        values of a UDT to the database.
   61.48       */
   61.49      public void writeLong(long x) throws SQLException {
   61.50 -        attribs.add(new Long(x));
   61.51 +        attribs.add(Long.valueOf(x));
   61.52      }
   61.53  
   61.54      /**
    62.1 --- a/src/share/classes/javax/sql/rowset/serial/SerialRef.java	Thu Oct 07 15:12:19 2010 -0700
    62.2 +++ b/src/share/classes/javax/sql/rowset/serial/SerialRef.java	Tue Oct 12 12:51:48 2010 -0700
    62.3 @@ -1,5 +1,5 @@
    62.4  /*
    62.5 - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
    62.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
    62.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    62.8   *
    62.9   * This code is free software; you can redistribute it and/or modify it
   62.10 @@ -77,7 +77,7 @@
   62.11              throw new SQLException("Cannot instantiate a SerialRef object " +
   62.12                  "that returns a null base type name");
   62.13          } else {
   62.14 -            baseTypeName = new String(ref.getBaseTypeName());
   62.15 +            baseTypeName = ref.getBaseTypeName();
   62.16          }
   62.17      }
   62.18  
   62.19 @@ -110,7 +110,7 @@
   62.20          throws SerialException
   62.21      {
   62.22          map = new Hashtable(map);
   62.23 -        if (!object.equals(null)) {
   62.24 +        if (object != null) {
   62.25              return map.get(object);
   62.26          } else {
   62.27              throw new SerialException("The object is not set");
    63.1 --- a/src/share/classes/javax/sql/rowset/serial/SerialStruct.java	Thu Oct 07 15:12:19 2010 -0700
    63.2 +++ b/src/share/classes/javax/sql/rowset/serial/SerialStruct.java	Tue Oct 12 12:51:48 2010 -0700
    63.3 @@ -1,5 +1,5 @@
    63.4  /*
    63.5 - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
    63.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
    63.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    63.8   *
    63.9   * This code is free software; you can redistribute it and/or modify it
   63.10 @@ -94,7 +94,7 @@
   63.11          try {
   63.12  
   63.13          // get the type name
   63.14 -        SQLTypeName = new String(in.getSQLTypeName());
   63.15 +        SQLTypeName = in.getSQLTypeName();
   63.16          System.out.println("SQLTypeName: " + SQLTypeName);
   63.17  
   63.18          // get the attributes of the struct
   63.19 @@ -137,7 +137,7 @@
   63.20          try {
   63.21  
   63.22          //set the type name
   63.23 -        SQLTypeName = new String(in.getSQLTypeName());
   63.24 +        SQLTypeName = in.getSQLTypeName();
   63.25  
   63.26          Vector tmp = new Vector();
   63.27          in.writeSQL(new SQLOutputImpl(tmp, map));
   63.28 @@ -247,7 +247,7 @@
   63.29      }
   63.30  
   63.31      /**
   63.32 -         * The identifier that assists in the serialization of this
   63.33 +     * The identifier that assists in the serialization of this
   63.34       * <code>SerialStruct</code> object.
   63.35       */
   63.36      static final long serialVersionUID = -8322445504027483372L;
    64.1 --- a/src/share/classes/javax/sql/rowset/spi/SyncFactory.java	Thu Oct 07 15:12:19 2010 -0700
    64.2 +++ b/src/share/classes/javax/sql/rowset/spi/SyncFactory.java	Tue Oct 12 12:51:48 2010 -0700
    64.3 @@ -125,12 +125,12 @@
    64.4   *
    64.5   *   # Optimistic synchronization provider
    64.6   *   rowset.provider.classname.0=com.sun.rowset.providers.RIOptimisticProvider
    64.7 - *   rowset.provider.vendor.0=Sun Microsystems Inc
    64.8 + *   rowset.provider.vendor.0=Oracle Corporation
    64.9   *   rowset.provider.version.0=1.0
   64.10   *
   64.11   *   # XML Provider using standard XML schema
   64.12   *   rowset.provider.classname.1=com.sun.rowset.providers.RIXMLProvider
   64.13 - *   rowset.provider.vendor.1=Sun Microsystems Inc.
   64.14 + *   rowset.provider.vendor.1=Oracle Corporation
   64.15   *   rowset.provider.version.1=1.0
   64.16   * </PRE>
   64.17   * The <code>SyncFactory</code> checks this file and registers the
   64.18 @@ -369,7 +369,7 @@
   64.19              try {
   64.20  
   64.21                  // check if user is supplying his Synchronisation Provider
   64.22 -                // Implementation  if not use Sun's implementation.
   64.23 +                // Implementation if not using Oracle's implementation.
   64.24                  // properties.load(new FileInputStream(ROWSET_PROPERTIES));
   64.25  
   64.26                  // The rowset.properties needs to be in jdk/jre/lib when
    65.1 --- a/src/share/classes/javax/sql/rowset/spi/SyncProvider.java	Thu Oct 07 15:12:19 2010 -0700
    65.2 +++ b/src/share/classes/javax/sql/rowset/spi/SyncProvider.java	Tue Oct 12 12:51:48 2010 -0700
    65.3 @@ -91,8 +91,8 @@
    65.4   * </pre>
    65.5   * <p>
    65.6   * A vendor can register a <code>SyncProvider</code> implementation class name
    65.7 - * with Sun Microsystems, Inc. by sending email to jdbc@sun.com.
    65.8 - * Sun will maintain a database listing the
    65.9 + * with Oracle Corporation by sending email to jdbc@sun.com.
   65.10 + * Oracle will maintain a database listing the
   65.11   * available <code>SyncProvider</code> implementations for use with compliant
   65.12   * <code>RowSet</code> implementations.  This database will be similar to the
   65.13   * one already maintained to list available JDBC drivers.
    66.1 --- a/src/share/classes/javax/sql/rowset/spi/package.html	Thu Oct 07 15:12:19 2010 -0700
    66.2 +++ b/src/share/classes/javax/sql/rowset/spi/package.html	Tue Oct 12 12:51:48 2010 -0700
    66.3 @@ -8,7 +8,7 @@
    66.4    <meta name="GENERATOR"
    66.5   content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
    66.6  <!--
    66.7 -Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
    66.8 +Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
    66.9  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   66.10  
   66.11  This code is free software; you can redistribute it and/or modify it
   66.12 @@ -199,7 +199,7 @@
   66.13  Vendors may develop a <tt>SyncProvider</tt> implementation with any one of the possible
   66.14  levels of synchronization, thus giving <code>RowSet</code> objects a choice of
   66.15  synchronization mechanisms.  A vendor can make its implementation available by 
   66.16 -registering the fully qualified class name with Sun Microsystems at 
   66.17 +registering the fully qualified class name with Oracle Corporation at
   66.18  <code>jdbc@sun.com</code>. This process is discussed in further detail below. 
   66.19  <P>
   66.20  
    67.1 --- a/src/share/classes/javax/swing/GroupLayout.java	Thu Oct 07 15:12:19 2010 -0700
    67.2 +++ b/src/share/classes/javax/swing/GroupLayout.java	Tue Oct 12 12:51:48 2010 -0700
    67.3 @@ -1464,8 +1464,8 @@
    67.4       * &lt;= {@code pref} &lt;= {@code max}.
    67.5       * <p>
    67.6       * Similarly any methods that take a {@code Component} throw a
    67.7 -     * {@code NullPointerException} if passed {@code null} and any methods
    67.8 -     * that take a {@code Group} throw an {@code IllegalArgumentException} if
    67.9 +     * {@code IllegalArgumentException} if passed {@code null} and any methods
   67.10 +     * that take a {@code Group} throw an {@code NullPointerException} if
   67.11       * passed {@code null}.
   67.12       *
   67.13       * @see #createSequentialGroup
    68.1 --- a/src/share/classes/javax/swing/JComponent.java	Thu Oct 07 15:12:19 2010 -0700
    68.2 +++ b/src/share/classes/javax/swing/JComponent.java	Tue Oct 12 12:51:48 2010 -0700
    68.3 @@ -4787,6 +4787,17 @@
    68.4       * @see RepaintManager#addDirtyRegion
    68.5       */
    68.6      public void repaint(long tm, int x, int y, int width, int height) {
    68.7 +        Container p = this;
    68.8 +        while ((p = p.getParent()) instanceof JComponent) {
    68.9 +            JComponent jp = (JComponent) p;
   68.10 +            if (jp.isPaintingOrigin()) {
   68.11 +                Rectangle rectangle = SwingUtilities.convertRectangle(
   68.12 +                        this, new Rectangle(x, y, width, height), jp);
   68.13 +                jp.repaint(tm,
   68.14 +                        rectangle.x, rectangle.y, rectangle.width, rectangle.height);
   68.15 +                return;
   68.16 +            }
   68.17 +        }
   68.18          RepaintManager.currentManager(this).addDirtyRegion(this, x, y, width, height);
   68.19      }
   68.20  
    69.1 --- a/src/share/classes/javax/swing/JDesktopPane.java	Thu Oct 07 15:12:19 2010 -0700
    69.2 +++ b/src/share/classes/javax/swing/JDesktopPane.java	Tue Oct 12 12:51:48 2010 -0700
    69.3 @@ -215,7 +215,8 @@
    69.4  
    69.5      /**
    69.6       * Sets the <code>DesktopManger</code> that will handle
    69.7 -     * desktop-specific UI actions.
    69.8 +     * desktop-specific UI actions. This may be overridden by
    69.9 +     * {@code LookAndFeel}.
   69.10       *
   69.11       * @param d the <code>DesktopManager</code> to use
   69.12       *
    70.1 --- a/src/share/classes/javax/swing/JLayer.java	Thu Oct 07 15:12:19 2010 -0700
    70.2 +++ b/src/share/classes/javax/swing/JLayer.java	Tue Oct 12 12:51:48 2010 -0700
    70.3 @@ -25,17 +25,17 @@
    70.4  
    70.5  package javax.swing;
    70.6  
    70.7 +import sun.awt.AWTAccessor;
    70.8 +
    70.9  import javax.swing.plaf.LayerUI;
   70.10 +import javax.swing.border.Border;
   70.11  import java.awt.*;
   70.12  import java.awt.event.*;
   70.13  import java.beans.PropertyChangeEvent;
   70.14  import java.beans.PropertyChangeListener;
   70.15  import java.io.IOException;
   70.16  import java.io.ObjectInputStream;
   70.17 -import java.io.Serializable;
   70.18 -import java.lang.ref.WeakReference;
   70.19  import java.util.ArrayList;
   70.20 -import java.util.Iterator;
   70.21  import java.security.AccessController;
   70.22  import java.security.PrivilegedAction;
   70.23  
   70.24 @@ -156,8 +156,6 @@
   70.25      private LayerUI<? super V> layerUI;
   70.26      private JPanel glassPane;
   70.27      private boolean isPainting;
   70.28 -    private static final DefaultLayerLayout sharedLayoutInstance =
   70.29 -            new DefaultLayerLayout();
   70.30      private long eventMask;
   70.31  
   70.32      private static final LayerEventController eventController =
   70.33 @@ -165,7 +163,7 @@
   70.34  
   70.35      /**
   70.36       * Creates a new {@code JLayer} object with a {@code null} view component
   70.37 -     * and {@code null} {@link javax.swing.plaf.LayerUI}.
   70.38 +     * and default {@link javax.swing.plaf.LayerUI}.
   70.39       *
   70.40       * @see #setView
   70.41       * @see #setUI
   70.42 @@ -176,14 +174,14 @@
   70.43  
   70.44      /**
   70.45       * Creates a new {@code JLayer} object
   70.46 -     * with {@code null} {@link javax.swing.plaf.LayerUI}.
   70.47 +     * with default {@link javax.swing.plaf.LayerUI}.
   70.48       *
   70.49       * @param view the component to be decorated by this {@code JLayer}
   70.50       *
   70.51       * @see #setUI
   70.52       */
   70.53      public JLayer(V view) {
   70.54 -        this(view, null);
   70.55 +        this(view, new LayerUI<V>());
   70.56      }
   70.57  
   70.58      /**
   70.59 @@ -195,7 +193,6 @@
   70.60       * to be used by this {@code JLayer}
   70.61       */
   70.62      public JLayer(V view, LayerUI<V> ui) {
   70.63 -        setLayout(sharedLayoutInstance);
   70.64          setGlassPane(createGlassPane());
   70.65          setView(view);
   70.66          setUI(ui);
   70.67 @@ -279,10 +276,15 @@
   70.68       */
   70.69      public void setGlassPane(JPanel glassPane) {
   70.70          Component oldGlassPane = getGlassPane();
   70.71 +        boolean isGlassPaneVisible = false;
   70.72          if (oldGlassPane != null) {
   70.73 +            isGlassPaneVisible = oldGlassPane.isVisible();
   70.74              super.remove(oldGlassPane);
   70.75          }
   70.76          if (glassPane != null) {
   70.77 +            AWTAccessor.getComponentAccessor().setMixingCutoutShape(glassPane,
   70.78 +                    new Rectangle());
   70.79 +            glassPane.setVisible(isGlassPaneVisible);
   70.80              super.addImpl(glassPane, null, 0);
   70.81          }
   70.82          this.glassPane = glassPane;
   70.83 @@ -303,6 +305,40 @@
   70.84      }
   70.85  
   70.86      /**
   70.87 +     * Sets the layout manager for this container.  This method is
   70.88 +     * overridden to prevent the layout manager from being set.
   70.89 +     * <p/>Note:  If {@code mgr} is non-{@code null}, this
   70.90 +     * method will throw an exception as layout managers are not supported on
   70.91 +     * a {@code JLayer}.
   70.92 +     *
   70.93 +     * @param mgr the specified layout manager
   70.94 +     * @exception IllegalArgumentException this method is not supported
   70.95 +     */
   70.96 +    public void setLayout(LayoutManager mgr) {
   70.97 +        if (mgr != null) {
   70.98 +            throw new IllegalArgumentException("JLayer.setLayout() not supported");
   70.99 +        }
  70.100 +    }
  70.101 +
  70.102 +    /**
  70.103 +     * A non-{@code null] border, or non-zero insets, isn't supported, to prevent the geometry
  70.104 +     * of this component from becoming complex enough to inhibit
  70.105 +     * subclassing of {@code LayerUI} class.  To create a {@code JLayer} with a border,
  70.106 +     * add it to a {@code JPanel} that has a border.
  70.107 +     * <p/>Note:  If {@code border} is non-{@code null}, this
  70.108 +     * method will throw an exception as borders are not supported on
  70.109 +     * a {@code JLayer}.
  70.110 +     *
  70.111 +     * @param border the {@code Border} to set
  70.112 +     * @exception IllegalArgumentException this method is not supported
  70.113 +     */
  70.114 +    public void setBorder(Border border) {
  70.115 +        if (border != null) {
  70.116 +            throw new IllegalArgumentException("JLayer.setBorder() not supported");
  70.117 +        }
  70.118 +    }
  70.119 +
  70.120 +    /**
  70.121       * This method is not supported by {@code JLayer}
  70.122       * and always throws {@code UnsupportedOperationException}
  70.123       *
  70.124 @@ -341,6 +377,32 @@
  70.125      }
  70.126  
  70.127      /**
  70.128 +     * Always returns {@code true} to cause painting to originate from {@code JLayer},
  70.129 +     * or one of its ancestors.
  70.130 +     *
  70.131 +     * @return true
  70.132 +     * @see JComponent#isPaintingOrigin()
  70.133 +     */
  70.134 +    boolean isPaintingOrigin() {
  70.135 +        return true;
  70.136 +    }
  70.137 +
  70.138 +    /**
  70.139 +     * Delegates repainting to {@link javax.swing.plaf.LayerUI#repaint} method.
  70.140 +     *
  70.141 +     * @param tm  this parameter is not used
  70.142 +     * @param x  the x value of the dirty region
  70.143 +     * @param y  the y value of the dirty region
  70.144 +     * @param width  the width of the dirty region
  70.145 +     * @param height  the height of the dirty region
  70.146 +     */
  70.147 +    public void repaint(long tm, int x, int y, int width, int height) {
  70.148 +        if (getUI() != null) {
  70.149 +            getUI().repaint(tm, x, y, width, height, this);
  70.150 +        }
  70.151 +    }
  70.152 +
  70.153 +    /**
  70.154       * Delegates all painting to the {@link javax.swing.plaf.LayerUI} object.
  70.155       *
  70.156       * @param g the {@code Graphics} to render to
  70.157 @@ -364,14 +426,18 @@
  70.158      }
  70.159  
  70.160      /**
  70.161 -     * To enable the correct painting of the {@code glassPane} and view component,
  70.162 -     * the {@code JLayer} overrides the default implementation of
  70.163 -     * this method to return {@code false} when the {@code glassPane} is visible.
  70.164 +     * The {@code JLayer} overrides the default implementation of
  70.165 +     * this method (in {@code JComponent}) to return {@code false}.
  70.166 +     * This ensures
  70.167 +     * that the drawing machinery will call the {@code JLayer}'s
  70.168 +     * {@code paint}
  70.169 +     * implementation rather than messaging the {@code JLayer}'s
  70.170 +     * children directly.
  70.171       *
  70.172 -     * @return false if {@code JLayer}'s {@code glassPane} is visible
  70.173 +     * @return false
  70.174       */
  70.175      public boolean isOptimizedDrawingEnabled() {
  70.176 -        return glassPane == null || !glassPane.isVisible();
  70.177 +        return false;
  70.178      }
  70.179  
  70.180      /**
  70.181 @@ -461,17 +527,16 @@
  70.182      /**
  70.183       * Returns the preferred size of the viewport for a view component.
  70.184       * <p/>
  70.185 -     * If the ui delegate of this layer is not {@code null}, this method delegates its
  70.186 -     * implementation to the {@code LayerUI.getPreferredScrollableViewportSize(JLayer)}
  70.187 +     * If the view component of this layer implements {@link Scrollable}, this method delegates its
  70.188 +     * implementation to the view component.
  70.189       *
  70.190       * @return the preferred size of the viewport for a view component
  70.191       *
  70.192       * @see Scrollable
  70.193 -     * @see LayerUI#getPreferredScrollableViewportSize(JLayer)
  70.194       */
  70.195      public Dimension getPreferredScrollableViewportSize() {
  70.196 -        if (getUI() != null) {
  70.197 -            return getUI().getPreferredScrollableViewportSize(this);
  70.198 +        if (getView() instanceof Scrollable) {
  70.199 +            return ((Scrollable)getView()).getPreferredScrollableViewportSize();
  70.200          }
  70.201          return getPreferredSize();
  70.202      }
  70.203 @@ -481,18 +546,17 @@
  70.204       * that display logical rows or columns in order to completely expose
  70.205       * one block of rows or columns, depending on the value of orientation.
  70.206       * <p/>
  70.207 -     * If the ui delegate of this layer is not {@code null}, this method delegates its
  70.208 -     * implementation to the {@code LayerUI.getScrollableBlockIncrement(JLayer,Rectangle,int,int)}
  70.209 +     * If the view component of this layer implements {@link Scrollable}, this method delegates its
  70.210 +     * implementation to the view component.
  70.211       *
  70.212       * @return the "block" increment for scrolling in the specified direction
  70.213       *
  70.214       * @see Scrollable
  70.215 -     * @see LayerUI#getScrollableBlockIncrement(JLayer, Rectangle, int, int)
  70.216       */
  70.217      public int getScrollableBlockIncrement(Rectangle visibleRect,
  70.218                                             int orientation, int direction) {
  70.219 -        if (getUI() != null) {
  70.220 -            return getUI().getScrollableBlockIncrement(this, visibleRect,
  70.221 +        if (getView() instanceof Scrollable) {
  70.222 +            return ((Scrollable)getView()).getScrollableBlockIncrement(visibleRect,
  70.223                      orientation, direction);
  70.224          }
  70.225          return (orientation == SwingConstants.VERTICAL) ? visibleRect.height :
  70.226 @@ -504,17 +568,16 @@
  70.227       * determine the height of the layer, unless the preferred height
  70.228       * of the layer is smaller than the height of the viewport.
  70.229       * <p/>
  70.230 -     * If the ui delegate of this layer is not null, this method delegates its
  70.231 -     * implementation to the {@code LayerUI.getScrollableTracksViewportHeight(JLayer)}
  70.232 +     * If the view component of this layer implements {@link Scrollable}, this method delegates its
  70.233 +     * implementation to the view component.
  70.234       *
  70.235       * @return whether the layer should track the height of the viewport
  70.236       *
  70.237       * @see Scrollable
  70.238 -     * @see LayerUI#getScrollableTracksViewportHeight(JLayer)
  70.239       */
  70.240      public boolean getScrollableTracksViewportHeight() {
  70.241 -        if (getUI() != null) {
  70.242 -            return getUI().getScrollableTracksViewportHeight(this);
  70.243 +        if (getView() instanceof Scrollable) {
  70.244 +            return ((Scrollable)getView()).getScrollableTracksViewportHeight();
  70.245          }
  70.246          return false;
  70.247      }
  70.248 @@ -524,17 +587,16 @@
  70.249       * determine the width of the layer, unless the preferred width
  70.250       * of the layer is smaller than the width of the viewport.
  70.251       * <p/>
  70.252 -     * If the ui delegate of this layer is not null, this method delegates its
  70.253 -     * implementation to the {@code LayerUI.getScrollableTracksViewportWidth(JLayer)}
  70.254 +     * If the view component of this layer implements {@link Scrollable}, this method delegates its
  70.255 +     * implementation to the view component.
  70.256       *
  70.257       * @return whether the layer should track the width of the viewport
  70.258       *
  70.259       * @see Scrollable
  70.260 -     * @see LayerUI#getScrollableTracksViewportWidth(JLayer)
  70.261       */
  70.262      public boolean getScrollableTracksViewportWidth() {
  70.263 -        if (getUI() != null) {
  70.264 -            return getUI().getScrollableTracksViewportWidth(this);
  70.265 +        if (getView() instanceof Scrollable) {
  70.266 +            return ((Scrollable)getView()).getScrollableTracksViewportWidth();
  70.267          }
  70.268          return false;
  70.269      }
  70.270 @@ -549,20 +611,19 @@
  70.271       * Scrolling containers, like {@code JScrollPane}, will use this method
  70.272       * each time the user requests a unit scroll.
  70.273       * <p/>
  70.274 -     * If the ui delegate of this layer is not {@code null}, this method delegates its
  70.275 -     * implementation to the {@code LayerUI.getScrollableUnitIncrement(JLayer,Rectangle,int,int)}
  70.276 +     * If the view component of this layer implements {@link Scrollable}, this method delegates its
  70.277 +     * implementation to the view component.
  70.278       *
  70.279       * @return The "unit" increment for scrolling in the specified direction.
  70.280       *         This value should always be positive.
  70.281       *
  70.282       * @see Scrollable
  70.283 -     * @see LayerUI#getScrollableUnitIncrement(JLayer, Rectangle, int, int)
  70.284       */
  70.285      public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation,
  70.286                                            int direction) {
  70.287 -        if (getUI() != null) {
  70.288 -            return getUI().getScrollableUnitIncrement(
  70.289 -                    this, visibleRect, orientation, direction);
  70.290 +        if (getView() instanceof Scrollable) {
  70.291 +            return ((Scrollable) getView()).getScrollableUnitIncrement(
  70.292 +                    visibleRect, orientation, direction);
  70.293          }
  70.294          return 1;
  70.295      }
  70.296 @@ -595,6 +656,16 @@
  70.297      }
  70.298  
  70.299      /**
  70.300 +     * Delegates its functionality to the {@link javax.swing.plaf.LayerUI#doLayout(JLayer)} method,
  70.301 +     * if {@code LayerUI} is set.
  70.302 +     */
  70.303 +    public void doLayout() {
  70.304 +        if (getUI() != null) {
  70.305 +            getUI().doLayout(this);
  70.306 +        }
  70.307 +    }
  70.308 +
  70.309 +    /**
  70.310       * static AWTEventListener to be shared with all AbstractLayerUIs
  70.311       */
  70.312      private static class LayerEventController implements AWTEventListener {
  70.313 @@ -625,8 +696,8 @@
  70.314                          JLayer l = (JLayer) component;
  70.315                          LayerUI ui = l.getUI();
  70.316                          if (ui != null &&
  70.317 -                                isEventEnabled(l.getLayerEventMask(),
  70.318 -                                        event.getID())) {
  70.319 +                                isEventEnabled(l.getLayerEventMask(), event.getID()) &&
  70.320 +                                (!(event instanceof InputEvent) || !((InputEvent)event).isConsumed())) {
  70.321                              ui.eventDispatched(event, l);
  70.322                          }
  70.323                      }
  70.324 @@ -758,82 +829,4 @@
  70.325              return super.contains(x, y);
  70.326          }
  70.327      }
  70.328 -
  70.329 -    /**
  70.330 -     * The default layout manager for the {@link javax.swing.JLayer}.<br/>
  70.331 -     * It places the glassPane on top of the view component
  70.332 -     * and makes it the same size as {@code JLayer},
  70.333 -     * it also makes the view component the same size but minus layer's insets<br/>
  70.334 -     */
  70.335 -    private static class DefaultLayerLayout implements LayoutManager, Serializable {
  70.336 -        /**
  70.337 -         * {@inheritDoc}
  70.338 -         */
  70.339 -        public void layoutContainer(Container parent) {
  70.340 -            JLayer layer = (JLayer) parent;
  70.341 -            Component view = layer.getView();
  70.342 -            Component glassPane = layer.getGlassPane();
  70.343 -            if (view != null) {
  70.344 -                Insets insets = layer.getInsets();
  70.345 -                view.setLocation(insets.left, insets.top);
  70.346 -                view.setSize(layer.getWidth() - insets.left - insets.right,
  70.347 -                        layer.getHeight() - insets.top - insets.bottom);
  70.348 -            }
  70.349 -            if (glassPane != null) {
  70.350 -                glassPane.setLocation(0, 0);
  70.351 -                glassPane.setSize(layer.getWidth(), layer.getHeight());
  70.352 -            }
  70.353 -        }
  70.354 -
  70.355 -        /**
  70.356 -         * {@inheritDoc}
  70.357 -         */
  70.358 -        public Dimension minimumLayoutSize(Container parent) {
  70.359 -            JLayer layer = (JLayer) parent;
  70.360 -            Insets insets = layer.getInsets();
  70.361 -            Dimension ret = new Dimension(insets.left + insets.right,
  70.362 -                    insets.top + insets.bottom);
  70.363 -            Component view = layer.getView();
  70.364 -            if (view != null) {
  70.365 -                Dimension size = view.getMinimumSize();
  70.366 -                ret.width += size.width;
  70.367 -                ret.height += size.height;
  70.368 -            }
  70.369 -            if (ret.width == 0 || ret.height == 0) {
  70.370 -                ret.width = ret.height = 4;
  70.371 -            }
  70.372 -            return ret;
  70.373 -        }
  70.374 -
  70.375 -        /**
  70.376 -         * {@inheritDoc}
  70.377 -         */
  70.378 -        public Dimension preferredLayoutSize(Container parent) {
  70.379 -            JLayer layer = (JLayer) parent;
  70.380 -            Insets insets = layer.getInsets();
  70.381 -            Dimension ret = new Dimension(insets.left + insets.right,
  70.382 -                    insets.top + insets.bottom);
  70.383 -            Component view = layer.getView();
  70.384 -            if (view != null) {
  70.385 -                Dimension size = view.getPreferredSize();
  70.386 -                if (size.width > 0 && size.height > 0) {
  70.387 -                    ret.width += size.width;
  70.388 -                    ret.height += size.height;
  70.389 -                }
  70.390 -            }
  70.391 -            return ret;
  70.392 -        }
  70.393 -
  70.394 -        /**
  70.395 -         * {@inheritDoc}
  70.396 -         */
  70.397 -        public void addLayoutComponent(String name, Component comp) {
  70.398 -        }
  70.399 -
  70.400 -        /**
  70.401 -         * {@inheritDoc}
  70.402 -         */
  70.403 -        public void removeLayoutComponent(Component comp) {
  70.404 -        }
  70.405 -    }
  70.406  }
    71.1 --- a/src/share/classes/javax/swing/JTable.java	Thu Oct 07 15:12:19 2010 -0700
    71.2 +++ b/src/share/classes/javax/swing/JTable.java	Tue Oct 12 12:51:48 2010 -0700
    71.3 @@ -4574,9 +4574,8 @@
    71.4       * @see TableColumnModelListener
    71.5       */
    71.6      public void columnMoved(TableColumnModelEvent e) {
    71.7 -        // If I'm currently editing, then I should stop editing
    71.8 -        if (isEditing()) {
    71.9 -            removeEditor();
   71.10 +        if (isEditing() && !getCellEditor().stopCellEditing()) {
   71.11 +            getCellEditor().cancelCellEditing();
   71.12          }
   71.13          repaint();
   71.14      }
   71.15 @@ -4593,8 +4592,8 @@
   71.16       * @see TableColumnModelListener
   71.17       */
   71.18      public void columnMarginChanged(ChangeEvent e) {
   71.19 -        if (isEditing()) {
   71.20 -            removeEditor();
   71.21 +        if (isEditing() && !getCellEditor().stopCellEditing()) {
   71.22 +            getCellEditor().cancelCellEditing();
   71.23          }
   71.24          TableColumn resizingColumn = getResizingColumn();
   71.25          // Need to do this here, before the parent's
    72.1 --- a/src/share/classes/javax/swing/ToolTipManager.java	Thu Oct 07 15:12:19 2010 -0700
    72.2 +++ b/src/share/classes/javax/swing/ToolTipManager.java	Tue Oct 12 12:51:48 2010 -0700
    72.3 @@ -459,7 +459,7 @@
    72.4          if (insideComponent == null) {
    72.5              // Drag exit
    72.6          }
    72.7 -        if (window != null && event.getSource() == window) {
    72.8 +        if (window != null && event.getSource() == window && insideComponent != null) {
    72.9            // if we get an exit and have a heavy window
   72.10            // we need to check if it if overlapping the inside component
   72.11              Container insideComponentWindow = insideComponent.getTopLevelAncestor();
    73.1 --- a/src/share/classes/javax/swing/plaf/LayerUI.java	Thu Oct 07 15:12:19 2010 -0700
    73.2 +++ b/src/share/classes/javax/swing/plaf/LayerUI.java	Tue Oct 12 12:51:48 2010 -0700
    73.3 @@ -600,104 +600,6 @@
    73.4      }
    73.5  
    73.6      /**
    73.7 -     * Returns the preferred size of the viewport for a view component.
    73.8 -     *
    73.9 -     * @param l the {@code JLayer} component where this UI delegate is being installed
   73.10 -     * @return the preferred size of the viewport for a view component
   73.11 -     * @see Scrollable#getPreferredScrollableViewportSize()
   73.12 -     */
   73.13 -    public Dimension getPreferredScrollableViewportSize(JLayer<? extends V> l) {
   73.14 -        if (l.getView() instanceof Scrollable) {
   73.15 -            return ((Scrollable)l.getView()).getPreferredScrollableViewportSize();
   73.16 -        }
   73.17 -        return l.getPreferredSize();
   73.18 -    }
   73.19 -
   73.20 -    /**
   73.21 -     * Returns a scroll increment, which is required for components
   73.22 -     * that display logical rows or columns in order to completely expose
   73.23 -     * one block of rows or columns, depending on the value of orientation.
   73.24 -     *
   73.25 -     * @param l the {@code JLayer} component where this UI delegate is being installed
   73.26 -     * @param visibleRect The view area visible within the viewport
   73.27 -     * @param orientation Either SwingConstants.VERTICAL or SwingConstants.HORIZONTAL.
   73.28 -     * @param direction Less than zero to scroll up/left, greater than zero for down/right.
   73.29 -     * @return the "block" increment for scrolling in the specified direction
   73.30 -     * @see Scrollable#getScrollableBlockIncrement(Rectangle, int, int)
   73.31 -     */
   73.32 -     public int getScrollableBlockIncrement(JLayer<? extends V> l,
   73.33 -                                           Rectangle visibleRect,
   73.34 -                                           int orientation, int direction) {
   73.35 -        if (l.getView() instanceof Scrollable) {
   73.36 -            return ((Scrollable)l.getView()).getScrollableBlockIncrement(
   73.37 -                    visibleRect,orientation, direction);
   73.38 -        }
   73.39 -        return (orientation == SwingConstants.VERTICAL) ? visibleRect.height :
   73.40 -            visibleRect.width;
   73.41 -    }
   73.42 -
   73.43 -    /**
   73.44 -     * Returns {@code false} to indicate that the height of the viewport does not
   73.45 -     * determine the height of the layer, unless the preferred height
   73.46 -     * of the layer is smaller than the height of the viewport.
   73.47 -     *
   73.48 -     * @param l the {@code JLayer} component where this UI delegate is being installed
   73.49 -     * @return whether the layer should track the height of the viewport
   73.50 -     * @see Scrollable#getScrollableTracksViewportHeight()
   73.51 -     */
   73.52 -    public boolean getScrollableTracksViewportHeight(JLayer<? extends V> l) {
   73.53 -        if (l.getView() instanceof Scrollable) {
   73.54 -            return ((Scrollable)l.getView()).getScrollableTracksViewportHeight();
   73.55 -        }
   73.56 -        return false;
   73.57 -    }
   73.58 -
   73.59 -    /**
   73.60 -     * Returns {@code false} to indicate that the width of the viewport does not
   73.61 -     * determine the width of the layer, unless the preferred width
   73.62 -     * of the layer is smaller than the width of the viewport.
   73.63 -     *
   73.64 -     * @param l the {@code JLayer} component where this UI delegate is being installed
   73.65 -     * @return whether the layer should track the width of the viewport
   73.66 -     * @see Scrollable
   73.67 -     * @see LayerUI#getScrollableTracksViewportWidth(JLayer)
   73.68 -     */
   73.69 -    public boolean getScrollableTracksViewportWidth(JLayer<? extends V> l) {
   73.70 -        if (l.getView() instanceof Scrollable) {
   73.71 -            return ((Scrollable)l.getView()).getScrollableTracksViewportWidth();
   73.72 -        }
   73.73 -        return false;
   73.74 -    }
   73.75 -
   73.76 -    /**
   73.77 -     * Returns a scroll increment, which is required for components
   73.78 -     * that display logical rows or columns in order to completely expose
   73.79 -     * one new row or column, depending on the value of orientation.
   73.80 -     * Ideally, components should handle a partially exposed row or column
   73.81 -     * by returning the distance required to completely expose the item.
   73.82 -     * <p>
   73.83 -     * Scrolling containers, like JScrollPane, will use this method
   73.84 -     * each time the user requests a unit scroll.
   73.85 -     *
   73.86 -     * @param l the {@code JLayer} component where this UI delegate is being installed
   73.87 -     * @param visibleRect The view area visible within the viewport
   73.88 -     * @param orientation Either SwingConstants.VERTICAL or SwingConstants.HORIZONTAL.
   73.89 -     * @param direction Less than zero to scroll up/left, greater than zero for down/right.
   73.90 -     * @return The "unit" increment for scrolling in the specified direction.
   73.91 -     *         This value should always be positive.
   73.92 -     * @see Scrollable#getScrollableUnitIncrement(Rectangle, int, int)
   73.93 -     */
   73.94 -    public int getScrollableUnitIncrement(JLayer<? extends V> l,
   73.95 -                                          Rectangle visibleRect,
   73.96 -                                          int orientation, int direction) {
   73.97 -        if (l.getView() instanceof Scrollable) {
   73.98 -            return ((Scrollable)l.getView()).getScrollableUnitIncrement(
   73.99 -                    visibleRect, orientation, direction);
  73.100 -        }
  73.101 -        return 1;
  73.102 -    }
  73.103 -
  73.104 -    /**
  73.105       * If the {@code JLayer}'s view component is not {@code null},
  73.106       * this calls the view's {@code getBaseline()} method.
  73.107       * Otherwise, the default implementation is called.
  73.108 @@ -718,7 +620,7 @@
  73.109  
  73.110      /**
  73.111       * If the {@code JLayer}'s view component is not {@code null},
  73.112 -     * this calls the view's {@code getBaselineResizeBehavior()} method.
  73.113 +     * this returns the result of the view's {@code getBaselineResizeBehavior()} method.
  73.114       * Otherwise, the default implementation is called.
  73.115       *
  73.116       * @param c {@code JLayer} to return baseline resize behavior for
  73.117 @@ -732,4 +634,90 @@
  73.118          }
  73.119          return super.getBaselineResizeBehavior(c);
  73.120      }
  73.121 +
  73.122 +    /**
  73.123 +     * Causes the passed instance of {@code JLayer} to lay out its components.
  73.124 +     *
  73.125 +     * @param l the {@code JLayer} component where this UI delegate is being installed
  73.126 +     */
  73.127 +    public void doLayout(JLayer<? extends V> l) {
  73.128 +        Component view = l.getView();
  73.129 +        if (view != null) {
  73.130 +            view.setBounds(0, 0, l.getWidth(), l.getHeight());
  73.131 +        }
  73.132 +        Component glassPane = l.getGlassPane();
  73.133 +        if (glassPane != null) {
  73.134 +            glassPane.setBounds(0, 0, l.getWidth(), l.getHeight());
  73.135 +        }
  73.136 +    }
  73.137 +
  73.138 +    /**
  73.139 +     * If the {@code JLayer}'s view component is not {@code null},
  73.140 +     * this returns the result of  the view's {@code getPreferredSize()} method.
  73.141 +     * Otherwise, the default implementation is used.
  73.142 +     *
  73.143 +     * @param c {@code JLayer} to return preferred size for
  73.144 +     * @return preferred size for the passed {@code JLayer}
  73.145 +     */
  73.146 +    public Dimension getPreferredSize(JComponent c) {
  73.147 +        JLayer l = (JLayer) c;
  73.148 +        Component view = l.getView();
  73.149 +        if (view != null) {
  73.150 +            return view.getPreferredSize();
  73.151 +        }
  73.152 +        return super.getPreferredSize(c);
  73.153 +    }
  73.154 +
  73.155 +    /**
  73.156 +     * If the {@code JLayer}'s view component is not {@code null},
  73.157 +     * this returns the result of  the view's {@code getMinimalSize()} method.
  73.158 +     * Otherwise, the default implementation is used.
  73.159 +     *
  73.160 +     * @param c {@code JLayer} to return preferred size for
  73.161 +     * @return minimal size for the passed {@code JLayer}
  73.162 +     */
  73.163 +    public Dimension getMinimumSize(JComponent c) {
  73.164 +        JLayer l = (JLayer) c;
  73.165 +        Component view = l.getView();
  73.166 +        if (view != null) {
  73.167 +            return view.getMinimumSize();
  73.168 +        }
  73.169 +        return super.getMinimumSize(c);
  73.170 +    }
  73.171 +
  73.172 +    /**
  73.173 +     * If the {@code JLayer}'s view component is not {@code null},
  73.174 +     * this returns the result of  the view's {@code getMaximumSize()} method.
  73.175 +     * Otherwise, the default implementation is used.
  73.176 +     *
  73.177 +     * @param c {@code JLayer} to return preferred size for
  73.178 +     * @return maximun size for the passed {@code JLayer}
  73.179 +     */
  73.180 +    public Dimension getMaximumSize(JComponent c) {
  73.181 +        JLayer l = (JLayer) c;
  73.182 +        Component view = l.getView();
  73.183 +        if (view != null) {
  73.184 +            return view.getMaximumSize();
  73.185 +        }
  73.186 +        return super.getMaximumSize(c);
  73.187 +    }
  73.188 +
  73.189 +    /**
  73.190 +     * Adds the specified region to the dirty region list if the component
  73.191 +     * is showing.  The component will be repainted after all of the
  73.192 +     * currently pending events have been dispatched.
  73.193 +     * <p/>
  73.194 +     * This method is to be overridden when the dirty region needs to be changed.
  73.195 +     *
  73.196 +     * @param tm  this parameter is not used
  73.197 +     * @param x  the x value of the dirty region
  73.198 +     * @param y  the y value of the dirty region
  73.199 +     * @param width  the width of the dirty region
  73.200 +     * @param height  the height of the dirty region
  73.201 +     * @see java.awt.Component#isShowing
  73.202 +     * @see RepaintManager#addDirtyRegion
  73.203 +     */
  73.204 +    public void repaint(long tm, int x, int y, int width, int height, JLayer<? extends V> l) {
  73.205 +        RepaintManager.currentManager(l).addDirtyRegion(l, x, y, width, height);
  73.206 +    }
  73.207  }
    74.1 --- a/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java	Thu Oct 07 15:12:19 2010 -0700
    74.2 +++ b/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java	Tue Oct 12 12:51:48 2010 -0700
    74.3 @@ -1603,6 +1603,7 @@
    74.4                  BoundedRangeModel newModel = (BoundedRangeModel)e.getNewValue();
    74.5                  oldModel.removeChangeListener(modelListener);
    74.6                  newModel.addChangeListener(modelListener);
    74.7 +                scrollBarValue = scrollbar.getValue();
    74.8                  scrollbar.repaint();
    74.9                  scrollbar.revalidate();
   74.10              } else if ("orientation" == propertyName) {
    75.1 --- a/src/share/classes/javax/swing/plaf/metal/MetalComboBoxUI.java	Thu Oct 07 15:12:19 2010 -0700
    75.2 +++ b/src/share/classes/javax/swing/plaf/metal/MetalComboBoxUI.java	Tue Oct 12 12:51:48 2010 -0700
    75.3 @@ -144,7 +144,7 @@
    75.4       */
    75.5      public int getBaseline(JComponent c, int width, int height) {
    75.6          int baseline;
    75.7 -        if (MetalLookAndFeel.usingOcean()) {
    75.8 +        if (MetalLookAndFeel.usingOcean() && height >= 4) {
    75.9              height -= 4;
   75.10              baseline = super.getBaseline(c, width, height);
   75.11              if (baseline >= 0) {
    76.1 --- a/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java	Thu Oct 07 15:12:19 2010 -0700
    76.2 +++ b/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java	Tue Oct 12 12:51:48 2010 -0700
    76.3 @@ -115,6 +115,9 @@
    76.4          return new SynthTabbedPaneUI();
    76.5      }
    76.6  
    76.7 +    private SynthTabbedPaneUI() {
    76.8 +    }
    76.9 +
   76.10      private boolean scrollableTabLayoutEnabled() {
   76.11          return (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT);
   76.12      }
    77.1 --- a/src/share/classes/sun/awt/AWTAccessor.java	Thu Oct 07 15:12:19 2010 -0700
    77.2 +++ b/src/share/classes/sun/awt/AWTAccessor.java	Tue Oct 12 12:51:48 2010 -0700
    77.3 @@ -344,6 +344,11 @@
    77.4           * Removes the last focus request for the heavyweight from the queue.
    77.5           */
    77.6          void removeLastFocusRequest(Component heavyweight);
    77.7 +
    77.8 +        /*
    77.9 +         * Sets the most recent focus owner in the window.
   77.10 +         */
   77.11 +        void setMostRecentFocusOwner(Window window, Component component);
   77.12      }
   77.13  
   77.14      /*
    78.1 --- a/src/share/classes/sun/awt/EmbeddedFrame.java	Thu Oct 07 15:12:19 2010 -0700
    78.2 +++ b/src/share/classes/sun/awt/EmbeddedFrame.java	Tue Oct 12 12:51:48 2010 -0700
    78.3 @@ -70,7 +70,10 @@
    78.4      // JDK 1.1 compatibility
    78.5      private static final long serialVersionUID = 2967042741780317130L;
    78.6  
    78.7 -    // Use these in traverseOut method to determine directions
    78.8 +    /*
    78.9 +     * The constants define focus traversal directions.
   78.10 +     * Use them in {@code traverseIn}, {@code traverseOut} methods.
   78.11 +     */
   78.12      protected static final boolean FORWARD = true;
   78.13      protected static final boolean BACKWARD = false;
   78.14  
   78.15 @@ -284,6 +287,41 @@
   78.16      }
   78.17  
   78.18      /**
   78.19 +     * This method is called by the embedder when we should receive focus as element
   78.20 +     * of the traversal chain.  The method requests focus on:
   78.21 +     * 1. the first Component of this EmbeddedFrame if user moves focus forward
   78.22 +     *    in the focus traversal cycle.
   78.23 +     * 2. the last Component of this EmbeddedFrame if user moves focus backward
   78.24 +     *    in the focus traversal cycle.
   78.25 +     *
   78.26 +     * The direction parameter specifies which of the two mentioned cases is
   78.27 +     * happening. Use FORWARD and BACKWARD constants defined in the EmbeddedFrame class
   78.28 +     * to avoid confusing boolean values.
   78.29 +     *
   78.30 +     * A concrete implementation of this method is defined in the platform-dependent
   78.31 +     * subclasses.
   78.32 +     *
   78.33 +     * @param direction FORWARD or BACKWARD
   78.34 +     * @return true, if the EmbeddedFrame wants to get focus, false otherwise.
   78.35 +     */
   78.36 +    public boolean traverseIn(boolean direction) {
   78.37 +        Component comp = null;
   78.38 +
   78.39 +        if (direction == FORWARD) {
   78.40 +            comp = getFocusTraversalPolicy().getFirstComponent(this);
   78.41 +        } else {
   78.42 +            comp = getFocusTraversalPolicy().getLastComponent(this);
   78.43 +        }
   78.44 +        if (comp != null) {
   78.45 +            // comp.requestFocus(); - Leads to a hung.
   78.46 +
   78.47 +            AWTAccessor.getKeyboardFocusManagerAccessor().setMostRecentFocusOwner(this, comp);
   78.48 +            synthesizeWindowActivation(true);
   78.49 +        }
   78.50 +        return (null != comp);
   78.51 +    }
   78.52 +
   78.53 +    /**
   78.54       * This method is called from dispatchKeyEvent in the following two cases:
   78.55       * 1. The focus is on the first Component of this EmbeddedFrame and we are
   78.56       *    about to transfer the focus backward.
    79.1 --- a/src/share/classes/sun/net/www/http/HttpClient.java	Thu Oct 07 15:12:19 2010 -0700
    79.2 +++ b/src/share/classes/sun/net/www/http/HttpClient.java	Tue Oct 12 12:51:48 2010 -0700
    79.3 @@ -55,6 +55,9 @@
    79.4      // Http data we send with the headers
    79.5      PosterOutputStream poster = null;
    79.6  
    79.7 +    // true if we are in streaming mode (fixed length or chunked)
    79.8 +    boolean streaming;
    79.9 +
   79.10      // if we've had one io error
   79.11      boolean failedOnce = false;
   79.12  
   79.13 @@ -275,6 +278,10 @@
   79.14                          ret.cachedHttpClient = true;
   79.15                          assert ret.inCache;
   79.16                          ret.inCache = false;
   79.17 +                        PlatformLogger logger = HttpURLConnection.getHttpLogger();
   79.18 +                        if (logger.isLoggable(PlatformLogger.FINEST)) {
   79.19 +                            logger.finest("KeepAlive stream retrieved from the cache, " + ret);
   79.20 +                        }
   79.21                      }
   79.22                  } else {
   79.23                      // We cannot return this connection to the cache as it's
   79.24 @@ -545,6 +552,13 @@
   79.25          serverOutput.flush();
   79.26      }
   79.27  
   79.28 +    public void writeRequests(MessageHeader head,
   79.29 +                              PosterOutputStream pos,
   79.30 +                              boolean streaming) throws IOException {
   79.31 +        this.streaming = streaming;
   79.32 +        writeRequests(head, pos);
   79.33 +    }
   79.34 +
   79.35      /** Parse the first line of the HTTP request.  It usually looks
   79.36          something like: "HTTP/1.0 <number> comment\r\n". */
   79.37  
   79.38 @@ -577,11 +591,11 @@
   79.39              closeServer();
   79.40              cachedHttpClient = false;
   79.41              if (!failedOnce && requests != null) {
   79.42 -                if (httpuc.getRequestMethod().equals("POST") && !retryPostProp) {
   79.43 +                failedOnce = true;
   79.44 +                if (httpuc.getRequestMethod().equals("POST") && (!retryPostProp || streaming)) {
   79.45                      // do not retry the request
   79.46                  }  else {
   79.47                      // try once more
   79.48 -                    failedOnce = true;
   79.49                      openServer();
   79.50                      if (needsTunneling()) {
   79.51                          httpuc.doTunneling();
   79.52 @@ -684,10 +698,10 @@
   79.53                  }
   79.54              } else if (nread != 8) {
   79.55                  if (!failedOnce && requests != null) {
   79.56 -                    if (httpuc.getRequestMethod().equals("POST") && !retryPostProp) {
   79.57 +                    failedOnce = true;
   79.58 +                    if (httpuc.getRequestMethod().equals("POST") && (!retryPostProp || streaming)) {
   79.59                          // do not retry the request
   79.60                      } else {
   79.61 -                        failedOnce = true;
   79.62                          closeServer();
   79.63                          cachedHttpClient = false;
   79.64                          openServer();
    80.1 --- a/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Thu Oct 07 15:12:19 2010 -0700
    80.2 +++ b/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Tue Oct 12 12:51:48 2010 -0700
    80.3 @@ -494,7 +494,7 @@
    80.4          if (logger.isLoggable(PlatformLogger.FINE)) {
    80.5              logger.fine(requests.toString());
    80.6          }
    80.7 -        http.writeRequests(requests, poster);
    80.8 +        http.writeRequests(requests, poster, streaming());
    80.9          if (ps.checkError()) {
   80.10              String proxyHost = http.getProxyHostUsed();
   80.11              int proxyPort = http.getProxyPortUsed();
   80.12 @@ -2825,6 +2825,38 @@
   80.13              }
   80.14          }
   80.15  
   80.16 +        /* skip() calls read() in order to ensure that entire response gets
   80.17 +         * cached. same implementation as InputStream.skip */
   80.18 +
   80.19 +        private byte[] skipBuffer;
   80.20 +        private static final int SKIP_BUFFER_SIZE = 8096;
   80.21 +
   80.22 +        @Override
   80.23 +        public long skip (long n) throws IOException {
   80.24 +
   80.25 +            long remaining = n;
   80.26 +            int nr;
   80.27 +            if (skipBuffer == null)
   80.28 +                skipBuffer = new byte[SKIP_BUFFER_SIZE];
   80.29 +
   80.30 +            byte[] localSkipBuffer = skipBuffer;
   80.31 +
   80.32 +            if (n <= 0) {
   80.33 +                return 0;
   80.34 +            }
   80.35 +
   80.36 +            while (remaining > 0) {
   80.37 +                nr = read(localSkipBuffer, 0,
   80.38 +                          (int) Math.min(SKIP_BUFFER_SIZE, remaining));
   80.39 +                if (nr < 0) {
   80.40 +                    break;
   80.41 +                }
   80.42 +                remaining -= nr;
   80.43 +            }
   80.44 +
   80.45 +            return n - remaining;
   80.46 +        }
   80.47 +
   80.48          @Override
   80.49          public void close () throws IOException {
   80.50              try {
    81.1 --- a/src/share/classes/sun/security/tools/KeyTool.java	Thu Oct 07 15:12:19 2010 -0700
    81.2 +++ b/src/share/classes/sun/security/tools/KeyTool.java	Tue Oct 12 12:51:48 2010 -0700
    81.3 @@ -281,7 +281,7 @@
    81.4          RFC("rfc", null, "output in RFC style"),
    81.5          SIGALG("sigalg", "<sigalg>", "signature algorithm name"),
    81.6          SRCALIAS("srcalias", "<srcalias>", "source alias"),
    81.7 -        SRCKEYPASS("srckeypass", "<arg>", "source keystore password"),
    81.8 +        SRCKEYPASS("srckeypass", "<arg>", "source key password"),
    81.9          SRCKEYSTORE("srckeystore", "<srckeystore>", "source keystore name"),
   81.10          SRCPROTECTED("srcprotected", null, "source keystore password protected"),
   81.11          SRCPROVIDERNAME("srcprovidername", "<srcprovidername>", "source keystore provider name"),
    82.1 --- a/src/share/classes/sun/security/util/Resources.java	Thu Oct 07 15:12:19 2010 -0700
    82.2 +++ b/src/share/classes/sun/security/util/Resources.java	Tue Oct 12 12:51:48 2010 -0700
    82.3 @@ -116,11 +116,9 @@
    82.4          {"X.509 extension",
    82.5                  "X.509 extension"}, //-ext
    82.6          {"output file name",
    82.7 -                "output file name"}, //-file
    82.8 +                "output file name"}, //-file and -outfile
    82.9          {"input file name",
   82.10 -                "input file name"}, //-file
   82.11 -        {"input file name",
   82.12 -                "input file name"}, //-infile
   82.13 +                "input file name"}, //-file and -infile
   82.14          {"key algorithm name",
   82.15                  "key algorithm name"}, //-keyalg
   82.16          {"key password",
   82.17 @@ -133,8 +131,6 @@
   82.18                  "new password"}, //-new
   82.19          {"do not prompt",
   82.20                  "do not prompt"}, //-noprompt
   82.21 -        {"output file name",
   82.22 -                "output file name"}, //-outfile
   82.23          {"password through protected mechanism",
   82.24                  "password through protected mechanism"}, //-protected
   82.25          {"provider argument",
   82.26 @@ -151,8 +147,8 @@
   82.27                  "signature algorithm name"}, //-sigalg
   82.28          {"source alias",
   82.29                  "source alias"}, //-srcalias
   82.30 -        {"source keystore password",
   82.31 -                "source keystore password"}, //-srckeypass
   82.32 +        {"source key password",
   82.33 +                "source key password"}, //-srckeypass
   82.34          {"source keystore name",
   82.35                  "source keystore name"}, //-srckeystore
   82.36          {"source keystore password protected",
   82.37 @@ -276,8 +272,6 @@
   82.38                  "Alias <{0}> has no certificate"},
   82.39          {"Key pair not generated, alias <alias> already exists",
   82.40                  "Key pair not generated, alias <{0}> already exists"},
   82.41 -        {"Cannot derive signature algorithm",
   82.42 -                "Cannot derive signature algorithm"},
   82.43          {"Generating keysize bit keyAlgName key pair and self-signed certificate (sigAlgName) with a validity of validality days\n\tfor: x500Name",
   82.44                  "Generating {0} bit {1} key pair and self-signed certificate ({2}) with a validity of {3} days\n\tfor: {4}"},
   82.45          {"Enter key password for <alias>", "Enter key password for <{0}>"},
   82.46 @@ -321,8 +315,6 @@
   82.47          {"Failed to parse input", "Failed to parse input"},
   82.48          {"Empty input", "Empty input"},
   82.49          {"Not X.509 certificate", "Not X.509 certificate"},
   82.50 -        {"Cannot derive signature algorithm",
   82.51 -                "Cannot derive signature algorithm"},
   82.52          {"alias has no public key", "{0} has no public key"},
   82.53          {"alias has no X.509 certificate", "{0} has no X.509 certificate"},
   82.54          {"New certificate (self-signed):", "New certificate (self-signed):"},
   82.55 @@ -552,7 +544,6 @@
   82.56          {"package name", "package name"},
   82.57          {"policy type", "policy type"},
   82.58          {"property name", "property name"},
   82.59 -        {"provider name", "provider name"},
   82.60          {"Principal List", "Principal List"},
   82.61          {"Permission List", "Permission List"},
   82.62          {"Code Base", "Code Base"},
    83.1 --- a/src/share/classes/sun/util/locale/BaseLocale.java	Thu Oct 07 15:12:19 2010 -0700
    83.2 +++ b/src/share/classes/sun/util/locale/BaseLocale.java	Tue Oct 12 12:51:48 2010 -0700
    83.3 @@ -64,12 +64,14 @@
    83.4  
    83.5      public static BaseLocale getInstance(String language, String script, String region, String variant) {
    83.6          // JDK uses deprecated ISO639.1 language codes for he, yi and id
    83.7 -        if (AsciiUtil.caseIgnoreMatch(language, "he")) {
    83.8 -            language = "iw";
    83.9 -        } else if (AsciiUtil.caseIgnoreMatch(language, "yi")) {
   83.10 -            language = "ji";
   83.11 -        } else if (AsciiUtil.caseIgnoreMatch(language, "id")) {
   83.12 -            language = "in";
   83.13 +        if (language != null) {
   83.14 +            if (AsciiUtil.caseIgnoreMatch(language, "he")) {
   83.15 +                language = "iw";
   83.16 +            } else if (AsciiUtil.caseIgnoreMatch(language, "yi")) {
   83.17 +                language = "ji";
   83.18 +            } else if (AsciiUtil.caseIgnoreMatch(language, "id")) {
   83.19 +                language = "in";
   83.20 +            }
   83.21          }
   83.22  
   83.23          Key key = new Key(language, script, region, variant);
    84.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    84.2 +++ b/src/share/demo/nio/zipfs/Demo.java	Tue Oct 12 12:51:48 2010 -0700
    84.3 @@ -0,0 +1,664 @@
    84.4 +/*
    84.5 + * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
    84.6 + *
    84.7 + * Redistribution and use in source and binary forms, with or without
    84.8 + * modification, are permitted provided that the following conditions
    84.9 + * are met:
   84.10 + *
   84.11 + *   - Redistributions of source code must retain the above copyright
   84.12 + *     notice, this list of conditions and the following disclaimer.
   84.13 + *
   84.14 + *   - Redistributions in binary form must reproduce the above copyright
   84.15 + *     notice, this list of conditions and the following disclaimer in the
   84.16 + *     documentation and/or other materials provided with the distribution.
   84.17 + *
   84.18 + *   - Neither the name of Oracle nor the names of its
   84.19 + *     contributors may be used to endorse or promote products derived
   84.20 + *     from this software without specific prior written permission.
   84.21 + *
   84.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
   84.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   84.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   84.25 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   84.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   84.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   84.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   84.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   84.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   84.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   84.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   84.33 + */
   84.34 +
   84.35 +import java.io.*;
   84.36 +import java.nio.*;
   84.37 +import java.nio.channels.*;
   84.38 +import java.nio.file.*;
   84.39 +import java.nio.file.attribute.*;
   84.40 +import java.net.*;
   84.41 +import java.text.DateFormat;
   84.42 +import java.text.SimpleDateFormat;
   84.43 +import java.util.*;
   84.44 +
   84.45 +import static java.nio.file.StandardOpenOption.*;
   84.46 +import static java.nio.file.StandardCopyOption.*;
   84.47 +
   84.48 +/*
   84.49 + * ZipFileSystem usage demo
   84.50 + *
   84.51 + * java [-cp .../zipfs.jar:./] Demo action ZipfileName [...]
   84.52 + *
   84.53 + * To deploy the provider, either copy the zipfs.jar into JDK/JRE
   84.54 + * extensions directory or add
   84.55 + *      <JDK_HOME>/demo/nio/ZipFileSystem/zipfs.jar
   84.56 + * into your class path as showed above.
   84.57 + *
   84.58 + * @author Xueming Shen
   84.59 + */
   84.60 +
   84.61 +public class Demo {
   84.62 +
   84.63 +    static enum Action {
   84.64 +        rename,          // <java Demo rename zipfile src dst>
   84.65 +                         // rename entry src to dst inside zipfile
   84.66 +
   84.67 +        movein,          // <java Demo movein zipfile src dst>
   84.68 +                         // move an external src file into zipfile
   84.69 +                         // as entry dst
   84.70 +
   84.71 +        moveout,         // <java Demo moveout zipfile src dst>
   84.72 +                         // move a zipfile entry src out to dst
   84.73 +
   84.74 +        copy,            // <java Demo copy zipfile src dst>
   84.75 +                         // copy entry src to dst inside zipfile
   84.76 +
   84.77 +        copyin,          // <java Demo copyin zipfile src dst>
   84.78 +                         // copy an external src file into zipfile
   84.79 +                         // as entry dst
   84.80 +
   84.81 +        copyout,         // <java Demo copyout zipfile src dst>
   84.82 +                         // copy zipfile entry src" out to file dst
   84.83 +
   84.84 +        zzmove,          // <java Demo zzmove zfsrc zfdst path>
   84.85 +                         // move entry path/dir from zfsrc to zfdst
   84.86 +
   84.87 +        zzcopy,          // <java Demo zzcopy zfsrc zfdst path>
   84.88 +                         // copy path from zipfile zfsrc to zipfile
   84.89 +                         // zfdst
   84.90 +
   84.91 +        attrs,           // <java Demo attrs zipfile path>
   84.92 +                         // printout the attributes of entry path
   84.93 +
   84.94 +        attrsspace,      // <java Demo attrsspace zipfile path>
   84.95 +                         // printout the storespace attrs of entry path
   84.96 +
   84.97 +        setmtime,        // <java Demo setmtime zipfile "MM/dd/yy-HH:mm:ss" path...>
   84.98 +                         // set the lastModifiedTime of entry path
   84.99 +
  84.100 +        lsdir,           // <java Demo lsdir zipfile dir>
  84.101 +                         // list dir's direct child files/dirs
  84.102 +
  84.103 +        mkdir,           // <java Demo mkdir zipfile dir>
  84.104 +
  84.105 +        mkdirs,          // <java Demo mkdirs zipfile dir>
  84.106 +
  84.107 +        rmdirs,          // <java Demo rmdirs zipfile dir>
  84.108 +
  84.109 +        list,            // <java Demo list zipfile [dir]>
  84.110 +                         // recursively list all entries of dir
  84.111 +                         // via DirectoryStream
  84.112 +
  84.113 +        tlist,           // <java Demo tlist zipfile [dir]>
  84.114 +                         // list with buildDirTree=true
  84.115 +
  84.116 +        vlist,           // <java Demo vlist zipfile [dir]>
  84.117 +                         // recursively verbose list all entries of
  84.118 +                         // dir via DirectoryStream
  84.119 +
  84.120 +        walk,            // <java Demo walk zipfile [dir]>
  84.121 +                         // recursively walk all entries of dir
  84.122 +                         // via Files.walkFileTree
  84.123 +
  84.124 +        twalk,           // <java Demo twalk zipfile [dir]>
  84.125 +                         // walk with buildDirTree=true
  84.126 +
  84.127 +        extract,         // <java Demo extract zipfile file [...]>
  84.128 +
  84.129 +        update,          // <java Demo extract zipfile file [...]>
  84.130 +
  84.131 +        delete,          // <java Demo delete zipfile file [...]>
  84.132 +
  84.133 +        add,             // <java Demo add zipfile file [...]>
  84.134 +
  84.135 +        create,          // <java Demo create zipfile file [...]>
  84.136 +                         // create a new zipfile if it doesn't exit
  84.137 +                         // and then add the file(s) into it.
  84.138 +
  84.139 +        attrs2,          // <java Demo attrs2 zipfile file [...]>
  84.140 +                         // test different ways to print attrs
  84.141 +    }
  84.142 +
  84.143 +    public static void main(String[] args) throws Throwable {
  84.144 +
  84.145 +        Action action = Action.valueOf(args[0]);;
  84.146 +        Map<String, Object> env = env = new HashMap<String, Object>();
  84.147 +        if (action == Action.create)
  84.148 +            env.put("createNew", true);
  84.149 +        if (action == Action.tlist || action == Action.twalk)
  84.150 +            env.put("buildDirTree", true);
  84.151 +
  84.152 +        FileSystem fs = FileSystems.newFileSystem(
  84.153 +                            URI.create("zip" + Paths.get(args[1]).toUri().toString().substring(4)),
  84.154 +                            env,
  84.155 +                            null);
  84.156 +        try {
  84.157 +            FileSystem fs2;
  84.158 +            Path path, src, dst;
  84.159 +            boolean isRename = false;
  84.160 +            switch (action) {
  84.161 +            case rename:
  84.162 +                src = fs.getPath(args[2]);
  84.163 +                dst = fs.getPath(args[3]);
  84.164 +                src.moveTo(dst);
  84.165 +                break;
  84.166 +            case moveout:
  84.167 +                src = fs.getPath(args[2]);
  84.168 +                dst = Paths.get(args[3]);
  84.169 +                src.moveTo(dst);
  84.170 +                break;
  84.171 +            case movein:
  84.172 +                src = Paths.get(args[2]);
  84.173 +                dst = fs.getPath(args[3]);
  84.174 +                src.moveTo(dst);
  84.175 +                break;
  84.176 +            case copy:
  84.177 +                src = fs.getPath(args[2]);
  84.178 +                dst = fs.getPath(args[3]);
  84.179 +                src.copyTo(dst);
  84.180 +                break;
  84.181 +            case copyout:
  84.182 +                src = fs.getPath(args[2]);
  84.183 +                dst = Paths.get(args[3]);
  84.184 +                src.copyTo(dst);
  84.185 +                break;
  84.186 +            case copyin:
  84.187 +                src = Paths.get(args[2]);
  84.188 +                dst = fs.getPath(args[3]);
  84.189 +                src.copyTo(dst);
  84.190 +                break;
  84.191 +            case zzmove:
  84.192 +                fs2 = FileSystems.newFileSystem(
  84.193 +                    URI.create("zip" + Paths.get(args[2]).toUri().toString().substring(4)),
  84.194 +                    env,
  84.195 +                    null);
  84.196 +                //sf1.getPath(args[3]).moveTo(fs2.getPath(args[3]));
  84.197 +                z2zmove(fs, fs2, args[3]);
  84.198 +                fs2.close();
  84.199 +                break;
  84.200 +            case zzcopy:
  84.201 +                fs2 = FileSystems.newFileSystem(
  84.202 +                    URI.create("zip" + Paths.get(args[2]).toUri().toString().substring(4)),
  84.203 +                    env,
  84.204 +                    null);
  84.205 +                //sf1.getPath(args[3]).copyTo(fs2.getPath(args[3]));
  84.206 +                z2zcopy(fs, fs2, args[3]);
  84.207 +                fs2.close();
  84.208 +                break;
  84.209 +            case attrs:
  84.210 +                for (int i = 2; i < args.length; i++) {
  84.211 +                    path = fs.getPath(args[i]);
  84.212 +                    System.out.println(
  84.213 +                        Attributes.readBasicFileAttributes(path).toString());
  84.214 +                }
  84.215 +                break;
  84.216 +            case setmtime:
  84.217 +                DateFormat df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss");
  84.218 +                Date newDatetime = df.parse(args[2]);
  84.219 +                for (int i = 3; i < args.length; i++) {
  84.220 +                    path = fs.getPath(args[i]);
  84.221 +                    path.setAttribute("lastModifiedTime",
  84.222 +                                      FileTime.fromMillis(newDatetime.getTime()));
  84.223 +                    System.out.println(
  84.224 +                        Attributes.readBasicFileAttributes(path).toString());
  84.225 +                }
  84.226 +                break;
  84.227 +            case attrsspace:
  84.228 +                path = fs.getPath("/");
  84.229 +                FileStore fstore = path.getFileStore();
  84.230 +                //System.out.println(fstore.getFileStoreAttributeView(FileStoreSpaceAttributeView.class)
  84.231 +                //                         .readAttributes());
  84.232 +                // or
  84.233 +                System.out.printf("filestore[%s]%n", fstore.name());
  84.234 +                System.out.printf("    totalSpace: %d%n",
  84.235 +                                  (Long)fstore.getAttribute("space:totalSpace"));
  84.236 +                System.out.printf("   usableSpace: %d%n",
  84.237 +                                  (Long)fstore.getAttribute("space:usableSpace"));
  84.238 +                System.out.printf("  unallocSpace: %d%n",
  84.239 +                                  (Long)fstore.getAttribute("space:unallocatedSpace"));
  84.240 +                break;
  84.241 +            case list:
  84.242 +            case tlist:
  84.243 +                if (args.length < 3)
  84.244 +                    list(fs.getPath("/"), false);
  84.245 +                else
  84.246 +                    list(fs.getPath(args[2]), false);
  84.247 +                break;
  84.248 +            case vlist:
  84.249 +                if (args.length < 3)
  84.250 +                    list(fs.getPath("/"), true);
  84.251 +                else
  84.252 +                    list(fs.getPath(args[2]), true);
  84.253 +                break;
  84.254 +            case twalk:
  84.255 +            case walk:
  84.256 +                walk(fs.getPath((args.length > 2)? args[2] : "/"));
  84.257 +                break;
  84.258 +            case extract:
  84.259 +                if (args.length == 2) {
  84.260 +                     extract(fs, "/");
  84.261 +                } else {
  84.262 +                    for (int i = 2; i < args.length; i++) {
  84.263 +                        extract(fs, args[i]);
  84.264 +                    }
  84.265 +                }
  84.266 +                break;
  84.267 +            case delete:
  84.268 +                for (int i = 2; i < args.length; i++)
  84.269 +                    fs.getPath(args[i]).delete();
  84.270 +                break;
  84.271 +            case create:
  84.272 +            case add:
  84.273 +            case update:
  84.274 +                for (int i = 2; i < args.length; i++) {
  84.275 +                    update(fs, args[i]);
  84.276 +                }
  84.277 +                break;
  84.278 +            case lsdir:
  84.279 +                path = fs.getPath(args[2]);
  84.280 +                final String fStr = (args.length > 3)?args[3]:"";
  84.281 +                DirectoryStream<Path> ds = path.newDirectoryStream(
  84.282 +                    new DirectoryStream.Filter<Path>() {
  84.283 +                        public boolean accept(Path path) {
  84.284 +                            return path.toString().contains(fStr);
  84.285 +                        }
  84.286 +                    });
  84.287 +                for (Path p : ds)
  84.288 +                    System.out.println(p);
  84.289 +                break;
  84.290 +            case mkdir:
  84.291 +                fs.getPath(args[2]).createDirectory();
  84.292 +                break;
  84.293 +            case mkdirs:
  84.294 +                mkdirs(fs.getPath(args[2]));
  84.295 +                break;
  84.296 +            case attrs2:
  84.297 +                for (int i = 2; i < args.length; i++) {
  84.298 +                    path = fs.getPath(args[i]);
  84.299 +                    System.out.println("-------(1)---------");
  84.300 +                    System.out.println(
  84.301 +                        Attributes.readBasicFileAttributes(path).toString());
  84.302 +                    System.out.println("-------(2)---------");
  84.303 +                    Map<String, ?> map = path.readAttributes("zip:*");
  84.304 +                    for (Map.Entry<String, ?> e : map.entrySet()) {
  84.305 +                        System.out.printf("    %s : %s%n", e.getKey(), e.getValue());
  84.306 +                    }
  84.307 +                    System.out.println("-------(3)---------");
  84.308 +                    map = path.readAttributes("size,lastModifiedTime,isDirectory");
  84.309 +                    for (Map.Entry<String, ?> e : map.entrySet()) {
  84.310 +                        System.out.printf("    %s : %s%n", e.getKey(), e.getValue());
  84.311 +                    }
  84.312 +                }
  84.313 +                break;
  84.314 +            }
  84.315 +        } catch (Exception x) {
  84.316 +            x.printStackTrace();
  84.317 +        } finally {
  84.318 +            if (fs != null)
  84.319 +                fs.close();
  84.320 +        }
  84.321 +    }
  84.322 +
  84.323 +    private static byte[] getBytes(String name) {
  84.324 +        return name.getBytes();
  84.325 +    }
  84.326 +
  84.327 +    private static String getString(byte[] name) {
  84.328 +        return new String(name);
  84.329 +    }
  84.330 +
  84.331 +    private static void walk(Path path) throws IOException
  84.332 +    {
  84.333 +        Files.walkFileTree(
  84.334 +            path,
  84.335 +            new SimpleFileVisitor<Path>() {
  84.336 +                private int indent = 0;
  84.337 +                private void indent() {
  84.338 +                    int n = 0;
  84.339 +                    while (n++ < indent)
  84.340 +                        System.out.printf(" ");
  84.341 +                }
  84.342 +
  84.343 +                @Override
  84.344 +                public FileVisitResult visitFile(Path file,
  84.345 +                                                 BasicFileAttributes attrs)
  84.346 +                {
  84.347 +                    indent();
  84.348 +                    System.out.printf("%s%n", file.getName().toString());
  84.349 +                    return FileVisitResult.CONTINUE;
  84.350 +                }
  84.351 +
  84.352 +                @Override
  84.353 +                public FileVisitResult preVisitDirectory(Path dir,
  84.354 +                                                         BasicFileAttributes attrs)
  84.355 +                {
  84.356 +                    indent();
  84.357 +                    System.out.printf("[%s]%n", dir.toString());
  84.358 +                    indent += 2;
  84.359 +                    return FileVisitResult.CONTINUE;
  84.360 +                }
  84.361 +
  84.362 +                @Override
  84.363 +                public FileVisitResult postVisitDirectory(Path dir,
  84.364 +                                                          IOException ioe)
  84.365 +                {
  84.366 +                    indent -= 2;
  84.367 +                    return FileVisitResult.CONTINUE;
  84.368 +                }
  84.369 +        });
  84.370 +    }
  84.371 +
  84.372 +    private static void update(FileSystem fs, String path) throws Throwable{
  84.373 +        Path src = FileSystems.getDefault().getPath(path);
  84.374 +        if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) {
  84.375 +            DirectoryStream<Path> ds = src.newDirectoryStream();
  84.376 +            for (Path child : ds)
  84.377 +                update(fs, child.toString());
  84.378 +            ds.close();
  84.379 +        } else {
  84.380 +            Path dst = fs.getPath(path);
  84.381 +            Path parent = dst.getParent();
  84.382 +            if (parent != null && parent.notExists())
  84.383 +                mkdirs(parent);
  84.384 +            src.copyTo(dst, REPLACE_EXISTING);
  84.385 +        }
  84.386 +    }
  84.387 +
  84.388 +    private static void extract(FileSystem fs, String path) throws Throwable{
  84.389 +        Path src = fs.getPath(path);
  84.390 +        if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) {
  84.391 +            DirectoryStream<Path> ds = src.newDirectoryStream();
  84.392 +            for (Path child : ds)
  84.393 +                extract(fs, child.toString());
  84.394 +            ds.close();
  84.395 +        } else {
  84.396 +            if (path.startsWith("/"))
  84.397 +                path = path.substring(1);
  84.398 +            Path dst = FileSystems.getDefault().getPath(path);
  84.399 +            Path parent = dst.getParent();
  84.400 +            if (parent.notExists())
  84.401 +                mkdirs(parent);
  84.402 +            src.copyTo(dst, REPLACE_EXISTING);
  84.403 +        }
  84.404 +    }
  84.405 +
  84.406 +    // use DirectoryStream
  84.407 +    private static void z2zcopy(FileSystem src, FileSystem dst, String path)
  84.408 +        throws IOException
  84.409 +    {
  84.410 +        Path srcPath = src.getPath(path);
  84.411 +        Path dstPath = dst.getPath(path);
  84.412 +
  84.413 +        if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) {
  84.414 +            if (!dstPath.exists()) {
  84.415 +                try {
  84.416 +                    mkdirs(dstPath);
  84.417 +                } catch (FileAlreadyExistsException x) {}
  84.418 +            }
  84.419 +            DirectoryStream<Path> ds = srcPath.newDirectoryStream();
  84.420 +            for (Path child : ds) {
  84.421 +                z2zcopy(src, dst,
  84.422 +                        path + (path.endsWith("/")?"":"/") + child.getName());
  84.423 +            }
  84.424 +            ds.close();
  84.425 +        } else {
  84.426 +            //System.out.println("copying..." + path);
  84.427 +            srcPath.copyTo(dstPath);
  84.428 +        }
  84.429 +    }
  84.430 +
  84.431 +    // use TreeWalk to move
  84.432 +    private static void z2zmove(FileSystem src, FileSystem dst, String path)
  84.433 +        throws IOException
  84.434 +    {
  84.435 +        final Path srcPath = src.getPath(path).toAbsolutePath();
  84.436 +        final Path dstPath = dst.getPath(path).toAbsolutePath();
  84.437 +
  84.438 +        Files.walkFileTree(srcPath, new SimpleFileVisitor<Path>() {
  84.439 +
  84.440 +            @Override
  84.441 +            public FileVisitResult visitFile(Path file,
  84.442 +                                            BasicFileAttributes attrs)
  84.443 +            {
  84.444 +                Path dst = srcPath.relativize(file);
  84.445 +                dst = dstPath.resolve(dst);
  84.446 +                try {
  84.447 +                    Path parent = dstPath.getParent();
  84.448 +                    if (parent != null && parent.notExists())
  84.449 +                        mkdirs(parent);
  84.450 +                    file.moveTo(dst);
  84.451 +                } catch (IOException x) {
  84.452 +                    x.printStackTrace();
  84.453 +                }
  84.454 +                return FileVisitResult.CONTINUE;
  84.455 +            }
  84.456 +
  84.457 +            @Override
  84.458 +            public FileVisitResult preVisitDirectory(Path dir,
  84.459 +                                                     BasicFileAttributes attrs)
  84.460 +            {
  84.461 +                Path dst = srcPath.relativize(dir);
  84.462 +                dst = dstPath.resolve(dst);
  84.463 +                try {
  84.464 +
  84.465 +                    if (dst.notExists())
  84.466 +                        mkdirs(dst);
  84.467 +                } catch (IOException x) {
  84.468 +                    x.printStackTrace();
  84.469 +                }
  84.470 +                return FileVisitResult.CONTINUE;
  84.471 +            }
  84.472 +
  84.473 +            @Override
  84.474 +            public FileVisitResult postVisitDirectory(Path dir,
  84.475 +                                                      IOException ioe)
  84.476 +                throws IOException
  84.477 +            {
  84.478 +                try {
  84.479 +                    dir.delete();
  84.480 +                } catch (IOException x) {
  84.481 +                    //x.printStackTrace();
  84.482 +                }
  84.483 +                return FileVisitResult.CONTINUE;
  84.484 +            }
  84.485 +        });
  84.486 +
  84.487 +    }
  84.488 +
  84.489 +    private static void mkdirs(Path path) throws IOException {
  84.490 +        path = path.toAbsolutePath();
  84.491 +        Path parent = path.getParent();
  84.492 +        if (parent != null) {
  84.493 +            if (parent.notExists())
  84.494 +                mkdirs(parent);
  84.495 +        }
  84.496 +        path.createDirectory();
  84.497 +    }
  84.498 +
  84.499 +    private static void rmdirs(Path path) throws IOException {
  84.500 +        while (path != null && path.getNameCount() != 0) {
  84.501 +            path.delete();
  84.502 +            path = path.getParent();
  84.503 +        }
  84.504 +    }
  84.505 +
  84.506 +    private static void list(Path path, boolean verbose ) throws IOException {
  84.507 +        if (verbose)
  84.508 +            System.out.println(Attributes.readBasicFileAttributes(path).toString());
  84.509 +        else
  84.510 +            System.out.printf("  %s%n", path.toString());
  84.511 +        if (path.notExists())
  84.512 +            return;
  84.513 +        if (Attributes.readBasicFileAttributes(path).isDirectory()) {
  84.514 +            DirectoryStream<Path> ds = path.newDirectoryStream();
  84.515 +            for (Path child : ds)
  84.516 +                list(child, verbose);
  84.517 +            ds.close();
  84.518 +        }
  84.519 +    }
  84.520 +
  84.521 +    // check the content of two paths are equal
  84.522 +    private static void checkEqual(Path src, Path dst) throws IOException
  84.523 +    {
  84.524 +        //System.out.printf("checking <%s> vs <%s>...%n",
  84.525 +        //                  src.toString(), dst.toString());
  84.526 +
  84.527 +        //streams
  84.528 +        InputStream isSrc = src.newInputStream();
  84.529 +        InputStream isDst = dst.newInputStream();
  84.530 +        byte[] bufSrc = new byte[8192];
  84.531 +        byte[] bufDst = new byte[8192];
  84.532 +
  84.533 +        try {
  84.534 +            int nSrc = 0;
  84.535 +            while ((nSrc = isSrc.read(bufSrc)) != -1) {
  84.536 +                int nDst = 0;
  84.537 +                while (nDst < nSrc) {
  84.538 +                    int n = isDst.read(bufDst, nDst, nSrc - nDst);
  84.539 +                    if (n == -1) {
  84.540 +                        System.out.printf("checking <%s> vs <%s>...%n",
  84.541 +                                          src.toString(), dst.toString());
  84.542 +                        throw new RuntimeException("CHECK FAILED!");
  84.543 +                    }
  84.544 +                    nDst += n;
  84.545 +                }
  84.546 +                while (--nSrc >= 0) {
  84.547 +                    if (bufSrc[nSrc] != bufDst[nSrc]) {
  84.548 +                        System.out.printf("checking <%s> vs <%s>...%n",
  84.549 +                                          src.toString(), dst.toString());
  84.550 +                        throw new RuntimeException("CHECK FAILED!");
  84.551 +                    }
  84.552 +                    nSrc--;
  84.553 +                }
  84.554 +            }
  84.555 +        } finally {
  84.556 +            isSrc.close();
  84.557 +            isDst.close();
  84.558 +        }
  84.559 +
  84.560 +        // channels
  84.561 +        SeekableByteChannel chSrc = src.newByteChannel();
  84.562 +        SeekableByteChannel chDst = dst.newByteChannel();
  84.563 +        if (chSrc.size() != chDst.size()) {
  84.564 +            System.out.printf("src[%s].size=%d, dst[%s].size=%d%n",
  84.565 +                              chSrc.toString(), chSrc.size(),
  84.566 +                              chDst.toString(), chDst.size());
  84.567 +            throw new RuntimeException("CHECK FAILED!");
  84.568 +        }
  84.569 +        ByteBuffer bbSrc = ByteBuffer.allocate(8192);
  84.570 +        ByteBuffer bbDst = ByteBuffer.allocate(8192);
  84.571 +
  84.572 +        try {
  84.573 +            int nSrc = 0;
  84.574 +            while ((nSrc = chSrc.read(bbSrc)) != -1) {
  84.575 +                int nDst = chDst.read(bbDst);
  84.576 +                if (nSrc != nDst) {
  84.577 +                    System.out.printf("checking <%s> vs <%s>...%n",
  84.578 +                                      src.toString(), dst.toString());
  84.579 +                    throw new RuntimeException("CHECK FAILED!");
  84.580 +                }
  84.581 +                while (--nSrc >= 0) {
  84.582 +                    if (bbSrc.get(nSrc) != bbDst.get(nSrc)) {
  84.583 +                        System.out.printf("checking <%s> vs <%s>...%n",
  84.584 +                                          src.toString(), dst.toString());
  84.585 +                        throw new RuntimeException("CHECK FAILED!");
  84.586 +                    }
  84.587 +                    nSrc--;
  84.588 +                }
  84.589 +                bbSrc.flip();
  84.590 +                bbDst.flip();
  84.591 +            }
  84.592 +        } catch (IOException x) {
  84.593 +            x.printStackTrace();
  84.594 +        } finally {
  84.595 +            chSrc.close();
  84.596 +            chDst.close();
  84.597 +        }
  84.598 +    }
  84.599 +
  84.600 +    private static void fchCopy(Path src, Path dst) throws IOException
  84.601 +    {
  84.602 +        Set<OpenOption> read = new HashSet<>();
  84.603 +        read.add(READ);
  84.604 +        Set<OpenOption> openwrite = new HashSet<>();
  84.605 +        openwrite.add(CREATE_NEW);
  84.606 +        openwrite.add(WRITE);
  84.607 +
  84.608 +        FileChannel srcFc = src.getFileSystem()
  84.609 +                               .provider()
  84.610 +                               .newFileChannel(src, read);
  84.611 +        FileChannel dstFc = dst.getFileSystem()
  84.612 +                               .provider()
  84.613 +                               .newFileChannel(dst, openwrite);
  84.614 +
  84.615 +        try {
  84.616 +            ByteBuffer bb = ByteBuffer.allocate(8192);
  84.617 +            while (srcFc.read(bb) >= 0) {
  84.618 +                bb.flip();
  84.619 +                dstFc.write(bb);
  84.620 +                bb.clear();
  84.621 +            }
  84.622 +        } finally {
  84.623 +            srcFc.close();
  84.624 +            dstFc.close();
  84.625 +        }
  84.626 +    }
  84.627 +
  84.628 +    private static void chCopy(Path src, Path dst) throws IOException
  84.629 +    {
  84.630 +        Set<OpenOption> read = new HashSet<>();
  84.631 +        read.add(READ);
  84.632 +        Set<OpenOption> openwrite = new HashSet<>();
  84.633 +        openwrite.add(CREATE_NEW);
  84.634 +        openwrite.add(WRITE);
  84.635 +
  84.636 +        SeekableByteChannel srcCh = src.newByteChannel(read);
  84.637 +        SeekableByteChannel dstCh = dst.newByteChannel(openwrite);
  84.638 +
  84.639 +        try {
  84.640 +            ByteBuffer bb = ByteBuffer.allocate(8192);
  84.641 +            while (srcCh.read(bb) >= 0) {
  84.642 +                bb.flip();
  84.643 +                dstCh.write(bb);
  84.644 +                bb.clear();
  84.645 +            }
  84.646 +        } finally {
  84.647 +            srcCh.close();
  84.648 +            dstCh.close();
  84.649 +        }
  84.650 +    }
  84.651 +
  84.652 +    private static void streamCopy(Path src, Path dst) throws IOException
  84.653 +    {
  84.654 +        InputStream isSrc = src.newInputStream();
  84.655 +        OutputStream osDst = dst.newOutputStream();
  84.656 +        byte[] buf = new byte[8192];
  84.657 +        try {
  84.658 +            int n = 0;
  84.659 +            while ((n = isSrc.read(buf)) != -1) {
  84.660 +                osDst.write(buf, 0, n);
  84.661 +            }
  84.662 +        } finally {
  84.663 +            isSrc.close();
  84.664 +            osDst.close();
  84.665 +        }
  84.666 +    }
  84.667 +}
    85.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    85.2 +++ b/src/share/demo/nio/zipfs/META-INF/services/java.nio.file.spi.FileSystemProvider	Tue Oct 12 12:51:48 2010 -0700
    85.3 @@ -0,0 +1,3 @@
    85.4 +com.sun.nio.zipfs.ZipFileSystemProvider
    85.5 +com.sun.nio.zipfs.JarFileSystemProvider
    85.6 +
    86.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    86.2 +++ b/src/share/demo/nio/zipfs/README.txt	Tue Oct 12 12:51:48 2010 -0700
    86.3 @@ -0,0 +1,29 @@
    86.4 +ZipFileSystem is a file system provider that treats the contents of a zip or
    86.5 +JAR file as a java.nio.file.FileSystem.
    86.6 +
    86.7 +To deploy the provider you must copy zipfs.jar into your extensions
    86.8 +directory or else add <JDK_HOME>/demo/nio/ZipFileSystem/zipfs.jar
    86.9 +to your class path.
   86.10 +
   86.11 +The factory methods defined by the java.nio.file.FileSystems class can be
   86.12 +used to create a FileSystem, eg:
   86.13 +
   86.14 +   // use file type detection
   86.15 +   Map<String,?> env = Collections.emptyMap();
   86.16 +   Path jarfile = Path.get("foo.jar");
   86.17 +   FileSystem fs = FileSystems.newFileSystem(jarfile, env);
   86.18 +
   86.19 +-or
   86.20 +
   86.21 +   // locate file system by URI
   86.22 +   Map<String,?> env = Collections.emptyMap();
   86.23 +   URI uri = URI.create("zip:///mydir/foo.jar");
   86.24 +   FileSystem fs = FileSystems.newFileSystem(uri, env);
   86.25 +
   86.26 +Once a FileSystem is created then classes in the java.nio.file package
   86.27 +can be used to access files in the zip/JAR file, eg:
   86.28 +
   86.29 +   Path mf = fs.getPath("/META-INF/MANIFEST.MF");
   86.30 +   InputStream in = mf.newInputStream();
   86.31 +
   86.32 +
    87.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    87.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/JarFileSystemProvider.java	Tue Oct 12 12:51:48 2010 -0700
    87.3 @@ -0,0 +1,71 @@
    87.4 +/*
    87.5 + * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
    87.6 + *
    87.7 + * Redistribution and use in source and binary forms, with or without
    87.8 + * modification, are permitted provided that the following conditions
    87.9 + * are met:
   87.10 + *
   87.11 + *   - Redistributions of source code must retain the above copyright
   87.12 + *     notice, this list of conditions and the following disclaimer.
   87.13 + *
   87.14 + *   - Redistributions in binary form must reproduce the above copyright
   87.15 + *     notice, this list of conditions and the following disclaimer in the
   87.16 + *     documentation and/or other materials provided with the distribution.
   87.17 + *
   87.18 + *   - Neither the name of Sun Microsystems nor the names of its
   87.19 + *     contributors may be used to endorse or promote products derived
   87.20 + *     from this software without specific prior written permission.
   87.21 + *
   87.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
   87.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   87.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   87.25 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   87.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   87.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   87.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   87.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   87.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   87.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   87.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   87.33 + */
   87.34 +package com.sun.nio.zipfs;
   87.35 +
   87.36 +import java.nio.file.*;
   87.37 +import java.nio.file.spi.*;
   87.38 +import java.nio.file.attribute.*;
   87.39 +import java.nio.file.spi.FileSystemProvider;
   87.40 +
   87.41 +import java.net.URI;
   87.42 +import java.io.IOException;
   87.43 +import java.net.URISyntaxException;
   87.44 +import java.nio.channels.FileChannel;
   87.45 +import java.util.HashMap;
   87.46 +import java.util.Map;
   87.47 +import java.util.Set;
   87.48 +
   87.49 +public class JarFileSystemProvider extends ZipFileSystemProvider
   87.50 +{
   87.51 +
   87.52 +    @Override
   87.53 +    public String getScheme() {
   87.54 +        return "jar";
   87.55 +    }
   87.56 +
   87.57 +    @Override
   87.58 +    protected Path uriToPath(URI uri) {
   87.59 +        String scheme = uri.getScheme();
   87.60 +        if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) {
   87.61 +            throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'");
   87.62 +        }
   87.63 +        try {
   87.64 +            String uristr = uri.toString();
   87.65 +            int end = uristr.indexOf("!/");
   87.66 +            uristr = uristr.substring(4, (end == -1) ? uristr.length() : end);
   87.67 +            uri = new URI(uristr);
   87.68 +            return Paths.get(new URI("file", uri.getHost(), uri.getPath(), null))
   87.69 +                        .toAbsolutePath();
   87.70 +        } catch (URISyntaxException e) {
   87.71 +            throw new AssertionError(e); //never thrown
   87.72 +        }
   87.73 +    }
   87.74 +}
    88.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    88.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipCoder.java	Tue Oct 12 12:51:48 2010 -0700
    88.3 @@ -0,0 +1,160 @@
    88.4 +/*
    88.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
    88.6 + *
    88.7 + * Redistribution and use in source and binary forms, with or without
    88.8 + * modification, are permitted provided that the following conditions
    88.9 + * are met:
   88.10 + *
   88.11 + *   - Redistributions of source code must retain the above copyright
   88.12 + *     notice, this list of conditions and the following disclaimer.
   88.13 + *
   88.14 + *   - Redistributions in binary form must reproduce the above copyright
   88.15 + *     notice, this list of conditions and the following disclaimer in the
   88.16 + *     documentation and/or other materials provided with the distribution.
   88.17 + *
   88.18 + *   - Neither the name of Oracle nor the names of its
   88.19 + *     contributors may be used to endorse or promote products derived
   88.20 + *     from this software without specific prior written permission.
   88.21 + *
   88.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
   88.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   88.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   88.25 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   88.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   88.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   88.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   88.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   88.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   88.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   88.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   88.33 + */
   88.34 +
   88.35 +package com.sun.nio.zipfs;
   88.36 +
   88.37 +import java.nio.ByteBuffer;
   88.38 +import java.nio.CharBuffer;
   88.39 +import java.nio.charset.Charset;
   88.40 +import java.nio.charset.CharsetDecoder;
   88.41 +import java.nio.charset.CharsetEncoder;
   88.42 +import java.nio.charset.CoderResult;
   88.43 +import java.nio.charset.CodingErrorAction;
   88.44 +import java.util.Arrays;
   88.45 +
   88.46 +/**
   88.47 + * Utility class for zipfile name and comment decoding and encoding
   88.48 + *
   88.49 + * @author  Xueming Shen
   88.50 + */
   88.51 +
   88.52 +final class ZipCoder {
   88.53 +
   88.54 +    String toString(byte[] ba, int length) {
   88.55 +        CharsetDecoder cd = decoder().reset();
   88.56 +        int len = (int)(length * cd.maxCharsPerByte());
   88.57 +        char[] ca = new char[len];
   88.58 +        if (len == 0)
   88.59 +            return new String(ca);
   88.60 +        ByteBuffer bb = ByteBuffer.wrap(ba, 0, length);
   88.61 +        CharBuffer cb = CharBuffer.wrap(ca);
   88.62 +        CoderResult cr = cd.decode(bb, cb, true);
   88.63 +        if (!cr.isUnderflow())
   88.64 +            throw new IllegalArgumentException(cr.toString());
   88.65 +        cr = cd.flush(cb);
   88.66 +        if (!cr.isUnderflow())
   88.67 +            throw new IllegalArgumentException(cr.toString());
   88.68 +        return new String(ca, 0, cb.position());
   88.69 +    }
   88.70 +
   88.71 +    String toString(byte[] ba) {
   88.72 +        return toString(ba, ba.length);
   88.73 +    }
   88.74 +
   88.75 +    byte[] getBytes(String s) {
   88.76 +        CharsetEncoder ce = encoder().reset();
   88.77 +        char[] ca = s.toCharArray();
   88.78 +        int len = (int)(ca.length * ce.maxBytesPerChar());
   88.79 +        byte[] ba = new byte[len];
   88.80 +        if (len == 0)
   88.81 +            return ba;
   88.82 +        ByteBuffer bb = ByteBuffer.wrap(ba);
   88.83 +        CharBuffer cb = CharBuffer.wrap(ca);
   88.84 +        CoderResult cr = ce.encode(cb, bb, true);
   88.85 +        if (!cr.isUnderflow())
   88.86 +            throw new IllegalArgumentException(cr.toString());
   88.87 +        cr = ce.flush(bb);
   88.88 +        if (!cr.isUnderflow())
   88.89 +            throw new IllegalArgumentException(cr.toString());
   88.90 +        if (bb.position() == ba.length)  // defensive copy?
   88.91 +            return ba;
   88.92 +        else
   88.93 +            return Arrays.copyOf(ba, bb.position());
   88.94 +    }
   88.95 +
   88.96 +    // assume invoked only if "this" is not utf8
   88.97 +    byte[] getBytesUTF8(String s) {
   88.98 +        if (isutf8)
   88.99 +            return getBytes(s);
  88.100 +        if (utf8 == null)
  88.101 +            utf8 = new ZipCoder(Charset.forName("UTF-8"));
  88.102 +        return utf8.getBytes(s);
  88.103 +    }
  88.104 +
  88.105 +    String toStringUTF8(byte[] ba, int len) {
  88.106 +        if (isutf8)
  88.107 +            return toString(ba, len);
  88.108 +        if (utf8 == null)
  88.109 +            utf8 = new ZipCoder(Charset.forName("UTF-8"));
  88.110 +        return utf8.toString(ba, len);
  88.111 +    }
  88.112 +
  88.113 +    boolean isUTF8() {
  88.114 +        return isutf8;
  88.115 +    }
  88.116 +
  88.117 +    private Charset cs;
  88.118 +    private boolean isutf8;
  88.119 +    private ZipCoder utf8;
  88.120 +
  88.121 +    private ZipCoder(Charset cs) {
  88.122 +        this.cs = cs;
  88.123 +        this.isutf8 = cs.name().equals("UTF-8");
  88.124 +    }
  88.125 +
  88.126 +    static ZipCoder get(Charset charset) {
  88.127 +        return new ZipCoder(charset);
  88.128 +    }
  88.129 +
  88.130 +    static ZipCoder get(String csn) {
  88.131 +        try {
  88.132 +            return new ZipCoder(Charset.forName(csn));
  88.133 +        } catch (Throwable t) {
  88.134 +            t.printStackTrace();
  88.135 +        }
  88.136 +        return new ZipCoder(Charset.defaultCharset());
  88.137 +    }
  88.138 +
  88.139 +    private final ThreadLocal<CharsetDecoder> decTL = new ThreadLocal<>();
  88.140 +    private final ThreadLocal<CharsetEncoder> encTL = new ThreadLocal<>();
  88.141 +
  88.142 +    private CharsetDecoder decoder() {
  88.143 +        CharsetDecoder dec = decTL.get();
  88.144 +        if (dec == null) {
  88.145 +            dec = cs.newDecoder()
  88.146 +              .onMalformedInput(CodingErrorAction.REPORT)
  88.147 +              .onUnmappableCharacter(CodingErrorAction.REPORT);
  88.148 +            decTL.set(dec);
  88.149 +        }
  88.150 +        return dec;
  88.151 +    }
  88.152 +
  88.153 +    private CharsetEncoder encoder() {
  88.154 +        CharsetEncoder enc = encTL.get();
  88.155 +        if (enc == null) {
  88.156 +            enc = cs.newEncoder()
  88.157 +              .onMalformedInput(CodingErrorAction.REPORT)
  88.158 +              .onUnmappableCharacter(CodingErrorAction.REPORT);
  88.159 +            encTL.set(enc);
  88.160 +        }
  88.161 +        return enc;
  88.162 +    }
  88.163 +}
    89.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    89.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipConstants.java	Tue Oct 12 12:51:48 2010 -0700
    89.3 @@ -0,0 +1,261 @@
    89.4 +/*
    89.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
    89.6 + *
    89.7 + * Redistribution and use in source and binary forms, with or without
    89.8 + * modification, are permitted provided that the following conditions
    89.9 + * are met:
   89.10 + *
   89.11 + *   - Redistributions of source code must retain the above copyright
   89.12 + *     notice, this list of conditions and the following disclaimer.
   89.13 + *
   89.14 + *   - Redistributions in binary form must reproduce the above copyright
   89.15 + *     notice, this list of conditions and the following disclaimer in the
   89.16 + *     documentation and/or other materials provided with the distribution.
   89.17 + *
   89.18 + *   - Neither the name of Oracle nor the names of its
   89.19 + *     contributors may be used to endorse or promote products derived
   89.20 + *     from this software without specific prior written permission.
   89.21 + *
   89.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
   89.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   89.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   89.25 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   89.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   89.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   89.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   89.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   89.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   89.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   89.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   89.33 + */
   89.34 +
   89.35 +package com.sun.nio.zipfs;
   89.36 +
   89.37 +import java.nio.ByteBuffer;
   89.38 +
   89.39 +/**
   89.40 + *
   89.41 + * @author Xueming Shen
   89.42 + */
   89.43 +
   89.44 +class ZipConstants {
   89.45 +    /*
   89.46 +     * Compression methods
   89.47 +     */
   89.48 +    static final int METHOD_STORED     = 0;
   89.49 +    static final int METHOD_DEFLATED   = 8;
   89.50 +    static final int METHOD_DEFLATED64 = 9;
   89.51 +    static final int METHOD_BZIP2      = 12;
   89.52 +    static final int METHOD_LZMA       = 14;
   89.53 +    static final int METHOD_LZ77       = 19;
   89.54 +
   89.55 +    /*
   89.56 +     * General purpose big flag
   89.57 +     */
   89.58 +    static final int FLAG_ENCRYPTED  = 0x01;
   89.59 +    static final int FLAG_DATADESCR  = 0x08;    // crc, size and csize in dd
   89.60 +    static final int FLAG_EFS        = 0x800;   // If this bit is set the filename and
   89.61 +                                                // comment fields for this file must be
   89.62 +                                                // encoded using UTF-8.
   89.63 +    /*
   89.64 +     * Header signatures
   89.65 +     */
   89.66 +    static long LOCSIG = 0x04034b50L;   // "PK\003\004"
   89.67 +    static long EXTSIG = 0x08074b50L;   // "PK\007\008"
   89.68 +    static long CENSIG = 0x02014b50L;   // "PK\001\002"
   89.69 +    static long ENDSIG = 0x06054b50L;   // "PK\005\006"
   89.70 +
   89.71 +    /*
   89.72 +     * Header sizes in bytes (including signatures)
   89.73 +     */
   89.74 +    static final int LOCHDR = 30;       // LOC header size
   89.75 +    static final int EXTHDR = 16;       // EXT header size
   89.76 +    static final int CENHDR = 46;       // CEN header size
   89.77 +    static final int ENDHDR = 22;       // END header size
   89.78 +
   89.79 +    /*
   89.80 +     * Local file (LOC) header field offsets
   89.81 +     */
   89.82 +    static final int LOCVER = 4;        // version needed to extract
   89.83 +    static final int LOCFLG = 6;        // general purpose bit flag
   89.84 +    static final int LOCHOW = 8;        // compression method
   89.85 +    static final int LOCTIM = 10;       // modification time
   89.86 +    static final int LOCCRC = 14;       // uncompressed file crc-32 value
   89.87 +    static final int LOCSIZ = 18;       // compressed size
   89.88 +    static final int LOCLEN = 22;       // uncompressed size
   89.89 +    static final int LOCNAM = 26;       // filename length
   89.90 +    static final int LOCEXT = 28;       // extra field length
   89.91 +
   89.92 +    /*
   89.93 +     * Extra local (EXT) header field offsets
   89.94 +     */
   89.95 +    static final int EXTCRC = 4;        // uncompressed file crc-32 value
   89.96 +    static final int EXTSIZ = 8;        // compressed size
   89.97 +    static final int EXTLEN = 12;       // uncompressed size
   89.98 +
   89.99 +    /*
  89.100 +     * Central directory (CEN) header field offsets
  89.101 +     */
  89.102 +    static final int CENVEM = 4;        // version made by
  89.103 +    static final int CENVER = 6;        // version needed to extract
  89.104 +    static final int CENFLG = 8;        // encrypt, decrypt flags
  89.105 +    static final int CENHOW = 10;       // compression method
  89.106 +    static final int CENTIM = 12;       // modification time
  89.107 +    static final int CENCRC = 16;       // uncompressed file crc-32 value
  89.108 +    static final int CENSIZ = 20;       // compressed size
  89.109 +    static final int CENLEN = 24;       // uncompressed size
  89.110 +    static final int CENNAM = 28;       // filename length
  89.111 +    static final int CENEXT = 30;       // extra field length
  89.112 +    static final int CENCOM = 32;       // comment length
  89.113 +    static final int CENDSK = 34;       // disk number start
  89.114 +    static final int CENATT = 36;       // internal file attributes
  89.115 +    static final int CENATX = 38;       // external file attributes
  89.116 +    static final int CENOFF = 42;       // LOC header offset
  89.117 +
  89.118 +    /*
  89.119 +     * End of central directory (END) header field offsets
  89.120 +     */
  89.121 +    static final int ENDSUB = 8;        // number of entries on this disk
  89.122 +    static final int ENDTOT = 10;       // total number of entries
  89.123 +    static final int ENDSIZ = 12;       // central directory size in bytes
  89.124 +    static final int ENDOFF = 16;       // offset of first CEN header
  89.125 +    static final int ENDCOM = 20;       // zip file comment length
  89.126 +
  89.127 +    /*
  89.128 +     * ZIP64 constants
  89.129 +     */
  89.130 +    static final long ZIP64_ENDSIG = 0x06064b50L;  // "PK\006\006"
  89.131 +    static final long ZIP64_LOCSIG = 0x07064b50L;  // "PK\006\007"
  89.132 +    static final int  ZIP64_ENDHDR = 56;           // ZIP64 end header size
  89.133 +    static final int  ZIP64_LOCHDR = 20;           // ZIP64 end loc header size
  89.134 +    static final int  ZIP64_EXTHDR = 24;           // EXT header size
  89.135 +    static final int  ZIP64_EXTID  = 0x0001;       // Extra field Zip64 header ID
  89.136 +
  89.137 +    static final int  ZIP64_MINVAL32 = 0xFFFF;
  89.138 +    static final long ZIP64_MINVAL = 0xFFFFFFFFL;
  89.139 +
  89.140 +    /*
  89.141 +     * Zip64 End of central directory (END) header field offsets
  89.142 +     */
  89.143 +    static final int  ZIP64_ENDLEN = 4;       // size of zip64 end of central dir
  89.144 +    static final int  ZIP64_ENDVEM = 12;      // version made by
  89.145 +    static final int  ZIP64_ENDVER = 14;      // version needed to extract
  89.146 +    static final int  ZIP64_ENDNMD = 16;      // number of this disk
  89.147 +    static final int  ZIP64_ENDDSK = 20;      // disk number of start
  89.148 +    static final int  ZIP64_ENDTOD = 24;      // total number of entries on this disk
  89.149 +    static final int  ZIP64_ENDTOT = 32;      // total number of entries
  89.150 +    static final int  ZIP64_ENDSIZ = 40;      // central directory size in bytes
  89.151 +    static final int  ZIP64_ENDOFF = 48;      // offset of first CEN header
  89.152 +    static final int  ZIP64_ENDEXT = 56;      // zip64 extensible data sector
  89.153 +
  89.154 +    /*
  89.155 +     * Zip64 End of central directory locator field offsets
  89.156 +     */
  89.157 +    static final int  ZIP64_LOCDSK = 4;       // disk number start
  89.158 +    static final int  ZIP64_LOCOFF = 8;       // offset of zip64 end
  89.159 +    static final int  ZIP64_LOCTOT = 16;      // total number of disks
  89.160 +
  89.161 +    /*
  89.162 +     * Zip64 Extra local (EXT) header field offsets
  89.163 +     */
  89.164 +    static final int  ZIP64_EXTCRC = 4;       // uncompressed file crc-32 value
  89.165 +    static final int  ZIP64_EXTSIZ = 8;       // compressed size, 8-byte
  89.166 +    static final int  ZIP64_EXTLEN = 16;      // uncompressed size, 8-byte
  89.167 +
  89.168 +    /*
  89.169 +     * Extra field header ID
  89.170 +     */
  89.171 +    static final int  EXTID_ZIP64 = 0x0001;      // ZIP64
  89.172 +    static final int  EXTID_NTFS  = 0x000a;      // NTFS
  89.173 +    static final int  EXTID_UNIX  = 0x000d;      // UNIX
  89.174 +
  89.175 +
  89.176 +    /*
  89.177 +     * fields access methods
  89.178 +     */
  89.179 +    ///////////////////////////////////////////////////////
  89.180 +    static final int CH(byte[] b, int n) {
  89.181 +       return b[n] & 0xff;
  89.182 +    }
  89.183 +
  89.184 +    static final int SH(byte[] b, int n) {
  89.185 +        return (b[n] & 0xff) | ((b[n + 1] & 0xff) << 8);
  89.186 +    }
  89.187 +
  89.188 +    static final long LG(byte[] b, int n) {
  89.189 +        return ((SH(b, n)) | (SH(b, n + 2) << 16)) & 0xffffffffL;
  89.190 +    }
  89.191 +
  89.192 +    static final long LL(byte[] b, int n) {
  89.193 +        return (LG(b, n)) | (LG(b, n + 4) << 32);
  89.194 +    }
  89.195 +
  89.196 +    static final long GETSIG(byte[] b) {
  89.197 +        return LG(b, 0);
  89.198 +    }
  89.199 +
  89.200 +    // local file (LOC) header fields
  89.201 +    static final long LOCSIG(byte[] b) { return LG(b, 0); } // signature
  89.202 +    static final int  LOCVER(byte[] b) { return SH(b, 4); } // version needed to extract
  89.203 +    static final int  LOCFLG(byte[] b) { return SH(b, 6); } // general purpose bit flags
  89.204 +    static final int  LOCHOW(byte[] b) { return SH(b, 8); } // compression method
  89.205 +    static final long LOCTIM(byte[] b) { return LG(b, 10);} // modification time
  89.206 +    static final long LOCCRC(byte[] b) { return LG(b, 14);} // crc of uncompressed data
  89.207 +    static final long LOCSIZ(byte[] b) { return LG(b, 18);} // compressed data size
  89.208 +    static final long LOCLEN(byte[] b) { return LG(b, 22);} // uncompressed data size
  89.209 +    static final int  LOCNAM(byte[] b) { return SH(b, 26);} // filename length
  89.210 +    static final int  LOCEXT(byte[] b) { return SH(b, 28);} // extra field length
  89.211 +
  89.212 +    // extra local (EXT) header fields
  89.213 +    static final long EXTCRC(byte[] b) { return LG(b, 4);}  // crc of uncompressed data
  89.214 +    static final long EXTSIZ(byte[] b) { return LG(b, 8);}  // compressed size
  89.215 +    static final long EXTLEN(byte[] b) { return LG(b, 12);} // uncompressed size
  89.216 +
  89.217 +    // end of central directory header (END) fields
  89.218 +    static final int  ENDSUB(byte[] b) { return SH(b, 8); }  // number of entries on this disk
  89.219 +    static final int  ENDTOT(byte[] b) { return SH(b, 10);}  // total number of entries
  89.220 +    static final long ENDSIZ(byte[] b) { return LG(b, 12);}  // central directory size
  89.221 +    static final long ENDOFF(byte[] b) { return LG(b, 16);}  // central directory offset
  89.222 +    static final int  ENDCOM(byte[] b) { return SH(b, 20);}  // size of zip file comment
  89.223 +    static final int  ENDCOM(byte[] b, int off) { return SH(b, off + 20);}
  89.224 +
  89.225 +    // zip64 end of central directory recoder fields
  89.226 +    static final long ZIP64_ENDTOD(byte[] b) { return LL(b, 24);}  // total number of entries on disk
  89.227 +    static final long ZIP64_ENDTOT(byte[] b) { return LL(b, 32);}  // total number of entries
  89.228 +    static final long ZIP64_ENDSIZ(byte[] b) { return LL(b, 40);}  // central directory size
  89.229 +    static final long ZIP64_ENDOFF(byte[] b) { return LL(b, 48);}  // central directory offset
  89.230 +    static final long ZIP64_LOCOFF(byte[] b) { return LL(b, 8);}   // zip64 end offset
  89.231 +
  89.232 +    //////////////////////////////////////////
  89.233 +    static final int CH(ByteBuffer b, int pos) {
  89.234 +       return b.get(pos) & 0xff;
  89.235 +    }
  89.236 +    static final int SH(ByteBuffer b, int pos) {
  89.237 +        return b.getShort(pos) & 0xffff;
  89.238 +    }
  89.239 +    static final long LG(ByteBuffer b, int pos) {
  89.240 +        return b.getInt(pos) & 0xffffffffL;
  89.241 +    }
  89.242 +
  89.243 +    // central directory header (END) fields
  89.244 +    static final long CENSIG(ByteBuffer b, int pos) { return LG(b, pos + 0); }
  89.245 +    static final int  CENVEM(ByteBuffer b, int pos) { return SH(b, pos + 4); }
  89.246 +    static final int  CENVER(ByteBuffer b, int pos) { return SH(b, pos + 6); }
  89.247 +    static final int  CENFLG(ByteBuffer b, int pos) { return SH(b, pos + 8); }
  89.248 +    static final int  CENHOW(ByteBuffer b, int pos) { return SH(b, pos + 10);}
  89.249 +    static final long CENTIM(ByteBuffer b, int pos) { return LG(b, pos + 12);}
  89.250 +    static final long CENCRC(ByteBuffer b, int pos) { return LG(b, pos + 16);}
  89.251 +    static final long CENSIZ(ByteBuffer b, int pos) { return LG(b, pos + 20);}
  89.252 +    static final long CENLEN(ByteBuffer b, int pos) { return LG(b, pos + 24);}
  89.253 +    static final int  CENNAM(ByteBuffer b, int pos) { return SH(b, pos + 28);}
  89.254 +    static final int  CENEXT(ByteBuffer b, int pos) { return SH(b, pos + 30);}
  89.255 +    static final int  CENCOM(ByteBuffer b, int pos) { return SH(b, pos + 32);}
  89.256 +    static final int  CENDSK(ByteBuffer b, int pos) { return SH(b, pos + 34);}
  89.257 +    static final int  CENATT(ByteBuffer b, int pos) { return SH(b, pos + 36);}
  89.258 +    static final long CENATX(ByteBuffer b, int pos) { return LG(b, pos + 38);}
  89.259 +    static final long CENOFF(ByteBuffer b, int pos) { return LG(b, pos + 42);}
  89.260 +
  89.261 +    /* The END header is followed by a variable length comment of size < 64k. */
  89.262 +    static final long END_MAXLEN = 0xFFFF + ENDHDR;
  89.263 +    static final int READBLOCKSZ = 128;
  89.264 +}
    90.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    90.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipDirectoryStream.java	Tue Oct 12 12:51:48 2010 -0700
    90.3 @@ -0,0 +1,109 @@
    90.4 +/*
    90.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
    90.6 + *
    90.7 + * Redistribution and use in source and binary forms, with or without
    90.8 + * modification, are permitted provided that the following conditions
    90.9 + * are met:
   90.10 + *
   90.11 + *   - Redistributions of source code must retain the above copyright
   90.12 + *     notice, this list of conditions and the following disclaimer.
   90.13 + *
   90.14 + *   - Redistributions in binary form must reproduce the above copyright
   90.15 + *     notice, this list of conditions and the following disclaimer in the
   90.16 + *     documentation and/or other materials provided with the distribution.
   90.17 + *
   90.18 + *   - Neither the name of Oracle nor the names of its
   90.19 + *     contributors may be used to endorse or promote products derived
   90.20 + *     from this software without specific prior written permission.
   90.21 + *
   90.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
   90.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   90.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   90.25 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   90.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   90.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   90.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   90.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   90.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   90.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   90.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   90.33 + */
   90.34 +
   90.35 +package com.sun.nio.zipfs;
   90.36 +
   90.37 +import java.nio.file.DirectoryStream;
   90.38 +import java.nio.file.ClosedDirectoryStreamException;
   90.39 +import java.nio.file.NotDirectoryException;
   90.40 +import java.nio.file.Path;
   90.41 +import java.util.Iterator;
   90.42 +import java.util.NoSuchElementException;
   90.43 +import java.io.IOException;
   90.44 +import static com.sun.nio.zipfs.ZipUtils.*;
   90.45 +
   90.46 +/**
   90.47 + *
   90.48 + * @author  Xueming Shen, Rajendra Gutupalli, Jaya Hangal
   90.49 + */
   90.50 +
   90.51 +public class ZipDirectoryStream implements DirectoryStream<Path> {
   90.52 +
   90.53 +    private final ZipFileSystem zipfs;
   90.54 +    private final byte[] path;
   90.55 +    private final DirectoryStream.Filter<? super Path> filter;
   90.56 +    private volatile boolean isClosed;
   90.57 +    private volatile Iterator<Path> itr;
   90.58 +
   90.59 +    ZipDirectoryStream(ZipPath zipPath,
   90.60 +                       DirectoryStream.Filter<? super java.nio.file.Path> filter)
   90.61 +        throws IOException
   90.62 +    {
   90.63 +        this.zipfs = zipPath.getFileSystem();
   90.64 +        this.path = zipPath.getResolvedPath();
   90.65 +        this.filter = filter;
   90.66 +        // sanity check
   90.67 +        if (!zipfs.isDirectory(path))
   90.68 +            throw new NotDirectoryException(zipPath.toString());
   90.69 +    }
   90.70 +
   90.71 +    @Override
   90.72 +    public synchronized Iterator<Path> iterator() {
   90.73 +        if (isClosed)
   90.74 +            throw new ClosedDirectoryStreamException();
   90.75 +        if (itr != null)
   90.76 +            throw new IllegalStateException("Iterator has already been returned");
   90.77 +
   90.78 +        try {
   90.79 +            itr = zipfs.iteratorOf(path, filter);
   90.80 +        } catch (IOException e) {
   90.81 +            throw new IllegalStateException(e);
   90.82 +        }
   90.83 +        return new Iterator<Path>() {
   90.84 +            private Path next;
   90.85 +            @Override
   90.86 +            public boolean hasNext() {
   90.87 +                if (isClosed)
   90.88 +                    return false;
   90.89 +                return itr.hasNext();
   90.90 +            }
   90.91 +
   90.92 +            @Override
   90.93 +            public synchronized Path next() {
   90.94 +                if (isClosed)
   90.95 +                    throw new NoSuchElementException();
   90.96 +                return itr.next();
   90.97 +            }
   90.98 +
   90.99 +            @Override
  90.100 +            public void remove() {
  90.101 +                throw new UnsupportedOperationException();
  90.102 +            }
  90.103 +        };
  90.104 +    }
  90.105 +
  90.106 +    @Override
  90.107 +    public synchronized void close() throws IOException {
  90.108 +        isClosed = true;
  90.109 +    }
  90.110 +
  90.111 +
  90.112 +}
    91.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    91.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributeView.java	Tue Oct 12 12:51:48 2010 -0700
    91.3 @@ -0,0 +1,185 @@
    91.4 +/*
    91.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
    91.6 + *
    91.7 + * Redistribution and use in source and binary forms, with or without
    91.8 + * modification, are permitted provided that the following conditions
    91.9 + * are met:
   91.10 + *
   91.11 + *   - Redistributions of source code must retain the above copyright
   91.12 + *     notice, this list of conditions and the following disclaimer.
   91.13 + *
   91.14 + *   - Redistributions in binary form must reproduce the above copyright
   91.15 + *     notice, this list of conditions and the following disclaimer in the
   91.16 + *     documentation and/or other materials provided with the distribution.
   91.17 + *
   91.18 + *   - Neither the name of Oracle nor the names of its
   91.19 + *     contributors may be used to endorse or promote products derived
   91.20 + *     from this software without specific prior written permission.
   91.21 + *
   91.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
   91.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   91.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   91.25 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   91.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   91.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   91.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   91.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   91.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   91.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   91.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   91.33 + */
   91.34 +
   91.35 +
   91.36 +package com.sun.nio.zipfs;
   91.37 +
   91.38 +import java.nio.file.ReadOnlyFileSystemException;
   91.39 +import java.nio.file.attribute.BasicFileAttributeView;
   91.40 +import java.nio.file.attribute.FileAttributeView;
   91.41 +import java.nio.file.attribute.FileTime;
   91.42 +import java.io.IOException;
   91.43 +import java.util.LinkedHashMap;
   91.44 +
   91.45 +/*
   91.46 + * @author  Xueming Shen, Rajendra Gutupalli, Jaya Hangal
   91.47 + */
   91.48 +
   91.49 +public class ZipFileAttributeView implements BasicFileAttributeView
   91.50 +{
   91.51 +    private static enum AttrID {
   91.52 +        size,
   91.53 +        creationTime,
   91.54 +        lastAccessTime,
   91.55 +        lastModifiedTime,
   91.56 +        isDirectory,
   91.57 +        isRegularFile,
   91.58 +        isSymbolicLink,
   91.59 +        isOther,
   91.60 +        fileKey,
   91.61 +        compressedSize,
   91.62 +        crc,
   91.63 +        method
   91.64 +    };
   91.65 +
   91.66 +    private final ZipPath path;
   91.67 +    private final boolean isZipView;
   91.68 +
   91.69 +    private ZipFileAttributeView(ZipPath path, boolean isZipView) {
   91.70 +        this.path = path;
   91.71 +        this.isZipView = isZipView;
   91.72 +    }
   91.73 +
   91.74 +    static <V extends FileAttributeView> V get(ZipPath path, Class<V> type) {
   91.75 +        if (type == null)
   91.76 +            throw new NullPointerException();
   91.77 +        if (type == BasicFileAttributeView.class)
   91.78 +            return (V)new ZipFileAttributeView(path, false);
   91.79 +        if (type == ZipFileAttributeView.class)
   91.80 +            return (V)new ZipFileAttributeView(path, true);
   91.81 +        return null;
   91.82 +    }
   91.83 +
   91.84 +    static ZipFileAttributeView get(ZipPath path, String type) {
   91.85 +        if (type == null)
   91.86 +            throw new NullPointerException();
   91.87 +        if (type.equals("basic"))
   91.88 +            return new ZipFileAttributeView(path, false);
   91.89 +        if (type.equals("zip"))
   91.90 +            return new ZipFileAttributeView(path, true);
   91.91 +        return null;
   91.92 +    }
   91.93 +
   91.94 +    @Override
   91.95 +    public String name() {
   91.96 +        return isZipView ? "zip" : "basic";
   91.97 +    }
   91.98 +
   91.99 +    public ZipFileAttributes readAttributes() throws IOException
  91.100 +    {
  91.101 +        return path.getAttributes();
  91.102 +    }
  91.103 +
  91.104 +    @Override
  91.105 +    public void setTimes(FileTime lastModifiedTime,
  91.106 +                         FileTime lastAccessTime,
  91.107 +                         FileTime createTime)
  91.108 +        throws IOException
  91.109 +    {
  91.110 +        path.setTimes(lastModifiedTime, lastAccessTime, createTime);
  91.111 +    }
  91.112 +
  91.113 +    void setAttribute(String attribute, Object value)
  91.114 +        throws IOException
  91.115 +    {
  91.116 +        try {
  91.117 +            if (AttrID.valueOf(attribute) == AttrID.lastModifiedTime)
  91.118 +                setTimes ((FileTime)value, null, null);
  91.119 +            return;
  91.120 +        } catch (IllegalArgumentException x) {}
  91.121 +        throw new UnsupportedOperationException("'" + attribute +
  91.122 +            "' is unknown or read-only attribute");
  91.123 +    }
  91.124 +
  91.125 +    public Object getAttribute(String attribute, boolean domap)
  91.126 +        throws IOException
  91.127 +    {
  91.128 +        ZipFileAttributes zfas = readAttributes();
  91.129 +        if (!domap) {
  91.130 +            try {
  91.131 +                return attribute(AttrID.valueOf(attribute), zfas);
  91.132 +            } catch (IllegalArgumentException x) {}
  91.133 +            return null;
  91.134 +        }
  91.135 +        LinkedHashMap<String, Object> map = new LinkedHashMap<>();
  91.136 +        if ("*".equals(attribute)) {
  91.137 +            for (AttrID id : AttrID.values()) {
  91.138 +                try {
  91.139 +                    map.put(id.name(), attribute(id, zfas));
  91.140 +                } catch (IllegalArgumentException x) {}
  91.141 +            }
  91.142 +        } else {
  91.143 +            String[] as = attribute.split(",");
  91.144 +            for (String a : as) {
  91.145 +                try {
  91.146 +                    map.put(a, attribute(AttrID.valueOf(a), zfas));
  91.147 +                } catch (IllegalArgumentException x) {}
  91.148 +            }
  91.149 +        }
  91.150 +        return map;
  91.151 +    }
  91.152 +
  91.153 +    Object attribute(AttrID id, ZipFileAttributes zfas) {
  91.154 +        switch (id) {
  91.155 +        case size:
  91.156 +            return zfas.size();
  91.157 +        case creationTime:
  91.158 +            return zfas.creationTime();
  91.159 +        case lastAccessTime:
  91.160 +            return zfas.lastAccessTime();
  91.161 +        case lastModifiedTime:
  91.162 +            return zfas.lastModifiedTime();
  91.163 +        case isDirectory:
  91.164 +            return zfas.isDirectory();
  91.165 +        case isRegularFile:
  91.166 +            return zfas.isRegularFile();
  91.167 +        case isSymbolicLink:
  91.168 +            return zfas.isSymbolicLink();
  91.169 +        case isOther:
  91.170 +            return zfas.isOther();
  91.171 +        case fileKey:
  91.172 +            return zfas.fileKey();
  91.173 +        case compressedSize:
  91.174 +            if (isZipView)
  91.175 +                return zfas.compressedSize();
  91.176 +            break;
  91.177 +        case crc:
  91.178 +            if (isZipView)
  91.179 +                return zfas.crc();
  91.180 +            break;
  91.181 +        case method:
  91.182 +            if (isZipView)
  91.183 +                return zfas.method();
  91.184 +            break;
  91.185 +        }
  91.186 +        return null;
  91.187 +    }
  91.188 +}
    92.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    92.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributes.java	Tue Oct 12 12:51:48 2010 -0700
    92.3 @@ -0,0 +1,156 @@
    92.4 +/*
    92.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
    92.6 + *
    92.7 + * Redistribution and use in source and binary forms, with or without
    92.8 + * modification, are permitted provided that the following conditions
    92.9 + * are met:
   92.10 + *
   92.11 + *   - Redistributions of source code must retain the above copyright
   92.12 + *     notice, this list of conditions and the following disclaimer.
   92.13 + *
   92.14 + *   - Redistributions in binary form must reproduce the above copyright
   92.15 + *     notice, this list of conditions and the following disclaimer in the
   92.16 + *     documentation and/or other materials provided with the distribution.
   92.17 + *
   92.18 + *   - Neither the name of Oracle nor the names of its
   92.19 + *     contributors may be used to endorse or promote products derived
   92.20 + *     from this software without specific prior written permission.
   92.21 + *
   92.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
   92.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   92.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   92.25 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   92.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   92.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   92.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   92.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   92.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   92.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   92.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   92.33 + */
   92.34 +
   92.35 +
   92.36 +package com.sun.nio.zipfs;
   92.37 +
   92.38 +import java.nio.file.attribute.BasicFileAttributes;
   92.39 +import java.nio.file.attribute.FileTime;
   92.40 +import java.util.Arrays;
   92.41 +import java.util.Formatter;
   92.42 +import static com.sun.nio.zipfs.ZipUtils.*;
   92.43 +
   92.44 +/**
   92.45 + *
   92.46 + * @author  Xueming Shen, Rajendra Gutupalli,Jaya Hangal
   92.47 + */
   92.48 +
   92.49 +public class ZipFileAttributes implements BasicFileAttributes
   92.50 +
   92.51 +{
   92.52 +    private final ZipFileSystem.Entry e;
   92.53 +
   92.54 +    ZipFileAttributes(ZipFileSystem.Entry e) {
   92.55 +        this.e = e;
   92.56 +    }
   92.57 +
   92.58 +    ///////// basic attributes ///////////
   92.59 +    @Override
   92.60 +    public FileTime creationTime() {
   92.61 +        if (e.ctime != -1)
   92.62 +            return FileTime.fromMillis(dosToJavaTime(e.ctime));
   92.63 +        return null;
   92.64 +    }
   92.65 +
   92.66 +    @Override
   92.67 +    public boolean isDirectory() {
   92.68 +        return e.isDir();
   92.69 +    }
   92.70 +
   92.71 +    @Override
   92.72 +    public boolean isOther() {
   92.73 +        return false;
   92.74 +    }
   92.75 +
   92.76 +    @Override
   92.77 +    public boolean isRegularFile() {
   92.78 +        return !e.isDir();
   92.79 +    }
   92.80 +
   92.81 +    @Override
   92.82 +    public FileTime lastAccessTime() {
   92.83 +        if (e.atime != -1)
   92.84 +            return FileTime.fromMillis(dosToJavaTime(e.atime));
   92.85 +        return null;
   92.86 +    }
   92.87 +
   92.88 +    @Override
   92.89 +    public FileTime lastModifiedTime() {
   92.90 +        return FileTime.fromMillis(dosToJavaTime(e.mtime));
   92.91 +    }
   92.92 +
   92.93 +    @Override
   92.94 +    public long size() {
   92.95 +        return e.size;
   92.96 +    }
   92.97 +
   92.98 +    @Override
   92.99 +    public boolean isSymbolicLink() {
  92.100 +        return false;
  92.101 +    }
  92.102 +
  92.103 +    @Override
  92.104 +    public Object fileKey() {
  92.105 +        return null;
  92.106 +    }
  92.107 +
  92.108 +    ///////// zip entry attributes ///////////
  92.109 +    public byte[] name() {
  92.110 +        return Arrays.copyOf(e.name, e.name.length);
  92.111 +    }
  92.112 +
  92.113 +    public long compressedSize() {
  92.114 +        return e.csize;
  92.115 +    }
  92.116 +
  92.117 +    public long crc() {
  92.118 +        return e.crc;
  92.119 +    }
  92.120 +
  92.121 +    public int method() {
  92.122 +        return e.method;
  92.123 +    }
  92.124 +
  92.125 +    public byte[] extra() {
  92.126 +        if (e.extra != null)
  92.127 +            return Arrays.copyOf(e.extra, e.extra.length);
  92.128 +        return null;
  92.129 +    }
  92.130 +
  92.131 +    public byte[] comment() {
  92.132 +        if (e.comment != null)
  92.133 +            return Arrays.copyOf(e.comment, e.comment.length);
  92.134 +        return null;
  92.135 +    }
  92.136 +
  92.137 +    public String toString() {
  92.138 +        StringBuilder sb = new StringBuilder();
  92.139 +        Formatter fm = new Formatter(sb);
  92.140 +        fm.format("[/%s]%n", new String(e.name));  // TBD encoding
  92.141 +        fm.format("    creationTime    : %s%n", creationTime());
  92.142 +        if (lastAccessTime() != null)
  92.143 +            fm.format("    lastAccessTime  : %tc%n", lastAccessTime().toMillis());
  92.144 +        else
  92.145 +            fm.format("    lastAccessTime  : null%n");
  92.146 +        fm.format("    lastModifiedTime: %tc%n", lastModifiedTime().toMillis());
  92.147 +        fm.format("    isRegularFile   : %b%n", isRegularFile());
  92.148 +        fm.format("    isDirectory     : %b%n", isDirectory());
  92.149 +        fm.format("    isSymbolicLink  : %b%n", isSymbolicLink());
  92.150 +        fm.format("    isOther         : %b%n", isOther());
  92.151 +        fm.format("    fileKey         : %s%n", fileKey());
  92.152 +        fm.format("    size            : %d%n", size());
  92.153 +        fm.format("    compressedSize  : %d%n", compressedSize());
  92.154 +        fm.format("    crc             : %x%n", crc());
  92.155 +        fm.format("    method          : %d%n", method());
  92.156 +        fm.close();
  92.157 +        return sb.toString();
  92.158 +    }
  92.159 +}
    93.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    93.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileStore.java	Tue Oct 12 12:51:48 2010 -0700
    93.3 @@ -0,0 +1,157 @@
    93.4 +/*
    93.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
    93.6 + *
    93.7 + * Redistribution and use in source and binary forms, with or without
    93.8 + * modification, are permitted provided that the following conditions
    93.9 + * are met:
   93.10 + *
   93.11 + *   - Redistributions of source code must retain the above copyright
   93.12 + *     notice, this list of conditions and the following disclaimer.
   93.13 + *
   93.14 + *   - Redistributions in binary form must reproduce the above copyright
   93.15 + *     notice, this list of conditions and the following disclaimer in the
   93.16 + *     documentation and/or other materials provided with the distribution.
   93.17 + *
   93.18 + *   - Neither the name of Oracle nor the names of its
   93.19 + *     contributors may be used to endorse or promote products derived
   93.20 + *     from this software without specific prior written permission.
   93.21 + *
   93.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
   93.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   93.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   93.25 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   93.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   93.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   93.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   93.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   93.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   93.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   93.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   93.33 + */
   93.34 +
   93.35 +package com.sun.nio.zipfs;
   93.36 +
   93.37 +import java.io.IOException;
   93.38 +import java.nio.file.FileStore;
   93.39 +import java.nio.file.FileSystems;
   93.40 +import java.nio.file.Path;
   93.41 +import java.nio.file.attribute.FileAttributeView;
   93.42 +import java.nio.file.attribute.FileStoreAttributeView;
   93.43 +import java.nio.file.attribute.FileStoreSpaceAttributeView;
   93.44 +import java.nio.file.attribute.FileStoreSpaceAttributes;
   93.45 +import java.nio.file.attribute.Attributes;
   93.46 +import java.nio.file.attribute.BasicFileAttributeView;
   93.47 +import java.util.Formatter;
   93.48 +
   93.49 +/*
   93.50 + *
   93.51 + * @author  Xueming Shen, Rajendra Gutupalli, Jaya Hangal
   93.52 + */
   93.53 +
   93.54 +public class ZipFileStore extends FileStore {
   93.55 +
   93.56 +    private final ZipFileSystem zfs;
   93.57 +
   93.58 +    ZipFileStore(ZipPath zpath) {
   93.59 +        this.zfs = (ZipFileSystem)zpath.getFileSystem();
   93.60 +    }
   93.61 +
   93.62 +    @Override
   93.63 +    public String name() {
   93.64 +        return zfs.toString() + "/";
   93.65 +    }
   93.66 +
   93.67 +    @Override
   93.68 +    public String type() {
   93.69 +        return "zipfs";
   93.70 +    }
   93.71 +
   93.72 +    @Override
   93.73 +    public boolean isReadOnly() {
   93.74 +        return zfs.isReadOnly();
   93.75 +    }
   93.76 +
   93.77 +    @Override
   93.78 +    public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) {
   93.79 +        return (type == BasicFileAttributeView.class ||
   93.80 +                type == ZipFileAttributeView.class);
   93.81 +    }
   93.82 +
   93.83 +    @Override
   93.84 +    public boolean supportsFileAttributeView(String name) {
   93.85 +        return name.equals("basic") || name.equals("zip");
   93.86 +    }
   93.87 +
   93.88 +    @Override
   93.89 +    @SuppressWarnings("unchecked")
   93.90 +    public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> type) {
   93.91 +        if (type == null)
   93.92 +            throw new NullPointerException();
   93.93 +        if (type == FileStoreSpaceAttributeView.class)
   93.94 +            return (V) new ZipFileStoreAttributeView(this);
   93.95 +        return null;
   93.96 +    }
   93.97 +
   93.98 +    @Override
   93.99 +    public Object getAttribute(String attribute) throws IOException {
  93.100 +         if (attribute.equals("space:totalSpace"))
  93.101 +               return new ZipFileStoreAttributeView(this).readAttributes().totalSpace();
  93.102 +         if (attribute.equals("space:usableSpace"))
  93.103 +               return new ZipFileStoreAttributeView(this).readAttributes().usableSpace();
  93.104 +         if (attribute.equals("space:unallocatedSpace"))
  93.105 +               return new ZipFileStoreAttributeView(this).readAttributes().unallocatedSpace();
  93.106 +         throw new UnsupportedOperationException("does not support the given attribute");
  93.107 +    }
  93.108 +
  93.109 +    private static class ZipFileStoreAttributeView implements FileStoreSpaceAttributeView {
  93.110 +
  93.111 +        private final ZipFileStore fileStore;
  93.112 +
  93.113 +        public ZipFileStoreAttributeView(ZipFileStore fileStore) {
  93.114 +            this.fileStore = fileStore;
  93.115 +        }
  93.116 +
  93.117 +        @Override
  93.118 +        public String name() {
  93.119 +            return "space";
  93.120 +        }
  93.121 +
  93.122 +        @Override
  93.123 +        public FileStoreSpaceAttributes readAttributes() throws IOException {
  93.124 +            final String file = fileStore.name();
  93.125 +            Path path = FileSystems.getDefault().getPath(file);
  93.126 +            final long size = Attributes.readBasicFileAttributes(path).size();
  93.127 +            final FileStore fstore = path.getFileStore();
  93.128 +            final FileStoreSpaceAttributes fstoreAttrs =
  93.129 +                Attributes.readFileStoreSpaceAttributes(fstore);
  93.130 +            return new FileStoreSpaceAttributes() {
  93.131 +                public long totalSpace() {
  93.132 +                    return size;
  93.133 +                }
  93.134 +
  93.135 +                public long usableSpace() {
  93.136 +                    if (!fstore.isReadOnly())
  93.137 +                        return fstoreAttrs.usableSpace();
  93.138 +                    return 0;
  93.139 +                }
  93.140 +
  93.141 +                public long unallocatedSpace() {
  93.142 +                    if (!fstore.isReadOnly())
  93.143 +                        return fstoreAttrs.unallocatedSpace();
  93.144 +                    return 0;
  93.145 +                }
  93.146 +
  93.147 +                public String toString() {
  93.148 +                    StringBuilder sb = new StringBuilder();
  93.149 +                    Formatter fm = new Formatter(sb);
  93.150 +                    fm.format("FileStoreSpaceAttributes[%s]%n", file);
  93.151 +                    fm.format("      totalSpace: %d%n", totalSpace());
  93.152 +                    fm.format("     usableSpace: %d%n", usableSpace());
  93.153 +                    fm.format("    unallocSpace: %d%n", unallocatedSpace());
  93.154 +                    fm.close();
  93.155 +                    return sb.toString();
  93.156 +                }
  93.157 +            };
  93.158 +        }
  93.159 +    }
  93.160 +}
    94.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    94.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystem.java	Tue Oct 12 12:51:48 2010 -0700
    94.3 @@ -0,0 +1,2257 @@
    94.4 +/*
    94.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
    94.6 + *
    94.7 + * Redistribution and use in source and binary forms, with or without
    94.8 + * modification, are permitted provided that the following conditions
    94.9 + * are met:
   94.10 + *
   94.11 + *   - Redistributions of source code must retain the above copyright
   94.12 + *     notice, this list of conditions and the following disclaimer.
   94.13 + *
   94.14 + *   - Redistributions in binary form must reproduce the above copyright
   94.15 + *     notice, this list of conditions and the following disclaimer in the
   94.16 + *     documentation and/or other materials provided with the distribution.
   94.17 + *
   94.18 + *   - Neither the name of Oracle nor the names of its
   94.19 + *     contributors may be used to endorse or promote products derived
   94.20 + *     from this software without specific prior written permission.
   94.21 + *
   94.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
   94.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   94.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   94.25 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   94.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   94.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   94.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   94.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   94.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   94.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   94.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   94.33 + */
   94.34 +
   94.35 +package com.sun.nio.zipfs;
   94.36 +
   94.37 +import java.io.ByteArrayInputStream;
   94.38 +import java.io.ByteArrayOutputStream;
   94.39 +import java.io.EOFException;
   94.40 +import java.io.File;
   94.41 +import java.io.FileInputStream;
   94.42 +import java.io.IOException;
   94.43 +import java.io.InputStream;
   94.44 +import java.io.OutputStream;
   94.45 +import java.nio.ByteBuffer;
   94.46 +import java.nio.ByteOrder;
   94.47 +import java.nio.MappedByteBuffer;
   94.48 +import java.nio.channels.*;
   94.49 +import java.nio.file.*;
   94.50 +import java.nio.file.attribute.*;
   94.51 +import java.nio.file.spi.*;
   94.52 +import java.net.URI;
   94.53 +import java.util.*;
   94.54 +import java.util.regex.Pattern;
   94.55 +import java.util.zip.CRC32;
   94.56 +import java.util.zip.Inflater;
   94.57 +import java.util.zip.Deflater;
   94.58 +import java.util.zip.InflaterInputStream;
   94.59 +import java.util.zip.DeflaterOutputStream;
   94.60 +import java.util.zip.ZipException;
   94.61 +import java.util.zip.ZipError;
   94.62 +import static java.lang.Boolean.*;
   94.63 +import static com.sun.nio.zipfs.ZipConstants.*;
   94.64 +import static com.sun.nio.zipfs.ZipUtils.*;
   94.65 +import static java.nio.file.StandardOpenOption.*;
   94.66 +import static java.nio.file.StandardCopyOption.*;
   94.67 +
   94.68 +/**
   94.69 + * A FileSystem built on a zip file
   94.70 + *
   94.71 + * @author Xueming Shen
   94.72 + */
   94.73 +
   94.74 +public class ZipFileSystem extends FileSystem {
   94.75 +
   94.76 +    private final ZipFileSystemProvider provider;
   94.77 +    private final ZipPath defaultdir;
   94.78 +    private boolean readOnly = false;
   94.79 +    private final Path zfpath;
   94.80 +    private final ZipCoder zc;
   94.81 +
   94.82 +    private final Object lock = new Object();
   94.83 +
   94.84 +    // configurable by env map
   94.85 +    private final String  defaultDir;    // default dir for the file system
   94.86 +    private final String  nameEncoding;  // default encoding for name/comment
   94.87 +    private final boolean buildDirTree;  // build a dir tree for directoryStream ops
   94.88 +    private final boolean useTempFile;   // use a temp file for newOS, default
   94.89 +                                         // is to use BAOS for better performance
   94.90 +    private final boolean createNew;     // create a new zip if not exists
   94.91 +
   94.92 +    ZipFileSystem(ZipFileSystemProvider provider,
   94.93 +                  Path zfpath,
   94.94 +                  Map<String, ?> env)
   94.95 +        throws IOException
   94.96 +    {
   94.97 +        // configurable env setup
   94.98 +        this.buildDirTree = TRUE.equals(env.get("buildDirTree"));
   94.99 +        this.useTempFile = TRUE.equals(env.get("useTempFile"));
  94.100 +        this.createNew = TRUE.equals(env.get("createNew"));
  94.101 +        this.nameEncoding = env.containsKey("nameEncoding") ?
  94.102 +                            (String)env.get("nameEncoding") : "UTF-8";
  94.103 +        this.defaultDir = env.containsKey("default.dir") ?
  94.104 +                          (String)env.get("default.dir") : "/";
  94.105 +        if (this.defaultDir.charAt(0) != '/')
  94.106 +            throw new IllegalArgumentException("default dir should be absolute");
  94.107 +
  94.108 +        this.provider = provider;
  94.109 +        this.zfpath = zfpath;
  94.110 +        if (zfpath.notExists()) {
  94.111 +            if (createNew) {
  94.112 +                OutputStream os = zfpath.newOutputStream(CREATE_NEW, WRITE);
  94.113 +                new END().write(os, 0);
  94.114 +                os.close();
  94.115 +            } else {
  94.116 +                throw new FileSystemNotFoundException(zfpath.toString());
  94.117 +            }
  94.118 +        }
  94.119 +        zfpath.checkAccess(AccessMode.READ); // sm and existence check
  94.120 +        try {
  94.121 +            zfpath.checkAccess(AccessMode.WRITE);
  94.122 +        } catch (AccessDeniedException x) {
  94.123 +            this.readOnly = true;
  94.124 +        }
  94.125 +        this.zc = ZipCoder.get(nameEncoding);
  94.126 +        this.defaultdir = new ZipPath(this, getBytes(defaultDir));
  94.127 +        initZipFile();
  94.128 +    }
  94.129 +
  94.130 +    @Override
  94.131 +    public FileSystemProvider provider() {
  94.132 +        return provider;
  94.133 +    }
  94.134 +
  94.135 +    @Override
  94.136 +    public String getSeparator() {
  94.137 +        return "/";
  94.138 +    }
  94.139 +
  94.140 +    @Override
  94.141 +    public boolean isOpen() {
  94.142 +        return isOpen;
  94.143 +    }
  94.144 +
  94.145 +    @Override
  94.146 +    public boolean isReadOnly() {
  94.147 +        return readOnly;
  94.148 +    }
  94.149 +
  94.150 +    private void checkWritable() throws IOException {
  94.151 +        if (readOnly)
  94.152 +            throw new ReadOnlyFileSystemException();
  94.153 +    }
  94.154 +
  94.155 +    @Override
  94.156 +    public Iterable<Path> getRootDirectories() {
  94.157 +        ArrayList<Path> pathArr = new ArrayList<>();
  94.158 +        pathArr.add(new ZipPath(this, new byte[]{'/'}));
  94.159 +        return pathArr;
  94.160 +    }
  94.161 +
  94.162 +    ZipPath getDefaultDir() {  // package private
  94.163 +        return defaultdir;
  94.164 +    }
  94.165 +
  94.166 +    @Override
  94.167 +    public ZipPath getPath(String path) {
  94.168 +        if (path.length() == 0)
  94.169 +            throw new InvalidPathException(path, "path should not be empty");
  94.170 +        return new ZipPath(this, getBytes(path));
  94.171 +    }
  94.172 +
  94.173 +    @Override
  94.174 +    public UserPrincipalLookupService getUserPrincipalLookupService() {
  94.175 +        throw new UnsupportedOperationException();
  94.176 +    }
  94.177 +
  94.178 +    @Override
  94.179 +    public WatchService newWatchService() {
  94.180 +        throw new UnsupportedOperationException();
  94.181 +    }
  94.182 +
  94.183 +    FileStore getFileStore(ZipPath path) {
  94.184 +        return new ZipFileStore(path);
  94.185 +    }
  94.186 +
  94.187 +    @Override
  94.188 +    public Iterable<FileStore> getFileStores() {
  94.189 +        ArrayList<FileStore> list = new ArrayList<FileStore>(1);
  94.190 +        list.add(new ZipFileStore(new ZipPath(this, new byte[]{'/'})));
  94.191 +        return list;
  94.192 +    }
  94.193 +
  94.194 +    private static final Set<String> supportedFileAttributeViews =
  94.195 +            Collections.unmodifiableSet(
  94.196 +                new HashSet<String>(Arrays.asList("basic", "zip")));
  94.197 +
  94.198 +    @Override
  94.199 +    public Set<String> supportedFileAttributeViews() {
  94.200 +        return supportedFileAttributeViews;
  94.201 +    }
  94.202 +
  94.203 +    @Override
  94.204 +    public String toString() {
  94.205 +        return zfpath.toString();
  94.206 +    }
  94.207 +
  94.208 +    Path getZipFile() {
  94.209 +        return zfpath;
  94.210 +    }
  94.211 +
  94.212 +    private static final String GLOB_SYNTAX = "glob";
  94.213 +    private static final String REGEX_SYNTAX = "regex";
  94.214 +
  94.215 +    @Override
  94.216 +    public PathMatcher getPathMatcher(String syntaxAndInput) {
  94.217 +        int pos = syntaxAndInput.indexOf(':');
  94.218 +        if (pos <= 0 || pos == syntaxAndInput.length()) {
  94.219 +            throw new IllegalArgumentException();
  94.220 +        }
  94.221 +        String syntax = syntaxAndInput.substring(0, pos);
  94.222 +        String input = syntaxAndInput.substring(pos + 1);
  94.223 +        String expr;
  94.224 +        if (syntax.equals(GLOB_SYNTAX)) {
  94.225 +            expr = toRegexPattern(input);
  94.226 +        } else {
  94.227 +            if (syntax.equals(REGEX_SYNTAX)) {
  94.228 +                expr = input;
  94.229 +            } else {
  94.230 +                throw new UnsupportedOperationException("Syntax '" + syntax +
  94.231 +                    "' not recognized");
  94.232 +            }
  94.233 +        }
  94.234 +        // return matcher
  94.235 +        final Pattern pattern = Pattern.compile(expr);
  94.236 +        return new PathMatcher() {
  94.237 +            @Override
  94.238 +            public boolean matches(Path path) {
  94.239 +                return pattern.matcher(path.toString()).matches();
  94.240 +            }
  94.241 +        };
  94.242 +    }
  94.243 +
  94.244 +    @Override
  94.245 +    public void close() throws IOException {
  94.246 +        synchronized (lock) {
  94.247 +            if (!isOpen)
  94.248 +                return;
  94.249 +            isOpen = false;
  94.250 +            if (!streams.isEmpty()) {
  94.251 +                synchronized(streams) {
  94.252 +                    for (InputStream is: streams)
  94.253 +                    is.close();
  94.254 +                }
  94.255 +            }
  94.256 +            sync();
  94.257 +            ch.close();
  94.258 +        }
  94.259 +        synchronized (inflaters) {
  94.260 +            for (Inflater inf : inflaters)
  94.261 +                inf.end();
  94.262 +        }
  94.263 +        synchronized (deflaters) {
  94.264 +            for (Deflater def : deflaters)
  94.265 +                def.end();
  94.266 +        }
  94.267 +        for (Path p: tmppaths) {
  94.268 +            try {
  94.269 +                p.deleteIfExists();
  94.270 +            } catch (IOException x) {
  94.271 +                x.printStackTrace();
  94.272 +            }
  94.273 +        }
  94.274 +        provider.removeFileSystem(zfpath);
  94.275 +    }
  94.276 +
  94.277 +    ZipFileAttributes[] getAllAttributes() throws IOException {
  94.278 +        ensureOpen();
  94.279 +        int n = inodes.size();
  94.280 +        ZipFileAttributes[] zes = new ZipFileAttributes[n];
  94.281 +        Iterator<IndexNode> itr = inodes.values().iterator();
  94.282 +        int i = 0;
  94.283 +        while(itr.hasNext()) {
  94.284 +            zes[i++] = new ZipFileAttributes(Entry.readCEN(cen, itr.next().pos));
  94.285 +        }
  94.286 +        return zes;
  94.287 +    }
  94.288 +
  94.289 +    EntryName[] getEntryNames() throws IOException {
  94.290 +        ensureOpen();
  94.291 +        return inodes.keySet().toArray(new EntryName[0]);
  94.292 +    }
  94.293 +
  94.294 +    ZipFileAttributes getFileAttributes(byte[] path)
  94.295 +        throws IOException
  94.296 +    {
  94.297 +        synchronized (lock) {
  94.298 +            Entry e = getEntry0(path);
  94.299 +            if (e == null) {
  94.300 +                if (path.length == 0) {
  94.301 +                    e = new Entry(new byte[0]);  // root
  94.302 +                } else if (buildDirTree) {
  94.303 +                    IndexNode inode = getDirs().get(new EntryName(path));
  94.304 +                    if (inode == null)
  94.305 +                        return null;
  94.306 +                    e = new Entry(inode.name);
  94.307 +                } else {
  94.308 +                    return null;
  94.309 +                }
  94.310 +                e.method = METHOD_STORED;        // STORED for dir
  94.311 +                BasicFileAttributes bfas = Attributes.readBasicFileAttributes(zfpath);
  94.312 +                if (bfas.lastModifiedTime() != null)
  94.313 +                    e.mtime = javaToDosTime(bfas.lastModifiedTime().toMillis());
  94.314 +                if (bfas.lastAccessTime() != null)
  94.315 +                    e.atime = javaToDosTime(bfas.lastAccessTime().toMillis());
  94.316 +                if (bfas.creationTime() != null)
  94.317 +                    e.ctime = javaToDosTime(bfas.creationTime().toMillis());
  94.318 +            }
  94.319 +            return new ZipFileAttributes(e);
  94.320 +        }
  94.321 +    }
  94.322 +
  94.323 +    void setTimes(byte[] path, FileTime mtime, FileTime atime, FileTime ctime)
  94.324 +        throws IOException
  94.325 +    {
  94.326 +        checkWritable();
  94.327 +        synchronized (lock) {
  94.328 +            Entry e = getEntry0(path);    // ensureOpen checked
  94.329 +            if (e == null)
  94.330 +                throw new NoSuchFileException(getString(path));
  94.331 +            if (e.type == Entry.CEN)
  94.332 +                e.type = Entry.COPY;      // copy e
  94.333 +            if (mtime != null)
  94.334 +                e.mtime = javaToDosTime(mtime.toMillis());
  94.335 +            if (atime != null)
  94.336 +                e.atime = javaToDosTime(atime.toMillis());
  94.337 +            if (ctime != null)
  94.338 +                e.ctime = javaToDosTime(ctime.toMillis());
  94.339 +            update(e);
  94.340 +        }
  94.341 +    }
  94.342 +
  94.343 +    boolean exists(byte[] path)
  94.344 +        throws IOException
  94.345 +    {
  94.346 +        return getEntry0(path) != null;
  94.347 +    }
  94.348 +
  94.349 +    boolean isDirectory(byte[] path)
  94.350 +        throws IOException
  94.351 +    {
  94.352 +        synchronized (lock) {
  94.353 +            if (buildDirTree) {
  94.354 +                return getDirs().containsKey(new EntryName(path));
  94.355 +            }
  94.356 +            Entry e = getEntry0(path);
  94.357 +            return (e != null && e.isDir()) || path.length == 0;
  94.358 +        }
  94.359 +    }
  94.360 +
  94.361 +    private ZipPath toZipPath(byte[] path) {
  94.362 +        // make it absolute
  94.363 +        byte[] p = new byte[path.length + 1];
  94.364 +        p[0] = '/';
  94.365 +        System.arraycopy(path, 0, p, 1, path.length);
  94.366 +        return new ZipPath(this, p);
  94.367 +    }
  94.368 +
  94.369 +    // returns the list of child paths of "path"
  94.370 +    Iterator<Path> iteratorOf(byte[] path,
  94.371 +                              DirectoryStream.Filter<? super Path> filter)
  94.372 +        throws IOException
  94.373 +    {
  94.374 +        synchronized (lock) {
  94.375 +            if (buildDirTree) {
  94.376 +                IndexNode inode = getDirs().get(new EntryName(path));
  94.377 +                if (inode == null)
  94.378 +                    throw new NotDirectoryException(getString(path));
  94.379 +                List<Path> list = new ArrayList<Path>();
  94.380 +                IndexNode child = inode.child;
  94.381 +                while (child != null) {
  94.382 +                    ZipPath zp = toZipPath(child.name);
  94.383 +                    if (filter == null || filter.accept(zp))
  94.384 +                        list.add(zp);
  94.385 +                    child = child.sibling;
  94.386 +                }
  94.387 +                return list.iterator();
  94.388 +            }
  94.389 +
  94.390 +            if (!isDirectory(path))
  94.391 +                throw new NotDirectoryException(getString(path));
  94.392 +            List<Path> list = new ArrayList<Path>();
  94.393 +            EntryName[] entries = getEntryNames();
  94.394 +            path = toDirectoryPath(path);
  94.395 +            for (EntryName en :entries) {
  94.396 +                if (!isParentOf(path, en.name))  // is "path" the parent of "name"
  94.397 +                    continue;
  94.398 +                int off = path.length;
  94.399 +                while (off < en.name.length) {
  94.400 +                    if (en.name[off] == '/')
  94.401 +                        break;
  94.402 +                    off++;
  94.403 +                }
  94.404 +                if (off < (en.name.length - 1))
  94.405 +                    continue;
  94.406 +                ZipPath zp = toZipPath(en.name);
  94.407 +                if (filter == null || filter.accept(zp))
  94.408 +                    list.add(zp);
  94.409 +            }
  94.410 +            return list.iterator();
  94.411 +        }
  94.412 +    }
  94.413 +
  94.414 +    void createDirectory(byte[] dir, FileAttribute<?>... attrs)
  94.415 +        throws IOException
  94.416 +    {
  94.417 +        checkWritable();
  94.418 +        dir = toDirectoryPath(dir);
  94.419 +        synchronized (lock) {
  94.420 +            ensureOpen();
  94.421 +            // pseudo root dir, or exiting dir
  94.422 +            if (dir.length == 0 || exists(dir))
  94.423 +                throw new FileAlreadyExistsException(getString(dir));
  94.424 +            checkParents(dir);
  94.425 +
  94.426 +            Entry e = new Entry(dir, Entry.NEW);
  94.427 +            e.method = METHOD_STORED;  // STORED for dir
  94.428 +            update(e);
  94.429 +        }
  94.430 +    }
  94.431 +
  94.432 +    void copyFile(boolean deletesrc, byte[]src, byte[] dst, CopyOption... options)
  94.433 +        throws IOException
  94.434 +    {
  94.435 +        checkWritable();
  94.436 +        if (Arrays.equals(src, dst))
  94.437 +            return;    // do nothing, src and dst are the same
  94.438 +        synchronized (lock) {
  94.439 +            Entry eSrc = getEntry0(src);  // ensureOpen checked
  94.440 +            if (eSrc == null)
  94.441 +                throw new NoSuchFileException(getString(src));
  94.442 +            if (eSrc.isDir()) {    // spec says to create dst dir
  94.443 +                createDirectory(dst);
  94.444 +                return;
  94.445 +            }
  94.446 +            boolean hasReplace = false;
  94.447 +            boolean hasCopyAttrs = false;
  94.448 +            for (CopyOption opt : options) {
  94.449 +                if (opt == REPLACE_EXISTING)
  94.450 +                    hasReplace = true;
  94.451 +                else if (opt == COPY_ATTRIBUTES)
  94.452 +                    hasCopyAttrs = true;
  94.453 +            }
  94.454 +            Entry eDst = getEntry0(dst);
  94.455 +            if (eDst != null) {
  94.456 +                if (!hasReplace)
  94.457 +                    throw new FileAlreadyExistsException(getString(dst));
  94.458 +            } else {
  94.459 +                checkParents(dst);
  94.460 +            }
  94.461 +            Entry u = new Entry(eSrc, Entry.COPY);    // copy eSrc entry
  94.462 +            u.name = dst;                             // change name
  94.463 +            // don't touch the "nlen and elen" here. writeLOC() always
  94.464 +            // re-calculate from "name" and "extra" for the correct length,
  94.465 +            // copyLOCEntry however needs the original lengths to skip the
  94.466 +            // loc header.
  94.467 +            // u.nlen = dst.length;
  94.468 +            if (eSrc.type == Entry.NEW || eSrc.type == Entry.FILECH)
  94.469 +            {
  94.470 +                u.type = eSrc.type;    // make it the same type
  94.471 +                if (!deletesrc) {      // if it's not "rename", just take the data
  94.472 +                    if (eSrc.bytes != null)
  94.473 +                        u.bytes = Arrays.copyOf(eSrc.bytes, eSrc.bytes.length);
  94.474 +                    else if (eSrc.file != null) {
  94.475 +                        u.file = getTempPathForEntry(null);
  94.476 +                        eSrc.file.copyTo(u.file, REPLACE_EXISTING);
  94.477 +                    }
  94.478 +                }
  94.479 +            }
  94.480 +            if (!hasCopyAttrs)
  94.481 +                u.mtime = u.atime= u.ctime = javaToDosTime(System.currentTimeMillis());
  94.482 +            update(u);
  94.483 +            if (deletesrc)
  94.484 +                updateDelete(eSrc);
  94.485 +        }
  94.486 +    }
  94.487 +
  94.488 +    // Returns an output stream for writing the contents into the specified
  94.489 +    // entry.
  94.490 +    OutputStream newOutputStream(byte[] path, OpenOption... options)
  94.491 +        throws IOException
  94.492 +    {
  94.493 +        checkWritable();
  94.494 +        boolean hasCreateNew = false;
  94.495 +        boolean hasCreate = false;
  94.496 +        boolean hasAppend = false;
  94.497 +        for (OpenOption opt: options) {
  94.498 +            if (opt == READ)
  94.499 +                throw new IllegalArgumentException("READ not allowed");
  94.500 +            if (opt == CREATE_NEW)
  94.501 +                hasCreateNew = true;
  94.502 +            if (opt == CREATE)
  94.503 +                hasCreate = true;
  94.504 +            if (opt == APPEND)
  94.505 +                hasAppend = true;
  94.506 +        }
  94.507 +        synchronized (lock) {
  94.508 +            Entry e = getEntry0(path);
  94.509 +            if (e != null) {
  94.510 +                if (e.isDir() || hasCreateNew)
  94.511 +                    throw new FileAlreadyExistsException(getString(path));
  94.512 +                if (hasAppend) {
  94.513 +                    InputStream is = getInputStream(e);
  94.514 +                    OutputStream os = getOutputStream(new Entry(e, Entry.NEW));
  94.515 +                    copyStream(is, os);
  94.516 +                    is.close();
  94.517 +                    return os;
  94.518 +                 }
  94.519 +                 return getOutputStream(new Entry(e, Entry.NEW));
  94.520 +            } else {
  94.521 +                if (!hasCreate && !hasCreateNew)
  94.522 +                    throw new NoSuchFileException(getString(path));
  94.523 +                checkParents(path);
  94.524 +                return getOutputStream(new Entry(path, Entry.NEW));
  94.525 +            }
  94.526 +        }
  94.527 +    }
  94.528 +
  94.529 +    // Returns an input stream for reading the contents of the specified
  94.530 +    // file entry.
  94.531 +    InputStream newInputStream(byte[] path) throws IOException {
  94.532 +        synchronized (lock) {
  94.533 +            Entry e = getEntry0(path);
  94.534 +            if (e == null)
  94.535 +                throw new NoSuchFileException(getString(path));
  94.536 +            if (e.isDir())
  94.537 +                throw new FileSystemException(getString(path), "is a directory", null);
  94.538 +            return getInputStream(e);
  94.539 +        }
  94.540 +    }
  94.541 +
  94.542 +    private void checkOptions(Set<? extends OpenOption> options) {
  94.543 +        // check for options of null type and option is an intance of StandardOpenOption
  94.544 +        for (OpenOption option : options) {
  94.545 +            if (option == null)
  94.546 +                throw new NullPointerException();
  94.547 +            if (!(option instanceof StandardOpenOption))
  94.548 +                throw new IllegalArgumentException();
  94.549 +        }
  94.550 +    }
  94.551 +
  94.552 +    // Returns a Writable/ReadByteChannel for now. Might consdier to use
  94.553 +    // newFileChannel() instead, which dump the entry data into a regular
  94.554 +    // file on the default file system and create a FileChannel on top of
  94.555 +    // it.
  94.556 +    SeekableByteChannel newByteChannel(byte[] path,
  94.557 +                                       Set<? extends OpenOption> options,
  94.558 +                                       FileAttribute<?>... attrs)
  94.559 +        throws IOException
  94.560 +    {
  94.561 +        checkOptions(options);
  94.562 +        if (options.contains(StandardOpenOption.WRITE) ||
  94.563 +            options.contains(StandardOpenOption.APPEND)) {
  94.564 +            checkWritable();
  94.565 +            final WritableByteChannel wbc = Channels.newChannel(newOutputStream(path,
  94.566 +                                                options.toArray(new OpenOption[0])));
  94.567 +            long leftover = 0;;
  94.568 +            if (options.contains(StandardOpenOption.APPEND)) {
  94.569 +                Entry e = getEntry0(path);
  94.570 +                if (e != null && e.size >= 0)
  94.571 +                    leftover = e.size;
  94.572 +            }
  94.573 +            final long offset = leftover;
  94.574 +            return new SeekableByteChannel() {
  94.575 +                long written = offset;
  94.576 +                public boolean isOpen() {
  94.577 +                    return wbc.isOpen();
  94.578 +                }
  94.579 +                public long position() throws IOException {
  94.580 +                    return written;
  94.581 +                }
  94.582 +                public SeekableByteChannel position(long pos) throws IOException {
  94.583 +                    throw new UnsupportedOperationException();
  94.584 +                }
  94.585 +                public int read(ByteBuffer dst) throws IOException {
  94.586 +                    throw new UnsupportedOperationException();
  94.587 +                }
  94.588 +                public SeekableByteChannel truncate(long size) throws IOException {
  94.589 +                    throw new UnsupportedOperationException();
  94.590 +                }
  94.591 +                public int write(ByteBuffer src) throws IOException {
  94.592 +                    int n = wbc.write(src);
  94.593 +                    written += n;
  94.594 +                    return n;
  94.595 +                }
  94.596 +                public long size() throws IOException {
  94.597 +                    return written;
  94.598 +                }
  94.599 +                public void close() throws IOException {
  94.600 +                    wbc.close();
  94.601 +                }
  94.602 +            };
  94.603 +        } else {
  94.604 +            Entry e = getEntry0(path);
  94.605 +            if (e == null || e.isDir())
  94.606 +                throw new NoSuchFileException(getString(path));
  94.607 +            final ReadableByteChannel rbc =
  94.608 +                Channels.newChannel(getInputStream(e));
  94.609 +            final long size = e.size;
  94.610 +            return new SeekableByteChannel() {
  94.611 +                long read = 0;
  94.612 +                public boolean isOpen() {
  94.613 +                    return rbc.isOpen();
  94.614 +                }
  94.615 +                public long position() throws IOException {
  94.616 +                    return read;
  94.617 +                }
  94.618 +                public SeekableByteChannel position(long pos) throws IOException {
  94.619 +                    throw new UnsupportedOperationException();
  94.620 +                }
  94.621 +                public int read(ByteBuffer dst) throws IOException {
  94.622 +                    return rbc.read(dst);
  94.623 +                }
  94.624 +                public SeekableByteChannel truncate(long size) throws IOException {
  94.625 +                    throw new NonWritableChannelException();
  94.626 +                }
  94.627 +                public int write (ByteBuffer src) throws IOException {
  94.628 +                    throw new NonWritableChannelException();
  94.629 +                }
  94.630 +                public long size() throws IOException {
  94.631 +                    return size;
  94.632 +                }
  94.633 +                public void close() throws IOException {
  94.634 +                    rbc.close();
  94.635 +                }
  94.636 +            };
  94.637 +        }
  94.638 +    }
  94.639 +
  94.640 +    // Returns a FileChannel of the specified entry.
  94.641 +    //
  94.642 +    // This implementation creates a temporary file on the default file system,
  94.643 +    // copy the entry data into it if the entry exists, and then create a
  94.644 +    // FileChannel on top of it.
  94.645 +    FileChannel newFileChannel(byte[] path,
  94.646 +                               Set<? extends OpenOption> options,
  94.647 +                               FileAttribute<?>... attrs)
  94.648 +        throws IOException
  94.649 +    {
  94.650 +        checkOptions(options);
  94.651 +        final  boolean forWrite = (options.contains(StandardOpenOption.WRITE) ||
  94.652 +                                   options.contains(StandardOpenOption.APPEND));
  94.653 +        Entry e = getEntry0(path);
  94.654 +        if (forWrite) {
  94.655 +            checkWritable();
  94.656 +            if (e == null) {
  94.657 +                if (!options.contains(StandardOpenOption.CREATE_NEW))
  94.658 +                    throw new NoSuchFileException(getString(path));
  94.659 +            } else {
  94.660 +                if (options.contains(StandardOpenOption.CREATE_NEW))
  94.661 +                    throw new FileAlreadyExistsException(getString(path));
  94.662 +                if (e.isDir())
  94.663 +                    throw new FileAlreadyExistsException("directory <"
  94.664 +                        + getString(path) + "> exists");
  94.665 +            }
  94.666 +            options.remove(StandardOpenOption.CREATE_NEW); // for tmpfile
  94.667 +        } else if (e == null || e.isDir()) {
  94.668 +            throw new NoSuchFileException(getString(path));
  94.669 +        }
  94.670 +
  94.671 +        final boolean isFCH = (e != null && e.type == Entry.FILECH);
  94.672 +        final Path tmpfile = isFCH ? e.file : getTempPathForEntry(path);
  94.673 +        final FileChannel fch = tmpfile.getFileSystem()
  94.674 +                                       .provider()
  94.675 +                                       .newFileChannel(tmpfile, options, attrs);
  94.676 +        final Entry u = isFCH ? e : new Entry(path, tmpfile, Entry.FILECH);
  94.677 +        if (forWrite) {
  94.678 +            u.flag = FLAG_DATADESCR;
  94.679 +            u.method = METHOD_DEFLATED;
  94.680 +        }
  94.681 +        // is there a better way to hook into the FileChannel's close method?
  94.682 +        return new FileChannel() {
  94.683 +            public int write(ByteBuffer src) throws IOException {
  94.684 +                return fch.write(src);
  94.685 +            }
  94.686 +            public long write(ByteBuffer[] srcs, int offset, int length)
  94.687 +                throws IOException
  94.688 +            {
  94.689 +                return fch.write(srcs, offset, length);
  94.690 +            }
  94.691 +            public long position() throws IOException {
  94.692 +                return fch.position();
  94.693 +            }
  94.694 +            public FileChannel position(long newPosition)
  94.695 +                throws IOException
  94.696 +            {
  94.697 +                fch.position(newPosition);
  94.698 +                return this;
  94.699 +            }
  94.700 +            public long size() throws IOException {
  94.701 +                return fch.size();
  94.702 +            }
  94.703 +            public FileChannel truncate(long size)
  94.704 +                throws IOException
  94.705 +            {
  94.706 +                fch.truncate(size);
  94.707 +                return this;
  94.708 +            }
  94.709 +            public void force(boolean metaData)
  94.710 +                throws IOException
  94.711 +            {
  94.712 +                fch.force(metaData);
  94.713 +            }
  94.714 +            public long transferTo(long position, long count,
  94.715 +                                   WritableByteChannel target)
  94.716 +                throws IOException
  94.717 +            {
  94.718 +                return fch.transferTo(position, count, target);
  94.719 +            }
  94.720 +            public long transferFrom(ReadableByteChannel src,
  94.721 +                                     long position, long count)
  94.722 +                throws IOException
  94.723 +            {
  94.724 +                return fch.transferFrom(src, position, count);
  94.725 +            }
  94.726 +            public int read(ByteBuffer dst) throws IOException {
  94.727 +                return fch.read(dst);
  94.728 +            }
  94.729 +            public int read(ByteBuffer dst, long position)
  94.730 +                throws IOException
  94.731 +            {
  94.732 +                return fch.read(dst, position);
  94.733 +            }
  94.734 +            public long read(ByteBuffer[] dsts, int offset, int length)
  94.735 +                throws IOException
  94.736 +            {
  94.737 +                return fch.read(dsts, offset, length);
  94.738 +            }
  94.739 +            public int write(ByteBuffer src, long position)
  94.740 +                throws IOException
  94.741 +            {
  94.742 +               return fch.write(src, position);
  94.743 +            }
  94.744 +            public MappedByteBuffer map(MapMode mode,
  94.745 +                                        long position, long size)
  94.746 +                throws IOException
  94.747 +            {
  94.748 +                throw new UnsupportedOperationException();
  94.749 +            }
  94.750 +            public FileLock lock(long position, long size, boolean shared)
  94.751 +                throws IOException
  94.752 +            {
  94.753 +                return fch.lock(position, size, shared);
  94.754 +            }
  94.755 +            public FileLock tryLock(long position, long size, boolean shared)
  94.756 +                throws IOException
  94.757 +            {
  94.758 +                return fch.tryLock(position, size, shared);
  94.759 +            }
  94.760 +            protected void implCloseChannel() throws IOException {
  94.761 +                fch.close();
  94.762 +                if (forWrite) {
  94.763 +                    u.mtime = javaToDosTime(System.currentTimeMillis());
  94.764 +                    u.size = Attributes.readBasicFileAttributes(u.file).size();
  94.765 +                    update(u);
  94.766 +                } else {
  94.767 +                    if (!isFCH)    // if this is a new fch for reading
  94.768 +                        removeTempPathForEntry(tmpfile);
  94.769 +                }
  94.770 +            }
  94.771 +        };
  94.772 +    }
  94.773 +
  94.774 +    // the outstanding input streams that need to be closed
  94.775 +    private Set<InputStream> streams =
  94.776 +        Collections.synchronizedSet(new HashSet<InputStream>());
  94.777 +
  94.778 +    // the ex-channel and ex-path that need to close when their outstanding
  94.779 +    // input streams are all closed by the obtainers.
  94.780 +    private Set<ExChannelCloser> exChClosers = new HashSet<>();
  94.781 +
  94.782 +    private Set<Path> tmppaths = new HashSet<>();
  94.783 +    private Path getTempPathForEntry(byte[] path) throws IOException {
  94.784 +        Path tmpPath = createTempFileInSameDirectoryAs(zfpath);
  94.785 +        tmppaths.add(tmpPath);
  94.786 +
  94.787 +        if (path != null) {
  94.788 +            Entry e = getEntry0(path);
  94.789 +            if (e != null) {
  94.790 +                InputStream is = newInputStream(path);
  94.791 +                OutputStream os = tmpPath.newOutputStream(WRITE);
  94.792 +                try {
  94.793 +                    copyStream(is, os);
  94.794 +                } finally {
  94.795 +                    is.close();
  94.796 +                    os.close();
  94.797 +                }
  94.798 +            }
  94.799 +        }
  94.800 +        return tmpPath;
  94.801 +    }
  94.802 +
  94.803 +    private void removeTempPathForEntry(Path path) throws IOException {
  94.804 +        path.delete();
  94.805 +        tmppaths.remove(path);
  94.806 +    }
  94.807 +
  94.808 +    // check if all parents really exit. ZIP spec does not require
  94.809 +    // the existence of any "parent directory".
  94.810 +    private void checkParents(byte[] path) throws IOException {
  94.811 +        while ((path = getParent(path)) != null) {
  94.812 +            if (!inodes.containsKey(new EntryName(path)))
  94.813 +                throw new NoSuchFileException(getString(path));
  94.814 +        }
  94.815 +    }
  94.816 +
  94.817 +    private static byte[] getParent(byte[] path) {
  94.818 +        int off = path.length - 1;
  94.819 +        if (off > 0 && path[off] == '/')  // isDirectory
  94.820 +            off--;
  94.821 +        while (off > 0 && path[off] != '/') { off--; }
  94.822 +        if (off == 0)
  94.823 +            return null;                  // top entry
  94.824 +        return Arrays.copyOf(path, off + 1);
  94.825 +    }
  94.826 +
  94.827 +    // If "starter" is the parent directory of "path"
  94.828 +    private static boolean isParentOf(byte[] p, byte[] c) {
  94.829 +        final int plen = p.length;
  94.830 +        if (plen == 0)          // root dir
  94.831 +            return true;
  94.832 +        if (plen  >= c.length)
  94.833 +            return false;
  94.834 +        int n = 0;
  94.835 +        while (n < plen) {
  94.836 +            if (p[n] != c[n])
  94.837 +                return false;
  94.838 +            n++;
  94.839 +        }
  94.840 +        if (p[n - 1] != '/' && (c[n] != '/' || n == c.length - 1))
  94.841 +            return false;
  94.842 +        return true;
  94.843 +    }
  94.844 +
  94.845 +    ///////////////////////////////////////////////////////////////////
  94.846 +    private void initZipFile() throws IOException {
  94.847 +        ch = zfpath.newByteChannel(READ);
  94.848 +        initCEN();
  94.849 +    }
  94.850 +
  94.851 +    private volatile boolean isOpen = true;
  94.852 +    private SeekableByteChannel ch; // channel to the zipfile
  94.853 +    ByteBuffer cen;        // CEN & ENDHDR
  94.854 +    private END  end;
  94.855 +    private long locpos;   // position of first LOC header (usually 0)
  94.856 +
  94.857 +    // name -> pos (in cen), package private for ZipInfo
  94.858 +    LinkedHashMap<EntryName, IndexNode> inodes;
  94.859 +
  94.860 +    byte[] getBytes(String name) {
  94.861 +        return zc.getBytes(name);
  94.862 +    }
  94.863 +    String getString(byte[] name) {
  94.864 +        return zc.toString(name);
  94.865 +    }
  94.866 +
  94.867 +    protected void finalize() throws IOException {
  94.868 +        close();
  94.869 +    }
  94.870 +
  94.871 +    private long getDataPos(Entry e) throws IOException {
  94.872 +        if (e.locoff == -1) {
  94.873 +            Entry e2 = getEntry0(e.name);
  94.874 +            if (e2 == null)
  94.875 +                throw new ZipException("invalid loc for entry <" + e.name + ">");
  94.876 +            e.locoff = e2.locoff;
  94.877 +        }
  94.878 +        byte[] buf = new byte[LOCHDR];
  94.879 +        if (readFullyAt(buf, 0, buf.length, e.locoff) != buf.length)
  94.880 +            throw new ZipException("invalid loc for entry <" + e.name + ">");
  94.881 +        return locpos + e.locoff + LOCHDR + LOCNAM(buf) + LOCEXT(buf);
  94.882 +    }
  94.883 +
  94.884 +    // Reads len bytes of data from the specified offset into buf.
  94.885 +    // Returns the total number of bytes read.
  94.886 +    // Each/every byte read from here (except the cen, which is mapped).
  94.887 +    private long readFullyAt(byte[] buf, int off, long len, long pos)
  94.888 +        throws IOException
  94.889 +    {
  94.890 +        ByteBuffer bb = ByteBuffer.wrap(buf);
  94.891 +        bb.position(off);
  94.892 +        bb.limit((int)(off + len));
  94.893 +        return readFullyAt(bb, pos);
  94.894 +    }
  94.895 +
  94.896 +    private long readFullyAt(ByteBuffer bb, long pos)
  94.897 +        throws IOException
  94.898 +    {
  94.899 +        synchronized(ch) {
  94.900 +            return ch.position(pos).read(bb);
  94.901 +        }
  94.902 +    }
  94.903 +
  94.904 +    // Searches for end of central directory (END) header. The contents of
  94.905 +    // the END header will be read and placed in endbuf. Returns the file
  94.906 +    // position of the END header, otherwise returns -1 if the END header
  94.907 +    // was not found or an error occurred.
  94.908 +    private END findEND() throws IOException
  94.909 +    {
  94.910 +        byte[] buf = new byte[READBLOCKSZ];
  94.911 +        long ziplen = ch.size();
  94.912 +        long minHDR = (ziplen - END_MAXLEN) > 0 ? ziplen - END_MAXLEN : 0;
  94.913 +        long minPos = minHDR - (buf.length - ENDHDR);
  94.914 +
  94.915 +        for (long pos = ziplen - buf.length; pos >= minPos; pos -= (buf.length - ENDHDR))
  94.916 +        {
  94.917 +            int off = 0;
  94.918 +            if (pos < 0) {
  94.919 +                // Pretend there are some NUL bytes before start of file
  94.920 +                off = (int)-pos;
  94.921 +                Arrays.fill(buf, 0, off, (byte)0);
  94.922 +            }
  94.923 +            int len = buf.length - off;
  94.924 +            if (readFullyAt(buf, off, len, pos + off) != len)
  94.925 +                zerror("zip END header not found");
  94.926 +
  94.927 +            // Now scan the block backwards for END header signature
  94.928 +            for (int i = buf.length - ENDHDR; i >= 0; i--) {
  94.929 +                if (buf[i+0] == (byte)'P'    &&
  94.930 +                    buf[i+1] == (byte)'K'    &&
  94.931 +                    buf[i+2] == (byte)'\005' &&
  94.932 +                    buf[i+3] == (byte)'\006' &&
  94.933 +                    (pos + i + ENDHDR + ENDCOM(buf, i) == ziplen)) {
  94.934 +                    // Found END header
  94.935 +                    buf = Arrays.copyOfRange(buf, i, i + ENDHDR);
  94.936 +                    END end = new END();
  94.937 +                    end.endsub = ENDSUB(buf);
  94.938 +                    end.centot = ENDTOT(buf);
  94.939 +                    end.cenlen = ENDSIZ(buf);
  94.940 +                    end.cenoff = ENDOFF(buf);
  94.941 +                    end.comlen = ENDCOM(buf);
  94.942 +                    end.endpos = pos + i;
  94.943 +                    if (end.cenlen == ZIP64_MINVAL ||
  94.944 +                        end.cenoff == ZIP64_MINVAL ||
  94.945 +                        end.centot == ZIP64_MINVAL32)
  94.946 +                    {
  94.947 +                        // need to find the zip64 end;
  94.948 +                        byte[] loc64 = new byte[ZIP64_LOCHDR];
  94.949 +                        if (readFullyAt(loc64, 0, loc64.length, end.endpos - ZIP64_LOCHDR)
  94.950 +                            != loc64.length) {
  94.951 +                            return end;
  94.952 +                        }
  94.953 +                        long end64pos = ZIP64_LOCOFF(loc64);
  94.954 +                        byte[] end64buf = new byte[ZIP64_ENDHDR];
  94.955 +                        if (readFullyAt(end64buf, 0, end64buf.length, end64pos)
  94.956 +                            != end64buf.length) {
  94.957 +                            return end;
  94.958 +                        }
  94.959 +                        // end64 found, re-calcualte everything.
  94.960 +                        end.cenlen = ZIP64_ENDSIZ(end64buf);
  94.961 +                        end.cenoff = ZIP64_ENDOFF(end64buf);
  94.962 +                        end.centot = (int)ZIP64_ENDTOT(end64buf); // assume total < 2g
  94.963 +                        end.endpos = end64pos;
  94.964 +                    }
  94.965 +                    return end;
  94.966 +                }
  94.967 +            }
  94.968 +        }
  94.969 +        zerror("zip END header not found");
  94.970 +        return null; //make compiler happy
  94.971 +    }
  94.972 +
  94.973 +    // Reads zip file central directory. Returns the file position of first
  94.974 +    // CEN header, otherwise returns -1 if an error occured. If zip->msg != NULL
  94.975 +    // then the error was a zip format error and zip->msg has the error text.
  94.976 +    // Always pass in -1 for knownTotal; it's used for a recursive call.
  94.977 +    private long initCEN() throws IOException {
  94.978 +        end = findEND();
  94.979 +        if (end.endpos == 0) {
  94.980 +            inodes = new LinkedHashMap<EntryName, IndexNode>(10);
  94.981 +            locpos = 0;
  94.982 +            return 0;         // only END header present
  94.983 +        }
  94.984 +        if (end.cenlen > end.endpos)
  94.985 +            zerror("invalid END header (bad central directory size)");
  94.986 +        long cenpos = end.endpos - end.cenlen;     // position of CEN table
  94.987 +
  94.988 +        // Get position of first local file (LOC) header, taking into
  94.989 +        // account that there may be a stub prefixed to the zip file.
  94.990 +        locpos = cenpos - end.cenoff;
  94.991 +        if (locpos < 0)
  94.992 +            zerror("invalid END header (bad central directory offset)");
  94.993 +
  94.994 +        // read in the CEN and END
  94.995 +        cen = ByteBuffer.allocate((int)(end.cenlen + ENDHDR));
  94.996 +        if (readFullyAt(cen, cenpos) != end.cenlen + ENDHDR) {
  94.997 +            zerror("read CEN tables failed");
  94.998 +        }
  94.999 +        cen.order(ByteOrder.LITTLE_ENDIAN).flip();
 94.1000 +
 94.1001 +        // Iterate through the entries in the central directory
 94.1002 +        inodes = new LinkedHashMap<EntryName, IndexNode>(end.centot + 1);
 94.1003 +        int pos = 0;
 94.1004 +        int limit = cen.remaining() - ENDHDR;
 94.1005 +        int i = 0;
 94.1006 +        byte[] bBuf = new byte[1024];
 94.1007 +        while (pos < limit) {
 94.1008 +            if (CENSIG(cen, pos) != CENSIG)
 94.1009 +                zerror("invalid CEN header (bad signature)");
 94.1010 +            int method = CENHOW(cen, pos);
 94.1011 +            int nlen   = CENNAM(cen, pos);
 94.1012 +            int elen   = CENEXT(cen, pos);
 94.1013 +            int clen   = CENCOM(cen, pos);
 94.1014 +            if ((CENFLG(cen, pos) & 1) != 0)
 94.1015 +                zerror("invalid CEN header (encrypted entry)");
 94.1016 +            if (method != METHOD_STORED && method != METHOD_DEFLATED)
 94.1017 +                zerror("invalid CEN header (bad compression method: " + method + ")");
 94.1018 +            if (pos + CENHDR + nlen > limit)
 94.1019 +                zerror("invalid CEN header (bad header size)");
 94.1020 +            if (bBuf.length < nlen)
 94.1021 +                 bBuf = new byte[nlen];
 94.1022 +            cen.position(pos + CENHDR);
 94.1023 +            byte[] name = new byte[nlen];
 94.1024 +            cen.get(name);
 94.1025 +            inodes.put(new EntryName(name), new IndexNode(name, pos));
 94.1026 +            // skip ext and comment
 94.1027 +            cen.position(pos += (CENHDR + nlen + elen + clen));
 94.1028 +            i++;
 94.1029 +        }
 94.1030 +        if (cen.remaining() != ENDHDR) {
 94.1031 +            zerror("invalid CEN header (bad header size)");
 94.1032 +        }
 94.1033 +        dirs = null;  // clear the dir map
 94.1034 +        return cenpos;
 94.1035 +    }
 94.1036 +
 94.1037 +    private void ensureOpen() throws IOException {
 94.1038 +        if (!isOpen)
 94.1039 +            throw new ClosedFileSystemException();
 94.1040 +    }
 94.1041 +
 94.1042 +    // Creates a new empty temporary file in the same directory as the
 94.1043 +    // specified file.  A variant of File.createTempFile.
 94.1044 +    private static Path createTempFileInSameDirectoryAs(Path path)
 94.1045 +        throws IOException
 94.1046 +    {
 94.1047 +        Path parent = path.toAbsolutePath().getParent();
 94.1048 +        String dir = (parent == null)? "." : parent.toString();
 94.1049 +        return File.createTempFile("zipfstmp", null, new File(dir)).toPath();
 94.1050 +    }
 94.1051 +
 94.1052 +    ////////////////////update & sync //////////////////////////////////////
 94.1053 +
 94.1054 +    private boolean hasUpdate = false;
 94.1055 +    private void updateDelete(Entry e) {
 94.1056 +        EntryName en = new EntryName(e.name);
 94.1057 +        inodes.remove(en);
 94.1058 +        hasUpdate = true;
 94.1059 +    }
 94.1060 +
 94.1061 +    private void update(Entry e) {
 94.1062 +        EntryName en = new EntryName(e.name);
 94.1063 +        inodes.put(en, e);
 94.1064 +        hasUpdate = true;
 94.1065 +    }
 94.1066 +
 94.1067 +    // copy over the whole LOC entry (header if necessary, data and ext) from
 94.1068 +    // old zip to the new one.
 94.1069 +    private long copyLOCEntry(Entry e, boolean updateHeader,
 94.1070 +                              OutputStream os,
 94.1071 +                              long written, byte[] buf)
 94.1072 +        throws IOException
 94.1073 +    {
 94.1074 +        long locoff = e.locoff;  // where to read
 94.1075 +        e.locoff = written;      // update the e.locoff with new value
 94.1076 +
 94.1077 +        // calculate the size need to write out
 94.1078 +        long size = 0;
 94.1079 +        //  if there is A ext
 94.1080 +        if ((e.flag & FLAG_DATADESCR) != 0) {
 94.1081 +            if (e.size >= ZIP64_MINVAL || e.csize >= ZIP64_MINVAL)
 94.1082 +                size = 24;
 94.1083 +            else
 94.1084 +                size = 16;
 94.1085 +        }
 94.1086 +        if (updateHeader) {       // if we need update the loc header
 94.1087 +            locoff += LOCHDR + e.nlen + e.elen;  // skip header
 94.1088 +            size += e.csize;
 94.1089 +            written = e.writeLOC(os) + size;
 94.1090 +        } else {
 94.1091 +            size += LOCHDR + e.nlen + e.elen + e.csize;
 94.1092 +            written = size;
 94.1093 +        }
 94.1094 +        int n;
 94.1095 +        while (size > 0 &&
 94.1096 +            (n = (int)readFullyAt(buf, 0, buf.length, locoff)) != -1)
 94.1097 +        {
 94.1098 +            if (size < n)
 94.1099 +                n = (int)size;
 94.1100 +            os.write(buf, 0, n);
 94.1101 +            size -= n;
 94.1102 +            locoff += n;
 94.1103 +        }
 94.1104 +        return written;
 94.1105 +    }
 94.1106 +
 94.1107 +    // sync the zip file system, if there is any udpate
 94.1108 +    private void sync() throws IOException {
 94.1109 +        assert Thread.holdsLock(this);
 94.1110 +
 94.1111 +        // check ex-closer
 94.1112 +        if (!exChClosers.isEmpty()) {
 94.1113 +            for (ExChannelCloser ecc : exChClosers) {
 94.1114 +                if (ecc.streams.isEmpty()) {
 94.1115 +                    ecc.ch.close();
 94.1116 +                    ecc.path.delete();
 94.1117 +                    exChClosers.remove(ecc);
 94.1118 +                }
 94.1119 +            }
 94.1120 +        }
 94.1121 +        if (!hasUpdate)
 94.1122 +            return;
 94.1123 +
 94.1124 +        Path tmpFile = createTempFileInSameDirectoryAs(zfpath);
 94.1125 +        OutputStream os = tmpFile.newOutputStream(WRITE);
 94.1126 +        ArrayList<Entry> elist = new ArrayList<>(inodes.size());
 94.1127 +        long written = 0;
 94.1128 +        byte[] buf = new byte[8192];
 94.1129 +        Entry e = null;
 94.1130 +
 94.1131 +        // write loc
 94.1132 +        for (IndexNode inode : inodes.values()) {
 94.1133 +            if (inode instanceof Entry) {    // an updated inode
 94.1134 +                e = (Entry)inode;
 94.1135 +                try {
 94.1136 +                    if (e.type == Entry.COPY) {
 94.1137 +                        // entry copy: the only thing changed is the "name"
 94.1138 +                        // and "nlen" in LOC header, so we udpate/rewrite the
 94.1139 +                        // LOC in new file and simply copy the rest (data and
 94.1140 +                        // ext) without enflating/deflating from the old zip
 94.1141 +                        // file LOC entry.
 94.1142 +                        written += copyLOCEntry(e, true, os, written, buf);
 94.1143 +                    } else {                          // NEW or FILECH
 94.1144 +                        e.locoff = written;
 94.1145 +                        written += e.writeLOC(os);    // write loc header
 94.1146 +                        if (e.bytes != null) {        // in-memory, deflated
 94.1147 +                            os.write(e.bytes);        // already
 94.1148 +                            written += e.bytes.length;
 94.1149 +                        } else if (e.file != null) {  // tmp file
 94.1150 +                            InputStream is = e.file.newInputStream();
 94.1151 +                            int n;
 94.1152 +                            if (e.type == Entry.NEW) {  // deflated already
 94.1153 +                                while ((n = is.read(buf)) != -1) {
 94.1154 +                                    os.write(buf, 0, n);
 94.1155 +                                    written += n;
 94.1156 +                                }
 94.1157 +                            } else if (e.type == Entry.FILECH) {
 94.1158 +                                // the data are not deflated, use ZEOS
 94.1159 +                                OutputStream os2 = new EntryOutputStream(e, os);
 94.1160 +                                while ((n = is.read(buf)) != -1) {
 94.1161 +                                    os2.write(buf, 0, n);
 94.1162 +                                }
 94.1163 +                                os2.close();
 94.1164 +                                written += e.csize;
 94.1165 +                                if ((e.flag & FLAG_DATADESCR) != 0)
 94.1166 +                                    written += e.writeEXT(os);
 94.1167 +                            }
 94.1168 +                            is.close();
 94.1169 +                            e.file.delete();
 94.1170 +                            tmppaths.remove(e.file);
 94.1171 +                        } else {
 94.1172 +                            // dir, 0-length data
 94.1173 +                        }
 94.1174 +                    }
 94.1175 +                    elist.add(e);
 94.1176 +                } catch (IOException x) {
 94.1177 +                    x.printStackTrace();    // skip any in-accurate entry
 94.1178 +                }
 94.1179 +            } else {    // unchanged inode
 94.1180 +                e = Entry.readCEN(cen, inode.pos);
 94.1181 +                try {
 94.1182 +                    written += copyLOCEntry(e, false, os, written, buf);
 94.1183 +                    elist.add(e);
 94.1184 +                } catch (IOException x) {
 94.1185 +                    x.printStackTrace();    // skip any wrong entry
 94.1186 +                }
 94.1187 +            }
 94.1188 +        }
 94.1189 +
 94.1190 +        // now write back the cen and end table
 94.1191 +        end.cenoff = written;
 94.1192 +        for (Entry entry : elist) {
 94.1193 +            written += entry.writeCEN(os);
 94.1194 +        }
 94.1195 +        end.centot = elist.size();
 94.1196 +        end.cenlen = written - end.cenoff;
 94.1197 +        end.write(os, written);
 94.1198 +        os.close();
 94.1199 +
 94.1200 +        if (!streams.isEmpty()) {
 94.1201 +            // There are outstanding input streams open on existing "ch",
 94.1202 +            // so, don't close the "cha" and delete the "file for now, let
 94.1203 +            // the "ex-channel-closer" to handle them
 94.1204 +            ExChannelCloser ecc = new ExChannelCloser(
 94.1205 +                                      createTempFileInSameDirectoryAs(zfpath),
 94.1206 +                                      ch,
 94.1207 +                                      streams);
 94.1208 +            zfpath.moveTo(ecc.path, REPLACE_EXISTING);
 94.1209 +            exChClosers.add(ecc);
 94.1210 +            streams = Collections.synchronizedSet(new HashSet<InputStream>());
 94.1211 +        } else {
 94.1212 +            ch.close();
 94.1213 +            zfpath.delete();
 94.1214 +        }
 94.1215 +        tmpFile.moveTo(zfpath, REPLACE_EXISTING);
 94.1216 +        hasUpdate = false;    // clear
 94.1217 +
 94.1218 +        if (isOpen) {
 94.1219 +            ch = zfpath.newByteChannel(READ); // re-fresh "ch" and "cen"
 94.1220 +            initCEN();
 94.1221 +        }
 94.1222 +        //System.out.println("->sync() done!");
 94.1223 +    }
 94.1224 +
 94.1225 +    private Entry getEntry0(byte[] path) throws IOException {
 94.1226 +        assert Thread.holdsLock(this);
 94.1227 +
 94.1228 +        if (path == null)
 94.1229 +            throw new NullPointerException("path");
 94.1230 +        if (path.length == 0)
 94.1231 +            return null;
 94.1232 +        EntryName en = new EntryName(path);
 94.1233 +        IndexNode inode = null;
 94.1234 +        synchronized (lock) {
 94.1235 +            ensureOpen();
 94.1236 +            if ((inode = inodes.get(en)) == null) {
 94.1237 +                if (path[path.length -1] == '/')  // already has a slash
 94.1238 +                    return null;
 94.1239 +                path = Arrays.copyOf(path, path.length + 1);
 94.1240 +                path[path.length - 1] = '/';
 94.1241 +                en.name(path);
 94.1242 +                if ((inode = inodes.get(en)) == null)
 94.1243 +                    return null;
 94.1244 +            }
 94.1245 +            if (inode instanceof Entry)
 94.1246 +                return (Entry)inode;
 94.1247 +            return Entry.readCEN(cen, inode.pos);
 94.1248 +        }
 94.1249 +    }
 94.1250 +
 94.1251 +    // Test if the "name" a parent directory of any entry (dir empty)
 94.1252 +    boolean isAncestor(byte[] name) {
 94.1253 +        for (Map.Entry<EntryName, IndexNode> entry : inodes.entrySet()) {
 94.1254 +            byte[] ename = entry.getKey().name;
 94.1255 +            if (isParentOf(name, ename))
 94.1256 +                return true;
 94.1257 +        }
 94.1258 +        return false;
 94.1259 +    }
 94.1260 +
 94.1261 +    public void deleteFile(byte[] path, boolean failIfNotExists)
 94.1262 +        throws IOException
 94.1263 +    {
 94.1264 +        checkWritable();
 94.1265 +        synchronized(lock) {
 94.1266 +            Entry e = getEntry0(path);
 94.1267 +            if (e == null) {
 94.1268 +                if (path != null && path.length == 0)
 94.1269 +                    throw new ZipException("root directory </> can't not be delete");
 94.1270 +                if (failIfNotExists)
 94.1271 +                    throw new NoSuchFileException(getString(path));
 94.1272 +            } else {
 94.1273 +                if (e.isDir() && isAncestor(path))
 94.1274 +                    throw new DirectoryNotEmptyException(getString(path));
 94.1275 +                updateDelete(e);
 94.1276 +            }
 94.1277 +        }
 94.1278 +    }
 94.1279 +
 94.1280 +    private static void copyStream(InputStream is, OutputStream os)
 94.1281 +        throws IOException
 94.1282 +    {
 94.1283 +        byte[] copyBuf = new byte[8192];
 94.1284 +        int n;
 94.1285 +        while ((n = is.read(copyBuf)) != -1) {
 94.1286 +            os.write(copyBuf, 0, n);
 94.1287 +        }
 94.1288 +    }
 94.1289 +
 94.1290 +    // Returns an out stream for either
 94.1291 +    // (1) writing the contents of a new entry, if the entry exits, or
 94.1292 +    // (2) updating/replacing the contents of the specified existing entry.
 94.1293 +    private OutputStream getOutputStream(Entry e) throws IOException {
 94.1294 +
 94.1295 +        ensureOpen();
 94.1296 +        if (e.mtime == -1)
 94.1297 +            e.mtime = javaToDosTime(System.currentTimeMillis());
 94.1298 +        if (e.method == -1)
 94.1299 +            e.method = METHOD_DEFLATED;  // TBD:  use default method
 94.1300 +        // store size, compressed size, and crc-32 in LOC header
 94.1301 +        e.flag = 0;
 94.1302 +        if (zc.isUTF8())
 94.1303 +            e.flag |= FLAG_EFS;
 94.1304 +        OutputStream os;
 94.1305 +        if (useTempFile) {
 94.1306 +            e.file = getTempPathForEntry(null);
 94.1307 +            os = e.file.newOutputStream(WRITE);
 94.1308 +        } else {
 94.1309 +            os = new ByteArrayOutputStream((e.size > 0)? (int)e.size : 8192);
 94.1310 +        }
 94.1311 +        return new EntryOutputStream(e, os);
 94.1312 +    }
 94.1313 +
 94.1314 +    private InputStream getInputStream(Entry e)
 94.1315 +        throws IOException
 94.1316 +    {
 94.1317 +        InputStream eis = null;
 94.1318 +
 94.1319 +        if (e.type == Entry.NEW) {
 94.1320 +            if (e.bytes != null)
 94.1321 +                eis = new ByteArrayInputStream(e.bytes);
 94.1322 +            else if (e.file != null)
 94.1323 +                eis = e.file.newInputStream();
 94.1324 +            else
 94.1325 +                throw new ZipException("update entry data is missing");
 94.1326 +        } else if (e.type == Entry.FILECH) {
 94.1327 +            // FILECH result is un-compressed.
 94.1328 +            eis = e.file.newInputStream();
 94.1329 +            // TBD: wrap to hook close()
 94.1330 +            // streams.add(eis);
 94.1331 +            return eis;
 94.1332 +        } else {  // untouced  CEN or COPY
 94.1333 +            eis = new EntryInputStream(e, ch);
 94.1334 +        }
 94.1335 +        if (e.method == METHOD_DEFLATED) {
 94.1336 +            // MORE: Compute good size for inflater stream:
 94.1337 +            long bufSize = e.size + 2; // Inflater likes a bit of slack
 94.1338 +            if (bufSize > 65536)
 94.1339 +                bufSize = 8192;
 94.1340 +            final long size = e.size;;
 94.1341 +            eis = new InflaterInputStream(eis, getInflater(), (int)bufSize) {
 94.1342 +
 94.1343 +                private boolean isClosed = false;
 94.1344 +                public void close() throws IOException {
 94.1345 +                    if (!isClosed) {
 94.1346 +                        releaseInflater(inf);
 94.1347 +                        this.in.close();
 94.1348 +                        isClosed = true;
 94.1349 +                    }
 94.1350 +                }
 94.1351 +                // Override fill() method to provide an extra "dummy" byte
 94.1352 +                // at the end of the input stream. This is required when
 94.1353 +                // using the "nowrap" Inflater option. (it appears the new
 94.1354 +                // zlib in 7 does not need it, but keep it for now)
 94.1355 +                protected void fill() throws IOException {
 94.1356 +                    if (eof) {
 94.1357 +                        throw new EOFException(
 94.1358 +                            "Unexpected end of ZLIB input stream");
 94.1359 +                    }
 94.1360 +                    len = this.in.read(buf, 0, buf.length);
 94.1361 +                    if (len == -1) {
 94.1362 +                        buf[0] = 0;
 94.1363 +                        len = 1;
 94.1364 +                        eof = true;
 94.1365 +                    }
 94.1366 +                    inf.setInput(buf, 0, len);
 94.1367 +                }
 94.1368 +                private boolean eof;
 94.1369 +
 94.1370 +                public int available() throws IOException {
 94.1371 +                    if (isClosed)
 94.1372 +                        return 0;
 94.1373 +                    long avail = size - inf.getBytesWritten();
 94.1374 +                    return avail > (long) Integer.MAX_VALUE ?
 94.1375 +                        Integer.MAX_VALUE : (int) avail;
 94.1376 +                }
 94.1377 +            };
 94.1378 +        } else if (e.method != METHOD_STORED) {
 94.1379 +            throw new ZipException("invalid compression method");
 94.1380 +        }
 94.1381 +        streams.add(eis);
 94.1382 +        return eis;
 94.1383 +    }
 94.1384 +
 94.1385 +    // Inner class implementing the input stream used to read
 94.1386 +    // a (possibly compressed) zip file entry.
 94.1387 +    private class EntryInputStream extends InputStream {
 94.1388 +        private SeekableByteChannel zfch; // local ref to zipfs's "ch". zipfs.ch might
 94.1389 +                                          // point to a new channel after sync()
 94.1390 +        private   long pos;               // current position within entry data
 94.1391 +        protected long rem;               // number of remaining bytes within entry
 94.1392 +        protected long size;              // uncompressed size of this entry
 94.1393 +
 94.1394 +        EntryInputStream(Entry e, SeekableByteChannel zfch)
 94.1395 +            throws IOException
 94.1396 +        {
 94.1397 +            this.zfch = zfch;
 94.1398 +            rem = e.csize;
 94.1399 +            size = e.size;
 94.1400 +            pos = getDataPos(e);
 94.1401 +        }
 94.1402 +        public int read(byte b[], int off, int len) throws IOException {
 94.1403 +            ensureOpen();
 94.1404 +            if (rem == 0) {
 94.1405 +                return -1;
 94.1406 +            }
 94.1407 +            if (len <= 0) {
 94.1408 +                return 0;
 94.1409 +            }
 94.1410 +            if (len > rem) {
 94.1411 +                len = (int) rem;
 94.1412 +            }
 94.1413 +            // readFullyAt()
 94.1414 +            long n = 0;
 94.1415 +            ByteBuffer bb = ByteBuffer.wrap(b);
 94.1416 +            bb.position(off);
 94.1417 +            bb.limit(off + len);
 94.1418 +            synchronized(zfch) {
 94.1419 +                n = zfch.position(pos).read(bb);
 94.1420 +            }
 94.1421 +            if (n > 0) {
 94.1422 +                pos += n;
 94.1423 +                rem -= n;
 94.1424 +            }
 94.1425 +            if (rem == 0) {
 94.1426 +                close();
 94.1427 +            }
 94.1428 +            return (int)n;
 94.1429 +        }
 94.1430 +        public int read() throws IOException {
 94.1431 +            byte[] b = new byte[1];
 94.1432 +            if (read(b, 0, 1) == 1) {
 94.1433 +                return b[0] & 0xff;
 94.1434 +            } else {
 94.1435 +                return -1;
 94.1436 +            }
 94.1437 +        }
 94.1438 +        public long skip(long n) throws IOException {
 94.1439 +            ensureOpen();
 94.1440 +            if (n > rem)
 94.1441 +                n = rem;
 94.1442 +            pos += n;
 94.1443 +            rem -= n;
 94.1444 +            if (rem == 0) {
 94.1445 +                close();
 94.1446 +            }
 94.1447 +            return n;
 94.1448 +        }
 94.1449 +        public int available() {
 94.1450 +            return rem > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) rem;
 94.1451 +        }
 94.1452 +
 94.1453 +        public long size() {
 94.1454 +            return size;
 94.1455 +        }
 94.1456 +        public void close() {
 94.1457 +            rem = 0;
 94.1458 +            streams.remove(this);
 94.1459 +        }
 94.1460 +    }
 94.1461 +
 94.1462 +    class EntryOutputStream extends DeflaterOutputStream
 94.1463 +    {
 94.1464 +        private CRC32 crc;
 94.1465 +        private Entry e;
 94.1466 +        private long written;
 94.1467 +
 94.1468 +        EntryOutputStream(Entry e, OutputStream os)
 94.1469 +            throws IOException
 94.1470 +        {
 94.1471 +            super(os, getDeflater());
 94.1472 +            if (e == null)
 94.1473 +                throw new NullPointerException("Zip entry is null");
 94.1474 +            this.e = e;
 94.1475 +            crc = new CRC32();
 94.1476 +        }
 94.1477 +
 94.1478 +        @Override
 94.1479 +        public void write(byte b[], int off, int len) throws IOException {
 94.1480 +            if (e.type != Entry.FILECH)    // only from sync
 94.1481 +                ensureOpen();
 94.1482 +            if (off < 0 || len < 0 || off > b.length - len) {
 94.1483 +                throw new IndexOutOfBoundsException();
 94.1484 +            } else if (len == 0) {
 94.1485 +                return;
 94.1486 +            }
 94.1487 +            switch (e.method) {
 94.1488 +            case METHOD_DEFLATED:
 94.1489 +                super.write(b, off, len);
 94.1490 +                break;
 94.1491 +            case METHOD_STORED:
 94.1492 +                written += len;
 94.1493 +                out.write(b, off, len);
 94.1494 +                break;
 94.1495 +            default:
 94.1496 +                throw new ZipException("invalid compression method");
 94.1497 +            }
 94.1498 +            crc.update(b, off, len);
 94.1499 +        }
 94.1500 +
 94.1501 +        @Override
 94.1502 +        public void close() throws IOException {
 94.1503 +            // TBD ensureOpen();
 94.1504 +            switch (e.method) {
 94.1505 +            case METHOD_DEFLATED:
 94.1506 +                finish();
 94.1507 +                e.size  = def.getBytesRead();
 94.1508 +                e.csize = def.getBytesWritten();
 94.1509 +                e.crc = crc.getValue();
 94.1510 +                break;
 94.1511 +            case METHOD_STORED:
 94.1512 +                // we already know that both e.size and e.csize are the same
 94.1513 +                e.size = e.csize = written;
 94.1514 +                e.crc = crc.getValue();
 94.1515 +                break;
 94.1516 +            default:
 94.1517 +                throw new ZipException("invalid compression method");
 94.1518 +            }
 94.1519 +            //crc.reset();
 94.1520 +            if (out instanceof ByteArrayOutputStream)
 94.1521 +                e.bytes = ((ByteArrayOutputStream)out).toByteArray();
 94.1522 +
 94.1523 +            if (e.type == Entry.FILECH) {
 94.1524 +                releaseDeflater(def);
 94.1525 +                return;
 94.1526 +            }
 94.1527 +            super.close();
 94.1528 +            releaseDeflater(def);
 94.1529 +            update(e);
 94.1530 +        }
 94.1531 +    }
 94.1532 +
 94.1533 +    private static void zerror(String msg) {
 94.1534 +        throw new ZipError(msg);
 94.1535 +    }
 94.1536 +
 94.1537 +    // Maxmum number of de/inflater we cache
 94.1538 +    private final int MAX_FLATER = 20;
 94.1539 +    // List of available Inflater objects for decompression
 94.1540 +    private List<Inflater> inflaters = new ArrayList<>();
 94.1541 +
 94.1542 +    // Gets an inflater from the list of available inflaters or allocates
 94.1543 +    // a new one.
 94.1544 +    private Inflater getInflater() {
 94.1545 +        synchronized (inflaters) {
 94.1546 +            int size = inflaters.size();
 94.1547 +            if (size > 0) {
 94.1548 +                Inflater inf = (Inflater)inflaters.remove(size - 1);
 94.1549 +                return inf;
 94.1550 +            } else {
 94.1551 +                return new Inflater(true);
 94.1552 +            }
 94.1553 +        }
 94.1554 +    }
 94.1555 +
 94.1556 +    // Releases the specified inflater to the list of available inflaters.
 94.1557 +    private void releaseInflater(Inflater inf) {
 94.1558 +        synchronized (inflaters) {
 94.1559 +            if (inflaters.size() < MAX_FLATER) {
 94.1560 +                inf.reset();
 94.1561 +                inflaters.add(inf);
 94.1562 +            } else {
 94.1563 +                inf.end();
 94.1564 +            }
 94.1565 +        }
 94.1566 +    }
 94.1567 +
 94.1568 +    // List of available Deflater objects for compression
 94.1569 +    private List<Deflater> deflaters = new ArrayList<>();
 94.1570 +
 94.1571 +    // Gets an deflater from the list of available deflaters or allocates
 94.1572 +    // a new one.
 94.1573 +    private Deflater getDeflater() {
 94.1574 +        synchronized (deflaters) {
 94.1575 +            int size = deflaters.size();
 94.1576 +            if (size > 0) {
 94.1577 +                Deflater def = (Deflater)deflaters.remove(size - 1);
 94.1578 +                return def;
 94.1579 +            } else {
 94.1580 +                return new Deflater(Deflater.DEFAULT_COMPRESSION, true);
 94.1581 +            }
 94.1582 +        }
 94.1583 +    }
 94.1584 +
 94.1585 +    // Releases the specified inflater to the list of available inflaters.
 94.1586 +    private void releaseDeflater(Deflater def) {
 94.1587 +        synchronized (deflaters) {
 94.1588 +            if (inflaters.size() < MAX_FLATER) {
 94.1589 +               def.reset();
 94.1590 +               deflaters.add(def);
 94.1591 +            } else {
 94.1592 +               def.end();
 94.1593 +            }
 94.1594 +        }
 94.1595 +    }
 94.1596 +
 94.1597 +    // End of central directory record
 94.1598 +    static class END {
 94.1599 +        int  disknum;
 94.1600 +        int  sdisknum;
 94.1601 +        int  endsub;     // endsub
 94.1602 +        int  centot;     // 4 bytes
 94.1603 +        long cenlen;     // 4 bytes
 94.1604 +        long cenoff;     // 4 bytes
 94.1605 +        int  comlen;     // comment length
 94.1606 +        byte[] comment;
 94.1607 +
 94.1608 +        /* members of Zip64 end of central directory locator */
 94.1609 +        int diskNum;
 94.1610 +        long endpos;
 94.1611 +        int disktot;
 94.1612 +
 94.1613 +        void write(OutputStream os, long offset) throws IOException {
 94.1614 +            boolean hasZip64 = false;
 94.1615 +            long xlen = cenlen;
 94.1616 +            long xoff = cenoff;
 94.1617 +            if (xlen >= ZIP64_MINVAL) {
 94.1618 +                xlen = ZIP64_MINVAL;
 94.1619 +                hasZip64 = true;
 94.1620 +            }
 94.1621 +            if (xoff >= ZIP64_MINVAL) {
 94.1622 +                xoff = ZIP64_MINVAL;
 94.1623 +                hasZip64 = true;
 94.1624 +            }
 94.1625 +            int count = centot;
 94.1626 +            if (count >= ZIP64_MINVAL32) {
 94.1627 +                count = ZIP64_MINVAL32;
 94.1628 +                hasZip64 = true;
 94.1629 +            }
 94.1630 +            if (hasZip64) {
 94.1631 +                long off64 = offset;
 94.1632 +                //zip64 end of central directory record
 94.1633 +                writeInt(os, ZIP64_ENDSIG);       // zip64 END record signature
 94.1634 +                writeLong(os, ZIP64_ENDHDR - 12); // size of zip64 end
 94.1635 +                writeShort(os, 45);               // version made by
 94.1636 +                writeShort(os, 45);               // version needed to extract
 94.1637 +                writeInt(os, 0);                  // number of this disk
 94.1638 +                writeInt(os, 0);                  // central directory start disk
 94.1639 +                writeLong(os, centot);            // number of directory entires on disk
 94.1640 +                writeLong(os, centot);            // number of directory entires
 94.1641 +                writeLong(os, cenlen);            // length of central directory
 94.1642 +                writeLong(os, cenoff);            // offset of central directory
 94.1643 +
 94.1644 +                //zip64 end of central directory locator
 94.1645 +                writeInt(os, ZIP64_LOCSIG);       // zip64 END locator signature
 94.1646 +                writeInt(os, 0);                  // zip64 END start disk
 94.1647 +                writeLong(os, off64);             // offset of zip64 END
 94.1648 +                writeInt(os, 1);                  // total number of disks (?)
 94.1649 +            }
 94.1650 +            writeInt(os, ENDSIG);                 // END record signature
 94.1651 +            writeShort(os, 0);                    // number of this disk
 94.1652 +            writeShort(os, 0);                    // central directory start disk
 94.1653 +            writeShort(os, count);                // number of directory entries on disk
 94.1654 +            writeShort(os, count);                // total number of directory entries
 94.1655 +            writeInt(os, xlen);                   // length of central directory
 94.1656 +            writeInt(os, xoff);                   // offset of central directory
 94.1657 +            if (comment != null) {            // zip file comment
 94.1658 +                writeShort(os, comment.length);
 94.1659 +                writeBytes(os, comment);
 94.1660 +            } else {
 94.1661 +                writeShort(os, 0);
 94.1662 +            }
 94.1663 +        }
 94.1664 +    }
 94.1665 +
 94.1666 +    // wrapper for the byte[] name
 94.1667 +    static class EntryName {
 94.1668 +        byte[] name;
 94.1669 +        int hashcode;    // node is hashable/hashed by its name
 94.1670 +
 94.1671 +        public EntryName (byte[] name) {
 94.1672 +            name(name);
 94.1673 +        }
 94.1674 +
 94.1675 +        void name(byte[] name) {
 94.1676 +            this.name = name;
 94.1677 +            this.hashcode = Arrays.hashCode(name);
 94.1678 +        }
 94.1679 +
 94.1680 +        public boolean equals(Object other) {
 94.1681 +            if (!(other instanceof EntryName))
 94.1682 +                return false;
 94.1683 +            return Arrays.equals(name, ((EntryName)other).name);
 94.1684 +        }
 94.1685 +
 94.1686 +        public int hashCode() {
 94.1687 +            return hashcode;
 94.1688 +        }
 94.1689 +    }
 94.1690 +
 94.1691 +    // can simply use Integer instead, if we don't use it to
 94.1692 +    // build a internal node tree.
 94.1693 +    static class IndexNode {
 94.1694 +        byte[] name;
 94.1695 +        int pos = -1;     // postion in cen table, -1 menas the
 94.1696 +                          // entry does not exists in zip file
 94.1697 +        IndexNode(byte[] name, int pos) {
 94.1698 +            this.name = name;
 94.1699 +            this.pos = pos;
 94.1700 +        }
 94.1701 +
 94.1702 +        IndexNode() {}
 94.1703 +
 94.1704 +        IndexNode sibling;
 94.1705 +        IndexNode child;  // 1st child
 94.1706 +    }
 94.1707 +
 94.1708 +    static class Entry extends IndexNode {
 94.1709 +
 94.1710 +        static final int CEN    = 1;    // entry read from cen
 94.1711 +        static final int NEW    = 2;    // updated contents in bytes or file
 94.1712 +        static final int FILECH = 3;    // fch update in "file"
 94.1713 +        static final int COPY   = 4;    // copy of a CEN entry
 94.1714 +
 94.1715 +        byte[] bytes;      // updated content bytes
 94.1716 +        Path   file;       // use tmp file to store bytes;
 94.1717 +        int    type = CEN; // default is the entry read from cen
 94.1718 +
 94.1719 +        // entry attributes
 94.1720 +        int    version;
 94.1721 +        int    flag;
 94.1722 +        int    method = -1;    // compression method
 94.1723 +        long   mtime  = -1;    // last modification time (in DOS time)
 94.1724 +        long   atime  = -1;    // last access time
 94.1725 +        long   ctime  = -1;    // create time
 94.1726 +        long   crc    = -1;    // crc-32 of entry data
 94.1727 +        long   csize  = -1;    // compressed size of entry data
 94.1728 +        long   size   = -1;    // uncompressed size of entry data
 94.1729 +        int    nlen;
 94.1730 +        int    elen;
 94.1731 +        byte[] extra;
 94.1732 +
 94.1733 +        // loc
 94.1734 +        long   startPos;
 94.1735 +        long   endPos;         // exclusive
 94.1736 +
 94.1737 +        // cen
 94.1738 +        int    versionMade;
 94.1739 +        int    disk;
 94.1740 +        int    attrs;
 94.1741 +        long   attrsEx;
 94.1742 +        long   locoff;
 94.1743 +
 94.1744 +        int    clen;
 94.1745 +        byte[] comment;
 94.1746 +
 94.1747 +        // ZIP64 flag
 94.1748 +        boolean hasZip64;
 94.1749 +
 94.1750 +        Entry() {}
 94.1751 +
 94.1752 +        Entry(byte[] name) {
 94.1753 +            this.name = name;
 94.1754 +            //this.nlen = name.length;
 94.1755 +            this.mtime  = javaToDosTime(System.currentTimeMillis());
 94.1756 +            this.crc       = 0;
 94.1757 +            this.size      = 0;
 94.1758 +            this.csize     = 0;
 94.1759 +            this.method    = METHOD_DEFLATED;
 94.1760 +        }
 94.1761 +
 94.1762 +        Entry(byte[] name, int type) {
 94.1763 +            this(name);
 94.1764 +            this.type = type;
 94.1765 +        }
 94.1766 +
 94.1767 +        Entry (byte[] name, Path file, int type) {
 94.1768 +            this(name, type);
 94.1769 +            this.file = file;
 94.1770 +            this.method = METHOD_STORED;
 94.1771 +        }
 94.1772 +
 94.1773 +        Entry(Entry e) {
 94.1774 +            this.version   = e.version;
 94.1775 +            this.name      = e.name;  // copyOf?
 94.1776 +            this.nlen      = e.nlen;
 94.1777 +            this.ctime     = e.ctime;
 94.1778 +            this.atime     = e.atime;
 94.1779 +            this.mtime     = e.mtime;
 94.1780 +            this.crc       = e.crc;
 94.1781 +            this.size      = e.size;
 94.1782 +            this.csize     = e.csize;
 94.1783 +            this.method    = e.method;
 94.1784 +            this.extra     = (e.extra == null)?
 94.1785 +                             null:Arrays.copyOf(e.extra, e.extra.length);
 94.1786 +            this.elen      = e.elen;
 94.1787 +            this.versionMade = e.versionMade;
 94.1788 +            this.disk      = e.disk;
 94.1789 +            this.attrs     = e.attrs;
 94.1790 +            this.attrsEx   = e.attrsEx;
 94.1791 +            this.locoff    = e.locoff;
 94.1792 +            this.clen      = e.clen;
 94.1793 +            this.comment   = (e.comment == null)?
 94.1794 +                             null:Arrays.copyOf(e.comment, e.comment.length);
 94.1795 +            this.startPos = e.startPos;
 94.1796 +            this.endPos   = e.endPos;
 94.1797 +            this.hasZip64 = e.hasZip64;;
 94.1798 +        }
 94.1799 +
 94.1800 +        Entry (Entry e, int type) {
 94.1801 +            this(e);
 94.1802 +            this.type = type;
 94.1803 +        }
 94.1804 +
 94.1805 +        boolean isDir() {
 94.1806 +            return name != null &&
 94.1807 +                   (name.length == 0 ||
 94.1808 +                    name[name.length - 1] == '/');
 94.1809 +        }
 94.1810 +
 94.1811 +        int version() throws ZipException {
 94.1812 +            if (method == METHOD_DEFLATED)
 94.1813 +                return 20;
 94.1814 +            else if (method == METHOD_STORED)
 94.1815 +                return 10;
 94.1816 +            throw new ZipException("unsupported compression method");
 94.1817 +        }
 94.1818 +
 94.1819 +        ///////////////////// CEN //////////////////////
 94.1820 +        static Entry readCEN(ByteBuffer cen, int pos) throws IOException
 94.1821 +        {
 94.1822 +            return new Entry().cen(cen, pos);
 94.1823 +        }
 94.1824 +
 94.1825 +        private Entry cen(ByteBuffer cen, int pos) throws IOException
 94.1826 +        {
 94.1827 +            if (CENSIG(cen, pos) != CENSIG)
 94.1828 +                zerror("invalid CEN header (bad signature)");
 94.1829 +            versionMade = CENVEM(cen, pos);
 94.1830 +            version     = CENVER(cen, pos);
 94.1831 +            flag        = CENFLG(cen, pos);
 94.1832 +            method      = CENHOW(cen, pos);
 94.1833 +            mtime       = CENTIM(cen, pos);
 94.1834 +            crc         = CENCRC(cen, pos);
 94.1835 +            csize       = CENSIZ(cen, pos);
 94.1836 +            size        = CENLEN(cen, pos);
 94.1837 +            nlen        = CENNAM(cen, pos);
 94.1838 +            elen        = CENEXT(cen, pos);
 94.1839 +            clen        = CENCOM(cen, pos);
 94.1840 +            disk        = CENDSK(cen, pos);
 94.1841 +            attrs       = CENATT(cen, pos);
 94.1842 +            attrsEx     = CENATX(cen, pos);
 94.1843 +            locoff      = CENOFF(cen, pos);
 94.1844 +
 94.1845 +            cen.position(pos + CENHDR);
 94.1846 +            name = new byte[nlen];
 94.1847 +            cen.get(name);
 94.1848 +
 94.1849 +            if (elen > 0) {
 94.1850 +                extra = new byte[elen];
 94.1851 +                cen.get(extra);
 94.1852 +                if (csize == ZIP64_MINVAL || size == ZIP64_MINVAL ||
 94.1853 +                    locoff == ZIP64_MINVAL) {
 94.1854 +                    int off = 0;
 94.1855 +                    while (off + 4 < elen) {
 94.1856 +                        // extra spec: HeaderID+DataSize+Data
 94.1857 +                        int sz = SH(extra, off + 2);
 94.1858 +                        if (SH(extra, off) == EXTID_ZIP64) {
 94.1859 +                            off += 4;
 94.1860 +                            if (size == ZIP64_MINVAL) {
 94.1861 +                                // if invalid zip64 extra fields, just skip
 94.1862 +                                if (sz < 8 || (off + 8) > elen)
 94.1863 +                                    break;
 94.1864 +                                size = LL(extra, off);
 94.1865 +                                sz -= 8;
 94.1866 +                                off += 8;
 94.1867 +                            }
 94.1868 +                            if (csize == ZIP64_MINVAL) {
 94.1869 +                                if (sz < 8 || (off + 8) > elen)
 94.1870 +                                    break;
 94.1871 +                                csize = LL(extra, off);
 94.1872 +                                sz -= 8;
 94.1873 +                                off += 8;
 94.1874 +                            }
 94.1875 +                            if (locoff == ZIP64_MINVAL) {
 94.1876 +                                if (sz < 8 || (off + 8) > elen)
 94.1877 +                                    break;
 94.1878 +                                locoff = LL(extra, off);
 94.1879 +                                sz -= 8;
 94.1880 +                                off += 8;
 94.1881 +                            }
 94.1882 +                            break;
 94.1883 +                        }
 94.1884 +                        off += (sz + 4);
 94.1885 +                    }
 94.1886 +                }
 94.1887 +            }
 94.1888 +            if (clen > 0) {
 94.1889 +                comment = new byte[clen];
 94.1890 +                cen.get(comment);
 94.1891 +            }
 94.1892 +            return this;
 94.1893 +        }
 94.1894 +
 94.1895 +        int writeCEN(OutputStream os) throws IOException
 94.1896 +        {
 94.1897 +            int written  = CENHDR;
 94.1898 +            int version0 = version();
 94.1899 +
 94.1900 +            long csize0  = csize;
 94.1901 +            long size0   = size;
 94.1902 +            long locoff0 = locoff;
 94.1903 +            int e64len   = 0;
 94.1904 +
 94.1905 +            // confirm size/length
 94.1906 +            nlen = (name != null) ? name.length : 0;
 94.1907 +            elen = (extra != null) ? extra.length : 0;
 94.1908 +            clen = (comment != null) ? comment.length : 0;
 94.1909 +
 94.1910 +            boolean hasZip64 = false;
 94.1911 +            if (csize >= ZIP64_MINVAL) {
 94.1912 +                csize0 = ZIP64_MINVAL;
 94.1913 +                e64len += 8;                 // csize(8)
 94.1914 +                hasZip64 = true;
 94.1915 +            }
 94.1916 +            if (size >= ZIP64_MINVAL) {
 94.1917 +                size0 = ZIP64_MINVAL;        // size(8)
 94.1918 +                e64len += 8;
 94.1919 +                hasZip64 = true;
 94.1920 +            }
 94.1921 +            if (locoff >= ZIP64_MINVAL) {
 94.1922 +                locoff0 = ZIP64_MINVAL;
 94.1923 +                e64len += 8;                 // offset(8)
 94.1924 +                hasZip64 = true;
 94.1925 +            }
 94.1926 +            writeInt(os, CENSIG);            // CEN header signature
 94.1927 +            if (hasZip64) {
 94.1928 +                writeShort(os, 45);          // ver 4.5 for zip64
 94.1929 +                writeShort(os, 45);
 94.1930 +            } else {
 94.1931 +                writeShort(os, version0);    // version made by
 94.1932 +                writeShort(os, version0);    // version needed to extract
 94.1933 +            }
 94.1934 +            writeShort(os, flag);            // general purpose bit flag
 94.1935 +            writeShort(os, method);          // compression method
 94.1936 +            writeInt(os, mtime);             // last modification time
 94.1937 +            writeInt(os, crc);               // crc-32
 94.1938 +            writeInt(os, csize0);            // compressed size
 94.1939 +            writeInt(os, size0);             // uncompressed size
 94.1940 +            writeShort(os, name.length);
 94.1941 +
 94.1942 +            if (hasZip64) {
 94.1943 +                // + headid(2) + datasize(2)
 94.1944 +                writeShort(os, e64len + 4 + elen);
 94.1945 +            } else {
 94.1946 +                writeShort(os, elen);
 94.1947 +            }
 94.1948 +            if (comment != null) {
 94.1949 +                writeShort(os, Math.min(clen, 0xffff));
 94.1950 +            } else {
 94.1951 +                writeShort(os, 0);
 94.1952 +            }
 94.1953 +            writeShort(os, 0);              // starting disk number
 94.1954 +            writeShort(os, 0);              // internal file attributes (unused)
 94.1955 +            writeInt(os, 0);                // external file attributes (unused)
 94.1956 +            writeInt(os, locoff0);          // relative offset of local header
 94.1957 +            writeBytes(os, name);
 94.1958 +            if (hasZip64) {
 94.1959 +                writeShort(os, EXTID_ZIP64);// Zip64 extra
 94.1960 +                writeShort(os, e64len);
 94.1961 +                if (size0 == ZIP64_MINVAL)
 94.1962 +                    writeLong(os, size);
 94.1963 +                if (csize0 == ZIP64_MINVAL)
 94.1964 +                    writeLong(os, csize);
 94.1965 +                if (locoff0 == ZIP64_MINVAL)
 94.1966 +                    writeLong(os, locoff);
 94.1967 +            }
 94.1968 +            if (extra != null) {
 94.1969 +                writeBytes(os, extra);
 94.1970 +            }
 94.1971 +            if (comment != null) {
 94.1972 +                //TBD: 0, Math.min(commentBytes.length, 0xffff));
 94.1973 +                writeBytes(os, comment);
 94.1974 +            }
 94.1975 +            return CENHDR + nlen + elen + clen + (hasZip64?(e64len + 4):0);
 94.1976 +        }
 94.1977 +
 94.1978 +        ///////////////////// LOC //////////////////////
 94.1979 +        static Entry readLOC(ZipFileSystem zf, long pos)
 94.1980 +            throws IOException
 94.1981 +        {
 94.1982 +            return readLOC(zf, pos, new byte[1024]);
 94.1983 +        }
 94.1984 +
 94.1985 +        static Entry readLOC(ZipFileSystem zf, long pos, byte[] buf)
 94.1986 +            throws IOException
 94.1987 +        {
 94.1988 +            return new Entry().loc(zf, pos, buf);
 94.1989 +        }
 94.1990 +
 94.1991 +        Entry loc(ZipFileSystem zf, long pos, byte[] buf)
 94.1992 +            throws IOException
 94.1993 +        {
 94.1994 +            assert (buf.length >= LOCHDR);
 94.1995 +            if (zf.readFullyAt(buf, 0, LOCHDR , pos) != LOCHDR) {
 94.1996 +                throw new ZipException("loc: reading failed");
 94.1997 +            }
 94.1998 +            if (LOCSIG(buf) != LOCSIG) {
 94.1999 +                throw new ZipException("loc: wrong sig ->"
 94.2000 +                                       + Long.toString(LOCSIG(buf), 16));
 94.2001 +            }
 94.2002 +            startPos = pos;
 94.2003 +            version  = LOCVER(buf);
 94.2004 +            flag     = LOCFLG(buf);
 94.2005 +            method   = LOCHOW(buf);
 94.2006 +            mtime    = LOCTIM(buf);
 94.2007 +            crc      = LOCCRC(buf);
 94.2008 +            csize    = LOCSIZ(buf);
 94.2009 +            size     = LOCLEN(buf);
 94.2010 +            nlen     = LOCNAM(buf);
 94.2011 +            elen     = LOCEXT(buf);
 94.2012 +
 94.2013 +            name = new byte[nlen];
 94.2014 +            if (zf.readFullyAt(name, 0, nlen, pos + LOCHDR) != nlen) {
 94.2015 +                throw new ZipException("loc: name reading failed");
 94.2016 +            }
 94.2017 +            if (elen > 0) {
 94.2018 +                extra = new byte[elen];
 94.2019 +                if (zf.readFullyAt(extra, 0, elen, pos + LOCHDR + nlen)
 94.2020 +                    != elen) {
 94.2021 +                    throw new ZipException("loc: ext reading failed");
 94.2022 +                }
 94.2023 +            }
 94.2024 +            pos += (LOCHDR + nlen + elen);
 94.2025 +            if ((flag & FLAG_DATADESCR) != 0) {
 94.2026 +                // Data Descriptor
 94.2027 +                Entry e = zf.getEntry0(name);  // get the size/csize from cen
 94.2028 +                if (e == null)
 94.2029 +                    throw new ZipException("loc: name not found in cen");
 94.2030 +                size = e.size;
 94.2031 +                csize = e.csize;
 94.2032 +                pos += (method == METHOD_STORED ? size : csize);
 94.2033 +                if (size >= ZIP64_MINVAL || csize >= ZIP64_MINVAL)
 94.2034 +                    pos += 24;
 94.2035 +                else
 94.2036 +                    pos += 16;
 94.2037 +            } else {
 94.2038 +                boolean hasZip64 = false;
 94.2039 +                if (extra != null &&
 94.2040 +                    (size == ZIP64_MINVAL || csize == ZIP64_MINVAL)) {
 94.2041 +                    // zip64 ext: must include both size and csize
 94.2042 +                    int off = 0;
 94.2043 +                    while (off + 20 < elen) {    // HeaderID+DataSize+Data
 94.2044 +                        int sz = SH(extra, off + 2);
 94.2045 +                        if (SH(extra, off) == EXTID_ZIP64 && sz == 16) {
 94.2046 +                            size = LL(extra, off + 4);
 94.2047 +                            csize = LL(extra, off + 12);
 94.2048 +                            hasZip64 = true;
 94.2049 +                            break;
 94.2050 +                        }
 94.2051 +                        off += (sz + 4);
 94.2052 +                    }
 94.2053 +                }
 94.2054 +                pos += (method == METHOD_STORED ? size : csize);
 94.2055 +            }
 94.2056 +            endPos = pos;
 94.2057 +            return this;
 94.2058 +        }
 94.2059 +
 94.2060 +        int writeLOC(OutputStream os)
 94.2061 +            throws IOException
 94.2062 +        {
 94.2063 +            writeInt(os, LOCSIG);               // LOC header signature
 94.2064 +
 94.2065 +            int version = version();
 94.2066 +            if ((flag & FLAG_DATADESCR) != 0) {
 94.2067 +                writeShort(os, version());      // version needed to extract
 94.2068 +                writeShort(os, flag);           // general purpose bit flag
 94.2069 +                writeShort(os, method);         // compression method
 94.2070 +                writeInt(os, mtime);            // last modification time
 94.2071 +
 94.2072 +                // store size, uncompressed size, and crc-32 in data descriptor
 94.2073 +                // immediately following compressed entry data
 94.2074 +                writeInt(os, 0);
 94.2075 +                writeInt(os, 0);
 94.2076 +                writeInt(os, 0);
 94.2077 +            } else {
 94.2078 +                if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) {
 94.2079 +                    hasZip64 = true;
 94.2080 +                    writeShort(os, 45);         // ver 4.5 for zip64
 94.2081 +                } else {
 94.2082 +                    writeShort(os, version());  // version needed to extract
 94.2083 +                }
 94.2084 +                writeShort(os, flag);           // general purpose bit flag
 94.2085 +                writeShort(os, method);         // compression method
 94.2086 +                writeInt(os, mtime);            // last modification time
 94.2087 +                writeInt(os, crc);              // crc-32
 94.2088 +                if (hasZip64) {
 94.2089 +                    writeInt(os, ZIP64_MINVAL);
 94.2090 +                    writeInt(os, ZIP64_MINVAL);
 94.2091 +                    //TBD:  e.elen += 20;       //headid(2) + size(2) + size(8) + csize(8)
 94.2092 +                } else {
 94.2093 +                    writeInt(os, csize);        // compressed size
 94.2094 +                    writeInt(os, size);         // uncompressed size
 94.2095 +                }
 94.2096 +            }
 94.2097 +            writeShort(os, name.length);
 94.2098 +            writeShort(os, elen + (hasZip64 ? 20 : 0));
 94.2099 +            writeBytes(os, name);
 94.2100 +            if (hasZip64) {
 94.2101 +                // TBD: should we update extra directory?
 94.2102 +                writeShort(os, EXTID_ZIP64);
 94.2103 +                writeShort(os, 16);
 94.2104 +                writeLong(os, size);
 94.2105 +                writeLong(os, csize);
 94.2106 +            }
 94.2107 +            if (extra != null) {
 94.2108 +                writeBytes(os, extra);
 94.2109 +            }
 94.2110 +            return LOCHDR + name.length + elen + (hasZip64 ? 20 : 0);
 94.2111 +        }
 94.2112 +
 94.2113 +        // Data Descriptior
 94.2114 +        int writeEXT(OutputStream os)
 94.2115 +            throws IOException
 94.2116 +        {
 94.2117 +            writeInt(os, EXTSIG);           // EXT header signature
 94.2118 +            writeInt(os, crc);              // crc-32
 94.2119 +            if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) {
 94.2120 +                writeLong(os, csize);
 94.2121 +                writeLong(os, size);
 94.2122 +                return 24;
 94.2123 +            } else {
 94.2124 +                writeInt(os, csize);        // compressed size
 94.2125 +                writeInt(os, size);         // uncompressed size
 94.2126 +                return 16;
 94.2127 +            }
 94.2128 +        }
 94.2129 +
 94.2130 +        // read NTFS, UNIX and ZIP64 data from cen.extra
 94.2131 +        void readExtra() {
 94.2132 +            if (extra == null)
 94.2133 +                return;
 94.2134 +            int elen = extra.length;
 94.2135 +            int off = 0;
 94.2136 +            while (off + 4 < elen) {
 94.2137 +                // extra spec: HeaderID+DataSize+Data
 94.2138 +                int sz = SH(extra, off + 2);
 94.2139 +                int tag = SH(extra, off);
 94.2140 +                off += 4;
 94.2141 +                int pos = off;
 94.2142 +                if (pos + sz > elen)         // invalid data
 94.2143 +                    break;
 94.2144 +                switch (tag) {
 94.2145 +                case EXTID_ZIP64 :
 94.2146 +                    if (size == ZIP64_MINVAL) {
 94.2147 +                        if (pos + 8 > elen)  // invalid zip64 extra
 94.2148 +                            break;           // fields, just skip
 94.2149 +                        size = LL(extra, pos);
 94.2150 +                        pos += 8;
 94.2151 +                    }
 94.2152 +                    if (csize == ZIP64_MINVAL) {
 94.2153 +                        if (pos + 8 > elen)
 94.2154 +                            break;
 94.2155 +                        csize = LL(extra, pos);
 94.2156 +                        pos += 8;
 94.2157 +                    }
 94.2158 +                    if (locoff == ZIP64_MINVAL) {
 94.2159 +                        if (pos + 8 > elen)
 94.2160 +                            break;
 94.2161 +                        locoff = LL(extra, pos);
 94.2162 +                        pos += 8;
 94.2163 +                    }
 94.2164 +                    break;
 94.2165 +                case EXTID_NTFS:
 94.2166 +                    pos += 4;    // reserved 4 bytes
 94.2167 +                    if (SH(extra, pos) !=  0x0001)
 94.2168 +                        break;
 94.2169 +                    if (SH(extra, pos + 2) != 24)
 94.2170 +                        break;
 94.2171 +                    mtime = LL(extra, pos + 4);
 94.2172 +                    atime = LL(extra, pos + 12);
 94.2173 +                    ctime = LL(extra, pos + 20);
 94.2174 +                    break;
 94.2175 +                case EXTID_UNIX:
 94.2176 +                    atime = LG(extra, pos);
 94.2177 +                    mtime = LG(extra, pos + 4);
 94.2178 +                    break;
 94.2179 +                default:    // unknow
 94.2180 +                }
 94.2181 +                off += sz;
 94.2182 +            }
 94.2183 +        }
 94.2184 +    }
 94.2185 +
 94.2186 +    private static class ExChannelCloser  {
 94.2187 +        Path path;
 94.2188 +        SeekableByteChannel ch;
 94.2189 +        Set<InputStream> streams;
 94.2190 +        ExChannelCloser(Path path,
 94.2191 +                        SeekableByteChannel ch,
 94.2192 +                        Set<InputStream> streams)
 94.2193 +        {
 94.2194 +            this.path = path;
 94.2195 +            this.ch = ch;
 94.2196 +            this.streams = streams;
 94.2197 +        }
 94.2198 +    }
 94.2199 +
 94.2200 +    // ZIP directory has two issues:
 94.2201 +    // (1) ZIP spec does not require the ZIP file to include
 94.2202 +    //     directory entry
 94.2203 +    // (2) all entries are not stored/organized in a "tree"
 94.2204 +    //     structure.
 94.2205 +    // A possible solution is to build the node tree ourself as
 94.2206 +    // implemented below.
 94.2207 +    private HashMap<EntryName, IndexNode> dirs;
 94.2208 +    private IndexNode root;
 94.2209 +    private IndexNode addToDir(EntryName child) {
 94.2210 +        IndexNode cinode = dirs.get(child);
 94.2211 +        if (cinode != null)
 94.2212 +            return cinode;
 94.2213 +
 94.2214 +        byte[] cname = child.name;
 94.2215 +        byte[] pname = getParent(cname);
 94.2216 +        IndexNode pinode;
 94.2217 +
 94.2218 +        if (pname != null)
 94.2219 +            pinode = addToDir(new EntryName(pname));
 94.2220 +        else
 94.2221 +            pinode = root;
 94.2222 +        cinode = inodes.get(child);
 94.2223 +        if (cname[cname.length -1] != '/') {  // not a dir
 94.2224 +            cinode.sibling = pinode.child;
 94.2225 +            pinode.child = cinode;
 94.2226 +            return null;
 94.2227 +        }
 94.2228 +        cinode = dirs.get(child);
 94.2229 +        if (cinode == null)  // pseudo directry entry
 94.2230 +            cinode = new IndexNode(cname, -1);
 94.2231 +        cinode.sibling = pinode.child;
 94.2232 +        pinode.child = cinode;
 94.2233 +
 94.2234 +        dirs.put(child, cinode);
 94.2235 +        return cinode;
 94.2236 +    }
 94.2237 +
 94.2238 +    private HashMap<EntryName, IndexNode> getDirs()
 94.2239 +        throws IOException
 94.2240 +    {
 94.2241 +        if (hasUpdate)
 94.2242 +            sync();
 94.2243 +        if (dirs != null)
 94.2244 +            return dirs;
 94.2245 +        dirs = new HashMap<EntryName, IndexNode>();
 94.2246 +        byte[] empty = new byte[0];
 94.2247 +        root = new IndexNode(empty, -1);
 94.2248 +        dirs.put(new EntryName(empty), root);
 94.2249 +
 94.2250 +        EntryName[] names = inodes.keySet().toArray(new EntryName[0]);
 94.2251 +        int i = names.length;
 94.2252 +        while (--i >= 0) {
 94.2253 +            addToDir(names[i]);
 94.2254 +        }
 94.2255 +        // for (int i EntryName en : inodes.keySet()) {
 94.2256 +        //     addToDir(en);
 94.2257 +        // }
 94.2258 +        return dirs;
 94.2259 +    }
 94.2260 +}
    95.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    95.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystemProvider.java	Tue Oct 12 12:51:48 2010 -0700
    95.3 @@ -0,0 +1,152 @@
    95.4 +/*
    95.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
    95.6 + *
    95.7 + * Redistribution and use in source and binary forms, with or without
    95.8 + * modification, are permitted provided that the following conditions
    95.9 + * are met:
   95.10 + *
   95.11 + *   - Redistributions of source code must retain the above copyright
   95.12 + *     notice, this list of conditions and the following disclaimer.
   95.13 + *
   95.14 + *   - Redistributions in binary form must reproduce the above copyright
   95.15 + *     notice, this list of conditions and the following disclaimer in the
   95.16 + *     documentation and/or other materials provided with the distribution.
   95.17 + *
   95.18 + *   - Neither the name of Oracle nor the names of its
   95.19 + *     contributors may be used to endorse or promote products derived
   95.20 + *     from this software without specific prior written permission.
   95.21 + *
   95.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
   95.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   95.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   95.25 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   95.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   95.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   95.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   95.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   95.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   95.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   95.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   95.33 + */
   95.34 +
   95.35 +package com.sun.nio.zipfs;
   95.36 +
   95.37 +import java.io.IOException;
   95.38 +import java.nio.channels.FileChannel;
   95.39 +import java.nio.file.FileRef;
   95.40 +import java.nio.file.FileSystem;
   95.41 +import java.nio.file.FileSystemNotFoundException;
   95.42 +import java.nio.file.FileSystemAlreadyExistsException;
   95.43 +import java.nio.file.OpenOption;
   95.44 +import java.nio.file.Path;
   95.45 +import java.nio.file.Paths;
   95.46 +import java.nio.file.ProviderMismatchException;
   95.47 +import java.nio.file.attribute.FileAttribute;
   95.48 +import java.nio.file.spi.FileSystemProvider;
   95.49 +import java.net.URI;
   95.50 +import java.net.URISyntaxException;
   95.51 +import java.util.HashMap;
   95.52 +import java.util.Map;
   95.53 +import java.util.Set;
   95.54 +
   95.55 +/*
   95.56 + *
   95.57 + * @author  Xueming Shen, Rajendra Gutupalli, Jaya Hangal
   95.58 + */
   95.59 +
   95.60 +public class ZipFileSystemProvider extends FileSystemProvider {
   95.61 +    private final Map<Path, ZipFileSystem> filesystems = new HashMap<>();
   95.62 +
   95.63 +    public ZipFileSystemProvider() {}
   95.64 +
   95.65 +    @Override
   95.66 +    public String getScheme() {
   95.67 +        return "zip";
   95.68 +    }
   95.69 +
   95.70 +    protected Path uriToPath(URI uri) {
   95.71 +        String scheme = uri.getScheme();
   95.72 +        if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) {
   95.73 +            throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'");
   95.74 +        }
   95.75 +        try {
   95.76 +            return Paths.get(new URI("file", uri.getHost(), uri.getPath(), null))
   95.77 +                        .toAbsolutePath();
   95.78 +        } catch (URISyntaxException e) {
   95.79 +            throw new AssertionError(e); //never thrown
   95.80 +        }
   95.81 +    }
   95.82 +
   95.83 +    @Override
   95.84 +    public FileSystem newFileSystem(URI uri, Map<String, ?> env)
   95.85 +        throws IOException
   95.86 +    {
   95.87 +        return newFileSystem(uriToPath(uri), env);
   95.88 +    }
   95.89 +
   95.90 +    @Override
   95.91 +    public FileSystem newFileSystem(FileRef file, Map<String, ?> env)
   95.92 +        throws IOException
   95.93 +    {
   95.94 +        if (!(file instanceof Path))
   95.95 +            throw new UnsupportedOperationException();
   95.96 +        Path path = (Path)file;
   95.97 +        if (!path.toUri().getScheme().equalsIgnoreCase("file")) {
   95.98 +            throw new UnsupportedOperationException();
   95.99 +        }
  95.100 +        return newFileSystem(path, env);
  95.101 +    }
  95.102 +
  95.103 +    private FileSystem newFileSystem(Path path, Map<String, ?> env)
  95.104 +        throws IOException
  95.105 +    {
  95.106 +        synchronized(filesystems) {
  95.107 +            if (filesystems.containsKey(path))
  95.108 +                throw new FileSystemAlreadyExistsException();
  95.109 +            ZipFileSystem zipfs = new ZipFileSystem(this, path, env);
  95.110 +            filesystems.put(path, zipfs);
  95.111 +            return zipfs;
  95.112 +        }
  95.113 +    }
  95.114 +
  95.115 +    @Override
  95.116 +    public Path getPath(URI uri) {
  95.117 +        FileSystem fs = getFileSystem(uri);
  95.118 +        String fragment = uri.getFragment();
  95.119 +        if (fragment == null) {
  95.120 +            throw new IllegalArgumentException("URI: "
  95.121 +                + uri
  95.122 +                + " does not contain path fragment ex. zip:///c:/foo.zip#/BAR");
  95.123 +        }
  95.124 +        return fs.getPath(fragment);
  95.125 +    }
  95.126 +
  95.127 +    @Override
  95.128 +    public FileChannel newFileChannel(Path path,
  95.129 +            Set<? extends OpenOption> options,
  95.130 +            FileAttribute<?>... attrs)
  95.131 +            throws IOException
  95.132 +    {
  95.133 +        if (path == null)
  95.134 +            throw new NullPointerException("path is null");
  95.135 +        if (path instanceof ZipPath)
  95.136 +            return ((ZipPath)path).newFileChannel(options, attrs);
  95.137 +        throw new ProviderMismatchException();
  95.138 +    }
  95.139 +
  95.140 +    @Override
  95.141 +    public FileSystem getFileSystem(URI uri) {
  95.142 +        synchronized (filesystems) {
  95.143 +            ZipFileSystem zipfs = filesystems.get(uriToPath(uri));
  95.144 +            if (zipfs == null)
  95.145 +                throw new FileSystemNotFoundException();
  95.146 +            return zipfs;
  95.147 +        }
  95.148 +    }
  95.149 +
  95.150 +    void removeFileSystem(Path zfpath) {
  95.151 +        synchronized (filesystems) {
  95.152 +            filesystems.remove(zfpath);
  95.153 +        }
  95.154 +    }
  95.155 +}
    96.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    96.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipInfo.java	Tue Oct 12 12:51:48 2010 -0700
    96.3 @@ -0,0 +1,132 @@
    96.4 +/*
    96.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
    96.6 + *
    96.7 + * Redistribution and use in source and binary forms, with or without
    96.8 + * modification, are permitted provided that the following conditions
    96.9 + * are met:
   96.10 + *
   96.11 + *   - Redistributions of source code must retain the above copyright
   96.12 + *     notice, this list of conditions and the following disclaimer.
   96.13 + *
   96.14 + *   - Redistributions in binary form must reproduce the above copyright
   96.15 + *     notice, this list of conditions and the following disclaimer in the
   96.16 + *     documentation and/or other materials provided with the distribution.
   96.17 + *
   96.18 + *   - Neither the name of Oracle nor the names of its
   96.19 + *     contributors may be used to endorse or promote products derived
   96.20 + *     from this software without specific prior written permission.
   96.21 + *
   96.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
   96.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   96.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   96.25 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   96.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   96.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   96.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   96.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   96.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   96.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   96.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   96.33 + */
   96.34 +
   96.35 +package com.sun.nio.zipfs;
   96.36 +
   96.37 +import java.io.PrintStream;
   96.38 +import java.nio.file.Paths;
   96.39 +import java.util.Collections;
   96.40 +import java.util.Iterator;
   96.41 +import java.util.Map;
   96.42 +import com.sun.nio.zipfs.ZipFileSystem.Entry;
   96.43 +import static com.sun.nio.zipfs.ZipConstants.*;
   96.44 +import static com.sun.nio.zipfs.ZipUtils.*;
   96.45 +
   96.46 +/**
   96.47 + * Print the loc and cen tables of the ZIP file
   96.48 + *
   96.49 + * @author  Xueming Shen
   96.50 + */
   96.51 +
   96.52 +public class ZipInfo {
   96.53 +
   96.54 +    public static void main(String[] args) throws Throwable {
   96.55 +        if (args.length < 2) {
   96.56 +            print("Usage: java ZipInfo [cen|loc] zfname");
   96.57 +        } else {
   96.58 +            Map<String, ?> env = Collections.emptyMap();
   96.59 +            ZipFileSystem zfs = (ZipFileSystem)(new ZipFileSystemProvider()
   96.60 +                                    .newFileSystem(Paths.get(args[1]), env));
   96.61 +
   96.62 +            long pos = 0;
   96.63 +
   96.64 +            if ("loc".equals(args[0])) {
   96.65 +                print("[Local File Header]%n");
   96.66 +                byte[] buf = new byte[1024];
   96.67 +                for (int i = 0; i < zfs.getEntryNames().length; i++) {
   96.68 +                    Entry loc = Entry.readLOC(zfs, pos, buf);
   96.69 +                    print("--------loc[%x]--------%n", pos);
   96.70 +                    printLOC(loc);
   96.71 +                    pos = loc.endPos;
   96.72 +                }
   96.73 +            } if ("cen".equals(args[0])) {
   96.74 +                int i = 0;
   96.75 +                Iterator<ZipFileSystem.IndexNode> itr = zfs.inodes.values().iterator();
   96.76 +                print("[Central Directory Header]%n");
   96.77 +                while (itr.hasNext()) {
   96.78 +                    Entry cen = Entry.readCEN(zfs.cen, itr.next().pos);
   96.79 +                    print("--------cen[%d]--------%n", i);
   96.80 +                    printCEN(cen);
   96.81 +                    i++;
   96.82 +                }
   96.83 +            }
   96.84 +            zfs.close();
   96.85 +        }
   96.86 +    }
   96.87 +
   96.88 +    static void print(String fmt, Object... objs) {
   96.89 +        System.out.printf(fmt, objs);
   96.90 +    }
   96.91 +
   96.92 +    static void printLOC(Entry loc) {
   96.93 +        print("  [%x, %x]%n", loc.startPos, loc.endPos);
   96.94 +        print("  Signature   :     %8x%n", LOCSIG);
   96.95 +        print("  Version     :         %4x    [%d.%d]%n",
   96.96 +                  loc.version, loc. version/10, loc. version%10);
   96.97 +        print("  Flag        :         %4x%n", loc.flag);
   96.98 +        print("  Method      :         %4x%n", loc. method);
   96.99 +        print("  LastMTime   :     %8x    [%tc]%n",
  96.100 +                  loc.mtime, dosToJavaTime(loc.mtime));
  96.101 +        print("  CRC         :     %8x%n", loc.crc);
  96.102 +        print("  CSize       :     %8x%n", loc.csize);
  96.103 +        print("  Size        :     %8x%n", loc.size);
  96.104 +        print("  NameLength  :         %4x    [%s]%n",
  96.105 +                  loc.nlen, new String(loc.name));
  96.106 +        print("  ExtraLength :         %4x%n", loc.elen);
  96.107 +        if (loc.hasZip64)
  96.108 +            print(" *ZIP64*%n");
  96.109 +    }
  96.110 +
  96.111 +    static void printCEN(Entry cen) {
  96.112 +        print("  Signature   :     %08x%n", CENSIG);
  96.113 +        print("  VerMadeby   :         %4x    [%d.%d]%n",
  96.114 +                  cen.versionMade, cen.versionMade/10, cen.versionMade%10);
  96.115 +        print("  VerExtract  :         %4x    [%d.%d]%n",
  96.116 +                  cen.version, cen.version/10, cen.version%10);
  96.117 +        print("  Flag        :         %4x%n", cen.flag);
  96.118 +        print("  Method      :         %4x%n", cen.method);
  96.119 +        print("  LastMTime   :     %8x    [%tc]%n",
  96.120 +                  cen.mtime, dosToJavaTime(cen.mtime));
  96.121 +        print("  CRC         :     %8x%n", cen.crc);
  96.122 +        print("  CSize       :     %8x%n", cen.csize);
  96.123 +        print("  Size        :     %8x%n", cen.size);
  96.124 +        print("  NameLen     :         %4x    [%s]%n",
  96.125 +                  cen.nlen, new String(cen.name));
  96.126 +        print("  ExtraLen    :         %4x%n", cen.elen);
  96.127 +        print("  CommentLen  :         %4x%n", cen.clen);
  96.128 +        print("  DiskStart   :         %4x%n", cen.disk);
  96.129 +        print("  Attrs       :         %4x%n", cen.attrs);
  96.130 +        print("  AttrsEx     :     %8x%n", cen.attrsEx);
  96.131 +        print("  LocOff      :     %8x%n", cen.locoff);
  96.132 +        if (cen.hasZip64)
  96.133 +            print(" *ZIP64*%n");
  96.134 +    }
  96.135 +}
    97.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    97.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipPath.java	Tue Oct 12 12:51:48 2010 -0700
    97.3 @@ -0,0 +1,964 @@
    97.4 +/*
    97.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
    97.6 + *
    97.7 + * Redistribution and use in source and binary forms, with or without
    97.8 + * modification, are permitted provided that the following conditions
    97.9 + * are met:
   97.10 + *
   97.11 + *   - Redistributions of source code must retain the above copyright
   97.12 + *     notice, this list of conditions and the following disclaimer.
   97.13 + *
   97.14 + *   - Redistributions in binary form must reproduce the above copyright
   97.15 + *     notice, this list of conditions and the following disclaimer in the
   97.16 + *     documentation and/or other materials provided with the distribution.
   97.17 + *
   97.18 + *   - Neither the name of Oracle nor the names of its
   97.19 + *     contributors may be used to endorse or promote products derived
   97.20 + *     from this software without specific prior written permission.
   97.21 + *
   97.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
   97.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   97.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   97.25 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   97.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   97.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   97.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   97.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   97.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   97.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   97.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   97.33 + */
   97.34 +
   97.35 +package com.sun.nio.zipfs;
   97.36 +
   97.37 +import java.io.File;
   97.38 +import java.io.FilterInputStream;
   97.39 +import java.io.IOException;
   97.40 +import java.io.InputStream;
   97.41 +import java.io.OutputStream;
   97.42 +import java.net.URI;
   97.43 +import java.nio.ByteBuffer;
   97.44 +import java.nio.channels.FileChannel;
   97.45 +import java.nio.channels.SeekableByteChannel;
   97.46 +import java.nio.file.*;
   97.47 +import java.nio.file.DirectoryStream.Filter;
   97.48 +import java.nio.file.spi.FileSystemProvider;
   97.49 +import java.nio.file.attribute.BasicFileAttributeView;
   97.50 +import java.nio.file.attribute.FileAttribute;
   97.51 +import java.nio.file.attribute.FileAttributeView;
   97.52 +import java.nio.file.attribute.FileTime;
   97.53 +import java.util.*;
   97.54 +import java.util.regex.Matcher;
   97.55 +import java.util.regex.Pattern;
   97.56 +import static java.nio.file.StandardOpenOption.*;
   97.57 +import static java.nio.file.StandardCopyOption.*;
   97.58 +
   97.59 +/**
   97.60 + *
   97.61 + * @author  Xueming Shen, Rajendra Gutupalli,Jaya Hangal
   97.62 + */
   97.63 +
   97.64 +public class ZipPath extends Path {
   97.65 +
   97.66 +    private final ZipFileSystem zfs;
   97.67 +    private final byte[] path;
   97.68 +    private volatile int[] offsets;
   97.69 +    private int hashcode = 0;  // cached hashcode (created lazily)
   97.70 +
   97.71 +    ZipPath(ZipFileSystem zfs, byte[] path) {
   97.72 +        this(zfs, path, false);
   97.73 +    }
   97.74 +
   97.75 +    ZipPath(ZipFileSystem zfs, byte[] path, boolean normalized)
   97.76 +    {
   97.77 +        this.zfs = zfs;
   97.78 +        if (normalized)
   97.79 +            this.path = path;
   97.80 +        else
   97.81 +            this.path = normalize(path);
   97.82 +    }
   97.83 +
   97.84 +    @Override
   97.85 +    public ZipPath getRoot() {
   97.86 +        if (this.isAbsolute())
   97.87 +            return new ZipPath(zfs, new byte[]{path[0]});
   97.88 +        else
   97.89 +            return null;
   97.90 +    }
   97.91 +
   97.92 +    @Override
   97.93 +    public Path getName() {
   97.94 +        initOffsets();
   97.95 +        int count = offsets.length;
   97.96 +        if (count == 0)
   97.97 +            return null;  // no elements so no name
   97.98 +        if (count == 1 && path[0] != '/')
   97.99 +            return this;
  97.100 +        int lastOffset = offsets[count-1];
  97.101 +        int len = path.length - lastOffset;
  97.102 +        byte[] result = new byte[len];
  97.103 +        System.arraycopy(path, lastOffset, result, 0, len);
  97.104 +        return new ZipPath(zfs, result);
  97.105 +    }
  97.106 +
  97.107 +    @Override
  97.108 +    public ZipPath getParent() {
  97.109 +        initOffsets();
  97.110 +        int count = offsets.length;
  97.111 +        if (count == 0)    // no elements so no parent
  97.112 +            return null;
  97.113 +        int len = offsets[count-1] - 1;
  97.114 +        if (len <= 0)      // parent is root only (may be null)
  97.115 +            return getRoot();
  97.116 +        byte[] result = new byte[len];
  97.117 +        System.arraycopy(path, 0, result, 0, len);
  97.118 +        return new ZipPath(zfs, result);
  97.119 +    }
  97.120 +
  97.121 +    @Override
  97.122 +    public int getNameCount() {
  97.123 +        initOffsets();
  97.124 +        return offsets.length;
  97.125 +    }
  97.126 +
  97.127 +    @Override
  97.128 +    public ZipPath getName(int index) {
  97.129 +        initOffsets();
  97.130 +        if (index < 0 || index >= offsets.length)
  97.131 +            throw new IllegalArgumentException();
  97.132 +        int begin = offsets[index];
  97.133 +        int len;
  97.134 +        if (index == (offsets.length-1))
  97.135 +            len = path.length - begin;
  97.136 +        else
  97.137 +            len = offsets[index+1] - begin - 1;
  97.138 +        // construct result
  97.139 +        byte[] result = new byte[len];
  97.140 +        System.arraycopy(path, begin, result, 0, len);
  97.141 +        return new ZipPath(zfs, result);
  97.142 +    }
  97.143 +
  97.144 +    @Override
  97.145 +    public ZipPath subpath(int beginIndex, int endIndex) {
  97.146 +        initOffsets();
  97.147 +        if (beginIndex < 0 ||
  97.148 +            beginIndex >=  offsets.length ||
  97.149 +            endIndex > offsets.length ||
  97.150 +            beginIndex >= endIndex)
  97.151 +            throw new IllegalArgumentException();
  97.152 +
  97.153 +        // starting offset and length
  97.154 +        int begin = offsets[beginIndex];
  97.155 +        int len;
  97.156 +        if (endIndex == offsets.length)
  97.157 +            len = path.length - begin;
  97.158 +        else
  97.159 +            len = offsets[endIndex] - begin - 1;
  97.160 +        // construct result
  97.161 +        byte[] result = new byte[len];
  97.162 +        System.arraycopy(path, begin, result, 0, len);
  97.163 +        return new ZipPath(zfs, result);
  97.164 +    }
  97.165 +
  97.166 +    @Override
  97.167 +    public ZipPath toRealPath(boolean resolveLinks) throws IOException {
  97.168 +        ZipPath realPath = new ZipPath(zfs, getResolvedPath());
  97.169 +        realPath.checkAccess();
  97.170 +        return realPath;
  97.171 +    }
  97.172 +
  97.173 +    @Override
  97.174 +    public boolean isHidden() {
  97.175 +        return false;
  97.176 +    }
  97.177 +
  97.178 +    @Override
  97.179 +    public ZipPath toAbsolutePath() {
  97.180 +        if (isAbsolute()) {
  97.181 +            return this;
  97.182 +        } else {
  97.183 +            //add / bofore the existing path
  97.184 +            byte[] defaultdir = zfs.getDefaultDir().path;
  97.185 +            int defaultlen = defaultdir.length;
  97.186 +            boolean endsWith = (defaultdir[defaultlen - 1] == '/');
  97.187 +            byte[] t = null;
  97.188 +            if (endsWith)
  97.189 +                t = new byte[defaultlen + path.length];
  97.190 +            else
  97.191 +                t = new byte[defaultlen + 1 + path.length];
  97.192 +            System.arraycopy(defaultdir, 0, t, 0, defaultlen);
  97.193 +            if (!endsWith)
  97.194 +                t[defaultlen++] = '/';
  97.195 +            System.arraycopy(path, 0, t, defaultlen, path.length);
  97.196 +            return new ZipPath(zfs, t, true);  // normalized
  97.197 +        }
  97.198 +    }
  97.199 +
  97.200 +    @Override
  97.201 +    public URI toUri() {
  97.202 +        String zfPath = zfs.toString();
  97.203 +        if (File.separatorChar == '\\')  // replace all separators by '/'
  97.204 +            zfPath = "/" + zfPath.replace("\\", "/");
  97.205 +        try {
  97.206 +            return new URI("zip", "",
  97.207 +                           zfPath,
  97.208 +                           zfs.getString(toAbsolutePath().path));
  97.209 +        } catch (Exception ex) {
  97.210 +            throw new AssertionError(ex);
  97.211 +        }
  97.212 +    }
  97.213 +
  97.214 +    private boolean equalsNameAt(ZipPath other, int index) {
  97.215 +        int mbegin = offsets[index];
  97.216 +        int mlen = 0;
  97.217 +        if (index == (offsets.length-1))
  97.218 +            mlen = path.length - mbegin;
  97.219 +        else
  97.220 +            mlen = offsets[index + 1] - mbegin - 1;
  97.221 +        int obegin = other.offsets[index];
  97.222 +        int olen = 0;
  97.223 +        if (index == (other.offsets.length - 1))
  97.224 +            olen = other.path.length - obegin;
  97.225 +        else
  97.226 +            olen = other.offsets[index + 1] - obegin - 1;
  97.227 +        if (mlen != olen)
  97.228 +            return false;
  97.229 +        int n = 0;
  97.230 +        while(n < mlen) {
  97.231 +            if (path[mbegin + n] != other.path[obegin + n])
  97.232 +                return false;
  97.233 +            n++;
  97.234 +        }
  97.235 +        return true;
  97.236 +    }
  97.237 +
  97.238 +    @Override
  97.239 +    public Path relativize(Path other) {
  97.240 +        final ZipPath o = checkPath(other);
  97.241 +        if (o.equals(this))
  97.242 +            return null;
  97.243 +        if (/* this.getFileSystem() != o.getFileSystem() || */
  97.244 +            this.isAbsolute() != o.isAbsolute()) {
  97.245 +            throw new IllegalArgumentException();
  97.246 +        }
  97.247 +        int mc = this.getNameCount();
  97.248 +        int oc = o.getNameCount();
  97.249 +        int n = Math.min(mc, oc);
  97.250 +        int i = 0;
  97.251 +        while (i < n) {
  97.252 +            if (!equalsNameAt(o, i))
  97.253 +                break;
  97.254 +            i++;
  97.255 +        }
  97.256 +        int dotdots = mc - i;
  97.257 +        int len = dotdots * 3 - 1;
  97.258 +        if (i < oc)
  97.259 +            len += (o.path.length - o.offsets[i] + 1);
  97.260 +        byte[] result = new byte[len];
  97.261 +
  97.262 +        int pos = 0;
  97.263 +        while (dotdots > 0) {
  97.264 +            result[pos++] = (byte)'.';
  97.265 +            result[pos++] = (byte)'.';
  97.266 +            if (pos < len)       // no tailing slash at the end
  97.267 +                result[pos++] = (byte)'/';
  97.268 +            dotdots--;
  97.269 +        }
  97.270 +        if (i < oc)
  97.271 +            System.arraycopy(o.path, o.offsets[i],
  97.272 +                             result, pos,
  97.273 +                             o.path.length - o.offsets[i]);
  97.274 +        return new ZipPath(getFileSystem(), result);
  97.275 +    }
  97.276 +
  97.277 +    @Override
  97.278 +    public ZipFileSystem getFileSystem() {
  97.279 +        return zfs;
  97.280 +    }
  97.281 +
  97.282 +    @Override
  97.283 +    public boolean isAbsolute() {
  97.284 +        return (this.path[0] == '/');
  97.285 +    }
  97.286 +
  97.287 +    @Override
  97.288 +    public ZipPath resolve(Path other) {
  97.289 +        if (other == null)
  97.290 +            return this;
  97.291 +        final ZipPath o = checkPath(other);
  97.292 +        if (o.isAbsolute())
  97.293 +            return o;
  97.294 +        byte[] resolved = null;
  97.295 +        if (this.path[path.length - 1] == '/') {
  97.296 +            resolved = new byte[path.length + o.path.length];
  97.297 +            System.arraycopy(path, 0, resolved, 0, path.length);
  97.298 +            System.arraycopy(o.path, 0, resolved, path.length, o.path.length);
  97.299 +        } else {
  97.300 +            resolved = new byte[path.length + 1 + o.path.length];
  97.301 +            System.arraycopy(path, 0, resolved, 0, path.length);
  97.302 +            resolved[path.length] = '/';
  97.303 +            System.arraycopy(o.path, 0, resolved, path.length + 1, o.path.length);
  97.304 +        }
  97.305 +        return new ZipPath(zfs, resolved);
  97.306 +    }
  97.307 +
  97.308 +    @Override
  97.309 +    public ZipPath resolve(String other) {
  97.310 +        return resolve(getFileSystem().getPath(other));
  97.311 +    }
  97.312 +
  97.313 +    @Override
  97.314 +    public boolean startsWith(Path other) {
  97.315 +        final ZipPath o = checkPath(other);
  97.316 +        if (o.isAbsolute() != this.isAbsolute())
  97.317 +            return false;
  97.318 +        final int oCount = o.getNameCount();
  97.319 +        if (getNameCount() < oCount)
  97.320 +            return false;
  97.321 +        for (int i = 0; i < oCount; i++) {
  97.322 +            if (!o.getName(i).equals(getName(i)))
  97.323 +                return false;
  97.324 +        }
  97.325 +        return true;
  97.326 +    }
  97.327 +
  97.328 +    @Override
  97.329 +    public boolean endsWith(Path other) {
  97.330 +        final ZipPath o = checkPath(other);
  97.331 +        if (o.isAbsolute())
  97.332 +            return this.isAbsolute() ? this.equals(o) : false;
  97.333 +        int i = o.getNameCount();
  97.334 +        int j = this.getNameCount();
  97.335 +        if (j < i)
  97.336 +            return false;
  97.337 +        for (--i, --j; i >= 0; i--, j--) {
  97.338 +            if (!o.getName(i).equals(this.getName(j)))
  97.339 +                return false;
  97.340 +        }
  97.341 +        return true;
  97.342 +    }
  97.343 +
  97.344 +    @Override
  97.345 +    public Path normalize() {
  97.346 +        byte[] resolved = getResolved();
  97.347 +        if (resolved == path)    // no change
  97.348 +            return this;
  97.349 +        if (resolved.length == 0)
  97.350 +            return null;
  97.351 +        return new ZipPath(zfs, resolved, true);
  97.352 +    }
  97.353 +
  97.354 +    private ZipPath checkPath(Path path) {
  97.355 +        if (path == null)
  97.356 +            throw new NullPointerException();
  97.357 +        if (!(path instanceof ZipPath))
  97.358 +            throw new ProviderMismatchException();
  97.359 +        return (ZipPath) path;
  97.360 +    }
  97.361 +
  97.362 +    // create offset list if not already created
  97.363 +    private void initOffsets() {
  97.364 +        if (offsets == null) {
  97.365 +            int count, index;
  97.366 +            // count names
  97.367 +            count = 0;
  97.368 +            index = 0;
  97.369 +            while (index < path.length) {
  97.370 +                byte c = path[index++];
  97.371 +                if (c != '/') {
  97.372 +                    count++;
  97.373 +                    while (index < path.length && path[index] != '/')
  97.374 +                        index++;
  97.375 +                }
  97.376 +            }
  97.377 +            // populate offsets
  97.378 +            int[] result = new int[count];
  97.379 +            count = 0;
  97.380 +            index = 0;
  97.381 +            while (index < path.length) {
  97.382 +                byte c = path[index];
  97.383 +                if (c == '/') {
  97.384 +                    index++;
  97.385 +                } else {
  97.386 +                    result[count++] = index++;
  97.387 +                    while (index < path.length && path[index] != '/')
  97.388 +                        index++;
  97.389 +                }
  97.390 +            }
  97.391 +            synchronized (this) {
  97.392 +                if (offsets == null)
  97.393 +                    offsets = result;
  97.394 +            }
  97.395 +        }
  97.396 +    }
  97.397 +
  97.398 +    // resolved path for locating zip entry inside the zip file,
  97.399 +    // the result path does not contain ./ and .. components
  97.400 +    private volatile byte[] resolved = null;
  97.401 +    byte[] getResolvedPath() {
  97.402 +        byte[] r = resolved;
  97.403 +        if (r == null) {
  97.404 +            if (isAbsolute())
  97.405 +                r = getResolved();
  97.406 +            else
  97.407 +                r = toAbsolutePath().getResolvedPath();
  97.408 +            if (r[0] == '/')
  97.409 +                r = Arrays.copyOfRange(r, 1, r.length);
  97.410 +            resolved = r;
  97.411 +        }
  97.412 +        return resolved;
  97.413 +    }
  97.414 +
  97.415 +    // removes redundant slashs, replace "\" to zip separator "/"
  97.416 +    // and check for invalid characters
  97.417 +    private byte[] normalize(byte[] path) {
  97.418 +        if (path.length == 0)
  97.419 +            return path;
  97.420 +        byte prevC = 0;
  97.421 +        for (int i = 0; i < path.length; i++) {
  97.422 +            byte c = path[i];
  97.423 +            if (c == '\\')
  97.424 +                return normalize(path, i);
  97.425 +            if (c == (byte)'/' && prevC == '/')
  97.426 +                return normalize(path, i - 1);
  97.427 +            if (c == '\u0000')
  97.428 +                throw new InvalidPathException(zfs.getString(path),
  97.429 +                                               "Path: nul character not allowed");
  97.430 +            prevC = c;
  97.431 +        }
  97.432 +        return path;
  97.433 +    }
  97.434 +
  97.435 +    private byte[] normalize(byte[] path, int off) {
  97.436 +        byte[] to = new byte[path.length];
  97.437 +        int n = 0;
  97.438 +        while (n < off) {
  97.439 +            to[n] = path[n];
  97.440 +            n++;
  97.441 +        }
  97.442 +        int m = n;
  97.443 +        byte prevC = 0;
  97.444 +        while (n < path.length) {
  97.445 +            byte c = path[n++];
  97.446 +            if (c == (byte)'\\')
  97.447 +                c = (byte)'/';
  97.448 +            if (c == (byte)'/' && prevC == (byte)'/')
  97.449 +                continue;
  97.450 +            if (c == '\u0000')
  97.451 +                throw new InvalidPathException(zfs.getString(path),
  97.452 +                                               "Path: nul character not allowed");
  97.453 +            to[m++] = c;
  97.454 +            prevC = c;
  97.455 +        }
  97.456 +        if (m > 1 && to[m - 1] == '/')
  97.457 +            m--;
  97.458 +        return (m == to.length)? to : Arrays.copyOf(to, m);
  97.459 +    }
  97.460 +
  97.461 +    // Remove DotSlash(./) and resolve DotDot (..) components
  97.462 +    private byte[] getResolved() {
  97.463 +        if (path.length == 0)
  97.464 +            return path;
  97.465 +        for (int i = 0; i < path.length; i++) {
  97.466 +            byte c = path[i];
  97.467 +            if (c == (byte)'.')
  97.468 +                return resolve0();
  97.469 +        }
  97.470 +        return path;
  97.471 +    }
  97.472 +
  97.473 +    // TBD: performance, avoid initOffsets
  97.474 +    private byte[] resolve0() {
  97.475 +        byte[] to = new byte[path.length];
  97.476 +        int nc = getNameCount();
  97.477 +        int[] lastM = new int[nc];
  97.478 +        int lastMOff = -1;
  97.479 +        int m = 0;
  97.480 +        for (int i = 0; i < nc; i++) {
  97.481 +            int n = offsets[i];
  97.482 +            int len = (i == offsets.length - 1)?
  97.483 +                      (path.length - n):(offsets[i + 1] - n - 1);
  97.484 +            if (len == 1 && path[n] == (byte)'.')
  97.485 +                continue;
  97.486 +            if (len == 2 && path[n] == '.' && path[n + 1] == '.') {
  97.487 +                if (lastMOff >= 0) {
  97.488 +                    m = lastM[lastMOff--];  // retreat
  97.489 +                    continue;
  97.490 +                }
  97.491 +                if (path[0] == '/') {  // "/../xyz" skip
  97.492 +                    if (m == 0)
  97.493 +                        to[m++] = '/';
  97.494 +                } else {               // "../xyz" -> "../xyz"
  97.495 +                    if (m != 0 && to[m-1] != '/')
  97.496 +                        to[m++] = '/';
  97.497 +                    while (len-- > 0)
  97.498 +                        to[m++] = path[n++];
  97.499 +                }
  97.500 +                continue;
  97.501 +            }
  97.502 +            if (m == 0 && path[0] == '/' ||   // absolute path
  97.503 +                m != 0 && to[m-1] != '/') {   // not the first name
  97.504 +                to[m++] = '/';
  97.505 +            }
  97.506 +            lastM[++lastMOff] = m;
  97.507 +            while (len-- > 0)
  97.508 +                to[m++] = path[n++];
  97.509 +        }
  97.510 +        if (m > 1 && to[m - 1] == '/')
  97.511 +            m--;
  97.512 +        return (m == to.length)? to : Arrays.copyOf(to, m);
  97.513 +    }
  97.514 +
  97.515 +    @Override
  97.516 +    public String toString() {
  97.517 +        return zfs.getString(path);
  97.518 +    }
  97.519 +
  97.520 +    @Override
  97.521 +    public int hashCode() {
  97.522 +        int h = hashcode;
  97.523 +        if (h == 0)
  97.524 +            hashcode = h = Arrays.hashCode(path);
  97.525 +        return h;
  97.526 +    }
  97.527 +
  97.528 +    @Override
  97.529 +    public boolean equals(Object obj) {
  97.530 +        return obj != null &&
  97.531 +               obj instanceof ZipPath &&
  97.532 +               this.zfs == ((ZipPath)obj).zfs &&
  97.533 +               compareTo((Path) obj) == 0;
  97.534 +    }
  97.535 +
  97.536 +    @Override
  97.537 +    public int compareTo(Path other) {
  97.538 +        final ZipPath o = checkPath(other);
  97.539 +        int len1 = this.path.length;
  97.540 +        int len2 = o.path.length;
  97.541 +
  97.542 +        int n = Math.min(len1, len2);
  97.543 +        byte v1[] = this.path;
  97.544 +        byte v2[] = o.path;
  97.545 +
  97.546 +        int k = 0;
  97.547 +        while (k < n) {
  97.548 +            int c1 = v1[k] & 0xff;
  97.549 +            int c2 = v2[k] & 0xff;
  97.550 +            if (c1 != c2)
  97.551 +                return c1 - c2;
  97.552 +            k++;
  97.553 +        }
  97.554 +        return len1 - len2;
  97.555 +    }
  97.556 +
  97.557 +    @Override
  97.558 +    public Path createSymbolicLink(
  97.559 +            Path target, FileAttribute<?>... attrs) throws IOException {
  97.560 +        throw new UnsupportedOperationException("Not supported.");
  97.561 +    }
  97.562 +
  97.563 +    @Override
  97.564 +    public Path createLink(
  97.565 +            Path existing) throws IOException {
  97.566 +        throw new UnsupportedOperationException("Not supported.");
  97.567 +    }
  97.568 +
  97.569 +    @Override
  97.570 +    public Path readSymbolicLink() throws IOException {
  97.571 +        throw new UnsupportedOperationException("Not supported.");
  97.572 +    }
  97.573 +
  97.574 +    @Override
  97.575 +    public Path createDirectory(FileAttribute<?>... attrs)
  97.576 +        throws IOException
  97.577 +    {
  97.578 +        zfs.createDirectory(getResolvedPath(), attrs);
  97.579 +        return this;
  97.580 +    }
  97.581 +
  97.582 +    public final Path createFile(FileAttribute<?>... attrs)
  97.583 +        throws IOException
  97.584 +    {
  97.585 +        OutputStream os = newOutputStream(CREATE_NEW, WRITE);
  97.586 +        try {
  97.587 +            os.close();
  97.588 +        } catch (IOException x) {}
  97.589 +        return this;
  97.590 +    }
  97.591 +
  97.592 +    @Override
  97.593 +    public InputStream newInputStream(OpenOption... options)
  97.594 +            throws IOException {
  97.595 +        if (options.length > 0) {
  97.596 +            for (OpenOption opt : options) {
  97.597 +                if (opt != READ)
  97.598 +                    throw new UnsupportedOperationException("'" + opt + "' not allowed");
  97.599 +            }
  97.600 +        }
  97.601 +        return zfs.newInputStream(getResolvedPath());
  97.602 +    }
  97.603 +
  97.604 +    private static final DirectoryStream.Filter<Path> acceptAllFilter =
  97.605 +        new DirectoryStream.Filter<Path>() {
  97.606 +            @Override public boolean accept(Path entry) { return true; }
  97.607 +        };
  97.608 +
  97.609 +    @Override
  97.610 +    public final DirectoryStream<Path> newDirectoryStream() throws IOException {
  97.611 +        return newDirectoryStream(acceptAllFilter);
  97.612 +    }
  97.613 +
  97.614 +    @Override
  97.615 +    public DirectoryStream<Path> newDirectoryStream(Filter<? super Path> filter)
  97.616 +        throws IOException
  97.617 +    {
  97.618 +        return new ZipDirectoryStream(this, filter);
  97.619 +    }
  97.620 +
  97.621 +    @Override
  97.622 +    public final DirectoryStream<Path> newDirectoryStream(String glob)
  97.623 +        throws IOException
  97.624 +    {
  97.625 +        // avoid creating a matcher if all entries are required.
  97.626 +        if (glob.equals("*"))
  97.627 +            return newDirectoryStream();
  97.628 +
  97.629 +        // create a matcher and return a filter that uses it.
  97.630 +        final PathMatcher matcher = getFileSystem().getPathMatcher("glob:" + glob);
  97.631 +        DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
  97.632 +            @Override
  97.633 +            public boolean accept(Path entry)  {
  97.634 +                return matcher.matches(entry.getName());
  97.635 +            }
  97.636 +        };
  97.637 +        return newDirectoryStream(filter);
  97.638 +    }
  97.639 +
  97.640 +    @Override
  97.641 +    public final void delete() throws IOException {
  97.642 +        zfs.deleteFile(getResolvedPath(), true);
  97.643 +    }
  97.644 +
  97.645 +    @Override
  97.646 +    public final void deleteIfExists() throws IOException {
  97.647 +        zfs.deleteFile(getResolvedPath(), false);
  97.648 +    }
  97.649 +
  97.650 +    ZipFileAttributes getAttributes() throws IOException
  97.651 +    {
  97.652 +        ZipFileAttributes zfas = zfs.getFileAttributes(getResolvedPath());
  97.653 +        if (zfas == null)
  97.654 +            throw new NoSuchFileException(toString());
  97.655 +        return zfas;
  97.656 +    }
  97.657 +
  97.658 +    @Override
  97.659 +    @SuppressWarnings("unchecked")
  97.660 +    public <V extends FileAttributeView> V getFileAttributeView(Class<V> type,
  97.661 +                                                                LinkOption... options)
  97.662 +    {
  97.663 +        return (V)ZipFileAttributeView.get(this, type);
  97.664 +    }
  97.665 +
  97.666 +    @Override
  97.667 +    public void setAttribute(String attribute,
  97.668 +                             Object value,
  97.669 +                             LinkOption... options)
  97.670 +        throws IOException
  97.671 +    {
  97.672 +        String type = null;
  97.673 +        String attr = null;
  97.674 +        int colonPos = attribute.indexOf(':');
  97.675 +        if (colonPos == -1) {
  97.676 +            type = "basic";
  97.677 +            attr = attribute;
  97.678 +        } else {
  97.679 +            type = attribute.substring(0, colonPos++);
  97.680 +            attr = attribute.substring(colonPos);
  97.681 +        }
  97.682 +        ZipFileAttributeView view = ZipFileAttributeView.get(this, type);
  97.683 +        if (view == null)
  97.684 +            throw new UnsupportedOperationException("view <" + view + "> is not supported");
  97.685 +        view.setAttribute(attr, value);
  97.686 +    }
  97.687 +
  97.688 +    void setTimes(FileTime mtime, FileTime atime, FileTime ctime)
  97.689 +        throws IOException
  97.690 +    {
  97.691 +        zfs.setTimes(getResolvedPath(), mtime, atime, ctime);
  97.692 +    }
  97.693 +
  97.694 +    private Object getAttributesImpl(String attribute, boolean domap)
  97.695 +        throws IOException
  97.696 +    {
  97.697 +        String view = null;
  97.698 +        String attr = null;
  97.699 +        int colonPos = attribute.indexOf(':');
  97.700 +        if (colonPos == -1) {
  97.701 +            view = "basic";
  97.702 +            attr = attribute;
  97.703 +        } else {
  97.704 +            view = attribute.substring(0, colonPos++);
  97.705 +            attr = attribute.substring(colonPos);
  97.706 +        }
  97.707 +        ZipFileAttributeView zfv = ZipFileAttributeView.get(this, view);
  97.708 +        if (zfv == null) {
  97.709 +            throw new UnsupportedOperationException("view not supported");
  97.710 +        }
  97.711 +        return zfv.getAttribute(attr, domap);
  97.712 +    }
  97.713 +
  97.714 +    @Override
  97.715 +    public Object getAttribute(String attribute, LinkOption... options)
  97.716 +        throws IOException
  97.717 +    {
  97.718 +        return getAttributesImpl(attribute, false);
  97.719 +    }
  97.720 +
  97.721 +    @Override
  97.722 +    public Map<String,?> readAttributes(String attribute, LinkOption... options)
  97.723 +        throws IOException
  97.724 +    {
  97.725 +        return (Map<String, ?>)getAttributesImpl(attribute, true);
  97.726 +    }
  97.727 +
  97.728 +    @Override
  97.729 +    public FileStore getFileStore() throws IOException {
  97.730 +        // each ZipFileSystem only has one root (as requested for now)
  97.731 +        if (exists())
  97.732 +            return zfs.getFileStore(this);
  97.733 +        throw new NoSuchFileException(zfs.getString(path));
  97.734 +    }
  97.735 +
  97.736 +    @Override
  97.737 +    public boolean isSameFile(Path other) throws IOException {
  97.738 +        if (other == null ||
  97.739 +            this.getFileSystem() != other.getFileSystem())
  97.740 +            return false;
  97.741 +        this.checkAccess();
  97.742 +        other.checkAccess();
  97.743 +        return Arrays.equals(this.getResolvedPath(),
  97.744 +                             ((ZipPath)other).getResolvedPath());
  97.745 +    }
  97.746 +
  97.747 +    public WatchKey register(
  97.748 +            WatchService watcher,
  97.749 +            WatchEvent.Kind<?>[] events,
  97.750 +            WatchEvent.Modifier... modifiers) {
  97.751 +        if (watcher == null || events == null || modifiers == null) {
  97.752 +            throw new NullPointerException();
  97.753 +        }
  97.754 +        throw new UnsupportedOperationException();
  97.755 +    }
  97.756 +
  97.757 +    @Override
  97.758 +    public WatchKey register(WatchService watcher, WatchEvent.Kind<?>... events) {
  97.759 +        return register(watcher, events, new WatchEvent.Modifier[0]);
  97.760 +    }
  97.761 +
  97.762 +    @Override
  97.763 +    public Iterator<Path> iterator() {
  97.764 +        return new Iterator<Path>() {
  97.765 +            private int i = 0;
  97.766 +
  97.767 +            @Override
  97.768 +            public boolean hasNext() {
  97.769 +                return (i < getNameCount());
  97.770 +            }
  97.771 +
  97.772 +            @Override
  97.773 +            public Path next() {
  97.774 +                if (i < getNameCount()) {
  97.775 +                    Path result = getName(i);
  97.776 +                    i++;
  97.777 +                    return result;
  97.778 +                } else {
  97.779 +                    throw new NoSuchElementException();
  97.780 +                }
  97.781 +            }
  97.782 +
  97.783 +            @Override
  97.784 +            public void remove() {
  97.785 +                throw new ReadOnlyFileSystemException();
  97.786 +            }
  97.787 +        };
  97.788 +    }
  97.789 +
  97.790 +    @Override
  97.791 +    public SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
  97.792 +                                              FileAttribute<?>... attrs)
  97.793 +        throws IOException
  97.794 +    {
  97.795 +        return zfs.newByteChannel(getResolvedPath(), options, attrs);
  97.796 +    }
  97.797 +
  97.798 +
  97.799 +    FileChannel newFileChannel(Set<? extends OpenOption> options,
  97.800 +                               FileAttribute<?>... attrs)
  97.801 +        throws IOException
  97.802 +    {
  97.803 +        return zfs.newFileChannel(getResolvedPath(), options, attrs);
  97.804 +    }
  97.805 +
  97.806 +    @Override
  97.807 +    public SeekableByteChannel newByteChannel(OpenOption... options)
  97.808 +            throws IOException {
  97.809 +        Set<OpenOption> set = new HashSet<OpenOption>(options.length);
  97.810 +        Collections.addAll(set, options);
  97.811 +        return newByteChannel(set);
  97.812 +    }
  97.813 +
  97.814 +    @Override
  97.815 +    public void checkAccess(AccessMode... modes) throws IOException {
  97.816 +        boolean w = false;
  97.817 +        boolean x = false;
  97.818 +        for (AccessMode mode : modes) {
  97.819 +            switch (mode) {
  97.820 +                case READ:
  97.821 +                    break;
  97.822 +                case WRITE:
  97.823 +                    w = true;
  97.824 +                    break;
  97.825 +                case EXECUTE:
  97.826 +                    x = true;
  97.827 +                    break;
  97.828 +                default:
  97.829 +                    throw new UnsupportedOperationException();
  97.830 +            }
  97.831 +        }
  97.832 +        ZipFileAttributes attrs = zfs.getFileAttributes(getResolvedPath());
  97.833 +        if (attrs == null && (path.length != 1 || path[0] != '/'))
  97.834 +            throw new NoSuchFileException(toString());
  97.835 +        if (w) {
  97.836 +            if (zfs.isReadOnly())
  97.837 +                throw new AccessDeniedException(toString());
  97.838 +        }
  97.839 +        if (x)
  97.840 +            throw new AccessDeniedException(toString());
  97.841 +
  97.842 +    }
  97.843 +
  97.844 +    @Override
  97.845 +    public boolean exists() {
  97.846 +        if (path.length == 1 && path[0] == '/')
  97.847 +            return true;
  97.848 +        try {
  97.849 +            return zfs.exists(getResolvedPath());
  97.850 +        } catch (IOException x) {}
  97.851 +        return false;
  97.852 +    }
  97.853 +
  97.854 +    @Override
  97.855 +    public boolean notExists() {
  97.856 +        return !exists();
  97.857 +    }
  97.858 +
  97.859 +
  97.860 +    @Override
  97.861 +    public OutputStream newOutputStream(OpenOption... options)
  97.862 +        throws IOException
  97.863 +    {
  97.864 +        if (options.length == 0)
  97.865 +            return zfs.newOutputStream(getResolvedPath(),
  97.866 +                                       CREATE_NEW, WRITE);
  97.867 +        return zfs.newOutputStream(getResolvedPath(), options);
  97.868 +    }
  97.869 +
  97.870 +    @Override
  97.871 +    public Path moveTo(Path target, CopyOption... options)
  97.872 +        throws IOException
  97.873 +    {
  97.874 +        if (this.zfs.provider() == target.getFileSystem().provider() &&
  97.875 +            this.zfs.getZipFile().isSameFile(((ZipPath)target).zfs.getZipFile()))
  97.876 +        {
  97.877 +            zfs.copyFile(true,
  97.878 +                         getResolvedPath(),
  97.879 +                         ((ZipPath)target).getResolvedPath(),
  97.880 +                         options);
  97.881 +        } else {
  97.882 +            copyToTarget(target, options);
  97.883 +            delete();
  97.884 +        }
  97.885 +        return target;
  97.886 +    }
  97.887 +
  97.888 +    @Override
  97.889 +    public Path copyTo(Path target, CopyOption... options)
  97.890 +        throws IOException
  97.891 +    {
  97.892 +        if (this.zfs.provider() == target.getFileSystem().provider() &&
  97.893 +            this.zfs.getZipFile().isSameFile(((ZipPath)target).zfs.getZipFile()))
  97.894 +        {
  97.895 +            zfs.copyFile(false,
  97.896 +                         getResolvedPath(),
  97.897 +                         ((ZipPath)target).getResolvedPath(),
  97.898 +                         options);
  97.899 +        } else {
  97.900 +            copyToTarget(target, options);
  97.901 +        }
  97.902 +        return target;
  97.903 +    }
  97.904 +
  97.905 +    private void copyToTarget(Path target, CopyOption... options)
  97.906 +        throws IOException
  97.907 +    {
  97.908 +        boolean replaceExisting = false;
  97.909 +        boolean copyAttrs = false;
  97.910 +        for (CopyOption opt : options) {
  97.911 +            if (opt == REPLACE_EXISTING)
  97.912 +                replaceExisting = true;
  97.913 +            else if (opt == COPY_ATTRIBUTES)
  97.914 +                copyAttrs = false;
  97.915 +        }
  97.916 +        // attributes of source file
  97.917 +        ZipFileAttributes zfas = getAttributes();
  97.918 +        // check if target exists
  97.919 +        boolean exists;
  97.920 +        if (replaceExisting) {
  97.921 +            try {
  97.922 +                target.deleteIfExists();
  97.923 +                exists = false;
  97.924 +            } catch (DirectoryNotEmptyException x) {
  97.925 +                exists = true;
  97.926 +            }
  97.927 +        } else {
  97.928 +            exists = target.exists();
  97.929 +        }
  97.930 +        if (exists)
  97.931 +            throw new FileAlreadyExistsException(target.toString());
  97.932 +
  97.933 +        if (zfas.isDirectory()) {
  97.934 +            // create directory or file
  97.935 +            target.createDirectory();
  97.936 +        } else {
  97.937 +            InputStream is = zfs.newInputStream(getResolvedPath());
  97.938 +            try {
  97.939 +                OutputStream os = target.newOutputStream();
  97.940 +                try {
  97.941 +                    byte[] buf = new byte[8192];
  97.942 +                    int n = 0;
  97.943 +                    while ((n = is.read(buf)) != -1) {
  97.944 +                        os.write(buf, 0, n);
  97.945 +                    }
  97.946 +                } finally {
  97.947 +                    os.close();
  97.948 +                }
  97.949 +            } finally {
  97.950 +                is.close();
  97.951 +            }
  97.952 +        }
  97.953 +        if (copyAttrs) {
  97.954 +            BasicFileAttributeView view =
  97.955 +                target.getFileAttributeView(BasicFileAttributeView.class);
  97.956 +            try {
  97.957 +                view.setTimes(zfas.lastModifiedTime(), null, null);
  97.958 +            } catch (IOException x) {
  97.959 +                // rollback?
  97.960 +                try {
  97.961 +                    target.delete();
  97.962 +                } catch (IOException ignore) { }
  97.963 +                throw x;
  97.964 +            }
  97.965 +        }
  97.966 +    }
  97.967 +}
    98.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    98.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipUtils.java	Tue Oct 12 12:51:48 2010 -0700
    98.3 @@ -0,0 +1,289 @@
    98.4 +/*
    98.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
    98.6 + *
    98.7 + * Redistribution and use in source and binary forms, with or without
    98.8 + * modification, are permitted provided that the following conditions
    98.9 + * are met:
   98.10 + *
   98.11 + *   - Redistributions of source code must retain the above copyright
   98.12 + *     notice, this list of conditions and the following disclaimer.
   98.13 + *
   98.14 + *   - Redistributions in binary form must reproduce the above copyright
   98.15 + *     notice, this list of conditions and the following disclaimer in the
   98.16 + *     documentation and/or other materials provided with the distribution.
   98.17 + *
   98.18 + *   - Neither the name of Oracle nor the names of its
   98.19 + *     contributors may be used to endorse or promote products derived
   98.20 + *     from this software without specific prior written permission.
   98.21 + *
   98.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
   98.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   98.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   98.25 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   98.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   98.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   98.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   98.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   98.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   98.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   98.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   98.33 + */
   98.34 +
   98.35 +package com.sun.nio.zipfs;
   98.36 +
   98.37 +import java.io.IOException;
   98.38 +import java.io.OutputStream;
   98.39 +import java.util.Arrays;
   98.40 +import java.util.Date;
   98.41 +import java.util.regex.PatternSyntaxException;
   98.42 +
   98.43 +/**
   98.44 + *
   98.45 + * @author Xueming Shen
   98.46 + */
   98.47 +
   98.48 +class ZipUtils {
   98.49 +
   98.50 +    /*
   98.51 +     * Writes a 16-bit short to the output stream in little-endian byte order.
   98.52 +     */
   98.53 +    public static void writeShort(OutputStream os, int v) throws IOException {
   98.54 +        os.write((v >>> 0) & 0xff);
   98.55 +        os.write((v >>> 8) & 0xff);
   98.56 +    }
   98.57 +
   98.58 +    /*
   98.59 +     * Writes a 32-bit int to the output stream in little-endian byte order.
   98.60 +     */
   98.61 +    public static void writeInt(OutputStream os, long v) throws IOException {
   98.62 +        os.write((int)((v >>>  0) & 0xff));
   98.63 +        os.write((int)((v >>>  8) & 0xff));
   98.64 +        os.write((int)((v >>> 16) & 0xff));
   98.65 +        os.write((int)((v >>> 24) & 0xff));
   98.66 +    }
   98.67 +
   98.68 +    /*
   98.69 +     * Writes a 64-bit int to the output stream in little-endian byte order.
   98.70 +     */
   98.71 +    public static void writeLong(OutputStream os, long v) throws IOException {
   98.72 +        os.write((int)((v >>>  0) & 0xff));
   98.73 +        os.write((int)((v >>>  8) & 0xff));
   98.74 +        os.write((int)((v >>> 16) & 0xff));
   98.75 +        os.write((int)((v >>> 24) & 0xff));
   98.76 +        os.write((int)((v >>> 32) & 0xff));
   98.77 +        os.write((int)((v >>> 40) & 0xff));
   98.78 +        os.write((int)((v >>> 48) & 0xff));
   98.79 +        os.write((int)((v >>> 56) & 0xff));
   98.80 +    }
   98.81 +
   98.82 +    /*
   98.83 +     * Writes an array of bytes to the output stream.
   98.84 +     */
   98.85 +    public static void writeBytes(OutputStream os, byte[] b)
   98.86 +        throws IOException
   98.87 +    {
   98.88 +        os.write(b, 0, b.length);
   98.89 +    }
   98.90 +
   98.91 +    /*
   98.92 +     * Writes an array of bytes to the output stream.
   98.93 +     */
   98.94 +    public static void writeBytes(OutputStream os, byte[] b, int off, int len)
   98.95 +        throws IOException
   98.96 +    {
   98.97 +        os.write(b, off, len);
   98.98 +    }
   98.99 +
  98.100 +    /*
  98.101 +     * Append a slash at the end, if it does not have one yet
  98.102 +     */
  98.103 +    public static byte[] toDirectoryPath(byte[] dir) {
  98.104 +        if (dir.length != 0 && dir[dir.length - 1] != '/') {
  98.105 +            dir = Arrays.copyOf(dir, dir.length + 1);
  98.106 +            dir[dir.length - 1] = '/';
  98.107 +        }
  98.108 +        return dir;
  98.109 +    }
  98.110 +
  98.111 +    /*
  98.112 +     * Converts DOS time to Java time (number of milliseconds since epoch).
  98.113 +     */
  98.114 +    public static long dosToJavaTime(long dtime) {
  98.115 +        Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80),
  98.116 +                          (int)(((dtime >> 21) & 0x0f) - 1),
  98.117 +                          (int)((dtime >> 16) & 0x1f),
  98.118 +                          (int)((dtime >> 11) & 0x1f),
  98.119 +                          (int)((dtime >> 5) & 0x3f),
  98.120 +                          (int)((dtime << 1) & 0x3e));
  98.121 +        return d.getTime();
  98.122 +    }
  98.123 +
  98.124 +    /*
  98.125 +     * Converts Java time to DOS time.
  98.126 +     */
  98.127 +    public static long javaToDosTime(long time) {
  98.128 +        Date d = new Date(time);
  98.129 +        int year = d.getYear() + 1900;
  98.130 +        if (year < 1980) {
  98.131 +            return (1 << 21) | (1 << 16);
  98.132 +        }
  98.133 +        return (year - 1980) << 25 | (d.getMonth() + 1) << 21 |
  98.134 +               d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 |
  98.135 +               d.getSeconds() >> 1;
  98.136 +    }
  98.137 +
  98.138 +    private static final String regexMetaChars = ".^$+{[]|()";
  98.139 +    private static final String globMetaChars = "\\*?[{";
  98.140 +    private static boolean isRegexMeta(char c) {
  98.141 +        return regexMetaChars.indexOf(c) != -1;
  98.142 +    }
  98.143 +    private static boolean isGlobMeta(char c) {
  98.144 +        return globMetaChars.indexOf(c) != -1;
  98.145 +    }
  98.146 +    private static char EOL = 0;  //TBD
  98.147 +    private static char next(String glob, int i) {
  98.148 +        if (i < glob.length()) {
  98.149 +            return glob.charAt(i);
  98.150 +        }
  98.151 +        return EOL;
  98.152 +    }
  98.153 +
  98.154 +    /*
  98.155 +     * Creates a regex pattern from the given glob expression.
  98.156 +     *
  98.157 +     * @throws  PatternSyntaxException
  98.158 +     */
  98.159 +    public static String toRegexPattern(String globPattern) {
  98.160 +        boolean inGroup = false;
  98.161 +        StringBuilder regex = new StringBuilder("^");
  98.162 +
  98.163 +        int i = 0;
  98.164 +        while (i < globPattern.length()) {
  98.165 +            char c = globPattern.charAt(i++);
  98.166 +            switch (c) {
  98.167 +                case '\\':
  98.168 +                    // escape special characters
  98.169 +                    if (i == globPattern.length()) {
  98.170 +                        throw new PatternSyntaxException("No character to escape",
  98.171 +                                globPattern, i - 1);
  98.172 +                    }
  98.173 +                    char next = globPattern.charAt(i++);
  98.174 +                    if (isGlobMeta(next) || isRegexMeta(next)) {
  98.175 +                        regex.append('\\');
  98.176 +                    }
  98.177 +                    regex.append(next);
  98.178 +                    break;
  98.179 +                case '/':
  98.180 +                    regex.append(c);
  98.181 +                    break;
  98.182 +                case '[':
  98.183 +                    // don't match name separator in class
  98.184 +                    regex.append("[[^/]&&[");
  98.185 +                    if (next(globPattern, i) == '^') {
  98.186 +                        // escape the regex negation char if it appears
  98.187 +                        regex.append("\\^");
  98.188 +                        i++;
  98.189 +                    } else {
  98.190 +                        // negation
  98.191 +                        if (next(globPattern, i) == '!') {
  98.192 +                            regex.append('^');
  98.193 +                            i++;
  98.194 +                        }
  98.195 +                        // hyphen allowed at start
  98.196 +                        if (next(globPattern, i) == '-') {
  98.197 +                            regex.append('-');
  98.198 +                            i++;
  98.199 +                        }
  98.200 +                    }
  98.201 +                    boolean hasRangeStart = false;
  98.202 +                    char last = 0;
  98.203 +                    while (i < globPattern.length()) {
  98.204 +                        c = globPattern.charAt(i++);
  98.205 +                        if (c == ']') {
  98.206 +                            break;
  98.207 +                        }
  98.208 +                        if (c == '/') {
  98.209 +                            throw new PatternSyntaxException("Explicit 'name separator' in class",
  98.210 +                                    globPattern, i - 1);
  98.211 +                        }
  98.212 +                        // TBD: how to specify ']' in a class?
  98.213 +                        if (c == '\\' || c == '[' ||
  98.214 +                                c == '&' && next(globPattern, i) == '&') {
  98.215 +                            // escape '\', '[' or "&&" for regex class
  98.216 +                            regex.append('\\');
  98.217 +                        }
  98.218 +                        regex.append(c);
  98.219 +
  98.220 +                        if (c == '-') {
  98.221 +                            if (!hasRangeStart) {
  98.222 +                                throw new PatternSyntaxException("Invalid range",
  98.223 +                                        globPattern, i - 1);
  98.224 +                            }
  98.225 +                            if ((c = next(globPattern, i++)) == EOL || c == ']') {
  98.226 +                                break;
  98.227 +                            }
  98.228 +                            if (c < last) {
  98.229 +                                throw new PatternSyntaxException("Invalid range",
  98.230 +                                        globPattern, i - 3);
  98.231 +                            }
  98.232 +                            regex.append(c);
  98.233 +                            hasRangeStart = false;
  98.234 +                        } else {
  98.235 +                            hasRangeStart = true;
  98.236 +                            last = c;
  98.237 +                        }
  98.238 +                    }
  98.239 +                    if (c != ']') {
  98.240 +                        throw new PatternSyntaxException("Missing ']", globPattern, i - 1);
  98.241 +                    }
  98.242 +                    regex.append("]]");
  98.243 +                    break;
  98.244 +                case '{':
  98.245 +                    if (inGroup) {
  98.246 +                        throw new PatternSyntaxException("Cannot nest groups",
  98.247 +                                globPattern, i - 1);
  98.248 +                    }
  98.249 +                    regex.append("(?:(?:");
  98.250 +                    inGroup = true;
  98.251 +                    break;
  98.252 +                case '}':
  98.253 +                    if (inGroup) {
  98.254 +                        regex.append("))");
  98.255 +                        inGroup = false;
  98.256 +                    } else {
  98.257 +                        regex.append('}');
  98.258 +                    }
  98.259 +                    break;
  98.260 +                case ',':
  98.261 +                    if (inGroup) {
  98.262 +                        regex.append(")|(?:");
  98.263 +                    } else {
  98.264 +                        regex.append(',');
  98.265 +                    }
  98.266 +                    break;
  98.267 +                case '*':
  98.268 +                    if (next(globPattern, i) == '*') {
  98.269 +                        // crosses directory boundaries
  98.270 +                        regex.append(".*");
  98.271 +                        i++;
  98.272 +                    } else {
  98.273 +                        // within directory boundary
  98.274 +                        regex.append("[^/]*");
  98.275 +                    }
  98.276 +                    break;
  98.277 +                case '?':
  98.278 +                   regex.append("[^/]");
  98.279 +                   break;
  98.280 +                default:
  98.281 +                    if (isRegexMeta(c)) {
  98.282 +                        regex.append('\\');
  98.283 +                    }
  98.284 +                    regex.append(c);
  98.285 +            }
  98.286 +        }
  98.287 +        if (inGroup) {
  98.288 +            throw new PatternSyntaxException("Missing '}", globPattern, i - 1);
  98.289 +        }
  98.290 +        return regex.append('$').toString();
  98.291 +    }
  98.292 +}
    99.1 --- a/src/share/native/java/lang/System.c	Thu Oct 07 15:12:19 2010 -0700
    99.2 +++ b/src/share/native/java/lang/System.c	Tue Oct 12 12:51:48 2010 -0700
    99.3 @@ -97,14 +97,20 @@
    99.4      } else ((void) 0)
    99.5  
    99.6  #ifndef VENDOR /* Third party may overwrite this. */
    99.7 -#define VENDOR "Sun Microsystems Inc."
    99.8 -#define VENDOR_URL "http://java.sun.com/"
    99.9 +#define VENDOR "Oracle Corporation"
   99.10 +#define VENDOR_URL "http://java.oracle.com/"
   99.11  #define VENDOR_URL_BUG "http://java.sun.com/cgi-bin/bugreport.cgi"
   99.12  #endif
   99.13  
   99.14  #define JAVA_MAX_SUPPORTED_VERSION 51
   99.15  #define JAVA_MAX_SUPPORTED_MINOR_VERSION 0
   99.16  
   99.17 +#ifdef JAVA_SPECIFICATION_VENDOR /* Third party may NOT overwrite this. */
   99.18 +  #error "ERROR: No override of JAVA_SPECIFICATION_VENDOR is allowed"
   99.19 +#else
   99.20 +  #define JAVA_SPECIFICATION_VENDOR "Oracle Corporation"
   99.21 +#endif
   99.22 +
   99.23  static int fmtdefault; // boolean value
   99.24  jobject fillI18nProps(JNIEnv *env, jobject props, char *baseKey,
   99.25                        char *platformDispVal, char *platformFmtVal,
   99.26 @@ -185,7 +191,8 @@
   99.27              JDK_MAJOR_VERSION "." JDK_MINOR_VERSION);
   99.28      PUTPROP(props, "java.specification.name",
   99.29              "Java Platform API Specification");
   99.30 -    PUTPROP(props, "java.specification.vendor", "Sun Microsystems Inc.");
   99.31 +    PUTPROP(props, "java.specification.vendor",
   99.32 +            JAVA_SPECIFICATION_VENDOR);
   99.33  
   99.34      PUTPROP(props, "java.version", RELEASE);
   99.35      PUTPROP(props, "java.vendor", VENDOR);
   99.36 @@ -239,7 +246,7 @@
   99.37      /* Printing properties */
   99.38      /* Note: java.awt.printerjob is an implementation private property which
   99.39       * just happens to have a java.* name because it is referenced in
   99.40 -     * a java.awt class. It is the mechanism by which the Sun implementation
   99.41 +     * a java.awt class. It is the mechanism by which the implementation
   99.42       * finds the appropriate class in the JRE for the platform.
   99.43       * It is explicitly not designed to be overridden by clients as
   99.44       * a way of replacing the implementation class, and in any case
   99.45 @@ -267,7 +274,7 @@
   99.46      /* Java2D properties */
   99.47      /* Note: java.awt.graphicsenv is an implementation private property which
   99.48       * just happens to have a java.* name because it is referenced in
   99.49 -     * a java.awt class. It is the mechanism by which the Sun implementation
   99.50 +     * a java.awt class. It is the mechanism by which the implementation
   99.51       * finds the appropriate class in the JRE for the platform.
   99.52       * It is explicitly not designed to be overridden by clients as
   99.53       * a way of replacing the implementation class, and in any case
   100.1 --- a/src/share/sample/nio/file/Chmod.java	Thu Oct 07 15:12:19 2010 -0700
   100.2 +++ b/src/share/sample/nio/file/Chmod.java	Tue Oct 12 12:51:48 2010 -0700
   100.3 @@ -285,18 +285,12 @@
   100.4          }
   100.5  
   100.6          @Override
   100.7 -        public FileVisitResult preVisitDirectory(FileRef dir) {
   100.8 +        public FileVisitResult preVisitDirectory(FileRef dir, BasicFileAttributes attrs) {
   100.9              chmod(dir, changer);
  100.10              return CONTINUE;
  100.11          }
  100.12  
  100.13          @Override
  100.14 -        public FileVisitResult preVisitDirectoryFailed(FileRef dir, IOException exc) {
  100.15 -            System.err.println("WARNING: " + exc);
  100.16 -            return CONTINUE;
  100.17 -        }
  100.18 -
  100.19 -        @Override
  100.20          public FileVisitResult visitFile(FileRef file, BasicFileAttributes attrs) {
  100.21              chmod(file, changer);
  100.22              return CONTINUE;
   101.1 --- a/src/share/sample/nio/file/Copy.java	Thu Oct 07 15:12:19 2010 -0700
   101.2 +++ b/src/share/sample/nio/file/Copy.java	Tue Oct 12 12:51:48 2010 -0700
   101.3 @@ -85,7 +85,7 @@
   101.4          }
   101.5  
   101.6          @Override
   101.7 -        public FileVisitResult preVisitDirectory(Path dir) {
   101.8 +        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
   101.9              // before visiting entries in a directory we copy the directory
  101.10              // (okay if directory already exists).
  101.11              CopyOption[] options = (preserve) ?
  101.12 @@ -104,19 +104,9 @@
  101.13          }
  101.14  
  101.15          @Override
  101.16 -        public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
  101.17 -            System.err.format("Unable to copy: %s: %s%n", dir, exc);
  101.18 -            return CONTINUE;
  101.19 -        }
  101.20 -
  101.21 -        @Override
  101.22          public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
  101.23 -            if (attrs.isDirectory()) {
  101.24 -                System.err.println("cycle detected: " + file);
  101.25 -            } else {
  101.26 -                copyFile(file, target.resolve(source.relativize(file)),
  101.27 -                         prompt, preserve);
  101.28 -            }
  101.29 +            copyFile(file, target.resolve(source.relativize(file)),
  101.30 +                     prompt, preserve);
  101.31              return CONTINUE;
  101.32          }
  101.33  
  101.34 @@ -137,7 +127,11 @@
  101.35  
  101.36          @Override
  101.37          public FileVisitResult visitFileFailed(Path file, IOException exc) {
  101.38 -            System.err.format("Unable to copy: %s: %s%n", file, exc);
  101.39 +            if (exc instanceof FileSystemLoopException) {
  101.40 +                System.err.println("cycle detected: " + file);
  101.41 +            } else {
  101.42 +                System.err.format("Unable to copy: %s: %s%n", file, exc);
  101.43 +            }
  101.44              return CONTINUE;
  101.45          }
  101.46      }
   102.1 --- a/src/share/sample/nio/file/WatchDir.java	Thu Oct 07 15:12:19 2010 -0700
   102.2 +++ b/src/share/sample/nio/file/WatchDir.java	Tue Oct 12 12:51:48 2010 -0700
   102.3 @@ -78,12 +78,10 @@
   102.4          // register directory and sub-directories
   102.5          Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
   102.6              @Override
   102.7 -            public FileVisitResult preVisitDirectory(Path dir) {
   102.8 -                try {
   102.9 -                    register(dir);
  102.10 -                } catch (IOException x) {
  102.11 -                    throw new IOError(x);
  102.12 -                }
  102.13 +            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
  102.14 +                throws IOException
  102.15 +            {
  102.16 +                register(dir);
  102.17                  return FileVisitResult.CONTINUE;
  102.18              }
  102.19          });
   103.1 --- a/src/solaris/classes/java/lang/UNIXProcess.java.linux	Thu Oct 07 15:12:19 2010 -0700
   103.2 +++ b/src/solaris/classes/java/lang/UNIXProcess.java.linux	Tue Oct 12 12:51:48 2010 -0700
   103.3 @@ -176,7 +176,13 @@
   103.4              }});
   103.5      }
   103.6  
   103.7 -    synchronized void processExited(int exitcode) {
   103.8 +    void processExited(int exitcode) {
   103.9 +        synchronized (this) {
  103.10 +            this.exitcode = exitcode;
  103.11 +            hasExited = true;
  103.12 +            notifyAll();
  103.13 +        }
  103.14 +
  103.15          if (stdout instanceof ProcessPipeInputStream)
  103.16              ((ProcessPipeInputStream) stdout).processExited();
  103.17  
  103.18 @@ -185,10 +191,6 @@
  103.19  
  103.20          if (stdin instanceof ProcessPipeOutputStream)
  103.21              ((ProcessPipeOutputStream) stdin).processExited();
  103.22 -
  103.23 -        this.exitcode = exitcode;
  103.24 -        hasExited = true;
  103.25 -        notifyAll();
  103.26      }
  103.27  
  103.28      public OutputStream getOutputStream() {
   104.1 --- a/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java	Thu Oct 07 15:12:19 2010 -0700
   104.2 +++ b/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java	Tue Oct 12 12:51:48 2010 -0700
   104.3 @@ -64,7 +64,10 @@
   104.4              accessor.setFile(fd, null);
   104.5              accessor.setFiles(fd, null, null);
   104.6          } else {
   104.7 -            accessor.setDirectory(fd, directory);
   104.8 +            // Fix 6987233: add the trailing slash if it's absent
   104.9 +            accessor.setDirectory(fd, directory +
  104.10 +                    (directory.endsWith(File.separator) ?
  104.11 +                     "" : File.separator));
  104.12              accessor.setFile(fd, filenames[0]);
  104.13              accessor.setFiles(fd, directory, filenames);
  104.14          }
   105.1 --- a/src/solaris/classes/sun/awt/X11/XBaseWindow.java	Thu Oct 07 15:12:19 2010 -0700
   105.2 +++ b/src/solaris/classes/sun/awt/X11/XBaseWindow.java	Tue Oct 12 12:51:48 2010 -0700
   105.3 @@ -705,12 +705,8 @@
   105.4              throw new IllegalStateException("Attempt to resize uncreated window");
   105.5          }
   105.6          insLog.fine("Setting bounds on " + this + " to (" + x + ", " + y + "), " + width + "x" + height);
   105.7 -        if (width <= 0) {
   105.8 -            width = 1;
   105.9 -        }
  105.10 -        if (height <= 0) {
  105.11 -            height = 1;
  105.12 -        }
  105.13 +        width = Math.max(MIN_SIZE, width);
  105.14 +        height = Math.max(MIN_SIZE, height);
  105.15          XToolkit.awtLock();
  105.16          try {
  105.17               XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), getWindow(), x,y,width,height);
   106.1 --- a/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java	Thu Oct 07 15:12:19 2010 -0700
   106.2 +++ b/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java	Tue Oct 12 12:51:48 2010 -0700
   106.3 @@ -763,12 +763,8 @@
   106.4      }
   106.5  
   106.6      private void checkShellRectSize(Rectangle shellRect) {
   106.7 -        if (shellRect.width < 0) {
   106.8 -            shellRect.width = 1;
   106.9 -        }
  106.10 -        if (shellRect.height < 0) {
  106.11 -            shellRect.height = 1;
  106.12 -        }
  106.13 +        shellRect.width = Math.max(MIN_SIZE, shellRect.width);
  106.14 +        shellRect.height = Math.max(MIN_SIZE, shellRect.height);
  106.15      }
  106.16  
  106.17      private void checkShellRectPos(Rectangle shellRect) {
   107.1 --- a/src/solaris/classes/sun/awt/X11/XEmbeddedFrame.java	Thu Oct 07 15:12:19 2010 -0700
   107.2 +++ b/src/solaris/classes/sun/awt/X11/XEmbeddedFrame.java	Tue Oct 12 12:51:48 2010 -0700
   107.3 @@ -28,9 +28,12 @@
   107.4  import sun.awt.EmbeddedFrame;
   107.5  import java.awt.*;
   107.6  import java.awt.AWTKeyStroke;
   107.7 +import java.util.logging.Logger;
   107.8  
   107.9  public class XEmbeddedFrame extends EmbeddedFrame {
  107.10  
  107.11 +    private static final Logger log = Logger.getLogger(XEmbeddedFrame.class.getName());
  107.12 +
  107.13      long handle;
  107.14      public XEmbeddedFrame() {
  107.15      }
  107.16 @@ -70,6 +73,21 @@
  107.17          this(handle, supportsXEmbed, false);
  107.18      }
  107.19  
  107.20 +    /*
  107.21 +     * The method shouldn't be called in case of active XEmbed.
  107.22 +     */
  107.23 +    public boolean traverseIn(boolean direction) {
  107.24 +        XEmbeddedFramePeer peer = (XEmbeddedFramePeer)getPeer();
  107.25 +        if (peer != null) {
  107.26 +            if (peer.supportsXEmbed() && peer.isXEmbedActive()) {
  107.27 +                log.fine("The method shouldn't be called when XEmbed is active!");
  107.28 +            } else {
  107.29 +                return super.traverseIn(direction);
  107.30 +            }
  107.31 +        }
  107.32 +        return false;
  107.33 +    }
  107.34 +
  107.35      protected boolean traverseOut(boolean direction) {
  107.36          XEmbeddedFramePeer xefp = (XEmbeddedFramePeer) getPeer();
  107.37          if (direction == FORWARD) {
  107.38 @@ -81,6 +99,20 @@
  107.39          return true;
  107.40      }
  107.41  
  107.42 +    /*
  107.43 +     * The method shouldn't be called in case of active XEmbed.
  107.44 +     */
  107.45 +    public void synthesizeWindowActivation(boolean doActivate) {
  107.46 +        XEmbeddedFramePeer peer = (XEmbeddedFramePeer)getPeer();
  107.47 +        if (peer != null) {
  107.48 +            if (peer.supportsXEmbed() && peer.isXEmbedActive()) {
  107.49 +                log.fine("The method shouldn't be called when XEmbed is active!");
  107.50 +            } else {
  107.51 +                peer.synthesizeFocusInOut(doActivate);
  107.52 +            }
  107.53 +        }
  107.54 +    }
  107.55 +
  107.56      public void registerAccelerator(AWTKeyStroke stroke) {
  107.57          XEmbeddedFramePeer xefp = (XEmbeddedFramePeer) getPeer();
  107.58          if (xefp != null) {
   108.1 --- a/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java	Thu Oct 07 15:12:19 2010 -0700
   108.2 +++ b/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java	Tue Oct 12 12:51:48 2010 -0700
   108.3 @@ -35,6 +35,8 @@
   108.4  import sun.awt.EmbeddedFrame;
   108.5  import sun.awt.SunToolkit;
   108.6  
   108.7 +import static sun.awt.X11.XConstants.*;
   108.8 +
   108.9  public class XEmbeddedFramePeer extends XFramePeer {
  108.10  
  108.11      private static final PlatformLogger xembedLog = PlatformLogger.getLogger("sun.awt.X11.xembed.XEmbeddedFramePeer");
  108.12 @@ -305,4 +307,20 @@
  108.13          EmbeddedFrame frame = (EmbeddedFrame)target;
  108.14          frame.notifyModalBlocked(blocker, blocked);
  108.15      }
  108.16 +
  108.17 +    public void synthesizeFocusInOut(boolean doFocus) {
  108.18 +        XFocusChangeEvent xev = new XFocusChangeEvent();
  108.19 +
  108.20 +        XToolkit.awtLock();
  108.21 +        try {
  108.22 +            xev.set_type(doFocus ? FocusIn : FocusOut);
  108.23 +            xev.set_window(getFocusProxy().getWindow());
  108.24 +            xev.set_mode(NotifyNormal);
  108.25 +            XlibWrapper.XSendEvent(XToolkit.getDisplay(), getFocusProxy().getWindow(), false,
  108.26 +                                   NoEventMask, xev.pData);
  108.27 +        } finally {
  108.28 +            XToolkit.awtUnlock();
  108.29 +            xev.dispose();
  108.30 +        }
  108.31 +    }
  108.32  }
   109.1 --- a/src/solaris/classes/sun/awt/X11/XToolkit.java	Thu Oct 07 15:12:19 2010 -0700
   109.2 +++ b/src/solaris/classes/sun/awt/X11/XToolkit.java	Tue Oct 12 12:51:48 2010 -0700
   109.3 @@ -1482,8 +1482,19 @@
   109.4          try {
   109.5              if (numberOfButtons == 0) {
   109.6                  numberOfButtons = getNumberOfButtonsImpl();
   109.7 +                numberOfButtons = (numberOfButtons > MAX_BUTTONS_SUPPORTED)? MAX_BUTTONS_SUPPORTED : numberOfButtons;
   109.8 +                //4th and 5th buttons are for wheel and shouldn't be reported as buttons.
   109.9 +                //If we have more than 3 physical buttons and a wheel, we report N-2 buttons.
  109.10 +                //If we have 3 physical buttons and a wheel, we report 3 buttons.
  109.11 +                //If we have 1,2,3 physical buttons, we report it as is i.e. 1,2 or 3 respectively.
  109.12 +                if (numberOfButtons >=5) {
  109.13 +                    numberOfButtons -= 2;
  109.14 +                } else if (numberOfButtons == 4 || numberOfButtons ==5){
  109.15 +                    numberOfButtons = 3;
  109.16 +                }
  109.17              }
  109.18 -            return (numberOfButtons > MAX_BUTTONS_SUPPORTED)? MAX_BUTTONS_SUPPORTED : numberOfButtons;
  109.19 +            //Assume don't have to re-query the number again and again.
  109.20 +            return numberOfButtons;
  109.21          } finally {
  109.22              awtUnlock();
  109.23          }
   110.1 --- a/src/solaris/classes/sun/nio/fs/LinuxFileStore.java	Thu Oct 07 15:12:19 2010 -0700
   110.2 +++ b/src/solaris/classes/sun/nio/fs/LinuxFileStore.java	Tue Oct 12 12:51:48 2010 -0700
   110.3 @@ -156,9 +156,4 @@
   110.4              return supportsFileAttributeView(UserDefinedFileAttributeView.class);
   110.5          return super.supportsFileAttributeView(name);
   110.6      }
   110.7 -
   110.8 -    @Override
   110.9 -    boolean isLoopback() {
  110.10 -        return false;
  110.11 -    }
  110.12  }
   111.1 --- a/src/solaris/classes/sun/nio/fs/SolarisFileStore.java	Thu Oct 07 15:12:19 2010 -0700
   111.2 +++ b/src/solaris/classes/sun/nio/fs/SolarisFileStore.java	Tue Oct 12 12:51:48 2010 -0700
   111.3 @@ -108,9 +108,4 @@
   111.4              return supportsFileAttributeView(UserDefinedFileAttributeView.class);
   111.5          return super.supportsFileAttributeView(name);
   111.6      }
   111.7 -
   111.8 -    @Override
   111.9 -    boolean isLoopback() {
  111.10 -        return type().equals("lofs");
  111.11 -    }
  111.12  }
   112.1 --- a/src/solaris/classes/sun/nio/fs/UnixFileStore.java	Thu Oct 07 15:12:19 2010 -0700
   112.2 +++ b/src/solaris/classes/sun/nio/fs/UnixFileStore.java	Tue Oct 12 12:51:48 2010 -0700
   112.3 @@ -76,12 +76,6 @@
   112.4       */
   112.5      abstract UnixMountEntry findMountEntry() throws IOException;
   112.6  
   112.7 -    /**
   112.8 -     * Returns true if this file store represents a loopback file system that
   112.9 -     * will have the same device ID as underlying file system.
  112.10 -     */
  112.11 -    abstract boolean isLoopback();
  112.12 -
  112.13      UnixPath file() {
  112.14          return file;
  112.15      }
  112.16 @@ -169,22 +163,13 @@
  112.17          if (!(ob instanceof UnixFileStore))
  112.18              return false;
  112.19          UnixFileStore other = (UnixFileStore)ob;
  112.20 -        if (dev != other.dev)
  112.21 -            return false;
  112.22 -        // deviceIDs are equal but they may not be equal if one or both of
  112.23 -        // them is a loopback file system
  112.24 -        boolean thisIsLoopback = isLoopback();
  112.25 -        if (thisIsLoopback != other.isLoopback())
  112.26 -            return false;  // one, but not both, are lofs
  112.27 -        if (!thisIsLoopback)
  112.28 -            return true;    // neither is lofs
  112.29 -        // both are lofs so compare mount points
  112.30 -        return Arrays.equals(this.entry.dir(), other.entry.dir());
  112.31 +        return (this.dev == other.dev) &&
  112.32 +               Arrays.equals(this.entry.dir(), other.entry.dir());
  112.33      }
  112.34  
  112.35      @Override
  112.36      public int hashCode() {
  112.37 -        return (int)(dev ^ (dev >>> 32));
  112.38 +        return (int)(dev ^ (dev >>> 32)) ^ Arrays.hashCode(entry.dir());
  112.39      }
  112.40  
  112.41      @Override
   113.1 --- a/src/solaris/native/java/io/io_util_md.c	Thu Oct 07 15:12:19 2010 -0700
   113.2 +++ b/src/solaris/native/java/io/io_util_md.c	Tue Oct 12 12:51:48 2010 -0700
   113.3 @@ -83,8 +83,6 @@
   113.4              close(devnull);
   113.5          }
   113.6      } else if (JVM_Close(fd) == -1) {
   113.7 -            SET_FD(this, fd, fid); // restore fd
   113.8 -            printf("JVM_Close returned -1\n");
   113.9 -            JNU_ThrowIOExceptionWithLastError(env, "close failed");
  113.10 +        JNU_ThrowIOExceptionWithLastError(env, "close failed");
  113.11      }
  113.12  }
   114.1 --- a/src/solaris/native/java/net/Inet6AddressImpl.c	Thu Oct 07 15:12:19 2010 -0700
   114.2 +++ b/src/solaris/native/java/net/Inet6AddressImpl.c	Tue Oct 12 12:51:48 2010 -0700
   114.3 @@ -124,7 +124,7 @@
   114.4  static int initialized = 0;
   114.5  
   114.6  /*
   114.7 - * Find an internet address for a given hostname.  Not this this
   114.8 + * Find an internet address for a given hostname.  Note that this
   114.9   * code only works for addresses of type INET. The translation
  114.10   * of %d.%d.%d.%d to an address (int) occurs in java now, so the
  114.11   * String "host" shouldn't *ever* be a %d.%d.%d.%d string
  114.12 @@ -200,7 +200,7 @@
  114.13           */
  114.14          if (isspace((unsigned char)hostname[0])) {
  114.15              JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
  114.16 -                            (char *)hostname);
  114.17 +                            hostname);
  114.18              JNU_ReleaseStringPlatformChars(env, host, hostname);
  114.19              return NULL;
  114.20          }
  114.21 @@ -210,8 +210,7 @@
  114.22  
  114.23          if (error) {
  114.24              /* report error */
  114.25 -            JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
  114.26 -                            (char *)hostname);
  114.27 +            ThrowUnknownHostExceptionWithGaiError(env, hostname, error);
  114.28              JNU_ReleaseStringPlatformChars(env, host, hostname);
  114.29              return NULL;
  114.30          } else {
  114.31 @@ -407,7 +406,7 @@
  114.32              addr |= ((caddr[1] <<16) & 0xff0000);
  114.33              addr |= ((caddr[2] <<8) & 0xff00);
  114.34              addr |= (caddr[3] & 0xff);
  114.35 -            memset((char *) &him4, 0, sizeof(him4));
  114.36 +            memset((void *) &him4, 0, sizeof(him4));
  114.37              him4.sin_addr.s_addr = (uint32_t) htonl(addr);
  114.38              him4.sin_family = AF_INET;
  114.39              sa = (struct sockaddr *) &him4;
  114.40 @@ -417,7 +416,7 @@
  114.41               * For IPv6 address construct a sockaddr_in6 structure.
  114.42               */
  114.43              (*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr);
  114.44 -            memset((char *) &him6, 0, sizeof(him6));
  114.45 +            memset((void *) &him6, 0, sizeof(him6));
  114.46              memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) );
  114.47              him6.sin6_family = AF_INET6;
  114.48              sa = (struct sockaddr *) &him6 ;
  114.49 @@ -579,8 +578,8 @@
  114.50                                                           ifArray, ttl);
  114.51      }
  114.52  
  114.53 -    memset((char *) caddr, 0, 16);
  114.54 -    memset((char *) &him6, 0, sizeof(him6));
  114.55 +    memset((void *) caddr, 0, 16);
  114.56 +    memset((void *) &him6, 0, sizeof(him6));
  114.57      (*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr);
  114.58      memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) );
  114.59      him6.sin6_family = AF_INET6;
  114.60 @@ -600,8 +599,8 @@
  114.61       * for it.
  114.62       */
  114.63      if (!(IS_NULL(ifArray))) {
  114.64 -      memset((char *) caddr, 0, 16);
  114.65 -      memset((char *) &inf6, 0, sizeof(inf6));
  114.66 +      memset((void *) caddr, 0, 16);
  114.67 +      memset((void *) &inf6, 0, sizeof(inf6));
  114.68        (*env)->GetByteArrayRegion(env, ifArray, 0, 16, caddr);
  114.69        memcpy((void *)&(inf6.sin6_addr), caddr, sizeof(struct in6_addr) );
  114.70        inf6.sin6_family = AF_INET6;
   115.1 --- a/src/solaris/native/java/net/net_util_md.c	Thu Oct 07 15:12:19 2010 -0700
   115.2 +++ b/src/solaris/native/java/net/net_util_md.c	Tue Oct 12 12:51:48 2010 -0700
   115.3 @@ -61,6 +61,7 @@
   115.4  
   115.5  getaddrinfo_f getaddrinfo_ptr = NULL;
   115.6  freeaddrinfo_f freeaddrinfo_ptr = NULL;
   115.7 +gai_strerror_f gai_strerror_ptr = NULL;
   115.8  getnameinfo_f getnameinfo_ptr = NULL;
   115.9  
  115.10  /*
  115.11 @@ -342,11 +343,14 @@
  115.12      freeaddrinfo_ptr = (freeaddrinfo_f)
  115.13          JVM_FindLibraryEntry(RTLD_DEFAULT, "freeaddrinfo");
  115.14  
  115.15 +    gai_strerror_ptr = (gai_strerror_f)
  115.16 +        JVM_FindLibraryEntry(RTLD_DEFAULT, "gai_strerror");
  115.17 +
  115.18      getnameinfo_ptr = (getnameinfo_f)
  115.19          JVM_FindLibraryEntry(RTLD_DEFAULT, "getnameinfo");
  115.20  
  115.21      if (freeaddrinfo_ptr == NULL || getnameinfo_ptr == NULL) {
  115.22 -        /* Wee need all 3 of them */
  115.23 +        /* We need all 3 of them */
  115.24          getaddrinfo_ptr = NULL;
  115.25      }
  115.26  
  115.27 @@ -355,6 +359,35 @@
  115.28  #endif /* AF_INET6 */
  115.29  }
  115.30  
  115.31 +void ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
  115.32 +                                           const char* hostname,
  115.33 +                                           int gai_error)
  115.34 +{
  115.35 +    int size;
  115.36 +    char *buf;
  115.37 +    const char *format = "%s: %s";
  115.38 +    const char *error_string =
  115.39 +        (gai_strerror_ptr == NULL) ? NULL : (*gai_strerror_ptr)(gai_error);
  115.40 +    if (error_string == NULL)
  115.41 +        error_string = "unknown error";
  115.42 +
  115.43 +    size = strlen(format) + strlen(hostname) + strlen(error_string) + 2;
  115.44 +    buf = (char *) malloc(size);
  115.45 +    if (buf) {
  115.46 +        jstring s;
  115.47 +        sprintf(buf, format, hostname, error_string);
  115.48 +        s = JNU_NewStringPlatform(env, buf);
  115.49 +        if (s != NULL) {
  115.50 +            jobject x = JNU_NewObjectByName(env,
  115.51 +                                            "java/net/UnknownHostException",
  115.52 +                                            "(Ljava/lang/String;)V", s);
  115.53 +            if (x != NULL)
  115.54 +                (*env)->Throw(env, x);
  115.55 +        }
  115.56 +        free(buf);
  115.57 +    }
  115.58 +}
  115.59 +
  115.60  void
  115.61  NET_AllocSockaddr(struct sockaddr **him, int *len) {
  115.62  #ifdef AF_INET6
  115.63 @@ -1173,19 +1206,26 @@
  115.64      }
  115.65  
  115.66      /*
  115.67 -     * SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On Solaris need to
  115.68 -     * ensure that value is <= max_buf as otherwise we get
  115.69 -     * an invalid argument.
  115.70 +     * SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On Solaris we may need to clamp
  115.71 +     * the value when it exceeds the system limit.
  115.72       */
  115.73  #ifdef __solaris__
  115.74      if (level == SOL_SOCKET) {
  115.75          if (opt == SO_SNDBUF || opt == SO_RCVBUF) {
  115.76              int sotype, arglen;
  115.77              int *bufsize, maxbuf;
  115.78 +            int ret;
  115.79 +
  115.80 +            /* Attempt with the original size */
  115.81 +            ret = setsockopt(fd, level, opt, arg, len);
  115.82 +            if ((ret == 0) || (ret == -1 && errno != ENOBUFS))
  115.83 +                return ret;
  115.84 +
  115.85 +            /* Exceeded system limit so clamp and retry */
  115.86  
  115.87              if (!init_max_buf) {
  115.88 -                tcp_max_buf = getParam("/dev/tcp", "tcp_max_buf", 64*1024);
  115.89 -                udp_max_buf = getParam("/dev/udp", "udp_max_buf", 64*1024);
  115.90 +                tcp_max_buf = getParam("/dev/tcp", "tcp_max_buf", 1024*1024);
  115.91 +                udp_max_buf = getParam("/dev/udp", "udp_max_buf", 2048*1024);
  115.92                  init_max_buf = 1;
  115.93              }
  115.94  
   116.1 --- a/src/solaris/native/java/net/net_util_md.h	Thu Oct 07 15:12:19 2010 -0700
   116.2 +++ b/src/solaris/native/java/net/net_util_md.h	Tue Oct 12 12:51:48 2010 -0700
   116.3 @@ -84,11 +84,13 @@
   116.4  
   116.5  /* needed from libsocket on Solaris 8 */
   116.6  
   116.7 -typedef int (*getaddrinfo_f)(const char *nodename, const char  *servname,
   116.8 -     const struct addrinfo *hints, struct addrinfo **res);
   116.9 +typedef int (*getaddrinfo_f)(const char *nodename, const char *servname,
  116.10 +    const struct addrinfo *hints, struct addrinfo **res);
  116.11  
  116.12  typedef void (*freeaddrinfo_f)(struct addrinfo *);
  116.13  
  116.14 +typedef const char * (*gai_strerror_f)(int ecode);
  116.15 +
  116.16  typedef int (*getnameinfo_f)(const struct sockaddr *, size_t,
  116.17      char *, size_t, char *, size_t, int);
  116.18  
  116.19 @@ -96,6 +98,10 @@
  116.20  extern freeaddrinfo_f freeaddrinfo_ptr;
  116.21  extern getnameinfo_f getnameinfo_ptr;
  116.22  
  116.23 +void ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
  116.24 +                                           const char* hostname,
  116.25 +                                           int gai_error);
  116.26 +
  116.27  /* do we have address translation support */
  116.28  
  116.29  extern jboolean NET_addrtransAvailable();
   117.1 --- a/src/solaris/native/sun/awt/awt_InputMethod.c	Thu Oct 07 15:12:19 2010 -0700
   117.2 +++ b/src/solaris/native/sun/awt/awt_InputMethod.c	Tue Oct 12 12:51:48 2010 -0700
   117.3 @@ -1473,6 +1473,10 @@
   117.4  static void DestroyXIMCallback(XIM im, XPointer client_data, XPointer call_data) {
   117.5      /* mark that XIM server was destroyed */
   117.6      X11im = NULL;
   117.7 +    JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
   117.8 +    /* free the old pX11IMData and set it to null. this also avoids crashing
   117.9 +     * the jvm if the XIM server reappears */
  117.10 +    X11InputMethodData *pX11IMData = getX11InputMethodData(env, currentX11InputMethodInstance);
  117.11  }
  117.12  
  117.13  /*
   118.1 --- a/src/windows/classes/sun/awt/windows/WComponentPeer.java	Thu Oct 07 15:12:19 2010 -0700
   118.2 +++ b/src/windows/classes/sun/awt/windows/WComponentPeer.java	Tue Oct 12 12:51:48 2010 -0700
   118.3 @@ -556,24 +556,26 @@
   118.4  
   118.5          Component target = (Component)getTarget();
   118.6          Window window = SunToolkit.getContainingWindow(target);
   118.7 -        if (window != null && !window.isOpaque()) {
   118.8 -            // Non-opaque windows do not support heavyweight children.
   118.9 -            // Redirect all painting to the Window's Graphics instead.
  118.10 -            // The caller is responsible for calling the
  118.11 -            // WindowPeer.updateWindow() after painting has finished.
  118.12 -            int x = 0, y = 0;
  118.13 -            for (Component c = target; c != window; c = c.getParent()) {
  118.14 -                x += c.getX();
  118.15 -                y += c.getY();
  118.16 -            }
  118.17 -
  118.18 +        if (window != null) {
  118.19              Graphics g =
  118.20                  ((WWindowPeer)window.getPeer()).getTranslucentGraphics();
  118.21 +            // getTranslucentGraphics() returns non-null value for non-opaque windows only
  118.22 +            if (g != null) {
  118.23 +                // Non-opaque windows do not support heavyweight children.
  118.24 +                // Redirect all painting to the Window's Graphics instead.
  118.25 +                // The caller is responsible for calling the
  118.26 +                // WindowPeer.updateWindow() after painting has finished.
  118.27 +                int x = 0, y = 0;
  118.28 +                for (Component c = target; c != window; c = c.getParent()) {
  118.29 +                    x += c.getX();
  118.30 +                    y += c.getY();
  118.31 +                }
  118.32  
  118.33 -            g.translate(x, y);
  118.34 -            g.clipRect(0, 0, target.getWidth(), target.getHeight());
  118.35 +                g.translate(x, y);
  118.36 +                g.clipRect(0, 0, target.getWidth(), target.getHeight());
  118.37  
  118.38 -            return g;
  118.39 +                return g;
  118.40 +            }
  118.41          }
  118.42  
  118.43          SurfaceData surfaceData = this.surfaceData;
   119.1 --- a/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java	Thu Oct 07 15:12:19 2010 -0700
   119.2 +++ b/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java	Tue Oct 12 12:51:48 2010 -0700
   119.3 @@ -191,9 +191,20 @@
   119.4      public void activateEmbeddingTopLevel() {
   119.5      }
   119.6  
   119.7 -    public void synthesizeWindowActivation(boolean doActivate) {
   119.8 -        ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(doActivate);
   119.9 +    public void synthesizeWindowActivation(final boolean doActivate) {
  119.10 +        if (!doActivate || EventQueue.isDispatchThread()) {
  119.11 +            ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(doActivate);
  119.12 +        } else {
  119.13 +            // To avoid focus concurrence b/w IE and EmbeddedFrame
  119.14 +            // activation is postponed by means of posting it to EDT.
  119.15 +            EventQueue.invokeLater(new Runnable() {
  119.16 +                    public void run() {
  119.17 +                        ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(true);
  119.18 +                    }
  119.19 +                });
  119.20 +        }
  119.21      }
  119.22 +
  119.23      public void registerAccelerator(AWTKeyStroke stroke) {}
  119.24      public void unregisterAccelerator(AWTKeyStroke stroke) {}
  119.25  
   120.1 --- a/src/windows/classes/sun/awt/windows/WWindowPeer.java	Thu Oct 07 15:12:19 2010 -0700
   120.2 +++ b/src/windows/classes/sun/awt/windows/WWindowPeer.java	Tue Oct 12 12:51:48 2010 -0700
   120.3 @@ -595,16 +595,6 @@
   120.4      }
   120.5  
   120.6      @Override
   120.7 -    public Graphics getGraphics() {
   120.8 -        synchronized (getStateLock()) {
   120.9 -            if (!isOpaque) {
  120.10 -                return getTranslucentGraphics();
  120.11 -            }
  120.12 -        }
  120.13 -        return super.getGraphics();
  120.14 -    }
  120.15 -
  120.16 -    @Override
  120.17      public void setBackground(Color c) {
  120.18          super.setBackground(c);
  120.19          synchronized (getStateLock()) {
   121.1 --- a/src/windows/lib/tzmappings	Thu Oct 07 15:12:19 2010 -0700
   121.2 +++ b/src/windows/lib/tzmappings	Tue Oct 12 12:51:48 2010 -0700
   121.3 @@ -1,5 +1,4 @@
   121.4  #
   121.5 -# 
   121.6  # This file describes mapping information between Windows and Java
   121.7  # time zones.
   121.8  # Format: Each line should include a colon separated fields of Windows
   121.9 @@ -11,7 +10,7 @@
  121.10  #                            NOTE
  121.11  # This table format is not a public interface of any Java
  121.12  # platforms. No applications should depend on this file in any form.
  121.13 -# 
  121.14 +#
  121.15  # This table has been generated by a program and should not be edited
  121.16  # manually.
  121.17  #
  121.18 @@ -84,8 +83,8 @@
  121.19  Ekaterinburg Standard Time:10,11::Asia/Yekaterinburg:
  121.20  West Asia:10,11:UZ:Asia/Tashkent:
  121.21  West Asia Standard Time:10,11:UZ:Asia/Tashkent:
  121.22 -Central Asia:12,13::Asia/Dhaka:
  121.23 -Central Asia Standard Time:12,13::Asia/Dhaka:
  121.24 +Central Asia:12,13::Asia/Almaty:
  121.25 +Central Asia Standard Time:12,13::Asia/Almaty:
  121.26  N. Central Asia Standard Time:12,13::Asia/Novosibirsk:
  121.27  Bangkok:14,15::Asia/Bangkok:
  121.28  Bangkok Standard Time:14,15::Asia/Bangkok:
  121.29 @@ -167,22 +166,27 @@
  121.30  Greenwich Standard Time:88,89::GMT:
  121.31  Argentina Standard Time:900,900::America/Buenos_Aires:
  121.32  Azerbaijan Standard Time:901,901:AZ:Asia/Baku:
  121.33 -Central Brazilian Standard Time:902,902:BR:America/Manaus:
  121.34 -Central Standard Time (Mexico):903,903::America/Mexico_City:
  121.35 -Georgian Standard Time:904,904:GE:Asia/Tbilisi:
  121.36 -Jordan Standard Time:905,905:JO:Asia/Amman:
  121.37 -Mauritius Standard Time:906,906:MU:Indian/Mauritius:
  121.38 -Middle East Standard Time:907,907:LB:Asia/Beirut:
  121.39 -Montevideo Standard Time:908,908:UY:America/Montevideo:
  121.40 -Morocco Standard Time:909,909:MA:Africa/Casablanca:
  121.41 -Mountain Standard Time (Mexico):910,910:MX:America/Chihuahua:
  121.42 -Namibia Standard Time:911,911:NA:Africa/Windhoek:
  121.43 -Pacific Standard Time (Mexico):912,912:MX:America/Tijuana:
  121.44 -Pakistan Standard Time:913,913::Asia/Karachi:
  121.45 -UTC:914,914::UTC:
  121.46 -Venezuela Standard Time:915,915::America/Caracas:
  121.47 -Kamchatka Standard Time:916,916:RU:Asia/Kamchatka:
  121.48 -Paraguay Standard Time:917,917:PY:America/Asuncion:
  121.49 -Western Brazilian Standard Time:918,918:BR:America/Rio_Branco:
  121.50 -Ulaanbaatar Standard Time:919,919::Asia/Ulaanbaatar:
  121.51 -Armenian Standard Time:920,920:AM:Asia/Yerevan:
  121.52 +Bangladesh Standard Time:902,902::Asia/Dhaka:
  121.53 +Central Brazilian Standard Time:903,903:BR:America/Manaus:
  121.54 +Central Standard Time (Mexico):904,904::America/Mexico_City:
  121.55 +Georgian Standard Time:905,905:GE:Asia/Tbilisi:
  121.56 +Jordan Standard Time:906,906:JO:Asia/Amman:
  121.57 +Kamchatka Standard Time:907,907:RU:Asia/Kamchatka:
  121.58 +Mauritius Standard Time:908,908:MU:Indian/Mauritius:
  121.59 +Middle East Standard Time:909,909:LB:Asia/Beirut:
  121.60 +Montevideo Standard Time:910,910:UY:America/Montevideo:
  121.61 +Morocco Standard Time:911,911:MA:Africa/Casablanca:
  121.62 +Mountain Standard Time (Mexico):912,912:MX:America/Chihuahua:
  121.63 +Namibia Standard Time:913,913:NA:Africa/Windhoek:
  121.64 +Pacific Standard Time (Mexico):914,914:MX:America/Tijuana:
  121.65 +Pakistan Standard Time:915,915::Asia/Karachi:
  121.66 +Paraguay Standard Time:916,916:PY:America/Asuncion:
  121.67 +Syria Standard Time:917,917:SY:Asia/Damascus:
  121.68 +UTC:918,918::UTC:
  121.69 +UTC+12:919,919::GMT+1200:
  121.70 +UTC-02:920,920::GMT-0200:
  121.71 +UTC-11:921,921::GMT-1100:
  121.72 +Ulaanbaatar Standard Time:922,922::Asia/Ulaanbaatar:
  121.73 +Venezuela Standard Time:923,923::America/Caracas:
  121.74 +Western Brazilian Standard Time:924,924:BR:America/Rio_Branco:
  121.75 +Armenian Standard Time:925,925:AM:Asia/Yerevan:
   122.1 --- a/src/windows/native/java/io/io_util_md.c	Thu Oct 07 15:12:19 2010 -0700
   122.2 +++ b/src/windows/native/java/io/io_util_md.c	Tue Oct 12 12:51:48 2010 -0700
   122.3 @@ -531,7 +531,6 @@
   122.4      SET_FD(this, -1, fid);
   122.5  
   122.6      if (CloseHandle(h) == 0) { /* Returns zero on failure */
   122.7 -        SET_FD(this, fd, fid); // restore fd
   122.8          JNU_ThrowIOExceptionWithLastError(env, "close failed");
   122.9      }
  122.10      return 0;
   123.1 --- a/src/windows/native/sun/net/spi/DefaultProxySelector.c	Thu Oct 07 15:12:19 2010 -0700
   123.2 +++ b/src/windows/native/sun/net/spi/DefaultProxySelector.c	Tue Oct 12 12:51:48 2010 -0700
   123.3 @@ -250,6 +250,10 @@
   123.4            return proxy;
   123.5          }
   123.6        }
   123.7 +    } else {
   123.8 +      /* ProxyEnable == 0 or Query failed      */
   123.9 +      /* close the handle to the registry key  */
  123.10 +      RegCloseKey(hKey);
  123.11      }
  123.12    }
  123.13  
   124.1 --- a/src/windows/native/sun/windows/awt_Component.cpp	Thu Oct 07 15:12:19 2010 -0700
   124.2 +++ b/src/windows/native/sun/windows/awt_Component.cpp	Tue Oct 12 12:51:48 2010 -0700
   124.3 @@ -2329,6 +2329,19 @@
   124.4      MSG msg;
   124.5      InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
   124.6  
   124.7 +    AwtWindow *toplevel = GetContainer();
   124.8 +    if (toplevel && !toplevel->IsSimpleWindow()) {
   124.9 +        /*
  124.10 +         * The frame should be focused by click in case it is
  124.11 +         * the active window but not the focused window. See 6886678.
  124.12 +         */
  124.13 +        if (toplevel->GetHWnd() == ::GetActiveWindow() &&
  124.14 +            toplevel->GetHWnd() != AwtComponent::GetFocusedWindow())
  124.15 +        {
  124.16 +            toplevel->AwtSetActiveWindow();
  124.17 +        }
  124.18 +    }
  124.19 +
  124.20      SendMouseEvent(java_awt_event_MouseEvent_MOUSE_PRESSED, now, x, y,
  124.21                     GetJavaModifiers(), clickCount, JNI_FALSE,
  124.22                     GetButton(button), &msg);
   125.1 --- a/src/windows/native/sun/windows/awt_Desktop.cpp	Thu Oct 07 15:12:19 2010 -0700
   125.2 +++ b/src/windows/native/sun/windows/awt_Desktop.cpp	Tue Oct 12 12:51:48 2010 -0700
   125.3 @@ -59,15 +59,17 @@
   125.4                      FORMAT_MESSAGE_FROM_SYSTEM  |
   125.5                      FORMAT_MESSAGE_IGNORE_INSERTS,
   125.6                      NULL,
   125.7 -                    GetLastError(),
   125.8 +                    (int)retval,
   125.9                      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  125.10                      (LPTSTR)&buffer,
  125.11                      0,
  125.12                      NULL );
  125.13  
  125.14 -        jstring errmsg = JNU_NewStringPlatform(env, buffer, len);
  125.15 -        LocalFree(buffer);
  125.16 -        return errmsg;
  125.17 +        if (buffer) {
  125.18 +            jstring errmsg = JNU_NewStringPlatform(env, buffer);
  125.19 +            LocalFree(buffer);
  125.20 +            return errmsg;
  125.21 +        }
  125.22      }
  125.23  
  125.24      return NULL;
   126.1 --- a/src/windows/native/sun/windows/awt_DesktopProperties.cpp	Thu Oct 07 15:12:19 2010 -0700
   126.2 +++ b/src/windows/native/sun/windows/awt_DesktopProperties.cpp	Tue Oct 12 12:51:48 2010 -0700
   126.3 @@ -505,7 +505,8 @@
   126.4      SetIntegerProperty(TEXT("win.drag.width"), cxdrag);
   126.5      SetIntegerProperty(TEXT("win.drag.height"), cydrag);
   126.6      SetIntegerProperty(TEXT("DnD.gestureMotionThreshold"), max(cxdrag, cydrag)/2);
   126.7 -    SetIntegerProperty(TEXT("awt.mouse.numButtons"), GetSystemMetrics(SM_CMOUSEBUTTONS));
   126.8 +    SetIntegerProperty(TEXT("awt.mouse.numButtons"), AwtToolkit::GetNumberOfButtons());
   126.9 +
  126.10      SetIntegerProperty(TEXT("awt.multiClickInterval"), GetDoubleClickTime());
  126.11  
  126.12      // BEGIN cross-platform properties
   127.1 --- a/src/windows/native/sun/windows/awt_Toolkit.cpp	Thu Oct 07 15:12:19 2010 -0700
   127.2 +++ b/src/windows/native/sun/windows/awt_Toolkit.cpp	Tue Oct 12 12:51:48 2010 -0700
   127.3 @@ -133,6 +133,8 @@
   127.4  
   127.5  static LPCTSTR szAwtToolkitClassName = TEXT("SunAwtToolkit");
   127.6  
   127.7 +static const int MOUSE_BUTTONS_WINDOWS_SUPPORTED = 5; //three standard buttons + XBUTTON1 + XBUTTON2.
   127.8 +
   127.9  UINT AwtToolkit::GetMouseKeyState()
  127.10  {
  127.11      static BOOL mbSwapped = ::GetSystemMetrics(SM_SWAPBUTTON);
  127.12 @@ -2310,5 +2312,9 @@
  127.13  
  127.14  JNIEXPORT jint JNICALL Java_sun_awt_windows_WToolkit_getNumberOfButtonsImpl
  127.15  (JNIEnv *, jobject self) {
  127.16 -    return GetSystemMetrics(SM_CMOUSEBUTTONS);
  127.17 +    return AwtToolkit::GetNumberOfButtons();
  127.18  }
  127.19 +
  127.20 +UINT AwtToolkit::GetNumberOfButtons() {
  127.21 +    return MOUSE_BUTTONS_WINDOWS_SUPPORTED;
  127.22 +}
   128.1 --- a/src/windows/native/sun/windows/awt_Toolkit.h	Thu Oct 07 15:12:19 2010 -0700
   128.2 +++ b/src/windows/native/sun/windows/awt_Toolkit.h	Tue Oct 12 12:51:48 2010 -0700
   128.3 @@ -185,6 +185,7 @@
   128.4      BOOL IsDynamicLayoutActive();
   128.5      BOOL areExtraMouseButtonsEnabled();
   128.6      void setExtraMouseButtonsEnabled(BOOL enable);
   128.7 +    static UINT GetNumberOfButtons();
   128.8  
   128.9      INLINE BOOL localPump() { return m_localPump; }
  128.10      INLINE BOOL VerifyComponents() { return FALSE; } // TODO: Use new DebugHelper class to set this flag
   129.1 --- a/test/ProblemList.txt	Thu Oct 07 15:12:19 2010 -0700
   129.2 +++ b/test/ProblemList.txt	Tue Oct 12 12:51:48 2010 -0700
   129.3 @@ -165,6 +165,12 @@
   129.4  #  very small tests and could greatly benefit from a samevm test run.
   129.5  #  So a large batch of beans tests are currently run with othervm mode.
   129.6  
   129.7 +# Filed 6986807
   129.8 +java/beans/Introspector/TestTypeResolver.java   		generic-all
   129.9 +
  129.10 +# Filed 6986813
  129.11 +java/beans/Introspector/memory/Test4508780.java			generic-all
  129.12 +
  129.13  # Linux, some kind of problems with X11 display
  129.14  java/beans/PropertyChangeSupport/Test4682386.java		generic-all
  129.15  java/beans/PropertyChangeSupport/TestSynchronization.java	generic-all
  129.16 @@ -493,6 +499,9 @@
  129.17  
  129.18  # jdk_security
  129.19  
  129.20 +# Filed 6986868
  129.21 +sun/security/tools/jarsigner/crl.sh				generic-all
  129.22 +
  129.23  # Filed 6951285, not sure how often this fails, last was Linux 64bit Fedora 9
  129.24  sun/security/krb5/auto/MaxRetries.java				generic-all
  129.25  
  129.26 @@ -689,10 +698,22 @@
  129.27  
  129.28  # jdk_tools
  129.29  
  129.30 +# Filed 6952105
  129.31 +com/sun/jdi/SuspendThreadTest.java				generic-all
  129.32 +
  129.33 +# Filed 6986875
  129.34 +sun/tools/jps/jps-Vvml.sh					generic-all
  129.35 +
  129.36 +# Filed 6979016
  129.37 +sun/tools/jconsole/ResourceCheckTest.sh				generic-all
  129.38 +
  129.39  ############################################################################
  129.40  
  129.41  # jdk_util
  129.42  
  129.43 +# Filed 6933803
  129.44 +java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java	generic-all
  129.45 +
  129.46  # Fails with assertion error on windows
  129.47  #   11 separate stacktraces created... file reuse problem?
  129.48  java/util/zip/ZipFile/ReadLongZipFileName.java			generic-all
   130.1 --- a/test/com/sun/security/sasl/ntlm/NTLMTest.java	Thu Oct 07 15:12:19 2010 -0700
   130.2 +++ b/test/com/sun/security/sasl/ntlm/NTLMTest.java	Tue Oct 12 12:51:48 2010 -0700
   130.3 @@ -31,8 +31,6 @@
   130.4  import javax.security.auth.callback.*;
   130.5  import java.util.*;
   130.6  
   130.7 -import com.sun.security.ntlm.NTLMException;
   130.8 -
   130.9  public class NTLMTest {
  130.10  
  130.11      private static final String MECH = "NTLM";
  130.12 @@ -95,19 +93,13 @@
  130.13              checkVersion("LM/NTLM", "LMv2");
  130.14              throw new Exception("Should not succeed");
  130.15          } catch (SaslException se) {
  130.16 -            NTLMException ne = (NTLMException)se.getCause();
  130.17 -            if (ne.errorCode() != NTLMException.AUTH_FAILED) {
  130.18 -                throw new Exception("Failed false");
  130.19 -            }
  130.20 +            // OK
  130.21          }
  130.22          try {
  130.23              checkVersion("LMv2/NTLMv2", "LM");
  130.24              throw new Exception("Should not succeed");
  130.25          } catch (SaslException se) {
  130.26 -            NTLMException ne = (NTLMException)se.getCause();
  130.27 -            if (ne.errorCode() != NTLMException.AUTH_FAILED) {
  130.28 -                throw new Exception("Failed false");
  130.29 -            }
  130.30 +            // OK
  130.31          }
  130.32  
  130.33      }
   131.1 --- a/test/com/sun/servicetag/JavaServiceTagTest.java	Thu Oct 07 15:12:19 2010 -0700
   131.2 +++ b/test/com/sun/servicetag/JavaServiceTagTest.java	Tue Oct 12 12:51:48 2010 -0700
   131.3 @@ -124,8 +124,9 @@
   131.4              throw new RuntimeException("Unexpected platform_arch: " +
   131.5                  st.getPlatformArch());
   131.6          }
   131.7 +        String vendor = System.getProperty("java.vendor");
   131.8          if (!st.getProductVendor().
   131.9 -                equals("Sun Microsystems")) {
  131.10 +                equals(vendor)) {
  131.11              throw new RuntimeException("Unexpected product_vendor: " +
  131.12                  st.getProductVendor());
  131.13          }
   132.1 --- a/test/com/sun/servicetag/JavaServiceTagTest1.java	Thu Oct 07 15:12:19 2010 -0700
   132.2 +++ b/test/com/sun/servicetag/JavaServiceTagTest1.java	Tue Oct 12 12:51:48 2010 -0700
   132.3 @@ -196,8 +196,10 @@
   132.4              throw new RuntimeException("Unexpected platform_arch: " +
   132.5                  st.getPlatformArch());
   132.6          }
   132.7 +
   132.8 +        String vendor = System.getProperty("java.vendor");
   132.9          if (!st.getProductVendor().
  132.10 -                equals("Sun Microsystems")) {
  132.11 +                equals(vendor)) {
  132.12              throw new RuntimeException("Unexpected product_vendor: " +
  132.13                  st.getProductVendor());
  132.14          }
   133.1 --- a/test/com/sun/servicetag/Util.java	Thu Oct 07 15:12:19 2010 -0700
   133.2 +++ b/test/com/sun/servicetag/Util.java	Tue Oct 12 12:51:48 2010 -0700
   133.3 @@ -162,6 +162,8 @@
   133.4          for (ServiceTag st : svcTags) {
   133.5              ServiceTag st1 = stMap.get(st.getInstanceURN());
   133.6              if (!matches(st, st1)) {
   133.7 +                System.err.println(st);
   133.8 +                System.err.println(st1);
   133.9                  throw new RuntimeException("ServiceTag in the registry " +
  133.10                      "does not match the one in the map");
  133.11              }
   134.1 --- a/test/com/sun/servicetag/environ.properties	Thu Oct 07 15:12:19 2010 -0700
   134.2 +++ b/test/com/sun/servicetag/environ.properties	Tue Oct 12 12:51:48 2010 -0700
   134.3 @@ -4,6 +4,6 @@
   134.4  osVersion=5.10
   134.5  osArchitecture=sparc
   134.6  systemModel=Sun-Fire-V440
   134.7 -systemManufacturer=Sun Microsystems
   134.8 -cpuManufacturer=Sun Microsystems
   134.9 +systemManufacturer=Oracle Corporation
  134.10 +cpuManufacturer=Oracle Corporation
  134.11  serialNumber=BEL078932
   135.1 --- a/test/com/sun/servicetag/missing-environ-field.xml	Thu Oct 07 15:12:19 2010 -0700
   135.2 +++ b/test/com/sun/servicetag/missing-environ-field.xml	Tue Oct 12 12:51:48 2010 -0700
   135.3 @@ -19,7 +19,7 @@
   135.4  <product_parent_urn>urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3</product_parent_urn>
   135.5  <product_parent>Java Platform Standard Edition 6 (Java SE 6)</product_parent>
   135.6  <product_defined_inst_id>id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc</product_defined_inst_id>
   135.7 -<product_vendor>Sun Microsystems</product_vendor>
   135.8 +<product_vendor>Oracle Corporation</product_vendor>
   135.9  <platform_arch>sparc</platform_arch>
  135.10  <timestamp>2007-11-12 06:15:11 GMT</timestamp>
  135.11  <container>global</container>
  135.12 @@ -34,7 +34,7 @@
  135.13  <product_parent_urn>urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3</product_parent_urn>
  135.14  <product_parent>Java Platform Standard Edition 6 (Java SE 6)</product_parent>
  135.15  <product_defined_inst_id>id=1.6.0_05-b01 sparc,dir=/myjdk/solaris-i586</product_defined_inst_id>
  135.16 -<product_vendor>Sun Microsystems</product_vendor>
  135.17 +<product_vendor>Oracle Corporation</product_vendor>
  135.18  <platform_arch>i386</platform_arch>
  135.19  <timestamp>2007-11-12 06:15:11 GMT</timestamp>
  135.20  <container>global</container>
   136.1 --- a/test/com/sun/servicetag/newer-registry-version.xml	Thu Oct 07 15:12:19 2010 -0700
   136.2 +++ b/test/com/sun/servicetag/newer-registry-version.xml	Tue Oct 12 12:51:48 2010 -0700
   136.3 @@ -20,7 +20,7 @@
   136.4  <product_parent_urn>urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3</product_parent_urn>
   136.5  <product_parent>Java Platform Standard Edition 6 (Java SE 6)</product_parent>
   136.6  <product_defined_inst_id>id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc</product_defined_inst_id>
   136.7 -<product_vendor>Sun Microsystems</product_vendor>
   136.8 +<product_vendor>Oracle Corporation</product_vendor>
   136.9  <platform_arch>sparc</platform_arch>
  136.10  <timestamp>2007-11-13 00:49:01 GMT</timestamp>
  136.11  <container>global</container>
   137.1 --- a/test/com/sun/servicetag/registration.xml	Thu Oct 07 15:12:19 2010 -0700
   137.2 +++ b/test/com/sun/servicetag/registration.xml	Tue Oct 12 12:51:48 2010 -0700
   137.3 @@ -7,8 +7,8 @@
   137.4  <osVersion>5.10</osVersion>
   137.5  <osArchitecture>sparc</osArchitecture>
   137.6  <systemModel>Sun-Fire-V440</systemModel>
   137.7 -<systemManufacturer>Sun Microsystems</systemManufacturer>
   137.8 -<cpuManufacturer>Sun Microsystems</cpuManufacturer>
   137.9 +<systemManufacturer>Oracle Corporation</systemManufacturer>
  137.10 +<cpuManufacturer>Oracle Corporation</cpuManufacturer>
  137.11  <serialNumber>BEL078932</serialNumber>
  137.12  </environment>
  137.13  <registry urn="urn:st:9543ffaa-a4f1-4f77-b2d1-f561922d4e4a" version="1.0">
  137.14 @@ -20,7 +20,7 @@
  137.15  <product_parent_urn>urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3</product_parent_urn>
  137.16  <product_parent>Java Platform Standard Edition 6 (Java SE 6)</product_parent>
  137.17  <product_defined_inst_id>id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc</product_defined_inst_id>
  137.18 -<product_vendor>Sun Microsystems</product_vendor>
  137.19 +<product_vendor>Oracle Corporation</product_vendor>
  137.20  <platform_arch>sparc</platform_arch>
  137.21  <timestamp>2007-11-13 00:49:01 GMT</timestamp>
  137.22  <container>global</container>
  137.23 @@ -35,7 +35,7 @@
  137.24  <product_parent_urn>urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3</product_parent_urn>
  137.25  <product_parent>Java Platform Standard Edition 6 (Java SE 6)</product_parent>
  137.26  <product_defined_inst_id>id=1.6.0_05-b01 i386,dir=/myjdk/solaris-i586</product_defined_inst_id>
  137.27 -<product_vendor>Sun Microsystems</product_vendor>
  137.28 +<product_vendor>Oracle Corporation</product_vendor>
  137.29  <platform_arch>i386</platform_arch>
  137.30  <timestamp>2007-11-13 00:49:01 GMT</timestamp>
  137.31  <container>global</container>
  137.32 @@ -50,7 +50,7 @@
  137.33  <product_parent_urn>urn:uuid:596ffcfa-63d5-11d7-9886-ac816a682f92</product_parent_urn>
  137.34  <product_parent>Solaris Operating System</product_parent>
  137.35  <product_defined_inst_id/>
  137.36 -<product_vendor>Sun Microsystems</product_vendor>
  137.37 +<product_vendor>Oracle Corporation</product_vendor>
  137.38  <platform_arch>sparc</platform_arch>
  137.39  <timestamp>2007-11-13 00:49:01 GMT</timestamp>
  137.40  <container>global</container>
   138.1 --- a/test/com/sun/servicetag/servicetag1.properties	Thu Oct 07 15:12:19 2010 -0700
   138.2 +++ b/test/com/sun/servicetag/servicetag1.properties	Tue Oct 12 12:51:48 2010 -0700
   138.3 @@ -5,7 +5,7 @@
   138.4  product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3
   138.5  product_parent=Java Platform Standard Edition 6 (Java SE 6)
   138.6  product_defined_inst_id=id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc
   138.7 -product_vendor=Sun Microsystems
   138.8 +product_vendor=Oracle Corporation
   138.9  platform_arch=sparc
  138.10  timestamp=2007-11-12 05:19:40 GMT
  138.11  container=global
   139.1 --- a/test/com/sun/servicetag/servicetag2.properties	Thu Oct 07 15:12:19 2010 -0700
   139.2 +++ b/test/com/sun/servicetag/servicetag2.properties	Tue Oct 12 12:51:48 2010 -0700
   139.3 @@ -5,7 +5,7 @@
   139.4  product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3
   139.5  product_parent=Java Platform Standard Edition 6 (Java SE 6)
   139.6  product_defined_inst_id=id=1.6.0_05-b01 i386,dir=/myjdk/solaris-i586
   139.7 -product_vendor=Sun Microsystems
   139.8 +product_vendor=Oracle Corporation
   139.9  platform_arch=i386
  139.10  timestamp=2007-11-12 06:12:21 GMT
  139.11  container=global
   140.1 --- a/test/com/sun/servicetag/servicetag3.properties	Thu Oct 07 15:12:19 2010 -0700
   140.2 +++ b/test/com/sun/servicetag/servicetag3.properties	Tue Oct 12 12:51:48 2010 -0700
   140.3 @@ -5,7 +5,7 @@
   140.4  product_parent_urn=urn:uuid:596ffcfa-63d5-11d7-9886-ac816a682f92
   140.5  product_parent=Solaris Operating System
   140.6  product_defined_inst_id=
   140.7 -product_vendor=Sun Microsystems
   140.8 +product_vendor=Oracle Corporation
   140.9  platform_arch=sparc
  140.10  timestamp=2007-06-20 22:07:11 GMT
  140.11  container=global
   141.1 --- a/test/com/sun/servicetag/servicetag4.properties	Thu Oct 07 15:12:19 2010 -0700
   141.2 +++ b/test/com/sun/servicetag/servicetag4.properties	Tue Oct 12 12:51:48 2010 -0700
   141.3 @@ -5,7 +5,7 @@
   141.4  product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3
   141.5  product_parent=Java Platform Standard Edition 6 (Java SE 6)
   141.6  product_defined_inst_id=id=1.6.0_05-b01 amd64,dir=/myjdk/linux-amd64
   141.7 -product_vendor=Sun Microsystems
   141.8 +product_vendor=Oracle Corporation
   141.9  platform_arch=x64
  141.10  timestamp=2007-12-12 05:19:40 GMT
  141.11  container=global
   142.1 --- a/test/com/sun/servicetag/servicetag5.properties	Thu Oct 07 15:12:19 2010 -0700
   142.2 +++ b/test/com/sun/servicetag/servicetag5.properties	Tue Oct 12 12:51:48 2010 -0700
   142.3 @@ -5,7 +5,7 @@
   142.4  product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3
   142.5  product_parent=Java Platform Standard Edition 6 (Java SE 6)
   142.6  product_defined_inst_id=id=1.6.0_06-b06 i386,dir=/w/mchung/bundles/jdk1.6.0_05/jre
   142.7 -product_vendor=Sun Microsystems
   142.8 +product_vendor=Oracle Corporation
   142.9  platform_arch=x86
  142.10  timestamp=2007-11-29 17:59:42 GMT
  142.11  container=global
   143.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   143.2 +++ b/test/demo/zipfs/Basic.java	Tue Oct 12 12:51:48 2010 -0700
   143.3 @@ -0,0 +1,159 @@
   143.4 +/*
   143.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
   143.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   143.7 + *
   143.8 + * This code is free software; you can redistribute it and/or modify it
   143.9 + * under the terms of the GNU General Public License version 2 only, as
  143.10 + * published by the Free Software Foundation.
  143.11 + *
  143.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  143.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  143.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  143.15 + * version 2 for more details (a copy is included in the LICENSE file that
  143.16 + * accompanied this code).
  143.17 + *
  143.18 + * You should have received a copy of the GNU General Public License version
  143.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  143.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  143.21 + *
  143.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  143.23 + * or visit www.oracle.com if you need additional information or have any
  143.24 + * questions.
  143.25 + */
  143.26 +
  143.27 +import java.nio.file.*;
  143.28 +import java.nio.file.attribute.*;
  143.29 +import java.nio.file.spi.FileSystemProvider;
  143.30 +import java.util.*;
  143.31 +import java.net.URI;
  143.32 +import java.io.IOException;
  143.33 +
  143.34 +/**
  143.35 + * Basic test for zip provider
  143.36 + */
  143.37 +
  143.38 +public class Basic {
  143.39 +    public static void main(String[] args) throws Exception {
  143.40 +        Path zipfile = Paths.get(args[0]);
  143.41 +
  143.42 +        // Test: zip should should be returned in provider list
  143.43 +        boolean found = false;
  143.44 +
  143.45 +        for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
  143.46 +            if (provider.getScheme().equalsIgnoreCase("zip")) {
  143.47 +                found = true;
  143.48 +                break;
  143.49 +            }
  143.50 +        }
  143.51 +        if (!found)
  143.52 +            throw new RuntimeException("'zip' provider not installed");
  143.53 +
  143.54 +        // Test: FileSystems#newFileSystem(FileRef)
  143.55 +        Map<String,?> env = new HashMap<String,Object>();
  143.56 +        FileSystems.newFileSystem(zipfile, env, null).close();
  143.57 +
  143.58 +        // Test: FileSystems#newFileSystem(URI)
  143.59 +        URI uri = URI.create("zip" + zipfile.toUri().toString().substring(4));
  143.60 +        FileSystem fs = FileSystems.newFileSystem(uri, env, null);
  143.61 +
  143.62 +        // Test: exercise toUri method
  143.63 +        String expected = uri.toString() + "#/foo";
  143.64 +        String actual = fs.getPath("/foo").toUri().toString();
  143.65 +        if (!actual.equals(expected)) {
  143.66 +            throw new RuntimeException("toUri returned '" + actual +
  143.67 +                "', expected '" + expected + "'");
  143.68 +        }
  143.69 +
  143.70 +        // Test: exercise directory iterator and retrieval of basic attributes
  143.71 +        Files.walkFileTree(fs.getPath("/"), new FileTreePrinter());
  143.72 +
  143.73 +        // Test: DirectoryStream
  143.74 +        found = false;
  143.75 +        DirectoryStream<Path> stream = fs.getPath("/").newDirectoryStream();
  143.76 +        try {
  143.77 +            for (Path entry: stream) {
  143.78 +                found = entry.toString().equals("/META-INF/");
  143.79 +                if (found) break;
  143.80 +            }
  143.81 +        } finally {
  143.82 +            stream.close();
  143.83 +        }
  143.84 +
  143.85 +        if (!found)
  143.86 +            throw new RuntimeException("Expected file not found");
  143.87 +
  143.88 +        // Test: copy file from zip file to current (scratch) directory
  143.89 +        Path source = fs.getPath("/META-INF/services/java.nio.file.spi.FileSystemProvider");
  143.90 +        if (source.exists()) {
  143.91 +            Path target = Paths.get(source.getName().toString());
  143.92 +            source.copyTo(target, StandardCopyOption.REPLACE_EXISTING);
  143.93 +            try {
  143.94 +                long s1 = Attributes.readBasicFileAttributes(source).size();
  143.95 +                long s2 = Attributes.readBasicFileAttributes(target).size();
  143.96 +                if (s2 != s1)
  143.97 +                    throw new RuntimeException("target size != source size");
  143.98 +            } finally {
  143.99 +                target.delete();
 143.100 +            }
 143.101 +        }
 143.102 +
 143.103 +        // Test: FileStore
 143.104 +        FileStore store = fs.getPath("/").getFileStore();
 143.105 +        if (!store.supportsFileAttributeView("basic"))
 143.106 +            throw new RuntimeException("BasicFileAttributeView should be supported");
 143.107 +
 143.108 +        // Test: ClosedFileSystemException
 143.109 +        fs.close();
 143.110 +        if (fs.isOpen())
 143.111 +            throw new RuntimeException("FileSystem should be closed");
 143.112 +        try {
 143.113 +            fs.getPath("/missing").checkAccess(AccessMode.READ);
 143.114 +        } catch (ClosedFileSystemException x) { }
 143.115 +    }
 143.116 +
 143.117 +    // FileVisitor that pretty prints a file tree
 143.118 +    static class FileTreePrinter extends SimpleFileVisitor<Path> {
 143.119 +        private int indent = 0;
 143.120 +
 143.121 +        private void indent() {
 143.122 +            StringBuilder sb = new StringBuilder(indent);
 143.123 +            for (int i=0; i<indent; i++) sb.append(" ");
 143.124 +            System.out.print(sb);
 143.125 +        }
 143.126 +
 143.127 +        @Override
 143.128 +        public FileVisitResult preVisitDirectory(Path dir,
 143.129 +                                                 BasicFileAttributes attrs)
 143.130 +        {
 143.131 +            if (dir.getName() != null) {
 143.132 +                indent();
 143.133 +                System.out.println(dir.getName() + "/");
 143.134 +                indent++;
 143.135 +            }
 143.136 +            return FileVisitResult.CONTINUE;
 143.137 +        }
 143.138 +
 143.139 +        @Override
 143.140 +        public FileVisitResult visitFile(Path file,
 143.141 +                                         BasicFileAttributes attrs)
 143.142 +        {
 143.143 +            indent();
 143.144 +            System.out.print(file.getName());
 143.145 +            if (attrs.isRegularFile())
 143.146 +                System.out.format(" (%d)", attrs.size());
 143.147 +            System.out.println();
 143.148 +            return FileVisitResult.CONTINUE;
 143.149 +        }
 143.150 +
 143.151 +        @Override
 143.152 +        public FileVisitResult postVisitDirectory(Path dir, IOException exc)
 143.153 +            throws IOException
 143.154 +        {
 143.155 +            if (exc != null)
 143.156 +                super.postVisitDirectory(dir, exc);
 143.157 +            if (dir.getName() != null)
 143.158 +                indent--;
 143.159 +            return FileVisitResult.CONTINUE;
 143.160 +        }
 143.161 +    }
 143.162 +}
   144.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   144.2 +++ b/test/demo/zipfs/PathOps.java	Tue Oct 12 12:51:48 2010 -0700
   144.3 @@ -0,0 +1,416 @@
   144.4 +/*
   144.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
   144.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   144.7 + *
   144.8 + * This code is free software; you can redistribute it and/or modify it
   144.9 + * under the terms of the GNU General Public License version 2 only, as
  144.10 + * published by the Free Software Foundation.
  144.11 + *
  144.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  144.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  144.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  144.15 + * version 2 for more details (a copy is included in the LICENSE file that
  144.16 + * accompanied this code).
  144.17 + *
  144.18 + * You should have received a copy of the GNU General Public License version
  144.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  144.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  144.21 + *
  144.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  144.23 + * or visit www.oracle.com if you need additional information or have any
  144.24 + * questions.
  144.25 + */
  144.26 +
  144.27 +import java.nio.file.*;
  144.28 +import java.net.*;
  144.29 +import java.util.*;
  144.30 +import java.io.IOException;
  144.31 +
  144.32 +/**
  144.33 + * Tests path operations for zip provider.
  144.34 + */
  144.35 +
  144.36 +public class PathOps {
  144.37 +
  144.38 +    static final java.io.PrintStream out = System.out;
  144.39 +    static FileSystem fs;
  144.40 +
  144.41 +    private String input;
  144.42 +    private Path path;
  144.43 +    private Exception exc;
  144.44 +
  144.45 +    private PathOps(String s) {
  144.46 +        out.println();
  144.47 +        input = s;
  144.48 +        try {
  144.49 +            path = fs.getPath(s);
  144.50 +            out.format("%s -> %s", s, path);
  144.51 +        } catch (Exception x) {
  144.52 +            exc = x;
  144.53 +            out.format("%s -> %s", s, x);
  144.54 +        }
  144.55 +        out.println();
  144.56 +    }
  144.57 +
  144.58 +    Path path() {
  144.59 +        return path;
  144.60 +    }
  144.61 +
  144.62 +    void fail() {
  144.63 +        throw new RuntimeException("PathOps failed");
  144.64 +    }
  144.65 +
  144.66 +    void checkPath() {
  144.67 +        if (path == null) {
  144.68 +            throw new InternalError("path is null");
  144.69 +        }
  144.70 +    }
  144.71 +
  144.72 +    void check(Object result, String expected) {
  144.73 +        out.format("\tExpected: %s\n", expected);
  144.74 +        out.format("\tActual: %s\n",  result);
  144.75 +        if (result == null) {
  144.76 +            if (expected == null) return;
  144.77 +        } else {
  144.78 +            // compare string representations
  144.79 +            if (expected != null && result.toString().equals(expected.toString()))
  144.80 +                return;
  144.81 +        }
  144.82 +        fail();
  144.83 +    }
  144.84 +
  144.85 +    void check(Object result, boolean expected) {
  144.86 +        check(result, Boolean.toString(expected));
  144.87 +    }
  144.88 +
  144.89 +    PathOps root(String expected) {
  144.90 +        out.println("check root");
  144.91 +        checkPath();
  144.92 +        check(path.getRoot(), expected);
  144.93 +        return this;
  144.94 +    }
  144.95 +
  144.96 +    PathOps parent(String expected) {
  144.97 +        out.println("check parent");
  144.98 +        checkPath();
  144.99 +        check(path.getParent(), expected);
 144.100 +        return this;
 144.101 +    }
 144.102 +
 144.103 +    PathOps name(String expected) {
 144.104 +        out.println("check name");
 144.105 +        checkPath();
 144.106 +        check(path.getName(), expected);
 144.107 +        return this;
 144.108 +    }
 144.109 +
 144.110 +    PathOps element(int index, String expected) {
 144.111 +        out.format("check element %d\n", index);
 144.112 +        checkPath();
 144.113 +        check(path.getName(index), expected);
 144.114 +        return this;
 144.115 +    }
 144.116 +
 144.117 +    PathOps subpath(int startIndex, int endIndex, String expected) {
 144.118 +        out.format("test subpath(%d,%d)\n", startIndex, endIndex);
 144.119 +        checkPath();
 144.120 +        check(path.subpath(startIndex, endIndex), expected);
 144.121 +        return this;
 144.122 +    }
 144.123 +
 144.124 +    PathOps starts(String prefix) {
 144.125 +        out.format("test startsWith with %s\n", prefix);
 144.126 +        checkPath();
 144.127 +        Path s = fs.getPath(prefix);
 144.128 +        check(path.startsWith(s), true);
 144.129 +        return this;
 144.130 +    }
 144.131 +
 144.132 +    PathOps notStarts(String prefix) {
 144.133 +        out.format("test not startsWith with %s\n", prefix);
 144.134 +        checkPath();
 144.135 +        Path s = fs.getPath(prefix);
 144.136 +        check(path.startsWith(s), false);
 144.137 +        return this;
 144.138 +    }
 144.139 +
 144.140 +    PathOps ends(String suffix) {
 144.141 +        out.format("test endsWith %s\n", suffix);
 144.142 +        checkPath();
 144.143 +        Path s = fs.getPath(suffix);
 144.144 +        check(path.endsWith(s), true);
 144.145 +        return this;
 144.146 +    }
 144.147 +
 144.148 +    PathOps notEnds(String suffix) {
 144.149 +        out.format("test not endsWith %s\n", suffix);
 144.150 +        checkPath();
 144.151 +        Path s = fs.getPath(suffix);
 144.152 +        check(path.endsWith(s), false);
 144.153 +        return this;
 144.154 +    }
 144.155 +
 144.156 +    PathOps absolute() {
 144.157 +        out.println("check path is absolute");
 144.158 +        checkPath();
 144.159 +        check(path.isAbsolute(), true);
 144.160 +        return this;
 144.161 +    }
 144.162 +
 144.163 +    PathOps notAbsolute() {
 144.164 +        out.println("check path is not absolute");
 144.165 +        checkPath();
 144.166 +        check(path.isAbsolute(), false);
 144.167 +        return this;
 144.168 +    }
 144.169 +
 144.170 +    PathOps resolve(String other, String expected) {
 144.171 +        out.format("test resolve %s\n", other);
 144.172 +        checkPath();
 144.173 +        check(path.resolve(other), expected);
 144.174 +        return this;
 144.175 +    }
 144.176 +
 144.177 +    PathOps relativize(String other, String expected) {
 144.178 +        out.format("test relativize %s\n", other);
 144.179 +        checkPath();
 144.180 +        Path that = fs.getPath(other);
 144.181 +        check(path.relativize(that), expected);
 144.182 +        return this;
 144.183 +    }
 144.184 +
 144.185 +    PathOps normalize(String expected) {
 144.186 +        out.println("check normalized path");
 144.187 +        checkPath();
 144.188 +        check(path.normalize(), expected);
 144.189 +        return this;
 144.190 +    }
 144.191 +
 144.192 +    PathOps string(String expected) {
 144.193 +        out.println("check string representation");
 144.194 +        checkPath();
 144.195 +        check(path, expected);
 144.196 +        return this;
 144.197 +    }
 144.198 +
 144.199 +    PathOps invalid() {
 144.200 +        if (!(exc instanceof InvalidPathException)) {
 144.201 +            out.println("InvalidPathException not thrown as expected");
 144.202 +            fail();
 144.203 +        }
 144.204 +        return this;
 144.205 +    }
 144.206 +
 144.207 +    static PathOps test(String s) {
 144.208 +        return new PathOps(s);
 144.209 +    }
 144.210 +
 144.211 +    // -- PathOpss --
 144.212 +
 144.213 +    static void header(String s) {
 144.214 +        out.println();
 144.215 +        out.println();
 144.216 +        out.println("-- " + s + " --");
 144.217 +    }
 144.218 +
 144.219 +    static void doPathOpTests() {
 144.220 +        header("Path operations");
 144.221 +
 144.222 +        // all components
 144.223 +        test("/a/b/c")
 144.224 +            .root("/")
 144.225 +            .parent("/a/b")
 144.226 +            .name("c");
 144.227 +
 144.228 +        // root component only
 144.229 +        test("/")
 144.230 +            .root("/")
 144.231 +            .parent(null)
 144.232 +            .name(null);
 144.233 +
 144.234 +        // no root component
 144.235 +        test("a/b")
 144.236 +            .root(null)
 144.237 +            .parent("a")
 144.238 +            .name("b");
 144.239 +
 144.240 +        // name component only
 144.241 +        test("foo")
 144.242 +            .root(null)
 144.243 +            .parent(null)
 144.244 +            .name("foo");
 144.245 +
 144.246 +        // startsWith
 144.247 +        test("/")
 144.248 +            .starts("/")
 144.249 +            .notStarts("/foo");
 144.250 +        test("/foo")
 144.251 +            .starts("/")
 144.252 +            .starts("/foo")
 144.253 +            .notStarts("/f");
 144.254 +        test("/foo/bar")
 144.255 +            .starts("/")
 144.256 +            .starts("/foo")
 144.257 +            .starts("/foo/bar")
 144.258 +            .notStarts("/f")
 144.259 +            .notStarts("foo")
 144.260 +            .notStarts("foo/bar");
 144.261 +        test("foo")
 144.262 +            .starts("foo")
 144.263 +            .notStarts("f");
 144.264 +        test("foo/bar")
 144.265 +            .starts("foo")
 144.266 +            .starts("foo/bar")
 144.267 +            .notStarts("f")
 144.268 +            .notStarts("/foo")
 144.269 +            .notStarts("/foo/bar");
 144.270 +
 144.271 +        // endsWith
 144.272 +        test("/")
 144.273 +            .ends("/")
 144.274 +            .notEnds("foo")
 144.275 +            .notEnds("/foo");
 144.276 +        test("/foo")
 144.277 +            .ends("foo")
 144.278 +            .ends("/foo")
 144.279 +            .notEnds("/");
 144.280 +        test("/foo/bar")
 144.281 +            .ends("bar")
 144.282 +            .ends("foo/bar")
 144.283 +            .ends("/foo/bar")
 144.284 +            .notEnds("/bar");
 144.285 +        test("foo")
 144.286 +            .ends("foo");
 144.287 +        test("foo/bar")
 144.288 +            .ends("bar")
 144.289 +            .ends("foo/bar");
 144.290 +
 144.291 +        // elements
 144.292 +        test("a/b/c")
 144.293 +            .element(0,"a")
 144.294 +            .element(1,"b")
 144.295 +            .element(2,"c");
 144.296 +
 144.297 +        // isAbsolute
 144.298 +        test("/")
 144.299 +            .absolute();
 144.300 +        test("/tmp")
 144.301 +            .absolute();
 144.302 +        test("tmp")
 144.303 +            .notAbsolute();
 144.304 +
 144.305 +        // resolve
 144.306 +        test("/tmp")
 144.307 +            .resolve("foo", "/tmp/foo")
 144.308 +            .resolve("/foo", "/foo");
 144.309 +        test("tmp")
 144.310 +            .resolve("foo", "tmp/foo")
 144.311 +            .resolve("/foo", "/foo");
 144.312 +
 144.313 +        // relativize
 144.314 +        test("/a/b/c")
 144.315 +            .relativize("/a/b/c", null)
 144.316 +            .relativize("/a/b/c/d/e", "d/e")
 144.317 +            .relativize("/a/x", "../../x");
 144.318 +
 144.319 +        // normalize
 144.320 +        test("/")
 144.321 +            .normalize("/");
 144.322 +        test("foo")
 144.323 +            .normalize("foo");
 144.324 +        test("/foo")
 144.325 +            .normalize("/foo");
 144.326 +        test(".")
 144.327 +            .normalize(null);
 144.328 +        test("..")
 144.329 +            .normalize("..");
 144.330 +        test("/..")
 144.331 +            .normalize("/");
 144.332 +        test("/../..")
 144.333 +            .normalize("/");
 144.334 +        test("foo/.")
 144.335 +            .normalize("foo");
 144.336 +        test("./foo")
 144.337 +            .normalize("foo");
 144.338 +        test("foo/..")
 144.339 +            .normalize(null);
 144.340 +        test("../foo")
 144.341 +            .normalize("../foo");
 144.342 +        test("../../foo")
 144.343 +            .normalize("../../foo");
 144.344 +        test("foo/bar/..")
 144.345 +            .normalize("foo");
 144.346 +        test("foo/bar/gus/../..")
 144.347 +            .normalize("foo");
 144.348 +        test("/foo/bar/gus/../..")
 144.349 +            .normalize("/foo");
 144.350 +
 144.351 +        // invalid
 144.352 +        test("foo\u0000bar")
 144.353 +            .invalid();
 144.354 +        test("\u0000foo")
 144.355 +            .invalid();
 144.356 +        test("bar\u0000")
 144.357 +            .invalid();
 144.358 +        test("//foo\u0000bar")
 144.359 +            .invalid();
 144.360 +        test("//\u0000foo")
 144.361 +            .invalid();
 144.362 +        test("//bar\u0000")
 144.363 +            .invalid();
 144.364 +
 144.365 +        // normalization
 144.366 +        test("//foo//bar")
 144.367 +            .string("/foo/bar")
 144.368 +            .root("/")
 144.369 +            .parent("/foo")
 144.370 +            .name("bar");
 144.371 +    }
 144.372 +
 144.373 +    static void npes() {
 144.374 +        header("NullPointerException");
 144.375 +
 144.376 +        Path path = fs.getPath("foo");
 144.377 +
 144.378 +        try {
 144.379 +            path.resolve((String)null);
 144.380 +            throw new RuntimeException("NullPointerException not thrown");
 144.381 +        } catch (NullPointerException npe) {
 144.382 +        }
 144.383 +
 144.384 +        try {
 144.385 +            path.relativize(null);
 144.386 +            throw new RuntimeException("NullPointerException not thrown");
 144.387 +        } catch (NullPointerException npe) {
 144.388 +        }
 144.389 +
 144.390 +        try {
 144.391 +            path.compareTo(null);
 144.392 +            throw new RuntimeException("NullPointerException not thrown");
 144.393 +        } catch (NullPointerException npe) {
 144.394 +        }
 144.395 +
 144.396 +        try {
 144.397 +            path.startsWith(null);
 144.398 +            throw new RuntimeException("NullPointerException not thrown");
 144.399 +        } catch (NullPointerException npe) {
 144.400 +        }
 144.401 +
 144.402 +        try {
 144.403 +            path.endsWith(null);
 144.404 +            throw new RuntimeException("NullPointerException not thrown");
 144.405 +        } catch (NullPointerException npe) {
 144.406 +        }
 144.407 +
 144.408 +    }
 144.409 +
 144.410 +    public static void main(String[] args) throws Throwable {
 144.411 +
 144.412 +        Path zipfile = Paths.get(args[0]);
 144.413 +        Map<String,?> env = new HashMap<String,Object>();
 144.414 +        fs = FileSystems.newFileSystem(zipfile, env, null);
 144.415 +        npes();
 144.416 +        doPathOpTests();
 144.417 +        fs.close();
 144.418 +    }
 144.419 +}
   145.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   145.2 +++ b/test/demo/zipfs/ZipFSTester.java	Tue Oct 12 12:51:48 2010 -0700
   145.3 @@ -0,0 +1,633 @@
   145.4 +/*
   145.5 + * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
   145.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   145.7 + *
   145.8 + * This code is free software; you can redistribute it and/or modify it
   145.9 + * under the terms of the GNU General Public License version 2 only, as
  145.10 + * published by the Free Software Foundation.
  145.11 + *
  145.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  145.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  145.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  145.15 + * version 2 for more details (a copy is included in the LICENSE file that
  145.16 + * accompanied this code).
  145.17 + *
  145.18 + * You should have received a copy of the GNU General Public License version
  145.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  145.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  145.21 + *
  145.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  145.23 + * or visit www.oracle.com if you need additional information or have any
  145.24 + * questions.
  145.25 + */
  145.26 +
  145.27 +import java.io.*;
  145.28 +import java.nio.*;
  145.29 +import java.nio.channels.*;
  145.30 +import java.nio.file.*;
  145.31 +import java.nio.file.attribute.*;
  145.32 +import java.net.*;
  145.33 +import java.util.*;
  145.34 +
  145.35 +import static java.nio.file.StandardOpenOption.*;
  145.36 +import static java.nio.file.StandardCopyOption.*;
  145.37 +
  145.38 +/*
  145.39 + * Tests various zipfs operations.
  145.40 + */
  145.41 +
  145.42 +public class ZipFSTester {
  145.43 +
  145.44 +    public static void main(String[] args) throws Throwable {
  145.45 +        FileSystem fs = null;
  145.46 +        try {
  145.47 +            fs = newZipFileSystem(Paths.get(args[0]), new HashMap<String, Object>());
  145.48 +            test(fs);
  145.49 +            test2(fs);   // more tests
  145.50 +        } finally {
  145.51 +            if (fs != null)
  145.52 +                fs.close();
  145.53 +        }
  145.54 +    }
  145.55 +
  145.56 +    static void test(FileSystem fs)
  145.57 +        throws Exception
  145.58 +    {
  145.59 +        Random rdm = new Random();
  145.60 +
  145.61 +        // clone a fs and test on it
  145.62 +        Path tmpfsPath = getTempPath();
  145.63 +        Map<String, Object> env = new HashMap<String, Object>();
  145.64 +        env.put("createNew", true);
  145.65 +        FileSystem fs0 = newZipFileSystem(tmpfsPath, env);
  145.66 +        z2zcopy(fs, fs0, "/", 0);
  145.67 +        fs0.close();                // sync to file
  145.68 +
  145.69 +        fs = newZipFileSystem(tmpfsPath, new HashMap<String, Object>());
  145.70 +
  145.71 +        try {
  145.72 +            // prepare a src
  145.73 +            Path src = getTempPath();
  145.74 +            String tmpName = src.toString();
  145.75 +            OutputStream os = src.newOutputStream();
  145.76 +            byte[] bits = new byte[12345];
  145.77 +            rdm.nextBytes(bits);
  145.78 +            os.write(bits);
  145.79 +            os.close();
  145.80 +
  145.81 +            // copyin
  145.82 +            Path dst = getPathWithParents(fs, tmpName);
  145.83 +            src.copyTo(dst);
  145.84 +            checkEqual(src, dst);
  145.85 +
  145.86 +            // copy
  145.87 +            Path dst2 = getPathWithParents(fs, "/xyz" + rdm.nextInt(100) +
  145.88 +                                           "/efg" + rdm.nextInt(100) + "/foo.class");
  145.89 +            dst.copyTo(dst2);
  145.90 +            //dst.moveTo(dst2);
  145.91 +            checkEqual(src, dst2);
  145.92 +
  145.93 +            // delete
  145.94 +            dst.delete();
  145.95 +            if (dst.exists())
  145.96 +                throw new RuntimeException("Failed!");
  145.97 +
  145.98 +            // moveout
  145.99 +            Path dst3 = Paths.get(tmpName + "_Tmp");
 145.100 +            dst2.moveTo(dst3);
 145.101 +            checkEqual(src, dst3);
 145.102 +
 145.103 +            // delete
 145.104 +            if (dst2.exists())
 145.105 +                throw new RuntimeException("Failed!");
 145.106 +            dst3.delete();
 145.107 +            if (dst3.exists())
 145.108 +                throw new RuntimeException("Failed!");
 145.109 +
 145.110 +            // newInputStream on dir
 145.111 +            Path parent = dst2.getParent();
 145.112 +            try {
 145.113 +                parent.newInputStream();
 145.114 +                throw new RuntimeException("Failed");
 145.115 +            } catch (FileSystemException e) {
 145.116 +                e.printStackTrace();    // expected fse
 145.117 +            }
 145.118 +
 145.119 +            // rmdirs
 145.120 +            try {
 145.121 +                rmdirs(parent);
 145.122 +            } catch (IOException x) {
 145.123 +                x.printStackTrace();
 145.124 +            }
 145.125 +
 145.126 +            // newFileChannel() copy in, out and verify via fch
 145.127 +            fchCopy(src, dst);    // in
 145.128 +            checkEqual(src, dst);
 145.129 +            Path tmp = Paths.get(tmpName + "_Tmp");
 145.130 +            fchCopy(dst, tmp);   //  out
 145.131 +            checkEqual(src, tmp);
 145.132 +            tmp.delete();
 145.133 +
 145.134 +            // test channels
 145.135 +            channel(fs, dst);
 145.136 +            dst.delete();
 145.137 +            src.delete();
 145.138 +        } finally {
 145.139 +            if (fs != null)
 145.140 +                fs.close();
 145.141 +            if (tmpfsPath.exists())
 145.142 +                tmpfsPath.delete();
 145.143 +        }
 145.144 +    }
 145.145 +
 145.146 +    static void test2(FileSystem fs) throws Exception {
 145.147 +
 145.148 +        Path fs1Path = getTempPath();
 145.149 +        Path fs2Path = getTempPath();
 145.150 +        Path fs3Path = getTempPath();
 145.151 +
 145.152 +        if (fs1Path.exists())
 145.153 +            fs1Path.delete();
 145.154 +        if (fs2Path.exists())
 145.155 +            fs2Path.delete();
 145.156 +        if (fs3Path.exists())
 145.157 +            fs3Path.delete();
 145.158 +
 145.159 +        // create a new filesystem, copy everything from fs
 145.160 +        Map<String, Object> env = new HashMap<String, Object>();
 145.161 +        env.put("createNew", true);
 145.162 +        FileSystem fs0 = newZipFileSystem(fs1Path, env);
 145.163 +
 145.164 +        final FileSystem fs2 = newZipFileSystem(fs2Path, env);
 145.165 +        final FileSystem fs3 = newZipFileSystem(fs3Path, env);
 145.166 +
 145.167 +        System.out.println("copy src: fs -> fs0...");
 145.168 +        z2zcopy(fs, fs0, "/", 0);   // copy fs -> fs1
 145.169 +        fs0.close();                // dump to file
 145.170 +
 145.171 +        System.out.println("open fs0 as fs1");
 145.172 +        env = new HashMap<String, Object>();
 145.173 +        final FileSystem fs1 = newZipFileSystem(fs1Path, env);
 145.174 +
 145.175 +        System.out.println("listing...");
 145.176 +        final ArrayList<String> files = new ArrayList<>();
 145.177 +        final ArrayList<String> dirs = new ArrayList<>();
 145.178 +        list(fs1.getPath("/"), files, dirs);
 145.179 +
 145.180 +        Thread t0 = new Thread(new Runnable() {
 145.181 +            public void run() {
 145.182 +                List<String> list = new ArrayList<>(dirs);
 145.183 +                Collections.shuffle(list);
 145.184 +                for (String path : list) {
 145.185 +                    try {
 145.186 +                        z2zcopy(fs1, fs2, path, 0);
 145.187 +                    } catch (Exception x) {
 145.188 +                        x.printStackTrace();
 145.189 +                    }
 145.190 +                }
 145.191 +            }
 145.192 +
 145.193 +        });
 145.194 +
 145.195 +        Thread t1 = new Thread(new Runnable() {
 145.196 +            public void run() {
 145.197 +                List<String> list = new ArrayList<>(dirs);
 145.198 +                Collections.shuffle(list);
 145.199 +                for (String path : list) {
 145.200 +                    try {
 145.201 +                        z2zcopy(fs1, fs2, path, 1);
 145.202 +                    } catch (Exception x) {
 145.203 +                        x.printStackTrace();
 145.204 +                    }
 145.205 +                }
 145.206 +            }
 145.207 +
 145.208 +        });
 145.209 +
 145.210 +        Thread t2 = new Thread(new Runnable() {
 145.211 +            public void run() {
 145.212 +                List<String> list = new ArrayList<>(dirs);
 145.213 +                Collections.shuffle(list);
 145.214 +                for (String path : list) {
 145.215 +                    try {
 145.216 +                        z2zcopy(fs1, fs2, path, 2);
 145.217 +                    } catch (Exception x) {
 145.218 +                        x.printStackTrace();
 145.219 +                    }
 145.220 +                }
 145.221 +            }
 145.222 +
 145.223 +        });
 145.224 +
 145.225 +        Thread t3 = new Thread(new Runnable() {
 145.226 +            public void run() {
 145.227 +                List<String> list = new ArrayList<>(files);
 145.228 +                Collections.shuffle(list);
 145.229 +                while (!list.isEmpty()) {
 145.230 +                    Iterator<String> itr = list.iterator();
 145.231 +                    while (itr.hasNext()) {
 145.232 +                        String path = itr.next();
 145.233 +                        try {
 145.234 +                            if (fs2.getPath(path).exists()) {
 145.235 +                                z2zmove(fs2, fs3, path);
 145.236 +                                itr.remove();
 145.237 +                            }
 145.238 +                        } catch (FileAlreadyExistsException x){
 145.239 +                            itr.remove();
 145.240 +                        } catch (Exception x) {
 145.241 +                            x.printStackTrace();
 145.242 +                        }
 145.243 +                    }
 145.244 +                }
 145.245 +            }
 145.246 +
 145.247 +        });
 145.248 +
 145.249 +        System.out.println("copying/removing...");
 145.250 +        t0.start(); t1.start(); t2.start(); t3.start();
 145.251 +        t0.join(); t1.join(); t2.join(); t3.join();
 145.252 +
 145.253 +        System.out.println("closing: fs1, fs2");
 145.254 +        fs1.close();
 145.255 +        fs2.close();
 145.256 +
 145.257 +        int failed = 0;
 145.258 +        System.out.println("checkEqual: fs vs fs3");
 145.259 +        for (String path : files) {
 145.260 +            try {
 145.261 +                checkEqual(fs.getPath(path), fs3.getPath(path));
 145.262 +            } catch (IOException x) {
 145.263 +                //x.printStackTrace();
 145.264 +                failed++;
 145.265 +            }
 145.266 +        }
 145.267 +        System.out.println("closing: fs3");
 145.268 +        fs3.close();
 145.269 +
 145.270 +        System.out.println("opening: fs3 as fs4");
 145.271 +        FileSystem fs4 = newZipFileSystem(fs3Path, env);
 145.272 +
 145.273 +
 145.274 +        ArrayList<String> files2 = new ArrayList<>();
 145.275 +        ArrayList<String> dirs2 = new ArrayList<>();
 145.276 +        list(fs4.getPath("/"), files2, dirs2);
 145.277 +
 145.278 +        System.out.println("checkEqual: fs vs fs4");
 145.279 +        for (String path : files2) {
 145.280 +            checkEqual(fs.getPath(path), fs4.getPath(path));
 145.281 +        }
 145.282 +        System.out.println("walking: fs4");
 145.283 +        walk(fs4.getPath("/"));
 145.284 +        System.out.println("closing: fs4");
 145.285 +        fs4.close();
 145.286 +
 145.287 +        System.out.printf("failed=%d%n", failed);
 145.288 +
 145.289 +        fs1Path.delete();
 145.290 +        fs2Path.delete();
 145.291 +        fs3Path.delete();
 145.292 +    }
 145.293 +
 145.294 +    private static FileSystem newZipFileSystem(Path path, Map<String, ?> env)
 145.295 +        throws IOException
 145.296 +    {
 145.297 +        return FileSystems.newFileSystem(
 145.298 +                   URI.create("zip" +
 145.299 +                               path.toUri().toString().substring(4)),
 145.300 +                   env,
 145.301 +                   null);
 145.302 +    }
 145.303 +
 145.304 +    private static Path getTempPath() throws IOException
 145.305 +    {
 145.306 +        File tmp = File.createTempFile("testzipfs_", "zip");
 145.307 +        tmp.delete();    // we need a clean path, no file
 145.308 +        return tmp.toPath();
 145.309 +    }
 145.310 +
 145.311 +    private static void list(Path path, List<String> files, List<String> dirs )
 145.312 +        throws IOException
 145.313 +    {
 145.314 +        if (Attributes.readBasicFileAttributes(path).isDirectory()) {
 145.315 +            DirectoryStream<Path> ds = path.newDirectoryStream();
 145.316 +            for (Path child : ds)
 145.317 +                list(child, files, dirs);
 145.318 +            ds.close();
 145.319 +            dirs.add(path.toString());
 145.320 +        } else {
 145.321 +            files.add(path.toString());
 145.322 +        }
 145.323 +    }
 145.324 +
 145.325 +    private static void z2zcopy(FileSystem src, FileSystem dst, String path,
 145.326 +                                int method)
 145.327 +        throws IOException
 145.328 +    {
 145.329 +        Path srcPath = src.getPath(path);
 145.330 +        Path dstPath = dst.getPath(path);
 145.331 +
 145.332 +        if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) {
 145.333 +            if (!dstPath.exists()) {
 145.334 +                try {
 145.335 +                    mkdirs(dstPath);
 145.336 +                } catch (FileAlreadyExistsException x) {}
 145.337 +            }
 145.338 +            DirectoryStream<Path> ds = srcPath.newDirectoryStream();
 145.339 +            for (Path child : ds) {
 145.340 +                z2zcopy(src, dst,
 145.341 +                        path + (path.endsWith("/")?"":"/") + child.getName(),
 145.342 +                        method);
 145.343 +            }
 145.344 +            ds.close();
 145.345 +        } else {
 145.346 +            try {
 145.347 +                if (dstPath.exists())
 145.348 +                    return;
 145.349 +                switch (method) {
 145.350 +                case 0:
 145.351 +                    srcPath.copyTo(dstPath);
 145.352 +                    break;
 145.353 +                case 1:
 145.354 +                    chCopy(srcPath, dstPath);
 145.355 +                    break;
 145.356 +                case 2:
 145.357 +                    //fchCopy(srcPath, dstPath);
 145.358 +                    streamCopy(srcPath, dstPath);
 145.359 +                    break;
 145.360 +                }
 145.361 +            } catch (FileAlreadyExistsException x) {}
 145.362 +        }
 145.363 +    }
 145.364 +
 145.365 +    private static void z2zmove(FileSystem src, FileSystem dst, String path)
 145.366 +        throws IOException
 145.367 +    {
 145.368 +        Path srcPath = src.getPath(path);
 145.369 +        Path dstPath = dst.getPath(path);
 145.370 +
 145.371 +        if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) {
 145.372 +            if (!dstPath.exists())
 145.373 +                mkdirs(dstPath);
 145.374 +            DirectoryStream<Path> ds = srcPath.newDirectoryStream();
 145.375 +            for (Path child : ds) {
 145.376 +                z2zmove(src, dst,
 145.377 +                        path + (path.endsWith("/")?"":"/") + child.getName());
 145.378 +            }
 145.379 +            ds.close();
 145.380 +        } else {
 145.381 +            //System.out.println("moving..." + path);
 145.382 +            Path parent = dstPath.getParent();
 145.383 +            if (parent != null && parent.notExists())
 145.384 +                mkdirs(parent);
 145.385 +            srcPath.moveTo(dstPath);
 145.386 +        }
 145.387 +    }
 145.388 +
 145.389 +    private static void walk(Path path) throws IOException
 145.390 +    {
 145.391 +        Files.walkFileTree(
 145.392 +            path,
 145.393 +            new SimpleFileVisitor<Path>() {
 145.394 +                private int indent = 0;
 145.395 +                private void indent() {
 145.396 +                    int n = 0;
 145.397 +                    while (n++ < indent)
 145.398 +                        System.out.printf(" ");
 145.399 +                }
 145.400 +
 145.401 +                @Override
 145.402 +                public FileVisitResult visitFile(Path file,
 145.403 +                                                 BasicFileAttributes attrs)
 145.404 +                {
 145.405 +                    indent();
 145.406 +                    System.out.printf("%s%n", file.getName().toString());
 145.407 +                    return FileVisitResult.CONTINUE;
 145.408 +                }
 145.409 +
 145.410 +                @Override
 145.411 +                public FileVisitResult preVisitDirectory(Path dir,
 145.412 +                                                         BasicFileAttributes attrs)
 145.413 +                {
 145.414 +                    indent();
 145.415 +                    System.out.printf("[%s]%n", dir.toString());
 145.416 +                    indent += 2;
 145.417 +                    return FileVisitResult.CONTINUE;
 145.418 +                }
 145.419 +
 145.420 +                @Override
 145.421 +                public FileVisitResult postVisitDirectory(Path dir,
 145.422 +                                                          IOException ioe)
 145.423 +                    throws IOException
 145.424 +                {
 145.425 +                    indent -= 2;
 145.426 +                    return FileVisitResult.CONTINUE;
 145.427 +                }
 145.428 +        });
 145.429 +    }
 145.430 +
 145.431 +    private static void mkdirs(Path path) throws IOException {
 145.432 +        path = path.toAbsolutePath();
 145.433 +        Path parent = path.getParent();
 145.434 +        if (parent != null) {
 145.435 +            if (parent.notExists())
 145.436 +                mkdirs(parent);
 145.437 +        }
 145.438 +        path.createDirectory();
 145.439 +    }
 145.440 +
 145.441 +    private static void rmdirs(Path path) throws IOException {
 145.442 +        while (path != null && path.getNameCount() != 0) {
 145.443 +            path.delete();
 145.444 +            path = path.getParent();
 145.445 +        }
 145.446 +    }
 145.447 +
 145.448 +    // check the content of two paths are equal
 145.449 +    private static void checkEqual(Path src, Path dst) throws IOException
 145.450 +    {
 145.451 +        //System.out.printf("checking <%s> vs <%s>...%n",
 145.452 +        //                  src.toString(), dst.toString());
 145.453 +
 145.454 +        //streams
 145.455 +        InputStream isSrc = src.newInputStream();
 145.456 +        InputStream isDst = dst.newInputStream();
 145.457 +        byte[] bufSrc = new byte[8192];
 145.458 +        byte[] bufDst = new byte[8192];
 145.459 +
 145.460 +        try {
 145.461 +            int nSrc = 0;
 145.462 +            while ((nSrc = isSrc.read(bufSrc)) != -1) {
 145.463 +                int nDst = 0;
 145.464 +                while (nDst < nSrc) {
 145.465 +                    int n = isDst.read(bufDst, nDst, nSrc - nDst);
 145.466 +                    if (n == -1) {
 145.467 +                        System.out.printf("checking <%s> vs <%s>...%n",
 145.468 +                                          src.toString(), dst.toString());
 145.469 +                        throw new RuntimeException("CHECK FAILED!");
 145.470 +                    }
 145.471 +                    nDst += n;
 145.472 +                }
 145.473 +                while (--nSrc >= 0) {
 145.474 +                    if (bufSrc[nSrc] != bufDst[nSrc]) {
 145.475 +                        System.out.printf("checking <%s> vs <%s>...%n",
 145.476 +                                          src.toString(), dst.toString());
 145.477 +                        throw new RuntimeException("CHECK FAILED!");
 145.478 +                    }
 145.479 +                    nSrc--;
 145.480 +                }
 145.481 +            }
 145.482 +        } finally {
 145.483 +            isSrc.close();
 145.484 +            isDst.close();
 145.485 +        }
 145.486 +
 145.487 +        // channels
 145.488 +        SeekableByteChannel chSrc = src.newByteChannel();
 145.489 +        SeekableByteChannel chDst = dst.newByteChannel();
 145.490 +        if (chSrc.size() != chDst.size()) {
 145.491 +            System.out.printf("src[%s].size=%d, dst[%s].size=%d%n",
 145.492 +                              chSrc.toString(), chSrc.size(),
 145.493 +                              chDst.toString(), chDst.size());
 145.494 +            throw new RuntimeException("CHECK FAILED!");
 145.495 +        }
 145.496 +        ByteBuffer bbSrc = ByteBuffer.allocate(8192);
 145.497 +        ByteBuffer bbDst = ByteBuffer.allocate(8192);
 145.498 +
 145.499 +        try {
 145.500 +            int nSrc = 0;
 145.501 +            while ((nSrc = chSrc.read(bbSrc)) != -1) {
 145.502 +                int nDst = chDst.read(bbDst);
 145.503 +                if (nSrc != nDst) {
 145.504 +                    System.out.printf("checking <%s> vs <%s>...%n",
 145.505 +                                      src.toString(), dst.toString());
 145.506 +                    throw new RuntimeException("CHECK FAILED!");
 145.507 +                }
 145.508 +                while (--nSrc >= 0) {
 145.509 +                    if (bbSrc.get(nSrc) != bbDst.get(nSrc)) {
 145.510 +                        System.out.printf("checking <%s> vs <%s>...%n",
 145.511 +                                          src.toString(), dst.toString());
 145.512 +                        throw new RuntimeException("CHECK FAILED!");
 145.513 +                    }
 145.514 +                    nSrc--;
 145.515 +                }
 145.516 +                bbSrc.flip();
 145.517 +                bbDst.flip();
 145.518 +            }
 145.519 +        } catch (IOException x) {
 145.520 +            x.printStackTrace();
 145.521 +        } finally {
 145.522 +            chSrc.close();
 145.523 +            chDst.close();
 145.524 +        }
 145.525 +    }
 145.526 +
 145.527 +    private static void fchCopy(Path src, Path dst) throws IOException
 145.528 +    {
 145.529 +        Set<OpenOption> read = new HashSet<>();
 145.530 +        read.add(READ);
 145.531 +        Set<OpenOption> openwrite = new HashSet<>();
 145.532 +        openwrite.add(CREATE_NEW);
 145.533 +        openwrite.add(WRITE);
 145.534 +
 145.535 +        FileChannel srcFc = src.getFileSystem()
 145.536 +                               .provider()
 145.537 +                               .newFileChannel(src, read);
 145.538 +        FileChannel dstFc = dst.getFileSystem()
 145.539 +                               .provider()
 145.540 +                               .newFileChannel(dst, openwrite);
 145.541 +
 145.542 +        try {
 145.543 +            ByteBuffer bb = ByteBuffer.allocate(8192);
 145.544 +            while (srcFc.read(bb) >= 0) {
 145.545 +                bb.flip();
 145.546 +                dstFc.write(bb);
 145.547 +                bb.clear();
 145.548 +            }
 145.549 +        } finally {
 145.550 +            srcFc.close();
 145.551 +            dstFc.close();
 145.552 +        }
 145.553 +    }
 145.554 +
 145.555 +    private static void chCopy(Path src, Path dst) throws IOException
 145.556 +    {
 145.557 +        Set<OpenOption> read = new HashSet<>();
 145.558 +        read.add(READ);
 145.559 +        Set<OpenOption> openwrite = new HashSet<>();
 145.560 +        openwrite.add(CREATE_NEW);
 145.561 +        openwrite.add(WRITE);
 145.562 +
 145.563 +        SeekableByteChannel srcCh = src.newByteChannel(read);
 145.564 +        SeekableByteChannel dstCh = dst.newByteChannel(openwrite);
 145.565 +
 145.566 +        try {
 145.567 +            ByteBuffer bb = ByteBuffer.allocate(8192);
 145.568 +            while (srcCh.read(bb) >= 0) {
 145.569 +                bb.flip();
 145.570 +                dstCh.write(bb);
 145.571 +                bb.clear();
 145.572 +            }
 145.573 +        } finally {
 145.574 +            srcCh.close();
 145.575 +            dstCh.close();
 145.576 +        }
 145.577 +    }
 145.578 +
 145.579 +    private static void streamCopy(Path src, Path dst) throws IOException
 145.580 +    {
 145.581 +        InputStream isSrc = src.newInputStream();
 145.582 +        OutputStream osDst = dst.newOutputStream();
 145.583 +        byte[] buf = new byte[8192];
 145.584 +        try {
 145.585 +            int n = 0;
 145.586 +            while ((n = isSrc.read(buf)) != -1) {
 145.587 +                osDst.write(buf, 0, n);
 145.588 +            }
 145.589 +        } finally {
 145.590 +            isSrc.close();
 145.591 +            osDst.close();
 145.592 +        }
 145.593 +    }
 145.594 +
 145.595 +    static void channel(FileSystem fs, Path path)
 145.596 +        throws Exception
 145.597 +    {
 145.598 +        System.out.println("test ByteChannel...");
 145.599 +        SeekableByteChannel sbc = path.newByteChannel();
 145.600 +        Set<OpenOption> read = new HashSet<>();
 145.601 +        read.add(READ);
 145.602 +        System.out.printf("   sbc[0]: pos=%d, size=%d%n", sbc.position(), sbc.size());
 145.603 +        ByteBuffer bb = ByteBuffer.allocate((int)sbc.size());
 145.604 +        int n = sbc.read(bb);
 145.605 +        System.out.printf("   sbc[1]: read=%d, pos=%d, size=%d%n",
 145.606 +                          n, sbc.position(), sbc.size());
 145.607 +        ByteBuffer bb2 = ByteBuffer.allocate((int)sbc.size());
 145.608 +        int N = 120;
 145.609 +        sbc.close();
 145.610 +
 145.611 +        // sbc.position(pos) is not supported in current version
 145.612 +        // try the FileChannel
 145.613 +        sbc = fs.provider().newFileChannel(path, read);
 145.614 +        sbc.position(N);
 145.615 +        System.out.printf("   sbc[2]: pos=%d, size=%d%n",
 145.616 +                          sbc.position(), sbc.size());
 145.617 +        bb2.limit(100);
 145.618 +        n = sbc.read(bb2);
 145.619 +        System.out.printf("   sbc[3]: read=%d, pos=%d, size=%d%n",
 145.620 +                          n, sbc.position(), sbc.size());
 145.621 +        System.out.printf("   sbc[4]: bb[%d]=%d, bb1[0]=%d%n",
 145.622 +                          N, bb.get(N) & 0xff, bb2.get(0) & 0xff);
 145.623 +        sbc.close();
 145.624 +    }
 145.625 +
 145.626 +    // create parents if does not exist
 145.627 +    static Path getPathWithParents(FileSystem fs, String name)
 145.628 +        throws Exception
 145.629 +    {
 145.630 +        Path path = fs.getPath(name);
 145.631 +        Path parent = path.getParent();
 145.632 +        if (parent != null && parent.notExists())
 145.633 +            mkdirs(parent);
 145.634 +        return path;
 145.635 +    }
 145.636 +}
   146.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   146.2 +++ b/test/demo/zipfs/basic.sh	Tue Oct 12 12:51:48 2010 -0700
   146.3 @@ -0,0 +1,73 @@
   146.4 +#
   146.5 +# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
   146.6 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   146.7 +# 
   146.8 +# This code is free software; you can redistribute it and/or modify it
   146.9 +# under the terms of the GNU General Public License version 2 only, as
  146.10 +# published by the Free Software Foundation.
  146.11 +# 
  146.12 +# This code is distributed in the hope that it will be useful, but WITHOUT
  146.13 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  146.14 +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  146.15 +# version 2 for more details (a copy is included in the LICENSE file that
  146.16 +# accompanied this code).
  146.17 +# 
  146.18 +# You should have received a copy of the GNU General Public License version
  146.19 +# 2 along with this work; if not, write to the Free Software Foundation,
  146.20 +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  146.21 +# 
  146.22 +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  146.23 +# or visit www.oracle.com if you need additional information or have any
  146.24 +# questions.
  146.25 +#
  146.26 +# @test
  146.27 +# @bug 6990846
  146.28 +# @summary Test ZipFileSystem demo
  146.29 +# @build Basic PathOps ZipFSTester
  146.30 +# @run shell basic.sh
  146.31 +
  146.32 +if [ -z "${TESTJAVA}" ]; then
  146.33 +    echo "Test must be run with jtreg"
  146.34 +    exit 0
  146.35 +fi
  146.36 +
  146.37 +ZIPFS="${TESTJAVA}/demo/nio/zipfs/zipfs.jar"
  146.38 +if [ ! -r "${ZIPFS}" ]; then
  146.39 +    echo "${ZIPFS} not found"
  146.40 +    exit 0
  146.41 +fi
  146.42 +
  146.43 +OS=`uname -s`
  146.44 +case "$OS" in
  146.45 +    Windows_* )
  146.46 +        CLASSPATH="${TESTCLASSES};${ZIPFS}"
  146.47 +        ;;
  146.48 +    * )
  146.49 +        CLASSPATH="${TESTCLASSES}:${ZIPFS}"
  146.50 +        ;;
  146.51 +esac
  146.52 +export CLASSPATH
  146.53 +
  146.54 +failures=0
  146.55 +
  146.56 +go() {
  146.57 +    echo ""
  146.58 +    ${TESTJAVA}/bin/java $1 $2 $3 2>&1
  146.59 +    if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
  146.60 +}
  146.61 +
  146.62 +# Run the tests
  146.63 +
  146.64 +go Basic "${ZIPFS}"
  146.65 +go PathOps "${ZIPFS}"
  146.66 +go ZipFSTester "${ZIPFS}"
  146.67 +
  146.68 +#
  146.69 +# Results
  146.70 +#
  146.71 +
  146.72 +if [ $failures -gt 0 ];
  146.73 +then echo "$failures tests failed";
  146.74 +else echo "All tests passed";
  146.75 +fi
  146.76 +exit $failures
   147.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   147.2 +++ b/test/java/awt/Focus/FocusOwnerFrameOnClick/FocusOwnerFrameOnClick.java	Tue Oct 12 12:51:48 2010 -0700
   147.3 @@ -0,0 +1,125 @@
   147.4 +/*
   147.5 + * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
   147.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   147.7 + *
   147.8 + * This code is free software; you can redistribute it and/or modify it
   147.9 + * under the terms of the GNU General Public License version 2 only, as
  147.10 + * published by the Free Software Foundation.  Oracle designates this
  147.11 + * particular file as subject to the "Classpath" exception as provided
  147.12 + * by Oracle in the LICENSE file that accompanied this code.
  147.13 + *
  147.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
  147.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  147.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  147.17 + * version 2 for more details (a copy is included in the LICENSE file that
  147.18 + * accompanied this code).
  147.19 + *
  147.20 + * You should have received a copy of the GNU General Public License version
  147.21 + * 2 along with this work; if not, write to the Free Software Foundation,
  147.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  147.23 + *
  147.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  147.25 + * or visit www.oracle.com if you need additional information or have any
  147.26 + * questions.
  147.27 + */
  147.28 +
  147.29 +/*
  147.30 +  @test      FocusOwnerFrameOnClick.java %W% %E%
  147.31 +  @bug       6886678
  147.32 +  @summary   Tests that clicking an owner frame switches focus from its owned window.
  147.33 +  @author    Anton Tarasov: area=awt.focus
  147.34 +  @library   ../../regtesthelpers
  147.35 +  @build     Util
  147.36 +  @run       main FocusOwnerFrameOnClick
  147.37 +*/
  147.38 +
  147.39 +import java.awt.*;
  147.40 +import java.awt.event.*;
  147.41 +import java.applet.Applet;
  147.42 +import java.util.concurrent.atomic.AtomicBoolean;
  147.43 +import java.lang.reflect.InvocationTargetException;
  147.44 +import test.java.awt.regtesthelpers.Util;
  147.45 +
  147.46 +public class FocusOwnerFrameOnClick extends Applet {
  147.47 +    Robot robot;
  147.48 +    Frame frame = new Frame("Frame");
  147.49 +    Window window = new Window(frame);
  147.50 +    Button fButton = new Button("fButton");
  147.51 +    Button wButton = new Button("wButton");
  147.52 +
  147.53 +    AtomicBoolean focused = new AtomicBoolean(false);
  147.54 +
  147.55 +    public static void main(String[] args) {
  147.56 +        FocusOwnerFrameOnClick app = new FocusOwnerFrameOnClick();
  147.57 +        app.init();
  147.58 +        app.start();
  147.59 +    }
  147.60 +
  147.61 +    public void init() {
  147.62 +        robot = Util.createRobot();
  147.63 +
  147.64 +        frame.setLayout(new FlowLayout());
  147.65 +        frame.setSize(200, 200);
  147.66 +        frame.add(fButton);
  147.67 +
  147.68 +        window.setLocation(300, 0);
  147.69 +        window.add(wButton);
  147.70 +        window.pack();
  147.71 +    }
  147.72 +
  147.73 +    public void start() {
  147.74 +        frame.setVisible(true);
  147.75 +        Util.waitForIdle(robot);
  147.76 +
  147.77 +        window.setVisible(true);
  147.78 +        Util.waitForIdle(robot);
  147.79 +
  147.80 +        if (!wButton.hasFocus()) {
  147.81 +            if (!Util.trackFocusGained(wButton, new Runnable() {
  147.82 +                    public void run() {
  147.83 +                        Util.clickOnComp(wButton, robot);
  147.84 +                    }
  147.85 +                }, 2000, false))
  147.86 +            {
  147.87 +                throw new TestErrorException("wButton didn't gain focus on showing");
  147.88 +            }
  147.89 +        }
  147.90 +
  147.91 +        Runnable clickAction = new Runnable() {
  147.92 +                public void run() {
  147.93 +                    Point loc = fButton.getLocationOnScreen();
  147.94 +                    Dimension dim = fButton.getSize();
  147.95 +
  147.96 +                    robot.mouseMove(loc.x, loc.y + dim.height + 20);
  147.97 +                    robot.delay(50);
  147.98 +                    robot.mousePress(InputEvent.BUTTON1_MASK);
  147.99 +                    robot.delay(50);
 147.100 +                    robot.mouseRelease(InputEvent.BUTTON1_MASK);
 147.101 +                }
 147.102 +            };
 147.103 +
 147.104 +        if (!Util.trackWindowGainedFocus(frame, clickAction, 2000, true)) {
 147.105 +            throw new TestFailedException("The frame wasn't focused on click");
 147.106 +        }
 147.107 +
 147.108 +        System.out.println("Test passed.");
 147.109 +    }
 147.110 +}
 147.111 +
 147.112 +/**
 147.113 + * Thrown when the behavior being verified is found wrong.
 147.114 + */
 147.115 +class TestFailedException extends RuntimeException {
 147.116 +    TestFailedException(String msg) {
 147.117 +        super("Test failed: " + msg);
 147.118 +    }
 147.119 +}
 147.120 +
 147.121 +/**
 147.122 + * Thrown when an error not related to the behavior being verified is encountered.
 147.123 + */
 147.124 +class TestErrorException extends RuntimeException {
 147.125 +    TestErrorException(String msg) {
 147.126 +        super("Unexpected error: " + msg);
 147.127 +    }
 147.128 +}
   148.1 --- a/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java	Thu Oct 07 15:12:19 2010 -0700
   148.2 +++ b/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java	Tue Oct 12 12:51:48 2010 -0700
   148.3 @@ -21,16 +21,15 @@
   148.4      static final int SHIFT = 1;
   148.5      static final int CTRL = 2;
   148.6      static final int ALT = 3;
   148.7 -    static CheckingModifierAdapter adapterTest1;
   148.8 -    static CheckingModifierAdapter adapterTest2;
   148.9 -    static CheckingModifierAdapter adapterTest3;
  148.10 -    static CheckingModifierAdapter adapterTest4;
  148.11 +    static CheckingModifierAdapterExtra adapterTest1;
  148.12 +    static CheckingModifierAdapterExtra adapterTest2;
  148.13 +    static CheckingModifierAdapterExtra adapterTest3;
  148.14 +    static CheckingModifierAdapterExtra adapterTest4;
  148.15  
  148.16      static boolean debug = true; //dump all errors (debug) or throw first(under jtreg) exception
  148.17      static boolean autorun = false; //use robot or manual run
  148.18      static int testModifier = NONE;
  148.19  
  148.20 -    static int [] mouseButtons;
  148.21      static int [] mouseButtonDownMasks;
  148.22  
  148.23      //an arrays representing a modifiersEx of extra mouse buttons while using ALT/CTRL/SHIFT or none of them
  148.24 @@ -39,7 +38,6 @@
  148.25      static int [] modifiersExStandardCTRL;
  148.26      static int [] modifiersExStandardALT;
  148.27  
  148.28 -    //    final static int [] mouseButtons = new int [] {MouseEvent.BUTTON1_MASK, MouseEvent.BUTTON2_MASK, MouseEvent.BUTTON3_MASK};
  148.29      // BUTTON1, 2, 3 press-release.
  148.30      final static int  modifiersStandard = 0; //InputEvent.BUTTON_DOWN_MASK;
  148.31  
  148.32 @@ -56,7 +54,7 @@
  148.33  
  148.34          if (modifiersEx != curStandardExModifiers[index]){
  148.35  //            System.out.println(">>>>>>>>>>>>>>> Pressed. modifiersEx "+modifiersEx +" : "+!= curStandardExModifiers");
  148.36 -            MessageLogger.reportError("Test failed :  Pressed. modifiersEx != curStandardExModifiers");
  148.37 +            MessageLogger.reportError("Test failed :  Pressed. modifiersEx != curStandardExModifiers. Got: " + modifiersEx + " , Expected: " + curStandardExModifiers[index]);
  148.38          }
  148.39  
  148.40       //check event.paramString() output
  148.41 @@ -168,7 +166,7 @@
  148.42          }
  148.43  
  148.44          if (modifiersEx != curStandardExModifiers[index]){
  148.45 -            MessageLogger.reportError("Test failed :  Released. modifiersEx != curStandardExModifiers");
  148.46 +            MessageLogger.reportError("Test failed :  Released. modifiersEx != curStandardExModifiers. Got: " + modifiersEx + " , Expected: " + curStandardExModifiers[index]);
  148.47          }
  148.48  
  148.49       //check event.paramString() output
  148.50 @@ -191,7 +189,7 @@
  148.51          }
  148.52  
  148.53          if (modifiersEx != curStandardExModifiers[index]){
  148.54 -            MessageLogger.reportError("Test failed :  Clicked. modifiersEx != curStandardExModifiers");
  148.55 +            MessageLogger.reportError("Test failed :  Clicked. modifiersEx != curStandardExModifiers. Got: " + modifiersEx + " , Expected: " + curStandardExModifiers[index]);
  148.56          }
  148.57  
  148.58       //check event.paramString() output
  148.59 @@ -275,11 +273,11 @@
  148.60          this.addMouseListener(adapterTest1);
  148.61          robot.delay(1000);
  148.62          robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
  148.63 -        for (int i = 3; i< mouseButtons.length; i++){
  148.64 -            System.out.println("testNONE() => " +mouseButtons[i] );
  148.65 -            robot.mousePress(mouseButtons[i]);
  148.66 +        for (int i = 3; i< mouseButtonDownMasks.length; i++){
  148.67 +            System.out.println("testNONE() => " +mouseButtonDownMasks[i] );
  148.68 +            robot.mousePress(mouseButtonDownMasks[i]);
  148.69              robot.delay(100);
  148.70 -            robot.mouseRelease(mouseButtons[i]);
  148.71 +            robot.mouseRelease(mouseButtonDownMasks[i]);
  148.72          }
  148.73          robot.delay(1000);
  148.74          this.removeMouseListener(adapterTest1);
  148.75 @@ -289,12 +287,12 @@
  148.76          this.addMouseListener(adapterTest2);
  148.77          robot.delay(1000);
  148.78          robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
  148.79 -        for (int i = 3; i< mouseButtons.length; i++){
  148.80 +        for (int i = 3; i< mouseButtonDownMasks.length; i++){
  148.81              robot.keyPress(KeyEvent.VK_SHIFT);
  148.82 -            System.out.println("testSHIFT() => " +mouseButtons[i] );
  148.83 -            robot.mousePress(mouseButtons[i]);
  148.84 +            System.out.println("testSHIFT() => " +mouseButtonDownMasks[i] );
  148.85 +            robot.mousePress(mouseButtonDownMasks[i]);
  148.86              robot.delay(100);
  148.87 -            robot.mouseRelease(mouseButtons[i]);
  148.88 +            robot.mouseRelease(mouseButtonDownMasks[i]);
  148.89              robot.keyRelease(KeyEvent.VK_SHIFT);
  148.90          }
  148.91          robot.delay(1000);
  148.92 @@ -305,12 +303,12 @@
  148.93          this.addMouseListener(adapterTest3);
  148.94          robot.delay(1000);
  148.95          robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
  148.96 -        for (int i = 3; i< mouseButtons.length; i++){
  148.97 +        for (int i = 3; i< mouseButtonDownMasks.length; i++){
  148.98              robot.keyPress(KeyEvent.VK_CONTROL);
  148.99 -            System.out.println("testCTRL() => " +mouseButtons[i] );
 148.100 -            robot.mousePress(mouseButtons[i]);
 148.101 +            System.out.println("testCTRL() => " +mouseButtonDownMasks[i] );
 148.102 +            robot.mousePress(mouseButtonDownMasks[i]);
 148.103              robot.delay(100);
 148.104 -            robot.mouseRelease(mouseButtons[i]);
 148.105 +            robot.mouseRelease(mouseButtonDownMasks[i]);
 148.106              robot.keyRelease(KeyEvent.VK_CONTROL);
 148.107          }
 148.108          robot.delay(1000);
 148.109 @@ -321,12 +319,12 @@
 148.110          this.addMouseListener(adapterTest4);
 148.111          robot.delay(1000);
 148.112          robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
 148.113 -        for (int i = 3; i< mouseButtons.length; i++){
 148.114 +        for (int i = 3; i< mouseButtonDownMasks.length; i++){
 148.115              robot.keyPress(KeyEvent.VK_ALT);
 148.116 -            System.out.println("testALT() => " +mouseButtons[i] );
 148.117 -            robot.mousePress(mouseButtons[i]);
 148.118 +            System.out.println("testALT() => " +mouseButtonDownMasks[i] );
 148.119 +            robot.mousePress(mouseButtonDownMasks[i]);
 148.120              robot.delay(100);
 148.121 -            robot.mouseRelease(mouseButtons[i]);
 148.122 +            robot.mouseRelease(mouseButtonDownMasks[i]);
 148.123              robot.keyRelease(KeyEvent.VK_ALT);
 148.124          }
 148.125          robot.delay(1000);
 148.126 @@ -368,52 +366,52 @@
 148.127      }
 148.128  
 148.129      public static void initAdapters(){
 148.130 -        adapterTest1 = new CheckingModifierAdapter(NONE);
 148.131 -        adapterTest2 = new CheckingModifierAdapter(SHIFT);
 148.132 -        adapterTest3 = new CheckingModifierAdapter(CTRL);
 148.133 -        adapterTest4 = new CheckingModifierAdapter(ALT);
 148.134 +        adapterTest1 = new CheckingModifierAdapterExtra(NONE);
 148.135 +        adapterTest2 = new CheckingModifierAdapterExtra(SHIFT);
 148.136 +        adapterTest3 = new CheckingModifierAdapterExtra(CTRL);
 148.137 +        adapterTest4 = new CheckingModifierAdapterExtra(ALT);
 148.138      }
 148.139  
 148.140      public static void initVars(){
 148.141 -        int [] tmp = new int [MouseInfo.getNumberOfButtons()];
 148.142 -        for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
 148.143 -            tmp[i] = InputEvent.getMaskForButton(i+1);
 148.144 -            //            System.out.println("TEST: "+tmp[i]);
 148.145 +        //Init the array of the mouse button masks. It will be used for generating mouse events.
 148.146 +        mouseButtonDownMasks = new int [MouseInfo.getNumberOfButtons()];
 148.147 +        for (int i = 0; i < mouseButtonDownMasks.length; i++){
 148.148 +            mouseButtonDownMasks[i] = InputEvent.getMaskForButton(i+1);
 148.149 +            System.out.println("MouseArray [i] == "+mouseButtonDownMasks[i]);
 148.150          }
 148.151  
 148.152 -        mouseButtons = Arrays.copyOf(tmp, tmp.length);
 148.153 -
 148.154 -        for (int i = 0; i < mouseButtons.length; i++){
 148.155 -            System.out.println("MouseArray [i] == "+mouseButtons[i]);
 148.156 -        }
 148.157 -
 148.158 -        mouseButtonDownMasks = Arrays.copyOf(tmp, tmp.length);
 148.159 -
 148.160          // So we need to get the number of extra buttons on the mouse:  "MouseInfo.getNumberOfButtons() - 3"
 148.161          // and multyply on 3 because each button will generate three events : PRESS, RELEASE and CLICK.
 148.162 -        tmp = new int [(MouseInfo.getNumberOfButtons()-3)*3];
 148.163 +        int [] tmp = new int [(MouseInfo.getNumberOfButtons()-3)*3];
 148.164 +
 148.165 +        //Fill array of expected results for the case when mouse buttons are only used (no-modifier keys)
 148.166          Arrays.fill(tmp, 0);
 148.167 -
 148.168          for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
 148.169              tmp[i] = mouseButtonDownMasks[j];
 148.170          }
 148.171          modifiersExStandard = Arrays.copyOf(tmp, tmp.length);
 148.172  
 148.173 +        //Fill array of expected results for the case when mouse buttons are only used with SHIFT modifier key
 148.174          Arrays.fill(tmp, InputEvent.SHIFT_DOWN_MASK);
 148.175 -        for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){
 148.176 -            tmp[i] = tmp[j] | mouseButtonDownMasks[j];
 148.177 +        for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
 148.178 +            System.out.println("modifiersExStandardSHIFT FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]);
 148.179 +            tmp[i] = tmp[i] | mouseButtonDownMasks[j];
 148.180          }
 148.181          modifiersExStandardSHIFT = Arrays.copyOf(tmp, tmp.length);
 148.182  
 148.183 +        //Fill array of expected results for the case when mouse buttons are only used with CTRL modifier key
 148.184          Arrays.fill(tmp, InputEvent.CTRL_DOWN_MASK);
 148.185 -        for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){
 148.186 -            tmp[i] = tmp[j] | mouseButtonDownMasks[j];
 148.187 +        for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
 148.188 +            System.out.println("modifiersExStandardCTRL FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]);
 148.189 +            tmp[i] = tmp[i] | mouseButtonDownMasks[j];
 148.190          }
 148.191          modifiersExStandardCTRL = Arrays.copyOf(tmp, tmp.length);
 148.192  
 148.193 +        //Fill array of expected results for the case when mouse buttons are only used with ALT modifier key
 148.194          Arrays.fill(tmp, InputEvent.ALT_DOWN_MASK);
 148.195 -        for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){
 148.196 -            tmp[i] = tmp[j] | mouseButtonDownMasks[j];
 148.197 +        for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
 148.198 +            System.out.println("modifiersExStandardALT FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]);
 148.199 +            tmp[i] = tmp[i] | mouseButtonDownMasks[j];
 148.200          }
 148.201          modifiersExStandardALT = Arrays.copyOf(tmp, tmp.length);
 148.202      }
 148.203 @@ -436,9 +434,9 @@
 148.204  /* A class that invoke appropriate verification
 148.205   * routine with current modifier.
 148.206   */
 148.207 -class CheckingModifierAdapter extends MouseAdapter{
 148.208 +class CheckingModifierAdapterExtra extends MouseAdapter{
 148.209      int modifier;
 148.210 -    public CheckingModifierAdapter(int modifier){
 148.211 +    public CheckingModifierAdapterExtra(int modifier){
 148.212          this.modifier = modifier;
 148.213      }
 148.214  
   149.1 --- a/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java	Thu Oct 07 15:12:19 2010 -0700
   149.2 +++ b/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java	Tue Oct 12 12:51:48 2010 -0700
   149.3 @@ -90,7 +90,7 @@
   149.4          int [] buttonMasks = new int[MouseInfo.getNumberOfButtons()]; // = InputEvent.getButtonDownMasks();
   149.5          for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
   149.6              buttonMasks[i] = InputEvent.getMaskForButton(i+1);
   149.7 -            System.out.println("TEST: "+buttonMasks[i]);
   149.8 +            System.out.println("TEST: buttonMasks["+ i +"] = " + buttonMasks[i]);
   149.9          }
  149.10  
  149.11          for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
   150.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   150.2 +++ b/test/java/awt/image/GetSamplesTest.java	Tue Oct 12 12:51:48 2010 -0700
   150.3 @@ -0,0 +1,121 @@
   150.4 +/*
   150.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
   150.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   150.7 + *
   150.8 + * This code is free software; you can redistribute it and/or modify it
   150.9 + * under the terms of the GNU General Public License version 2 only, as
  150.10 + * published by the Free Software Foundation.
  150.11 + *
  150.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  150.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  150.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  150.15 + * version 2 for more details (a copy is included in the LICENSE file that
  150.16 + * accompanied this code).
  150.17 + *
  150.18 + * You should have received a copy of the GNU General Public License version
  150.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  150.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  150.21 + *
  150.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  150.23 + * or visit www.oracle.com if you need additional information or have any
  150.24 + * questions.
  150.25 + */
  150.26 +
  150.27 +/*
  150.28 + * @test
  150.29 + * @bug     6735275
  150.30 + * @summary Test verifies that SampleModel.getSamples() throws an appropriate
  150.31 + *           exception if coordinates are not in bounds.
  150.32 + *
  150.33 + * @run     main GetSamplesTest
  150.34 + */
  150.35 +
  150.36 +import java.awt.image.BandedSampleModel;
  150.37 +import java.awt.image.ComponentSampleModel;
  150.38 +import java.awt.image.DataBuffer;
  150.39 +import java.awt.image.MultiPixelPackedSampleModel;
  150.40 +import java.awt.image.PixelInterleavedSampleModel;
  150.41 +import java.awt.image.SampleModel;
  150.42 +import java.awt.image.SinglePixelPackedSampleModel;
  150.43 +import java.util.Vector;
  150.44 +
  150.45 +public class GetSamplesTest {
  150.46 +
  150.47 +    public static int width = 100;
  150.48 +    public static int height = 100;
  150.49 +    public static int dataType = DataBuffer.TYPE_BYTE;
  150.50 +    public static int numBands = 4;
  150.51 +
  150.52 +    public static void main(String[] args) {
  150.53 +        Vector<Class<? extends SampleModel>> classes = new Vector<Class<? extends SampleModel>>();
  150.54 +
  150.55 +        classes.add(ComponentSampleModel.class);
  150.56 +        classes.add(MultiPixelPackedSampleModel.class);
  150.57 +        classes.add(SinglePixelPackedSampleModel.class);
  150.58 +        classes.add(BandedSampleModel.class);
  150.59 +        classes.add(PixelInterleavedSampleModel.class);
  150.60 +
  150.61 +        for (Class<? extends SampleModel> c : classes) {
  150.62 +            doTest(c);
  150.63 +        }
  150.64 +    }
  150.65 +    private static void doTest(Class<? extends SampleModel> c) {
  150.66 +        System.out.println("Test for: " + c.getName());
  150.67 +        SampleModel sm = createSampleModel(c);
  150.68 +
  150.69 +        DataBuffer db = sm.createDataBuffer();
  150.70 +
  150.71 +        int[] iArray = new int[ width * height + numBands];
  150.72 +        float[] fArray = new float[ width * height + numBands];
  150.73 +        double[] dArray = new double[ width * height + numBands];
  150.74 +
  150.75 +        boolean iOk = false;
  150.76 +        boolean fOk = false;
  150.77 +        boolean dOk = false;
  150.78 +
  150.79 +        try {
  150.80 +            sm.getSamples(Integer.MAX_VALUE, 0, 1, 1, 0, iArray, db);
  150.81 +        } catch (ArrayIndexOutOfBoundsException e) {
  150.82 +            System.out.println(e.getMessage());
  150.83 +            iOk = true;
  150.84 +        }
  150.85 +
  150.86 +        try {
  150.87 +            sm.getSamples(Integer.MAX_VALUE, 0, 1, 1, 0, fArray, db);
  150.88 +        } catch (ArrayIndexOutOfBoundsException e) {
  150.89 +            System.out.println(e.getMessage());
  150.90 +            fOk = true;
  150.91 +        }
  150.92 +
  150.93 +        try {
  150.94 +            sm.getSamples(0, Integer.MAX_VALUE, 1, 1, 0, dArray, db);
  150.95 +        } catch (ArrayIndexOutOfBoundsException e) {
  150.96 +            System.out.println(e.getMessage());
  150.97 +            dOk = true;
  150.98 +        }
  150.99 +        if (!iOk || !fOk || !dOk) {
 150.100 +            throw new RuntimeException("Test for " + c.getSimpleName() +
 150.101 +                    " failed: iOk=" + iOk + "; fOk=" + fOk + "; dOk=" + dOk);
 150.102 +        }
 150.103 +    }
 150.104 +
 150.105 +    private static SampleModel createSampleModel(Class<? extends SampleModel> cls) {
 150.106 +        SampleModel res = null;
 150.107 +
 150.108 +        if (cls == ComponentSampleModel.class) {
 150.109 +            res = new ComponentSampleModel(dataType, width, height, 4, width * 4, new int[] { 0, 1, 2, 3 } );
 150.110 +        } else if (cls == MultiPixelPackedSampleModel.class) {
 150.111 +            res = new MultiPixelPackedSampleModel(dataType, width, height, 4);
 150.112 +        } else if (cls == SinglePixelPackedSampleModel.class) {
 150.113 +            res = new SinglePixelPackedSampleModel(dataType, width, height,
 150.114 +                    new int[]{ 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff });
 150.115 +        } else if (cls == BandedSampleModel.class) {
 150.116 +            res = new BandedSampleModel(dataType, width, height, numBands);
 150.117 +        } else if (cls == PixelInterleavedSampleModel.class) {
 150.118 +            res = new PixelInterleavedSampleModel(dataType, width, height, 4, width * 4, new int[] { 0, 1, 2, 3 });
 150.119 +        } else {
 150.120 +            throw new RuntimeException("Unknown class " + cls);
 150.121 +        }
 150.122 +        return res;
 150.123 +    }
 150.124 +}
   151.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   151.2 +++ b/test/java/beans/Introspector/6976577/Test6976577.java	Tue Oct 12 12:51:48 2010 -0700
   151.3 @@ -0,0 +1,71 @@
   151.4 +/*
   151.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
   151.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   151.7 + *
   151.8 + * This code is free software; you can redistribute it and/or modify it
   151.9 + * under the terms of the GNU General Public License version 2 only, as
  151.10 + * published by the Free Software Foundation.
  151.11 + *
  151.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  151.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  151.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  151.15 + * version 2 for more details (a copy is included in the LICENSE file that
  151.16 + * accompanied this code).
  151.17 + *
  151.18 + * You should have received a copy of the GNU General Public License version
  151.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  151.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  151.21 + *
  151.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  151.23 + * or visit www.oracle.com if you need additional information or have any
  151.24 + * questions.
  151.25 + */
  151.26 +
  151.27 +/*
  151.28 + * @test
  151.29 + * @bug 6976577
  151.30 + * @summary Tests public methods in non-public beans
  151.31 + * @author Sergey Malenkov
  151.32 + */
  151.33 +
  151.34 +import test.Accessor;
  151.35 +
  151.36 +import java.beans.EventSetDescriptor;
  151.37 +import java.beans.IndexedPropertyDescriptor;
  151.38 +import java.beans.PropertyDescriptor;
  151.39 +import java.lang.reflect.Method;
  151.40 +
  151.41 +public class Test6976577 {
  151.42 +
  151.43 +    public static void main(String[] args) throws Exception {
  151.44 +        Class<?> bt = Accessor.getBeanType();
  151.45 +        Class<?> lt = Accessor.getListenerType();
  151.46 +
  151.47 +        // test PropertyDescriptor
  151.48 +        PropertyDescriptor pd = new PropertyDescriptor("boolean", bt);
  151.49 +        test(pd.getReadMethod());
  151.50 +        test(pd.getWriteMethod());
  151.51 +
  151.52 +        // test IndexedPropertyDescriptor
  151.53 +        IndexedPropertyDescriptor ipd = new IndexedPropertyDescriptor("indexed", bt);
  151.54 +        test(ipd.getReadMethod());
  151.55 +        test(ipd.getWriteMethod());
  151.56 +        test(ipd.getIndexedReadMethod());
  151.57 +        test(ipd.getIndexedWriteMethod());
  151.58 +
  151.59 +        // test EventSetDescriptor
  151.60 +        EventSetDescriptor esd = new EventSetDescriptor(bt, "test", lt, "process");
  151.61 +        test(esd.getAddListenerMethod());
  151.62 +        test(esd.getRemoveListenerMethod());
  151.63 +        test(esd.getGetListenerMethod());
  151.64 +        test(esd.getListenerMethods());
  151.65 +    }
  151.66 +
  151.67 +    private static void test(Method... methods) {
  151.68 +        for (Method method : methods) {
  151.69 +            if (method == null) {
  151.70 +                throw new Error("public method is not found");
  151.71 +            }
  151.72 +        }
  151.73 +    }
  151.74 +}
   152.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   152.2 +++ b/test/java/beans/Introspector/6976577/test/Accessor.java	Tue Oct 12 12:51:48 2010 -0700
   152.3 @@ -0,0 +1,81 @@
   152.4 +package test;
   152.5 +
   152.6 +import java.beans.PropertyChangeListener;
   152.7 +import java.beans.PropertyChangeSupport;
   152.8 +import java.util.EventListener;
   152.9 +import java.util.TooManyListenersException;
  152.10 +
  152.11 +public class Accessor {
  152.12 +
  152.13 +    public static Class<?> getBeanType() {
  152.14 +        return Bean.class;
  152.15 +    }
  152.16 +
  152.17 +    public static Class<?> getListenerType() {
  152.18 +        return TestListener.class;
  152.19 +    }
  152.20 +}
  152.21 +
  152.22 +interface TestEvent {
  152.23 +}
  152.24 +
  152.25 +interface TestListener extends EventListener {
  152.26 +    void process(TestEvent event);
  152.27 +}
  152.28 +
  152.29 +class Bean {
  152.30 +
  152.31 +    private boolean b;
  152.32 +    private int[] indexed;
  152.33 +    private TestListener listener;
  152.34 +    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
  152.35 +
  152.36 +    public void addPropertyChangeListener(PropertyChangeListener listener) {
  152.37 +        this.pcs.addPropertyChangeListener(listener);
  152.38 +    }
  152.39 +
  152.40 +    public void addTestListener(TestListener listener) throws TooManyListenersException {
  152.41 +        if (listener != null) {
  152.42 +            if (this.listener != null) {
  152.43 +                throw new TooManyListenersException();
  152.44 +            }
  152.45 +            this.listener = listener;
  152.46 +        }
  152.47 +    }
  152.48 +
  152.49 +    public void removeTestListener(TestListener listener) {
  152.50 +        if (this.listener == listener) {
  152.51 +            this.listener = null;
  152.52 +        }
  152.53 +    }
  152.54 +
  152.55 +    public TestListener[] getTestListeners() {
  152.56 +        return (this.listener != null)
  152.57 +                ? new TestListener[] { this.listener }
  152.58 +                : new TestListener[0];
  152.59 +    }
  152.60 +
  152.61 +    public boolean isBoolean() {
  152.62 +        return this.b;
  152.63 +    }
  152.64 +
  152.65 +    public void setBoolean(boolean b) {
  152.66 +        this.b = b;
  152.67 +    }
  152.68 +
  152.69 +    public int[] getIndexed() {
  152.70 +        return this.indexed;
  152.71 +    }
  152.72 +
  152.73 +    public void setIndexed(int[] values) {
  152.74 +        this.indexed = values;
  152.75 +    }
  152.76 +
  152.77 +    public int getIndexed(int index) {
  152.78 +        return this.indexed[index];
  152.79 +    }
  152.80 +
  152.81 +    public void setIndexed(int index, int value) {
  152.82 +        this.indexed[index] = value;
  152.83 +    }
  152.84 +}
   153.1 --- a/test/java/lang/ProcessBuilder/Basic.java	Thu Oct 07 15:12:19 2010 -0700
   153.2 +++ b/test/java/lang/ProcessBuilder/Basic.java	Tue Oct 12 12:51:48 2010 -0700
   153.3 @@ -1825,6 +1825,64 @@
   153.4          } catch (Throwable t) { unexpected(t); }
   153.5  
   153.6          //----------------------------------------------------------------
   153.7 +        // Check that subprocesses which create subprocesses of their
   153.8 +        // own do not cause parent to hang waiting for file
   153.9 +        // descriptors to be closed.
  153.10 +        //----------------------------------------------------------------
  153.11 +        try {
  153.12 +            if (Unix.is()
  153.13 +                && new File("/bin/bash").exists()
  153.14 +                && new File("/bin/sleep").exists()) {
  153.15 +                final String[] cmd = { "/bin/bash", "-c", "(/bin/sleep 6666)" };
  153.16 +                final ProcessBuilder pb = new ProcessBuilder(cmd);
  153.17 +                final Process p = pb.start();
  153.18 +                final InputStream stdout = p.getInputStream();
  153.19 +                final InputStream stderr = p.getErrorStream();
  153.20 +                final OutputStream stdin = p.getOutputStream();
  153.21 +                final Thread reader = new Thread() {
  153.22 +                    public void run() {
  153.23 +                        try { stdout.read(); }
  153.24 +                        catch (IOException e) {
  153.25 +                            // e.printStackTrace();
  153.26 +                            if (EnglishUnix.is() &&
  153.27 +                                ! (e.getMessage().matches(".*Bad file descriptor.*")))
  153.28 +                                unexpected(e);
  153.29 +                        }
  153.30 +                        catch (Throwable t) { unexpected(t); }}};
  153.31 +                reader.setDaemon(true);
  153.32 +                reader.start();
  153.33 +                Thread.sleep(100);
  153.34 +                p.destroy();
  153.35 +                // Subprocess is now dead, but file descriptors remain open.
  153.36 +                check(p.waitFor() != 0);
  153.37 +                check(p.exitValue() != 0);
  153.38 +                stdout.close();
  153.39 +                stderr.close();
  153.40 +                stdin.close();
  153.41 +                //----------------------------------------------------------
  153.42 +                // There remain unsolved issues with asynchronous close.
  153.43 +                // Here's a highly non-portable experiment to demonstrate:
  153.44 +                //----------------------------------------------------------
  153.45 +                if (Boolean.getBoolean("wakeupJeff!")) {
  153.46 +                    System.out.println("wakeupJeff!");
  153.47 +                    // Initialize signal handler for INTERRUPT_SIGNAL.
  153.48 +                    new FileInputStream("/bin/sleep").getChannel().close();
  153.49 +                    // Send INTERRUPT_SIGNAL to every thread in this java.
  153.50 +                    String[] wakeupJeff = {
  153.51 +                        "/bin/bash", "-c",
  153.52 +                        "/bin/ps --noheaders -Lfp $PPID | " +
  153.53 +                        "/usr/bin/perl -nale 'print $F[3]' | " +
  153.54 +                        // INTERRUPT_SIGNAL == 62 on my machine du jour.
  153.55 +                        "/usr/bin/xargs kill -62"
  153.56 +                    };
  153.57 +                    new ProcessBuilder(wakeupJeff).start().waitFor();
  153.58 +                    // If wakeupJeff worked, reader probably got EBADF.
  153.59 +                    reader.join();
  153.60 +                }
  153.61 +            }
  153.62 +        } catch (Throwable t) { unexpected(t); }
  153.63 +
  153.64 +        //----------------------------------------------------------------
  153.65          // Attempt to start process with insufficient permissions fails.
  153.66          //----------------------------------------------------------------
  153.67          try {
   154.1 --- a/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java	Thu Oct 07 15:12:19 2010 -0700
   154.2 +++ b/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java	Tue Oct 12 12:51:48 2010 -0700
   154.3 @@ -29,7 +29,9 @@
   154.4  
   154.5  import java.nio.channels.*;
   154.6  import java.net.*;
   154.7 +import static java.net.StandardSocketOption.*;
   154.8  import java.io.IOException;
   154.9 +import java.util.Set;
  154.10  import java.util.concurrent.ExecutionException;
  154.11  import java.util.concurrent.Future;
  154.12  import java.util.concurrent.atomic.AtomicReference;
  154.13 @@ -39,6 +41,7 @@
  154.14      public static void main(String[] args) throws Exception {
  154.15          testBind();
  154.16          testAccept();
  154.17 +        testSocketOptions();
  154.18      }
  154.19  
  154.20      static void testBind() throws Exception {
  154.21 @@ -131,4 +134,39 @@
  154.22          }
  154.23  
  154.24      }
  154.25 +
  154.26 +    static void testSocketOptions() throws Exception {
  154.27 +        System.out.println("-- socket options --");
  154.28 +        AsynchronousServerSocketChannel ch = AsynchronousServerSocketChannel.open();
  154.29 +        try {
  154.30 +            // check supported options
  154.31 +            Set<SocketOption<?>> options = ch.supportedOptions();
  154.32 +            if (!options.contains(SO_REUSEADDR))
  154.33 +                throw new RuntimeException("SO_REUSEADDR should be supported");
  154.34 +            if (!options.contains(SO_RCVBUF))
  154.35 +                throw new RuntimeException("SO_RCVBUF should be supported");
  154.36 +
  154.37 +            // allowed to change when not bound
  154.38 +            ch.setOption(SO_RCVBUF, 256*1024);     // can't check
  154.39 +            int before = ch.getOption(SO_RCVBUF);
  154.40 +            int after = ch.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
  154.41 +            if (after < before)
  154.42 +                 throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
  154.43 +            ch.setOption(SO_REUSEADDR, true);
  154.44 +            checkOption(ch, SO_REUSEADDR, true);
  154.45 +            ch.setOption(SO_REUSEADDR, false);
  154.46 +            checkOption(ch, SO_REUSEADDR, false);
  154.47 +        } finally {
  154.48 +            ch.close();
  154.49 +        }
  154.50 +    }
  154.51 +
  154.52 +    static void checkOption(AsynchronousServerSocketChannel ch,
  154.53 +                            SocketOption name, Object expectedValue)
  154.54 +        throws IOException
  154.55 +    {
  154.56 +        Object value = ch.getOption(name);
  154.57 +        if (!value.equals(expectedValue))
  154.58 +            throw new RuntimeException("value not as expected");
  154.59 +    }
  154.60  }
   155.1 --- a/test/java/nio/channels/AsynchronousSocketChannel/Basic.java	Thu Oct 07 15:12:19 2010 -0700
   155.2 +++ b/test/java/nio/channels/AsynchronousSocketChannel/Basic.java	Tue Oct 12 12:51:48 2010 -0700
   155.3 @@ -121,8 +121,20 @@
   155.4          AsynchronousSocketChannel ch = AsynchronousSocketChannel.open()
   155.5              .setOption(SO_RCVBUF, 128*1024)
   155.6              .setOption(SO_SNDBUF, 128*1024)
   155.7 -            .setOption(SO_REUSEADDR, true)
   155.8 -            .bind(new InetSocketAddress(0));
   155.9 +            .setOption(SO_REUSEADDR, true);
  155.10 +
  155.11 +        // check SO_SNDBUF/SO_RCVBUF limits
  155.12 +        int before, after;
  155.13 +        before = ch.getOption(SO_SNDBUF);
  155.14 +        after = ch.setOption(SO_SNDBUF, Integer.MAX_VALUE).getOption(SO_SNDBUF);
  155.15 +        if (after < before)
  155.16 +            throw new RuntimeException("setOption caused SO_SNDBUF to decrease");
  155.17 +        before = ch.getOption(SO_RCVBUF);
  155.18 +        after = ch.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
  155.19 +        if (after < before)
  155.20 +            throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
  155.21 +
  155.22 +        ch.bind(new InetSocketAddress(0));
  155.23  
  155.24          // default values
  155.25          if ((Boolean)ch.getOption(SO_KEEPALIVE))
   156.1 --- a/test/java/nio/channels/DatagramChannel/SocketOptionTests.java	Thu Oct 07 15:12:19 2010 -0700
   156.2 +++ b/test/java/nio/channels/DatagramChannel/SocketOptionTests.java	Tue Oct 12 12:51:48 2010 -0700
   156.3 @@ -68,8 +68,17 @@
   156.4          checkOption(dc, SO_BROADCAST, true);
   156.5          dc.setOption(SO_BROADCAST, false);
   156.6          checkOption(dc, SO_BROADCAST, false);
   156.7 -        dc.setOption(SO_SNDBUF, 16*1024);       // can't check
   156.8 -        dc.setOption(SO_RCVBUF, 16*1024);       // can't check
   156.9 +        dc.setOption(SO_SNDBUF, 128*1024);       // can't check
  156.10 +        dc.setOption(SO_RCVBUF, 128*1024);       // can't check
  156.11 +        int before, after;
  156.12 +        before = dc.getOption(SO_SNDBUF);
  156.13 +        after = dc.setOption(SO_SNDBUF, Integer.MAX_VALUE).getOption(SO_SNDBUF);
  156.14 +        if (after < before)
  156.15 +            throw new RuntimeException("setOption caused SO_SNDBUF to decrease");
  156.16 +        before = dc.getOption(SO_RCVBUF);
  156.17 +        after = dc.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
  156.18 +        if (after < before)
  156.19 +            throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
  156.20          dc.setOption(SO_REUSEADDR, true);
  156.21          checkOption(dc, SO_REUSEADDR, true);
  156.22          dc.setOption(SO_REUSEADDR, false);
   157.1 --- a/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java	Thu Oct 07 15:12:19 2010 -0700
   157.2 +++ b/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java	Tue Oct 12 12:51:48 2010 -0700
   157.3 @@ -56,6 +56,10 @@
   157.4  
   157.5          // allowed to change when not bound
   157.6          ssc.setOption(SO_RCVBUF, 256*1024);     // can't check
   157.7 +        int before = ssc.getOption(SO_RCVBUF);
   157.8 +        int after = ssc.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
   157.9 +        if (after < before)
  157.10 +            throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
  157.11          ssc.setOption(SO_REUSEADDR, true);
  157.12          checkOption(ssc, SO_REUSEADDR, true);
  157.13          ssc.setOption(SO_REUSEADDR, false);
   158.1 --- a/test/java/nio/channels/SocketChannel/SocketOptionTests.java	Thu Oct 07 15:12:19 2010 -0700
   158.2 +++ b/test/java/nio/channels/SocketChannel/SocketOptionTests.java	Tue Oct 12 12:51:48 2010 -0700
   158.3 @@ -70,6 +70,15 @@
   158.4          checkOption(sc, SO_KEEPALIVE, false);
   158.5          sc.setOption(SO_SNDBUF, 128*1024);      // can't check
   158.6          sc.setOption(SO_RCVBUF, 256*1024);      // can't check
   158.7 +        int before, after;
   158.8 +        before = sc.getOption(SO_SNDBUF);
   158.9 +        after = sc.setOption(SO_SNDBUF, Integer.MAX_VALUE).getOption(SO_SNDBUF);
  158.10 +        if (after < before)
  158.11 +            throw new RuntimeException("setOption caused SO_SNDBUF to decrease");
  158.12 +        before = sc.getOption(SO_RCVBUF);
  158.13 +        after = sc.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
  158.14 +        if (after < before)
  158.15 +            throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
  158.16          sc.setOption(SO_REUSEADDR, true);
  158.17          checkOption(sc, SO_REUSEADDR, true);
  158.18          sc.setOption(SO_REUSEADDR, false);
   159.1 --- a/test/java/nio/file/FileStore/Basic.java	Thu Oct 07 15:12:19 2010 -0700
   159.2 +++ b/test/java/nio/file/FileStore/Basic.java	Tue Oct 12 12:51:48 2010 -0700
   159.3 @@ -22,7 +22,7 @@
   159.4   */
   159.5  
   159.6  /* @test
   159.7 - * @bug 4313887 6873621
   159.8 + * @bug 4313887 6873621 6979526
   159.9   * @summary Unit test for java.nio.file.FileStore
  159.10   * @library ..
  159.11   */
   160.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   160.2 +++ b/test/java/nio/file/Files/MaxDepth.java	Tue Oct 12 12:51:48 2010 -0700
   160.3 @@ -0,0 +1,67 @@
   160.4 +/*
   160.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
   160.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   160.7 + *
   160.8 + * This code is free software; you can redistribute it and/or modify it
   160.9 + * under the terms of the GNU General Public License version 2 only, as
  160.10 + * published by the Free Software Foundation.
  160.11 + *
  160.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  160.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  160.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  160.15 + * version 2 for more details (a copy is included in the LICENSE file that
  160.16 + * accompanied this code).
  160.17 + *
  160.18 + * You should have received a copy of the GNU General Public License version
  160.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  160.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  160.21 + *
  160.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  160.23 + * or visit www.oracle.com if you need additional information or have any
  160.24 + * questions.
  160.25 + */
  160.26 +
  160.27 +import java.nio.file.*;
  160.28 +import java.nio.file.attribute.*;
  160.29 +import java.io.IOException;
  160.30 +import java.util.*;
  160.31 +
  160.32 +/**
  160.33 + * Unit test for Files.walkFileTree to test maxDepth parameter
  160.34 + */
  160.35 +
  160.36 +public class MaxDepth {
  160.37 +    public static void main(String[] args) throws Exception {
  160.38 +        final Path top = Paths.get(args[0]);
  160.39 +
  160.40 +        for (int i=0; i<5; i++) {
  160.41 +            Set<FileVisitOption> opts = Collections.emptySet();
  160.42 +            final int maxDepth = i;
  160.43 +            Files.walkFileTree(top, opts, maxDepth, new SimpleFileVisitor<Path>() {
  160.44 +                // compute depth based on relative path to top directory
  160.45 +                private int depth(Path file) {
  160.46 +                    Path rp = file.relativize(top);
  160.47 +                    return (rp == null) ? 0 : rp.getNameCount();
  160.48 +                }
  160.49 +
  160.50 +                @Override
  160.51 +                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
  160.52 +                    int d = depth(dir);
  160.53 +                    if (d == maxDepth)
  160.54 +                        throw new RuntimeException("Should not open directories at maxDepth");
  160.55 +                    if (d > maxDepth)
  160.56 +                        throw new RuntimeException("Too deep");
  160.57 +                    return FileVisitResult.CONTINUE;
  160.58 +                }
  160.59 +
  160.60 +                @Override
  160.61 +                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
  160.62 +                    int d = depth(file);
  160.63 +                    if (d > maxDepth)
  160.64 +                        throw new RuntimeException("Too deep");
  160.65 +                    return FileVisitResult.CONTINUE;
  160.66 +                }
  160.67 +            });
  160.68 +        }
  160.69 +    }
  160.70 +}
   161.1 --- a/test/java/nio/file/Files/Misc.java	Thu Oct 07 15:12:19 2010 -0700
   161.2 +++ b/test/java/nio/file/Files/Misc.java	Tue Oct 12 12:51:48 2010 -0700
   161.3 @@ -30,6 +30,7 @@
   161.4  
   161.5  import java.nio.file.*;
   161.6  import java.nio.file.attribute.Attributes;
   161.7 +import java.nio.file.attribute.BasicFileAttributes;
   161.8  import java.io.IOException;
   161.9  import java.util.*;
  161.10  
  161.11 @@ -117,25 +118,25 @@
  161.12  
  161.13          SimpleFileVisitor<Path> visitor = new SimpleFileVisitor<Path>() { };
  161.14          boolean ranTheGauntlet = false;
  161.15 -        try { visitor.preVisitDirectory(null);
  161.16 +        BasicFileAttributes attrs = Attributes.readBasicFileAttributes(Paths.get("."));
  161.17 +
  161.18 +        try { visitor.preVisitDirectory(null, attrs);
  161.19          } catch (NullPointerException x0) {
  161.20 -        try { visitor.preVisitDirectoryFailed(null, new IOException());
  161.21 +        try { visitor.preVisitDirectory(dir, null);
  161.22          } catch (NullPointerException x1) {
  161.23 -        try { visitor.preVisitDirectoryFailed(dir, null);
  161.24 +        try { visitor.visitFile(null, attrs);
  161.25          } catch (NullPointerException x2) {
  161.26 -        try { visitor.visitFile(null, Attributes.readBasicFileAttributes(Paths.get(".")));
  161.27 +        try {  visitor.visitFile(dir, null);
  161.28          } catch (NullPointerException x3) {
  161.29 -        try {  visitor.visitFile(dir, null);
  161.30 +        try { visitor.visitFileFailed(null, new IOException());
  161.31          } catch (NullPointerException x4) {
  161.32 -        try { visitor.visitFileFailed(null, new IOException());
  161.33 +        try { visitor.visitFileFailed(dir, null);
  161.34          } catch (NullPointerException x5) {
  161.35 -        try { visitor.visitFileFailed(dir, null);
  161.36 +        try { visitor.postVisitDirectory(null, new IOException());
  161.37          } catch (NullPointerException x6) {
  161.38 -        try { visitor.postVisitDirectory(null, new IOException());
  161.39 -        } catch (NullPointerException x7) {
  161.40              // if we get here then all visit* methods threw NPE as expected
  161.41              ranTheGauntlet = true;
  161.42 -        }}}}}}}}
  161.43 +        }}}}}}}
  161.44          if (!ranTheGauntlet)
  161.45              throw new RuntimeException("A visit method did not throw NPE");
  161.46      }
   162.1 --- a/test/java/nio/file/Files/PrintFileTree.java	Thu Oct 07 15:12:19 2010 -0700
   162.2 +++ b/test/java/nio/file/Files/PrintFileTree.java	Tue Oct 12 12:51:48 2010 -0700
   162.3 @@ -56,29 +56,34 @@
   162.4  
   162.5          final boolean reportCycles = printCycles;
   162.6          Files.walkFileTree(dir, options, Integer.MAX_VALUE, new FileVisitor<FileRef>() {
   162.7 -            public FileVisitResult preVisitDirectory(FileRef dir) {
   162.8 +            @Override
   162.9 +            public FileVisitResult preVisitDirectory(FileRef dir, BasicFileAttributes attrs) {
  162.10                  System.out.println(dir);
  162.11                  return FileVisitResult.CONTINUE;
  162.12              }
  162.13 -            public FileVisitResult preVisitDirectoryFailed(FileRef dir, IOException exc) {
  162.14 -                exc.printStackTrace();
  162.15 -                return FileVisitResult.CONTINUE;
  162.16 -            }
  162.17 +            @Override
  162.18              public FileVisitResult visitFile(FileRef file, BasicFileAttributes attrs) {
  162.19                  if (!attrs.isDirectory() || reportCycles)
  162.20                      System.out.println(file);
  162.21                  return FileVisitResult.CONTINUE;
  162.22              }
  162.23 -            public FileVisitResult postVisitDirectory(FileRef dir, IOException exc) {
  162.24 -                if (exc != null) {
  162.25 -                    exc.printStackTrace();
  162.26 -                    return FileVisitResult.TERMINATE;
  162.27 -                }
  162.28 +            @Override
  162.29 +            public FileVisitResult postVisitDirectory(FileRef dir, IOException exc)
  162.30 +                throws IOException
  162.31 +            {
  162.32 +                if (exc != null)
  162.33 +                    throw exc;
  162.34                  return FileVisitResult.CONTINUE;
  162.35              }
  162.36 -            public FileVisitResult visitFileFailed(FileRef file, IOException exc) {
  162.37 -                exc.printStackTrace();
  162.38 -                return FileVisitResult.TERMINATE;
  162.39 +            @Override
  162.40 +            public FileVisitResult visitFileFailed(FileRef file, IOException exc)
  162.41 +                throws IOException
  162.42 +            {
  162.43 +                if (reportCycles && (exc instanceof FileSystemLoopException)) {
  162.44 +                    System.out.println(file);
  162.45 +                    return FileVisitResult.CONTINUE;
  162.46 +                }
  162.47 +                throw exc;
  162.48              }
  162.49          });
  162.50      }
   163.1 --- a/test/java/nio/file/Files/SkipSiblings.java	Thu Oct 07 15:12:19 2010 -0700
   163.2 +++ b/test/java/nio/file/Files/SkipSiblings.java	Tue Oct 12 12:51:48 2010 -0700
   163.3 @@ -54,32 +54,28 @@
   163.4      public static void main(String[] args) throws Exception {
   163.5          Path dir = Paths.get(args[0]);
   163.6  
   163.7 -        Files.walkFileTree(dir, new FileVisitor<Path>() {
   163.8 -            public FileVisitResult preVisitDirectory(Path dir) {
   163.9 +        Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
  163.10 +            @Override
  163.11 +            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
  163.12                  check(dir);
  163.13                  if (skip(dir))
  163.14                      return FileVisitResult.SKIP_SIBLINGS;
  163.15                  return FileVisitResult.CONTINUE;
  163.16              }
  163.17 -            public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
  163.18 -                throw new RuntimeException(exc);
  163.19 -            }
  163.20 -
  163.21 +            @Override
  163.22              public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
  163.23                  check(file);
  163.24                  if (skip(file))
  163.25                      return FileVisitResult.SKIP_SIBLINGS;
  163.26                  return FileVisitResult.CONTINUE;
  163.27              }
  163.28 +            @Override
  163.29              public FileVisitResult postVisitDirectory(Path dir, IOException x) {
  163.30                  if (x != null)
  163.31                      throw new RuntimeException(x);
  163.32                  check(dir);
  163.33                  return FileVisitResult.CONTINUE;
  163.34              }
  163.35 -            public FileVisitResult visitFileFailed(Path file, IOException x) {
  163.36 -                throw new RuntimeException(x);
  163.37 -            }
  163.38          });
  163.39      }
  163.40  }
   164.1 --- a/test/java/nio/file/Files/TerminateWalk.java	Thu Oct 07 15:12:19 2010 -0700
   164.2 +++ b/test/java/nio/file/Files/TerminateWalk.java	Tue Oct 12 12:51:48 2010 -0700
   164.3 @@ -49,22 +49,19 @@
   164.4      public static void main(String[] args) throws Exception {
   164.5          Path dir = Paths.get(args[0]);
   164.6  
   164.7 -        Files.walkFileTree(dir, new FileVisitor<Path>() {
   164.8 -            public FileVisitResult preVisitDirectory(Path dir) {
   164.9 +        Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
  164.10 +            @Override
  164.11 +            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
  164.12                  return maybeTerminate();
  164.13              }
  164.14 -            public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
  164.15 -                return maybeTerminate();
  164.16 -            }
  164.17 +            @Override
  164.18              public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
  164.19                  return maybeTerminate();
  164.20              }
  164.21 +            @Override
  164.22              public FileVisitResult postVisitDirectory(Path dir, IOException x) {
  164.23                  return maybeTerminate();
  164.24              }
  164.25 -            public FileVisitResult visitFileFailed(Path file, IOException x) {
  164.26 -                return maybeTerminate();
  164.27 -            }
  164.28          });
  164.29      }
  164.30  }
   165.1 --- a/test/java/nio/file/Files/WalkWithSecurity.java	Thu Oct 07 15:12:19 2010 -0700
   165.2 +++ b/test/java/nio/file/Files/WalkWithSecurity.java	Tue Oct 12 12:51:48 2010 -0700
   165.3 @@ -116,7 +116,7 @@
   165.4          }
   165.5  
   165.6          @Override
   165.7 -        public FileVisitResult preVisitDirectory(Path dir) {
   165.8 +        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
   165.9              System.out.println(dir);
  165.10              count++;
  165.11              return FileVisitResult.CONTINUE;
   166.1 --- a/test/java/nio/file/Files/walk_file_tree.sh	Thu Oct 07 15:12:19 2010 -0700
   166.2 +++ b/test/java/nio/file/Files/walk_file_tree.sh	Tue Oct 12 12:51:48 2010 -0700
   166.3 @@ -22,9 +22,9 @@
   166.4  #
   166.5  
   166.6  # @test
   166.7 -# @bug 4313887
   166.8 +# @bug 4313887 6907737
   166.9  # @summary Unit test for walkFileTree method
  166.10 -# @build CreateFileTree PrintFileTree SkipSiblings TerminateWalk
  166.11 +# @build CreateFileTree PrintFileTree SkipSiblings TerminateWalk MaxDepth
  166.12  # @run shell walk_file_tree.sh
  166.13  
  166.14  # if TESTJAVA isn't set then we assume an interactive run.
  166.15 @@ -84,6 +84,10 @@
  166.16  $JAVA TerminateWalk "$ROOT"
  166.17  if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
  166.18  
  166.19 +# test maxDepth
  166.20 +$JAVA MaxDepth "$ROOT"
  166.21 +if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
  166.22 +
  166.23  # clean-up
  166.24  rm -r "$ROOT"
  166.25  
   167.1 --- a/test/java/nio/file/TestUtil.java	Thu Oct 07 15:12:19 2010 -0700
   167.2 +++ b/test/java/nio/file/TestUtil.java	Tue Oct 12 12:51:48 2010 -0700
   167.3 @@ -44,15 +44,10 @@
   167.4          return createTemporaryDirectory(System.getProperty("java.io.tmpdir"));
   167.5      }
   167.6  
   167.7 -    static void removeAll(Path dir) {
   167.8 +    static void removeAll(Path dir) throws IOException {
   167.9          Files.walkFileTree(dir, new FileVisitor<Path>() {
  167.10              @Override
  167.11 -            public FileVisitResult preVisitDirectory(Path dir) {
  167.12 -                return FileVisitResult.CONTINUE;
  167.13 -            }
  167.14 -            @Override
  167.15 -            public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
  167.16 -                System.err.format("Error occured accessing directory %s\n", dir, exc);
  167.17 +            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
  167.18                  return FileVisitResult.CONTINUE;
  167.19              }
  167.20              @Override
   168.1 --- a/test/java/util/Collection/BiggernYours.java	Thu Oct 07 15:12:19 2010 -0700
   168.2 +++ b/test/java/util/Collection/BiggernYours.java	Tue Oct 12 12:51:48 2010 -0700
   168.3 @@ -174,6 +174,11 @@
   168.4                  public int size() {return randomize(super.size());}});
   168.5  
   168.6          testCollections(
   168.7 +            new ConcurrentLinkedDeque(),
   168.8 +            new ConcurrentLinkedDeque() {
   168.9 +                public int size() {return randomize(super.size());}});
  168.10 +
  168.11 +        testCollections(
  168.12              new ConcurrentLinkedQueue(),
  168.13              new ConcurrentLinkedQueue() {
  168.14                  public int size() {return randomize(super.size());}});
   169.1 --- a/test/java/util/Collection/IteratorAtEnd.java	Thu Oct 07 15:12:19 2010 -0700
   169.2 +++ b/test/java/util/Collection/IteratorAtEnd.java	Tue Oct 12 12:51:48 2010 -0700
   169.3 @@ -48,6 +48,7 @@
   169.4          testCollection(new PriorityQueue());
   169.5          testCollection(new LinkedBlockingQueue());
   169.6          testCollection(new ArrayBlockingQueue(100));
   169.7 +        testCollection(new ConcurrentLinkedDeque());
   169.8          testCollection(new ConcurrentLinkedQueue());
   169.9          testCollection(new LinkedTransferQueue());
  169.10  
   170.1 --- a/test/java/util/Collection/MOAT.java	Thu Oct 07 15:12:19 2010 -0700
   170.2 +++ b/test/java/util/Collection/MOAT.java	Tue Oct 12 12:51:48 2010 -0700
   170.3 @@ -75,6 +75,7 @@
   170.4          testCollection(new ArrayBlockingQueue<Integer>(20));
   170.5          testCollection(new LinkedBlockingQueue<Integer>(20));
   170.6          testCollection(new LinkedBlockingDeque<Integer>(20));
   170.7 +        testCollection(new ConcurrentLinkedDeque<Integer>());
   170.8          testCollection(new ConcurrentLinkedQueue<Integer>());
   170.9          testCollection(new LinkedTransferQueue<Integer>());
  170.10          testCollection(new ConcurrentSkipListSet<Integer>());
  170.11 @@ -431,8 +432,9 @@
  170.12          q.poll();
  170.13          equal(q.size(), 4);
  170.14          checkFunctionalInvariants(q);
  170.15 -        if ((q instanceof LinkedBlockingQueue) ||
  170.16 -            (q instanceof LinkedBlockingDeque) ||
  170.17 +        if ((q instanceof LinkedBlockingQueue)   ||
  170.18 +            (q instanceof LinkedBlockingDeque)   ||
  170.19 +            (q instanceof ConcurrentLinkedDeque) ||
  170.20              (q instanceof ConcurrentLinkedQueue)) {
  170.21              testQueueIteratorRemove(q);
  170.22          }
   171.1 --- a/test/java/util/Collections/RacingCollections.java	Thu Oct 07 15:12:19 2010 -0700
   171.2 +++ b/test/java/util/Collections/RacingCollections.java	Tue Oct 12 12:51:48 2010 -0700
   171.3 @@ -235,6 +235,7 @@
   171.4              new ArrayList<Queue<Integer>>(newConcurrentDeques());
   171.5          list.add(new LinkedBlockingQueue<Integer>(10));
   171.6          list.add(new LinkedTransferQueue<Integer>());
   171.7 +        list.add(new ConcurrentLinkedQueue<Integer>());
   171.8          return list;
   171.9      }
  171.10  
  171.11 @@ -248,6 +249,7 @@
  171.12      private static List<Deque<Integer>> newConcurrentDeques() {
  171.13          List<Deque<Integer>> list = new ArrayList<Deque<Integer>>();
  171.14          list.add(new LinkedBlockingDeque<Integer>(10));
  171.15 +        list.add(new ConcurrentLinkedDeque<Integer>());
  171.16          return list;
  171.17      }
  171.18  
   172.1 --- a/test/java/util/Deque/ChorusLine.java	Thu Oct 07 15:12:19 2010 -0700
   172.2 +++ b/test/java/util/Deque/ChorusLine.java	Tue Oct 12 12:51:48 2010 -0700
   172.3 @@ -129,6 +129,7 @@
   172.4          deqs.add(new ArrayDeque<Integer>());
   172.5          deqs.add(new LinkedList<Integer>());
   172.6          deqs.add(new LinkedBlockingDeque<Integer>());
   172.7 +        deqs.add(new ConcurrentLinkedDeque<Integer>());
   172.8  
   172.9          equal(deqs);
  172.10  
   173.1 --- a/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java	Thu Oct 07 15:12:19 2010 -0700
   173.2 +++ b/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java	Tue Oct 12 12:51:48 2010 -0700
   173.3 @@ -55,6 +55,7 @@
   173.4  
   173.5      Collection<Queue<Integer>> concurrentQueues() {
   173.6          List<Queue<Integer>> queues = new ArrayList<Queue<Integer>>();
   173.7 +        queues.add(new ConcurrentLinkedDeque<Integer>());
   173.8          queues.add(new ConcurrentLinkedQueue<Integer>());
   173.9          queues.add(new ArrayBlockingQueue<Integer>(items, false));
  173.10          //queues.add(new ArrayBlockingQueue<Integer>(count, true));
  173.11 @@ -105,7 +106,7 @@
  173.12          final Queue<Integer> queue;
  173.13          final CyclicBarrier barrier;
  173.14          int items;
  173.15 -        Stage (Queue<Integer> q, CyclicBarrier b, int items) {
  173.16 +        Stage(Queue<Integer> q, CyclicBarrier b, int items) {
  173.17              queue = q;
  173.18              barrier = b;
  173.19              this.items = items;
   174.1 --- a/test/java/util/concurrent/ConcurrentQueues/GCRetention.java	Thu Oct 07 15:12:19 2010 -0700
   174.2 +++ b/test/java/util/concurrent/ConcurrentQueues/GCRetention.java	Tue Oct 12 12:51:48 2010 -0700
   174.3 @@ -40,6 +40,7 @@
   174.4  
   174.5  import java.util.concurrent.ArrayBlockingQueue;
   174.6  import java.util.concurrent.ConcurrentHashMap;
   174.7 +import java.util.concurrent.ConcurrentLinkedDeque;
   174.8  import java.util.concurrent.ConcurrentLinkedQueue;
   174.9  import java.util.concurrent.LinkedBlockingDeque;
  174.10  import java.util.concurrent.LinkedBlockingQueue;
  174.11 @@ -62,6 +63,7 @@
  174.12  
  174.13      Collection<Queue<Boolean>> queues() {
  174.14          List<Queue<Boolean>> queues = new ArrayList<Queue<Boolean>>();
  174.15 +        queues.add(new ConcurrentLinkedDeque<Boolean>());
  174.16          queues.add(new ConcurrentLinkedQueue<Boolean>());
  174.17          queues.add(new ArrayBlockingQueue<Boolean>(count, false));
  174.18          queues.add(new ArrayBlockingQueue<Boolean>(count, true));
   175.1 --- a/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java	Thu Oct 07 15:12:19 2010 -0700
   175.2 +++ b/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java	Tue Oct 12 12:51:48 2010 -0700
   175.3 @@ -48,6 +48,7 @@
   175.4          test(new LinkedBlockingQueue(20));
   175.5          test(new LinkedBlockingDeque());
   175.6          test(new LinkedBlockingDeque(20));
   175.7 +        test(new ConcurrentLinkedDeque());
   175.8          test(new ConcurrentLinkedQueue());
   175.9          test(new LinkedTransferQueue());
  175.10          // Other concurrent queues (e.g. ArrayBlockingQueue) do not
   176.1 --- a/test/java/util/concurrent/ConcurrentQueues/OfferRemoveLoops.java	Thu Oct 07 15:12:19 2010 -0700
   176.2 +++ b/test/java/util/concurrent/ConcurrentQueues/OfferRemoveLoops.java	Tue Oct 12 12:51:48 2010 -0700
   176.3 @@ -55,6 +55,7 @@
   176.4          testQueue(new LinkedBlockingDeque());
   176.5          testQueue(new ArrayBlockingQueue(10));
   176.6          testQueue(new PriorityBlockingQueue(10));
   176.7 +        testQueue(new ConcurrentLinkedDeque());
   176.8          testQueue(new ConcurrentLinkedQueue());
   176.9          testQueue(new LinkedTransferQueue());
  176.10      }
   177.1 --- a/test/java/util/concurrent/ConcurrentQueues/RemovePollRace.java	Thu Oct 07 15:12:19 2010 -0700
   177.2 +++ b/test/java/util/concurrent/ConcurrentQueues/RemovePollRace.java	Tue Oct 12 12:51:48 2010 -0700
   177.3 @@ -41,6 +41,7 @@
   177.4  
   177.5  import java.util.concurrent.ArrayBlockingQueue;
   177.6  import java.util.concurrent.ConcurrentHashMap;
   177.7 +import java.util.concurrent.ConcurrentLinkedDeque;
   177.8  import java.util.concurrent.ConcurrentLinkedQueue;
   177.9  import java.util.concurrent.CountDownLatch;
  177.10  import java.util.concurrent.LinkedBlockingDeque;
  177.11 @@ -62,6 +63,7 @@
  177.12  
  177.13      Collection<Queue<Boolean>> concurrentQueues() {
  177.14          List<Queue<Boolean>> queues = new ArrayList<Queue<Boolean>>();
  177.15 +        queues.add(new ConcurrentLinkedDeque<Boolean>());
  177.16          queues.add(new ConcurrentLinkedQueue<Boolean>());
  177.17          queues.add(new ArrayBlockingQueue<Boolean>(count, false));
  177.18          queues.add(new ArrayBlockingQueue<Boolean>(count, true));
   178.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   178.2 +++ b/test/javax/swing/JComboBox/6632953/bug6632953.java	Tue Oct 12 12:51:48 2010 -0700
   178.3 @@ -0,0 +1,44 @@
   178.4 +/*
   178.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
   178.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   178.7 + *
   178.8 + * This code is free software; you can redistribute it and/or modify it
   178.9 + * under the terms of the GNU General Public License version 2 only, as
  178.10 + * published by the Free Software Foundation.
  178.11 + *
  178.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  178.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  178.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  178.15 + * version 2 for more details (a copy is included in the LICENSE file that
  178.16 + * accompanied this code).
  178.17 + *
  178.18 + * You should have received a copy of the GNU General Public License version
  178.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  178.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  178.21 + *
  178.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  178.23 + * or visit www.oracle.com if you need additional information or have any
  178.24 + * questions.
  178.25 + */
  178.26 +
  178.27 +/* @test
  178.28 + * @bug 6632953
  178.29 + * @summary MetalComboBoxUI.getBaseline(JComponent, int, int) throws IAE for valid width/height
  178.30 + * @author Alexander Potochkin
  178.31 + */
  178.32 +
  178.33 +import javax.swing.JComboBox;
  178.34 +import javax.swing.plaf.metal.MetalComboBoxUI;
  178.35 +
  178.36 +public class bug6632953 {
  178.37 +
  178.38 +    public static void main(String... args) throws Exception {
  178.39 +        MetalComboBoxUI ui = new MetalComboBoxUI();
  178.40 +        ui.installUI(new JComboBox());
  178.41 +        ui.getBaseline(new JComboBox(), 0, 0);
  178.42 +        ui.getBaseline(new JComboBox(), 1, 1);
  178.43 +        ui.getBaseline(new JComboBox(), 2, 2);
  178.44 +        ui.getBaseline(new JComboBox(), 3, 3);
  178.45 +        ui.getBaseline(new JComboBox(), 4, 4);
  178.46 +    }
  178.47 +}
   179.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   179.2 +++ b/test/javax/swing/JScrollBar/6542335/bug6542335.java	Tue Oct 12 12:51:48 2010 -0700
   179.3 @@ -0,0 +1,92 @@
   179.4 +/*
   179.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
   179.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   179.7 + *
   179.8 + * This code is free software; you can redistribute it and/or modify it
   179.9 + * under the terms of the GNU General Public License version 2 only, as
  179.10 + * published by the Free Software Foundation.
  179.11 + *
  179.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  179.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  179.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  179.15 + * version 2 for more details (a copy is included in the LICENSE file that
  179.16 + * accompanied this code).
  179.17 + *
  179.18 + * You should have received a copy of the GNU General Public License version
  179.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  179.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  179.21 + *
  179.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  179.23 + * or visit www.oracle.com if you need additional information or have any
  179.24 + * questions.
  179.25 + */
  179.26 +
  179.27 +/* @test
  179.28 +   @bug 6542335
  179.29 +   @summary different behavior on knob of scroll bar between 1.4.2 and 5.0
  179.30 +   @author  Alexander Potochkin
  179.31 +   @run main bug6542335
  179.32 +*/
  179.33 +
  179.34 +import sun.awt.SunToolkit;
  179.35 +
  179.36 +import javax.swing.*;
  179.37 +import javax.swing.plaf.basic.BasicScrollBarUI;
  179.38 +import java.awt.*;
  179.39 +import java.awt.event.InputEvent;
  179.40 +
  179.41 +public class bug6542335 {
  179.42 +    private static JScrollBar sb;
  179.43 +    private static MyScrollBarUI ui;
  179.44 +
  179.45 +    public static void main(String[] args) throws Exception {
  179.46 +        Robot robot = new Robot();
  179.47 +        robot.setAutoDelay(10);
  179.48 +
  179.49 +        SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
  179.50 +
  179.51 +        SwingUtilities.invokeAndWait(new Runnable() {
  179.52 +            public void run() {
  179.53 +                final JFrame frame = new JFrame("bug6542335");
  179.54 +                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  179.55 +
  179.56 +                sb = new JScrollBar(0, 0, 1, 0, 1);
  179.57 +
  179.58 +                ui = new MyScrollBarUI();
  179.59 +                sb.setUI(ui);
  179.60 +
  179.61 +                sb.setPreferredSize(new Dimension(200, 17));
  179.62 +                DefaultBoundedRangeModel rangeModel = new DefaultBoundedRangeModel();
  179.63 +                rangeModel.setMaximum(100);
  179.64 +                rangeModel.setMinimum(0);
  179.65 +                rangeModel.setExtent(50);
  179.66 +                rangeModel.setValue(50);
  179.67 +
  179.68 +                sb.setModel(rangeModel);
  179.69 +                frame.add(sb);
  179.70 +
  179.71 +                frame.setSize(200, 100);
  179.72 +                frame.setVisible(true);
  179.73 +            }
  179.74 +        });
  179.75 +
  179.76 +        Rectangle thumbBounds = new Rectangle(ui.getThumbBounds());
  179.77 +
  179.78 +        toolkit.realSync();
  179.79 +        Point l = sb.getLocationOnScreen();
  179.80 +        robot.mouseMove(l.x + (int) (0.75 * sb.getWidth()), l.y + sb.getHeight()/2);
  179.81 +        robot.mousePress(InputEvent.BUTTON1_MASK);
  179.82 +        robot.mouseRelease(InputEvent.BUTTON1_MASK);
  179.83 +        toolkit.realSync();
  179.84 +
  179.85 +        if (!thumbBounds.equals(ui.getThumbBounds())) {
  179.86 +            throw new RuntimeException("Test failed");
  179.87 +        }
  179.88 +    }
  179.89 +
  179.90 +    static class MyScrollBarUI extends BasicScrollBarUI {
  179.91 +        public Rectangle getThumbBounds() {
  179.92 +            return super.getThumbBounds();
  179.93 +        }
  179.94 +    }
  179.95 +}
   180.1 --- a/test/javax/swing/JTable/Test6888156.java	Thu Oct 07 15:12:19 2010 -0700
   180.2 +++ b/test/javax/swing/JTable/Test6888156.java	Tue Oct 12 12:51:48 2010 -0700
   180.3 @@ -1,5 +1,5 @@
   180.4  /*
   180.5 - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
   180.6 + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
   180.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   180.8   *
   180.9   * This code is free software; you can redistribute it and/or modify it
  180.10 @@ -71,14 +71,14 @@
  180.11          table = new JTable(model);
  180.12      }
  180.13  
  180.14 -    public void test(final LookAndFeel laf) throws Exception {
  180.15 +    public void test(final String laf) throws Exception {
  180.16          SwingUtilities.invokeAndWait(new Runnable() {
  180.17              @Override public void run() {
  180.18                  try {
  180.19 +                    System.out.println(laf);
  180.20                      UIManager.setLookAndFeel(laf);
  180.21 -                } catch (UnsupportedLookAndFeelException e) {
  180.22 -                    System.err.println(laf.getDescription() +
  180.23 -                                       " is unsupported; continuing");
  180.24 +                } catch (Exception e) {
  180.25 +                    System.err.println(laf + " is unsupported; continuing");
  180.26                      return;
  180.27                  }
  180.28                  SwingUtilities.updateComponentTreeUI(table);
  180.29 @@ -92,8 +92,10 @@
  180.30  
  180.31      public static void main(String[] args) throws Exception {
  180.32          Test6888156 t = new Test6888156();
  180.33 -        t.test(new javax.swing.plaf.nimbus.NimbusLookAndFeel());
  180.34 -        t.test(new com.sun.java.swing.plaf.gtk.GTKLookAndFeel());
  180.35 +        t.test("javax.swing.plaf.nimbus.NimbusLookAndFeel");
  180.36 +        t.test("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
  180.37 +        for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
  180.38 +            t.test(laf.getClassName());
  180.39 +        }
  180.40      }
  180.41  }
  180.42 -
   181.1 --- a/test/javax/swing/JTextArea/6940863/bug6940863.java	Thu Oct 07 15:12:19 2010 -0700
   181.2 +++ b/test/javax/swing/JTextArea/6940863/bug6940863.java	Tue Oct 12 12:51:48 2010 -0700
   181.3 @@ -56,6 +56,7 @@
   181.4      public static void main(String[] args) throws Exception {
   181.5          if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) {
   181.6              System.out.println("The test is suitable only for Windows OS. Skipped");
   181.7 +            return;
   181.8          }
   181.9  
  181.10          UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
   182.1 --- a/test/sun/net/www/http/ChunkedInputStream/ChunkedCharEncoding.sh	Thu Oct 07 15:12:19 2010 -0700
   182.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   182.3 @@ -1,62 +0,0 @@
   182.4 -#
   182.5 -# Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
   182.6 -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   182.7 -#
   182.8 -# This code is free software; you can redistribute it and/or modify it
   182.9 -# under the terms of the GNU General Public License version 2 only, as
  182.10 -# published by the Free Software Foundation.
  182.11 -#
  182.12 -# This code is distributed in the hope that it will be useful, but WITHOUT
  182.13 -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  182.14 -# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  182.15 -# version 2 for more details (a copy is included in the LICENSE file that
  182.16 -# accompanied this code).
  182.17 -#
  182.18 -# You should have received a copy of the GNU General Public License version
  182.19 -# 2 along with this work; if not, write to the Free Software Foundation,
  182.20 -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  182.21 -#
  182.22 -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  182.23 -# or visit www.oracle.com if you need additional information or have any
  182.24 -# questions.
  182.25 -#
  182.26 -
  182.27 - # @test
  182.28 - # @bug 6502503
  182.29 - # @run shell/timeout=140 ChunkedCharEncoding.sh
  182.30 - # @summary Http URL connection don't work when default encoding is Cp037: HTTP Transfer-Encoding:chunked
  182.31 -
  182.32 -OS=`uname -s`
  182.33 -case "$OS" in
  182.34 -  SunOS | Linux )
  182.35 -    PS=":"
  182.36 -    FS="/"
  182.37 -    ;;
  182.38 -  CYGWIN* )
  182.39 -    PS=";"
  182.40 -    FS="/"
  182.41 -    ;;
  182.42 -  Windows* )
  182.43 -    PS=";"
  182.44 -    FS="\\"
  182.45 -    ;;
  182.46 -  * )
  182.47 -    echo "Unrecognized system!"
  182.48 -    exit 1;
  182.49 -    ;;
  182.50 -esac
  182.51 -
  182.52 -# compile
  182.53 -${TESTJAVA}${FS}bin${FS}javac -d . ${TESTSRC}${FS}TestAvailable.java
  182.54 -
  182.55 -# run with CP037 encoding specified. 
  182.56 -${TESTJAVA}${FS}bin${FS}java -Dfile.encoding=Cp037 TestAvailable 2>&1 
  182.57 -
  182.58 -result=$?
  182.59 -if [ "$result" -ne "0" ]; then
  182.60 -    exit 1
  182.61 -fi
  182.62 -
  182.63 -# no failures, exit.
  182.64 -exit 0
  182.65 -
   183.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   183.2 +++ b/test/sun/net/www/http/HttpClient/StreamingRetry.java	Tue Oct 12 12:51:48 2010 -0700
   183.3 @@ -0,0 +1,89 @@
   183.4 +/*
   183.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
   183.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   183.7 + *
   183.8 + * This code is free software; you can redistribute it and/or modify it
   183.9 + * under the terms of the GNU General Public License version 2 only, as
  183.10 + * published by the Free Software Foundation.
  183.11 + *
  183.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  183.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  183.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  183.15 + * version 2 for more details (a copy is included in the LICENSE file that
  183.16 + * accompanied this code).
  183.17 + *
  183.18 + * You should have received a copy of the GNU General Public License version
  183.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  183.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  183.21 + *
  183.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  183.23 + * or visit www.oracle.com if you need additional information or have any
  183.24 + * questions.
  183.25 + */
  183.26 +
  183.27 +/*
  183.28 + * @test
  183.29 + * @bug 6672144
  183.30 + * @summary HttpURLConnection.getInputStream sends POST request after failed chunked send
  183.31 + */
  183.32 +
  183.33 +import java.net.HttpURLConnection;
  183.34 +import java.net.ServerSocket;
  183.35 +import java.net.URL;
  183.36 +import java.io.IOException;
  183.37 +import java.io.InputStream;
  183.38 +import java.io.OutputStream;
  183.39 +
  183.40 +public class StreamingRetry implements Runnable {
  183.41 +    static final int ACCEPT_TIMEOUT = 20 * 1000; // 20 seconds
  183.42 +    ServerSocket ss;
  183.43 +
  183.44 +    public static void main(String[] args) throws IOException {
  183.45 +        (new StreamingRetry()).instanceMain();
  183.46 +    }
  183.47 +
  183.48 +    void instanceMain() throws IOException {
  183.49 +        test();
  183.50 +        if (failed > 0) throw new RuntimeException("Some tests failed");
  183.51 +    }
  183.52 +
  183.53 +    void test() throws IOException {
  183.54 +        ss = new ServerSocket(0);
  183.55 +        ss.setSoTimeout(ACCEPT_TIMEOUT);
  183.56 +        int port = ss.getLocalPort();
  183.57 +
  183.58 +        (new Thread(this)).start();
  183.59 +
  183.60 +        try {
  183.61 +            URL url = new URL("http://localhost:" + port + "/");
  183.62 +            HttpURLConnection uc = (HttpURLConnection) url.openConnection();
  183.63 +            uc.setDoOutput(true);
  183.64 +            uc.setChunkedStreamingMode(4096);
  183.65 +            OutputStream os = uc.getOutputStream();
  183.66 +            os.write("Hello there".getBytes());
  183.67 +
  183.68 +            InputStream is = uc.getInputStream();
  183.69 +            is.close();
  183.70 +        } catch (IOException expected) {
  183.71 +            //expected.printStackTrace();
  183.72 +        } finally {
  183.73 +            ss.close();
  183.74 +        }
  183.75 +    }
  183.76 +
  183.77 +    // Server
  183.78 +    public void run() {
  183.79 +        try {
  183.80 +            (ss.accept()).close();
  183.81 +            (ss.accept()).close();
  183.82 +            ss.close();
  183.83 +            fail("The server shouldn't accept a second connection");
  183.84 +         } catch (IOException e) {
  183.85 +            //OK, the clien will close the server socket if successfull
  183.86 +        }
  183.87 +    }
  183.88 +
  183.89 +    volatile int failed = 0;
  183.90 +    void fail() {failed++; Thread.dumpStack();}
  183.91 +    void fail(String msg) {System.err.println(msg); fail();}
  183.92 +}
   184.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   184.2 +++ b/test/sun/net/www/protocol/http/6550798/TestCache.java	Tue Oct 12 12:51:48 2010 -0700
   184.3 @@ -0,0 +1,133 @@
   184.4 +/*
   184.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
   184.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   184.7 + *
   184.8 + * This code is free software; you can redistribute it and/or modify it
   184.9 + * under the terms of the GNU General Public License version 2 only, as
  184.10 + * published by the Free Software Foundation.
  184.11 + *
  184.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  184.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  184.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  184.15 + * version 2 for more details (a copy is included in the LICENSE file that
  184.16 + * accompanied this code).
  184.17 + *
  184.18 + * You should have received a copy of the GNU General Public License version
  184.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  184.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  184.21 + *
  184.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  184.23 + * or visit www.oracle.com if you need additional information or have any
  184.24 + * questions.
  184.25 + */
  184.26 +
  184.27 +import java.net.*;
  184.28 +import java.io.*;
  184.29 +import java.io.IOException;
  184.30 +import java.io.InputStream;
  184.31 +import java.io.OutputStream;
  184.32 +import java.io.FileInputStream;
  184.33 +import java.io.FileOutputStream;
  184.34 +import java.io.BufferedInputStream;
  184.35 +import java.io.ByteArrayInputStream;
  184.36 +import java.io.PrintStream;
  184.37 +import java.io.InputStream;
  184.38 +import java.io.File;
  184.39 +import java.net.CacheRequest;
  184.40 +import java.net.CacheResponse;
  184.41 +import java.net.ResponseCache;
  184.42 +import java.net.URI;
  184.43 +import java.net.URL;
  184.44 +import java.net.URLConnection;
  184.45 +import java.util.ArrayList;
  184.46 +import java.util.HashMap;
  184.47 +import java.util.Map;
  184.48 +import java.util.List;
  184.49 +import java.util.Iterator;
  184.50 +import java.util.StringTokenizer;
  184.51 +import java.util.jar.JarInputStream;
  184.52 +import java.util.jar.JarFile;
  184.53 +import java.security.AccessController;
  184.54 +import java.security.PrivilegedAction;
  184.55 +import java.security.PrivilegedExceptionAction;
  184.56 +import java.security.PrivilegedActionException;
  184.57 +import java.security.Principal;
  184.58 +import java.security.cert.Certificate;
  184.59 +import javax.net.ssl.SSLPeerUnverifiedException;
  184.60 +
  184.61 +public class TestCache extends java.net.ResponseCache {
  184.62 +    private boolean inCacheHandler = false;
  184.63 +    private boolean _downloading = false;
  184.64 +
  184.65 +    public static volatile boolean fail = false;
  184.66 +
  184.67 +    public static void reset() {
  184.68 +        // Set system wide cache handler
  184.69 +        System.out.println("install deploy cache handler");
  184.70 +        ResponseCache.setDefault(new TestCache());
  184.71 +    }
  184.72 +
  184.73 +    public synchronized CacheResponse get(final URI uri, String rqstMethod,
  184.74 +            Map requestHeaders) throws IOException {
  184.75 +        System.out.println("get: " + uri);
  184.76 +        Thread.currentThread().dumpStack();
  184.77 +        return null;
  184.78 +    }
  184.79 +
  184.80 +    public synchronized CacheRequest put(URI uri, URLConnection conn)
  184.81 +    throws IOException {
  184.82 +        System.out.println("put: " + uri);
  184.83 +        Thread.currentThread().dumpStack();
  184.84 +        URL url = uri.toURL();
  184.85 +        return new DeployCacheRequest(url, conn);
  184.86 +
  184.87 +    }
  184.88 +}
  184.89 +
  184.90 +class DeployByteArrayOutputStream extends java.io.ByteArrayOutputStream {
  184.91 +
  184.92 +    private URL _url;
  184.93 +    private URLConnection _conn;
  184.94 +
  184.95 +    DeployByteArrayOutputStream(URL url, URLConnection conn) {
  184.96 +        _url = url;
  184.97 +        _conn = conn;
  184.98 +    }
  184.99 +
 184.100 +
 184.101 +    public void close() throws IOException {
 184.102 +
 184.103 +        System.out.println("contentLength: " + _conn.getContentLength());
 184.104 +        System.out.println("byte array size: " + size());
 184.105 +        if ( _conn.getContentLength() == size()) {
 184.106 +            System.out.println("correct content length");
 184.107 +        } else {
 184.108 +            System.out.println("wrong content length");
 184.109 +            System.out.println("TEST FAILED");
 184.110 +            TestCache.fail = true;
 184.111 +        }
 184.112 +        super.close();
 184.113 +    }
 184.114 +}
 184.115 +
 184.116 +class DeployCacheRequest extends java.net.CacheRequest {
 184.117 +
 184.118 +    private URL _url;
 184.119 +    private URLConnection _conn;
 184.120 +    private boolean _downloading = false;
 184.121 +
 184.122 +    DeployCacheRequest(URL url, URLConnection conn) {
 184.123 +        System.out.println("DeployCacheRequest ctor for: " + url);
 184.124 +        _url = url;
 184.125 +        _conn = conn;
 184.126 +    }
 184.127 +
 184.128 +    public void abort() {
 184.129 +        System.out.println("abort called");
 184.130 +    }
 184.131 +
 184.132 +    public OutputStream getBody() throws IOException {
 184.133 +        System.out.println("getBody called");
 184.134 +        return new DeployByteArrayOutputStream(_url, _conn);
 184.135 +    }
 184.136 +}
   185.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   185.2 +++ b/test/sun/net/www/protocol/http/6550798/test.java	Tue Oct 12 12:51:48 2010 -0700
   185.3 @@ -0,0 +1,90 @@
   185.4 +/*
   185.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
   185.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   185.7 + *
   185.8 + * This code is free software; you can redistribute it and/or modify it
   185.9 + * under the terms of the GNU General Public License version 2 only, as
  185.10 + * published by the Free Software Foundation.
  185.11 + *
  185.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  185.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  185.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  185.15 + * version 2 for more details (a copy is included in the LICENSE file that
  185.16 + * accompanied this code).
  185.17 + *
  185.18 + * You should have received a copy of the GNU General Public License version
  185.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  185.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  185.21 + *
  185.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  185.23 + * or visit www.oracle.com if you need additional information or have any
  185.24 + * questions.
  185.25 + */
  185.26 +
  185.27 +/**
  185.28 + * @test
  185.29 + * @bug 6550798
  185.30 + * @summary Using InputStream.skip with ResponseCache will cause partial data to be cached
  185.31 + * @run main/othervm test
  185.32 + */
  185.33 +
  185.34 +import java.net.*;
  185.35 +import com.sun.net.httpserver.*;
  185.36 +import java.io.*;
  185.37 +
  185.38 +public class test {
  185.39 +
  185.40 +    final static int LEN = 16 * 1024;
  185.41 +
  185.42 +    public static void main(String[] args)  throws Exception {
  185.43 +
  185.44 +        TestCache.reset();
  185.45 +        HttpServer s = HttpServer.create (new InetSocketAddress(0), 10);
  185.46 +        s.createContext ("/", new HttpHandler () {
  185.47 +            public void handle (HttpExchange e) {
  185.48 +                try {
  185.49 +                    byte[] buf = new byte [LEN];
  185.50 +                    OutputStream o = e.getResponseBody();
  185.51 +                    e.sendResponseHeaders(200, LEN);
  185.52 +                    o.write (buf);
  185.53 +                    e.close();
  185.54 +                } catch (IOException ex) {
  185.55 +                    ex.printStackTrace();
  185.56 +                    TestCache.fail = true;
  185.57 +                }
  185.58 +            }
  185.59 +        });
  185.60 +        s.start();
  185.61 +
  185.62 +        System.out.println("http request with cache hander");
  185.63 +        URL u = new URL("http://127.0.0.1:"+s.getAddress().getPort()+"/f");
  185.64 +        URLConnection conn = u.openConnection();
  185.65 +
  185.66 +        InputStream is = null;
  185.67 +        try {
  185.68 +            // this calls into TestCache.get
  185.69 +            byte[] buf = new byte[8192];
  185.70 +            is = new BufferedInputStream(conn.getInputStream());
  185.71 +
  185.72 +            is.skip(1000);
  185.73 +
  185.74 +            while (is.read(buf) != -1) {
  185.75 +            }
  185.76 +        } finally {
  185.77 +            if (is != null) {
  185.78 +                // this calls into TestCache.put
  185.79 +                // TestCache.put will check if the resource
  185.80 +                // should be cached
  185.81 +                is.close();
  185.82 +            }
  185.83 +            s.stop(0);
  185.84 +        }
  185.85 +
  185.86 +        if (TestCache.fail) {
  185.87 +            System.out.println ("TEST FAILED");
  185.88 +            throw new RuntimeException ();
  185.89 +        } else {
  185.90 +            System.out.println ("TEST OK");
  185.91 +        }
  185.92 +    }
  185.93 +}
   186.1 --- a/test/sun/security/tools/jarsigner/crl.sh	Thu Oct 07 15:12:19 2010 -0700
   186.2 +++ b/test/sun/security/tools/jarsigner/crl.sh	Tue Oct 12 12:51:48 2010 -0700
   186.3 @@ -63,7 +63,15 @@
   186.4  $KT -alias b -dname CN=b -keyalg rsa -genkey -validity 300
   186.5  $KT -alias b -gencrl -id 5:1 -id 6:2 -file crl3
   186.6  
   186.7 -$TESTJAVA${FS}bin${FS}jrunscript -e 'println(new File("crl1").toURI())' > uri
   186.8 +cat > ToURI.java <<EOF
   186.9 +class ToURI {
  186.10 +    public static void main(String[] args) throws Exception {
  186.11 +        System.out.println(new java.io.File("crl1").toURI());
  186.12 +    }
  186.13 +}
  186.14 +EOF
  186.15 +$TESTJAVA${FS}bin${FS}javac ToURI.java
  186.16 +$TESTJAVA${FS}bin${FS}java ToURI > uri
  186.17  $KT -alias c -dname CN=c -keyalg rsa -genkey -validity 300 \
  186.18      -ext crl=uri:`cat uri`
  186.19