Merge jdk7-b115
authorjqzuo
Mon, 18 Oct 2010 11:25:28 -0400
changeset 2876449bad8d67b5
parent 2875 0dcee22ced98
parent 2865 0613978371d8
child 2877 9c4165d5661c
child 2976 4e04d1e8f533
Merge
make/common/Rules-SCCS.gmk
make/common/shared/Defs.gmk
test/sun/net/www/http/ChunkedInputStream/ChunkedCharEncoding.sh
     1.1 --- a/.hgtags	Tue Oct 12 13:34:59 2010 -0400
     1.2 +++ b/.hgtags	Mon Oct 18 11:25:28 2010 -0400
     1.3 @@ -88,3 +88,4 @@
     1.4  fb63a2688db807a73e2a3de7d9bab298f1bff0e8 jdk7-b111
     1.5  b53f226b1d91473ac54184afa827be07b87e0319 jdk7-b112
     1.6  61d3b9fbb26bdef56cfa41b9af5bc312a22cbeb8 jdk7-b113
     1.7 +e250cef36ea05e627e7e6f7d75e5e19f529e2ba3 jdk7-b114
     2.1 --- a/make/Makefile	Tue Oct 12 13:34:59 2010 -0400
     2.2 +++ b/make/Makefile	Mon Oct 18 11:25:28 2010 -0400
     2.3 @@ -75,7 +75,6 @@
     2.4  import_fastdebug  -- copy in the fastdebug components \n\
     2.5  import_debug      -- copy in the debug components \n\
     2.6  modules           -- build the jdk and jre module images (experimental) \n\
     2.7 -sccs_get          -- make sure all SCCS files are up-to-date (need SCCS) \n\
     2.8  create_links      -- create softlinks in Solaris 32bit build to 64bit dirs \n\
     2.9  "
    2.10  
    2.11 @@ -278,21 +277,6 @@
    2.12  $(OUTPUTDIR) $(TEMPDIR):
    2.13  	$(MKDIR) -p $@
    2.14  
    2.15 -# cleanup everything. If the workspace is not being built by the control
    2.16 -# workspace, and if it is a Teamware workspace, then see if there are
    2.17 -# any files which are not under SCCS control.
    2.18 -clean clobber:: 
    2.19 -ifndef EXTERNALSANITYCONTROL
    2.20 -	@if [ -d $(TOPDIR)/Codemgr_wsdata ]; then \
    2.21 -	  $(ECHO) '\nPerforming workspace scan for remnant files.\n' \
    2.22 -		'  Any files listed below are not under SCCS control in the workspace\n' \
    2.23 -		'  and you should review them and possibly remove them manually:' ; \
    2.24 -	  $(FIND) $(TOPDIR)/make $(TOPDIR)/src -type f | \
    2.25 -		$(SED) 's+SCCS/[ps]\.++' | $(SORT) | $(UNIQ) -c | $(NAWK) '$$1<2 {print $$2;}' ; \
    2.26 -	  $(ECHO) 'End of workspace scan.' ; \
    2.27 -	fi
    2.28 -endif
    2.29 -
    2.30  # this should be the last rule in this file:
    2.31  all::
    2.32  	@if [ -r $(WARNING_FILE) ]; then \
    2.33 @@ -341,16 +325,70 @@
    2.34  include $(BUILDDIR)/common/internal/BinaryPlugs.gmk
    2.35  
    2.36  #
    2.37 -# Get top level sccs_get rule
    2.38 +# Test rule
    2.39  #
    2.40 -include $(BUILDDIR)/common/Rules-SCCS.gmk
    2.41  
    2.42 +.NOTPARALLEL: test_run
    2.43 +
    2.44 +test:
    2.45 +	$(MAKE) test_run
    2.46 +
    2.47 +test_run: test_clean test_start test_summary
    2.48 +
    2.49 +test_start:
    2.50 +	@$(ECHO) "Tests started at `$(DATE)`"
    2.51 +
    2.52 +test_clean:
    2.53 +	$(RM) $(OUTPUTDIR)/test_failures.txt $(OUTPUTDIR)/test_log.txt
    2.54 +
    2.55 +test_summary: $(OUTPUTDIR)/test_failures.txt
    2.56 +	@$(ECHO) "#################################################"
    2.57 +	@$(ECHO) "Tests completed at `$(DATE)`"
    2.58 +	@( $(EGREP) '^TEST STATS:' $(OUTPUTDIR)/test_log.txt \
    2.59 +          || $(ECHO) "No TEST STATS seen in log" )
    2.60 +	@$(ECHO) "For complete details see: $(OUTPUTDIR)/test_log.txt"
    2.61 +	@$(ECHO) "#################################################"
    2.62 +	@if [ -s $< ] ; then                                           \
    2.63 +          $(ECHO) "ERROR: Test failure count: `$(CAT) $< | $(WC) -l`"; \
    2.64 +          $(CAT) $<;                                                   \
    2.65 +          exit 1;                                                      \
    2.66 +        else                                                           \
    2.67 +          $(ECHO) "Success! No failures detected";                     \
    2.68 +        fi
    2.69 +
    2.70 +# Get failure list from log
    2.71 +$(OUTPUTDIR)/test_failures.txt: $(OUTPUTDIR)/test_log.txt
    2.72 +	@$(RM) $@
    2.73 +	@( $(EGREP) '^FAILED:' $< || $(ECHO) "" ) | $(NAWK) 'length>0' > $@
    2.74 +
    2.75 +# Get log file of all tests run
    2.76 +JDK_TO_TEST := $(shell 							\
    2.77 +  if [ -d "$(ABS_OUTPUTDIR)/j2sdk-image" ] ; then 			\
    2.78 +    $(ECHO) "$(ABS_OUTPUTDIR)/j2sdk-image"; 				\
    2.79 +  elif [ -d "$(ABS_OUTPUTDIR)/bin" ] ; then 				\
    2.80 +    $(ECHO) "$(ABS_OUTPUTDIR)"; 					\
    2.81 +  elif [ "$(PRODUCT_HOME)" != "" -a -d "$(PRODUCT_HOME)/bin" ] ; then 	\
    2.82 +    $(ECHO) "$(PRODUCT_HOME)"; 						\
    2.83 +  fi 									\
    2.84 +)
    2.85 +
    2.86 +TEST_TARGETS=jdk_all
    2.87 +$(OUTPUTDIR)/test_log.txt:
    2.88 +	$(RM) $@
    2.89 +	( $(CD) ../test &&                                              \
    2.90 +          $(MAKE) NO_STOPPING=- PRODUCT_HOME=$(JDK_TO_TEST) $(TEST_TARGETS) \
    2.91 +        ) | tee $@
    2.92 +
    2.93 +#
    2.94  # JPRT rules
    2.95 +#
    2.96 +
    2.97  include jprt.gmk
    2.98  
    2.99  #
   2.100  # Phonies to avoid accidents.
   2.101  #
   2.102  .PHONY: all build clean clobber optimized debug fastdebug create_links \
   2.103 -	import import_product import_fastdebug import_debug
   2.104 +	import import_product import_fastdebug import_debug \
   2.105 +	test test_run test_start test_clean test_summary
   2.106  
     3.1 --- a/make/common/Cscope.gmk	Tue Oct 12 13:34:59 2010 -0400
     3.2 +++ b/make/common/Cscope.gmk	Mon Oct 18 11:25:28 2010 -0400
     3.3 @@ -76,7 +76,7 @@
     3.4  # What files should we include?  A simple rule might be just those files under
     3.5  # SCM control, however this would miss files we create like the opcodes and
     3.6  # CClassHeaders.  The following attempts to find everything that is *useful*.
     3.7 -# (.del files are created by sccsrm, demo directories contain many .java files
     3.8 +# (demo directories contain many .java files
     3.9  # that probably aren't useful for development, and the pkgarchive may contain
    3.10  # duplicates of files within the source hierarchy).  The ordering of the .raw
    3.11  # file is an attempt to make cscope display the most relevant files first.
     4.1 --- a/make/common/Defs.gmk	Tue Oct 12 13:34:59 2010 -0400
     4.2 +++ b/make/common/Defs.gmk	Mon Oct 18 11:25:28 2010 -0400
     4.3 @@ -334,7 +334,7 @@
     4.4  DOCSDIRSUFFIX       =
     4.5  
     4.6  # The MESSAGE, WARNING and ERROR files are used to store sanityck and 
     4.7 -# SCCS check messages, warnings and errors. 
     4.8 +# warnings and errors. 
     4.9  ifndef ERROR_FILE
    4.10    ERROR_FILE   = $(OUTPUTDIR)/sanityCheckErrors.txt
    4.11  endif
    4.12 @@ -634,38 +634,6 @@
    4.13  
    4.14  VERSION_DEFINES = -DRELEASE='"$(RELEASE)"'
    4.15  
    4.16 -# Note: As a rule, GNU Make rules should not appear in any of the 
    4.17 -# Defs*.gmk files. These were added for Kestrel-Solaris and do address
    4.18 -# a TeamWare bug. They should be moved elsewhere for Merlin.
    4.19 -# 
    4.20 -#  Override gnumake built-in rules which do sccs get operations badly.
    4.21 -#  (They put the checked out code in the current directory, not in the
    4.22 -#  directory of the original file.) 
    4.23 -# Since this is a symptom of a teamware failure, complain and die on the spot.
    4.24 -
    4.25 -# This message immediately goes to stdout and the build terminates.
    4.26 -define SCCS-trouble
    4.27 -$(error  \
    4.28 -"ERROR: File $@ referenced while building in $(CURRENT_DIRECTORY) \
    4.29 - is out of date with respect to its SCCS file $<. \
    4.30 - This can happen from an unresolved Teamware conflict, a file movement, or \
    4.31 - a failure in which SCCS files are updated but the 'sccs get' was not done. \
    4.32 - You should double check for other out of date files in your workspace. \
    4.33 - Or run: cd $(TOPDIR) && $(MAKE) sccs_get")
    4.34 -endef
    4.35 -
    4.36 -%:: s.%
    4.37 -	@$(SCCS-trouble)
    4.38 -%:: SCCS/s.%
    4.39 -	@$(SCCS-trouble)
    4.40 -	@$(ECHO) "         is out of date with respect to its SCCS file." >> $(WARNING_FILE)
    4.41 -	@$(ECHO) "         This file may be from an unresolved Teamware conflict." >> $(WARNING_FILE)
    4.42 -	@$(ECHO) "         This is also a symptom of a Teamware bringover/putback failure" >> $(WARNING_FILE)
    4.43 -	@$(ECHO) "         in which SCCS files are updated but not checked out." >> $(WARNING_FILE)
    4.44 -	@$(ECHO) "         Check for other out of date files in your workspace." >> $(WARNING_FILE)
    4.45 -	@$(ECHO) "" >> $(WARNING_FILE)
    4.46 -	@#exit 666
    4.47 -
    4.48  ifdef INSANE
    4.49    export INSANE
    4.50  endif
     5.1 --- a/make/common/Rules-SCCS.gmk	Tue Oct 12 13:34:59 2010 -0400
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,70 +0,0 @@
     5.4 -#
     5.5 -# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
     5.6 -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.7 -#
     5.8 -# This code is free software; you can redistribute it and/or modify it
     5.9 -# under the terms of the GNU General Public License version 2 only, as
    5.10 -# published by the Free Software Foundation.  Oracle designates this
    5.11 -# particular file as subject to the "Classpath" exception as provided
    5.12 -# by Oracle in the LICENSE file that accompanied this code.
    5.13 -#
    5.14 -# This code is distributed in the hope that it will be useful, but WITHOUT
    5.15 -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    5.16 -# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    5.17 -# version 2 for more details (a copy is included in the LICENSE file that
    5.18 -# accompanied this code).
    5.19 -#
    5.20 -# You should have received a copy of the GNU General Public License version
    5.21 -# 2 along with this work; if not, write to the Free Software Foundation,
    5.22 -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    5.23 -#
    5.24 -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    5.25 -# or visit www.oracle.com if you need additional information or have any
    5.26 -# questions.
    5.27 -#
    5.28 -
    5.29 -#
    5.30 -# Only get these rules if SCCS is available
    5.31 -#
    5.32 -
    5.33 -ifdef SCCS
    5.34 -
    5.35 -# SCCS command to extract out latest source
    5.36 -SCCS_GET=$(SCCS) get -s
    5.37 -
    5.38 -#
    5.39 -# Make sure all files in workspace are fresh
    5.40 -#
    5.41 -TEMP_ALL_FILES=$(JDK_TOPDIR)/temp_filelist
    5.42 -$(TEMP_ALL_FILES): $(JDK_TOPDIR)/Codemgr_wsdata/nametable
    5.43 -	$(prep-target)
    5.44 -	@$(CUT) -d' ' -f1 $< \
    5.45 -	    | $(GREP) -v '^VERSION' \
    5.46 -	    | $(GREP) -v '^deleted_files' \
    5.47 -	    | $(GREP) -v '^Codemgr_wsdata' > $@
    5.48 -
    5.49 -sccs_get: $(TEMP_ALL_FILES)
    5.50 -	@$(PRINTF) "Workspace has %d files\n"  `$(CAT) $< | $(WC) -l`
    5.51 -	@count=0; \
    5.52 -	for i in `$(CAT) $<` ; do \
    5.53 -	    f=$(JDK_TOPDIR)/$$i; \
    5.54 -	    count=`$(EXPR) $$count '+' 1`; \
    5.55 -	    if [ `$(EXPR) $$count '%' 100` = 0 ] ; then \
    5.56 -		$(PRINTF) "\rChecked $$count files"; \
    5.57 -	    fi; \
    5.58 -	    if [ ! -f $$f ] ; then \
    5.59 -		$(PRINTF) "\r$(SCCS_GET) $$f\n"; \
    5.60 -		(cd `$(DIRNAME) $$f` && $(SCCS_GET) `$(BASENAME) $$f`); \
    5.61 -	    elif /usr/bin/test $$f -ot `$(DIRNAME) $$f`/SCCS/s.`$(BASENAME) $$f` ; then \
    5.62 -		$(PRINTF) "\r$(SCCS_GET) $$f\n"; \
    5.63 -		(cd `$(DIRNAME) $$f` && $(SCCS_GET) `$(BASENAME) $$f`); \
    5.64 -	    fi; \
    5.65 -	done; \
    5.66 -	$(PRINTF) "\rChecked $$count files\n"
    5.67 -
    5.68 -#
    5.69 -# Phonies to avoid accidents.
    5.70 -#
    5.71 -.PHONY: sccs_get
    5.72 -
    5.73 -endif
     6.1 --- a/make/common/shared/Defs-utils.gmk	Tue Oct 12 13:34:59 2010 -0400
     6.2 +++ b/make/common/shared/Defs-utils.gmk	Mon Oct 18 11:25:28 2010 -0400
     6.3 @@ -33,7 +33,7 @@
     6.4  #            UTILS_COMMAND_PATH
     6.5  #         /usr/bin/ 
     6.6  #            UTILS_USR_BIN_PATH
     6.7 -#         /usr/ccs/bin/ (sccs, m4, lex, yacc, as, ar, strip, mcs)
     6.8 +#         /usr/ccs/bin/ (m4, lex, yacc, as, ar, strip, mcs)
     6.9  #            UTILS_CCS_BIN_PATH
    6.10  #         Dev Tools: zip, unzip, etc that we may have special versions of
    6.11  #            UTILS_DEVTOOL_PATH
    6.12 @@ -117,7 +117,6 @@
    6.13  RMDIR          = $(UTILS_COMMAND_PATH)rmdir
    6.14  RPM            = $(UTILS_COMMAND_PATH)rpm
    6.15  RPMBUILD       = $(UTILS_COMMAND_PATH)rpmbuild
    6.16 -SCCS           = $(UTILS_CCS_BIN_PATH)sccs
    6.17  SED            = $(UTILS_COMMAND_PATH)sed
    6.18  SH             = $(UTILS_COMMAND_PATH)sh
    6.19  SHOWREV        = $(UTILS_USR_BIN_PATH)showrev
    6.20 @@ -183,7 +182,7 @@
    6.21    NAWK           = $(USRBIN_PATH)gawk
    6.22    # Intrinsic unix command, with backslash-escaped character interpretation
    6.23    ECHO           = /bin/echo -e
    6.24 -  # These are really in UTILS_USR_BIN_PATH on Linux (only sccs is not)
    6.25 +  # These are really in UTILS_USR_BIN_PATH on Linux
    6.26    AR             = $(UTILS_USR_BIN_PATH)ar
    6.27    AS             = $(UTILS_USR_BIN_PATH)as
    6.28    LD             = $(UTILS_USR_BIN_PATH)ld
     7.1 --- a/make/common/shared/Defs.gmk	Tue Oct 12 13:34:59 2010 -0400
     7.2 +++ b/make/common/shared/Defs.gmk	Mon Oct 18 11:25:28 2010 -0400
     7.3 @@ -219,7 +219,7 @@
     7.4    PRODUCT_NAME = Java(TM)
     7.5    PRODUCT_SUFFIX = SE Runtime Environment
     7.6    JDK_RC_PLATFORM_NAME = Platform SE
     7.7 -  COMPANY_NAME = Oracle
     7.8 +  COMPANY_NAME = Oracle Corporation
     7.9  endif
    7.10  
    7.11  RUNTIME_NAME = $(PRODUCT_NAME) $(PRODUCT_SUFFIX)
     8.1 --- a/make/java/java/FILES_java.gmk	Tue Oct 12 13:34:59 2010 -0400
     8.2 +++ b/make/java/java/FILES_java.gmk	Mon Oct 18 11:25:28 2010 -0400
     8.3 @@ -284,6 +284,7 @@
     8.4      java/util/concurrent/CancellationException.java \
     8.5      java/util/concurrent/CompletionService.java \
     8.6      java/util/concurrent/ConcurrentHashMap.java \
     8.7 +    java/util/concurrent/ConcurrentLinkedDeque.java \
     8.8      java/util/concurrent/ConcurrentLinkedQueue.java \
     8.9      java/util/concurrent/ConcurrentMap.java \
    8.10      java/util/concurrent/ConcurrentNavigableMap.java \
     9.1 --- a/make/jprt.properties	Tue Oct 12 13:34:59 2010 -0400
     9.2 +++ b/make/jprt.properties	Mon Oct 18 11:25:28 2010 -0400
     9.3 @@ -25,43 +25,265 @@
     9.4  
     9.5  # Properties for jprt
     9.6  
     9.7 -# Use whatever release that the submitted job requests
     9.8 +# At submit time, the release supplied will be in jprt.submit.release
     9.9 +#    and will be one of the official release names defined in jprt.
    9.10 +#    jprt supports property value expansion using ${property.name} syntax.
    9.11 +
    9.12 +# This tells jprt what default release we want to build
    9.13  jprt.tools.default.release=${jprt.submit.release}
    9.14  
    9.15  # The different build flavors we want, we override here so we just get these 2
    9.16  jprt.build.flavors=product,fastdebug
    9.17  
    9.18 -# Standard test target for everybody
    9.19 -jprt.test.targets=*-*-*-jvm98
    9.20 +# Define the Windows we want (temporary)
    9.21 +jprt.my.windows.i586.jdk7b107=windows_i586_5.0
    9.22 +jprt.my.windows.i586.jdk7temp=windows_i586_5.0
    9.23 +jprt.my.windows.i586.jdk7=windows_i586_5.1
    9.24 +jprt.my.windows.i586=${jprt.my.windows.i586.${jprt.tools.default.release}}
    9.25  
    9.26 -# Test targets in test/Makefile (some longer running tests only test c2)
    9.27 -jprt.make.rule.test.targets=    \
    9.28 -   *-product-*-jdk_beans1,      \
    9.29 -   *-product-*-jdk_beans2,      \
    9.30 -   *-product-*-jdk_beans3,      \
    9.31 -   *-product-*-jdk_io,          \
    9.32 -   *-product-*-jdk_lang,        \
    9.33 -   *-product-*-jdk_management1, \
    9.34 -   *-product-*-jdk_management2, \
    9.35 -   *-product-*-jdk_math,        \
    9.36 -   *-product-*-jdk_misc,        \
    9.37 -   *-product-*-jdk_net,         \
    9.38 -   *-product-*-jdk_nio1,        \
    9.39 -   *-product-*-jdk_nio2,        \
    9.40 -   *-product-*-jdk_nio3,        \
    9.41 -   *-product-*-jdk_security1,   \
    9.42 -   *-product-*-jdk_security2,   \
    9.43 -   *-product-*-jdk_security3,   \
    9.44 -   *-product-*-jdk_text,        \
    9.45 -   *-product-*-jdk_tools1,      \
    9.46 -   *-product-*-jdk_tools2,      \
    9.47 -   *-product-*-jdk_util
    9.48 +# Standard list of jprt build targets for this source tree
    9.49 +jprt.build.targets= 						\
    9.50 +    solaris_sparc_5.10-{product|fastdebug}, 			\
    9.51 +    solaris_sparcv9_5.10-{product|fastdebug}, 			\
    9.52 +    solaris_i586_5.10-{product|fastdebug}, 			\
    9.53 +    solaris_x64_5.10-{product|fastdebug}, 			\
    9.54 +    linux_i586_2.6-{product|fastdebug}, 			\
    9.55 +    linux_x64_2.6-{product|fastdebug}, 				\
    9.56 +    ${jprt.my.windows.i586}-{product|fastdebug}, 		\
    9.57 +    windows_x64_5.2-{product|fastdebug}
    9.58  
    9.59 -# Some of these are crashing Xvfb or windows manager, need dedicated DISPLAY per test batch
    9.60 -jprt2.make.rule.test.targets=    \
    9.61 -   *-product-*-jdk_awt,         \
    9.62 -   *-product-*-jdk_rmi,         \
    9.63 -   *-product-*-jdk_swing,       \
    9.64 +# Standard vm test target
    9.65 +jprt.test.targets=						\
    9.66 +    solaris_sparc_5.10-product-c1-jvm98, 			\
    9.67 +    solaris_sparcv9_5.10-product-c2-jvm98, 			\
    9.68 +    solaris_i586_5.10-product-c1-jvm98, 			\
    9.69 +    solaris_x64_5.10-product-c2-jvm98, 				\
    9.70 +    linux_i586_2.6-product-{c1|c2}-jvm98, 			\
    9.71 +    linux_x64_2.6-product-c2-jvm98, 				\
    9.72 +    ${jprt.my.windows.i586}-product-c1-jvm98, 			\
    9.73 +    windows_x64_5.2-product-c2-jvm98
    9.74 +
    9.75 +# User can select the test set with jprt submit "-testset name" option
    9.76 +jprt.my.test.set=${jprt.test.set}
    9.77 +
    9.78 +# Default jdk test targets in test/Makefile (no fastdebug & limited c2)
    9.79 +jprt.make.rule.default.test.targets=				\
    9.80 +    								\
    9.81 +    solaris_sparc_5.10-product-c1-jdk_beans1, 			\
    9.82 +    solaris_sparcv9_5.10-product-c2-jdk_beans1, 		\
    9.83 +    solaris_i586_5.10-product-c1-jdk_beans1, 			\
    9.84 +    solaris_x64_5.10-product-c2-jdk_beans1, 			\
    9.85 +    linux_i586_2.6-product-{c1|c2}-jdk_beans1, 			\
    9.86 +    linux_x64_2.6-product-c2-jdk_beans1, 			\
    9.87 +    ${jprt.my.windows.i586}-product-c1-jdk_beans1, 		\
    9.88 +    windows_x64_5.2-product-c2-jdk_beans1, 			\
    9.89 +    								\
    9.90 +    solaris_sparc_5.10-product-c1-jdk_io, 			\
    9.91 +    solaris_sparcv9_5.10-product-c2-jdk_io, 			\
    9.92 +    solaris_i586_5.10-product-c1-jdk_io, 			\
    9.93 +    solaris_x64_5.10-product-c2-jdk_io, 			\
    9.94 +    linux_i586_2.6-product-{c1|c2}-jdk_io, 			\
    9.95 +    linux_x64_2.6-product-c2-jdk_io, 				\
    9.96 +    ${jprt.my.windows.i586}-product-c1-jdk_io, 			\
    9.97 +    windows_x64_5.2-product-c2-jdk_io, 				\
    9.98 +    								\
    9.99 +    solaris_sparc_5.10-product-c1-jdk_lang, 			\
   9.100 +    solaris_sparcv9_5.10-product-c2-jdk_lang, 			\
   9.101 +    solaris_i586_5.10-product-c1-jdk_lang, 			\
   9.102 +    solaris_x64_5.10-product-c2-jdk_lang, 			\
   9.103 +    linux_i586_2.6-product-{c1|c2}-jdk_lang, 			\
   9.104 +    linux_x64_2.6-product-c2-jdk_lang, 				\
   9.105 +    ${jprt.my.windows.i586}-product-c1-jdk_lang, 		\
   9.106 +    windows_x64_5.2-product-c2-jdk_lang, 			\
   9.107 +    								\
   9.108 +    solaris_sparc_5.10-product-c1-jdk_math, 			\
   9.109 +    solaris_sparcv9_5.10-product-c2-jdk_math, 			\
   9.110 +    solaris_i586_5.10-product-c1-jdk_math, 			\
   9.111 +    solaris_x64_5.10-product-c2-jdk_math, 			\
   9.112 +    linux_i586_2.6-product-{c1|c2}-jdk_math, 			\
   9.113 +    linux_x64_2.6-product-c2-jdk_math, 				\
   9.114 +    ${jprt.my.windows.i586}-product-c1-jdk_math, 		\
   9.115 +    windows_x64_5.2-product-c2-jdk_math, 			\
   9.116 +    								\
   9.117 +    solaris_sparc_5.10-product-c1-jdk_misc, 			\
   9.118 +    solaris_sparcv9_5.10-product-c2-jdk_misc, 			\
   9.119 +    solaris_i586_5.10-product-c1-jdk_misc, 			\
   9.120 +    solaris_x64_5.10-product-c2-jdk_misc, 			\
   9.121 +    linux_i586_2.6-product-{c1|c2}-jdk_misc, 			\
   9.122 +    linux_x64_2.6-product-c2-jdk_misc, 				\
   9.123 +    ${jprt.my.windows.i586}-product-c1-jdk_misc, 		\
   9.124 +    windows_x64_5.2-product-c2-jdk_misc, 			\
   9.125 +    								\
   9.126 +    solaris_sparc_5.10-product-c1-jdk_net, 			\
   9.127 +    solaris_sparcv9_5.10-product-c2-jdk_net, 			\
   9.128 +    solaris_i586_5.10-product-c1-jdk_net, 			\
   9.129 +    solaris_x64_5.10-product-c2-jdk_net, 			\
   9.130 +    linux_i586_2.6-product-{c1|c2}-jdk_net, 			\
   9.131 +    linux_x64_2.6-product-c2-jdk_net, 				\
   9.132 +    ${jprt.my.windows.i586}-product-c1-jdk_net, 		\
   9.133 +    windows_x64_5.2-product-c2-jdk_net, 			\
   9.134 +    								\
   9.135 +    solaris_sparc_5.10-product-c1-jdk_nio1, 			\
   9.136 +    solaris_sparcv9_5.10-product-c2-jdk_nio1, 			\
   9.137 +    solaris_i586_5.10-product-c1-jdk_nio1, 			\
   9.138 +    solaris_x64_5.10-product-c2-jdk_nio1, 			\
   9.139 +    linux_i586_2.6-product-{c1|c2}-jdk_nio1, 			\
   9.140 +    linux_x64_2.6-product-c2-jdk_nio1, 				\
   9.141 +    ${jprt.my.windows.i586}-product-c1-jdk_nio1, 		\
   9.142 +    windows_x64_5.2-product-c2-jdk_nio1, 			\
   9.143 +    								\
   9.144 +    solaris_sparc_5.10-product-c1-jdk_nio2, 			\
   9.145 +    solaris_sparcv9_5.10-product-c2-jdk_nio2, 			\
   9.146 +    solaris_i586_5.10-product-c1-jdk_nio2, 			\
   9.147 +    solaris_x64_5.10-product-c2-jdk_nio2, 			\
   9.148 +    linux_i586_2.6-product-{c1|c2}-jdk_nio2, 			\
   9.149 +    linux_x64_2.6-product-c2-jdk_nio2, 				\
   9.150 +    ${jprt.my.windows.i586}-product-c1-jdk_nio2, 		\
   9.151 +    windows_x64_5.2-product-c2-jdk_nio2, 			\
   9.152 +    								\
   9.153 +    solaris_sparc_5.10-product-c1-jdk_nio3, 			\
   9.154 +    solaris_sparcv9_5.10-product-c2-jdk_nio3, 			\
   9.155 +    solaris_i586_5.10-product-c1-jdk_nio3, 			\
   9.156 +    solaris_x64_5.10-product-c2-jdk_nio3, 			\
   9.157 +    linux_i586_2.6-product-{c1|c2}-jdk_nio3, 			\
   9.158 +    linux_x64_2.6-product-c2-jdk_nio3, 				\
   9.159 +    ${jprt.my.windows.i586}-product-c1-jdk_nio3, 		\
   9.160 +    windows_x64_5.2-product-c2-jdk_nio3, 			\
   9.161 +    								\
   9.162 +    solaris_sparc_5.10-product-c1-jdk_security1, 		\
   9.163 +    solaris_sparcv9_5.10-product-c2-jdk_security1, 		\
   9.164 +    solaris_i586_5.10-product-c1-jdk_security1, 		\
   9.165 +    solaris_x64_5.10-product-c2-jdk_security1, 			\
   9.166 +    linux_i586_2.6-product-{c1|c2}-jdk_security1, 		\
   9.167 +    linux_x64_2.6-product-c2-jdk_security1, 			\
   9.168 +    ${jprt.my.windows.i586}-product-c1-jdk_security1, 		\
   9.169 +    windows_x64_5.2-product-c2-jdk_security1, 			\
   9.170 +    								\
   9.171 +    solaris_sparc_5.10-product-c1-jdk_text, 			\
   9.172 +    solaris_sparcv9_5.10-product-c2-jdk_text, 			\
   9.173 +    solaris_i586_5.10-product-c1-jdk_text, 			\
   9.174 +    solaris_x64_5.10-product-c2-jdk_text, 			\
   9.175 +    linux_i586_2.6-product-{c1|c2}-jdk_text, 			\
   9.176 +    linux_x64_2.6-product-c2-jdk_text, 				\
   9.177 +    ${jprt.my.windows.i586}-product-c1-jdk_text, 		\
   9.178 +    windows_x64_5.2-product-c2-jdk_text, 			\
   9.179 +    								\
   9.180 +    solaris_sparc_5.10-product-c1-jdk_tools1, 			\
   9.181 +    solaris_sparcv9_5.10-product-c2-jdk_tools1, 		\
   9.182 +    solaris_i586_5.10-product-c1-jdk_tools1, 			\
   9.183 +    solaris_x64_5.10-product-c2-jdk_tools1, 			\
   9.184 +    linux_i586_2.6-product-{c1|c2}-jdk_tools1, 			\
   9.185 +    linux_x64_2.6-product-c2-jdk_tools1, 			\
   9.186 +    ${jprt.my.windows.i586}-product-c1-jdk_tools1, 		\
   9.187 +    windows_x64_5.2-product-c2-jdk_tools1, 			\
   9.188 +    								\
   9.189 +    solaris_sparc_5.10-product-c1-jdk_util, 			\
   9.190 +    solaris_sparcv9_5.10-product-c2-jdk_util, 			\
   9.191 +    solaris_i586_5.10-product-c1-jdk_util, 			\
   9.192 +    solaris_x64_5.10-product-c2-jdk_util, 			\
   9.193 +    linux_i586_2.6-product-{c1|c2}-jdk_util, 			\
   9.194 +    linux_x64_2.6-product-c2-jdk_util, 				\
   9.195 +    ${jprt.my.windows.i586}-product-c1-jdk_util, 		\
   9.196 +    windows_x64_5.2-product-c2-jdk_util
   9.197 +
   9.198 +# All jdk test targets in test/Makefile (still no fastdebug & limited c2)
   9.199 +jprt.make.rule.all.test.targets=    				\
   9.200 +    								\
   9.201 +   ${jprt.make.rule.default.test.targets}, 			\
   9.202 +    								\
   9.203 +    solaris_sparc_5.10-product-c1-jdk_awt, 			\
   9.204 +    solaris_sparcv9_5.10-product-c2-jdk_awt, 			\
   9.205 +    solaris_i586_5.10-product-c1-jdk_awt, 			\
   9.206 +    solaris_x64_5.10-product-c2-jdk_awt, 			\
   9.207 +    linux_i586_2.6-product-{c1|c2}-jdk_awt, 			\
   9.208 +    linux_x64_2.6-product-c2-jdk_awt, 				\
   9.209 +    ${jprt.my.windows.i586}-product-c1-jdk_awt, 		\
   9.210 +    windows_x64_5.2-product-c2-jdk_awt, 			\
   9.211 +    								\
   9.212 +    solaris_sparc_5.10-product-c1-jdk_beans2, 			\
   9.213 +    solaris_sparcv9_5.10-product-c2-jdk_beans2, 		\
   9.214 +    solaris_i586_5.10-product-c1-jdk_beans2, 			\
   9.215 +    solaris_x64_5.10-product-c2-jdk_beans2, 			\
   9.216 +    linux_i586_2.6-product-{c1|c2}-jdk_beans2, 			\
   9.217 +    linux_x64_2.6-product-c2-jdk_beans2, 			\
   9.218 +    ${jprt.my.windows.i586}-product-c1-jdk_beans2, 		\
   9.219 +    windows_x64_5.2-product-c2-jdk_beans2, 			\
   9.220 +    								\
   9.221 +    solaris_sparc_5.10-product-c1-jdk_beans3, 			\
   9.222 +    solaris_sparcv9_5.10-product-c2-jdk_beans3, 		\
   9.223 +    solaris_i586_5.10-product-c1-jdk_beans3, 			\
   9.224 +    solaris_x64_5.10-product-c2-jdk_beans3, 			\
   9.225 +    linux_i586_2.6-product-{c1|c2}-jdk_beans3, 			\
   9.226 +    linux_x64_2.6-product-c2-jdk_beans3, 			\
   9.227 +    ${jprt.my.windows.i586}-product-c1-jdk_beans3, 		\
   9.228 +    windows_x64_5.2-product-c2-jdk_beans3, 			\
   9.229 +    								\
   9.230 +    solaris_sparc_5.10-product-c1-jdk_management1, 		\
   9.231 +    solaris_sparcv9_5.10-product-c2-jdk_management1, 		\
   9.232 +    solaris_i586_5.10-product-c1-jdk_management1, 		\
   9.233 +    solaris_x64_5.10-product-c2-jdk_management1, 		\
   9.234 +    linux_i586_2.6-product-{c1|c2}-jdk_management1, 		\
   9.235 +    linux_x64_2.6-product-c2-jdk_management1, 			\
   9.236 +    ${jprt.my.windows.i586}-product-c1-jdk_management1, 	\
   9.237 +    windows_x64_5.2-product-c2-jdk_management1, 		\
   9.238 +    								\
   9.239 +    solaris_sparc_5.10-product-c1-jdk_management2, 		\
   9.240 +    solaris_sparcv9_5.10-product-c2-jdk_management2, 		\
   9.241 +    solaris_i586_5.10-product-c1-jdk_management2, 		\
   9.242 +    solaris_x64_5.10-product-c2-jdk_management2, 		\
   9.243 +    linux_i586_2.6-product-{c1|c2}-jdk_management2, 		\
   9.244 +    linux_x64_2.6-product-c2-jdk_management2, 			\
   9.245 +    ${jprt.my.windows.i586}-product-c1-jdk_management2, 	\
   9.246 +    windows_x64_5.2-product-c2-jdk_management2, 		\
   9.247 +    								\
   9.248 +    solaris_sparc_5.10-product-c1-jdk_rmi, 			\
   9.249 +    solaris_sparcv9_5.10-product-c2-jdk_rmi, 			\
   9.250 +    solaris_i586_5.10-product-c1-jdk_rmi, 			\
   9.251 +    solaris_x64_5.10-product-c2-jdk_rmi, 			\
   9.252 +    linux_i586_2.6-product-{c1|c2}-jdk_rmi, 			\
   9.253 +    linux_x64_2.6-product-c2-jdk_rmi, 				\
   9.254 +    ${jprt.my.windows.i586}-product-c1-jdk_rmi, 		\
   9.255 +    windows_x64_5.2-product-c2-jdk_rmi, 			\
   9.256 +    								\
   9.257 +    solaris_sparc_5.10-product-c1-jdk_security2, 		\
   9.258 +    solaris_sparcv9_5.10-product-c2-jdk_security2, 		\
   9.259 +    solaris_i586_5.10-product-c1-jdk_security2, 		\
   9.260 +    solaris_x64_5.10-product-c2-jdk_security2, 			\
   9.261 +    linux_i586_2.6-product-{c1|c2}-jdk_security2, 		\
   9.262 +    linux_x64_2.6-product-c2-jdk_security2, 			\
   9.263 +    ${jprt.my.windows.i586}-product-c1-jdk_security2, 		\
   9.264 +    windows_x64_5.2-product-c2-jdk_security2, 			\
   9.265 +    								\
   9.266 +    solaris_sparc_5.10-product-c1-jdk_security3, 		\
   9.267 +    solaris_sparcv9_5.10-product-c2-jdk_security3, 		\
   9.268 +    solaris_i586_5.10-product-c1-jdk_security3, 		\
   9.269 +    solaris_x64_5.10-product-c2-jdk_security3, 			\
   9.270 +    linux_i586_2.6-product-{c1|c2}-jdk_security3, 		\
   9.271 +    linux_x64_2.6-product-c2-jdk_security3, 			\
   9.272 +    ${jprt.my.windows.i586}-product-c1-jdk_security3, 		\
   9.273 +    windows_x64_5.2-product-c2-jdk_security3, 			\
   9.274 +    								\
   9.275 +    solaris_sparc_5.10-product-c1-jdk_swing, 			\
   9.276 +    solaris_sparcv9_5.10-product-c2-jdk_swing, 			\
   9.277 +    solaris_i586_5.10-product-c1-jdk_swing, 			\
   9.278 +    solaris_x64_5.10-product-c2-jdk_swing, 			\
   9.279 +    linux_i586_2.6-product-{c1|c2}-jdk_swing, 			\
   9.280 +    linux_x64_2.6-product-c2-jdk_swing, 			\
   9.281 +    ${jprt.my.windows.i586}-product-c1-jdk_swing, 		\
   9.282 +    windows_x64_5.2-product-c2-jdk_swing, 			\
   9.283 +    								\
   9.284 +    solaris_sparc_5.10-product-c1-jdk_tools2, 			\
   9.285 +    solaris_sparcv9_5.10-product-c2-jdk_tools2, 		\
   9.286 +    solaris_i586_5.10-product-c1-jdk_tools2, 			\
   9.287 +    solaris_x64_5.10-product-c2-jdk_tools2, 			\
   9.288 +    linux_i586_2.6-product-{c1|c2}-jdk_tools2, 			\
   9.289 +    linux_x64_2.6-product-c2-jdk_tools2, 			\
   9.290 +    ${jprt.my.windows.i586}-product-c1-jdk_tools2, 		\
   9.291 +    windows_x64_5.2-product-c2-jdk_tools2
   9.292 +
   9.293 +# Select list to use (allow for testset to be empty too)
   9.294 +jprt.make.rule..test.targets=${jprt.make.rule.default.test.targets} 
   9.295 +jprt.make.rule.test.targets=${jprt.make.rule.${jprt.my.test.set}.test.targets} 
   9.296  
   9.297  # Directories to be excluded from the source bundles
   9.298  jprt.bundle.exclude.src.dirs=build dist webrev
    10.1 --- a/make/mkdemo/Makefile	Tue Oct 12 13:34:59 2010 -0400
    10.2 +++ b/make/mkdemo/Makefile	Mon Oct 18 11:25:28 2010 -0400
    10.3 @@ -31,7 +31,7 @@
    10.4  PRODUCT = demos
    10.5  include $(BUILDDIR)/common/Defs.gmk
    10.6  
    10.7 -SUBDIRS            = jni
    10.8 +SUBDIRS            = jni nio
    10.9  SUBDIRS_desktop    = applets jfc
   10.10  SUBDIRS_management = management
   10.11  SUBDIRS_misc       = scripting
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/make/mkdemo/nio/Makefile	Mon Oct 18 11:25:28 2010 -0400
    11.3 @@ -0,0 +1,39 @@
    11.4 +#
    11.5 +# Copyright (c) 1997, 2007, 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 for building the jfc demos
   11.31 +#
   11.32 +
   11.33 +BUILDDIR = ../..
   11.34 +PRODUCT = demos
   11.35 +include $(BUILDDIR)/common/Defs.gmk
   11.36 +
   11.37 +SUBDIRS = zipfs
   11.38 +include $(BUILDDIR)/common/Subdirs.gmk
   11.39 +
   11.40 +all build clean clobber::
   11.41 +	$(SUBDIRS-loop)
   11.42 +
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/make/mkdemo/nio/zipfs/Makefile	Mon Oct 18 11:25:28 2010 -0400
    12.3 @@ -0,0 +1,44 @@
    12.4 +#
    12.5 +# Copyright (c) 1997, 2002, Oracle and/or its affiliates. All rights reserved.
    12.6 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    12.7 +#
    12.8 +# This code is free software; you can redistribute it and/or modify it
    12.9 +# under the terms of the GNU General Public License version 2 only, as
   12.10 +# published by the Free Software Foundation.  Oracle designates this
   12.11 +# particular file as subject to the "Classpath" exception as provided
   12.12 +# by Oracle in the LICENSE file that accompanied this code.
   12.13 +#
   12.14 +# This code is distributed in the hope that it will be useful, but WITHOUT
   12.15 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   12.16 +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   12.17 +# version 2 for more details (a copy is included in the LICENSE file that
   12.18 +# accompanied this code).
   12.19 +#
   12.20 +# You should have received a copy of the GNU General Public License version
   12.21 +# 2 along with this work; if not, write to the Free Software Foundation,
   12.22 +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   12.23 +#
   12.24 +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   12.25 +# or visit www.oracle.com if you need additional information or have any
   12.26 +# questions.
   12.27 +#
   12.28 +
   12.29 +#
   12.30 +# Makefile to build the ZipFileSystem demo.
   12.31 +#
   12.32 +
   12.33 +BUILDDIR = ../../..
   12.34 +PRODUCT = demo/zipfs
   12.35 +DEMONAME = zipfs
   12.36 +include $(BUILDDIR)/common/Defs.gmk
   12.37 +
   12.38 +DEMO_ROOT       = $(SHARE_SRC)/demo/nio/$(DEMONAME)
   12.39 +DEMO_TOPFILES   = ./README.txt
   12.40 +DEMO_SRCDIR     = $(DEMO_ROOT)
   12.41 +DEMO_DESTDIR    = $(DEMODIR)/nio/$(DEMONAME)
   12.42 +
   12.43 +#
   12.44 +# Demo jar building rules.
   12.45 +#
   12.46 +include $(BUILDDIR)/common/Demo.gmk
   12.47 +
    13.1 --- a/make/sun/cmm/lcms/Makefile	Tue Oct 12 13:34:59 2010 -0400
    13.2 +++ b/make/sun/cmm/lcms/Makefile	Mon Oct 18 11:25:28 2010 -0400
    13.3 @@ -80,7 +80,12 @@
    13.4  vpath %.c   $(SHARE_SRC)/native/sun/java2d
    13.5  
    13.6  ifeq ($(PLATFORM), windows)
    13.7 -OTHER_CFLAGS += -DCMS_IS_WINDOWS_ -Dsqrtf=sqrt
    13.8 +OTHER_CFLAGS += -DCMS_IS_WINDOWS_
    13.9 +
   13.10 +ifeq ($(COMPILER_VERSION), VS2003)
   13.11 +OTHER_CFLAGS += -Dsqrtf=sqrt
   13.12 +endif
   13.13 +
   13.14  OTHER_LDLIBS = $(OBJDIR)/../../../sun.awt/awt/$(OBJDIRNAME)/awt.lib
   13.15  OTHER_INCLUDES += -I$(SHARE_SRC)/native/sun/java2d \
   13.16                    -I$(SHARE_SRC)/native/sun/awt/debug
    14.1 --- a/src/share/classes/com/sun/rowset/CachedRowSetImpl.java	Tue Oct 12 13:34:59 2010 -0400
    14.2 +++ b/src/share/classes/com/sun/rowset/CachedRowSetImpl.java	Mon Oct 18 11:25:28 2010 -0400
    14.3 @@ -525,7 +525,7 @@
    14.4  
    14.5          iMatchColumns = new Vector(10);
    14.6          for(int i = 0; i < 10 ; i++) {
    14.7 -           iMatchColumns.add(i,new Integer(-1));
    14.8 +           iMatchColumns.add(i,Integer.valueOf(-1));
    14.9          }
   14.10  
   14.11          strMatchColumns = new Vector(10);
   14.12 @@ -889,7 +889,12 @@
   14.13                      success = false;
   14.14                  } else {
   14.15                      tWriter = (TransactionalWriter)rowSetWriter;
   14.16 -                    ((CachedRowSetWriter)tWriter).commit(this, updateOnInsert);
   14.17 +                    if (tWriter instanceof CachedRowSetWriter) {
   14.18 +                        ((CachedRowSetWriter)tWriter).commit(this, updateOnInsert);
   14.19 +                    } else {
   14.20 +                        tWriter.commit();
   14.21 +                    }
   14.22 +
   14.23                      success = true;
   14.24                  }
   14.25              }
   14.26 @@ -1294,7 +1299,7 @@
   14.27          tMap = new TreeMap();
   14.28  
   14.29          for (int i = 0; i<numRows; i++) {
   14.30 -            tMap.put(new Integer(i), rvh.get(i));
   14.31 +            tMap.put(Integer.valueOf(i), rvh.get(i));
   14.32          }
   14.33  
   14.34          return (tMap.values());
   14.35 @@ -1806,7 +1811,7 @@
   14.36              return (byte)0;
   14.37          }
   14.38          try {
   14.39 -            return ((new Byte(value.toString())).byteValue());
   14.40 +            return ((Byte.valueOf(value.toString())).byteValue());
   14.41          } catch (NumberFormatException ex) {
   14.42              throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.bytefail").toString(),
   14.43                    new Object[] {value.toString().trim(), columnIndex}));
   14.44 @@ -1850,7 +1855,7 @@
   14.45          }
   14.46  
   14.47          try {
   14.48 -            return ((new Short(value.toString().trim())).shortValue());
   14.49 +            return ((Short.valueOf(value.toString().trim())).shortValue());
   14.50          } catch (NumberFormatException ex) {
   14.51              throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.shortfail").toString(),
   14.52                    new Object[] {value.toString().trim(), columnIndex}));
   14.53 @@ -1893,7 +1898,7 @@
   14.54          }
   14.55  
   14.56          try {
   14.57 -            return ((new Integer(value.toString().trim())).intValue());
   14.58 +            return ((Integer.valueOf(value.toString().trim())).intValue());
   14.59          } catch (NumberFormatException ex) {
   14.60              throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.intfail").toString(),
   14.61                    new Object[] {value.toString().trim(), columnIndex}));
   14.62 @@ -1936,7 +1941,7 @@
   14.63              return (long)0;
   14.64          }
   14.65          try {
   14.66 -            return ((new Long(value.toString().trim())).longValue());
   14.67 +            return ((Long.valueOf(value.toString().trim())).longValue());
   14.68          } catch (NumberFormatException ex) {
   14.69              throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.longfail").toString(),
   14.70                    new Object[] {value.toString().trim(), columnIndex}));
   14.71 @@ -4014,18 +4019,18 @@
   14.72          try {
   14.73              switch (trgType) {
   14.74                  case java.sql.Types.BIT:
   14.75 -                    Integer i = new Integer(srcObj.toString().trim());
   14.76 -                    return i.equals(new Integer((int)0)) ?
   14.77 -                    new Boolean(false) :
   14.78 -                        new Boolean(true);
   14.79 +                    Integer i = Integer.valueOf(srcObj.toString().trim());
   14.80 +                    return i.equals(Integer.valueOf((int)0)) ?
   14.81 +                    Boolean.valueOf(false) :
   14.82 +                        Boolean.valueOf(true);
   14.83                  case java.sql.Types.TINYINT:
   14.84 -                    return new Byte(srcObj.toString().trim());
   14.85 +                    return Byte.valueOf(srcObj.toString().trim());
   14.86                  case java.sql.Types.SMALLINT:
   14.87 -                    return new Short(srcObj.toString().trim());
   14.88 +                    return Short.valueOf(srcObj.toString().trim());
   14.89                  case java.sql.Types.INTEGER:
   14.90 -                    return new Integer(srcObj.toString().trim());
   14.91 +                    return Integer.valueOf(srcObj.toString().trim());
   14.92                  case java.sql.Types.BIGINT:
   14.93 -                    return new Long(srcObj.toString().trim());
   14.94 +                    return Long.valueOf(srcObj.toString().trim());
   14.95                  case java.sql.Types.NUMERIC:
   14.96                  case java.sql.Types.DECIMAL:
   14.97                      return new BigDecimal(srcObj.toString().trim());
   14.98 @@ -4037,7 +4042,7 @@
   14.99                  case java.sql.Types.CHAR:
  14.100                  case java.sql.Types.VARCHAR:
  14.101                  case java.sql.Types.LONGVARCHAR:
  14.102 -                    return new String(srcObj.toString());
  14.103 +                    return srcObj.toString();
  14.104                  default:
  14.105                      throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()+ trgType);
  14.106              }
  14.107 @@ -4134,7 +4139,7 @@
  14.108                  case java.sql.Types.CHAR:
  14.109                  case java.sql.Types.VARCHAR:
  14.110                  case java.sql.Types.LONGVARCHAR:
  14.111 -                    return new String(srcObj.toString());
  14.112 +                    return srcObj.toString();
  14.113                  default:
  14.114                      throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());
  14.115              }
  14.116 @@ -4181,12 +4186,12 @@
  14.117          try {
  14.118              switch (trgType) {
  14.119                  case java.sql.Types.BIT:
  14.120 -                    Integer i = new Integer(srcObj.toString().trim());
  14.121 -                    return i.equals(new Integer((int)0)) ?
  14.122 -                    new Boolean(false) :
  14.123 -                        new Boolean(true);
  14.124 +                    Integer i = Integer.valueOf(srcObj.toString().trim());
  14.125 +                    return i.equals(Integer.valueOf((int)0)) ?
  14.126 +                    Boolean.valueOf(false) :
  14.127 +                        Boolean.valueOf(true);
  14.128                  case java.sql.Types.BOOLEAN:
  14.129 -                    return new Boolean(srcObj.toString().trim());
  14.130 +                    return Boolean.valueOf(srcObj.toString().trim());
  14.131                  default:
  14.132                      throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()+ trgType);
  14.133              }
  14.134 @@ -4260,7 +4265,7 @@
  14.135          checkIndex(columnIndex);
  14.136          // make sure the cursor is on a valid row
  14.137          checkCursor();
  14.138 -        Object obj = convertBoolean(new Boolean(x),
  14.139 +        Object obj = convertBoolean(Boolean.valueOf(x),
  14.140          java.sql.Types.BIT,
  14.141          RowSetMD.getColumnType(columnIndex));
  14.142  
  14.143 @@ -4296,7 +4301,7 @@
  14.144          // make sure the cursor is on a valid row
  14.145          checkCursor();
  14.146  
  14.147 -        Object obj = convertNumeric(new Byte(x),
  14.148 +        Object obj = convertNumeric(Byte.valueOf(x),
  14.149          java.sql.Types.TINYINT,
  14.150          RowSetMD.getColumnType(columnIndex));
  14.151  
  14.152 @@ -4332,7 +4337,7 @@
  14.153          // make sure the cursor is on a valid row
  14.154          checkCursor();
  14.155  
  14.156 -        Object obj = convertNumeric(new Short(x),
  14.157 +        Object obj = convertNumeric(Short.valueOf(x),
  14.158          java.sql.Types.SMALLINT,
  14.159          RowSetMD.getColumnType(columnIndex));
  14.160  
  14.161 @@ -4367,7 +4372,7 @@
  14.162          checkIndex(columnIndex);
  14.163          // make sure the cursor is on a valid row
  14.164          checkCursor();
  14.165 -        Object obj = convertNumeric(new Integer(x),
  14.166 +        Object obj = convertNumeric(Integer.valueOf(x),
  14.167          java.sql.Types.INTEGER,
  14.168          RowSetMD.getColumnType(columnIndex));
  14.169  
  14.170 @@ -4403,7 +4408,7 @@
  14.171          // make sure the cursor is on a valid row
  14.172          checkCursor();
  14.173  
  14.174 -        Object obj = convertNumeric(new Long(x),
  14.175 +        Object obj = convertNumeric(Long.valueOf(x),
  14.176          java.sql.Types.BIGINT,
  14.177          RowSetMD.getColumnType(columnIndex));
  14.178  
  14.179 @@ -6429,7 +6434,7 @@
  14.180          if (tabName == null)
  14.181              throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.tablename").toString());
  14.182          else
  14.183 -            tableName = new String(tabName);
  14.184 +            tableName = tabName;
  14.185      }
  14.186  
  14.187      /**
  14.188 @@ -6940,7 +6945,7 @@
  14.189           }
  14.190  
  14.191           for( int i = 0;i < columnIdxes.length ;i++) {
  14.192 -            iMatchColumns.set(i,new Integer(-1));
  14.193 +            iMatchColumns.set(i,Integer.valueOf(-1));
  14.194           }
  14.195      }
  14.196  
  14.197 @@ -7049,7 +7054,7 @@
  14.198             }
  14.199          }
  14.200          for(int i = 0 ;i < columnIdxes.length; i++) {
  14.201 -           iMatchColumns.add(i,new Integer(columnIdxes[i]));
  14.202 +           iMatchColumns.add(i,Integer.valueOf(columnIdxes[i]));
  14.203          }
  14.204      }
  14.205  
  14.206 @@ -7104,7 +7109,7 @@
  14.207              throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols1").toString());
  14.208          } else {
  14.209              // set iMatchColumn
  14.210 -            iMatchColumns.set(0, new Integer(columnIdx));
  14.211 +            iMatchColumns.set(0, Integer.valueOf(columnIdx));
  14.212              //strMatchColumn = null;
  14.213          }
  14.214      }
  14.215 @@ -7126,7 +7131,7 @@
  14.216       */
  14.217      public void setMatchColumn(String columnName) throws SQLException {
  14.218          // validate, if col is ok to be set
  14.219 -        if(columnName.equals(null) || ((columnName = columnName.trim()) == "" )) {
  14.220 +        if(columnName == null || (columnName= columnName.trim()).equals("") ) {
  14.221              throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols2").toString());
  14.222          } else {
  14.223              // set strMatchColumn
  14.224 @@ -7151,13 +7156,13 @@
  14.225       */
  14.226      public void unsetMatchColumn(int columnIdx) throws SQLException {
  14.227          // check if we are unsetting the SAME column
  14.228 -        if(! iMatchColumns.get(0).equals(new Integer(columnIdx) )  ) {
  14.229 +        if(! iMatchColumns.get(0).equals(Integer.valueOf(columnIdx) )  ) {
  14.230              throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch").toString());
  14.231          } else if(strMatchColumns.get(0) != null) {
  14.232              throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch1").toString());
  14.233          } else {
  14.234                  // that is, we are unsetting it.
  14.235 -               iMatchColumns.set(0, new Integer(-1));
  14.236 +               iMatchColumns.set(0, Integer.valueOf(-1));
  14.237          }
  14.238      }
  14.239  
    15.1 --- a/src/share/classes/com/sun/rowset/FilteredRowSetImpl.java	Tue Oct 12 13:34:59 2010 -0400
    15.2 +++ b/src/share/classes/com/sun/rowset/FilteredRowSetImpl.java	Mon Oct 18 11:25:28 2010 -0400
    15.3 @@ -499,7 +499,7 @@
    15.4  
    15.5       if(onInsertRow) {
    15.6          if(p != null) {
    15.7 -           bool = p.evaluate(new Integer(x),columnIndex);
    15.8 +           bool = p.evaluate(Integer.valueOf(x),columnIndex);
    15.9  
   15.10             if(!bool) {
   15.11                throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
   15.12 @@ -566,7 +566,7 @@
   15.13  
   15.14        if(onInsertRow) {
   15.15           if(p != null) {
   15.16 -            bool = p.evaluate(new Boolean(x) , columnIndex);
   15.17 +            bool = p.evaluate(Boolean.valueOf(x) , columnIndex);
   15.18  
   15.19              if(!bool) {
   15.20                 throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
   15.21 @@ -634,7 +634,7 @@
   15.22  
   15.23        if(onInsertRow) {
   15.24           if(p != null) {
   15.25 -            bool = p.evaluate(new Byte(x),columnIndex);
   15.26 +            bool = p.evaluate(Byte.valueOf(x),columnIndex);
   15.27  
   15.28              if(!bool) {
   15.29                  throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
   15.30 @@ -703,7 +703,7 @@
   15.31  
   15.32        if(onInsertRow) {
   15.33           if(p != null) {
   15.34 -            bool = p.evaluate(new Short(x), columnIndex);
   15.35 +            bool = p.evaluate(Short.valueOf(x), columnIndex);
   15.36  
   15.37              if(!bool) {
   15.38                 throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
   15.39 @@ -771,7 +771,7 @@
   15.40  
   15.41        if(onInsertRow) {
   15.42           if(p != null) {
   15.43 -            bool = p.evaluate(new Long(x), columnIndex);
   15.44 +            bool = p.evaluate(Long.valueOf(x), columnIndex);
   15.45  
   15.46              if(!bool) {
   15.47                 throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
   15.48 @@ -1106,12 +1106,12 @@
   15.49     public void updateBytes(int columnIndex , byte []x) throws SQLException {
   15.50  
   15.51        boolean bool;
   15.52 -      String val = new String();
   15.53 +      String val = "";
   15.54  
   15.55        Byte [] obj_arr = new Byte[x.length];
   15.56  
   15.57        for(int i = 0; i < x.length; i++) {
   15.58 -         obj_arr[i] = new Byte(x[i]);
   15.59 +         obj_arr[i] = Byte.valueOf(x[i]);
   15.60           val = val.concat(obj_arr[i].toString());
   15.61       }
   15.62  
    16.1 --- a/src/share/classes/com/sun/rowset/JdbcRowSetImpl.java	Tue Oct 12 13:34:59 2010 -0400
    16.2 +++ b/src/share/classes/com/sun/rowset/JdbcRowSetImpl.java	Mon Oct 18 11:25:28 2010 -0400
    16.3 @@ -215,7 +215,7 @@
    16.4  
    16.5          iMatchColumns = new Vector(10);
    16.6          for(int i = 0; i < 10 ; i++) {
    16.7 -           iMatchColumns.add(i,new Integer(-1));
    16.8 +           iMatchColumns.add(i,Integer.valueOf(-1));
    16.9          }
   16.10  
   16.11          strMatchColumns = new Vector(10);
   16.12 @@ -288,7 +288,7 @@
   16.13  
   16.14          iMatchColumns = new Vector(10);
   16.15          for(int i = 0; i < 10 ; i++) {
   16.16 -           iMatchColumns.add(i,new Integer(-1));
   16.17 +           iMatchColumns.add(i,Integer.valueOf(-1));
   16.18          }
   16.19  
   16.20          strMatchColumns = new Vector(10);
   16.21 @@ -375,7 +375,7 @@
   16.22  
   16.23          iMatchColumns = new Vector(10);
   16.24          for(int i = 0; i < 10 ; i++) {
   16.25 -           iMatchColumns.add(i,new Integer(-1));
   16.26 +           iMatchColumns.add(i,Integer.valueOf(-1));
   16.27          }
   16.28  
   16.29          strMatchColumns = new Vector(10);
   16.30 @@ -465,7 +465,7 @@
   16.31  
   16.32          iMatchColumns = new Vector(10);
   16.33          for(int i = 0; i < 10 ; i++) {
   16.34 -           iMatchColumns.add(i,new Integer(-1));
   16.35 +           iMatchColumns.add(i,Integer.valueOf(-1));
   16.36          }
   16.37  
   16.38          strMatchColumns = new Vector(10);
   16.39 @@ -3754,7 +3754,7 @@
   16.40           }
   16.41  
   16.42           for( int i = 0;i < columnIdxes.length ;i++) {
   16.43 -            iMatchColumns.set(i,new Integer(-1));
   16.44 +            iMatchColumns.set(i,Integer.valueOf(-1));
   16.45           }
   16.46      }
   16.47  
   16.48 @@ -3863,7 +3863,7 @@
   16.49             }
   16.50          }
   16.51          for(int i = 0 ;i < columnIdxes.length; i++) {
   16.52 -           iMatchColumns.add(i,new Integer(columnIdxes[i]));
   16.53 +           iMatchColumns.add(i,Integer.valueOf(columnIdxes[i]));
   16.54          }
   16.55      }
   16.56  
   16.57 @@ -3918,7 +3918,7 @@
   16.58              throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.matchcols1").toString());
   16.59          } else {
   16.60              // set iMatchColumn
   16.61 -            iMatchColumns.set(0, new Integer(columnIdx));
   16.62 +            iMatchColumns.set(0, Integer.valueOf(columnIdx));
   16.63              //strMatchColumn = null;
   16.64          }
   16.65      }
   16.66 @@ -3940,7 +3940,7 @@
   16.67       */
   16.68      public void setMatchColumn(String columnName) throws SQLException {
   16.69          // validate, if col is ok to be set
   16.70 -        if(columnName.equals(null) || ((columnName = columnName.trim()) == "" )) {
   16.71 +        if(columnName == null || (columnName= columnName.trim()).equals("")) {
   16.72              throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.matchcols2").toString());
   16.73          } else {
   16.74              // set strMatchColumn
   16.75 @@ -3965,13 +3965,13 @@
   16.76       */
   16.77      public void unsetMatchColumn(int columnIdx) throws SQLException {
   16.78          // check if we are unsetting the SAME column
   16.79 -        if(! iMatchColumns.get(0).equals(new Integer(columnIdx) )  ) {
   16.80 +        if(! iMatchColumns.get(0).equals(Integer.valueOf(columnIdx) )  ) {
   16.81              throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.unsetmatch").toString());
   16.82          } else if(strMatchColumns.get(0) != null) {
   16.83              throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.usecolname").toString());
   16.84          } else {
   16.85                  // that is, we are unsetting it.
   16.86 -               iMatchColumns.set(0, new Integer(-1));
   16.87 +               iMatchColumns.set(0, Integer.valueOf(-1));
   16.88          }
   16.89      }
   16.90  
    17.1 --- a/src/share/classes/com/sun/rowset/JoinRowSetImpl.java	Tue Oct 12 13:34:59 2010 -0400
    17.2 +++ b/src/share/classes/com/sun/rowset/JoinRowSetImpl.java	Mon Oct 18 11:25:28 2010 -0400
    17.3 @@ -33,6 +33,8 @@
    17.4  import java.util.*;
    17.5  
    17.6  import javax.sql.rowset.*;
    17.7 +import javax.sql.rowset.spi.SyncProvider;
    17.8 +import javax.sql.rowset.spi.SyncProviderException;
    17.9  
   17.10  /**
   17.11   * The standard implementation of the <code>JoinRowSet</code>
   17.12 @@ -550,7 +552,7 @@
   17.13                 // This 'if' will be removed after all joins are implemented.
   17.14                 throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.notsupported").toString());
   17.15             } else {
   17.16 -              Integer Intgr = new Integer(JoinRowSet.INNER_JOIN);
   17.17 +              Integer Intgr = Integer.valueOf(JoinRowSet.INNER_JOIN);
   17.18                vecJoinType.add(Intgr);
   17.19             }
   17.20         } else {
   17.21 @@ -874,8 +876,8 @@
   17.22  
   17.23         String strWhereClause = "Select ";
   17.24         String whereClause;
   17.25 -       String tabName= null;
   17.26 -       String strTabName = null;
   17.27 +       String tabName= "";
   17.28 +       String strTabName = "";
   17.29         int sz,cols;
   17.30         int j;
   17.31         CachedRowSetImpl crs;
   17.32 @@ -889,8 +891,6 @@
   17.33         // tableNameX.(rowsetX.getMatchColumnName()) ==
   17.34         // tableNameZ.(rowsetZ.getMatchColumnName()));
   17.35  
   17.36 -       tabName = new String();
   17.37 -       strTabName  = new String();
   17.38         sz = vecRowSetsInJOIN.size();
   17.39         for(int i=0;i<sz; i++) {
   17.40            crs = (CachedRowSetImpl)vecRowSetsInJOIN.get(i);
   17.41 @@ -4311,6 +4311,27 @@
   17.42           return crsInternal.createCopySchema();
   17.43       }
   17.44  
   17.45 +     /**
   17.46 +      * {@inheritDoc}
   17.47 +      */
   17.48 +     public void setSyncProvider(String providerStr) throws SQLException {
   17.49 +         crsInternal.setSyncProvider(providerStr);
   17.50 +     }
   17.51 +
   17.52 +     /**
   17.53 +      * {@inheritDoc}
   17.54 +      */
   17.55 +     public void acceptChanges() throws SyncProviderException {
   17.56 +         crsInternal.acceptChanges();
   17.57 +     }
   17.58 +
   17.59 +     /**
   17.60 +      * {@inheritDoc}
   17.61 +      */
   17.62 +     public SyncProvider getSyncProvider() throws SQLException {
   17.63 +        return crsInternal.getSyncProvider();
   17.64 +     }
   17.65 +
   17.66      /**
   17.67       * This method re populates the resBundle
   17.68       * during the deserialization process
    18.1 --- a/src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java	Tue Oct 12 13:34:59 2010 -0400
    18.2 +++ b/src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java	Mon Oct 18 11:25:28 2010 -0400
    18.3 @@ -338,11 +338,11 @@
    18.4              if (crs.rowDeleted()) {
    18.5                  // The row has been deleted.
    18.6                  if (conflict = (deleteOriginalRow(crs, this.crsResolve)) == true) {
    18.7 -                       status.add(rows, new Integer(SyncResolver.DELETE_ROW_CONFLICT));
    18.8 +                       status.add(rows, Integer.valueOf(SyncResolver.DELETE_ROW_CONFLICT));
    18.9                  } else {
   18.10                        // delete happened without any occurrence of conflicts
   18.11                        // so update status accordingly
   18.12 -                       status.add(rows, new Integer(SyncResolver.NO_ROW_CONFLICT));
   18.13 +                       status.add(rows, Integer.valueOf(SyncResolver.NO_ROW_CONFLICT));
   18.14                  }
   18.15  
   18.16             } else if (crs.rowInserted()) {
   18.17 @@ -350,20 +350,20 @@
   18.18  
   18.19                  pstmtIns = con.prepareStatement(insertCmd);
   18.20                  if ( (conflict = insertNewRow(crs, pstmtIns, this.crsResolve)) == true) {
   18.21 -                          status.add(rows, new Integer(SyncResolver.INSERT_ROW_CONFLICT));
   18.22 +                          status.add(rows, Integer.valueOf(SyncResolver.INSERT_ROW_CONFLICT));
   18.23                  } else {
   18.24                        // insert happened without any occurrence of conflicts
   18.25                        // so update status accordingly
   18.26 -                       status.add(rows, new Integer(SyncResolver.NO_ROW_CONFLICT));
   18.27 +                       status.add(rows, Integer.valueOf(SyncResolver.NO_ROW_CONFLICT));
   18.28                  }
   18.29              } else  if (crs.rowUpdated()) {
   18.30                    // The row has been updated.
   18.31                         if ( conflict = (updateOriginalRow(crs)) == true) {
   18.32 -                             status.add(rows, new Integer(SyncResolver.UPDATE_ROW_CONFLICT));
   18.33 +                             status.add(rows, Integer.valueOf(SyncResolver.UPDATE_ROW_CONFLICT));
   18.34                 } else {
   18.35                        // update happened without any occurrence of conflicts
   18.36                        // so update status accordingly
   18.37 -                      status.add(rows, new Integer(SyncResolver.NO_ROW_CONFLICT));
   18.38 +                      status.add(rows, Integer.valueOf(SyncResolver.NO_ROW_CONFLICT));
   18.39                 }
   18.40  
   18.41              } else {
   18.42 @@ -375,7 +375,7 @@
   18.43                  *  that is fine.
   18.44                  **/
   18.45                  int icolCount = crs.getMetaData().getColumnCount();
   18.46 -                status.add(rows, new Integer(SyncResolver.NO_ROW_CONFLICT));
   18.47 +                status.add(rows, Integer.valueOf(SyncResolver.NO_ROW_CONFLICT));
   18.48  
   18.49                  this.crsResolve.moveToInsertRow();
   18.50                  for(int cols=0;cols<iColCount;cols++) {
   18.51 @@ -398,7 +398,7 @@
   18.52        boolean boolConf = false;
   18.53        for (int j=1;j<status.size();j++){
   18.54            // ignore status for index = 0 which is set to null
   18.55 -          if(! ((status.get(j)).equals(new Integer(SyncResolver.NO_ROW_CONFLICT)))) {
   18.56 +          if(! ((status.get(j)).equals(Integer.valueOf(SyncResolver.NO_ROW_CONFLICT)))) {
   18.57                // there is at least one conflict which needs to be resolved
   18.58                boolConf = true;
   18.59               break;
   18.60 @@ -541,7 +541,7 @@
   18.61                  // how many fields need to be updated
   18.62                  int colsNotChanged = 0;
   18.63                  Vector cols = new Vector();
   18.64 -                String updateExec = new String(updateCmd);
   18.65 +                String updateExec = updateCmd;
   18.66                  Object orig;
   18.67                  Object curr;
   18.68                  Object rsval;
   18.69 @@ -652,7 +652,7 @@
   18.70                            updateExec += ", ";
   18.71                           }
   18.72                          updateExec += crs.getMetaData().getColumnName(i);
   18.73 -                        cols.add(new Integer(i));
   18.74 +                        cols.add(Integer.valueOf(i));
   18.75                          updateExec += " = ? ";
   18.76                          first = false;
   18.77  
   18.78 @@ -698,7 +698,7 @@
   18.79                                      updateExec += ", ";
   18.80                                   }
   18.81                                  updateExec += crs.getMetaData().getColumnName(i);
   18.82 -                                cols.add(new Integer(i));
   18.83 +                                cols.add(Integer.valueOf(i));
   18.84                                  updateExec += " = ? ";
   18.85                                  flag = false;
   18.86                               } else {
   18.87 @@ -1184,7 +1184,7 @@
   18.88         // trim all the leading and trailing whitespaces,
   18.89         // white spaces can never be catalog, schema or a table name.
   18.90  
   18.91 -        String cmd = new String();
   18.92 +        String cmd = "";
   18.93  
   18.94          catalog = catalog.trim();
   18.95          schema = schema.trim();
    19.1 --- a/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java	Tue Oct 12 13:34:59 2010 -0400
    19.2 +++ b/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java	Mon Oct 18 11:25:28 2010 -0400
    19.3 @@ -248,7 +248,7 @@
    19.4              String strProvider = strProviderInstance.substring(0, (caller.getSyncProvider()).toString().indexOf("@"));
    19.5  
    19.6              propString("sync-provider-name", strProvider);
    19.7 -            propString("sync-provider-vendor", "Sun Microsystems Inc.");
    19.8 +            propString("sync-provider-vendor", "Oracle Corporation");
    19.9              propString("sync-provider-version", "1.0");
   19.10              propInteger("sync-provider-grade", caller.getSyncProvider().getProviderGrade());
   19.11              propInteger("data-source-lock", caller.getSyncProvider().getDataSourceLock());
   19.12 @@ -387,7 +387,7 @@
   19.13                      if (caller.wasNull())
   19.14                          writeNull();
   19.15                      else
   19.16 -                        writeInteger(caller.getInt(idx));
   19.17 +                        writeInteger(i);
   19.18                      break;
   19.19                  case java.sql.Types.BIGINT:
   19.20                      long l = caller.getLong(idx);
   19.21 @@ -574,7 +574,7 @@
   19.22      }
   19.23  
   19.24      private void writeBoolean(boolean b) throws java.io.IOException {
   19.25 -        writer.write(new Boolean(b).toString());
   19.26 +        writer.write(Boolean.valueOf(b).toString());
   19.27      }
   19.28  
   19.29      private void writeFloat(float f) throws java.io.IOException {
   19.30 @@ -641,7 +641,7 @@
   19.31              return null;
   19.32          }
   19.33          char []charStr = s.toCharArray();
   19.34 -        String specialStr = new String();
   19.35 +        String specialStr = "";
   19.36  
   19.37          for(int i = 0; i < charStr.length; i++) {
   19.38              if(charStr[i] == '&') {
    20.1 --- a/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java	Tue Oct 12 13:34:59 2010 -0400
    20.2 +++ b/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java	Mon Oct 18 11:25:28 2010 -0400
    20.3 @@ -441,9 +441,9 @@
    20.4          updates = new Vector();
    20.5  
    20.6          // start out with the empty string
    20.7 -        columnValue = new String("");
    20.8 -        propertyValue = new String("");
    20.9 -        metaDataValue = new String("");
   20.10 +        columnValue = "";
   20.11 +        propertyValue = "";
   20.12 +        metaDataValue = "";
   20.13  
   20.14          nullVal = false;
   20.15          idx = 0;
   20.16 @@ -481,21 +481,21 @@
   20.17          items = properties.length;
   20.18  
   20.19          for (i=0;i<items;i++) {
   20.20 -            propMap.put(properties[i], new Integer(i));
   20.21 +            propMap.put(properties[i], Integer.valueOf(i));
   20.22          }
   20.23  
   20.24          colDefMap = new HashMap();
   20.25          items = colDef.length;
   20.26  
   20.27          for (i=0;i<items;i++) {
   20.28 -            colDefMap.put(colDef[i], new Integer(i));
   20.29 +            colDefMap.put(colDef[i], Integer.valueOf(i));
   20.30          }
   20.31  
   20.32          dataMap = new HashMap();
   20.33          items = data.length;
   20.34  
   20.35          for (i=0;i<items;i++) {
   20.36 -            dataMap.put(data[i], new Integer(i));
   20.37 +            dataMap.put(data[i], Integer.valueOf(i));
   20.38          }
   20.39  
   20.40          //Initialize connection map here
   20.41 @@ -686,7 +686,7 @@
   20.42              }
   20.43  
   20.44              // propertyValue need to be reset to an empty string
   20.45 -            propertyValue = new String("");
   20.46 +            propertyValue = "";
   20.47              setTag(-1);
   20.48              break;
   20.49          case METADATA:
   20.50 @@ -710,7 +710,7 @@
   20.51  
   20.52                  }
   20.53                  // metaDataValue needs to be reset to an empty string
   20.54 -                metaDataValue = new String("");
   20.55 +                metaDataValue = "";
   20.56              }
   20.57              setTag(-1);
   20.58              break;
   20.59 @@ -736,7 +736,7 @@
   20.60                          insertValue(tempStr);
   20.61                      }
   20.62                      // columnValue now need to be reset to the empty string
   20.63 -                    columnValue = new String("");
   20.64 +                    columnValue = "";
   20.65                  } catch (SQLException ex) {
   20.66                      throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errinsert").toString(), ex.getMessage()));
   20.67                  }
   20.68 @@ -981,7 +981,7 @@
   20.69  
   20.70      private boolean getBooleanValue(String s) {
   20.71  
   20.72 -        return new Boolean(s).booleanValue();
   20.73 +        return Boolean.valueOf(s).booleanValue();
   20.74      }
   20.75  
   20.76      private java.math.BigDecimal getBigDecimalValue(String s) {
   20.77 @@ -1316,7 +1316,7 @@
   20.78                **/
   20.79  
   20.80              tempUpdate = tempUpdate.concat(new String(ch,start,len));
   20.81 -            upd[0] = new Integer(idx);
   20.82 +            upd[0] = Integer.valueOf(idx);
   20.83              upd[1] = tempUpdate;
   20.84              //updates.add(upd);
   20.85  
    21.1 --- a/src/share/classes/com/sun/rowset/providers/RIOptimisticProvider.java	Tue Oct 12 13:34:59 2010 -0400
    21.2 +++ b/src/share/classes/com/sun/rowset/providers/RIOptimisticProvider.java	Mon Oct 18 11:25:28 2010 -0400
    21.3 @@ -93,14 +93,14 @@
    21.4      private CachedRowSetWriter writer;
    21.5  
    21.6      /**
    21.7 -     * The unique provider indentifier.
    21.8 +     * The unique provider identifier.
    21.9       */
   21.10      private String providerID = "com.sun.rowset.providers.RIOptimisticProvider";
   21.11  
   21.12      /**
   21.13       * The vendor name of this SyncProvider implementation
   21.14       */
   21.15 -    private String vendorName = "Sun Microsystems Inc.";
   21.16 +    private String vendorName = "Oracle Corporation";
   21.17  
   21.18      /**
   21.19       * The version number of this SyncProvider implementation
   21.20 @@ -236,8 +236,8 @@
   21.21      }
   21.22  
   21.23      /**
   21.24 -     * Returns the vendor name of the Reference Implemntation Optimistic
   21.25 -     * Syncchronication Provider
   21.26 +     * Returns the vendor name of the Reference Implementation Optimistic
   21.27 +     * Synchronization Provider
   21.28       *
   21.29       * @return the <code>String</code> detailing the vendor name of this
   21.30       *      SyncProvider
    22.1 --- a/src/share/classes/com/sun/rowset/providers/RIXMLProvider.java	Tue Oct 12 13:34:59 2010 -0400
    22.2 +++ b/src/share/classes/com/sun/rowset/providers/RIXMLProvider.java	Mon Oct 18 11:25:28 2010 -0400
    22.3 @@ -1,5 +1,5 @@
    22.4  /*
    22.5 - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
    22.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
    22.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    22.8   *
    22.9   * This code is free software; you can redistribute it and/or modify it
   22.10 @@ -85,7 +85,7 @@
   22.11      /**
   22.12       * The vendor name of this SyncProvider implementation.
   22.13       */
   22.14 -    private String vendorName = "Sun Microsystems Inc.";
   22.15 +    private String vendorName = "Oracle Corporation";
   22.16  
   22.17      /**
   22.18       * The version number of this SyncProvider implementation.
    23.1 --- a/src/share/classes/com/sun/servicetag/Installer.java	Tue Oct 12 13:34:59 2010 -0400
    23.2 +++ b/src/share/classes/com/sun/servicetag/Installer.java	Mon Oct 18 11:25:28 2010 -0400
    23.3 @@ -43,7 +43,8 @@
    23.4          "servicetag.dir.path";
    23.5      private static String SVCTAG_ENABLE_REGISTRATION =
    23.6          "servicetag.registration.enabled";
    23.7 -    private final static String SUN_VENDOR = "Sun Microsystems";
    23.8 +    private final static String ORACLE = "Oracle";
    23.9 +    private final static String SUN = "Sun Microsystems";
   23.10      private final static String REGISTRATION_XML = "registration.xml";
   23.11      private final static String SERVICE_TAG_FILE = "servicetag";
   23.12      private final static String REGISTRATION_HTML_NAME = "register";
   23.13 @@ -84,9 +85,10 @@
   23.14  
   23.15      // Implementation of ServiceTag.getJavaServiceTag(String) method
   23.16      static ServiceTag getJavaServiceTag(String source) throws IOException {
   23.17 -        if (!System.getProperty("java.vendor").startsWith(SUN_VENDOR)) {
   23.18 +        String vendor = System.getProperty("java.vendor", "");
   23.19 +        if (!vendor.startsWith(SUN) && !vendor.startsWith(ORACLE)) {
   23.20              // Products bundling this implementation may run on
   23.21 -            // Mac OS which is not a Sun JDK
   23.22 +            // Mac OS which is not a Sun/Oracle JDK
   23.23              return null;
   23.24          }
   23.25          boolean cleanup = false;
   23.26 @@ -365,7 +367,7 @@
   23.27                                        props.getProperty("servicetag.parent.name"),
   23.28                                        props.getProperty("servicetag.parent.urn"),
   23.29                                        getProductDefinedId(),
   23.30 -                                      SUN_VENDOR,
   23.31 +                                      System.getProperty("java.vendor"),
   23.32                                        System.getProperty("os.arch"),
   23.33                                        getZoneName(),
   23.34                                        svcTagSource);
    24.1 --- a/src/share/classes/com/sun/servicetag/RegistrationData.java	Tue Oct 12 13:34:59 2010 -0400
    24.2 +++ b/src/share/classes/com/sun/servicetag/RegistrationData.java	Mon Oct 18 11:25:28 2010 -0400
    24.3 @@ -80,12 +80,12 @@
    24.4   *       <tr>
    24.5   *          <td><tt>systemManufacturer</tt></td>
    24.6   *          <td>System manufacturer</td>
    24.7 - *          <td> e.g. Sun Microsystems</td>
    24.8 + *          <td> e.g. Oracle Corporation</td>
    24.9   *       </tr>
   24.10   *       <tr>
   24.11   *          <td><tt>cpuManufacturer</tt></td>
   24.12   *          <td>CPU manufacturer</td>
   24.13 - *          <td> e.g. Sun Microsystems</td>
   24.14 + *          <td> e.g. Oracle Corporation</td>
   24.15   *       </tr>
   24.16   *       <tr>
   24.17   *          <td><tt>serialNumber</tt></td>
    25.1 --- a/src/share/classes/com/sun/servicetag/Registry.java	Tue Oct 12 13:34:59 2010 -0400
    25.2 +++ b/src/share/classes/com/sun/servicetag/Registry.java	Mon Oct 18 11:25:28 2010 -0400
    25.3 @@ -90,7 +90,7 @@
    25.4                  stclient = getWindowsStClientFile();
    25.5              } else {
    25.6                  if (isVerbose()) {
    25.7 -                    System.out.println("Running on non-Sun JDK");
    25.8 +                    System.out.println("Running on unsupported platform");
    25.9                  }
   25.10              }
   25.11              initialized = true;
    26.1 --- a/src/share/classes/com/sun/servicetag/SolarisSystemEnvironment.java	Tue Oct 12 13:34:59 2010 -0400
    26.2 +++ b/src/share/classes/com/sun/servicetag/SolarisSystemEnvironment.java	Mon Oct 18 11:25:28 2010 -0400
    26.3 @@ -44,6 +44,7 @@
    26.4   * Solaris implementation of the SystemEnvironment class.
    26.5   */
    26.6  class SolarisSystemEnvironment extends SystemEnvironment {
    26.7 +    private static final String ORACLE = "Oracle Corporation";
    26.8      SolarisSystemEnvironment() {
    26.9          setHostId(getCommandOutput("/usr/bin/hostid"));
   26.10          setSystemModel(getCommandOutput("/usr/bin/uname", "-i"));
   26.11 @@ -59,7 +60,7 @@
   26.12      private String getSolarisCpuManufacturer() {
   26.13          // not fully accurate, this could be another manufacturer (fujitsu for example)
   26.14          if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) {
   26.15 -            return "Sun Microsystems, Inc";
   26.16 +            return ORACLE;
   26.17          }
   26.18  
   26.19          // if we're here, then we'll try smbios (type 4)
   26.20 @@ -73,7 +74,7 @@
   26.21      private String getSolarisSystemManufacturer() {
   26.22          // not fully accurate, this could be another manufacturer (fujitsu for example)
   26.23          if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) {
   26.24 -            return "Sun Microsystems, Inc";
   26.25 +            return ORACLE;
   26.26          }
   26.27  
   26.28          // if we're here, then we'll try smbios (type 1)
   26.29 @@ -117,7 +118,7 @@
   26.30      // ID    SIZE TYPE
   26.31      // 1     150  SMB_TYPE_SYSTEM (system information)
   26.32      //
   26.33 -    //   Manufacturer: Sun Microsystems
   26.34 +    //   Manufacturer: Oracle Corporation
   26.35      //   Product: Sun Fire X4600
   26.36      //   Version: To Be Filled By O.E.M.
   26.37      //   Serial Number: 00:14:4F:45:0C:2A
    27.1 --- a/src/share/classes/java/awt/Dialog.java	Tue Oct 12 13:34:59 2010 -0400
    27.2 +++ b/src/share/classes/java/awt/Dialog.java	Mon Oct 18 11:25:28 2010 -0400
    27.3 @@ -1068,7 +1068,7 @@
    27.4                      modalityPushed();
    27.5                      try {
    27.6                          EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
    27.7 -                        secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 5000);
    27.8 +                        secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 0);
    27.9                          if (!secondaryLoop.enter()) {
   27.10                              secondaryLoop = null;
   27.11                          }
    28.1 --- a/src/share/classes/java/awt/KeyboardFocusManager.java	Tue Oct 12 13:34:59 2010 -0400
    28.2 +++ b/src/share/classes/java/awt/KeyboardFocusManager.java	Mon Oct 18 11:25:28 2010 -0400
    28.3 @@ -142,6 +142,9 @@
    28.4                  public void removeLastFocusRequest(Component heavyweight) {
    28.5                      KeyboardFocusManager.removeLastFocusRequest(heavyweight);
    28.6                  }
    28.7 +                public void setMostRecentFocusOwner(Window window, Component component) {
    28.8 +                    KeyboardFocusManager.setMostRecentFocusOwner(window, component);
    28.9 +                }
   28.10              }
   28.11          );
   28.12      }
    29.1 --- a/src/share/classes/java/awt/event/ActionEvent.java	Tue Oct 12 13:34:59 2010 -0400
    29.2 +++ b/src/share/classes/java/awt/event/ActionEvent.java	Mon Oct 18 11:25:28 2010 -0400
    29.3 @@ -51,7 +51,7 @@
    29.4   * in the range from {@code ACTION_FIRST} to {@code ACTION_LAST}.
    29.5   *
    29.6   * @see ActionListener
    29.7 - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/eventmodel.html">Tutorial: Java 1.1 Event Model</a>
    29.8 + * @see <a href="http://java.sun.com/docs/books/tutorial/uiswing/events/actionlistener.html">Tutorial: How to Write an Action Listener</a>
    29.9   *
   29.10   * @author Carl Quinn
   29.11   * @since 1.1
    30.1 --- a/src/share/classes/java/awt/image/SampleModel.java	Tue Oct 12 13:34:59 2010 -0400
    30.2 +++ b/src/share/classes/java/awt/image/SampleModel.java	Mon Oct 18 11:25:28 2010 -0400
    30.3 @@ -937,14 +937,22 @@
    30.4                              int iArray[], DataBuffer data) {
    30.5          int pixels[];
    30.6          int Offset=0;
    30.7 +        int x1 = x + w;
    30.8 +        int y1 = y + h;
    30.9 +
   30.10 +        if (x < 0 || x1 < x || x1 > width ||
   30.11 +            y < 0 || y1 < y || y1 > height)
   30.12 +        {
   30.13 +            throw new ArrayIndexOutOfBoundsException("Invalid coordinates.");
   30.14 +        }
   30.15  
   30.16          if (iArray != null)
   30.17              pixels = iArray;
   30.18          else
   30.19              pixels = new int[w * h];
   30.20  
   30.21 -        for(int i=y; i<(h+y); i++) {
   30.22 -            for (int j=x; j<(w+x); j++) {
   30.23 +        for(int i=y; i<y1; i++) {
   30.24 +            for (int j=x; j<x1; j++) {
   30.25                  pixels[Offset++] = getSample(j, i, b, data);
   30.26              }
   30.27          }
   30.28 @@ -978,14 +986,22 @@
   30.29                                DataBuffer data) {
   30.30          float pixels[];
   30.31          int   Offset=0;
   30.32 +        int x1 = x + w;
   30.33 +        int y1 = y + h;
   30.34 +
   30.35 +        if (x < 0 || x1 < x || x1 > width ||
   30.36 +            y < 0 || y1 < y || y1 > height)
   30.37 +        {
   30.38 +            throw new ArrayIndexOutOfBoundsException("Invalid coordinates");
   30.39 +        }
   30.40  
   30.41          if (fArray != null)
   30.42              pixels = fArray;
   30.43          else
   30.44              pixels = new float[w * h];
   30.45  
   30.46 -        for (int i=y; i<(h+y); i++) {
   30.47 -            for (int j=x; j<(w+x); j++) {
   30.48 +        for (int i=y; i<y1; i++) {
   30.49 +            for (int j=x; j<x1; j++) {
   30.50                  pixels[Offset++] = getSampleFloat(j, i, b, data);
   30.51              }
   30.52          }
   30.53 @@ -1019,14 +1035,22 @@
   30.54                                 DataBuffer data) {
   30.55          double pixels[];
   30.56          int    Offset=0;
   30.57 +        int x1 = x + w;
   30.58 +        int y1 = y + h;
   30.59 +
   30.60 +        if (x < 0 || x1 < x || x1 > width ||
   30.61 +            y < 0 || y1 < y || y1 > height)
   30.62 +        {
   30.63 +            throw new ArrayIndexOutOfBoundsException("Invalid coordinates");
   30.64 +        }
   30.65  
   30.66          if (dArray != null)
   30.67              pixels = dArray;
   30.68          else
   30.69              pixels = new double[w * h];
   30.70  
   30.71 -        for (int i=y; i<(y+h); i++) {
   30.72 -            for (int j=x; j<(x+w); j++) {
   30.73 +        for (int i=y; i<y1; i++) {
   30.74 +            for (int j=x; j<x1; j++) {
   30.75                  pixels[Offset++] = getSampleDouble(j, i, b, data);
   30.76              }
   30.77          }
    31.1 --- a/src/share/classes/java/beans/EventSetDescriptor.java	Tue Oct 12 13:34:59 2010 -0400
    31.2 +++ b/src/share/classes/java/beans/EventSetDescriptor.java	Mon Oct 18 11:25:28 2010 -0400
    31.3 @@ -176,8 +176,9 @@
    31.4          setRemoveListenerMethod(getMethod(sourceClass, removeListenerMethodName, 1));
    31.5  
    31.6          // Be more forgiving of not finding the getListener method.
    31.7 -        if (getListenerMethodName != null) {
    31.8 -            setGetListenerMethod(Introspector.findInstanceMethod(sourceClass, getListenerMethodName));
    31.9 +        Method method = Introspector.findMethod(sourceClass, getListenerMethodName, 0);
   31.10 +        if (method != null) {
   31.11 +            setGetListenerMethod(method);
   31.12          }
   31.13      }
   31.14  
    32.1 --- a/src/share/classes/java/beans/IndexedPropertyDescriptor.java	Tue Oct 12 13:34:59 2010 -0400
    32.2 +++ b/src/share/classes/java/beans/IndexedPropertyDescriptor.java	Mon Oct 18 11:25:28 2010 -0400
    32.3 @@ -189,11 +189,13 @@
    32.4                      indexedReadMethodName = Introspector.GET_PREFIX + getBaseName();
    32.5                  }
    32.6              }
    32.7 -            indexedReadMethod = Introspector.findInstanceMethod(cls, indexedReadMethodName, int.class);
    32.8 +
    32.9 +            Class[] args = { int.class };
   32.10 +            indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args);
   32.11              if (indexedReadMethod == null) {
   32.12                  // no "is" method, so look for a "get" method.
   32.13                  indexedReadMethodName = Introspector.GET_PREFIX + getBaseName();
   32.14 -                indexedReadMethod = Introspector.findInstanceMethod(cls, indexedReadMethodName, int.class);
   32.15 +                indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args);
   32.16              }
   32.17              setIndexedReadMethod0(indexedReadMethod);
   32.18          }
   32.19 @@ -265,7 +267,9 @@
   32.20              if (indexedWriteMethodName == null) {
   32.21                  indexedWriteMethodName = Introspector.SET_PREFIX + getBaseName();
   32.22              }
   32.23 -            indexedWriteMethod = Introspector.findInstanceMethod(cls, indexedWriteMethodName, int.class, type);
   32.24 +
   32.25 +            Class[] args = (type == null) ? null : new Class[] { int.class, type };
   32.26 +            indexedWriteMethod = Introspector.findMethod(cls, indexedWriteMethodName, 2, args);
   32.27              if (indexedWriteMethod != null) {
   32.28                  if (!indexedWriteMethod.getReturnType().equals(void.class)) {
   32.29                      indexedWriteMethod = null;
    33.1 --- a/src/share/classes/java/beans/Introspector.java	Tue Oct 12 13:34:59 2010 -0400
    33.2 +++ b/src/share/classes/java/beans/Introspector.java	Mon Oct 18 11:25:28 2010 -0400
    33.3 @@ -28,7 +28,6 @@
    33.4  import com.sun.beans.WeakCache;
    33.5  import com.sun.beans.finder.BeanInfoFinder;
    33.6  import com.sun.beans.finder.ClassFinder;
    33.7 -import com.sun.beans.finder.MethodFinder;
    33.8  
    33.9  import java.lang.ref.Reference;
   33.10  import java.lang.ref.SoftReference;
   33.11 @@ -843,8 +842,8 @@
   33.12                  Method read = result.getReadMethod();
   33.13  
   33.14                  if (read == null && write != null) {
   33.15 -                    read = findInstanceMethod(result.getClass0(),
   33.16 -                                              GET_PREFIX + NameGenerator.capitalize(result.getName()));
   33.17 +                    read = findMethod(result.getClass0(),
   33.18 +                                      GET_PREFIX + NameGenerator.capitalize(result.getName()), 0);
   33.19                      if (read != null) {
   33.20                          try {
   33.21                              result.setReadMethod(read);
   33.22 @@ -854,9 +853,9 @@
   33.23                      }
   33.24                  }
   33.25                  if (write == null && read != null) {
   33.26 -                    write = findInstanceMethod(result.getClass0(),
   33.27 -                                               SET_PREFIX + NameGenerator.capitalize(result.getName()),
   33.28 -                                               FeatureDescriptor.getReturnType(result.getClass0(), read));
   33.29 +                    write = findMethod(result.getClass0(),
   33.30 +                                       SET_PREFIX + NameGenerator.capitalize(result.getName()), 1,
   33.31 +                                       new Class[] { FeatureDescriptor.getReturnType(result.getClass0(), read) });
   33.32                      if (write != null) {
   33.33                          try {
   33.34                              result.setWriteMethod(write);
   33.35 @@ -1280,27 +1279,90 @@
   33.36      // Package private support methods.
   33.37      //======================================================================
   33.38  
   33.39 -    static Method findMethod(Class<?> type, String name, int args) {
   33.40 -        for (Method method : type.getMethods()) {
   33.41 -            if (method.getName().equals(name) && (args == method.getParameterTypes().length)) {
   33.42 -                try {
   33.43 -                    return MethodFinder.findAccessibleMethod(method);
   33.44 +    /**
   33.45 +     * Internal support for finding a target methodName with a given
   33.46 +     * parameter list on a given class.
   33.47 +     */
   33.48 +    private static Method internalFindMethod(Class start, String methodName,
   33.49 +                                                 int argCount, Class args[]) {
   33.50 +        // For overriden methods we need to find the most derived version.
   33.51 +        // So we start with the given class and walk up the superclass chain.
   33.52 +
   33.53 +        Method method = null;
   33.54 +
   33.55 +        for (Class cl = start; cl != null; cl = cl.getSuperclass()) {
   33.56 +            Method methods[] = getPublicDeclaredMethods(cl);
   33.57 +            for (int i = 0; i < methods.length; i++) {
   33.58 +                method = methods[i];
   33.59 +                if (method == null) {
   33.60 +                    continue;
   33.61                  }
   33.62 -                catch (NoSuchMethodException exception) {
   33.63 -                    // continue search for a method with the specified count of parameters
   33.64 +
   33.65 +                // make sure method signature matches.
   33.66 +                Class params[] = FeatureDescriptor.getParameterTypes(start, method);
   33.67 +                if (method.getName().equals(methodName) &&
   33.68 +                    params.length == argCount) {
   33.69 +                    if (args != null) {
   33.70 +                        boolean different = false;
   33.71 +                        if (argCount > 0) {
   33.72 +                            for (int j = 0; j < argCount; j++) {
   33.73 +                                if (params[j] != args[j]) {
   33.74 +                                    different = true;
   33.75 +                                    continue;
   33.76 +                                }
   33.77 +                            }
   33.78 +                            if (different) {
   33.79 +                                continue;
   33.80 +                            }
   33.81 +                        }
   33.82 +                    }
   33.83 +                    return method;
   33.84                  }
   33.85              }
   33.86          }
   33.87 -        return null;
   33.88 +        method = null;
   33.89 +
   33.90 +        // Now check any inherited interfaces.  This is necessary both when
   33.91 +        // the argument class is itself an interface, and when the argument
   33.92 +        // class is an abstract class.
   33.93 +        Class ifcs[] = start.getInterfaces();
   33.94 +        for (int i = 0 ; i < ifcs.length; i++) {
   33.95 +            // Note: The original implementation had both methods calling
   33.96 +            // the 3 arg method. This is preserved but perhaps it should
   33.97 +            // pass the args array instead of null.
   33.98 +            method = internalFindMethod(ifcs[i], methodName, argCount, null);
   33.99 +            if (method != null) {
  33.100 +                break;
  33.101 +            }
  33.102 +        }
  33.103 +        return method;
  33.104      }
  33.105  
  33.106 -    static Method findInstanceMethod(Class<?> type, String name, Class<?>... args) {
  33.107 -        try {
  33.108 -            return MethodFinder.findInstanceMethod(type, name, args);
  33.109 -        }
  33.110 -        catch (NoSuchMethodException exception) {
  33.111 +    /**
  33.112 +     * Find a target methodName on a given class.
  33.113 +     */
  33.114 +    static Method findMethod(Class cls, String methodName, int argCount) {
  33.115 +        return findMethod(cls, methodName, argCount, null);
  33.116 +    }
  33.117 +
  33.118 +    /**
  33.119 +     * Find a target methodName with specific parameter list on a given class.
  33.120 +     * <p>
  33.121 +     * Used in the contructors of the EventSetDescriptor,
  33.122 +     * PropertyDescriptor and the IndexedPropertyDescriptor.
  33.123 +     * <p>
  33.124 +     * @param cls The Class object on which to retrieve the method.
  33.125 +     * @param methodName Name of the method.
  33.126 +     * @param argCount Number of arguments for the desired method.
  33.127 +     * @param args Array of argument types for the method.
  33.128 +     * @return the method or null if not found
  33.129 +     */
  33.130 +    static Method findMethod(Class cls, String methodName, int argCount,
  33.131 +                             Class args[]) {
  33.132 +        if (methodName == null) {
  33.133              return null;
  33.134          }
  33.135 +        return internalFindMethod(cls, methodName, argCount, args);
  33.136      }
  33.137  
  33.138      /**
    34.1 --- a/src/share/classes/java/beans/MethodDescriptor.java	Tue Oct 12 13:34:59 2010 -0400
    34.2 +++ b/src/share/classes/java/beans/MethodDescriptor.java	Mon Oct 18 11:25:28 2010 -0400
    34.3 @@ -90,13 +90,13 @@
    34.4                          // Find methods for up to 2 params. We are guessing here.
    34.5                          // This block should never execute unless the classloader
    34.6                          // that loaded the argument classes disappears.
    34.7 -                        method = Introspector.findMethod(cls, name, i);
    34.8 +                        method = Introspector.findMethod(cls, name, i, null);
    34.9                          if (method != null) {
   34.10                              break;
   34.11                          }
   34.12                      }
   34.13                  } else {
   34.14 -                    method = Statement.getMethod(cls, name, params);
   34.15 +                    method = Introspector.findMethod(cls, name, params.length, params);
   34.16                  }
   34.17                  setMethod(method);
   34.18              }
    35.1 --- a/src/share/classes/java/beans/PropertyDescriptor.java	Tue Oct 12 13:34:59 2010 -0400
    35.2 +++ b/src/share/classes/java/beans/PropertyDescriptor.java	Mon Oct 18 11:25:28 2010 -0400
    35.3 @@ -112,7 +112,8 @@
    35.4          // If this class or one of its base classes allow PropertyChangeListener,
    35.5          // then we assume that any properties we discover are "bound".
    35.6          // See Introspector.getTargetPropertyInfo() method.
    35.7 -        this.bound = null != Introspector.findInstanceMethod(beanClass, "addPropertyChangeListener", PropertyChangeListener.class);
    35.8 +        Class[] args = { PropertyChangeListener.class };
    35.9 +        this.bound = null != Introspector.findMethod(beanClass, "addPropertyChangeListener", args.length, args);
   35.10      }
   35.11  
   35.12      /**
   35.13 @@ -223,10 +224,10 @@
   35.14              // property type is.  For booleans, there can be "is" and "get"
   35.15              // methods.  If an "is" method exists, this is the official
   35.16              // reader method so look for this one first.
   35.17 -            readMethod = Introspector.findInstanceMethod(cls, readMethodName);
   35.18 +            readMethod = Introspector.findMethod(cls, readMethodName, 0);
   35.19              if (readMethod == null) {
   35.20                  readMethodName = Introspector.GET_PREFIX + getBaseName();
   35.21 -                readMethod = Introspector.findInstanceMethod(cls, readMethodName);
   35.22 +                readMethod = Introspector.findMethod(cls, readMethodName, 0);
   35.23              }
   35.24              try {
   35.25                  setReadMethod(readMethod);
   35.26 @@ -291,7 +292,8 @@
   35.27                  writeMethodName = Introspector.SET_PREFIX + getBaseName();
   35.28              }
   35.29  
   35.30 -            writeMethod = Introspector.findInstanceMethod(cls, writeMethodName, type);
   35.31 +            Class[] args = (type == null) ? null : new Class[] { type };
   35.32 +            writeMethod = Introspector.findMethod(cls, writeMethodName, 1, args);
   35.33              if (writeMethod != null) {
   35.34                  if (!writeMethod.getReturnType().equals(void.class)) {
   35.35                      writeMethod = null;
    36.1 --- a/src/share/classes/java/lang/System.java	Tue Oct 12 13:34:59 2010 -0400
    36.2 +++ b/src/share/classes/java/lang/System.java	Mon Oct 18 11:25:28 2010 -0400
    36.3 @@ -1101,22 +1101,12 @@
    36.4          lineSeparator = props.getProperty("line.separator");
    36.5          sun.misc.Version.init();
    36.6  
    36.7 -        // Workaround until DownloadManager initialization is revisited.
    36.8 -        // Make JavaLangAccess available early enough for internal
    36.9 -        // Shutdown hooks to be registered
   36.10 -        setJavaLangAccess();
   36.11 -
   36.12          // Gets and removes system properties that configure the Integer
   36.13          // cache used to support the object identity semantics of autoboxing.
   36.14          // At this time, the size of the cache may be controlled by the
   36.15          // vm option -XX:AutoBoxCacheMax=<size>.
   36.16          Integer.getAndRemoveCacheProperties();
   36.17  
   36.18 -        // Load the zip library now in order to keep java.util.zip.ZipFile
   36.19 -        // from trying to use itself to load this library later.
   36.20 -        loadLibrary("zip");
   36.21 -
   36.22 -
   36.23          FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
   36.24          FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
   36.25          FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
   36.26 @@ -1124,6 +1114,10 @@
   36.27          setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
   36.28          setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true));
   36.29  
   36.30 +        // Load the zip library now in order to keep java.util.zip.ZipFile
   36.31 +        // from trying to use itself to load this library later.
   36.32 +        loadLibrary("zip");
   36.33 +
   36.34          // Setup Java signal handlers for HUP, TERM, and INT (where available).
   36.35          Terminator.setup();
   36.36  
   36.37 @@ -1153,6 +1147,9 @@
   36.38          // way as other threads; we must do it ourselves here.
   36.39          Thread current = Thread.currentThread();
   36.40          current.getThreadGroup().add(current);
   36.41 +
   36.42 +        // register shared secrets
   36.43 +        setJavaLangAccess();
   36.44      }
   36.45  
   36.46      private static void setJavaLangAccess() {
    37.1 --- a/src/share/classes/java/net/InetAddress.java	Tue Oct 12 13:34:59 2010 -0400
    37.2 +++ b/src/share/classes/java/net/InetAddress.java	Mon Oct 18 11:25:28 2010 -0400
    37.3 @@ -677,19 +677,20 @@
    37.4  
    37.5      static InetAddressImpl  impl;
    37.6  
    37.7 -    private static HashMap          lookupTable = new HashMap();
    37.8 +    private static HashMap<String, InetAddress[]> lookupTable
    37.9 +        = new HashMap<String, InetAddress[]>();
   37.10  
   37.11      /**
   37.12       * Represents a cache entry
   37.13       */
   37.14      static final class CacheEntry {
   37.15  
   37.16 -        CacheEntry(Object address, long expiration) {
   37.17 -            this.address = address;
   37.18 +        CacheEntry(InetAddress[] addresses, long expiration) {
   37.19 +            this.addresses = addresses;
   37.20              this.expiration = expiration;
   37.21          }
   37.22  
   37.23 -        Object address;
   37.24 +        InetAddress[] addresses;
   37.25          long expiration;
   37.26      }
   37.27  
   37.28 @@ -698,7 +699,7 @@
   37.29       * at creation time.
   37.30       */
   37.31      static final class Cache {
   37.32 -        private LinkedHashMap cache;
   37.33 +        private LinkedHashMap<String, CacheEntry> cache;
   37.34          private Type type;
   37.35  
   37.36          enum Type {Positive, Negative};
   37.37 @@ -708,7 +709,7 @@
   37.38           */
   37.39          public Cache(Type type) {
   37.40              this.type = type;
   37.41 -            cache = new LinkedHashMap();
   37.42 +            cache = new LinkedHashMap<String, CacheEntry>();
   37.43          }
   37.44  
   37.45          private int getPolicy() {
   37.46 @@ -724,7 +725,7 @@
   37.47           * entry then for this host then the entry will be
   37.48           * replaced.
   37.49           */
   37.50 -        public Cache put(String host, Object address) {
   37.51 +        public Cache put(String host, InetAddress[] addresses) {
   37.52              int policy = getPolicy();
   37.53              if (policy == InetAddressCachePolicy.NEVER) {
   37.54                  return this;
   37.55 @@ -736,12 +737,10 @@
   37.56  
   37.57                  // As we iterate in insertion order we can
   37.58                  // terminate when a non-expired entry is found.
   37.59 -                LinkedList expired = new LinkedList();
   37.60 -                Iterator i = cache.keySet().iterator();
   37.61 +                LinkedList<String> expired = new LinkedList<String>();
   37.62                  long now = System.currentTimeMillis();
   37.63 -                while (i.hasNext()) {
   37.64 -                    String key = (String)i.next();
   37.65 -                    CacheEntry entry = (CacheEntry)cache.get(key);
   37.66 +                for (String key : cache.keySet()) {
   37.67 +                    CacheEntry entry = cache.get(key);
   37.68  
   37.69                      if (entry.expiration >= 0 && entry.expiration < now) {
   37.70                          expired.add(key);
   37.71 @@ -750,9 +749,8 @@
   37.72                      }
   37.73                  }
   37.74  
   37.75 -                i = expired.iterator();
   37.76 -                while (i.hasNext()) {
   37.77 -                    cache.remove(i.next());
   37.78 +                for (String key : expired) {
   37.79 +                    cache.remove(key);
   37.80                  }
   37.81              }
   37.82  
   37.83 @@ -766,7 +764,7 @@
   37.84              } else {
   37.85                  expiration = System.currentTimeMillis() + (policy * 1000);
   37.86              }
   37.87 -            CacheEntry entry = new CacheEntry(address, expiration);
   37.88 +            CacheEntry entry = new CacheEntry(addresses, expiration);
   37.89              cache.put(host, entry);
   37.90              return this;
   37.91          }
   37.92 @@ -780,7 +778,7 @@
   37.93              if (policy == InetAddressCachePolicy.NEVER) {
   37.94                  return null;
   37.95              }
   37.96 -            CacheEntry entry = (CacheEntry)cache.get(host);
   37.97 +            CacheEntry entry = cache.get(host);
   37.98  
   37.99              // check if entry has expired
  37.100              if (entry != null && policy != InetAddressCachePolicy.FOREVER) {
  37.101 @@ -814,42 +812,41 @@
  37.102      }
  37.103  
  37.104      /*
  37.105 -     * Cache the given hostname and address.
  37.106 +     * Cache the given hostname and addresses.
  37.107       */
  37.108 -    private static void cacheAddress(String hostname, Object address,
  37.109 -                                     boolean success) {
  37.110 +    private static void cacheAddresses(String hostname,
  37.111 +                                       InetAddress[] addresses,
  37.112 +                                       boolean success) {
  37.113          hostname = hostname.toLowerCase();
  37.114          synchronized (addressCache) {
  37.115              cacheInitIfNeeded();
  37.116              if (success) {
  37.117 -                addressCache.put(hostname, address);
  37.118 +                addressCache.put(hostname, addresses);
  37.119              } else {
  37.120 -                negativeCache.put(hostname, address);
  37.121 +                negativeCache.put(hostname, addresses);
  37.122              }
  37.123          }
  37.124      }
  37.125  
  37.126      /*
  37.127       * Lookup hostname in cache (positive & negative cache). If
  37.128 -     * found return address, null if not found.
  37.129 +     * found return addresses, null if not found.
  37.130       */
  37.131 -    private static Object getCachedAddress(String hostname) {
  37.132 +    private static InetAddress[] getCachedAddresses(String hostname) {
  37.133          hostname = hostname.toLowerCase();
  37.134  
  37.135          // search both positive & negative caches
  37.136  
  37.137          synchronized (addressCache) {
  37.138 -            CacheEntry entry;
  37.139 -
  37.140              cacheInitIfNeeded();
  37.141  
  37.142 -            entry = addressCache.get(hostname);
  37.143 +            CacheEntry entry = addressCache.get(hostname);
  37.144              if (entry == null) {
  37.145                  entry = negativeCache.get(hostname);
  37.146              }
  37.147  
  37.148              if (entry != null) {
  37.149 -                return entry.address;
  37.150 +                return entry.addresses;
  37.151              }
  37.152          }
  37.153  
  37.154 @@ -911,7 +908,7 @@
  37.155  
  37.156      static {
  37.157          // create the impl
  37.158 -        impl = (new InetAddressImplFactory()).create();
  37.159 +        impl = InetAddressImplFactory.create();
  37.160  
  37.161          // get name service if provided and requested
  37.162          String provider = null;;
  37.163 @@ -931,7 +928,7 @@
  37.164          }
  37.165  
  37.166          // if not designate any name services provider,
  37.167 -        // creat a default one
  37.168 +        // create a default one
  37.169          if (nameServices.size() == 0) {
  37.170              NameService ns = createNSProvider("default");
  37.171              nameServices.add(ns);
  37.172 @@ -939,7 +936,7 @@
  37.173      }
  37.174  
  37.175      /**
  37.176 -     * Create an InetAddress based on the provided host name and IP address
  37.177 +     * Creates an InetAddress based on the provided host name and IP address.
  37.178       * No name service is checked for the validity of the address.
  37.179       *
  37.180       * <p> The host name can either be a machine name, such as
  37.181 @@ -1067,13 +1064,13 @@
  37.182  
  37.183          boolean ipv6Expected = false;
  37.184          if (host.charAt(0) == '[') {
  37.185 -            // This is supposed to be an IPv6 litteral
  37.186 +            // This is supposed to be an IPv6 literal
  37.187              if (host.length() > 2 && host.charAt(host.length()-1) == ']') {
  37.188                  host = host.substring(1, host.length() -1);
  37.189                  ipv6Expected = true;
  37.190              } else {
  37.191                  // This was supposed to be a IPv6 address, but it's not!
  37.192 -                throw new UnknownHostException(host);
  37.193 +                throw new UnknownHostException(host + ": invalid IPv6 address");
  37.194              }
  37.195          }
  37.196  
  37.197 @@ -1180,8 +1177,6 @@
  37.198          throws UnknownHostException  {
  37.199          /* If it gets here it is presumed to be a hostname */
  37.200          /* Cache.get can return: null, unknownAddress, or InetAddress[] */
  37.201 -        Object obj = null;
  37.202 -        Object objcopy = null;
  37.203  
  37.204          /* make sure the connection to the host is allowed, before we
  37.205           * give out a hostname
  37.206 @@ -1193,26 +1188,23 @@
  37.207              }
  37.208          }
  37.209  
  37.210 -        obj = getCachedAddress(host);
  37.211 +        InetAddress[] addresses = getCachedAddresses(host);
  37.212  
  37.213          /* If no entry in cache, then do the host lookup */
  37.214 -        if (obj == null) {
  37.215 -            obj = getAddressFromNameService(host);
  37.216 +        if (addresses == null) {
  37.217 +            addresses = getAddressesFromNameService(host);
  37.218          }
  37.219  
  37.220 -        if (obj == unknown_array)
  37.221 +        if (addresses == unknown_array)
  37.222              throw new UnknownHostException(host);
  37.223  
  37.224 -        /* Make a copy of the InetAddress array */
  37.225 -        objcopy = ((InetAddress [])obj).clone();
  37.226 -
  37.227 -        return (InetAddress [])objcopy;
  37.228 +        return addresses.clone();
  37.229      }
  37.230  
  37.231 -    private static Object getAddressFromNameService(String host)
  37.232 +    private static InetAddress[] getAddressesFromNameService(String host)
  37.233          throws UnknownHostException
  37.234      {
  37.235 -        Object obj = null;
  37.236 +        InetAddress[] addresses = null;
  37.237          boolean success = false;
  37.238          UnknownHostException ex = null;
  37.239  
  37.240 @@ -1226,16 +1218,16 @@
  37.241          //    would be blocked until the host is removed
  37.242          //    from the lookupTable. Then this thread
  37.243          //    should try to look up the addressCache.
  37.244 -        //     i) if it found the address in the
  37.245 +        //     i) if it found the addresses in the
  37.246          //        addressCache, checkLookupTable()  would
  37.247 -        //        return the address.
  37.248 -        //     ii) if it didn't find the address in the
  37.249 +        //        return the addresses.
  37.250 +        //     ii) if it didn't find the addresses in the
  37.251          //         addressCache for any reason,
  37.252          //         it should add the host in the
  37.253          //         lookupTable and return null so the
  37.254          //         following code would do  a lookup itself.
  37.255 -        if ((obj = checkLookupTable(host)) == null) {
  37.256 -            // This is the first thread which looks up the address
  37.257 +        if ((addresses = checkLookupTable(host)) == null) {
  37.258 +            // This is the first thread which looks up the addresses
  37.259              // this host or the cache entry for this host has been
  37.260              // expired so this thread should do the lookup.
  37.261              for (NameService nameService : nameServices) {
  37.262 @@ -1246,26 +1238,26 @@
  37.263                       * allocating space when the lookup fails.
  37.264                       */
  37.265  
  37.266 -                    obj = nameService.lookupAllHostAddr(host);
  37.267 +                    addresses = nameService.lookupAllHostAddr(host);
  37.268                      success = true;
  37.269                      break;
  37.270                  } catch (UnknownHostException uhe) {
  37.271                      if (host.equalsIgnoreCase("localhost")) {
  37.272                          InetAddress[] local = new InetAddress[] { impl.loopbackAddress() };
  37.273 -                        obj = local;
  37.274 +                        addresses = local;
  37.275                          success = true;
  37.276                          break;
  37.277                      }
  37.278                      else {
  37.279 -                        obj  = unknown_array;
  37.280 +                        addresses = unknown_array;
  37.281                          success = false;
  37.282                          ex = uhe;
  37.283                      }
  37.284                  }
  37.285              }
  37.286  
  37.287 -            // Cache the address.
  37.288 -            cacheAddress(host, obj, success);
  37.289 +            // Cache the addresses.
  37.290 +            cacheAddresses(host, addresses, success);
  37.291              // Delete the host from the lookupTable, and
  37.292              // notify all threads waiting for the monitor
  37.293              // for lookupTable.
  37.294 @@ -1274,13 +1266,13 @@
  37.295                  throw ex;
  37.296          }
  37.297  
  37.298 -        return obj;
  37.299 +        return addresses;
  37.300      }
  37.301  
  37.302  
  37.303 -    private static Object checkLookupTable(String host) {
  37.304 -        // make sure obj  is null.
  37.305 -        Object obj = null;
  37.306 +    private static InetAddress[] checkLookupTable(String host) {
  37.307 +        // make sure addresses is null.
  37.308 +        InetAddress[] addresses = null;
  37.309  
  37.310          synchronized (lookupTable) {
  37.311              // If the host isn't in the lookupTable, add it in the
  37.312 @@ -1288,11 +1280,11 @@
  37.313              // the lookup.
  37.314              if (lookupTable.containsKey(host) == false) {
  37.315                  lookupTable.put(host, null);
  37.316 -                return obj;
  37.317 +                return addresses;
  37.318              }
  37.319  
  37.320              // If the host is in the lookupTable, it means that another
  37.321 -            // thread is trying to look up the address of this host.
  37.322 +            // thread is trying to look up the addresses of this host.
  37.323              // This thread should wait.
  37.324              while (lookupTable.containsKey(host)) {
  37.325                  try {
  37.326 @@ -1302,18 +1294,18 @@
  37.327              }
  37.328          }
  37.329  
  37.330 -        // The other thread has finished looking up the address of
  37.331 -        // the host. This thread should retry to get the address
  37.332 -        // from the addressCache. If it doesn't get the address from
  37.333 -        // the cache,  it will try to look up the address itself.
  37.334 -        obj = getCachedAddress(host);
  37.335 -        if (obj == null) {
  37.336 +        // The other thread has finished looking up the addresses of
  37.337 +        // the host. This thread should retry to get the addresses
  37.338 +        // from the addressCache. If it doesn't get the addresses from
  37.339 +        // the cache, it will try to look up the addresses itself.
  37.340 +        addresses = getCachedAddresses(host);
  37.341 +        if (addresses == null) {
  37.342              synchronized (lookupTable) {
  37.343                  lookupTable.put(host, null);
  37.344              }
  37.345          }
  37.346  
  37.347 -        return obj;
  37.348 +        return addresses;
  37.349      }
  37.350  
  37.351      private static void updateLookupTable(String host) {
  37.352 @@ -1396,15 +1388,20 @@
  37.353                          cachedLocalHost = null;
  37.354                  }
  37.355  
  37.356 -                // we are calling getAddressFromNameService directly
  37.357 +                // we are calling getAddressesFromNameService directly
  37.358                  // to avoid getting localHost from cache
  37.359                  if (ret == null) {
  37.360                      InetAddress[] localAddrs;
  37.361                      try {
  37.362                          localAddrs =
  37.363 -                            (InetAddress[]) InetAddress.getAddressFromNameService(local);
  37.364 +                            InetAddress.getAddressesFromNameService(local);
  37.365                      } catch (UnknownHostException uhe) {
  37.366 -                        throw new UnknownHostException(local + ": " + uhe.getMessage());
  37.367 +                        // Rethrow with a more informative error message.
  37.368 +                        UnknownHostException uhe2 =
  37.369 +                            new UnknownHostException(local + ": " +
  37.370 +                                                     uhe.getMessage());
  37.371 +                        uhe2.initCause(uhe);
  37.372 +                        throw uhe2;
  37.373                      }
  37.374                      cachedLocalHost = localAddrs[0];
  37.375                      cacheTime = now;
  37.376 @@ -1434,8 +1431,8 @@
  37.377      /*
  37.378       * Load and instantiate an underlying impl class
  37.379       */
  37.380 -    static Object loadImpl(String implName) {
  37.381 -        Object impl;
  37.382 +    static InetAddressImpl loadImpl(String implName) {
  37.383 +        Object impl = null;
  37.384  
  37.385          /*
  37.386           * Property "impl.prefix" will be prepended to the classname
  37.387 @@ -1446,7 +1443,6 @@
  37.388           */
  37.389          String prefix = AccessController.doPrivileged(
  37.390                        new GetPropertyAction("impl.prefix", ""));
  37.391 -        impl = null;
  37.392          try {
  37.393              impl = Class.forName("java.net." + prefix + implName).newInstance();
  37.394          } catch (ClassNotFoundException e) {
  37.395 @@ -1471,7 +1467,7 @@
  37.396              }
  37.397          }
  37.398  
  37.399 -        return impl;
  37.400 +        return (InetAddressImpl) impl;
  37.401      }
  37.402  
  37.403      private void readObjectNoData (ObjectInputStream s) throws
  37.404 @@ -1498,13 +1494,8 @@
  37.405  class InetAddressImplFactory {
  37.406  
  37.407      static InetAddressImpl create() {
  37.408 -        Object o;
  37.409 -        if (isIPv6Supported()) {
  37.410 -            o = InetAddress.loadImpl("Inet6AddressImpl");
  37.411 -        } else {
  37.412 -            o = InetAddress.loadImpl("Inet4AddressImpl");
  37.413 -        }
  37.414 -        return (InetAddressImpl)o;
  37.415 +        return InetAddress.loadImpl(isIPv6Supported() ?
  37.416 +                                    "Inet6AddressImpl" : "Inet4AddressImpl");
  37.417      }
  37.418  
  37.419      static native boolean isIPv6Supported();
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/src/share/classes/java/nio/file/FileSystemLoopException.java	Mon Oct 18 11:25:28 2010 -0400
    38.3 @@ -0,0 +1,50 @@
    38.4 +/*
    38.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
    38.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    38.7 + *
    38.8 + * This code is free software; you can redistribute it and/or modify it
    38.9 + * under the terms of the GNU General Public License version 2 only, as
   38.10 + * published by the Free Software Foundation.  Oracle designates this
   38.11 + * particular file as subject to the "Classpath" exception as provided
   38.12 + * by Oracle in the LICENSE file that accompanied this code.
   38.13 + *
   38.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   38.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   38.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   38.17 + * version 2 for more details (a copy is included in the LICENSE file that
   38.18 + * accompanied this code).
   38.19 + *
   38.20 + * You should have received a copy of the GNU General Public License version
   38.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   38.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   38.23 + *
   38.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   38.25 + * or visit www.oracle.com if you need additional information or have any
   38.26 + * questions.
   38.27 + */
   38.28 +
   38.29 +package java.nio.file;
   38.30 +
   38.31 +/**
   38.32 + * Checked exception thrown when a file system loop, or cycle, is encountered.
   38.33 + *
   38.34 + * @since 1.7
   38.35 + * @see Files#walkFileTree
   38.36 + */
   38.37 +
   38.38 +public class FileSystemLoopException
   38.39 +    extends FileSystemException
   38.40 +{
   38.41 +    private static final long serialVersionUID = 4843039591949217617L;
   38.42 +
   38.43 +    /**
   38.44 +     * Constructs an instance of this class.
   38.45 +     *
   38.46 +     * @param   file
   38.47 +     *          a string identifying the file causing the cycle or {@code null} if
   38.48 +     *          not known
   38.49 +     */
   38.50 +    public FileSystemLoopException(String file) {
   38.51 +        super(file);
   38.52 +    }
   38.53 +}
    39.1 --- a/src/share/classes/java/nio/file/FileTreeWalker.java	Tue Oct 12 13:34:59 2010 -0400
    39.2 +++ b/src/share/classes/java/nio/file/FileTreeWalker.java	Mon Oct 18 11:25:28 2010 -0400
    39.3 @@ -38,7 +38,6 @@
    39.4  
    39.5  class FileTreeWalker {
    39.6      private final boolean followLinks;
    39.7 -    private final boolean detectCycles;
    39.8      private final LinkOption[] linkOptions;
    39.9      private final FileVisitor<? super Path> visitor;
   39.10      private final int maxDepth;
   39.11 @@ -48,17 +47,15 @@
   39.12                     int maxDepth)
   39.13      {
   39.14          boolean fl = false;
   39.15 -        boolean dc = false;
   39.16          for (FileVisitOption option: options) {
   39.17 +            // will throw NPE if options contains null
   39.18              switch (option) {
   39.19 -                case FOLLOW_LINKS  : fl = true; break;
   39.20 -                case DETECT_CYCLES : dc = true; break;
   39.21 +                case FOLLOW_LINKS : fl = true; break;
   39.22                  default:
   39.23                      throw new AssertionError("Should not get here");
   39.24              }
   39.25          }
   39.26          this.followLinks = fl;
   39.27 -        this.detectCycles = fl | dc;
   39.28          this.linkOptions = (fl) ? new LinkOption[0] :
   39.29              new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
   39.30          this.visitor = visitor;
   39.31 @@ -68,13 +65,11 @@
   39.32      /**
   39.33       * Walk file tree starting at the given file
   39.34       */
   39.35 -    void walk(Path start) {
   39.36 +    void walk(Path start) throws IOException {
   39.37          FileVisitResult result = walk(start,
   39.38                                        0,
   39.39                                        new ArrayList<AncestorDirectory>());
   39.40 -        if (result == null) {
   39.41 -            throw new NullPointerException("Visitor returned 'null'");
   39.42 -        }
   39.43 +        Objects.nonNull(result, "FileVisitor returned null");
   39.44      }
   39.45  
   39.46      /**
   39.47 @@ -88,11 +83,8 @@
   39.48      private FileVisitResult walk(Path file,
   39.49                                   int depth,
   39.50                                   List<AncestorDirectory> ancestors)
   39.51 +        throws IOException
   39.52      {
   39.53 -        // depth check
   39.54 -        if (depth > maxDepth)
   39.55 -            return FileVisitResult.CONTINUE;
   39.56 -
   39.57          // if attributes are cached then use them if possible
   39.58          BasicFileAttributes attrs = null;
   39.59          if ((depth > 0) &&
   39.60 @@ -137,13 +129,13 @@
   39.61              return visitor.visitFileFailed(file, exc);
   39.62          }
   39.63  
   39.64 -        // file is not a directory so invoke visitFile method
   39.65 -        if (!attrs.isDirectory()) {
   39.66 +        // at maximum depth or file is not a directory
   39.67 +        if (depth >= maxDepth || !attrs.isDirectory()) {
   39.68              return visitor.visitFile(file, attrs);
   39.69          }
   39.70  
   39.71 -        // check for cycles
   39.72 -        if (detectCycles) {
   39.73 +        // check for cycles when following links
   39.74 +        if (followLinks) {
   39.75              Object key = attrs.fileKey();
   39.76  
   39.77              // if this directory and ancestor has a file key then we compare
   39.78 @@ -153,19 +145,23 @@
   39.79                  if (key != null && ancestorKey != null) {
   39.80                      if (key.equals(ancestorKey)) {
   39.81                          // cycle detected
   39.82 -                        return visitor.visitFile(file, attrs);
   39.83 +                        return visitor.visitFileFailed(file,
   39.84 +                            new FileSystemLoopException(file.toString()));
   39.85                      }
   39.86                  } else {
   39.87 +                    boolean isSameFile = false;
   39.88                      try {
   39.89 -                        if (file.isSameFile(ancestor.file())) {
   39.90 -                            // cycle detected
   39.91 -                            return visitor.visitFile(file, attrs);
   39.92 -                        }
   39.93 +                        isSameFile = file.isSameFile(ancestor.file());
   39.94                      } catch (IOException x) {
   39.95                          // ignore
   39.96                      } catch (SecurityException x) {
   39.97                          // ignore
   39.98                      }
   39.99 +                    if (isSameFile) {
  39.100 +                        // cycle detected
  39.101 +                        return visitor.visitFileFailed(file,
  39.102 +                            new FileSystemLoopException(file.toString()));
  39.103 +                    }
  39.104                  }
  39.105              }
  39.106  
  39.107 @@ -181,7 +177,7 @@
  39.108              try {
  39.109                  stream = file.newDirectoryStream();
  39.110              } catch (IOException x) {
  39.111 -                return visitor.preVisitDirectoryFailed(file, x);
  39.112 +                return visitor.visitFileFailed(file, x);
  39.113              } catch (SecurityException x) {
  39.114                  // ignore, as per spec
  39.115                  return FileVisitResult.CONTINUE;
  39.116 @@ -192,20 +188,14 @@
  39.117  
  39.118              // invoke preVisitDirectory and then visit each entry
  39.119              try {
  39.120 -                result = visitor.preVisitDirectory(file);
  39.121 +                result = visitor.preVisitDirectory(file, attrs);
  39.122                  if (result != FileVisitResult.CONTINUE) {
  39.123                      return result;
  39.124                  }
  39.125  
  39.126 -                // if an I/O occurs during iteration then a CME is thrown. We
  39.127 -                // need to distinguish this from a CME thrown by the visitor.
  39.128 -                boolean inAction = false;
  39.129 -
  39.130                  try {
  39.131                      for (Path entry: stream) {
  39.132 -                        inAction = true;
  39.133                          result = walk(entry, depth+1, ancestors);
  39.134 -                        inAction = false;
  39.135  
  39.136                          // returning null will cause NPE to be thrown
  39.137                          if (result == null || result == FileVisitResult.TERMINATE)
  39.138 @@ -215,17 +205,9 @@
  39.139                          if (result == FileVisitResult.SKIP_SIBLINGS)
  39.140                              break;
  39.141                      }
  39.142 -                } catch (ConcurrentModificationException x) {
  39.143 -                    // if CME thrown because the iteration failed then remember
  39.144 -                    // the IOException so that it is notified to postVisitDirectory
  39.145 -                    if (!inAction) {
  39.146 -                        // iteration failed
  39.147 -                        Throwable t = x.getCause();
  39.148 -                        if (t instanceof IOException)
  39.149 -                            ioe = (IOException)t;
  39.150 -                    }
  39.151 -                    if (ioe == null)
  39.152 -                        throw x;
  39.153 +                } catch (DirectoryIteratorException e) {
  39.154 +                    // IOException will be notified to postVisitDirectory
  39.155 +                    ioe = e.getCause();
  39.156                  }
  39.157              } finally {
  39.158                  try {
  39.159 @@ -238,7 +220,7 @@
  39.160  
  39.161          } finally {
  39.162              // remove key from trail if doing cycle detection
  39.163 -            if (detectCycles) {
  39.164 +            if (followLinks) {
  39.165                  ancestors.remove(ancestors.size()-1);
  39.166              }
  39.167          }
    40.1 --- a/src/share/classes/java/nio/file/FileVisitOption.java	Tue Oct 12 13:34:59 2010 -0400
    40.2 +++ b/src/share/classes/java/nio/file/FileVisitOption.java	Mon Oct 18 11:25:28 2010 -0400
    40.3 @@ -37,9 +37,5 @@
    40.4      /**
    40.5       * Follow symbolic links.
    40.6       */
    40.7 -    FOLLOW_LINKS,
    40.8 -    /**
    40.9 -     * Detect cycles in the file tree.
   40.10 -     */
   40.11 -    DETECT_CYCLES;
   40.12 +    FOLLOW_LINKS;
   40.13  }
    41.1 --- a/src/share/classes/java/nio/file/FileVisitor.java	Tue Oct 12 13:34:59 2010 -0400
    41.2 +++ b/src/share/classes/java/nio/file/FileVisitor.java	Mon Oct 18 11:25:28 2010 -0400
    41.3 @@ -40,33 +40,28 @@
    41.4   *     Path start = ...
    41.5   *     Files.walkFileTree(start, new SimpleFileVisitor&lt;Path&gt;() {
    41.6   *         &#64;Override
    41.7 - *         public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
    41.8 - *             try {
    41.9 - *                 file.delete();
   41.10 - *             } catch (IOException exc) {
   41.11 - *                 // failed to delete, do error handling here
   41.12 - *             }
   41.13 + *         public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
   41.14 + *             throws IOException
   41.15 + *         {
   41.16 + *             file.delete();
   41.17   *             return FileVisitResult.CONTINUE;
   41.18   *         }
   41.19   *         &#64;Override
   41.20 - *         public FileVisitResult postVisitDirectory(Path dir, IOException e) {
   41.21 - *             if (e == null) {
   41.22 - *                 try {
   41.23 - *                     dir.delete();
   41.24 - *                 } catch (IOException exc) {
   41.25 - *                     // failed to delete, do error handling here
   41.26 - *                 }
   41.27 - *             } else {
   41.28 + *         public FileVisitResult postVisitDirectory(Path dir, IOException e)
   41.29 + *             throws IOException
   41.30 + *         {
   41.31 + *             if (e != null) {
   41.32   *                 // directory iteration failed
   41.33 + *                 throw e;
   41.34   *             }
   41.35 + *             dir.delete();
   41.36   *             return FileVisitResult.CONTINUE;
   41.37   *         }
   41.38   *     });
   41.39   * </pre>
   41.40 - * <p> Furthermore, suppose we want to copy a file tree rooted at a source
   41.41 - * directory to a target location. In that case, symbolic links should be
   41.42 - * followed and the target directory should be created before the entries in
   41.43 - * the directory are copied.
   41.44 + * <p> Furthermore, suppose we want to copy a file tree to a target location.
   41.45 + * In that case, symbolic links should be followed and the target directory
   41.46 + * should be created before the entries in the directory are copied.
   41.47   * <pre>
   41.48   *     final Path source = ...
   41.49   *     final Path target = ...
   41.50 @@ -74,25 +69,21 @@
   41.51   *     Files.walkFileTree(source, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
   41.52   *         new SimpleFileVisitor&lt;Path&gt;() {
   41.53   *             &#64;Override
   41.54 - *             public FileVisitResult preVisitDirectory(Path dir) {
   41.55 + *             public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
   41.56 + *                 throws IOException
   41.57 + *             {
   41.58   *                 try {
   41.59   *                     dir.copyTo(target.resolve(source.relativize(dir)));
   41.60   *                 } catch (FileAlreadyExistsException e) {
   41.61   *                      // ignore
   41.62 - *                 } catch (IOException e) {
   41.63 - *                     // copy failed, do error handling here
   41.64 - *                     // skip rest of directory and descendants
   41.65 - *                     return SKIP_SUBTREE;
   41.66   *                 }
   41.67   *                 return CONTINUE;
   41.68   *             }
   41.69   *             &#64;Override
   41.70 - *             public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
   41.71 - *                 try {
   41.72 - *                     file.copyTo(target.resolve(source.relativize(file)));
   41.73 - *                 } catch (IOException e) {
   41.74 - *                     // copy failed, do error handling here
   41.75 - *                 }
   41.76 + *             public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
   41.77 + *                 throws IOException
   41.78 + *             {
   41.79 + *                 file.copyTo(target.resolve(source.relativize(file)));
   41.80   *                 return CONTINUE;
   41.81   *             }
   41.82   *         });
   41.83 @@ -114,22 +105,16 @@
   41.84       *
   41.85       * @param   dir
   41.86       *          a reference to the directory
   41.87 +     * @param   attrs
   41.88 +     *          the directory's basic attributes
   41.89       *
   41.90       * @return  the visit result
   41.91 +     *
   41.92 +     * @throws  IOException
   41.93 +     *          if an I/O error occurs
   41.94       */
   41.95 -    FileVisitResult preVisitDirectory(T dir);
   41.96 -
   41.97 -    /**
   41.98 -     * Invoked for a directory that could not be opened.
   41.99 -     *
  41.100 -     * @param   dir
  41.101 -     *          a reference to the directory
  41.102 -     * @param   exc
  41.103 -     *          the I/O exception thrown from the attempt to open the directory
  41.104 -     *
  41.105 -     * @return  the visit result
  41.106 -     */
  41.107 -    FileVisitResult preVisitDirectoryFailed(T dir, IOException exc);
  41.108 +    FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
  41.109 +        throws IOException;
  41.110  
  41.111      /**
  41.112       * Invoked for a file in a directory.
  41.113 @@ -140,21 +125,30 @@
  41.114       *          the file's basic attributes
  41.115       *
  41.116       * @return  the visit result
  41.117 +     *
  41.118 +     * @throws  IOException
  41.119 +     *          if an I/O error occurs
  41.120       */
  41.121 -    FileVisitResult visitFile(T file, BasicFileAttributes attrs);
  41.122 +    FileVisitResult visitFile(T file, BasicFileAttributes attrs)
  41.123 +        throws IOException;
  41.124  
  41.125      /**
  41.126 -     * Invoked for a file when its basic file attributes could not be read.
  41.127 +     * Invoked for a file that could not be visited. This method is invoked
  41.128 +     * if the file's attributes could not be read, the file is a directory
  41.129 +     * that could not be opened, and other reasons.
  41.130       *
  41.131       * @param   file
  41.132       *          a reference to the file
  41.133       * @param   exc
  41.134 -     *          the I/O exception thrown from the attempt to read the file
  41.135 -     *          attributes
  41.136 +     *          the I/O exception that prevented the file from being visited
  41.137       *
  41.138       * @return  the visit result
  41.139 +     *
  41.140 +     * @throws  IOException
  41.141 +     *          if an I/O error occurs
  41.142       */
  41.143 -    FileVisitResult visitFileFailed(T file, IOException exc);
  41.144 +    FileVisitResult visitFileFailed(T file, IOException exc)
  41.145 +        throws IOException;
  41.146  
  41.147      /**
  41.148       * Invoked for a directory after entries in the directory, and all of their
  41.149 @@ -171,6 +165,10 @@
  41.150       *          of the directory to complete prematurely
  41.151       *
  41.152       * @return  the visit result
  41.153 +     *
  41.154 +     * @throws  IOException
  41.155 +     *          if an I/O error occurs
  41.156       */
  41.157 -    FileVisitResult postVisitDirectory(T dir, IOException exc);
  41.158 +    FileVisitResult postVisitDirectory(T dir, IOException exc)
  41.159 +        throws IOException;
  41.160  }
    42.1 --- a/src/share/classes/java/nio/file/Files.java	Tue Oct 12 13:34:59 2010 -0400
    42.2 +++ b/src/share/classes/java/nio/file/Files.java	Mon Oct 18 11:25:28 2010 -0400
    42.3 @@ -135,9 +135,9 @@
    42.4       * FileVisitor} invoked for each file encountered. File tree traversal
    42.5       * completes when all accessible files in the tree have been visited, or a
    42.6       * visit method returns a result of {@link FileVisitResult#TERMINATE
    42.7 -     * TERMINATE}. Where a visit method terminates due an uncaught error or
    42.8 -     * runtime exception then the traversal is terminated and the error or
    42.9 -     * exception is propagated to the caller of this method.
   42.10 +     * TERMINATE}. Where a visit method terminates due an {@code IOException},
   42.11 +     * an uncaught error, or runtime exception, then the traversal is terminated
   42.12 +     * and the error or exception is propagated to the caller of this method.
   42.13       *
   42.14       * <p> For each file encountered this method attempts to gets its {@link
   42.15       * java.nio.file.attribute.BasicFileAttributes}. If the file is not a
   42.16 @@ -146,12 +146,10 @@
   42.17       * due to an I/O exception, then the {@link FileVisitor#visitFileFailed
   42.18       * visitFileFailed} method is invoked with the I/O exception.
   42.19       *
   42.20 -     * <p> Where the file is a directory, this method attempts to open it by
   42.21 -     * invoking its {@link Path#newDirectoryStream newDirectoryStream} method.
   42.22 -     * Where the directory could not be opened, due to an {@code IOException},
   42.23 -     * then the {@link FileVisitor#preVisitDirectoryFailed preVisitDirectoryFailed}
   42.24 -     * method is invoked with the I/O exception, after which, the file tree walk
   42.25 -     * continues, by default, at the next <em>sibling</em> of the directory.
   42.26 +     * <p> Where the file is a directory, and the directory could not be opened,
   42.27 +     * then the {@code visitFileFailed} method is invoked with the I/O exception,
   42.28 +     * after which, the file tree walk continues, by default, at the next
   42.29 +     * <em>sibling</em> of the directory.
   42.30       *
   42.31       * <p> Where the directory is opened successfully, then the entries in the
   42.32       * directory, and their <em>descendants</em> are visited. When all entries
   42.33 @@ -171,26 +169,25 @@
   42.34       * method is invoked as specified above).
   42.35       *
   42.36       * <p> If the {@code options} parameter contains the {@link
   42.37 -     * FileVisitOption#DETECT_CYCLES DETECT_CYCLES} or {@link
   42.38 -     * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} options then this method keeps
   42.39 +     * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then this method keeps
   42.40       * track of directories visited so that cycles can be detected. A cycle
   42.41       * arises when there is an entry in a directory that is an ancestor of the
   42.42       * directory. Cycle detection is done by recording the {@link
   42.43       * java.nio.file.attribute.BasicFileAttributes#fileKey file-key} of directories,
   42.44       * or if file keys are not available, by invoking the {@link Path#isSameFile
   42.45       * isSameFile} method to test if a directory is the same file as an
   42.46 -     * ancestor. When a cycle is detected the {@link FileVisitor#visitFile
   42.47 -     * visitFile} is invoked with the attributes of the directory. The {@link
   42.48 -     * java.nio.file.attribute.BasicFileAttributes#isDirectory isDirectory}
   42.49 -     * method may be used to test if the file is a directory and that a cycle is
   42.50 -     * detected. The {@code preVisitDirectory} and {@code postVisitDirectory}
   42.51 -     * methods are not invoked.
   42.52 +     * ancestor. When a cycle is detected it is treated as an I/O error, and the
   42.53 +     * {@link FileVisitor#visitFileFailed visitFileFailed} method is invoked with
   42.54 +     * an instance of {@link FileSystemLoopException}.
   42.55       *
   42.56       * <p> The {@code maxDepth} parameter is the maximum number of levels of
   42.57       * directories to visit. A value of {@code 0} means that only the starting
   42.58       * file is visited, unless denied by the security manager. A value of
   42.59       * {@link Integer#MAX_VALUE MAX_VALUE} may be used to indicate that all
   42.60 -     * levels should be visited.
   42.61 +     * levels should be visited. The {@code visitFile} method is invoked for all
   42.62 +     * files, including directories, encountered at {@code maxDepth}, unless the
   42.63 +     * basic file attributes cannot be read, in which case the {@code
   42.64 +     * visitFileFailed} method is invoked.
   42.65       *
   42.66       * <p> If a visitor returns a result of {@code null} then {@code
   42.67       * NullPointerException} is thrown.
   42.68 @@ -215,11 +212,14 @@
   42.69       *          In the case of the default provider, the {@link
   42.70       *          SecurityManager#checkRead(String) checkRead} method is invoked
   42.71       *          to check read access to the directory.
   42.72 +     * @throws  IOException
   42.73 +     *          If an I/O error is thrown by a visitor method
   42.74       */
   42.75      public static void walkFileTree(Path start,
   42.76                                      Set<FileVisitOption> options,
   42.77                                      int maxDepth,
   42.78                                      FileVisitor<? super Path> visitor)
   42.79 +        throws IOException
   42.80      {
   42.81          if (maxDepth < 0)
   42.82              throw new IllegalArgumentException("'maxDepth' is negative");
   42.83 @@ -245,8 +245,12 @@
   42.84       *          In the case of the default provider, the {@link
   42.85       *          SecurityManager#checkRead(String) checkRead} method is invoked
   42.86       *          to check read access to the directory.
   42.87 +     * @throws  IOException
   42.88 +     *          If an I/O error is thrown by a visitor method
   42.89       */
   42.90 -    public static void walkFileTree(Path start, FileVisitor<? super Path> visitor) {
   42.91 +    public static void walkFileTree(Path start, FileVisitor<? super Path> visitor)
   42.92 +        throws IOException
   42.93 +    {
   42.94          walkFileTree(start,
   42.95                       EnumSet.noneOf(FileVisitOption.class),
   42.96                       Integer.MAX_VALUE,
    43.1 --- a/src/share/classes/java/nio/file/SimpleFileVisitor.java	Tue Oct 12 13:34:59 2010 -0400
    43.2 +++ b/src/share/classes/java/nio/file/SimpleFileVisitor.java	Mon Oct 18 11:25:28 2010 -0400
    43.3 @@ -27,7 +27,7 @@
    43.4  
    43.5  import java.nio.file.attribute.BasicFileAttributes;
    43.6  import java.io.IOException;
    43.7 -import java.io.IOError;
    43.8 +import java.util.Objects;
    43.9  
   43.10  /**
   43.11   * A simple visitor of files with default behavior to visit all files and to
   43.12 @@ -48,70 +48,47 @@
   43.13      }
   43.14  
   43.15      /**
   43.16 -     * Throws NullPointerException if obj is null.
   43.17 -     */
   43.18 -    private static void checkNotNull(Object obj) {
   43.19 -        if (obj == null)
   43.20 -            throw new NullPointerException();
   43.21 -    }
   43.22 -
   43.23 -    /**
   43.24       * Invoked for a directory before entries in the directory are visited.
   43.25       *
   43.26       * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
   43.27       * CONTINUE}.
   43.28       */
   43.29      @Override
   43.30 -    public FileVisitResult preVisitDirectory(T dir) {
   43.31 -        checkNotNull(dir);
   43.32 +    public FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
   43.33 +        throws IOException
   43.34 +    {
   43.35 +        Objects.nonNull(dir);
   43.36 +        Objects.nonNull(attrs);
   43.37          return FileVisitResult.CONTINUE;
   43.38      }
   43.39  
   43.40      /**
   43.41 -     * Invoked for a directory that could not be opened.
   43.42 -     *
   43.43 -     * <p> Unless overridden, this method throws {@link IOError} with the I/O
   43.44 -     * exception as cause.
   43.45 -     *
   43.46 -     * @throws  IOError
   43.47 -     *          with the I/O exception thrown when the attempt to open the
   43.48 -     *          directory failed
   43.49 -     */
   43.50 -    @Override
   43.51 -    public FileVisitResult preVisitDirectoryFailed(T dir, IOException exc) {
   43.52 -        checkNotNull(dir);
   43.53 -        checkNotNull(exc);
   43.54 -        throw new IOError(exc);
   43.55 -    }
   43.56 -
   43.57 -    /**
   43.58       * Invoked for a file in a directory.
   43.59       *
   43.60       * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
   43.61       * CONTINUE}.
   43.62       */
   43.63      @Override
   43.64 -    public FileVisitResult visitFile(T file, BasicFileAttributes attrs) {
   43.65 -        checkNotNull(file);
   43.66 -        checkNotNull(attrs);
   43.67 +    public FileVisitResult visitFile(T file, BasicFileAttributes attrs)
   43.68 +        throws IOException
   43.69 +    {
   43.70 +        Objects.nonNull(file);
   43.71 +        Objects.nonNull(attrs);
   43.72          return FileVisitResult.CONTINUE;
   43.73      }
   43.74  
   43.75      /**
   43.76 -     * Invoked for a file when its basic file attributes could not be read.
   43.77 +     * Invoked for a file that could not be visited.
   43.78       *
   43.79 -     * <p> Unless overridden, this method throws {@link IOError} with the I/O
   43.80 -     * exception as cause.
   43.81 -     *
   43.82 -     * @throws  IOError
   43.83 -     *          with the I/O exception thrown when the attempt to read the file
   43.84 -     *          attributes failed
   43.85 +     * <p> Unless overridden, this method re-throws the I/O exception that prevented
   43.86 +     * the file from being visited.
   43.87       */
   43.88      @Override
   43.89 -    public FileVisitResult visitFileFailed(T file, IOException exc) {
   43.90 -        checkNotNull(file);
   43.91 -        checkNotNull(exc);
   43.92 -        throw new IOError(exc);
   43.93 +    public FileVisitResult visitFileFailed(T file, IOException exc)
   43.94 +        throws IOException
   43.95 +    {
   43.96 +        Objects.nonNull(file);
   43.97 +        throw exc;
   43.98      }
   43.99  
  43.100      /**
  43.101 @@ -120,18 +97,16 @@
  43.102       *
  43.103       * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
  43.104       * CONTINUE} if the directory iteration completes without an I/O exception;
  43.105 -     * otherwise this method throws {@link IOError} with the I/O exception as
  43.106 -     * cause.
  43.107 -     *
  43.108 -     * @throws  IOError
  43.109 -     *          with the I/O exception thrown when iteration of the directory
  43.110 -     *          completed prematurely due to an I/O error
  43.111 +     * otherwise this method re-throws the I/O exception that caused the iteration
  43.112 +     * of the directory to terminate prematurely.
  43.113       */
  43.114      @Override
  43.115 -    public FileVisitResult postVisitDirectory(T dir, IOException exc) {
  43.116 -        checkNotNull(dir);
  43.117 +    public FileVisitResult postVisitDirectory(T dir, IOException exc)
  43.118 +        throws IOException
  43.119 +    {
  43.120 +        Objects.nonNull(dir);
  43.121          if (exc != null)
  43.122 -            throw new IOError(exc);
  43.123 +            throw exc;
  43.124          return FileVisitResult.CONTINUE;
  43.125      }
  43.126  }
    44.1 --- a/src/share/classes/java/sql/DatabaseMetaData.java	Tue Oct 12 13:34:59 2010 -0400
    44.2 +++ b/src/share/classes/java/sql/DatabaseMetaData.java	Mon Oct 18 11:25:28 2010 -0400
    44.3 @@ -3643,7 +3643,7 @@
    44.4  
    44.5      /**
    44.6       * Retrieves whether a generated key will always be returned if the column
    44.7 -     * name(s) or indexe(s) specified for the auto generated key column(s)
    44.8 +     * name(s) or index(es) specified for the auto generated key column(s)
    44.9       * are valid and the statement succeeds.  The key that is returned may or
   44.10       * may not be based on the column(s) for the auto generated key.
   44.11       * Consult your JDBC driver documentation for additional details.
    45.1 --- a/src/share/classes/java/sql/Statement.java	Tue Oct 12 13:34:59 2010 -0400
    45.2 +++ b/src/share/classes/java/sql/Statement.java	Mon Oct 18 11:25:28 2010 -0400
    45.3 @@ -1051,9 +1051,9 @@
    45.4  
    45.5      /**
    45.6       * Returns a value indicating whether this {@code Statement} will be
    45.7 -     * closed when all dependent objects such as resultsets are closed.
    45.8 +     * closed when all its dependent result sets are closed.
    45.9       * @return {@code true} if the {@code Statement} will be closed when all
   45.10 -     * of its dependent objects are closed; {@code false} otherwise
   45.11 +     * of its dependent result sets are closed; {@code false} otherwise
   45.12       * @throws SQLException if this method is called on a closed
   45.13       * {@code Statement}
   45.14       * @since 1.7
    46.1 --- a/src/share/classes/java/util/Locale.java	Tue Oct 12 13:34:59 2010 -0400
    46.2 +++ b/src/share/classes/java/util/Locale.java	Mon Oct 18 11:25:28 2010 -0400
    46.3 @@ -569,6 +569,9 @@
    46.4       * @exception NullPointerException thrown if any argument is null.
    46.5       */
    46.6      public Locale(String language, String country, String variant) {
    46.7 +        if (language== null || country == null || variant == null) {
    46.8 +            throw new NullPointerException();
    46.9 +        }
   46.10          _baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), "", country, variant);
   46.11          _extensions = getCompatibilityExtensions(language, "", country, variant);
   46.12      }
    47.1 --- a/src/share/classes/java/util/ResourceBundle.java	Tue Oct 12 13:34:59 2010 -0400
    47.2 +++ b/src/share/classes/java/util/ResourceBundle.java	Mon Oct 18 11:25:28 2010 -0400
    47.3 @@ -293,16 +293,6 @@
    47.4          = new ConcurrentHashMap<CacheKey, BundleReference>(INITIAL_CACHE_SIZE);
    47.5  
    47.6      /**
    47.7 -     * This ConcurrentMap is used to keep multiple threads from loading the
    47.8 -     * same bundle concurrently.  The table entries are <CacheKey, Thread>
    47.9 -     * where CacheKey is the key for the bundle that is under construction
   47.10 -     * and Thread is the thread that is constructing the bundle.
   47.11 -     * This list is manipulated in findBundleInCache and putBundleInCache.
   47.12 -     */
   47.13 -    private static final ConcurrentMap<CacheKey, Thread> underConstruction
   47.14 -        = new ConcurrentHashMap<CacheKey, Thread>();
   47.15 -
   47.16 -    /**
   47.17       * Queue for reference objects referring to class loaders or bundles.
   47.18       */
   47.19      private static final ReferenceQueue referenceQueue = new ReferenceQueue();
   47.20 @@ -1381,7 +1371,7 @@
   47.21          boolean expiredBundle = false;
   47.22  
   47.23          // First, look up the cache to see if it's in the cache, without
   47.24 -        // declaring beginLoading.
   47.25 +        // attempting to load bundle.
   47.26          cacheKey.setLocale(targetLocale);
   47.27          ResourceBundle bundle = findBundleInCache(cacheKey, control);
   47.28          if (isValidBundle(bundle)) {
   47.29 @@ -1408,56 +1398,25 @@
   47.30              CacheKey constKey = (CacheKey) cacheKey.clone();
   47.31  
   47.32              try {
   47.33 -                // Try declaring loading. If beginLoading() returns true,
   47.34 -                // then we can proceed. Otherwise, we need to take a look
   47.35 -                // at the cache again to see if someone else has loaded
   47.36 -                // the bundle and put it in the cache while we've been
   47.37 -                // waiting for other loading work to complete.
   47.38 -                while (!beginLoading(constKey)) {
   47.39 -                    bundle = findBundleInCache(cacheKey, control);
   47.40 -                    if (bundle == null) {
   47.41 -                        continue;
   47.42 +                bundle = loadBundle(cacheKey, formats, control, expiredBundle);
   47.43 +                if (bundle != null) {
   47.44 +                    if (bundle.parent == null) {
   47.45 +                        bundle.setParent(parent);
   47.46                      }
   47.47 -                    if (bundle == NONEXISTENT_BUNDLE) {
   47.48 -                        // If the bundle is NONEXISTENT_BUNDLE, the bundle doesn't exist.
   47.49 -                        return parent;
   47.50 -                    }
   47.51 -                    expiredBundle = bundle.expired;
   47.52 -                    if (!expiredBundle) {
   47.53 -                        if (bundle.parent == parent) {
   47.54 -                            return bundle;
   47.55 -                        }
   47.56 -                        BundleReference bundleRef = cacheList.get(cacheKey);
   47.57 -                        if (bundleRef != null && bundleRef.get() == bundle) {
   47.58 -                            cacheList.remove(cacheKey, bundleRef);
   47.59 -                        }
   47.60 -                    }
   47.61 +                    bundle.locale = targetLocale;
   47.62 +                    bundle = putBundleInCache(cacheKey, bundle, control);
   47.63 +                    return bundle;
   47.64                  }
   47.65  
   47.66 -                try {
   47.67 -                    bundle = loadBundle(cacheKey, formats, control, expiredBundle);
   47.68 -                    if (bundle != null) {
   47.69 -                        if (bundle.parent == null) {
   47.70 -                            bundle.setParent(parent);
   47.71 -                        }
   47.72 -                        bundle.locale = targetLocale;
   47.73 -                        bundle = putBundleInCache(cacheKey, bundle, control);
   47.74 -                        return bundle;
   47.75 -                    }
   47.76 -
   47.77 -                    // Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle
   47.78 -                    // instance for the locale.
   47.79 -                    putBundleInCache(cacheKey, NONEXISTENT_BUNDLE, control);
   47.80 -                } finally {
   47.81 -                    endLoading(constKey);
   47.82 -                }
   47.83 +                // Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle
   47.84 +                // instance for the locale.
   47.85 +                putBundleInCache(cacheKey, NONEXISTENT_BUNDLE, control);
   47.86              } finally {
   47.87                  if (constKey.getCause() instanceof InterruptedException) {
   47.88                      Thread.currentThread().interrupt();
   47.89                  }
   47.90              }
   47.91          }
   47.92 -        assert underConstruction.get(cacheKey) != Thread.currentThread();
   47.93          return parent;
   47.94      }
   47.95  
   47.96 @@ -1465,7 +1424,6 @@
   47.97                                                     List<String> formats,
   47.98                                                     Control control,
   47.99                                                     boolean reload) {
  47.100 -        assert underConstruction.get(cacheKey) == Thread.currentThread();
  47.101  
  47.102          // Here we actually load the bundle in the order of formats
  47.103          // specified by the getFormats() value.
  47.104 @@ -1498,7 +1456,6 @@
  47.105                  break;
  47.106              }
  47.107          }
  47.108 -        assert underConstruction.get(cacheKey) == Thread.currentThread();
  47.109  
  47.110          return bundle;
  47.111      }
  47.112 @@ -1530,57 +1487,6 @@
  47.113      }
  47.114  
  47.115      /**
  47.116 -     * Declares the beginning of actual resource bundle loading. This method
  47.117 -     * returns true if the declaration is successful and the current thread has
  47.118 -     * been put in underConstruction. If someone else has already begun
  47.119 -     * loading, this method waits until that loading work is complete and
  47.120 -     * returns false.
  47.121 -     */
  47.122 -    private static final boolean beginLoading(CacheKey constKey) {
  47.123 -        Thread me = Thread.currentThread();
  47.124 -        Thread worker;
  47.125 -        // We need to declare by putting the current Thread (me) to
  47.126 -        // underConstruction that we are working on loading the specified
  47.127 -        // resource bundle. If we are already working the loading, it means
  47.128 -        // that the resource loading requires a recursive call. In that case,
  47.129 -        // we have to proceed. (4300693)
  47.130 -        if (((worker = underConstruction.putIfAbsent(constKey, me)) == null)
  47.131 -            || worker == me) {
  47.132 -            return true;
  47.133 -        }
  47.134 -
  47.135 -        // If someone else is working on the loading, wait until
  47.136 -        // the Thread finishes the bundle loading.
  47.137 -        synchronized (worker) {
  47.138 -            while (underConstruction.get(constKey) == worker) {
  47.139 -                try {
  47.140 -                    worker.wait();
  47.141 -                } catch (InterruptedException e) {
  47.142 -                    // record the interruption
  47.143 -                    constKey.setCause(e);
  47.144 -                }
  47.145 -            }
  47.146 -        }
  47.147 -        return false;
  47.148 -    }
  47.149 -
  47.150 -    /**
  47.151 -     * Declares the end of the bundle loading. This method calls notifyAll
  47.152 -     * for those who are waiting for this completion.
  47.153 -     */
  47.154 -    private static final void endLoading(CacheKey constKey) {
  47.155 -        // Remove this Thread from the underConstruction map and wake up
  47.156 -        // those who have been waiting for me to complete this bundle
  47.157 -        // loading.
  47.158 -        Thread me = Thread.currentThread();
  47.159 -        assert (underConstruction.get(constKey) == me);
  47.160 -        underConstruction.remove(constKey);
  47.161 -        synchronized (me) {
  47.162 -            me.notifyAll();
  47.163 -        }
  47.164 -    }
  47.165 -
  47.166 -    /**
  47.167       * Throw a MissingResourceException with proper message
  47.168       */
  47.169      private static final void throwMissingResourceException(String baseName,
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java	Mon Oct 18 11:25:28 2010 -0400
    48.3 @@ -0,0 +1,1445 @@
    48.4 +/*
    48.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    48.6 + *
    48.7 + * This code is free software; you can redistribute it and/or modify it
    48.8 + * under the terms of the GNU General Public License version 2 only, as
    48.9 + * published by the Free Software Foundation.  Oracle designates this
   48.10 + * particular file as subject to the "Classpath" exception as provided
   48.11 + * by Oracle in the LICENSE file that accompanied this code.
   48.12 + *
   48.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
   48.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   48.15 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   48.16 + * version 2 for more details (a copy is included in the LICENSE file that
   48.17 + * accompanied this code).
   48.18 + *
   48.19 + * You should have received a copy of the GNU General Public License version
   48.20 + * 2 along with this work; if not, write to the Free Software Foundation,
   48.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   48.22 + *
   48.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   48.24 + * or visit www.oracle.com if you need additional information or have any
   48.25 + * questions.
   48.26 + */
   48.27 +
   48.28 +/*
   48.29 + * This file is available under and governed by the GNU General Public
   48.30 + * License version 2 only, as published by the Free Software Foundation.
   48.31 + * However, the following notice accompanied the original version of this
   48.32 + * file:
   48.33 + *
   48.34 + * Written by Doug Lea and Martin Buchholz with assistance from members of
   48.35 + * JCP JSR-166 Expert Group and released to the public domain, as explained
   48.36 + * at http://creativecommons.org/licenses/publicdomain
   48.37 + */
   48.38 +
   48.39 +package java.util.concurrent;
   48.40 +
   48.41 +import java.util.AbstractCollection;
   48.42 +import java.util.ArrayList;
   48.43 +import java.util.Collection;
   48.44 +import java.util.ConcurrentModificationException;
   48.45 +import java.util.Deque;
   48.46 +import java.util.Iterator;
   48.47 +import java.util.NoSuchElementException;
   48.48 +import java.util.Queue;
   48.49 +
   48.50 +/**
   48.51 + * An unbounded concurrent {@linkplain Deque deque} based on linked nodes.
   48.52 + * Concurrent insertion, removal, and access operations execute safely
   48.53 + * across multiple threads.
   48.54 + * A {@code ConcurrentLinkedDeque} is an appropriate choice when
   48.55 + * many threads will share access to a common collection.
   48.56 + * Like most other concurrent collection implementations, this class
   48.57 + * does not permit the use of {@code null} elements.
   48.58 + *
   48.59 + * <p>Iterators are <i>weakly consistent</i>, returning elements
   48.60 + * reflecting the state of the deque at some point at or since the
   48.61 + * creation of the iterator.  They do <em>not</em> throw {@link
   48.62 + * java.util.ConcurrentModificationException
   48.63 + * ConcurrentModificationException}, and may proceed concurrently with
   48.64 + * other operations.
   48.65 + *
   48.66 + * <p>Beware that, unlike in most collections, the {@code size}
   48.67 + * method is <em>NOT</em> a constant-time operation. Because of the
   48.68 + * asynchronous nature of these deques, determining the current number
   48.69 + * of elements requires a traversal of the elements.
   48.70 + *
   48.71 + * <p>This class and its iterator implement all of the <em>optional</em>
   48.72 + * methods of the {@link Deque} and {@link Iterator} interfaces.
   48.73 + *
   48.74 + * <p>Memory consistency effects: As with other concurrent collections,
   48.75 + * actions in a thread prior to placing an object into a
   48.76 + * {@code ConcurrentLinkedDeque}
   48.77 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
   48.78 + * actions subsequent to the access or removal of that element from
   48.79 + * the {@code ConcurrentLinkedDeque} in another thread.
   48.80 + *
   48.81 + * <p>This class is a member of the
   48.82 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
   48.83 + * Java Collections Framework</a>.
   48.84 + *
   48.85 + * @since 1.7
   48.86 + * @author Doug Lea
   48.87 + * @author Martin Buchholz
   48.88 + * @param <E> the type of elements held in this collection
   48.89 + */
   48.90 +
   48.91 +public class ConcurrentLinkedDeque<E>
   48.92 +    extends AbstractCollection<E>
   48.93 +    implements Deque<E>, java.io.Serializable {
   48.94 +
   48.95 +    /*
   48.96 +     * This is an implementation of a concurrent lock-free deque
   48.97 +     * supporting interior removes but not interior insertions, as
   48.98 +     * required to support the entire Deque interface.
   48.99 +     *
  48.100 +     * We extend the techniques developed for ConcurrentLinkedQueue and
  48.101 +     * LinkedTransferQueue (see the internal docs for those classes).
  48.102 +     * Understanding the ConcurrentLinkedQueue implementation is a
  48.103 +     * prerequisite for understanding the implementation of this class.
  48.104 +     *
  48.105 +     * The data structure is a symmetrical doubly-linked "GC-robust"
  48.106 +     * linked list of nodes.  We minimize the number of volatile writes
  48.107 +     * using two techniques: advancing multiple hops with a single CAS
  48.108 +     * and mixing volatile and non-volatile writes of the same memory
  48.109 +     * locations.
  48.110 +     *
  48.111 +     * A node contains the expected E ("item") and links to predecessor
  48.112 +     * ("prev") and successor ("next") nodes:
  48.113 +     *
  48.114 +     * class Node<E> { volatile Node<E> prev, next; volatile E item; }
  48.115 +     *
  48.116 +     * A node p is considered "live" if it contains a non-null item
  48.117 +     * (p.item != null).  When an item is CASed to null, the item is
  48.118 +     * atomically logically deleted from the collection.
  48.119 +     *
  48.120 +     * At any time, there is precisely one "first" node with a null
  48.121 +     * prev reference that terminates any chain of prev references
  48.122 +     * starting at a live node.  Similarly there is precisely one
  48.123 +     * "last" node terminating any chain of next references starting at
  48.124 +     * a live node.  The "first" and "last" nodes may or may not be live.
  48.125 +     * The "first" and "last" nodes are always mutually reachable.
  48.126 +     *
  48.127 +     * A new element is added atomically by CASing the null prev or
  48.128 +     * next reference in the first or last node to a fresh node
  48.129 +     * containing the element.  The element's node atomically becomes
  48.130 +     * "live" at that point.
  48.131 +     *
  48.132 +     * A node is considered "active" if it is a live node, or the
  48.133 +     * first or last node.  Active nodes cannot be unlinked.
  48.134 +     *
  48.135 +     * A "self-link" is a next or prev reference that is the same node:
  48.136 +     *   p.prev == p  or  p.next == p
  48.137 +     * Self-links are used in the node unlinking process.  Active nodes
  48.138 +     * never have self-links.
  48.139 +     *
  48.140 +     * A node p is active if and only if:
  48.141 +     *
  48.142 +     * p.item != null ||
  48.143 +     * (p.prev == null && p.next != p) ||
  48.144 +     * (p.next == null && p.prev != p)
  48.145 +     *
  48.146 +     * The deque object has two node references, "head" and "tail".
  48.147 +     * The head and tail are only approximations to the first and last
  48.148 +     * nodes of the deque.  The first node can always be found by
  48.149 +     * following prev pointers from head; likewise for tail.  However,
  48.150 +     * it is permissible for head and tail to be referring to deleted
  48.151 +     * nodes that have been unlinked and so may not be reachable from
  48.152 +     * any live node.
  48.153 +     *
  48.154 +     * There are 3 stages of node deletion;
  48.155 +     * "logical deletion", "unlinking", and "gc-unlinking".
  48.156 +     *
  48.157 +     * 1. "logical deletion" by CASing item to null atomically removes
  48.158 +     * the element from the collection, and makes the containing node
  48.159 +     * eligible for unlinking.
  48.160 +     *
  48.161 +     * 2. "unlinking" makes a deleted node unreachable from active
  48.162 +     * nodes, and thus eventually reclaimable by GC.  Unlinked nodes
  48.163 +     * may remain reachable indefinitely from an iterator.
  48.164 +     *
  48.165 +     * Physical node unlinking is merely an optimization (albeit a
  48.166 +     * critical one), and so can be performed at our convenience.  At
  48.167 +     * any time, the set of live nodes maintained by prev and next
  48.168 +     * links are identical, that is, the live nodes found via next
  48.169 +     * links from the first node is equal to the elements found via
  48.170 +     * prev links from the last node.  However, this is not true for
  48.171 +     * nodes that have already been logically deleted - such nodes may
  48.172 +     * be reachable in one direction only.
  48.173 +     *
  48.174 +     * 3. "gc-unlinking" takes unlinking further by making active
  48.175 +     * nodes unreachable from deleted nodes, making it easier for the
  48.176 +     * GC to reclaim future deleted nodes.  This step makes the data
  48.177 +     * structure "gc-robust", as first described in detail by Boehm
  48.178 +     * (http://portal.acm.org/citation.cfm?doid=503272.503282).
  48.179 +     *
  48.180 +     * GC-unlinked nodes may remain reachable indefinitely from an
  48.181 +     * iterator, but unlike unlinked nodes, are never reachable from
  48.182 +     * head or tail.
  48.183 +     *
  48.184 +     * Making the data structure GC-robust will eliminate the risk of
  48.185 +     * unbounded memory retention with conservative GCs and is likely
  48.186 +     * to improve performance with generational GCs.
  48.187 +     *
  48.188 +     * When a node is dequeued at either end, e.g. via poll(), we would
  48.189 +     * like to break any references from the node to active nodes.  We
  48.190 +     * develop further the use of self-links that was very effective in
  48.191 +     * other concurrent collection classes.  The idea is to replace
  48.192 +     * prev and next pointers with special values that are interpreted
  48.193 +     * to mean off-the-list-at-one-end.  These are approximations, but
  48.194 +     * good enough to preserve the properties we want in our
  48.195 +     * traversals, e.g. we guarantee that a traversal will never visit
  48.196 +     * the same element twice, but we don't guarantee whether a
  48.197 +     * traversal that runs out of elements will be able to see more
  48.198 +     * elements later after enqueues at that end.  Doing gc-unlinking
  48.199 +     * safely is particularly tricky, since any node can be in use
  48.200 +     * indefinitely (for example by an iterator).  We must ensure that
  48.201 +     * the nodes pointed at by head/tail never get gc-unlinked, since
  48.202 +     * head/tail are needed to get "back on track" by other nodes that
  48.203 +     * are gc-unlinked.  gc-unlinking accounts for much of the
  48.204 +     * implementation complexity.
  48.205 +     *
  48.206 +     * Since neither unlinking nor gc-unlinking are necessary for
  48.207 +     * correctness, there are many implementation choices regarding
  48.208 +     * frequency (eagerness) of these operations.  Since volatile
  48.209 +     * reads are likely to be much cheaper than CASes, saving CASes by
  48.210 +     * unlinking multiple adjacent nodes at a time may be a win.
  48.211 +     * gc-unlinking can be performed rarely and still be effective,
  48.212 +     * since it is most important that long chains of deleted nodes
  48.213 +     * are occasionally broken.
  48.214 +     *
  48.215 +     * The actual representation we use is that p.next == p means to
  48.216 +     * goto the first node (which in turn is reached by following prev
  48.217 +     * pointers from head), and p.next == null && p.prev == p means
  48.218 +     * that the iteration is at an end and that p is a (final static)
  48.219 +     * dummy node, NEXT_TERMINATOR, and not the last active node.
  48.220 +     * Finishing the iteration when encountering such a TERMINATOR is
  48.221 +     * good enough for read-only traversals, so such traversals can use
  48.222 +     * p.next == null as the termination condition.  When we need to
  48.223 +     * find the last (active) node, for enqueueing a new node, we need
  48.224 +     * to check whether we have reached a TERMINATOR node; if so,
  48.225 +     * restart traversal from tail.
  48.226 +     *
  48.227 +     * The implementation is completely directionally symmetrical,
  48.228 +     * except that most public methods that iterate through the list
  48.229 +     * follow next pointers ("forward" direction).
  48.230 +     *
  48.231 +     * We believe (without full proof) that all single-element deque
  48.232 +     * operations (e.g., addFirst, peekLast, pollLast) are linearizable
  48.233 +     * (see Herlihy and Shavit's book).  However, some combinations of
  48.234 +     * operations are known not to be linearizable.  In particular,
  48.235 +     * when an addFirst(A) is racing with pollFirst() removing B, it is
  48.236 +     * possible for an observer iterating over the elements to observe
  48.237 +     * A B C and subsequently observe A C, even though no interior
  48.238 +     * removes are ever performed.  Nevertheless, iterators behave
  48.239 +     * reasonably, providing the "weakly consistent" guarantees.
  48.240 +     *
  48.241 +     * Empirically, microbenchmarks suggest that this class adds about
  48.242 +     * 40% overhead relative to ConcurrentLinkedQueue, which feels as
  48.243 +     * good as we can hope for.
  48.244 +     */
  48.245 +
  48.246 +    private static final long serialVersionUID = 876323262645176354L;
  48.247 +
  48.248 +    /**
  48.249 +     * A node from which the first node on list (that is, the unique node p
  48.250 +     * with p.prev == null && p.next != p) can be reached in O(1) time.
  48.251 +     * Invariants:
  48.252 +     * - the first node is always O(1) reachable from head via prev links
  48.253 +     * - all live nodes are reachable from the first node via succ()
  48.254 +     * - head != null
  48.255 +     * - (tmp = head).next != tmp || tmp != head
  48.256 +     * - head is never gc-unlinked (but may be unlinked)
  48.257 +     * Non-invariants:
  48.258 +     * - head.item may or may not be null
  48.259 +     * - head may not be reachable from the first or last node, or from tail
  48.260 +     */
  48.261 +    private transient volatile Node<E> head;
  48.262 +
  48.263 +    /**
  48.264 +     * A node from which the last node on list (that is, the unique node p
  48.265 +     * with p.next == null && p.prev != p) can be reached in O(1) time.
  48.266 +     * Invariants:
  48.267 +     * - the last node is always O(1) reachable from tail via next links
  48.268 +     * - all live nodes are reachable from the last node via pred()
  48.269 +     * - tail != null
  48.270 +     * - tail is never gc-unlinked (but may be unlinked)
  48.271 +     * Non-invariants:
  48.272 +     * - tail.item may or may not be null
  48.273 +     * - tail may not be reachable from the first or last node, or from head
  48.274 +     */
  48.275 +    private transient volatile Node<E> tail;
  48.276 +
  48.277 +    private final static Node<Object> PREV_TERMINATOR, NEXT_TERMINATOR;
  48.278 +
  48.279 +    static {
  48.280 +        PREV_TERMINATOR = new Node<Object>(null);
  48.281 +        PREV_TERMINATOR.next = PREV_TERMINATOR;
  48.282 +        NEXT_TERMINATOR = new Node<Object>(null);
  48.283 +        NEXT_TERMINATOR.prev = NEXT_TERMINATOR;
  48.284 +    }
  48.285 +
  48.286 +    @SuppressWarnings("unchecked")
  48.287 +    Node<E> prevTerminator() {
  48.288 +        return (Node<E>) PREV_TERMINATOR;
  48.289 +    }
  48.290 +
  48.291 +    @SuppressWarnings("unchecked")
  48.292 +    Node<E> nextTerminator() {
  48.293 +        return (Node<E>) NEXT_TERMINATOR;
  48.294 +    }
  48.295 +
  48.296 +    static final class Node<E> {
  48.297 +        volatile Node<E> prev;
  48.298 +        volatile E item;
  48.299 +        volatile Node<E> next;
  48.300 +
  48.301 +        /**
  48.302 +         * Constructs a new node.  Uses relaxed write because item can
  48.303 +         * only be seen after publication via casNext or casPrev.
  48.304 +         */
  48.305 +        Node(E item) {
  48.306 +            UNSAFE.putObject(this, itemOffset, item);
  48.307 +        }
  48.308 +
  48.309 +        boolean casItem(E cmp, E val) {
  48.310 +            return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
  48.311 +        }
  48.312 +
  48.313 +        void lazySetNext(Node<E> val) {
  48.314 +            UNSAFE.putOrderedObject(this, nextOffset, val);
  48.315 +        }
  48.316 +
  48.317 +        boolean casNext(Node<E> cmp, Node<E> val) {
  48.318 +            return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
  48.319 +        }
  48.320 +
  48.321 +        void lazySetPrev(Node<E> val) {
  48.322 +            UNSAFE.putOrderedObject(this, prevOffset, val);
  48.323 +        }
  48.324 +
  48.325 +        boolean casPrev(Node<E> cmp, Node<E> val) {
  48.326 +            return UNSAFE.compareAndSwapObject(this, prevOffset, cmp, val);
  48.327 +        }
  48.328 +
  48.329 +        // Unsafe mechanics
  48.330 +
  48.331 +        private static final sun.misc.Unsafe UNSAFE =
  48.332 +            sun.misc.Unsafe.getUnsafe();
  48.333 +        private static final long prevOffset =
  48.334 +            objectFieldOffset(UNSAFE, "prev", Node.class);
  48.335 +        private static final long itemOffset =
  48.336 +            objectFieldOffset(UNSAFE, "item", Node.class);
  48.337 +        private static final long nextOffset =
  48.338 +            objectFieldOffset(UNSAFE, "next", Node.class);
  48.339 +    }
  48.340 +
  48.341 +    /**
  48.342 +     * Links e as first element.
  48.343 +     */
  48.344 +    private void linkFirst(E e) {
  48.345 +        checkNotNull(e);
  48.346 +        final Node<E> newNode = new Node<E>(e);
  48.347 +
  48.348 +        restartFromHead:
  48.349 +        for (;;)
  48.350 +            for (Node<E> h = head, p = h, q;;) {
  48.351 +                if ((q = p.prev) != null &&
  48.352 +                    (q = (p = q).prev) != null)
  48.353 +                    // Check for head updates every other hop.
  48.354 +                    // If p == q, we are sure to follow head instead.
  48.355 +                    p = (h != (h = head)) ? h : q;
  48.356 +                else if (p.next == p) // PREV_TERMINATOR
  48.357 +                    continue restartFromHead;
  48.358 +                else {
  48.359 +                    // p is first node
  48.360 +                    newNode.lazySetNext(p); // CAS piggyback
  48.361 +                    if (p.casPrev(null, newNode)) {
  48.362 +                        // Successful CAS is the linearization point
  48.363 +                        // for e to become an element of this deque,
  48.364 +                        // and for newNode to become "live".
  48.365 +                        if (p != h) // hop two nodes at a time
  48.366 +                            casHead(h, newNode);  // Failure is OK.
  48.367 +                        return;
  48.368 +                    }
  48.369 +                    // Lost CAS race to another thread; re-read prev
  48.370 +                }
  48.371 +            }
  48.372 +    }
  48.373 +
  48.374 +    /**
  48.375 +     * Links e as last element.
  48.376 +     */
  48.377 +    private void linkLast(E e) {
  48.378 +        checkNotNull(e);
  48.379 +        final Node<E> newNode = new Node<E>(e);
  48.380 +
  48.381 +        restartFromTail:
  48.382 +        for (;;)
  48.383 +            for (Node<E> t = tail, p = t, q;;) {
  48.384 +                if ((q = p.next) != null &&
  48.385 +                    (q = (p = q).next) != null)
  48.386 +                    // Check for tail updates every other hop.
  48.387 +                    // If p == q, we are sure to follow tail instead.
  48.388 +                    p = (t != (t = tail)) ? t : q;
  48.389 +                else if (p.prev == p) // NEXT_TERMINATOR
  48.390 +                    continue restartFromTail;
  48.391 +                else {
  48.392 +                    // p is last node
  48.393 +                    newNode.lazySetPrev(p); // CAS piggyback
  48.394 +                    if (p.casNext(null, newNode)) {
  48.395 +                        // Successful CAS is the linearization point
  48.396 +                        // for e to become an element of this deque,
  48.397 +                        // and for newNode to become "live".
  48.398 +                        if (p != t) // hop two nodes at a time
  48.399 +                            casTail(t, newNode);  // Failure is OK.
  48.400 +                        return;
  48.401 +                    }
  48.402 +                    // Lost CAS race to another thread; re-read next
  48.403 +                }
  48.404 +            }
  48.405 +    }
  48.406 +
  48.407 +    private final static int HOPS = 2;
  48.408 +
  48.409 +    /**
  48.410 +     * Unlinks non-null node x.
  48.411 +     */
  48.412 +    void unlink(Node<E> x) {
  48.413 +        // assert x != null;
  48.414 +        // assert x.item == null;
  48.415 +        // assert x != PREV_TERMINATOR;
  48.416 +        // assert x != NEXT_TERMINATOR;
  48.417 +
  48.418 +        final Node<E> prev = x.prev;
  48.419 +        final Node<E> next = x.next;
  48.420 +        if (prev == null) {
  48.421 +            unlinkFirst(x, next);
  48.422 +        } else if (next == null) {
  48.423 +            unlinkLast(x, prev);
  48.424 +        } else {
  48.425 +            // Unlink interior node.
  48.426 +            //
  48.427 +            // This is the common case, since a series of polls at the
  48.428 +            // same end will be "interior" removes, except perhaps for
  48.429 +            // the first one, since end nodes cannot be unlinked.
  48.430 +            //
  48.431 +            // At any time, all active nodes are mutually reachable by
  48.432 +            // following a sequence of either next or prev pointers.
  48.433 +            //
  48.434 +            // Our strategy is to find the unique active predecessor
  48.435 +            // and successor of x.  Try to fix up their links so that
  48.436 +            // they point to each other, leaving x unreachable from
  48.437 +            // active nodes.  If successful, and if x has no live
  48.438 +            // predecessor/successor, we additionally try to gc-unlink,
  48.439 +            // leaving active nodes unreachable from x, by rechecking
  48.440 +            // that the status of predecessor and successor are
  48.441 +            // unchanged and ensuring that x is not reachable from
  48.442 +            // tail/head, before setting x's prev/next links to their
  48.443 +            // logical approximate replacements, self/TERMINATOR.
  48.444 +            Node<E> activePred, activeSucc;
  48.445 +            boolean isFirst, isLast;
  48.446 +            int hops = 1;
  48.447 +
  48.448 +            // Find active predecessor
  48.449 +            for (Node<E> p = prev; ; ++hops) {
  48.450 +                if (p.item != null) {
  48.451 +                    activePred = p;
  48.452 +                    isFirst = false;
  48.453 +                    break;
  48.454 +                }
  48.455 +                Node<E> q = p.prev;
  48.456 +                if (q == null) {
  48.457 +                    if (p.next == p)
  48.458 +                        return;
  48.459 +                    activePred = p;
  48.460 +                    isFirst = true;
  48.461 +                    break;
  48.462 +                }
  48.463 +                else if (p == q)
  48.464 +                    return;
  48.465 +                else
  48.466 +                    p = q;
  48.467 +            }
  48.468 +
  48.469 +            // Find active successor
  48.470 +            for (Node<E> p = next; ; ++hops) {
  48.471 +                if (p.item != null) {
  48.472 +                    activeSucc = p;
  48.473 +                    isLast = false;
  48.474 +                    break;
  48.475 +                }
  48.476 +                Node<E> q = p.next;
  48.477 +                if (q == null) {
  48.478 +                    if (p.prev == p)
  48.479 +                        return;
  48.480 +                    activeSucc = p;
  48.481 +                    isLast = true;
  48.482 +                    break;
  48.483 +                }
  48.484 +                else if (p == q)
  48.485 +                    return;
  48.486 +                else
  48.487 +                    p = q;
  48.488 +            }
  48.489 +
  48.490 +            // TODO: better HOP heuristics
  48.491 +            if (hops < HOPS
  48.492 +                // always squeeze out interior deleted nodes
  48.493 +                && (isFirst | isLast))
  48.494 +                return;
  48.495 +
  48.496 +            // Squeeze out deleted nodes between activePred and
  48.497 +            // activeSucc, including x.
  48.498 +            skipDeletedSuccessors(activePred);
  48.499 +            skipDeletedPredecessors(activeSucc);
  48.500 +
  48.501 +            // Try to gc-unlink, if possible
  48.502 +            if ((isFirst | isLast) &&
  48.503 +
  48.504 +                // Recheck expected state of predecessor and successor
  48.505 +                (activePred.next == activeSucc) &&
  48.506 +                (activeSucc.prev == activePred) &&
  48.507 +                (isFirst ? activePred.prev == null : activePred.item != null) &&
  48.508 +                (isLast  ? activeSucc.next == null : activeSucc.item != null)) {
  48.509 +
  48.510 +                updateHead(); // Ensure x is not reachable from head
  48.511 +                updateTail(); // Ensure x is not reachable from tail
  48.512 +
  48.513 +                // Finally, actually gc-unlink
  48.514 +                x.lazySetPrev(isFirst ? prevTerminator() : x);
  48.515 +                x.lazySetNext(isLast  ? nextTerminator() : x);
  48.516 +            }
  48.517 +        }
  48.518 +    }
  48.519 +
  48.520 +    /**
  48.521 +     * Unlinks non-null first node.
  48.522 +     */
  48.523 +    private void unlinkFirst(Node<E> first, Node<E> next) {
  48.524 +        // assert first != null;
  48.525 +        // assert next != null;
  48.526 +        // assert first.item == null;
  48.527 +        for (Node<E> o = null, p = next, q;;) {
  48.528 +            if (p.item != null || (q = p.next) == null) {
  48.529 +                if (o != null && p.prev != p && first.casNext(next, p)) {
  48.530 +                    skipDeletedPredecessors(p);
  48.531 +                    if (first.prev == null &&
  48.532 +                        (p.next == null || p.item != null) &&
  48.533 +                        p.prev == first) {
  48.534 +
  48.535 +                        updateHead(); // Ensure o is not reachable from head
  48.536 +                        updateTail(); // Ensure o is not reachable from tail
  48.537 +
  48.538 +                        // Finally, actually gc-unlink
  48.539 +                        o.lazySetNext(o);
  48.540 +                        o.lazySetPrev(prevTerminator());
  48.541 +                    }
  48.542 +                }
  48.543 +                return;
  48.544 +            }
  48.545 +            else if (p == q)
  48.546 +                return;
  48.547 +            else {
  48.548 +                o = p;
  48.549 +                p = q;
  48.550 +            }
  48.551 +        }
  48.552 +    }
  48.553 +
  48.554 +    /**
  48.555 +     * Unlinks non-null last node.
  48.556 +     */
  48.557 +    private void unlinkLast(Node<E> last, Node<E> prev) {
  48.558 +        // assert last != null;
  48.559 +        // assert prev != null;
  48.560 +        // assert last.item == null;
  48.561 +        for (Node<E> o = null, p = prev, q;;) {
  48.562 +            if (p.item != null || (q = p.prev) == null) {
  48.563 +                if (o != null && p.next != p && last.casPrev(prev, p)) {
  48.564 +                    skipDeletedSuccessors(p);
  48.565 +                    if (last.next == null &&
  48.566 +                        (p.prev == null || p.item != null) &&
  48.567 +                        p.next == last) {
  48.568 +
  48.569 +                        updateHead(); // Ensure o is not reachable from head
  48.570 +                        updateTail(); // Ensure o is not reachable from tail
  48.571 +
  48.572 +                        // Finally, actually gc-unlink
  48.573 +                        o.lazySetPrev(o);
  48.574 +                        o.lazySetNext(nextTerminator());
  48.575 +                    }
  48.576 +                }
  48.577 +                return;
  48.578 +            }
  48.579 +            else if (p == q)
  48.580 +                return;
  48.581 +            else {
  48.582 +                o = p;
  48.583 +                p = q;
  48.584 +            }
  48.585 +        }
  48.586 +    }
  48.587 +
  48.588 +    /**
  48.589 +     * Guarantees that any node which was unlinked before a call to
  48.590 +     * this method will be unreachable from head after it returns.
  48.591 +     * Does not guarantee to eliminate slack, only that head will
  48.592 +     * point to a node that was active while this method was running.
  48.593 +     */
  48.594 +    private final void updateHead() {
  48.595 +        // Either head already points to an active node, or we keep
  48.596 +        // trying to cas it to the first node until it does.
  48.597 +        Node<E> h, p, q;
  48.598 +        restartFromHead:
  48.599 +        while ((h = head).item == null && (p = h.prev) != null) {
  48.600 +            for (;;) {
  48.601 +                if ((q = p.prev) == null ||
  48.602 +                    (q = (p = q).prev) == null) {
  48.603 +                    // It is possible that p is PREV_TERMINATOR,
  48.604 +                    // but if so, the CAS is guaranteed to fail.
  48.605 +                    if (casHead(h, p))
  48.606 +                        return;
  48.607 +                    else
  48.608 +                        continue restartFromHead;
  48.609 +                }
  48.610 +                else if (h != head)
  48.611 +                    continue restartFromHead;
  48.612 +                else
  48.613 +                    p = q;
  48.614 +            }
  48.615 +        }
  48.616 +    }
  48.617 +
  48.618 +    /**
  48.619 +     * Guarantees that any node which was unlinked before a call to
  48.620 +     * this method will be unreachable from tail after it returns.
  48.621 +     * Does not guarantee to eliminate slack, only that tail will
  48.622 +     * point to a node that was active while this method was running.
  48.623 +     */
  48.624 +    private final void updateTail() {
  48.625 +        // Either tail already points to an active node, or we keep
  48.626 +        // trying to cas it to the last node until it does.
  48.627 +        Node<E> t, p, q;
  48.628 +        restartFromTail:
  48.629 +        while ((t = tail).item == null && (p = t.next) != null) {
  48.630 +            for (;;) {
  48.631 +                if ((q = p.next) == null ||
  48.632 +                    (q = (p = q).next) == null) {
  48.633 +                    // It is possible that p is NEXT_TERMINATOR,
  48.634 +                    // but if so, the CAS is guaranteed to fail.
  48.635 +                    if (casTail(t, p))
  48.636 +                        return;
  48.637 +                    else
  48.638 +                        continue restartFromTail;
  48.639 +                }
  48.640 +                else if (t != tail)
  48.641 +                    continue restartFromTail;
  48.642 +                else
  48.643 +                    p = q;
  48.644 +            }
  48.645 +        }
  48.646 +    }
  48.647 +
  48.648 +    private void skipDeletedPredecessors(Node<E> x) {
  48.649 +        whileActive:
  48.650 +        do {
  48.651 +            Node<E> prev = x.prev;
  48.652 +            // assert prev != null;
  48.653 +            // assert x != NEXT_TERMINATOR;
  48.654 +            // assert x != PREV_TERMINATOR;
  48.655 +            Node<E> p = prev;
  48.656 +            findActive:
  48.657 +            for (;;) {
  48.658 +                if (p.item != null)
  48.659 +                    break findActive;
  48.660 +                Node<E> q = p.prev;
  48.661 +                if (q == null) {
  48.662 +                    if (p.next == p)
  48.663 +                        continue whileActive;
  48.664 +                    break findActive;
  48.665 +                }
  48.666 +                else if (p == q)
  48.667 +                    continue whileActive;
  48.668 +                else
  48.669 +                    p = q;
  48.670 +            }
  48.671 +
  48.672 +            // found active CAS target
  48.673 +            if (prev == p || x.casPrev(prev, p))
  48.674 +                return;
  48.675 +
  48.676 +        } while (x.item != null || x.next == null);
  48.677 +    }
  48.678 +
  48.679 +    private void skipDeletedSuccessors(Node<E> x) {
  48.680 +        whileActive:
  48.681 +        do {
  48.682 +            Node<E> next = x.next;
  48.683 +            // assert next != null;
  48.684 +            // assert x != NEXT_TERMINATOR;
  48.685 +            // assert x != PREV_TERMINATOR;
  48.686 +            Node<E> p = next;
  48.687 +            findActive:
  48.688 +            for (;;) {
  48.689 +                if (p.item != null)
  48.690 +                    break findActive;
  48.691 +                Node<E> q = p.next;
  48.692 +                if (q == null) {
  48.693 +                    if (p.prev == p)
  48.694 +                        continue whileActive;
  48.695 +                    break findActive;
  48.696 +                }
  48.697 +                else if (p == q)
  48.698 +                    continue whileActive;
  48.699 +                else
  48.700 +                    p = q;
  48.701 +            }
  48.702 +
  48.703 +            // found active CAS target
  48.704 +            if (next == p || x.casNext(next, p))
  48.705 +                return;
  48.706 +
  48.707 +        } while (x.item != null || x.prev == null);
  48.708 +    }
  48.709 +
  48.710 +    /**
  48.711 +     * Returns the successor of p, or the first node if p.next has been
  48.712 +     * linked to self, which will only be true if traversing with a
  48.713 +     * stale pointer that is now off the list.
  48.714 +     */
  48.715 +    final Node<E> succ(Node<E> p) {
  48.716 +        // TODO: should we skip deleted nodes here?
  48.717 +        Node<E> q = p.next;
  48.718 +        return (p == q) ? first() : q;
  48.719 +    }
  48.720 +
  48.721 +    /**
  48.722 +     * Returns the predecessor of p, or the last node if p.prev has been
  48.723 +     * linked to self, which will only be true if traversing with a
  48.724 +     * stale pointer that is now off the list.
  48.725 +     */
  48.726 +    final Node<E> pred(Node<E> p) {
  48.727 +        Node<E> q = p.prev;
  48.728 +        return (p == q) ? last() : q;
  48.729 +    }
  48.730 +
  48.731 +    /**
  48.732 +     * Returns the first node, the unique node p for which:
  48.733 +     *     p.prev == null && p.next != p
  48.734 +     * The returned node may or may not be logically deleted.
  48.735 +     * Guarantees that head is set to the returned node.
  48.736 +     */
  48.737 +    Node<E> first() {
  48.738 +        restartFromHead:
  48.739 +        for (;;)
  48.740 +            for (Node<E> h = head, p = h, q;;) {
  48.741 +                if ((q = p.prev) != null &&
  48.742 +                    (q = (p = q).prev) != null)
  48.743 +                    // Check for head updates every other hop.
  48.744 +                    // If p == q, we are sure to follow head instead.
  48.745 +                    p = (h != (h = head)) ? h : q;
  48.746 +                else if (p == h
  48.747 +                         // It is possible that p is PREV_TERMINATOR,
  48.748 +                         // but if so, the CAS is guaranteed to fail.
  48.749 +                         || casHead(h, p))
  48.750 +                    return p;
  48.751 +                else
  48.752 +                    continue restartFromHead;
  48.753 +            }
  48.754 +    }
  48.755 +
  48.756 +    /**
  48.757 +     * Returns the last node, the unique node p for which:
  48.758 +     *     p.next == null && p.prev != p
  48.759 +     * The returned node may or may not be logically deleted.
  48.760 +     * Guarantees that tail is set to the returned node.
  48.761 +     */
  48.762 +    Node<E> last() {
  48.763 +        restartFromTail:
  48.764 +        for (;;)
  48.765 +            for (Node<E> t = tail, p = t, q;;) {
  48.766 +                if ((q = p.next) != null &&
  48.767 +                    (q = (p = q).next) != null)
  48.768 +                    // Check for tail updates every other hop.
  48.769 +                    // If p == q, we are sure to follow tail instead.
  48.770 +                    p = (t != (t = tail)) ? t : q;
  48.771 +                else if (p == t
  48.772 +                         // It is possible that p is NEXT_TERMINATOR,
  48.773 +                         // but if so, the CAS is guaranteed to fail.
  48.774 +                         || casTail(t, p))
  48.775 +                    return p;
  48.776 +                else
  48.777 +                    continue restartFromTail;
  48.778 +            }
  48.779 +    }
  48.780 +
  48.781 +    // Minor convenience utilities
  48.782 +
  48.783 +    /**
  48.784 +     * Throws NullPointerException if argument is null.
  48.785 +     *
  48.786 +     * @param v the element
  48.787 +     */
  48.788 +    private static void checkNotNull(Object v) {
  48.789 +        if (v == null)
  48.790 +            throw new NullPointerException();
  48.791 +    }
  48.792 +
  48.793 +    /**
  48.794 +     * Returns element unless it is null, in which case throws
  48.795 +     * NoSuchElementException.
  48.796 +     *
  48.797 +     * @param v the element
  48.798 +     * @return the element
  48.799 +     */
  48.800 +    private E screenNullResult(E v) {
  48.801 +        if (v == null)
  48.802 +            throw new NoSuchElementException();
  48.803 +        return v;
  48.804 +    }
  48.805 +
  48.806 +    /**
  48.807 +     * Creates an array list and fills it with elements of this list.
  48.808 +     * Used by toArray.
  48.809 +     *
  48.810 +     * @return the arrayList
  48.811 +     */
  48.812 +    private ArrayList<E> toArrayList() {
  48.813 +        ArrayList<E> list = new ArrayList<E>();
  48.814 +        for (Node<E> p = first(); p != null; p = succ(p)) {
  48.815 +            E item = p.item;
  48.816 +            if (item != null)
  48.817 +                list.add(item);
  48.818 +        }
  48.819 +        return list;
  48.820 +    }
  48.821 +
  48.822 +    /**
  48.823 +     * Constructs an empty deque.
  48.824 +     */
  48.825 +    public ConcurrentLinkedDeque() {
  48.826 +        head = tail = new Node<E>(null);
  48.827 +    }
  48.828 +
  48.829 +    /**
  48.830 +     * Constructs a deque initially containing the elements of
  48.831 +     * the given collection, added in traversal order of the
  48.832 +     * collection's iterator.
  48.833 +     *
  48.834 +     * @param c the collection of elements to initially contain
  48.835 +     * @throws NullPointerException if the specified collection or any
  48.836 +     *         of its elements are null
  48.837 +     */
  48.838 +    public ConcurrentLinkedDeque(Collection<? extends E> c) {
  48.839 +        // Copy c into a private chain of Nodes
  48.840 +        Node<E> h = null, t = null;
  48.841 +        for (E e : c) {
  48.842 +            checkNotNull(e);
  48.843 +            Node<E> newNode = new Node<E>(e);
  48.844 +            if (h == null)
  48.845 +                h = t = newNode;
  48.846 +            else {
  48.847 +                t.lazySetNext(newNode);
  48.848 +                newNode.lazySetPrev(t);
  48.849 +                t = newNode;
  48.850 +            }
  48.851 +        }
  48.852 +        initHeadTail(h, t);
  48.853 +    }
  48.854 +
  48.855 +    /**
  48.856 +     * Initializes head and tail, ensuring invariants hold.
  48.857 +     */
  48.858 +    private void initHeadTail(Node<E> h, Node<E> t) {
  48.859 +        if (h == t) {
  48.860 +            if (h == null)
  48.861 +                h = t = new Node<E>(null);
  48.862 +            else {
  48.863 +                // Avoid edge case of a single Node with non-null item.
  48.864 +                Node<E> newNode = new Node<E>(null);
  48.865 +                t.lazySetNext(newNode);
  48.866 +                newNode.lazySetPrev(t);
  48.867 +                t = newNode;
  48.868 +            }
  48.869 +        }
  48.870 +        head = h;
  48.871 +        tail = t;
  48.872 +    }
  48.873 +
  48.874 +    /**
  48.875 +     * Inserts the specified element at the front of this deque.
  48.876 +     *
  48.877 +     * @throws NullPointerException {@inheritDoc}
  48.878 +     */
  48.879 +    public void addFirst(E e) {
  48.880 +        linkFirst(e);
  48.881 +    }
  48.882 +
  48.883 +    /**
  48.884 +     * Inserts the specified element at the end of this deque.
  48.885 +     *
  48.886 +     * <p>This method is equivalent to {@link #add}.
  48.887 +     *
  48.888 +     * @throws NullPointerException {@inheritDoc}
  48.889 +     */
  48.890 +    public void addLast(E e) {
  48.891 +        linkLast(e);
  48.892 +    }
  48.893 +
  48.894 +    /**
  48.895 +     * Inserts the specified element at the front of this deque.
  48.896 +     *
  48.897 +     * @return {@code true} always
  48.898 +     * @throws NullPointerException {@inheritDoc}
  48.899 +     */
  48.900 +    public boolean offerFirst(E e) {
  48.901 +        linkFirst(e);
  48.902 +        return true;
  48.903 +    }
  48.904 +
  48.905 +    /**
  48.906 +     * Inserts the specified element at the end of this deque.
  48.907 +     *
  48.908 +     * <p>This method is equivalent to {@link #add}.
  48.909 +     *
  48.910 +     * @return {@code true} always
  48.911 +     * @throws NullPointerException {@inheritDoc}
  48.912 +     */
  48.913 +    public boolean offerLast(E e) {
  48.914 +        linkLast(e);
  48.915 +        return true;
  48.916 +    }
  48.917 +
  48.918 +    public E peekFirst() {
  48.919 +        for (Node<E> p = first(); p != null; p = succ(p)) {
  48.920 +            E item = p.item;
  48.921 +            if (item != null)
  48.922 +                return item;
  48.923 +        }
  48.924 +        return null;
  48.925 +    }
  48.926 +
  48.927 +    public E peekLast() {
  48.928 +        for (Node<E> p = last(); p != null; p = pred(p)) {
  48.929 +            E item = p.item;
  48.930 +            if (item != null)
  48.931 +                return item;
  48.932 +        }
  48.933 +        return null;
  48.934 +    }
  48.935 +
  48.936 +    /**
  48.937 +     * @throws NoSuchElementException {@inheritDoc}
  48.938 +     */
  48.939 +    public E getFirst() {
  48.940 +        return screenNullResult(peekFirst());
  48.941 +    }
  48.942 +
  48.943 +    /**
  48.944 +     * @throws NoSuchElementException {@inheritDoc}
  48.945 +     */
  48.946 +    public E getLast()  {
  48.947 +        return screenNullResult(peekLast());
  48.948 +    }
  48.949 +
  48.950 +    public E pollFirst() {
  48.951 +        for (Node<E> p = first(); p != null; p = succ(p)) {
  48.952 +            E item = p.item;
  48.953 +            if (item != null && p.casItem(item, null)) {
  48.954 +                unlink(p);
  48.955 +                return item;
  48.956 +            }
  48.957 +        }
  48.958 +        return null;
  48.959 +    }
  48.960 +
  48.961 +    public E pollLast() {
  48.962 +        for (Node<E> p = last(); p != null; p = pred(p)) {
  48.963 +            E item = p.item;
  48.964 +            if (item != null && p.casItem(item, null)) {
  48.965 +                unlink(p);
  48.966 +                return item;
  48.967 +            }
  48.968 +        }
  48.969 +        return null;
  48.970 +    }
  48.971 +
  48.972 +    /**
  48.973 +     * @throws NoSuchElementException {@inheritDoc}
  48.974 +     */
  48.975 +    public E removeFirst() {
  48.976 +        return screenNullResult(pollFirst());
  48.977 +    }
  48.978 +
  48.979 +    /**
  48.980 +     * @throws NoSuchElementException {@inheritDoc}
  48.981 +     */
  48.982 +    public E removeLast() {
  48.983 +        return screenNullResult(pollLast());
  48.984 +    }
  48.985 +
  48.986 +    // *** Queue and stack methods ***
  48.987 +
  48.988 +    /**
  48.989 +     * Inserts the specified element at the tail of this deque.
  48.990 +     *
  48.991 +     * @return {@code true} (as specified by {@link Queue#offer})
  48.992 +     * @throws NullPointerException if the specified element is null
  48.993 +     */
  48.994 +    public boolean offer(E e) {
  48.995 +        return offerLast(e);
  48.996 +    }
  48.997 +
  48.998 +    /**
  48.999 +     * Inserts the specified element at the tail of this deque.
 48.1000 +     *
 48.1001 +     * @return {@code true} (as specified by {@link Collection#add})
 48.1002 +     * @throws NullPointerException if the specified element is null
 48.1003 +     */
 48.1004 +    public boolean add(E e) {
 48.1005 +        return offerLast(e);
 48.1006 +    }
 48.1007 +
 48.1008 +    public E poll()           { return pollFirst(); }
 48.1009 +    public E remove()         { return removeFirst(); }
 48.1010 +    public E peek()           { return peekFirst(); }
 48.1011 +    public E element()        { return getFirst(); }
 48.1012 +    public void push(E e)     { addFirst(e); }
 48.1013 +    public E pop()            { return removeFirst(); }
 48.1014 +
 48.1015 +    /**
 48.1016 +     * Removes the first element {@code e} such that
 48.1017 +     * {@code o.equals(e)}, if such an element exists in this deque.
 48.1018 +     * If the deque does not contain the element, it is unchanged.
 48.1019 +     *
 48.1020 +     * @param o element to be removed from this deque, if present
 48.1021 +     * @return {@code true} if the deque contained the specified element
 48.1022 +     * @throws NullPointerException if the specified element is {@code null}
 48.1023 +     */
 48.1024 +    public boolean removeFirstOccurrence(Object o) {
 48.1025 +        checkNotNull(o);
 48.1026 +        for (Node<E> p = first(); p != null; p = succ(p)) {
 48.1027 +            E item = p.item;
 48.1028 +            if (item != null && o.equals(item) && p.casItem(item, null)) {
 48.1029 +                unlink(p);
 48.1030 +                return true;
 48.1031 +            }
 48.1032 +        }
 48.1033 +        return false;
 48.1034 +    }
 48.1035 +
 48.1036 +    /**
 48.1037 +     * Removes the last element {@code e} such that
 48.1038 +     * {@code o.equals(e)}, if such an element exists in this deque.
 48.1039 +     * If the deque does not contain the element, it is unchanged.
 48.1040 +     *
 48.1041 +     * @param o element to be removed from this deque, if present
 48.1042 +     * @return {@code true} if the deque contained the specified element
 48.1043 +     * @throws NullPointerException if the specified element is {@code null}
 48.1044 +     */
 48.1045 +    public boolean removeLastOccurrence(Object o) {
 48.1046 +        checkNotNull(o);
 48.1047 +        for (Node<E> p = last(); p != null; p = pred(p)) {
 48.1048 +            E item = p.item;
 48.1049 +            if (item != null && o.equals(item) && p.casItem(item, null)) {
 48.1050 +                unlink(p);
 48.1051 +                return true;
 48.1052 +            }
 48.1053 +        }
 48.1054 +        return false;
 48.1055 +    }
 48.1056 +
 48.1057 +    /**
 48.1058 +     * Returns {@code true} if this deque contains at least one
 48.1059 +     * element {@code e} such that {@code o.equals(e)}.
 48.1060 +     *
 48.1061 +     * @param o element whose presence in this deque is to be tested
 48.1062 +     * @return {@code true} if this deque contains the specified element
 48.1063 +     */
 48.1064 +    public boolean contains(Object o) {
 48.1065 +        if (o == null) return false;
 48.1066 +        for (Node<E> p = first(); p != null; p = succ(p)) {
 48.1067 +            E item = p.item;
 48.1068 +            if (item != null && o.equals(item))
 48.1069 +                return true;
 48.1070 +        }
 48.1071 +        return false;
 48.1072 +    }
 48.1073 +
 48.1074 +    /**
 48.1075 +     * Returns {@code true} if this collection contains no elements.
 48.1076 +     *
 48.1077 +     * @return {@code true} if this collection contains no elements
 48.1078 +     */
 48.1079 +    public boolean isEmpty() {
 48.1080 +        return peekFirst() == null;
 48.1081 +    }
 48.1082 +
 48.1083 +    /**
 48.1084 +     * Returns the number of elements in this deque.  If this deque
 48.1085 +     * contains more than {@code Integer.MAX_VALUE} elements, it
 48.1086 +     * returns {@code Integer.MAX_VALUE}.
 48.1087 +     *
 48.1088 +     * <p>Beware that, unlike in most collections, this method is
 48.1089 +     * <em>NOT</em> a constant-time operation. Because of the
 48.1090 +     * asynchronous nature of these deques, determining the current
 48.1091 +     * number of elements requires traversing them all to count them.
 48.1092 +     * Additionally, it is possible for the size to change during
 48.1093 +     * execution of this method, in which case the returned result
 48.1094 +     * will be inaccurate. Thus, this method is typically not very
 48.1095 +     * useful in concurrent applications.
 48.1096 +     *
 48.1097 +     * @return the number of elements in this deque
 48.1098 +     */
 48.1099 +    public int size() {
 48.1100 +        int count = 0;
 48.1101 +        for (Node<E> p = first(); p != null; p = succ(p))
 48.1102 +            if (p.item != null)
 48.1103 +                // Collection.size() spec says to max out
 48.1104 +                if (++count == Integer.MAX_VALUE)
 48.1105 +                    break;
 48.1106 +        return count;
 48.1107 +    }
 48.1108 +
 48.1109 +    /**
 48.1110 +     * Removes the first element {@code e} such that
 48.1111 +     * {@code o.equals(e)}, if such an element exists in this deque.
 48.1112 +     * If the deque does not contain the element, it is unchanged.
 48.1113 +     *
 48.1114 +     * @param o element to be removed from this deque, if present
 48.1115 +     * @return {@code true} if the deque contained the specified element
 48.1116 +     * @throws NullPointerException if the specified element is {@code null}
 48.1117 +     */
 48.1118 +    public boolean remove(Object o) {
 48.1119 +        return removeFirstOccurrence(o);
 48.1120 +    }
 48.1121 +
 48.1122 +    /**
 48.1123 +     * Appends all of the elements in the specified collection to the end of
 48.1124 +     * this deque, in the order that they are returned by the specified
 48.1125 +     * collection's iterator.  Attempts to {@code addAll} of a deque to
 48.1126 +     * itself result in {@code IllegalArgumentException}.
 48.1127 +     *
 48.1128 +     * @param c the elements to be inserted into this deque
 48.1129 +     * @return {@code true} if this deque changed as a result of the call
 48.1130 +     * @throws NullPointerException if the specified collection or any
 48.1131 +     *         of its elements are null
 48.1132 +     * @throws IllegalArgumentException if the collection is this deque
 48.1133 +     */
 48.1134 +    public boolean addAll(Collection<? extends E> c) {
 48.1135 +        if (c == this)
 48.1136 +            // As historically specified in AbstractQueue#addAll
 48.1137 +            throw new IllegalArgumentException();
 48.1138 +
 48.1139 +        // Copy c into a private chain of Nodes
 48.1140 +        Node<E> beginningOfTheEnd = null, last = null;
 48.1141 +        for (E e : c) {
 48.1142 +            checkNotNull(e);
 48.1143 +            Node<E> newNode = new Node<E>(e);
 48.1144 +            if (beginningOfTheEnd == null)
 48.1145 +                beginningOfTheEnd = last = newNode;
 48.1146 +            else {
 48.1147 +                last.lazySetNext(newNode);
 48.1148 +                newNode.lazySetPrev(last);
 48.1149 +                last = newNode;
 48.1150 +            }
 48.1151 +        }
 48.1152 +        if (beginningOfTheEnd == null)
 48.1153 +            return false;
 48.1154 +
 48.1155 +        // Atomically append the chain at the tail of this collection
 48.1156 +        restartFromTail:
 48.1157 +        for (;;)
 48.1158 +            for (Node<E> t = tail, p = t, q;;) {
 48.1159 +                if ((q = p.next) != null &&
 48.1160 +                    (q = (p = q).next) != null)
 48.1161 +                    // Check for tail updates every other hop.
 48.1162 +                    // If p == q, we are sure to follow tail instead.
 48.1163 +                    p = (t != (t = tail)) ? t : q;
 48.1164 +                else if (p.prev == p) // NEXT_TERMINATOR
 48.1165 +                    continue restartFromTail;
 48.1166 +                else {
 48.1167 +                    // p is last node
 48.1168 +                    beginningOfTheEnd.lazySetPrev(p); // CAS piggyback
 48.1169 +                    if (p.casNext(null, beginningOfTheEnd)) {
 48.1170 +                        // Successful CAS is the linearization point
 48.1171 +                        // for all elements to be added to this queue.
 48.1172 +                        if (!casTail(t, last)) {
 48.1173 +                            // Try a little harder to update tail,
 48.1174 +                            // since we may be adding many elements.
 48.1175 +                            t = tail;
 48.1176 +                            if (last.next == null)
 48.1177 +                                casTail(t, last);
 48.1178 +                        }
 48.1179 +                        return true;
 48.1180 +                    }
 48.1181 +                    // Lost CAS race to another thread; re-read next
 48.1182 +                }
 48.1183 +            }
 48.1184 +    }
 48.1185 +
 48.1186 +    /**
 48.1187 +     * Removes all of the elements from this deque.
 48.1188 +     */
 48.1189 +    public void clear() {
 48.1190 +        while (pollFirst() != null)
 48.1191 +            ;
 48.1192 +    }
 48.1193 +
 48.1194 +    /**
 48.1195 +     * Returns an array containing all of the elements in this deque, in
 48.1196 +     * proper sequence (from first to last element).
 48.1197 +     *
 48.1198 +     * <p>The returned array will be "safe" in that no references to it are
 48.1199 +     * maintained by this deque.  (In other words, this method must allocate
 48.1200 +     * a new array).  The caller is thus free to modify the returned array.
 48.1201 +     *
 48.1202 +     * <p>This method acts as bridge between array-based and collection-based
 48.1203 +     * APIs.
 48.1204 +     *
 48.1205 +     * @return an array containing all of the elements in this deque
 48.1206 +     */
 48.1207 +    public Object[] toArray() {
 48.1208 +        return toArrayList().toArray();
 48.1209 +    }
 48.1210 +
 48.1211 +    /**
 48.1212 +     * Returns an array containing all of the elements in this deque,
 48.1213 +     * in proper sequence (from first to last element); the runtime
 48.1214 +     * type of the returned array is that of the specified array.  If
 48.1215 +     * the deque fits in the specified array, it is returned therein.
 48.1216 +     * Otherwise, a new array is allocated with the runtime type of
 48.1217 +     * the specified array and the size of this deque.
 48.1218 +     *
 48.1219 +     * <p>If this deque fits in the specified array with room to spare
 48.1220 +     * (i.e., the array has more elements than this deque), the element in
 48.1221 +     * the array immediately following the end of the deque is set to
 48.1222 +     * {@code null}.
 48.1223 +     *
 48.1224 +     * <p>Like the {@link #toArray()} method, this method acts as
 48.1225 +     * bridge between array-based and collection-based APIs.  Further,
 48.1226 +     * this method allows precise control over the runtime type of the
 48.1227 +     * output array, and may, under certain circumstances, be used to
 48.1228 +     * save allocation costs.
 48.1229 +     *
 48.1230 +     * <p>Suppose {@code x} is a deque known to contain only strings.
 48.1231 +     * The following code can be used to dump the deque into a newly
 48.1232 +     * allocated array of {@code String}:
 48.1233 +     *
 48.1234 +     * <pre>
 48.1235 +     *     String[] y = x.toArray(new String[0]);</pre>
 48.1236 +     *
 48.1237 +     * Note that {@code toArray(new Object[0])} is identical in function to
 48.1238 +     * {@code toArray()}.
 48.1239 +     *
 48.1240 +     * @param a the array into which the elements of the deque are to
 48.1241 +     *          be stored, if it is big enough; otherwise, a new array of the
 48.1242 +     *          same runtime type is allocated for this purpose
 48.1243 +     * @return an array containing all of the elements in this deque
 48.1244 +     * @throws ArrayStoreException if the runtime type of the specified array
 48.1245 +     *         is not a supertype of the runtime type of every element in
 48.1246 +     *         this deque
 48.1247 +     * @throws NullPointerException if the specified array is null
 48.1248 +     */
 48.1249 +    public <T> T[] toArray(T[] a) {
 48.1250 +        return toArrayList().toArray(a);
 48.1251 +    }
 48.1252 +
 48.1253 +    /**
 48.1254 +     * Returns an iterator over the elements in this deque in proper sequence.
 48.1255 +     * The elements will be returned in order from first (head) to last (tail).
 48.1256 +     *
 48.1257 +     * <p>The returned {@code Iterator} is a "weakly consistent" iterator that
 48.1258 +     * will never throw {@link java.util.ConcurrentModificationException
 48.1259 +     * ConcurrentModificationException},
 48.1260 +     * and guarantees to traverse elements as they existed upon
 48.1261 +     * construction of the iterator, and may (but is not guaranteed to)
 48.1262 +     * reflect any modifications subsequent to construction.
 48.1263 +     *
 48.1264 +     * @return an iterator over the elements in this deque in proper sequence
 48.1265 +     */
 48.1266 +    public Iterator<E> iterator() {
 48.1267 +        return new Itr();
 48.1268 +    }
 48.1269 +
 48.1270 +    /**
 48.1271 +     * Returns an iterator over the elements in this deque in reverse
 48.1272 +     * sequential order.  The elements will be returned in order from
 48.1273 +     * last (tail) to first (head).
 48.1274 +     *
 48.1275 +     * <p>The returned {@code Iterator} is a "weakly consistent" iterator that
 48.1276 +     * will never throw {@link java.util.ConcurrentModificationException
 48.1277 +     * ConcurrentModificationException},
 48.1278 +     * and guarantees to traverse elements as they existed upon
 48.1279 +     * construction of the iterator, and may (but is not guaranteed to)
 48.1280 +     * reflect any modifications subsequent to construction.
 48.1281 +     *
 48.1282 +     * @return an iterator over the elements in this deque in reverse order
 48.1283 +     */
 48.1284 +    public Iterator<E> descendingIterator() {
 48.1285 +        return new DescendingItr();
 48.1286 +    }
 48.1287 +
 48.1288 +    private abstract class AbstractItr implements Iterator<E> {
 48.1289 +        /**
 48.1290 +         * Next node to return item for.
 48.1291 +         */
 48.1292 +        private Node<E> nextNode;
 48.1293 +
 48.1294 +        /**
 48.1295 +         * nextItem holds on to item fields because once we claim
 48.1296 +         * that an element exists in hasNext(), we must return it in
 48.1297 +         * the following next() call even if it was in the process of
 48.1298 +         * being removed when hasNext() was called.
 48.1299 +         */
 48.1300 +        private E nextItem;
 48.1301 +
 48.1302 +        /**
 48.1303 +         * Node returned by most recent call to next. Needed by remove.
 48.1304 +         * Reset to null if this element is deleted by a call to remove.
 48.1305 +         */
 48.1306 +        private Node<E> lastRet;
 48.1307 +
 48.1308 +        abstract Node<E> startNode();
 48.1309 +        abstract Node<E> nextNode(Node<E> p);
 48.1310 +
 48.1311 +        AbstractItr() {
 48.1312 +            advance();
 48.1313 +        }
 48.1314 +
 48.1315 +        /**
 48.1316 +         * Sets nextNode and nextItem to next valid node, or to null
 48.1317 +         * if no such.
 48.1318 +         */
 48.1319 +        private void advance() {
 48.1320 +            lastRet = nextNode;
 48.1321 +
 48.1322 +            Node<E> p = (nextNode == null) ? startNode() : nextNode(nextNode);
 48.1323 +            for (;; p = nextNode(p)) {
 48.1324 +                if (p == null) {
 48.1325 +                    // p might be active end or TERMINATOR node; both are OK
 48.1326 +                    nextNode = null;
 48.1327 +                    nextItem = null;
 48.1328 +                    break;
 48.1329 +                }
 48.1330 +                E item = p.item;
 48.1331 +                if (item != null) {
 48.1332 +                    nextNode = p;
 48.1333 +                    nextItem = item;
 48.1334 +                    break;
 48.1335 +                }
 48.1336 +            }
 48.1337 +        }
 48.1338 +
 48.1339 +        public boolean hasNext() {
 48.1340 +            return nextItem != null;
 48.1341 +        }
 48.1342 +
 48.1343 +        public E next() {
 48.1344 +            E item = nextItem;
 48.1345 +            if (item == null) throw new NoSuchElementException();
 48.1346 +            advance();
 48.1347 +            return item;
 48.1348 +        }
 48.1349 +
 48.1350 +        public void remove() {
 48.1351 +            Node<E> l = lastRet;
 48.1352 +            if (l == null) throw new IllegalStateException();
 48.1353 +            l.item = null;
 48.1354 +            unlink(l);
 48.1355 +            lastRet = null;
 48.1356 +        }
 48.1357 +    }
 48.1358 +
 48.1359 +    /** Forward iterator */
 48.1360 +    private class Itr extends AbstractItr {
 48.1361 +        Node<E> startNode() { return first(); }
 48.1362 +        Node<E> nextNode(Node<E> p) { return succ(p); }
 48.1363 +    }
 48.1364 +
 48.1365 +    /** Descending iterator */
 48.1366 +    private class DescendingItr extends AbstractItr {
 48.1367 +        Node<E> startNode() { return last(); }
 48.1368 +        Node<E> nextNode(Node<E> p) { return pred(p); }
 48.1369 +    }
 48.1370 +
 48.1371 +    /**
 48.1372 +     * Saves the state to a stream (that is, serializes it).
 48.1373 +     *
 48.1374 +     * @serialData All of the elements (each an {@code E}) in
 48.1375 +     * the proper order, followed by a null
 48.1376 +     * @param s the stream
 48.1377 +     */
 48.1378 +    private void writeObject(java.io.ObjectOutputStream s)
 48.1379 +        throws java.io.IOException {
 48.1380 +
 48.1381 +        // Write out any hidden stuff
 48.1382 +        s.defaultWriteObject();
 48.1383 +
 48.1384 +        // Write out all elements in the proper order.
 48.1385 +        for (Node<E> p = first(); p != null; p = succ(p)) {
 48.1386 +            E item = p.item;
 48.1387 +            if (item != null)
 48.1388 +                s.writeObject(item);
 48.1389 +        }
 48.1390 +
 48.1391 +        // Use trailing null as sentinel
 48.1392 +        s.writeObject(null);
 48.1393 +    }
 48.1394 +
 48.1395 +    /**
 48.1396 +     * Reconstitutes the instance from a stream (that is, deserializes it).
 48.1397 +     * @param s the stream
 48.1398 +     */
 48.1399 +    private void readObject(java.io.ObjectInputStream s)
 48.1400 +        throws java.io.IOException, ClassNotFoundException {
 48.1401 +        s.defaultReadObject();
 48.1402 +
 48.1403 +        // Read in elements until trailing null sentinel found
 48.1404 +        Node<E> h = null, t = null;
 48.1405 +        Object item;
 48.1406 +        while ((item = s.readObject()) != null) {
 48.1407 +            @SuppressWarnings("unchecked")
 48.1408 +            Node<E> newNode = new Node<E>((E) item);
 48.1409 +            if (h == null)
 48.1410 +                h = t = newNode;
 48.1411 +            else {
 48.1412 +                t.lazySetNext(newNode);
 48.1413 +                newNode.lazySetPrev(t);
 48.1414 +                t = newNode;
 48.1415 +            }
 48.1416 +        }
 48.1417 +        initHeadTail(h, t);
 48.1418 +    }
 48.1419 +
 48.1420 +    // Unsafe mechanics
 48.1421 +
 48.1422 +    private static final sun.misc.Unsafe UNSAFE =
 48.1423 +        sun.misc.Unsafe.getUnsafe();
 48.1424 +    private static final long headOffset =
 48.1425 +        objectFieldOffset(UNSAFE, "head", ConcurrentLinkedDeque.class);
 48.1426 +    private static final long tailOffset =
 48.1427 +        objectFieldOffset(UNSAFE, "tail", ConcurrentLinkedDeque.class);
 48.1428 +
 48.1429 +    private boolean casHead(Node<E> cmp, Node<E> val) {
 48.1430 +        return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
 48.1431 +    }
 48.1432 +
 48.1433 +    private boolean casTail(Node<E> cmp, Node<E> val) {
 48.1434 +        return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val);
 48.1435 +    }
 48.1436 +
 48.1437 +    static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
 48.1438 +                                  String field, Class<?> klazz) {
 48.1439 +        try {
 48.1440 +            return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
 48.1441 +        } catch (NoSuchFieldException e) {
 48.1442 +            // Convert Exception to corresponding Error
 48.1443 +            NoSuchFieldError error = new NoSuchFieldError(field);
 48.1444 +            error.initCause(e);
 48.1445 +            throw error;
 48.1446 +        }
 48.1447 +    }
 48.1448 +}
    49.1 --- a/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java	Tue Oct 12 13:34:59 2010 -0400
    49.2 +++ b/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java	Mon Oct 18 11:25:28 2010 -0400
    49.3 @@ -28,9 +28,9 @@
    49.4   * However, the following notice accompanied the original version of this
    49.5   * file:
    49.6   *
    49.7 - * Written by Doug Lea with assistance from members of JCP JSR-166
    49.8 - * Expert Group and released to the public domain, as explained at
    49.9 - * http://creativecommons.org/licenses/publicdomain
   49.10 + * Written by Doug Lea and Martin Buchholz with assistance from members of
   49.11 + * JCP JSR-166 Expert Group and released to the public domain, as explained
   49.12 + * at http://creativecommons.org/licenses/publicdomain
   49.13   */
   49.14  
   49.15  package java.util.concurrent;
   49.16 @@ -53,7 +53,8 @@
   49.17   * operations obtain elements at the head of the queue.
   49.18   * A {@code ConcurrentLinkedQueue} is an appropriate choice when
   49.19   * many threads will share access to a common collection.
   49.20 - * This queue does not permit {@code null} elements.
   49.21 + * Like most other concurrent collection implementations, this class
   49.22 + * does not permit the use of {@code null} elements.
   49.23   *
   49.24   * <p>This implementation employs an efficient &quot;wait-free&quot;
   49.25   * algorithm based on one described in <a
   49.26 @@ -61,14 +62,20 @@
   49.27   * Fast, and Practical Non-Blocking and Blocking Concurrent Queue
   49.28   * Algorithms</a> by Maged M. Michael and Michael L. Scott.
   49.29   *
   49.30 + * <p>Iterators are <i>weakly consistent</i>, returning elements
   49.31 + * reflecting the state of the queue at some point at or since the
   49.32 + * creation of the iterator.  They do <em>not</em> throw {@link
   49.33 + * ConcurrentModificationException}, and may proceed concurrently with
   49.34 + * other operations.  Elements contained in the queue since the creation
   49.35 + * of the iterator will be returned exactly once.
   49.36 + *
   49.37   * <p>Beware that, unlike in most collections, the {@code size} method
   49.38   * is <em>NOT</em> a constant-time operation. Because of the
   49.39   * asynchronous nature of these queues, determining the current number
   49.40   * of elements requires a traversal of the elements.
   49.41   *
   49.42 - * <p>This class and its iterator implement all of the
   49.43 - * <em>optional</em> methods of the {@link Collection} and {@link
   49.44 - * Iterator} interfaces.
   49.45 + * <p>This class and its iterator implement all of the <em>optional</em>
   49.46 + * methods of the {@link Queue} and {@link Iterator} interfaces.
   49.47   *
   49.48   * <p>Memory consistency effects: As with other concurrent
   49.49   * collections, actions in a thread prior to placing an object into a
   49.50 @@ -132,9 +139,10 @@
   49.51       *
   49.52       * Both head and tail are permitted to lag.  In fact, failing to
   49.53       * update them every time one could is a significant optimization
   49.54 -     * (fewer CASes). This is controlled by local "hops" variables
   49.55 -     * that only trigger helping-CASes after experiencing multiple
   49.56 -     * lags.
   49.57 +     * (fewer CASes). As with LinkedTransferQueue (see the internal
   49.58 +     * documentation for that class), we use a slack threshold of two;
   49.59 +     * that is, we update head/tail when the current pointer appears
   49.60 +     * to be two or more steps away from the first/last node.
   49.61       *
   49.62       * Since head and tail are updated concurrently and independently,
   49.63       * it is possible for tail to lag behind head (why not)?
   49.64 @@ -148,8 +156,8 @@
   49.65       * this is merely an optimization.
   49.66       *
   49.67       * When constructing a Node (before enqueuing it) we avoid paying
   49.68 -     * for a volatile write to item by using lazySet instead of a
   49.69 -     * normal write.  This allows the cost of enqueue to be
   49.70 +     * for a volatile write to item by using Unsafe.putObject instead
   49.71 +     * of a normal write.  This allows the cost of enqueue to be
   49.72       * "one-and-a-half" CASes.
   49.73       *
   49.74       * Both head and tail may or may not point to a Node with a
   49.75 @@ -161,38 +169,25 @@
   49.76       */
   49.77  
   49.78      private static class Node<E> {
   49.79 -        private volatile E item;
   49.80 -        private volatile Node<E> next;
   49.81 +        volatile E item;
   49.82 +        volatile Node<E> next;
   49.83  
   49.84 +        /**
   49.85 +         * Constructs a new node.  Uses relaxed write because item can
   49.86 +         * only be seen after publication via casNext.
   49.87 +         */
   49.88          Node(E item) {
   49.89 -            // Piggyback on imminent casNext()
   49.90 -            lazySetItem(item);
   49.91 -        }
   49.92 -
   49.93 -        E getItem() {
   49.94 -            return item;
   49.95 +            UNSAFE.putObject(this, itemOffset, item);
   49.96          }
   49.97  
   49.98          boolean casItem(E cmp, E val) {
   49.99              return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
  49.100          }
  49.101  
  49.102 -        void setItem(E val) {
  49.103 -            item = val;
  49.104 -        }
  49.105 -
  49.106 -        void lazySetItem(E val) {
  49.107 -            UNSAFE.putOrderedObject(this, itemOffset, val);
  49.108 -        }
  49.109 -
  49.110          void lazySetNext(Node<E> val) {
  49.111              UNSAFE.putOrderedObject(this, nextOffset, val);
  49.112          }
  49.113  
  49.114 -        Node<E> getNext() {
  49.115 -            return next;
  49.116 -        }
  49.117 -
  49.118          boolean casNext(Node<E> cmp, Node<E> val) {
  49.119              return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
  49.120          }
  49.121 @@ -219,7 +214,7 @@
  49.122       * - it is permitted for tail to lag behind head, that is, for tail
  49.123       *   to not be reachable from head!
  49.124       */
  49.125 -    private transient volatile Node<E> head = new Node<E>(null);
  49.126 +    private transient volatile Node<E> head;
  49.127  
  49.128      /**
  49.129       * A node from which the last node on list (that is, the unique
  49.130 @@ -233,25 +228,41 @@
  49.131       *   to not be reachable from head!
  49.132       * - tail.next may or may not be self-pointing to tail.
  49.133       */
  49.134 -    private transient volatile Node<E> tail = head;
  49.135 +    private transient volatile Node<E> tail;
  49.136  
  49.137  
  49.138      /**
  49.139       * Creates a {@code ConcurrentLinkedQueue} that is initially empty.
  49.140       */
  49.141 -    public ConcurrentLinkedQueue() {}
  49.142 +    public ConcurrentLinkedQueue() {
  49.143 +        head = tail = new Node<E>(null);
  49.144 +    }
  49.145  
  49.146      /**
  49.147       * Creates a {@code ConcurrentLinkedQueue}
  49.148       * initially containing the elements of the given collection,
  49.149       * added in traversal order of the collection's iterator.
  49.150 +     *
  49.151       * @param c the collection of elements to initially contain
  49.152       * @throws NullPointerException if the specified collection or any
  49.153       *         of its elements are null
  49.154       */
  49.155      public ConcurrentLinkedQueue(Collection<? extends E> c) {
  49.156 -        for (E e : c)
  49.157 -            add(e);
  49.158 +        Node<E> h = null, t = null;
  49.159 +        for (E e : c) {
  49.160 +            checkNotNull(e);
  49.161 +            Node<E> newNode = new Node<E>(e);
  49.162 +            if (h == null)
  49.163 +                h = t = newNode;
  49.164 +            else {
  49.165 +                t.lazySetNext(newNode);
  49.166 +                t = newNode;
  49.167 +            }
  49.168 +        }
  49.169 +        if (h == null)
  49.170 +            h = t = new Node<E>(null);
  49.171 +        head = h;
  49.172 +        tail = t;
  49.173      }
  49.174  
  49.175      // Have to override just to update the javadoc
  49.176 @@ -267,13 +278,6 @@
  49.177      }
  49.178  
  49.179      /**
  49.180 -     * We don't bother to update head or tail pointers if fewer than
  49.181 -     * HOPS links from "true" location.  We assume that volatile
  49.182 -     * writes are significantly more expensive than volatile reads.
  49.183 -     */
  49.184 -    private static final int HOPS = 1;
  49.185 -
  49.186 -    /**
  49.187       * Try to CAS head to p. If successful, repoint old head to itself
  49.188       * as sentinel for succ(), below.
  49.189       */
  49.190 @@ -288,7 +292,7 @@
  49.191       * stale pointer that is now off the list.
  49.192       */
  49.193      final Node<E> succ(Node<E> p) {
  49.194 -        Node<E> next = p.getNext();
  49.195 +        Node<E> next = p.next;
  49.196          return (p == next) ? head : next;
  49.197      }
  49.198  
  49.199 @@ -299,68 +303,75 @@
  49.200       * @throws NullPointerException if the specified element is null
  49.201       */
  49.202      public boolean offer(E e) {
  49.203 -        if (e == null) throw new NullPointerException();
  49.204 -        Node<E> n = new Node<E>(e);
  49.205 -        retry:
  49.206 +        checkNotNull(e);
  49.207 +        final Node<E> newNode = new Node<E>(e);
  49.208 +
  49.209 +        for (Node<E> t = tail, p = t;;) {
  49.210 +            Node<E> q = p.next;
  49.211 +            if (q == null) {
  49.212 +                // p is last node
  49.213 +                if (p.casNext(null, newNode)) {
  49.214 +                    // Successful CAS is the linearization point
  49.215 +                    // for e to become an element of this queue,
  49.216 +                    // and for newNode to become "live".
  49.217 +                    if (p != t) // hop two nodes at a time
  49.218 +                        casTail(t, newNode);  // Failure is OK.
  49.219 +                    return true;
  49.220 +                }
  49.221 +                // Lost CAS race to another thread; re-read next
  49.222 +            }
  49.223 +            else if (p == q)
  49.224 +                // We have fallen off list.  If tail is unchanged, it
  49.225 +                // will also be off-list, in which case we need to
  49.226 +                // jump to head, from which all live nodes are always
  49.227 +                // reachable.  Else the new tail is a better bet.
  49.228 +                p = (t != (t = tail)) ? t : head;
  49.229 +            else
  49.230 +                // Check for tail updates after two hops.
  49.231 +                p = (p != t && t != (t = tail)) ? t : q;
  49.232 +        }
  49.233 +    }
  49.234 +
  49.235 +    public E poll() {
  49.236 +        restartFromHead:
  49.237          for (;;) {
  49.238 -            Node<E> t = tail;
  49.239 -            Node<E> p = t;
  49.240 -            for (int hops = 0; ; hops++) {
  49.241 -                Node<E> next = succ(p);
  49.242 -                if (next != null) {
  49.243 -                    if (hops > HOPS && t != tail)
  49.244 -                        continue retry;
  49.245 -                    p = next;
  49.246 -                } else if (p.casNext(null, n)) {
  49.247 -                    if (hops >= HOPS)
  49.248 -                        casTail(t, n);  // Failure is OK.
  49.249 -                    return true;
  49.250 -                } else {
  49.251 -                    p = succ(p);
  49.252 +            for (Node<E> h = head, p = h, q;;) {
  49.253 +                E item = p.item;
  49.254 +
  49.255 +                if (item != null && p.casItem(item, null)) {
  49.256 +                    // Successful CAS is the linearization point
  49.257 +                    // for item to be removed from this queue.
  49.258 +                    if (p != h) // hop two nodes at a time
  49.259 +                        updateHead(h, ((q = p.next) != null) ? q : p);
  49.260 +                    return item;
  49.261                  }
  49.262 +                else if ((q = p.next) == null) {
  49.263 +                    updateHead(h, p);
  49.264 +                    return null;
  49.265 +                }
  49.266 +                else if (p == q)
  49.267 +                    continue restartFromHead;
  49.268 +                else
  49.269 +                    p = q;
  49.270              }
  49.271          }
  49.272      }
  49.273  
  49.274 -    public E poll() {
  49.275 -        Node<E> h = head;
  49.276 -        Node<E> p = h;
  49.277 -        for (int hops = 0; ; hops++) {
  49.278 -            E item = p.getItem();
  49.279 -
  49.280 -            if (item != null && p.casItem(item, null)) {
  49.281 -                if (hops >= HOPS) {
  49.282 -                    Node<E> q = p.getNext();
  49.283 -                    updateHead(h, (q != null) ? q : p);
  49.284 +    public E peek() {
  49.285 +        restartFromHead:
  49.286 +        for (;;) {
  49.287 +            for (Node<E> h = head, p = h, q;;) {
  49.288 +                E item = p.item;
  49.289 +                if (item != null || (q = p.next) == null) {
  49.290 +                    updateHead(h, p);
  49.291 +                    return item;
  49.292                  }
  49.293 -                return item;
  49.294 +                else if (p == q)
  49.295 +                    continue restartFromHead;
  49.296 +                else
  49.297 +                    p = q;
  49.298              }
  49.299 -            Node<E> next = succ(p);
  49.300 -            if (next == null) {
  49.301 -                updateHead(h, p);
  49.302 -                break;
  49.303 -            }
  49.304 -            p = next;
  49.305          }
  49.306 -        return null;
  49.307 -    }
  49.308 -
  49.309 -    public E peek() {
  49.310 -        Node<E> h = head;
  49.311 -        Node<E> p = h;
  49.312 -        E item;
  49.313 -        for (;;) {
  49.314 -            item = p.getItem();
  49.315 -            if (item != null)
  49.316 -                break;
  49.317 -            Node<E> next = succ(p);
  49.318 -            if (next == null) {
  49.319 -                break;
  49.320 -            }
  49.321 -            p = next;
  49.322 -        }
  49.323 -        updateHead(h, p);
  49.324 -        return item;
  49.325      }
  49.326  
  49.327      /**
  49.328 @@ -372,24 +383,20 @@
  49.329       * of losing a race to a concurrent poll().
  49.330       */
  49.331      Node<E> first() {
  49.332 -        Node<E> h = head;
  49.333 -        Node<E> p = h;
  49.334 -        Node<E> result;
  49.335 +        restartFromHead:
  49.336          for (;;) {
  49.337 -            E item = p.getItem();
  49.338 -            if (item != null) {
  49.339 -                result = p;
  49.340 -                break;
  49.341 +            for (Node<E> h = head, p = h, q;;) {
  49.342 +                boolean hasItem = (p.item != null);
  49.343 +                if (hasItem || (q = p.next) == null) {
  49.344 +                    updateHead(h, p);
  49.345 +                    return hasItem ? p : null;
  49.346 +                }
  49.347 +                else if (p == q)
  49.348 +                    continue restartFromHead;
  49.349 +                else
  49.350 +                    p = q;
  49.351              }
  49.352 -            Node<E> next = succ(p);
  49.353 -            if (next == null) {
  49.354 -                result = null;
  49.355 -                break;
  49.356 -            }
  49.357 -            p = next;
  49.358          }
  49.359 -        updateHead(h, p);
  49.360 -        return result;
  49.361      }
  49.362  
  49.363      /**
  49.364 @@ -410,18 +417,20 @@
  49.365       * <em>NOT</em> a constant-time operation. Because of the
  49.366       * asynchronous nature of these queues, determining the current
  49.367       * number of elements requires an O(n) traversal.
  49.368 +     * Additionally, if elements are added or removed during execution
  49.369 +     * of this method, the returned result may be inaccurate.  Thus,
  49.370 +     * this method is typically not very useful in concurrent
  49.371 +     * applications.
  49.372       *
  49.373       * @return the number of elements in this queue
  49.374       */
  49.375      public int size() {
  49.376          int count = 0;
  49.377 -        for (Node<E> p = first(); p != null; p = succ(p)) {
  49.378 -            if (p.getItem() != null) {
  49.379 -                // Collections.size() spec says to max out
  49.380 +        for (Node<E> p = first(); p != null; p = succ(p))
  49.381 +            if (p.item != null)
  49.382 +                // Collection.size() spec says to max out
  49.383                  if (++count == Integer.MAX_VALUE)
  49.384                      break;
  49.385 -            }
  49.386 -        }
  49.387          return count;
  49.388      }
  49.389  
  49.390 @@ -436,9 +445,8 @@
  49.391      public boolean contains(Object o) {
  49.392          if (o == null) return false;
  49.393          for (Node<E> p = first(); p != null; p = succ(p)) {
  49.394 -            E item = p.getItem();
  49.395 -            if (item != null &&
  49.396 -                o.equals(item))
  49.397 +            E item = p.item;
  49.398 +            if (item != null && o.equals(item))
  49.399                  return true;
  49.400          }
  49.401          return false;
  49.402 @@ -459,7 +467,7 @@
  49.403          if (o == null) return false;
  49.404          Node<E> pred = null;
  49.405          for (Node<E> p = first(); p != null; p = succ(p)) {
  49.406 -            E item = p.getItem();
  49.407 +            E item = p.item;
  49.408              if (item != null &&
  49.409                  o.equals(item) &&
  49.410                  p.casItem(item, null)) {
  49.411 @@ -474,6 +482,69 @@
  49.412      }
  49.413  
  49.414      /**
  49.415 +     * Appends all of the elements in the specified collection to the end of
  49.416 +     * this queue, in the order that they are returned by the specified
  49.417 +     * collection's iterator.  Attempts to {@code addAll} of a queue to
  49.418 +     * itself result in {@code IllegalArgumentException}.
  49.419 +     *
  49.420 +     * @param c the elements to be inserted into this queue
  49.421 +     * @return {@code true} if this queue changed as a result of the call
  49.422 +     * @throws NullPointerException if the specified collection or any
  49.423 +     *         of its elements are null
  49.424 +     * @throws IllegalArgumentException if the collection is this queue
  49.425 +     */
  49.426 +    public boolean addAll(Collection<? extends E> c) {
  49.427 +        if (c == this)
  49.428 +            // As historically specified in AbstractQueue#addAll
  49.429 +            throw new IllegalArgumentException();
  49.430 +
  49.431 +        // Copy c into a private chain of Nodes
  49.432 +        Node<E> beginningOfTheEnd = null, last = null;
  49.433 +        for (E e : c) {
  49.434 +            checkNotNull(e);
  49.435 +            Node<E> newNode = new Node<E>(e);
  49.436 +            if (beginningOfTheEnd == null)
  49.437 +                beginningOfTheEnd = last = newNode;
  49.438 +            else {
  49.439 +                last.lazySetNext(newNode);
  49.440 +                last = newNode;
  49.441 +            }
  49.442 +        }
  49.443 +        if (beginningOfTheEnd == null)
  49.444 +            return false;
  49.445 +
  49.446 +        // Atomically append the chain at the tail of this collection
  49.447 +        for (Node<E> t = tail, p = t;;) {
  49.448 +            Node<E> q = p.next;
  49.449 +            if (q == null) {
  49.450 +                // p is last node
  49.451 +                if (p.casNext(null, beginningOfTheEnd)) {
  49.452 +                    // Successful CAS is the linearization point
  49.453 +                    // for all elements to be added to this queue.
  49.454 +                    if (!casTail(t, last)) {
  49.455 +                        // Try a little harder to update tail,
  49.456 +                        // since we may be adding many elements.
  49.457 +                        t = tail;
  49.458 +                        if (last.next == null)
  49.459 +                            casTail(t, last);
  49.460 +                    }
  49.461 +                    return true;
  49.462 +                }
  49.463 +                // Lost CAS race to another thread; re-read next
  49.464 +            }
  49.465 +            else if (p == q)
  49.466 +                // We have fallen off list.  If tail is unchanged, it
  49.467 +                // will also be off-list, in which case we need to
  49.468 +                // jump to head, from which all live nodes are always
  49.469 +                // reachable.  Else the new tail is a better bet.
  49.470 +                p = (t != (t = tail)) ? t : head;
  49.471 +            else
  49.472 +                // Check for tail updates after two hops.
  49.473 +                p = (p != t && t != (t = tail)) ? t : q;
  49.474 +        }
  49.475 +    }
  49.476 +
  49.477 +    /**
  49.478       * Returns an array containing all of the elements in this queue, in
  49.479       * proper sequence.
  49.480       *
  49.481 @@ -490,7 +561,7 @@
  49.482          // Use ArrayList to deal with resizing.
  49.483          ArrayList<E> al = new ArrayList<E>();
  49.484          for (Node<E> p = first(); p != null; p = succ(p)) {
  49.485 -            E item = p.getItem();
  49.486 +            E item = p.item;
  49.487              if (item != null)
  49.488                  al.add(item);
  49.489          }
  49.490 @@ -539,7 +610,7 @@
  49.491          int k = 0;
  49.492          Node<E> p;
  49.493          for (p = first(); p != null && k < a.length; p = succ(p)) {
  49.494 -            E item = p.getItem();
  49.495 +            E item = p.item;
  49.496              if (item != null)
  49.497                  a[k++] = (T)item;
  49.498          }
  49.499 @@ -552,7 +623,7 @@
  49.500          // If won't fit, use ArrayList version
  49.501          ArrayList<E> al = new ArrayList<E>();
  49.502          for (Node<E> q = first(); q != null; q = succ(q)) {
  49.503 -            E item = q.getItem();
  49.504 +            E item = q.item;
  49.505              if (item != null)
  49.506                  al.add(item);
  49.507          }
  49.508 @@ -561,7 +632,9 @@
  49.509  
  49.510      /**
  49.511       * Returns an iterator over the elements in this queue in proper sequence.
  49.512 -     * The returned iterator is a "weakly consistent" iterator that
  49.513 +     * The elements will be returned in order from first (head) to last (tail).
  49.514 +     *
  49.515 +     * <p>The returned {@code Iterator} is a "weakly consistent" iterator that
  49.516       * will never throw {@link java.util.ConcurrentModificationException
  49.517       * ConcurrentModificationException},
  49.518       * and guarantees to traverse elements as they existed upon
  49.519 @@ -620,7 +693,7 @@
  49.520                      nextItem = null;
  49.521                      return x;
  49.522                  }
  49.523 -                E item = p.getItem();
  49.524 +                E item = p.item;
  49.525                  if (item != null) {
  49.526                      nextNode = p;
  49.527                      nextItem = item;
  49.528 @@ -648,13 +721,13 @@
  49.529              Node<E> l = lastRet;
  49.530              if (l == null) throw new IllegalStateException();
  49.531              // rely on a future traversal to relink.
  49.532 -            l.setItem(null);
  49.533 +            l.item = null;
  49.534              lastRet = null;
  49.535          }
  49.536      }
  49.537  
  49.538      /**
  49.539 -     * Save the state to a stream (that is, serialize it).
  49.540 +     * Saves the state to a stream (that is, serializes it).
  49.541       *
  49.542       * @serialData All of the elements (each an {@code E}) in
  49.543       * the proper order, followed by a null
  49.544 @@ -668,7 +741,7 @@
  49.545  
  49.546          // Write out all elements in the proper order.
  49.547          for (Node<E> p = first(); p != null; p = succ(p)) {
  49.548 -            Object item = p.getItem();
  49.549 +            Object item = p.item;
  49.550              if (item != null)
  49.551                  s.writeObject(item);
  49.552          }
  49.553 @@ -678,25 +751,40 @@
  49.554      }
  49.555  
  49.556      /**
  49.557 -     * Reconstitute the Queue instance from a stream (that is,
  49.558 -     * deserialize it).
  49.559 +     * Reconstitutes the instance from a stream (that is, deserializes it).
  49.560       * @param s the stream
  49.561       */
  49.562      private void readObject(java.io.ObjectInputStream s)
  49.563          throws java.io.IOException, ClassNotFoundException {
  49.564 -        // Read in capacity, and any hidden stuff
  49.565          s.defaultReadObject();
  49.566 -        head = new Node<E>(null);
  49.567 -        tail = head;
  49.568 -        // Read in all elements and place in queue
  49.569 -        for (;;) {
  49.570 +
  49.571 +        // Read in elements until trailing null sentinel found
  49.572 +        Node<E> h = null, t = null;
  49.573 +        Object item;
  49.574 +        while ((item = s.readObject()) != null) {
  49.575              @SuppressWarnings("unchecked")
  49.576 -            E item = (E)s.readObject();
  49.577 -            if (item == null)
  49.578 -                break;
  49.579 -            else
  49.580 -                offer(item);
  49.581 +            Node<E> newNode = new Node<E>((E) item);
  49.582 +            if (h == null)
  49.583 +                h = t = newNode;
  49.584 +            else {
  49.585 +                t.lazySetNext(newNode);
  49.586 +                t = newNode;
  49.587 +            }
  49.588          }
  49.589 +        if (h == null)
  49.590 +            h = t = new Node<E>(null);
  49.591 +        head = h;
  49.592 +        tail = t;
  49.593 +    }
  49.594 +
  49.595 +    /**
  49.596 +     * Throws NullPointerException if argument is null.
  49.597 +     *
  49.598 +     * @param v the element
  49.599 +     */
  49.600 +    private static void checkNotNull(Object v) {
  49.601 +        if (v == null)
  49.602 +            throw new NullPointerException();
  49.603      }
  49.604  
  49.605      // Unsafe mechanics
  49.606 @@ -715,10 +803,6 @@
  49.607          return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
  49.608      }
  49.609  
  49.610 -    private void lazySetHead(Node<E> val) {
  49.611 -        UNSAFE.putOrderedObject(this, headOffset, val);
  49.612 -    }
  49.613 -
  49.614      static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
  49.615                                    String field, Class<?> klazz) {
  49.616          try {
    50.1 --- a/src/share/classes/java/util/concurrent/ForkJoinPool.java	Tue Oct 12 13:34:59 2010 -0400
    50.2 +++ b/src/share/classes/java/util/concurrent/ForkJoinPool.java	Mon Oct 18 11:25:28 2010 -0400
    50.3 @@ -42,7 +42,6 @@
    50.4  import java.util.List;
    50.5  import java.util.concurrent.AbstractExecutorService;
    50.6  import java.util.concurrent.Callable;
    50.7 -import java.util.concurrent.CountDownLatch;
    50.8  import java.util.concurrent.ExecutorService;
    50.9  import java.util.concurrent.Future;
   50.10  import java.util.concurrent.RejectedExecutionException;
   50.11 @@ -823,15 +822,13 @@
   50.12                                     (workerCounts & RUNNING_COUNT_MASK) <= 1);
   50.13                  long startTime = untimed? 0 : System.nanoTime();
   50.14                  Thread.interrupted();         // clear/ignore interrupt
   50.15 -                if (eventCount != ec || w.runState != 0 ||
   50.16 -                    runState >= TERMINATING)  // recheck after clear
   50.17 -                    break;
   50.18 +                if (eventCount != ec || w.isTerminating())
   50.19 +                    break;                    // recheck after clear
   50.20                  if (untimed)
   50.21                      LockSupport.park(w);
   50.22                  else {
   50.23                      LockSupport.parkNanos(w, SHRINK_RATE_NANOS);
   50.24 -                    if (eventCount != ec || w.runState != 0 ||
   50.25 -                        runState >= TERMINATING)
   50.26 +                    if (eventCount != ec || w.isTerminating())
   50.27                          break;
   50.28                      if (System.nanoTime() - startTime >= SHRINK_RATE_NANOS)
   50.29                          tryShutdownUnusedWorker(ec);
   50.30 @@ -899,16 +896,23 @@
   50.31                       UNSAFE.compareAndSwapInt(this, workerCountsOffset, wc,
   50.32                                                wc + (ONE_RUNNING|ONE_TOTAL))) {
   50.33                  ForkJoinWorkerThread w = null;
   50.34 +                Throwable fail = null;
   50.35                  try {
   50.36                      w = factory.newThread(this);
   50.37 -                } finally { // adjust on null or exceptional factory return
   50.38 -                    if (w == null) {
   50.39 -                        decrementWorkerCounts(ONE_RUNNING, ONE_TOTAL);
   50.40 -                        tryTerminate(false); // handle failure during shutdown
   50.41 -                    }
   50.42 +                } catch (Throwable ex) {
   50.43 +                    fail = ex;
   50.44                  }
   50.45 -                if (w == null)
   50.46 +                if (w == null) { // null or exceptional factory return
   50.47 +                    decrementWorkerCounts(ONE_RUNNING, ONE_TOTAL);
   50.48 +                    tryTerminate(false); // handle failure during shutdown
   50.49 +                    // If originating from an external caller,
   50.50 +                    // propagate exception, else ignore
   50.51 +                    if (fail != null && runState < TERMINATING &&
   50.52 +                        !(Thread.currentThread() instanceof
   50.53 +                          ForkJoinWorkerThread))
   50.54 +                        UNSAFE.throwException(fail);
   50.55                      break;
   50.56 +                }
   50.57                  w.start(recordWorker(w), ueh);
   50.58                  if ((workerCounts >>> TOTAL_COUNT_SHIFT) >= pc) {
   50.59                      int c; // advance event count
   50.60 @@ -997,8 +1001,12 @@
   50.61          boolean active = w.active;
   50.62          boolean inactivate = false;
   50.63          int pc = parallelism;
   50.64 -        int rs;
   50.65 -        while (w.runState == 0 && (rs = runState) < TERMINATING) {
   50.66 +        while (w.runState == 0) {
   50.67 +            int rs = runState;
   50.68 +            if (rs >= TERMINATING) { // propagate shutdown
   50.69 +                w.shutdown();
   50.70 +                break;
   50.71 +            }
   50.72              if ((inactivate || (active && (rs & ACTIVE_COUNT_MASK) >= pc)) &&
   50.73                  UNSAFE.compareAndSwapInt(this, runStateOffset, rs, rs - 1))
   50.74                  inactivate = active = w.active = false;
   50.75 @@ -1126,6 +1134,7 @@
   50.76          return true;
   50.77      }
   50.78  
   50.79 +
   50.80      /**
   50.81       * Actions on transition to TERMINATING
   50.82       *
   50.83 @@ -1149,7 +1158,7 @@
   50.84                      if (passes > 0 && !w.isTerminated()) {
   50.85                          w.cancelTasks();
   50.86                          LockSupport.unpark(w);
   50.87 -                        if (passes > 1) {
   50.88 +                        if (passes > 1 && !w.isInterrupted()) {
   50.89                              try {
   50.90                                  w.interrupt();
   50.91                              } catch (SecurityException ignore) {
   50.92 @@ -1726,6 +1735,13 @@
   50.93      }
   50.94  
   50.95      /**
   50.96 +     * Returns true if terminating or terminated. Used by ForkJoinWorkerThread.
   50.97 +     */
   50.98 +    final boolean isAtLeastTerminating() {
   50.99 +        return runState >= TERMINATING;
  50.100 +    }
  50.101 +
  50.102 +    /**
  50.103       * Returns {@code true} if this pool has been shut down.
  50.104       *
  50.105       * @return {@code true} if this pool has been shut down
    51.1 --- a/src/share/classes/java/util/concurrent/ForkJoinTask.java	Tue Oct 12 13:34:59 2010 -0400
    51.2 +++ b/src/share/classes/java/util/concurrent/ForkJoinTask.java	Mon Oct 18 11:25:28 2010 -0400
    51.3 @@ -55,10 +55,10 @@
    51.4   * start other subtasks.  As indicated by the name of this class,
    51.5   * many programs using {@code ForkJoinTask} employ only methods
    51.6   * {@link #fork} and {@link #join}, or derivatives such as {@link
    51.7 - * #invokeAll}.  However, this class also provides a number of other
    51.8 - * methods that can come into play in advanced usages, as well as
    51.9 - * extension mechanics that allow support of new forms of fork/join
   51.10 - * processing.
   51.11 + * #invokeAll(ForkJoinTask...) invokeAll}.  However, this class also
   51.12 + * provides a number of other methods that can come into play in
   51.13 + * advanced usages, as well as extension mechanics that allow
   51.14 + * support of new forms of fork/join processing.
   51.15   *
   51.16   * <p>A {@code ForkJoinTask} is a lightweight form of {@link Future}.
   51.17   * The efficiency of {@code ForkJoinTask}s stems from a set of
   51.18 @@ -250,7 +250,7 @@
   51.19          int s;         // the odd construction reduces lock bias effects
   51.20          while ((s = status) >= 0) {
   51.21              try {
   51.22 -                synchronized(this) {
   51.23 +                synchronized (this) {
   51.24                      if (UNSAFE.compareAndSwapInt(this, statusOffset, s,SIGNAL))
   51.25                          wait();
   51.26                  }
   51.27 @@ -270,7 +270,7 @@
   51.28          int s;
   51.29          if ((s = status) >= 0) {
   51.30              try {
   51.31 -                synchronized(this) {
   51.32 +                synchronized (this) {
   51.33                      if (UNSAFE.compareAndSwapInt(this, statusOffset, s,SIGNAL))
   51.34                          wait(millis, 0);
   51.35                  }
   51.36 @@ -288,7 +288,7 @@
   51.37      private void externalAwaitDone() {
   51.38          int s;
   51.39          while ((s = status) >= 0) {
   51.40 -            synchronized(this) {
   51.41 +            synchronized (this) {
   51.42                  if (UNSAFE.compareAndSwapInt(this, statusOffset, s, SIGNAL)){
   51.43                      boolean interrupted = false;
   51.44                      while (status >= 0) {
   51.45 @@ -669,11 +669,34 @@
   51.46          setCompletion(NORMAL);
   51.47      }
   51.48  
   51.49 +    /**
   51.50 +     * Waits if necessary for the computation to complete, and then
   51.51 +     * retrieves its result.
   51.52 +     *
   51.53 +     * @return the computed result
   51.54 +     * @throws CancellationException if the computation was cancelled
   51.55 +     * @throws ExecutionException if the computation threw an
   51.56 +     * exception
   51.57 +     * @throws InterruptedException if the current thread is not a
   51.58 +     * member of a ForkJoinPool and was interrupted while waiting
   51.59 +     */
   51.60      public final V get() throws InterruptedException, ExecutionException {
   51.61 -        quietlyJoin();
   51.62 -        if (Thread.interrupted())
   51.63 -            throw new InterruptedException();
   51.64 -        int s = status;
   51.65 +        int s;
   51.66 +        if (Thread.currentThread() instanceof ForkJoinWorkerThread) {
   51.67 +            quietlyJoin();
   51.68 +            s = status;
   51.69 +        }
   51.70 +        else {
   51.71 +            while ((s = status) >= 0) {
   51.72 +                synchronized (this) { // interruptible form of awaitDone
   51.73 +                    if (UNSAFE.compareAndSwapInt(this, statusOffset,
   51.74 +                                                 s, SIGNAL)) {
   51.75 +                        while (status >= 0)
   51.76 +                            wait();
   51.77 +                    }
   51.78 +                }
   51.79 +            }
   51.80 +        }
   51.81          if (s < NORMAL) {
   51.82              Throwable ex;
   51.83              if (s == CANCELLED)
   51.84 @@ -684,6 +707,20 @@
   51.85          return getRawResult();
   51.86      }
   51.87  
   51.88 +    /**
   51.89 +     * Waits if necessary for at most the given time for the computation
   51.90 +     * to complete, and then retrieves its result, if available.
   51.91 +     *
   51.92 +     * @param timeout the maximum time to wait
   51.93 +     * @param unit the time unit of the timeout argument
   51.94 +     * @return the computed result
   51.95 +     * @throws CancellationException if the computation was cancelled
   51.96 +     * @throws ExecutionException if the computation threw an
   51.97 +     * exception
   51.98 +     * @throws InterruptedException if the current thread is not a
   51.99 +     * member of a ForkJoinPool and was interrupted while waiting
  51.100 +     * @throws TimeoutException if the wait timed out
  51.101 +     */
  51.102      public final V get(long timeout, TimeUnit unit)
  51.103          throws InterruptedException, ExecutionException, TimeoutException {
  51.104          Thread t = Thread.currentThread();
  51.105 @@ -725,7 +762,7 @@
  51.106                          long ms = nt / 1000000;
  51.107                          int ns = (int) (nt % 1000000);
  51.108                          try {
  51.109 -                            synchronized(this) {
  51.110 +                            synchronized (this) {
  51.111                                  if (status >= 0)
  51.112                                      wait(ms, ns);
  51.113                              }
    52.1 --- a/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java	Tue Oct 12 13:34:59 2010 -0400
    52.2 +++ b/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java	Mon Oct 18 11:25:28 2010 -0400
    52.3 @@ -778,11 +778,20 @@
    52.4  
    52.5      // status check methods used mainly by ForkJoinPool
    52.6      final boolean isRunning()     { return runState == 0; }
    52.7 -    final boolean isTerminating() { return (runState & TERMINATING) != 0; }
    52.8      final boolean isTerminated()  { return (runState & TERMINATED) != 0; }
    52.9      final boolean isSuspended()   { return (runState & SUSPENDED) != 0; }
   52.10      final boolean isTrimmed()     { return (runState & TRIMMED) != 0; }
   52.11  
   52.12 +    final boolean isTerminating() {
   52.13 +        if ((runState & TERMINATING) != 0)
   52.14 +            return true;
   52.15 +        if (pool.isAtLeastTerminating()) { // propagate pool state
   52.16 +            shutdown();
   52.17 +            return true;
   52.18 +        }
   52.19 +        return false;
   52.20 +    }
   52.21 +
   52.22      /**
   52.23       * Sets state to TERMINATING. Does NOT unpark or interrupt
   52.24       * to wake up if currently blocked. Callers must do so if desired.
    53.1 --- a/src/share/classes/java/util/concurrent/RecursiveAction.java	Tue Oct 12 13:34:59 2010 -0400
    53.2 +++ b/src/share/classes/java/util/concurrent/RecursiveAction.java	Mon Oct 18 11:25:28 2010 -0400
    53.3 @@ -138,7 +138,7 @@
    53.4   *        if (right.tryUnfork()) // directly calculate if not stolen
    53.5   *          sum += right.atLeaf(right.lo, right.hi);
    53.6   *       else {
    53.7 - *          right.helpJoin();
    53.8 + *          right.join();
    53.9   *          sum += right.result;
   53.10   *        }
   53.11   *        right = right.next;
    54.1 --- a/src/share/classes/java/util/logging/LogManager.java	Tue Oct 12 13:34:59 2010 -0400
    54.2 +++ b/src/share/classes/java/util/logging/LogManager.java	Mon Oct 18 11:25:28 2010 -0400
    54.3 @@ -690,6 +690,11 @@
    54.4       * Note that since untrusted code may create loggers with
    54.5       * arbitrary names this method should not be relied on to
    54.6       * find Loggers for security sensitive logging.
    54.7 +     * It is also important to note that the Logger associated with the
    54.8 +     * String {@code name} may be garbage collected at any time if there
    54.9 +     * is no strong reference to the Logger. The caller of this method
   54.10 +     * must check the return value for null in order to properly handle
   54.11 +     * the case where the Logger has been garbage collected.
   54.12       * <p>
   54.13       * @param name name of the logger
   54.14       * @return  matching logger or null if none is found
   54.15 @@ -713,6 +718,14 @@
   54.16       * <p>
   54.17       * Note:  Loggers may be added dynamically as new classes are loaded.
   54.18       * This method only reports on the loggers that are currently registered.
   54.19 +     * It is also important to note that this method only returns the name
   54.20 +     * of a Logger, not a strong reference to the Logger itself.
   54.21 +     * The returned String does nothing to prevent the Logger from being
   54.22 +     * garbage collected. In particular, if the returned name is passed
   54.23 +     * to {@code LogManager.getLogger()}, then the caller must check the
   54.24 +     * return value from {@code LogManager.getLogger()} for null to properly
   54.25 +     * handle the case where the Logger has been garbage collected in the
   54.26 +     * time since its name was returned by this method.
   54.27       * <p>
   54.28       * @return  enumeration of logger name strings
   54.29       */
    55.1 --- a/src/share/classes/java/util/logging/Logger.java	Tue Oct 12 13:34:59 2010 -0400
    55.2 +++ b/src/share/classes/java/util/logging/Logger.java	Mon Oct 18 11:25:28 2010 -0400
    55.3 @@ -42,7 +42,10 @@
    55.4   * <p>
    55.5   * Logger objects may be obtained by calls on one of the getLogger
    55.6   * factory methods.  These will either create a new Logger or
    55.7 - * return a suitable existing Logger.
    55.8 + * return a suitable existing Logger. It is important to note that
    55.9 + * the Logger returned by one of the {@code getLogger} factory methods
   55.10 + * may be garbage collected at any time if a strong reference to the
   55.11 + * Logger is not kept.
   55.12   * <p>
   55.13   * Logging messages will be forwarded to registered Handler
   55.14   * objects, which can forward the messages to a variety of
   55.15 @@ -210,7 +213,9 @@
   55.16       * who are making serious use of the logging package (for example
   55.17       * in products) should create and use their own Logger objects,
   55.18       * with appropriate names, so that logging can be controlled on a
   55.19 -     * suitable per-Logger granularity.
   55.20 +     * suitable per-Logger granularity. Developers also need to keep a
   55.21 +     * strong reference to their Logger objects to prevent them from
   55.22 +     * being garbage collected.
   55.23       * <p>
   55.24       * @deprecated Initialization of this field is prone to deadlocks.
   55.25       * The field must be initialized by the Logger class initialization
   55.26 @@ -287,6 +292,15 @@
   55.27       * based on the LogManager configuration and it will configured
   55.28       * to also send logging output to its parent's Handlers.  It will
   55.29       * be registered in the LogManager global namespace.
   55.30 +     * <p>
   55.31 +     * Note: The LogManager may only retain a weak reference to the newly
   55.32 +     * created Logger. It is important to understand that a previously
   55.33 +     * created Logger with the given name may be garbage collected at any
   55.34 +     * time if there is no strong reference to the Logger. In particular,
   55.35 +     * this means that two back-to-back calls like
   55.36 +     * {@code getLogger("MyLogger").log(...)} may use different Logger
   55.37 +     * objects named "MyLogger" if there is no strong reference to the
   55.38 +     * Logger named "MyLogger" elsewhere in the program.
   55.39       *
   55.40       * @param   name            A name for the logger.  This should
   55.41       *                          be a dot-separated name and should normally
   55.42 @@ -311,6 +325,15 @@
   55.43       * output to its parent's Handlers.  It will be registered in
   55.44       * the LogManager global namespace.
   55.45       * <p>
   55.46 +     * Note: The LogManager may only retain a weak reference to the newly
   55.47 +     * created Logger. It is important to understand that a previously
   55.48 +     * created Logger with the given name may be garbage collected at any
   55.49 +     * time if there is no strong reference to the Logger. In particular,
   55.50 +     * this means that two back-to-back calls like
   55.51 +     * {@code getLogger("MyLogger", ...).log(...)} may use different Logger
   55.52 +     * objects named "MyLogger" if there is no strong reference to the
   55.53 +     * Logger named "MyLogger" elsewhere in the program.
   55.54 +     * <p>
   55.55       * If the named Logger already exists and does not yet have a
   55.56       * localization resource bundle then the given resource bundle
   55.57       * name is used.  If the named Logger already exists and has
    56.1 --- a/src/share/classes/javax/sql/rowset/BaseRowSet.java	Tue Oct 12 13:34:59 2010 -0400
    56.2 +++ b/src/share/classes/javax/sql/rowset/BaseRowSet.java	Mon Oct 18 11:25:28 2010 -0400
    56.3 @@ -1,5 +1,5 @@
    56.4  /*
    56.5 - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
    56.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
    56.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    56.8   *
    56.9   * This code is free software; you can redistribute it and/or modify it
   56.10 @@ -734,7 +734,7 @@
   56.11                   throw new SQLException("Set initParams() before setCommand");
   56.12              }
   56.13              params.clear();
   56.14 -            command = new String(cmd);
   56.15 +            command = cmd;
   56.16          }
   56.17  
   56.18      }
   56.19 @@ -797,7 +797,7 @@
   56.20              throw new SQLException("Invalid url string detected. " +
   56.21              "Cannot be of length less than 1");
   56.22          } else {
   56.23 -            URL = new String(url);
   56.24 +            URL = url;
   56.25          }
   56.26  
   56.27          dataSource = null;
   56.28 @@ -854,7 +854,7 @@
   56.29          } else if (name.equals("")) {
   56.30             throw new SQLException("DataSource name cannot be empty string");
   56.31          } else {
   56.32 -           dataSource = new String(name);
   56.33 +           dataSource = name;
   56.34          }
   56.35  
   56.36          URL = null;
   56.37 @@ -889,7 +889,7 @@
   56.38          {
   56.39             username = null;
   56.40          } else {
   56.41 -           username = new String(name);
   56.42 +           username = name;
   56.43          }
   56.44      }
   56.45  
   56.46 @@ -924,7 +924,7 @@
   56.47          {
   56.48             password = null;
   56.49          } else {
   56.50 -           password = new String(pass);
   56.51 +           password = pass;
   56.52          }
   56.53      }
   56.54  
   56.55 @@ -1563,13 +1563,13 @@
   56.56  
   56.57          nullVal = new Object[2];
   56.58          nullVal[0] = null;
   56.59 -        nullVal[1] = new Integer(sqlType);
   56.60 +        nullVal[1] = Integer.valueOf(sqlType);
   56.61  
   56.62         if (params == null){
   56.63              throw new SQLException("Set initParams() before setNull");
   56.64         }
   56.65  
   56.66 -        params.put(new Integer(parameterIndex - 1), nullVal);
   56.67 +        params.put(Integer.valueOf(parameterIndex - 1), nullVal);
   56.68      }
   56.69  
   56.70      /**
   56.71 @@ -1644,14 +1644,14 @@
   56.72  
   56.73          nullVal = new Object[3];
   56.74          nullVal[0] = null;
   56.75 -        nullVal[1] = new Integer(sqlType);
   56.76 -        nullVal[2] = new String(typeName);
   56.77 +        nullVal[1] = Integer.valueOf(sqlType);
   56.78 +        nullVal[2] = typeName;
   56.79  
   56.80         if(params == null){
   56.81              throw new SQLException("Set initParams() before setNull");
   56.82         }
   56.83  
   56.84 -        params.put(new Integer(parameterIndex - 1), nullVal);
   56.85 +        params.put(Integer.valueOf(parameterIndex - 1), nullVal);
   56.86      }
   56.87  
   56.88  
   56.89 @@ -1686,7 +1686,7 @@
   56.90              throw new SQLException("Set initParams() before setNull");
   56.91         }
   56.92  
   56.93 -        params.put(new Integer(parameterIndex - 1), new Boolean(x));
   56.94 +        params.put(Integer.valueOf(parameterIndex - 1), Boolean.valueOf(x));
   56.95      }
   56.96  
   56.97      /**
   56.98 @@ -1720,7 +1720,7 @@
   56.99              throw new SQLException("Set initParams() before setByte");
  56.100         }
  56.101  
  56.102 -        params.put(new Integer(parameterIndex - 1), new Byte(x));
  56.103 +        params.put(Integer.valueOf(parameterIndex - 1), Byte.valueOf(x));
  56.104      }
  56.105  
  56.106      /**
  56.107 @@ -1754,7 +1754,7 @@
  56.108               throw new SQLException("Set initParams() before setShort");
  56.109          }
  56.110  
  56.111 -        params.put(new Integer(parameterIndex - 1), new Short(x));
  56.112 +        params.put(Integer.valueOf(parameterIndex - 1), Short.valueOf(x));
  56.113      }
  56.114  
  56.115      /**
  56.116 @@ -1786,7 +1786,7 @@
  56.117          if(params == null){
  56.118               throw new SQLException("Set initParams() before setInt");
  56.119          }
  56.120 -        params.put(new Integer(parameterIndex - 1), new Integer(x));
  56.121 +        params.put(Integer.valueOf(parameterIndex - 1), Integer.valueOf(x));
  56.122      }
  56.123  
  56.124      /**
  56.125 @@ -1818,7 +1818,7 @@
  56.126          if(params == null){
  56.127               throw new SQLException("Set initParams() before setLong");
  56.128          }
  56.129 -        params.put(new Integer(parameterIndex - 1), new Long(x));
  56.130 +        params.put(Integer.valueOf(parameterIndex - 1), Long.valueOf(x));
  56.131      }
  56.132  
  56.133      /**
  56.134 @@ -1850,7 +1850,7 @@
  56.135          if(params == null){
  56.136               throw new SQLException("Set initParams() before setFloat");
  56.137          }
  56.138 -        params.put(new Integer(parameterIndex - 1), new Float(x));
  56.139 +        params.put(Integer.valueOf(parameterIndex - 1), new Float(x));
  56.140      }
  56.141  
  56.142      /**
  56.143 @@ -1882,7 +1882,7 @@
  56.144          if(params == null){
  56.145               throw new SQLException("Set initParams() before setDouble");
  56.146          }
  56.147 -        params.put(new Integer(parameterIndex - 1), new Double(x));
  56.148 +        params.put(Integer.valueOf(parameterIndex - 1), new Double(x));
  56.149      }
  56.150  
  56.151      /**
  56.152 @@ -1914,7 +1914,7 @@
  56.153          if(params == null){
  56.154               throw new SQLException("Set initParams() before setBigDecimal");
  56.155          }
  56.156 -        params.put(new Integer(parameterIndex - 1), x);
  56.157 +        params.put(Integer.valueOf(parameterIndex - 1), x);
  56.158      }
  56.159  
  56.160      /**
  56.161 @@ -1948,7 +1948,7 @@
  56.162          if(params == null){
  56.163               throw new SQLException("Set initParams() before setString");
  56.164          }
  56.165 -        params.put(new Integer(parameterIndex - 1), x);
  56.166 +        params.put(Integer.valueOf(parameterIndex - 1), x);
  56.167      }
  56.168  
  56.169      /**
  56.170 @@ -1982,7 +1982,7 @@
  56.171          if(params == null){
  56.172               throw new SQLException("Set initParams() before setBytes");
  56.173          }
  56.174 -        params.put(new Integer(parameterIndex - 1), x);
  56.175 +        params.put(Integer.valueOf(parameterIndex - 1), x);
  56.176      }
  56.177  
  56.178      /**
  56.179 @@ -2024,7 +2024,7 @@
  56.180          if(params == null){
  56.181               throw new SQLException("Set initParams() before setDate");
  56.182          }
  56.183 -        params.put(new Integer(parameterIndex - 1), x);
  56.184 +        params.put(Integer.valueOf(parameterIndex - 1), x);
  56.185      }
  56.186  
  56.187      /**
  56.188 @@ -2069,7 +2069,7 @@
  56.189               throw new SQLException("Set initParams() before setTime");
  56.190          }
  56.191  
  56.192 -        params.put(new Integer(parameterIndex - 1), x);
  56.193 +        params.put(Integer.valueOf(parameterIndex - 1), x);
  56.194      }
  56.195  
  56.196      /**
  56.197 @@ -2112,7 +2112,7 @@
  56.198               throw new SQLException("Set initParams() before setTimestamp");
  56.199          }
  56.200  
  56.201 -        params.put(new Integer(parameterIndex - 1), x);
  56.202 +        params.put(Integer.valueOf(parameterIndex - 1), x);
  56.203      }
  56.204  
  56.205      /**
  56.206 @@ -2185,14 +2185,14 @@
  56.207  
  56.208          asciiStream = new Object[3];
  56.209          asciiStream[0] = x;
  56.210 -        asciiStream[1] = new Integer(length);
  56.211 -        asciiStream[2] = new Integer(ASCII_STREAM_PARAM);
  56.212 +        asciiStream[1] = Integer.valueOf(length);
  56.213 +        asciiStream[2] = Integer.valueOf(ASCII_STREAM_PARAM);
  56.214  
  56.215          if(params == null){
  56.216               throw new SQLException("Set initParams() before setAsciiStream");
  56.217          }
  56.218  
  56.219 -        params.put(new Integer(parameterIndex - 1), asciiStream);
  56.220 +        params.put(Integer.valueOf(parameterIndex - 1), asciiStream);
  56.221      }
  56.222  
  56.223    /**
  56.224 @@ -2290,13 +2290,13 @@
  56.225  
  56.226          binaryStream = new Object[3];
  56.227          binaryStream[0] = x;
  56.228 -        binaryStream[1] = new Integer(length);
  56.229 -        binaryStream[2] = new Integer(BINARY_STREAM_PARAM);
  56.230 +        binaryStream[1] = Integer.valueOf(length);
  56.231 +        binaryStream[2] = Integer.valueOf(BINARY_STREAM_PARAM);
  56.232          if(params == null){
  56.233               throw new SQLException("Set initParams() before setBinaryStream");
  56.234          }
  56.235  
  56.236 -        params.put(new Integer(parameterIndex - 1), binaryStream);
  56.237 +        params.put(Integer.valueOf(parameterIndex - 1), binaryStream);
  56.238      }
  56.239  
  56.240  
  56.241 @@ -2396,12 +2396,12 @@
  56.242  
  56.243          unicodeStream = new Object[3];
  56.244          unicodeStream[0] = x;
  56.245 -        unicodeStream[1] = new Integer(length);
  56.246 -        unicodeStream[2] = new Integer(UNICODE_STREAM_PARAM);
  56.247 +        unicodeStream[1] = Integer.valueOf(length);
  56.248 +        unicodeStream[2] = Integer.valueOf(UNICODE_STREAM_PARAM);
  56.249          if(params == null){
  56.250               throw new SQLException("Set initParams() before setUnicodeStream");
  56.251          }
  56.252 -        params.put(new Integer(parameterIndex - 1), unicodeStream);
  56.253 +        params.put(Integer.valueOf(parameterIndex - 1), unicodeStream);
  56.254      }
  56.255  
  56.256      /**
  56.257 @@ -2475,11 +2475,11 @@
  56.258  
  56.259          charStream = new Object[2];
  56.260          charStream[0] = reader;
  56.261 -        charStream[1] = new Integer(length);
  56.262 +        charStream[1] = Integer.valueOf(length);
  56.263          if(params == null){
  56.264               throw new SQLException("Set initParams() before setCharacterStream");
  56.265          }
  56.266 -        params.put(new Integer(parameterIndex - 1), charStream);
  56.267 +        params.put(Integer.valueOf(parameterIndex - 1), charStream);
  56.268      }
  56.269  
  56.270     /**
  56.271 @@ -2591,12 +2591,12 @@
  56.272  
  56.273          obj = new Object[3];
  56.274          obj[0] = x;
  56.275 -        obj[1] = new Integer(targetSqlType);
  56.276 -        obj[2] = new Integer(scale);
  56.277 +        obj[1] = Integer.valueOf(targetSqlType);
  56.278 +        obj[2] = Integer.valueOf(scale);
  56.279          if(params == null){
  56.280               throw new SQLException("Set initParams() before setObject");
  56.281          }
  56.282 -        params.put(new Integer(parameterIndex - 1), obj);
  56.283 +        params.put(Integer.valueOf(parameterIndex - 1), obj);
  56.284      }
  56.285  
  56.286      /**
  56.287 @@ -2654,11 +2654,11 @@
  56.288  
  56.289          obj = new Object[2];
  56.290          obj[0] = x;
  56.291 -        obj[1] = new Integer(targetSqlType);
  56.292 +        obj[1] = Integer.valueOf(targetSqlType);
  56.293          if (params == null){
  56.294               throw new SQLException("Set initParams() before setObject");
  56.295          }
  56.296 -        params.put(new Integer(parameterIndex - 1), obj);
  56.297 +        params.put(Integer.valueOf(parameterIndex - 1), obj);
  56.298      }
  56.299  
  56.300      /**
  56.301 @@ -2726,7 +2726,7 @@
  56.302          if (params == null) {
  56.303               throw new SQLException("Set initParams() before setObject");
  56.304          }
  56.305 -        params.put(new Integer(parameterIndex - 1), x);
  56.306 +        params.put(Integer.valueOf(parameterIndex - 1), x);
  56.307      }
  56.308  
  56.309      /**
  56.310 @@ -2773,7 +2773,7 @@
  56.311          if (params == null) {
  56.312               throw new SQLException("Set initParams() before setRef");
  56.313          }
  56.314 -        params.put(new Integer(parameterIndex - 1), new SerialRef(ref));
  56.315 +        params.put(Integer.valueOf(parameterIndex - 1), new SerialRef(ref));
  56.316      }
  56.317  
  56.318      /**
  56.319 @@ -2817,7 +2817,7 @@
  56.320          if(params == null){
  56.321               throw new SQLException("Set initParams() before setBlob");
  56.322          }
  56.323 -        params.put(new Integer(parameterIndex - 1), new SerialBlob(x));
  56.324 +        params.put(Integer.valueOf(parameterIndex - 1), new SerialBlob(x));
  56.325      }
  56.326  
  56.327      /**
  56.328 @@ -2862,7 +2862,7 @@
  56.329          if(params == null){
  56.330               throw new SQLException("Set initParams() before setClob");
  56.331          }
  56.332 -        params.put(new Integer(parameterIndex - 1), new SerialClob(x));
  56.333 +        params.put(Integer.valueOf(parameterIndex - 1), new SerialClob(x));
  56.334      }
  56.335  
  56.336      /**
  56.337 @@ -2910,7 +2910,7 @@
  56.338          if (params == null){
  56.339               throw new SQLException("Set initParams() before setArray");
  56.340          }
  56.341 -        params.put(new Integer(parameterIndex - 1), new SerialArray(array));
  56.342 +        params.put(Integer.valueOf(parameterIndex - 1), new SerialArray(array));
  56.343      }
  56.344  
  56.345      /**
  56.346 @@ -2975,7 +2975,7 @@
  56.347          if(params == null){
  56.348               throw new SQLException("Set initParams() before setDate");
  56.349          }
  56.350 -        params.put(new Integer(parameterIndex - 1), date);
  56.351 +        params.put(Integer.valueOf(parameterIndex - 1), date);
  56.352      }
  56.353  
  56.354      /**
  56.355 @@ -3041,7 +3041,7 @@
  56.356          if(params == null){
  56.357               throw new SQLException("Set initParams() before setTime");
  56.358          }
  56.359 -        params.put(new Integer(parameterIndex - 1), time);
  56.360 +        params.put(Integer.valueOf(parameterIndex - 1), time);
  56.361      }
  56.362  
  56.363      /**
  56.364 @@ -3107,7 +3107,7 @@
  56.365          if(params == null){
  56.366               throw new SQLException("Set initParams() before setTimestamp");
  56.367          }
  56.368 -        params.put(new Integer(parameterIndex - 1), timestamp);
  56.369 +        params.put(Integer.valueOf(parameterIndex - 1), timestamp);
  56.370      }
  56.371  
  56.372      /**
  56.373 @@ -3181,7 +3181,7 @@
  56.374  
  56.375              Object[] paramsArray = new Object[params.size()];
  56.376              for (int i = 0; i < params.size(); i++) {
  56.377 -               paramsArray[i] = params.get(new Integer(i));
  56.378 +               paramsArray[i] = params.get(Integer.valueOf(i));
  56.379                 if (paramsArray[i] == null) {
  56.380                   throw new SQLException("missing parameter: " + (i + 1));
  56.381                 } //end if
    57.1 --- a/src/share/classes/javax/sql/rowset/CachedRowSet.java	Tue Oct 12 13:34:59 2010 -0400
    57.2 +++ b/src/share/classes/javax/sql/rowset/CachedRowSet.java	Mon Oct 18 11:25:28 2010 -0400
    57.3 @@ -39,7 +39,7 @@
    57.4   * <code>CachedRowSet</code> must implement.
    57.5   * <P>
    57.6   * The reference implementation of the <code>CachedRowSet</code> interface provided
    57.7 - * by Sun Microsystems is a standard implementation. Developers may use this implementation
    57.8 + * by Oracle Corporation is a standard implementation. Developers may use this implementation
    57.9   * just as it is, they may extend it, or they may choose to write their own implementations
   57.10   * of this interface.
   57.11   * <P>
   57.12 @@ -1623,4 +1623,3 @@
   57.13      public boolean previousPage() throws SQLException;
   57.14  
   57.15  }
   57.16 -
    58.1 --- a/src/share/classes/javax/sql/rowset/RowSetMetaDataImpl.java	Tue Oct 12 13:34:59 2010 -0400
    58.2 +++ b/src/share/classes/javax/sql/rowset/RowSetMetaDataImpl.java	Mon Oct 18 11:25:28 2010 -0400
    58.3 @@ -1,5 +1,5 @@
    58.4  /*
    58.5 - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
    58.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
    58.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    58.8   *
    58.9   * This code is free software; you can redistribute it and/or modify it
   58.10 @@ -306,9 +306,9 @@
   58.11      public void setColumnLabel(int columnIndex, String label) throws SQLException {
   58.12          checkColRange(columnIndex);
   58.13          if (label != null) {
   58.14 -            colInfo[columnIndex].columnLabel = new String(label);
   58.15 +            colInfo[columnIndex].columnLabel = label;
   58.16          } else {
   58.17 -            colInfo[columnIndex].columnLabel = new String("");
   58.18 +            colInfo[columnIndex].columnLabel = "";
   58.19          }
   58.20      }
   58.21  
   58.22 @@ -326,9 +326,9 @@
   58.23      public void setColumnName(int columnIndex, String columnName) throws SQLException {
   58.24          checkColRange(columnIndex);
   58.25          if (columnName != null) {
   58.26 -            colInfo[columnIndex].columnName = new String(columnName);
   58.27 +            colInfo[columnIndex].columnName = columnName;
   58.28          } else {
   58.29 -            colInfo[columnIndex].columnName = new String("");
   58.30 +            colInfo[columnIndex].columnName = "";
   58.31          }
   58.32      }
   58.33  
   58.34 @@ -348,9 +348,9 @@
   58.35      public void setSchemaName(int columnIndex, String schemaName) throws SQLException {
   58.36          checkColRange(columnIndex);
   58.37          if (schemaName != null ) {
   58.38 -            colInfo[columnIndex].schemaName = new String(schemaName);
   58.39 +            colInfo[columnIndex].schemaName = schemaName;
   58.40          } else {
   58.41 -            colInfo[columnIndex].schemaName = new String("");
   58.42 +            colInfo[columnIndex].schemaName = "";
   58.43          }
   58.44      }
   58.45  
   58.46 @@ -411,9 +411,9 @@
   58.47      public void setTableName(int columnIndex, String tableName) throws SQLException {
   58.48          checkColRange(columnIndex);
   58.49          if (tableName != null) {
   58.50 -            colInfo[columnIndex].tableName = new String(tableName);
   58.51 +            colInfo[columnIndex].tableName = tableName;
   58.52          } else {
   58.53 -            colInfo[columnIndex].tableName = new String("");
   58.54 +            colInfo[columnIndex].tableName = "";
   58.55          }
   58.56      }
   58.57  
   58.58 @@ -432,9 +432,9 @@
   58.59      public void setCatalogName(int columnIndex, String catalogName) throws SQLException {
   58.60          checkColRange(columnIndex);
   58.61          if (catalogName != null)
   58.62 -            colInfo[columnIndex].catName = new String(catalogName);
   58.63 +            colInfo[columnIndex].catName = catalogName;
   58.64          else
   58.65 -            colInfo[columnIndex].catName = new String("");
   58.66 +            colInfo[columnIndex].catName = "";
   58.67      }
   58.68  
   58.69      /**
   58.70 @@ -474,9 +474,9 @@
   58.71          throws SQLException {
   58.72          checkColRange(columnIndex);
   58.73          if (typeName != null) {
   58.74 -            colInfo[columnIndex].colTypeName = new String(typeName);
   58.75 +            colInfo[columnIndex].colTypeName = typeName;
   58.76          } else {
   58.77 -            colInfo[columnIndex].colTypeName = new String("");
   58.78 +            colInfo[columnIndex].colTypeName = "";
   58.79          }
   58.80      }
   58.81  
   58.82 @@ -827,7 +827,7 @@
   58.83       *         or the given column number is out of bounds
   58.84       */
   58.85      public String getColumnClassName(int columnIndex) throws SQLException {
   58.86 -        String className = (new String()).getClass().getName();
   58.87 +        String className = String.class.getName();
   58.88  
   58.89          int sqlType = getColumnType(columnIndex);
   58.90  
   58.91 @@ -835,65 +835,62 @@
   58.92  
   58.93          case Types.NUMERIC:
   58.94          case Types.DECIMAL:
   58.95 -            className = (new java.math.BigDecimal(0)).getClass().getName ();
   58.96 +            className = java.math.BigDecimal.class.getName();
   58.97              break;
   58.98  
   58.99          case Types.BIT:
  58.100 -            className = (new Boolean(false)).getClass().getName ();
  58.101 +            className = java.lang.Boolean.class.getName();
  58.102              break;
  58.103  
  58.104          case Types.TINYINT:
  58.105 -            className = (new Byte("0")).getClass().getName ();
  58.106 +            className = java.lang.Byte.class.getName();
  58.107              break;
  58.108  
  58.109          case Types.SMALLINT:
  58.110 -            className = (new Short("0")).getClass().getName ();
  58.111 +            className = java.lang.Short.class.getName();
  58.112              break;
  58.113  
  58.114          case Types.INTEGER:
  58.115 -            className = (new Integer(0)).getClass().getName ();
  58.116 +            className = java.lang.Integer.class.getName();
  58.117              break;
  58.118  
  58.119          case Types.BIGINT:
  58.120 -            className = (new Long(0)).getClass().getName ();
  58.121 +            className = java.lang.Long.class.getName();
  58.122              break;
  58.123  
  58.124          case Types.REAL:
  58.125 -            className = (new Float(0)).getClass().getName ();
  58.126 +            className = java.lang.Float.class.getName();
  58.127              break;
  58.128  
  58.129          case Types.FLOAT:
  58.130          case Types.DOUBLE:
  58.131 -            className = (new Double(0)).getClass().getName();
  58.132 +            className = java.lang.Double.class.getName();
  58.133              break;
  58.134  
  58.135          case Types.BINARY:
  58.136          case Types.VARBINARY:
  58.137          case Types.LONGVARBINARY:
  58.138 -            byte[] b = {};
  58.139 -            className = (b.getClass()).getName();
  58.140 +            className = "byte[]";
  58.141              break;
  58.142  
  58.143          case Types.DATE:
  58.144 -            className = (new java.sql.Date(123456)).getClass().getName ();
  58.145 +            className = java.sql.Date.class.getName();
  58.146              break;
  58.147  
  58.148          case Types.TIME:
  58.149 -            className = (new java.sql.Time(123456)).getClass().getName ();
  58.150 +            className = java.sql.Time.class.getName();
  58.151              break;
  58.152  
  58.153          case Types.TIMESTAMP:
  58.154 -            className = (new java.sql.Timestamp(123456)).getClass().getName ();
  58.155 +            className = java.sql.Timestamp.class.getName();
  58.156              break;
  58.157  
  58.158          case Types.BLOB:
  58.159 -            byte[] blob = {};
  58.160 -            className = (blob.getClass()).getName();
  58.161 +            className = java.sql.Blob.class.getName();
  58.162              break;
  58.163  
  58.164          case Types.CLOB:
  58.165 -            char[] c = {};
  58.166 -            className = (c.getClass()).getName();
  58.167 +            className = java.sql.Clob.class.getName();
  58.168              break;
  58.169          }
  58.170  
    59.1 --- a/src/share/classes/javax/sql/rowset/RowSetProvider.java	Tue Oct 12 13:34:59 2010 -0400
    59.2 +++ b/src/share/classes/javax/sql/rowset/RowSetProvider.java	Mon Oct 18 11:25:28 2010 -0400
    59.3 @@ -29,7 +29,6 @@
    59.4  import java.security.PrivilegedAction;
    59.5  import java.sql.SQLException;
    59.6  import java.util.ServiceLoader;
    59.7 -import javax.sql.rowset.RowSetFactory;
    59.8  
    59.9  /**
   59.10   * A factory API that enables applications to obtain a
   59.11 @@ -82,15 +81,15 @@
   59.12       * the <code>RowSetFactory</code> implementation class to load:</p>
   59.13       * <ul>
   59.14       * <li>
   59.15 -     * The System property {@code javax.sql.rowset.RowsetFactory}.  For example:
   59.16 +     * The System property {@code javax.sql.rowset.RowSetFactory}.  For example:
   59.17       * <ul>
   59.18       * <li>
   59.19 -     * -Djavax.sql.rowset.RowsetFactory=com.sun.rowset.RowSetFactoryImpl
   59.20 +     * -Djavax.sql.rowset.RowSetFactory=com.sun.rowset.RowSetFactoryImpl
   59.21       * </li>
   59.22       * </ul>
   59.23       * <li>
   59.24 -     * The ServiceLocator API. The ServiceLocator API will look
   59.25 -     * for a classname in the file
   59.26 +     * The {@link ServiceLoader} API. The {@code ServiceLoader} API will look
   59.27 +     * for a class name in the file
   59.28       * {@code META-INF/services/javax.sql.rowset.RowSetFactory}
   59.29       * in jars available to the runtime. For example, to have the the RowSetFactory
   59.30       * implementation {@code com.sun.rowset.RowSetFactoryImpl } loaded, the
   59.31 @@ -271,7 +270,7 @@
   59.32      /**
   59.33       * Returns the requested System Property.  If a {@code SecurityException}
   59.34       * occurs, just return NULL
   59.35 -     * @param propName - System property to retreive
   59.36 +     * @param propName - System property to retrieve
   59.37       * @return The System property value or NULL if the property does not exist
   59.38       * or a {@code SecurityException} occurs.
   59.39       */
    60.1 --- a/src/share/classes/javax/sql/rowset/WebRowSet.java	Tue Oct 12 13:34:59 2010 -0400
    60.2 +++ b/src/share/classes/javax/sql/rowset/WebRowSet.java	Mon Oct 18 11:25:28 2010 -0400
    60.3 @@ -1,5 +1,5 @@
    60.4  /*
    60.5 - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
    60.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
    60.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    60.8   *
    60.9   * This code is free software; you can redistribute it and/or modify it
   60.10 @@ -115,7 +115,7 @@
   60.11   *      &lt;<font color=red>url</font>&gt;jdbc:thin:oracle&lt;<font color=red>/url</font>&gt;
   60.12   *      &lt;<font color=red>sync-provider</font>&gt;
   60.13   *              &lt;<font color=red>sync-provider-name</font>&gt;.com.rowset.provider.RIOptimisticProvider&lt;<font color=red>/sync-provider-name</font>&gt;
   60.14 - *              &lt;<font color=red>sync-provider-vendor</font>&gt;Sun Microsystems&lt;<font color=red>/sync-provider-vendor</font>&gt;
   60.15 + *              &lt;<font color=red>sync-provider-vendor</font>&gt;Oracle Corporation&lt;<font color=red>/sync-provider-vendor</font>&gt;
   60.16   *              &lt;<font color=red>sync-provider-version</font>&gt;1.0&lt;<font color=red>/sync-provider-name</font>&gt;
   60.17   *              &lt;<font color=red>sync-provider-grade</font>&gt;LOW&lt;<font color=red>/sync-provider-grade</font>&gt;
   60.18   *              &lt;<font color=red>data-source-lock</font>&gt;NONE&lt;<font color=red>/data-source-lock</font>&gt;
   60.19 @@ -489,7 +489,7 @@
   60.20       * tags and their valid values for a <code>WebRowSet</code> implementation.
   60.21       */
   60.22      public static String PUBLIC_XML_SCHEMA =
   60.23 -        "--//Sun Microsystems, Inc.//XSD Schema//EN";
   60.24 +        "--//Oracle Corporation//XSD Schema//EN";
   60.25  
   60.26      /**
   60.27       * The URL for the XML Schema definition file that defines the XML tags and
    61.1 --- a/src/share/classes/javax/sql/rowset/rowset.properties	Tue Oct 12 13:34:59 2010 -0400
    61.2 +++ b/src/share/classes/javax/sql/rowset/rowset.properties	Mon Oct 18 11:25:28 2010 -0400
    61.3 @@ -3,10 +3,10 @@
    61.4  
    61.5  # Optimistic synchonriztaion provider
    61.6  rowset.provider.classname.0=com.sun.rowset.providers.RIOptimisticProvider
    61.7 -rowset.provider.vendor.0=Sun Microsystems Inc
    61.8 +rowset.provider.vendor.0=Oracle Corporation
    61.9  rowset.provider.version.0=1.0
   61.10  
   61.11  # XML Provider using standard XML schema
   61.12  rowset.provider.classname.1=com.sun.rowset.providers.RIXMLProvider
   61.13 -rowset.provider.vendor.1=Sun Microsystems Inc.
   61.14 +rowset.provider.vendor.1=Oracle Corporation
   61.15  rowset.provider.version.1=1.0
    62.1 --- a/src/share/classes/javax/sql/rowset/serial/SQLOutputImpl.java	Tue Oct 12 13:34:59 2010 -0400
    62.2 +++ b/src/share/classes/javax/sql/rowset/serial/SQLOutputImpl.java	Mon Oct 18 11:25:28 2010 -0400
    62.3 @@ -1,5 +1,5 @@
    62.4  /*
    62.5 - * Copyright (c) 2003, 2006, 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 @@ -137,7 +137,7 @@
   62.11       *        values of a UDT to the database.
   62.12       */
   62.13      public void writeBoolean(boolean x) throws SQLException {
   62.14 -        attribs.add(new Boolean(x));
   62.15 +        attribs.add(Boolean.valueOf(x));
   62.16      }
   62.17  
   62.18      /**
   62.19 @@ -151,7 +151,7 @@
   62.20       *        values of a UDT to the database.
   62.21       */
   62.22      public void writeByte(byte x) throws SQLException {
   62.23 -        attribs.add(new Byte(x));
   62.24 +        attribs.add(Byte.valueOf(x));
   62.25      }
   62.26  
   62.27      /**
   62.28 @@ -165,7 +165,7 @@
   62.29       *        values of a UDT to the database.
   62.30       */
   62.31      public void writeShort(short x) throws SQLException {
   62.32 -        attribs.add(new Short(x));
   62.33 +        attribs.add(Short.valueOf(x));
   62.34      }
   62.35  
   62.36      /**
   62.37 @@ -179,7 +179,7 @@
   62.38       *        values of a UDT to the database.
   62.39       */
   62.40      public void writeInt(int x) throws SQLException {
   62.41 -        attribs.add(new Integer(x));
   62.42 +        attribs.add(Integer.valueOf(x));
   62.43      }
   62.44  
   62.45      /**
   62.46 @@ -193,7 +193,7 @@
   62.47       *        values of a UDT to the database.
   62.48       */
   62.49      public void writeLong(long x) throws SQLException {
   62.50 -        attribs.add(new Long(x));
   62.51 +        attribs.add(Long.valueOf(x));
   62.52      }
   62.53  
   62.54      /**
    63.1 --- a/src/share/classes/javax/sql/rowset/serial/SerialRef.java	Tue Oct 12 13:34:59 2010 -0400
    63.2 +++ b/src/share/classes/javax/sql/rowset/serial/SerialRef.java	Mon Oct 18 11:25:28 2010 -0400
    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 @@ -77,7 +77,7 @@
   63.11              throw new SQLException("Cannot instantiate a SerialRef object " +
   63.12                  "that returns a null base type name");
   63.13          } else {
   63.14 -            baseTypeName = new String(ref.getBaseTypeName());
   63.15 +            baseTypeName = ref.getBaseTypeName();
   63.16          }
   63.17      }
   63.18  
   63.19 @@ -110,7 +110,7 @@
   63.20          throws SerialException
   63.21      {
   63.22          map = new Hashtable(map);
   63.23 -        if (!object.equals(null)) {
   63.24 +        if (object != null) {
   63.25              return map.get(object);
   63.26          } else {
   63.27              throw new SerialException("The object is not set");
    64.1 --- a/src/share/classes/javax/sql/rowset/serial/SerialStruct.java	Tue Oct 12 13:34:59 2010 -0400
    64.2 +++ b/src/share/classes/javax/sql/rowset/serial/SerialStruct.java	Mon Oct 18 11:25:28 2010 -0400
    64.3 @@ -1,5 +1,5 @@
    64.4  /*
    64.5 - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
    64.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
    64.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    64.8   *
    64.9   * This code is free software; you can redistribute it and/or modify it
   64.10 @@ -94,7 +94,7 @@
   64.11          try {
   64.12  
   64.13          // get the type name
   64.14 -        SQLTypeName = new String(in.getSQLTypeName());
   64.15 +        SQLTypeName = in.getSQLTypeName();
   64.16          System.out.println("SQLTypeName: " + SQLTypeName);
   64.17  
   64.18          // get the attributes of the struct
   64.19 @@ -137,7 +137,7 @@
   64.20          try {
   64.21  
   64.22          //set the type name
   64.23 -        SQLTypeName = new String(in.getSQLTypeName());
   64.24 +        SQLTypeName = in.getSQLTypeName();
   64.25  
   64.26          Vector tmp = new Vector();
   64.27          in.writeSQL(new SQLOutputImpl(tmp, map));
   64.28 @@ -247,7 +247,7 @@
   64.29      }
   64.30  
   64.31      /**
   64.32 -         * The identifier that assists in the serialization of this
   64.33 +     * The identifier that assists in the serialization of this
   64.34       * <code>SerialStruct</code> object.
   64.35       */
   64.36      static final long serialVersionUID = -8322445504027483372L;
    65.1 --- a/src/share/classes/javax/sql/rowset/spi/SyncFactory.java	Tue Oct 12 13:34:59 2010 -0400
    65.2 +++ b/src/share/classes/javax/sql/rowset/spi/SyncFactory.java	Mon Oct 18 11:25:28 2010 -0400
    65.3 @@ -125,12 +125,12 @@
    65.4   *
    65.5   *   # Optimistic synchronization provider
    65.6   *   rowset.provider.classname.0=com.sun.rowset.providers.RIOptimisticProvider
    65.7 - *   rowset.provider.vendor.0=Sun Microsystems Inc
    65.8 + *   rowset.provider.vendor.0=Oracle Corporation
    65.9   *   rowset.provider.version.0=1.0
   65.10   *
   65.11   *   # XML Provider using standard XML schema
   65.12   *   rowset.provider.classname.1=com.sun.rowset.providers.RIXMLProvider
   65.13 - *   rowset.provider.vendor.1=Sun Microsystems Inc.
   65.14 + *   rowset.provider.vendor.1=Oracle Corporation
   65.15   *   rowset.provider.version.1=1.0
   65.16   * </PRE>
   65.17   * The <code>SyncFactory</code> checks this file and registers the
   65.18 @@ -369,7 +369,7 @@
   65.19              try {
   65.20  
   65.21                  // check if user is supplying his Synchronisation Provider
   65.22 -                // Implementation  if not use Sun's implementation.
   65.23 +                // Implementation if not using Oracle's implementation.
   65.24                  // properties.load(new FileInputStream(ROWSET_PROPERTIES));
   65.25  
   65.26                  // The rowset.properties needs to be in jdk/jre/lib when
    66.1 --- a/src/share/classes/javax/sql/rowset/spi/SyncProvider.java	Tue Oct 12 13:34:59 2010 -0400
    66.2 +++ b/src/share/classes/javax/sql/rowset/spi/SyncProvider.java	Mon Oct 18 11:25:28 2010 -0400
    66.3 @@ -91,8 +91,8 @@
    66.4   * </pre>
    66.5   * <p>
    66.6   * A vendor can register a <code>SyncProvider</code> implementation class name
    66.7 - * with Sun Microsystems, Inc. by sending email to jdbc@sun.com.
    66.8 - * Sun will maintain a database listing the
    66.9 + * with Oracle Corporation by sending email to jdbc@sun.com.
   66.10 + * Oracle will maintain a database listing the
   66.11   * available <code>SyncProvider</code> implementations for use with compliant
   66.12   * <code>RowSet</code> implementations.  This database will be similar to the
   66.13   * one already maintained to list available JDBC drivers.
    67.1 --- a/src/share/classes/javax/sql/rowset/spi/package.html	Tue Oct 12 13:34:59 2010 -0400
    67.2 +++ b/src/share/classes/javax/sql/rowset/spi/package.html	Mon Oct 18 11:25:28 2010 -0400
    67.3 @@ -8,7 +8,7 @@
    67.4    <meta name="GENERATOR"
    67.5   content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
    67.6  <!--
    67.7 -Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
    67.8 +Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
    67.9  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   67.10  
   67.11  This code is free software; you can redistribute it and/or modify it
   67.12 @@ -199,7 +199,7 @@
   67.13  Vendors may develop a <tt>SyncProvider</tt> implementation with any one of the possible
   67.14  levels of synchronization, thus giving <code>RowSet</code> objects a choice of
   67.15  synchronization mechanisms.  A vendor can make its implementation available by 
   67.16 -registering the fully qualified class name with Sun Microsystems at 
   67.17 +registering the fully qualified class name with Oracle Corporation at
   67.18  <code>jdbc@sun.com</code>. This process is discussed in further detail below. 
   67.19  <P>
   67.20  
    68.1 --- a/src/share/classes/javax/swing/GroupLayout.java	Tue Oct 12 13:34:59 2010 -0400
    68.2 +++ b/src/share/classes/javax/swing/GroupLayout.java	Mon Oct 18 11:25:28 2010 -0400
    68.3 @@ -1464,8 +1464,8 @@
    68.4       * &lt;= {@code pref} &lt;= {@code max}.
    68.5       * <p>
    68.6       * Similarly any methods that take a {@code Component} throw a
    68.7 -     * {@code NullPointerException} if passed {@code null} and any methods
    68.8 -     * that take a {@code Group} throw an {@code IllegalArgumentException} if
    68.9 +     * {@code IllegalArgumentException} if passed {@code null} and any methods
   68.10 +     * that take a {@code Group} throw an {@code NullPointerException} if
   68.11       * passed {@code null}.
   68.12       *
   68.13       * @see #createSequentialGroup
    69.1 --- a/src/share/classes/javax/swing/JComponent.java	Tue Oct 12 13:34:59 2010 -0400
    69.2 +++ b/src/share/classes/javax/swing/JComponent.java	Mon Oct 18 11:25:28 2010 -0400
    69.3 @@ -4787,6 +4787,17 @@
    69.4       * @see RepaintManager#addDirtyRegion
    69.5       */
    69.6      public void repaint(long tm, int x, int y, int width, int height) {
    69.7 +        Container p = this;
    69.8 +        while ((p = p.getParent()) instanceof JComponent) {
    69.9 +            JComponent jp = (JComponent) p;
   69.10 +            if (jp.isPaintingOrigin()) {
   69.11 +                Rectangle rectangle = SwingUtilities.convertRectangle(
   69.12 +                        this, new Rectangle(x, y, width, height), jp);
   69.13 +                jp.repaint(tm,
   69.14 +                        rectangle.x, rectangle.y, rectangle.width, rectangle.height);
   69.15 +                return;
   69.16 +            }
   69.17 +        }
   69.18          RepaintManager.currentManager(this).addDirtyRegion(this, x, y, width, height);
   69.19      }
   69.20  
    70.1 --- a/src/share/classes/javax/swing/JDesktopPane.java	Tue Oct 12 13:34:59 2010 -0400
    70.2 +++ b/src/share/classes/javax/swing/JDesktopPane.java	Mon Oct 18 11:25:28 2010 -0400
    70.3 @@ -215,7 +215,8 @@
    70.4  
    70.5      /**
    70.6       * Sets the <code>DesktopManger</code> that will handle
    70.7 -     * desktop-specific UI actions.
    70.8 +     * desktop-specific UI actions. This may be overridden by
    70.9 +     * {@code LookAndFeel}.
   70.10       *
   70.11       * @param d the <code>DesktopManager</code> to use
   70.12       *
    71.1 --- a/src/share/classes/javax/swing/JLayer.java	Tue Oct 12 13:34:59 2010 -0400
    71.2 +++ b/src/share/classes/javax/swing/JLayer.java	Mon Oct 18 11:25:28 2010 -0400
    71.3 @@ -25,17 +25,17 @@
    71.4  
    71.5  package javax.swing;
    71.6  
    71.7 +import sun.awt.AWTAccessor;
    71.8 +
    71.9  import javax.swing.plaf.LayerUI;
   71.10 +import javax.swing.border.Border;
   71.11  import java.awt.*;
   71.12  import java.awt.event.*;
   71.13  import java.beans.PropertyChangeEvent;
   71.14  import java.beans.PropertyChangeListener;
   71.15  import java.io.IOException;
   71.16  import java.io.ObjectInputStream;
   71.17 -import java.io.Serializable;
   71.18 -import java.lang.ref.WeakReference;
   71.19  import java.util.ArrayList;
   71.20 -import java.util.Iterator;
   71.21  import java.security.AccessController;
   71.22  import java.security.PrivilegedAction;
   71.23  
   71.24 @@ -156,8 +156,6 @@
   71.25      private LayerUI<? super V> layerUI;
   71.26      private JPanel glassPane;
   71.27      private boolean isPainting;
   71.28 -    private static final DefaultLayerLayout sharedLayoutInstance =
   71.29 -            new DefaultLayerLayout();
   71.30      private long eventMask;
   71.31  
   71.32      private static final LayerEventController eventController =
   71.33 @@ -165,7 +163,7 @@
   71.34  
   71.35      /**
   71.36       * Creates a new {@code JLayer} object with a {@code null} view component
   71.37 -     * and {@code null} {@link javax.swing.plaf.LayerUI}.
   71.38 +     * and default {@link javax.swing.plaf.LayerUI}.
   71.39       *
   71.40       * @see #setView
   71.41       * @see #setUI
   71.42 @@ -176,14 +174,14 @@
   71.43  
   71.44      /**
   71.45       * Creates a new {@code JLayer} object
   71.46 -     * with {@code null} {@link javax.swing.plaf.LayerUI}.
   71.47 +     * with default {@link javax.swing.plaf.LayerUI}.
   71.48       *
   71.49       * @param view the component to be decorated by this {@code JLayer}
   71.50       *
   71.51       * @see #setUI
   71.52       */
   71.53      public JLayer(V view) {
   71.54 -        this(view, null);
   71.55 +        this(view, new LayerUI<V>());
   71.56      }
   71.57  
   71.58      /**
   71.59 @@ -195,7 +193,6 @@
   71.60       * to be used by this {@code JLayer}
   71.61       */
   71.62      public JLayer(V view, LayerUI<V> ui) {
   71.63 -        setLayout(sharedLayoutInstance);
   71.64          setGlassPane(createGlassPane());
   71.65          setView(view);
   71.66          setUI(ui);
   71.67 @@ -279,10 +276,15 @@
   71.68       */
   71.69      public void setGlassPane(JPanel glassPane) {
   71.70          Component oldGlassPane = getGlassPane();
   71.71 +        boolean isGlassPaneVisible = false;
   71.72          if (oldGlassPane != null) {
   71.73 +            isGlassPaneVisible = oldGlassPane.isVisible();
   71.74              super.remove(oldGlassPane);
   71.75          }
   71.76          if (glassPane != null) {
   71.77 +            AWTAccessor.getComponentAccessor().setMixingCutoutShape(glassPane,
   71.78 +                    new Rectangle());
   71.79 +            glassPane.setVisible(isGlassPaneVisible);
   71.80              super.addImpl(glassPane, null, 0);
   71.81          }
   71.82          this.glassPane = glassPane;
   71.83 @@ -303,6 +305,40 @@
   71.84      }
   71.85  
   71.86      /**
   71.87 +     * Sets the layout manager for this container.  This method is
   71.88 +     * overridden to prevent the layout manager from being set.
   71.89 +     * <p/>Note:  If {@code mgr} is non-{@code null}, this
   71.90 +     * method will throw an exception as layout managers are not supported on
   71.91 +     * a {@code JLayer}.
   71.92 +     *
   71.93 +     * @param mgr the specified layout manager
   71.94 +     * @exception IllegalArgumentException this method is not supported
   71.95 +     */
   71.96 +    public void setLayout(LayoutManager mgr) {
   71.97 +        if (mgr != null) {
   71.98 +            throw new IllegalArgumentException("JLayer.setLayout() not supported");
   71.99 +        }
  71.100 +    }
  71.101 +
  71.102 +    /**
  71.103 +     * A non-{@code null] border, or non-zero insets, isn't supported, to prevent the geometry
  71.104 +     * of this component from becoming complex enough to inhibit
  71.105 +     * subclassing of {@code LayerUI} class.  To create a {@code JLayer} with a border,
  71.106 +     * add it to a {@code JPanel} that has a border.
  71.107 +     * <p/>Note:  If {@code border} is non-{@code null}, this
  71.108 +     * method will throw an exception as borders are not supported on
  71.109 +     * a {@code JLayer}.
  71.110 +     *
  71.111 +     * @param border the {@code Border} to set
  71.112 +     * @exception IllegalArgumentException this method is not supported
  71.113 +     */
  71.114 +    public void setBorder(Border border) {
  71.115 +        if (border != null) {
  71.116 +            throw new IllegalArgumentException("JLayer.setBorder() not supported");
  71.117 +        }
  71.118 +    }
  71.119 +
  71.120 +    /**
  71.121       * This method is not supported by {@code JLayer}
  71.122       * and always throws {@code UnsupportedOperationException}
  71.123       *
  71.124 @@ -341,6 +377,32 @@
  71.125      }
  71.126  
  71.127      /**
  71.128 +     * Always returns {@code true} to cause painting to originate from {@code JLayer},
  71.129 +     * or one of its ancestors.
  71.130 +     *
  71.131 +     * @return true
  71.132 +     * @see JComponent#isPaintingOrigin()
  71.133 +     */
  71.134 +    boolean isPaintingOrigin() {
  71.135 +        return true;
  71.136 +    }
  71.137 +
  71.138 +    /**
  71.139 +     * Delegates repainting to {@link javax.swing.plaf.LayerUI#repaint} method.
  71.140 +     *
  71.141 +     * @param tm  this parameter is not used
  71.142 +     * @param x  the x value of the dirty region
  71.143 +     * @param y  the y value of the dirty region
  71.144 +     * @param width  the width of the dirty region
  71.145 +     * @param height  the height of the dirty region
  71.146 +     */
  71.147 +    public void repaint(long tm, int x, int y, int width, int height) {
  71.148 +        if (getUI() != null) {
  71.149 +            getUI().repaint(tm, x, y, width, height, this);
  71.150 +        }
  71.151 +    }
  71.152 +
  71.153 +    /**
  71.154       * Delegates all painting to the {@link javax.swing.plaf.LayerUI} object.
  71.155       *
  71.156       * @param g the {@code Graphics} to render to
  71.157 @@ -364,14 +426,18 @@
  71.158      }
  71.159  
  71.160      /**
  71.161 -     * To enable the correct painting of the {@code glassPane} and view component,
  71.162 -     * the {@code JLayer} overrides the default implementation of
  71.163 -     * this method to return {@code false} when the {@code glassPane} is visible.
  71.164 +     * The {@code JLayer} overrides the default implementation of
  71.165 +     * this method (in {@code JComponent}) to return {@code false}.
  71.166 +     * This ensures
  71.167 +     * that the drawing machinery will call the {@code JLayer}'s
  71.168 +     * {@code paint}
  71.169 +     * implementation rather than messaging the {@code JLayer}'s
  71.170 +     * children directly.
  71.171       *
  71.172 -     * @return false if {@code JLayer}'s {@code glassPane} is visible
  71.173 +     * @return false
  71.174       */
  71.175      public boolean isOptimizedDrawingEnabled() {
  71.176 -        return glassPane == null || !glassPane.isVisible();
  71.177 +        return false;
  71.178      }
  71.179  
  71.180      /**
  71.181 @@ -461,17 +527,16 @@
  71.182      /**
  71.183       * Returns the preferred size of the viewport for a view component.
  71.184       * <p/>
  71.185 -     * If the ui delegate of this layer is not {@code null}, this method delegates its
  71.186 -     * implementation to the {@code LayerUI.getPreferredScrollableViewportSize(JLayer)}
  71.187 +     * If the view component of this layer implements {@link Scrollable}, this method delegates its
  71.188 +     * implementation to the view component.
  71.189       *
  71.190       * @return the preferred size of the viewport for a view component
  71.191       *
  71.192       * @see Scrollable
  71.193 -     * @see LayerUI#getPreferredScrollableViewportSize(JLayer)
  71.194       */
  71.195      public Dimension getPreferredScrollableViewportSize() {
  71.196 -        if (getUI() != null) {
  71.197 -            return getUI().getPreferredScrollableViewportSize(this);
  71.198 +        if (getView() instanceof Scrollable) {
  71.199 +            return ((Scrollable)getView()).getPreferredScrollableViewportSize();
  71.200          }
  71.201          return getPreferredSize();
  71.202      }
  71.203 @@ -481,18 +546,17 @@
  71.204       * that display logical rows or columns in order to completely expose
  71.205       * one block of rows or columns, depending on the value of orientation.
  71.206       * <p/>
  71.207 -     * If the ui delegate of this layer is not {@code null}, this method delegates its
  71.208 -     * implementation to the {@code LayerUI.getScrollableBlockIncrement(JLayer,Rectangle,int,int)}
  71.209 +     * If the view component of this layer implements {@link Scrollable}, this method delegates its
  71.210 +     * implementation to the view component.
  71.211       *
  71.212       * @return the "block" increment for scrolling in the specified direction
  71.213       *
  71.214       * @see Scrollable
  71.215 -     * @see LayerUI#getScrollableBlockIncrement(JLayer, Rectangle, int, int)
  71.216       */
  71.217      public int getScrollableBlockIncrement(Rectangle visibleRect,
  71.218                                             int orientation, int direction) {
  71.219 -        if (getUI() != null) {
  71.220 -            return getUI().getScrollableBlockIncrement(this, visibleRect,
  71.221 +        if (getView() instanceof Scrollable) {
  71.222 +            return ((Scrollable)getView()).getScrollableBlockIncrement(visibleRect,
  71.223                      orientation, direction);
  71.224          }
  71.225          return (orientation == SwingConstants.VERTICAL) ? visibleRect.height :
  71.226 @@ -504,17 +568,16 @@
  71.227       * determine the height of the layer, unless the preferred height
  71.228       * of the layer is smaller than the height of the viewport.
  71.229       * <p/>
  71.230 -     * If the ui delegate of this layer is not null, this method delegates its
  71.231 -     * implementation to the {@code LayerUI.getScrollableTracksViewportHeight(JLayer)}
  71.232 +     * If the view component of this layer implements {@link Scrollable}, this method delegates its
  71.233 +     * implementation to the view component.
  71.234       *
  71.235       * @return whether the layer should track the height of the viewport
  71.236       *
  71.237       * @see Scrollable
  71.238 -     * @see LayerUI#getScrollableTracksViewportHeight(JLayer)
  71.239       */
  71.240      public boolean getScrollableTracksViewportHeight() {
  71.241 -        if (getUI() != null) {
  71.242 -            return getUI().getScrollableTracksViewportHeight(this);
  71.243 +        if (getView() instanceof Scrollable) {
  71.244 +            return ((Scrollable)getView()).getScrollableTracksViewportHeight();
  71.245          }
  71.246          return false;
  71.247      }
  71.248 @@ -524,17 +587,16 @@
  71.249       * determine the width of the layer, unless the preferred width
  71.250       * of the layer is smaller than the width of the viewport.
  71.251       * <p/>
  71.252 -     * If the ui delegate of this layer is not null, this method delegates its
  71.253 -     * implementation to the {@code LayerUI.getScrollableTracksViewportWidth(JLayer)}
  71.254 +     * If the view component of this layer implements {@link Scrollable}, this method delegates its
  71.255 +     * implementation to the view component.
  71.256       *
  71.257       * @return whether the layer should track the width of the viewport
  71.258       *
  71.259       * @see Scrollable
  71.260 -     * @see LayerUI#getScrollableTracksViewportWidth(JLayer)
  71.261       */
  71.262      public boolean getScrollableTracksViewportWidth() {
  71.263 -        if (getUI() != null) {
  71.264 -            return getUI().getScrollableTracksViewportWidth(this);
  71.265 +        if (getView() instanceof Scrollable) {
  71.266 +            return ((Scrollable)getView()).getScrollableTracksViewportWidth();
  71.267          }
  71.268          return false;
  71.269      }
  71.270 @@ -549,20 +611,19 @@
  71.271       * Scrolling containers, like {@code JScrollPane}, will use this method
  71.272       * each time the user requests a unit scroll.
  71.273       * <p/>
  71.274 -     * If the ui delegate of this layer is not {@code null}, this method delegates its
  71.275 -     * implementation to the {@code LayerUI.getScrollableUnitIncrement(JLayer,Rectangle,int,int)}
  71.276 +     * If the view component of this layer implements {@link Scrollable}, this method delegates its
  71.277 +     * implementation to the view component.
  71.278       *
  71.279       * @return The "unit" increment for scrolling in the specified direction.
  71.280       *         This value should always be positive.
  71.281       *
  71.282       * @see Scrollable
  71.283 -     * @see LayerUI#getScrollableUnitIncrement(JLayer, Rectangle, int, int)
  71.284       */
  71.285      public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation,
  71.286                                            int direction) {
  71.287 -        if (getUI() != null) {
  71.288 -            return getUI().getScrollableUnitIncrement(
  71.289 -                    this, visibleRect, orientation, direction);
  71.290 +        if (getView() instanceof Scrollable) {
  71.291 +            return ((Scrollable) getView()).getScrollableUnitIncrement(
  71.292 +                    visibleRect, orientation, direction);
  71.293          }
  71.294          return 1;
  71.295      }
  71.296 @@ -595,6 +656,16 @@
  71.297      }
  71.298  
  71.299      /**
  71.300 +     * Delegates its functionality to the {@link javax.swing.plaf.LayerUI#doLayout(JLayer)} method,
  71.301 +     * if {@code LayerUI} is set.
  71.302 +     */
  71.303 +    public void doLayout() {
  71.304 +        if (getUI() != null) {
  71.305 +            getUI().doLayout(this);
  71.306 +        }
  71.307 +    }
  71.308 +
  71.309 +    /**
  71.310       * static AWTEventListener to be shared with all AbstractLayerUIs
  71.311       */
  71.312      private static class LayerEventController implements AWTEventListener {
  71.313 @@ -625,8 +696,8 @@
  71.314                          JLayer l = (JLayer) component;
  71.315                          LayerUI ui = l.getUI();
  71.316                          if (ui != null &&
  71.317 -                                isEventEnabled(l.getLayerEventMask(),
  71.318 -                                        event.getID())) {
  71.319 +                                isEventEnabled(l.getLayerEventMask(), event.getID()) &&
  71.320 +                                (!(event instanceof InputEvent) || !((InputEvent)event).isConsumed())) {
  71.321                              ui.eventDispatched(event, l);
  71.322                          }
  71.323                      }
  71.324 @@ -758,82 +829,4 @@
  71.325              return super.contains(x, y);
  71.326          }
  71.327      }
  71.328 -
  71.329 -    /**
  71.330 -     * The default layout manager for the {@link javax.swing.JLayer}.<br/>
  71.331 -     * It places the glassPane on top of the view component
  71.332 -     * and makes it the same size as {@code JLayer},
  71.333 -     * it also makes the view component the same size but minus layer's insets<br/>
  71.334 -     */
  71.335 -    private static class DefaultLayerLayout implements LayoutManager, Serializable {
  71.336 -        /**
  71.337 -         * {@inheritDoc}
  71.338 -         */
  71.339 -        public void layoutContainer(Container parent) {
  71.340 -            JLayer layer = (JLayer) parent;
  71.341 -            Component view = layer.getView();
  71.342 -            Component glassPane = layer.getGlassPane();
  71.343 -            if (view != null) {
  71.344 -                Insets insets = layer.getInsets();
  71.345 -                view.setLocation(insets.left, insets.top);
  71.346 -                view.setSize(layer.getWidth() - insets.left - insets.right,
  71.347 -                        layer.getHeight() - insets.top - insets.bottom);
  71.348 -            }
  71.349 -            if (glassPane != null) {
  71.350 -                glassPane.setLocation(0, 0);
  71.351 -                glassPane.setSize(layer.getWidth(), layer.getHeight());
  71.352 -            }
  71.353 -        }
  71.354 -
  71.355 -        /**
  71.356 -         * {@inheritDoc}
  71.357 -         */
  71.358 -        public Dimension minimumLayoutSize(Container parent) {
  71.359 -            JLayer layer = (JLayer) parent;
  71.360 -            Insets insets = layer.getInsets();
  71.361 -            Dimension ret = new Dimension(insets.left + insets.right,
  71.362 -                    insets.top + insets.bottom);
  71.363 -            Component view = layer.getView();
  71.364 -            if (view != null) {
  71.365 -                Dimension size = view.getMinimumSize();
  71.366 -                ret.width += size.width;
  71.367 -                ret.height += size.height;
  71.368 -            }
  71.369 -            if (ret.width == 0 || ret.height == 0) {
  71.370 -                ret.width = ret.height = 4;
  71.371 -            }
  71.372 -            return ret;
  71.373 -        }
  71.374 -
  71.375 -        /**
  71.376 -         * {@inheritDoc}
  71.377 -         */
  71.378 -        public Dimension preferredLayoutSize(Container parent) {
  71.379 -            JLayer layer = (JLayer) parent;
  71.380 -            Insets insets = layer.getInsets();
  71.381 -            Dimension ret = new Dimension(insets.left + insets.right,
  71.382 -                    insets.top + insets.bottom);
  71.383 -            Component view = layer.getView();
  71.384 -            if (view != null) {
  71.385 -                Dimension size = view.getPreferredSize();
  71.386 -                if (size.width > 0 && size.height > 0) {
  71.387 -                    ret.width += size.width;
  71.388 -                    ret.height += size.height;
  71.389 -                }
  71.390 -            }
  71.391 -            return ret;
  71.392 -        }
  71.393 -
  71.394 -        /**
  71.395 -         * {@inheritDoc}
  71.396 -         */
  71.397 -        public void addLayoutComponent(String name, Component comp) {
  71.398 -        }
  71.399 -
  71.400 -        /**
  71.401 -         * {@inheritDoc}
  71.402 -         */
  71.403 -        public void removeLayoutComponent(Component comp) {
  71.404 -        }
  71.405 -    }
  71.406  }
    72.1 --- a/src/share/classes/javax/swing/JTable.java	Tue Oct 12 13:34:59 2010 -0400
    72.2 +++ b/src/share/classes/javax/swing/JTable.java	Mon Oct 18 11:25:28 2010 -0400
    72.3 @@ -4574,9 +4574,8 @@
    72.4       * @see TableColumnModelListener
    72.5       */
    72.6      public void columnMoved(TableColumnModelEvent e) {
    72.7 -        // If I'm currently editing, then I should stop editing
    72.8 -        if (isEditing()) {
    72.9 -            removeEditor();
   72.10 +        if (isEditing() && !getCellEditor().stopCellEditing()) {
   72.11 +            getCellEditor().cancelCellEditing();
   72.12          }
   72.13          repaint();
   72.14      }
   72.15 @@ -4593,8 +4592,8 @@
   72.16       * @see TableColumnModelListener
   72.17       */
   72.18      public void columnMarginChanged(ChangeEvent e) {
   72.19 -        if (isEditing()) {
   72.20 -            removeEditor();
   72.21 +        if (isEditing() && !getCellEditor().stopCellEditing()) {
   72.22 +            getCellEditor().cancelCellEditing();
   72.23          }
   72.24          TableColumn resizingColumn = getResizingColumn();
   72.25          // Need to do this here, before the parent's
    73.1 --- a/src/share/classes/javax/swing/ToolTipManager.java	Tue Oct 12 13:34:59 2010 -0400
    73.2 +++ b/src/share/classes/javax/swing/ToolTipManager.java	Mon Oct 18 11:25:28 2010 -0400
    73.3 @@ -459,7 +459,7 @@
    73.4          if (insideComponent == null) {
    73.5              // Drag exit
    73.6          }
    73.7 -        if (window != null && event.getSource() == window) {
    73.8 +        if (window != null && event.getSource() == window && insideComponent != null) {
    73.9            // if we get an exit and have a heavy window
   73.10            // we need to check if it if overlapping the inside component
   73.11              Container insideComponentWindow = insideComponent.getTopLevelAncestor();
    74.1 --- a/src/share/classes/javax/swing/plaf/LayerUI.java	Tue Oct 12 13:34:59 2010 -0400
    74.2 +++ b/src/share/classes/javax/swing/plaf/LayerUI.java	Mon Oct 18 11:25:28 2010 -0400
    74.3 @@ -600,104 +600,6 @@
    74.4      }
    74.5  
    74.6      /**
    74.7 -     * Returns the preferred size of the viewport for a view component.
    74.8 -     *
    74.9 -     * @param l the {@code JLayer} component where this UI delegate is being installed
   74.10 -     * @return the preferred size of the viewport for a view component
   74.11 -     * @see Scrollable#getPreferredScrollableViewportSize()
   74.12 -     */
   74.13 -    public Dimension getPreferredScrollableViewportSize(JLayer<? extends V> l) {
   74.14 -        if (l.getView() instanceof Scrollable) {
   74.15 -            return ((Scrollable)l.getView()).getPreferredScrollableViewportSize();
   74.16 -        }
   74.17 -        return l.getPreferredSize();
   74.18 -    }
   74.19 -
   74.20 -    /**
   74.21 -     * Returns a scroll increment, which is required for components
   74.22 -     * that display logical rows or columns in order to completely expose
   74.23 -     * one block of rows or columns, depending on the value of orientation.
   74.24 -     *
   74.25 -     * @param l the {@code JLayer} component where this UI delegate is being installed
   74.26 -     * @param visibleRect The view area visible within the viewport
   74.27 -     * @param orientation Either SwingConstants.VERTICAL or SwingConstants.HORIZONTAL.
   74.28 -     * @param direction Less than zero to scroll up/left, greater than zero for down/right.
   74.29 -     * @return the "block" increment for scrolling in the specified direction
   74.30 -     * @see Scrollable#getScrollableBlockIncrement(Rectangle, int, int)
   74.31 -     */
   74.32 -     public int getScrollableBlockIncrement(JLayer<? extends V> l,
   74.33 -                                           Rectangle visibleRect,
   74.34 -                                           int orientation, int direction) {
   74.35 -        if (l.getView() instanceof Scrollable) {
   74.36 -            return ((Scrollable)l.getView()).getScrollableBlockIncrement(
   74.37 -                    visibleRect,orientation, direction);
   74.38 -        }
   74.39 -        return (orientation == SwingConstants.VERTICAL) ? visibleRect.height :
   74.40 -            visibleRect.width;
   74.41 -    }
   74.42 -
   74.43 -    /**
   74.44 -     * Returns {@code false} to indicate that the height of the viewport does not
   74.45 -     * determine the height of the layer, unless the preferred height
   74.46 -     * of the layer is smaller than the height of the viewport.
   74.47 -     *
   74.48 -     * @param l the {@code JLayer} component where this UI delegate is being installed
   74.49 -     * @return whether the layer should track the height of the viewport
   74.50 -     * @see Scrollable#getScrollableTracksViewportHeight()
   74.51 -     */
   74.52 -    public boolean getScrollableTracksViewportHeight(JLayer<? extends V> l) {
   74.53 -        if (l.getView() instanceof Scrollable) {
   74.54 -            return ((Scrollable)l.getView()).getScrollableTracksViewportHeight();
   74.55 -        }
   74.56 -        return false;
   74.57 -    }
   74.58 -
   74.59 -    /**
   74.60 -     * Returns {@code false} to indicate that the width of the viewport does not
   74.61 -     * determine the width of the layer, unless the preferred width
   74.62 -     * of the layer is smaller than the width of the viewport.
   74.63 -     *
   74.64 -     * @param l the {@code JLayer} component where this UI delegate is being installed
   74.65 -     * @return whether the layer should track the width of the viewport
   74.66 -     * @see Scrollable
   74.67 -     * @see LayerUI#getScrollableTracksViewportWidth(JLayer)
   74.68 -     */
   74.69 -    public boolean getScrollableTracksViewportWidth(JLayer<? extends V> l) {
   74.70 -        if (l.getView() instanceof Scrollable) {
   74.71 -            return ((Scrollable)l.getView()).getScrollableTracksViewportWidth();
   74.72 -        }
   74.73 -        return false;
   74.74 -    }
   74.75 -
   74.76 -    /**
   74.77 -     * Returns a scroll increment, which is required for components
   74.78 -     * that display logical rows or columns in order to completely expose
   74.79 -     * one new row or column, depending on the value of orientation.
   74.80 -     * Ideally, components should handle a partially exposed row or column
   74.81 -     * by returning the distance required to completely expose the item.
   74.82 -     * <p>
   74.83 -     * Scrolling containers, like JScrollPane, will use this method
   74.84 -     * each time the user requests a unit scroll.
   74.85 -     *
   74.86 -     * @param l the {@code JLayer} component where this UI delegate is being installed
   74.87 -     * @param visibleRect The view area visible within the viewport
   74.88 -     * @param orientation Either SwingConstants.VERTICAL or SwingConstants.HORIZONTAL.
   74.89 -     * @param direction Less than zero to scroll up/left, greater than zero for down/right.
   74.90 -     * @return The "unit" increment for scrolling in the specified direction.
   74.91 -     *         This value should always be positive.
   74.92 -     * @see Scrollable#getScrollableUnitIncrement(Rectangle, int, int)
   74.93 -     */
   74.94 -    public int getScrollableUnitIncrement(JLayer<? extends V> l,
   74.95 -                                          Rectangle visibleRect,
   74.96 -                                          int orientation, int direction) {
   74.97 -        if (l.getView() instanceof Scrollable) {
   74.98 -            return ((Scrollable)l.getView()).getScrollableUnitIncrement(
   74.99 -                    visibleRect, orientation, direction);
  74.100 -        }
  74.101 -        return 1;
  74.102 -    }
  74.103 -
  74.104 -    /**
  74.105       * If the {@code JLayer}'s view component is not {@code null},
  74.106       * this calls the view's {@code getBaseline()} method.
  74.107       * Otherwise, the default implementation is called.
  74.108 @@ -718,7 +620,7 @@
  74.109  
  74.110      /**
  74.111       * If the {@code JLayer}'s view component is not {@code null},
  74.112 -     * this calls the view's {@code getBaselineResizeBehavior()} method.
  74.113 +     * this returns the result of the view's {@code getBaselineResizeBehavior()} method.
  74.114       * Otherwise, the default implementation is called.
  74.115       *
  74.116       * @param c {@code JLayer} to return baseline resize behavior for
  74.117 @@ -732,4 +634,90 @@
  74.118          }
  74.119          return super.getBaselineResizeBehavior(c);
  74.120      }
  74.121 +
  74.122 +    /**
  74.123 +     * Causes the passed instance of {@code JLayer} to lay out its components.
  74.124 +     *
  74.125 +     * @param l the {@code JLayer} component where this UI delegate is being installed
  74.126 +     */
  74.127 +    public void doLayout(JLayer<? extends V> l) {
  74.128 +        Component view = l.getView();
  74.129 +        if (view != null) {
  74.130 +            view.setBounds(0, 0, l.getWidth(), l.getHeight());
  74.131 +        }
  74.132 +        Component glassPane = l.getGlassPane();
  74.133 +        if (glassPane != null) {
  74.134 +            glassPane.setBounds(0, 0, l.getWidth(), l.getHeight());
  74.135 +        }
  74.136 +    }
  74.137 +
  74.138 +    /**
  74.139 +     * If the {@code JLayer}'s view component is not {@code null},
  74.140 +     * this returns the result of  the view's {@code getPreferredSize()} method.
  74.141 +     * Otherwise, the default implementation is used.
  74.142 +     *
  74.143 +     * @param c {@code JLayer} to return preferred size for
  74.144 +     * @return preferred size for the passed {@code JLayer}
  74.145 +     */
  74.146 +    public Dimension getPreferredSize(JComponent c) {
  74.147 +        JLayer l = (JLayer) c;
  74.148 +        Component view = l.getView();
  74.149 +        if (view != null) {
  74.150 +            return view.getPreferredSize();
  74.151 +        }
  74.152 +        return super.getPreferredSize(c);
  74.153 +    }
  74.154 +
  74.155 +    /**
  74.156 +     * If the {@code JLayer}'s view component is not {@code null},
  74.157 +     * this returns the result of  the view's {@code getMinimalSize()} method.
  74.158 +     * Otherwise, the default implementation is used.
  74.159 +     *
  74.160 +     * @param c {@code JLayer} to return preferred size for
  74.161 +     * @return minimal size for the passed {@code JLayer}
  74.162 +     */
  74.163 +    public Dimension getMinimumSize(JComponent c) {
  74.164 +        JLayer l = (JLayer) c;
  74.165 +        Component view = l.getView();
  74.166 +        if (view != null) {
  74.167 +            return view.getMinimumSize();
  74.168 +        }
  74.169 +        return super.getMinimumSize(c);
  74.170 +    }
  74.171 +
  74.172 +    /**
  74.173 +     * If the {@code JLayer}'s view component is not {@code null},
  74.174 +     * this returns the result of  the view's {@code getMaximumSize()} method.
  74.175 +     * Otherwise, the default implementation is used.
  74.176 +     *
  74.177 +     * @param c {@code JLayer} to return preferred size for
  74.178 +     * @return maximun size for the passed {@code JLayer}
  74.179 +     */
  74.180 +    public Dimension getMaximumSize(JComponent c) {
  74.181 +        JLayer l = (JLayer) c;
  74.182 +        Component view = l.getView();
  74.183 +        if (view != null) {
  74.184 +            return view.getMaximumSize();
  74.185 +        }
  74.186 +        return super.getMaximumSize(c);
  74.187 +    }
  74.188 +
  74.189 +    /**
  74.190 +     * Adds the specified region to the dirty region list if the component
  74.191 +     * is showing.  The component will be repainted after all of the
  74.192 +     * currently pending events have been dispatched.
  74.193 +     * <p/>
  74.194 +     * This method is to be overridden when the dirty region needs to be changed.
  74.195 +     *
  74.196 +     * @param tm  this parameter is not used
  74.197 +     * @param x  the x value of the dirty region
  74.198 +     * @param y  the y value of the dirty region
  74.199 +     * @param width  the width of the dirty region
  74.200 +     * @param height  the height of the dirty region
  74.201 +     * @see java.awt.Component#isShowing
  74.202 +     * @see RepaintManager#addDirtyRegion
  74.203 +     */
  74.204 +    public void repaint(long tm, int x, int y, int width, int height, JLayer<? extends V> l) {
  74.205 +        RepaintManager.currentManager(l).addDirtyRegion(l, x, y, width, height);
  74.206 +    }
  74.207  }
    75.1 --- a/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java	Tue Oct 12 13:34:59 2010 -0400
    75.2 +++ b/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java	Mon Oct 18 11:25:28 2010 -0400
    75.3 @@ -1603,6 +1603,7 @@
    75.4                  BoundedRangeModel newModel = (BoundedRangeModel)e.getNewValue();
    75.5                  oldModel.removeChangeListener(modelListener);
    75.6                  newModel.addChangeListener(modelListener);
    75.7 +                scrollBarValue = scrollbar.getValue();
    75.8                  scrollbar.repaint();
    75.9                  scrollbar.revalidate();
   75.10              } else if ("orientation" == propertyName) {
    76.1 --- a/src/share/classes/javax/swing/plaf/metal/MetalComboBoxUI.java	Tue Oct 12 13:34:59 2010 -0400
    76.2 +++ b/src/share/classes/javax/swing/plaf/metal/MetalComboBoxUI.java	Mon Oct 18 11:25:28 2010 -0400
    76.3 @@ -144,7 +144,7 @@
    76.4       */
    76.5      public int getBaseline(JComponent c, int width, int height) {
    76.6          int baseline;
    76.7 -        if (MetalLookAndFeel.usingOcean()) {
    76.8 +        if (MetalLookAndFeel.usingOcean() && height >= 4) {
    76.9              height -= 4;
   76.10              baseline = super.getBaseline(c, width, height);
   76.11              if (baseline >= 0) {
    77.1 --- a/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java	Tue Oct 12 13:34:59 2010 -0400
    77.2 +++ b/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java	Mon Oct 18 11:25:28 2010 -0400
    77.3 @@ -115,6 +115,9 @@
    77.4          return new SynthTabbedPaneUI();
    77.5      }
    77.6  
    77.7 +    private SynthTabbedPaneUI() {
    77.8 +    }
    77.9 +
   77.10      private boolean scrollableTabLayoutEnabled() {
   77.11          return (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT);
   77.12      }
    78.1 --- a/src/share/classes/sun/awt/AWTAccessor.java	Tue Oct 12 13:34:59 2010 -0400
    78.2 +++ b/src/share/classes/sun/awt/AWTAccessor.java	Mon Oct 18 11:25:28 2010 -0400
    78.3 @@ -344,6 +344,11 @@
    78.4           * Removes the last focus request for the heavyweight from the queue.
    78.5           */
    78.6          void removeLastFocusRequest(Component heavyweight);
    78.7 +
    78.8 +        /*
    78.9 +         * Sets the most recent focus owner in the window.
   78.10 +         */
   78.11 +        void setMostRecentFocusOwner(Window window, Component component);
   78.12      }
   78.13  
   78.14      /*
    79.1 --- a/src/share/classes/sun/awt/EmbeddedFrame.java	Tue Oct 12 13:34:59 2010 -0400
    79.2 +++ b/src/share/classes/sun/awt/EmbeddedFrame.java	Mon Oct 18 11:25:28 2010 -0400
    79.3 @@ -70,7 +70,10 @@
    79.4      // JDK 1.1 compatibility
    79.5      private static final long serialVersionUID = 2967042741780317130L;
    79.6  
    79.7 -    // Use these in traverseOut method to determine directions
    79.8 +    /*
    79.9 +     * The constants define focus traversal directions.
   79.10 +     * Use them in {@code traverseIn}, {@code traverseOut} methods.
   79.11 +     */
   79.12      protected static final boolean FORWARD = true;
   79.13      protected static final boolean BACKWARD = false;
   79.14  
   79.15 @@ -284,6 +287,41 @@
   79.16      }
   79.17  
   79.18      /**
   79.19 +     * This method is called by the embedder when we should receive focus as element
   79.20 +     * of the traversal chain.  The method requests focus on:
   79.21 +     * 1. the first Component of this EmbeddedFrame if user moves focus forward
   79.22 +     *    in the focus traversal cycle.
   79.23 +     * 2. the last Component of this EmbeddedFrame if user moves focus backward
   79.24 +     *    in the focus traversal cycle.
   79.25 +     *
   79.26 +     * The direction parameter specifies which of the two mentioned cases is
   79.27 +     * happening. Use FORWARD and BACKWARD constants defined in the EmbeddedFrame class
   79.28 +     * to avoid confusing boolean values.
   79.29 +     *
   79.30 +     * A concrete implementation of this method is defined in the platform-dependent
   79.31 +     * subclasses.
   79.32 +     *
   79.33 +     * @param direction FORWARD or BACKWARD
   79.34 +     * @return true, if the EmbeddedFrame wants to get focus, false otherwise.
   79.35 +     */
   79.36 +    public boolean traverseIn(boolean direction) {
   79.37 +        Component comp = null;
   79.38 +
   79.39 +        if (direction == FORWARD) {
   79.40 +            comp = getFocusTraversalPolicy().getFirstComponent(this);
   79.41 +        } else {
   79.42 +            comp = getFocusTraversalPolicy().getLastComponent(this);
   79.43 +        }
   79.44 +        if (comp != null) {
   79.45 +            // comp.requestFocus(); - Leads to a hung.
   79.46 +
   79.47 +            AWTAccessor.getKeyboardFocusManagerAccessor().setMostRecentFocusOwner(this, comp);
   79.48 +            synthesizeWindowActivation(true);
   79.49 +        }
   79.50 +        return (null != comp);
   79.51 +    }
   79.52 +
   79.53 +    /**
   79.54       * This method is called from dispatchKeyEvent in the following two cases:
   79.55       * 1. The focus is on the first Component of this EmbeddedFrame and we are
   79.56       *    about to transfer the focus backward.
    80.1 --- a/src/share/classes/sun/net/www/http/HttpClient.java	Tue Oct 12 13:34:59 2010 -0400
    80.2 +++ b/src/share/classes/sun/net/www/http/HttpClient.java	Mon Oct 18 11:25:28 2010 -0400
    80.3 @@ -55,6 +55,9 @@
    80.4      // Http data we send with the headers
    80.5      PosterOutputStream poster = null;
    80.6  
    80.7 +    // true if we are in streaming mode (fixed length or chunked)
    80.8 +    boolean streaming;
    80.9 +
   80.10      // if we've had one io error
   80.11      boolean failedOnce = false;
   80.12  
   80.13 @@ -275,6 +278,10 @@
   80.14                          ret.cachedHttpClient = true;
   80.15                          assert ret.inCache;
   80.16                          ret.inCache = false;
   80.17 +                        PlatformLogger logger = HttpURLConnection.getHttpLogger();
   80.18 +                        if (logger.isLoggable(PlatformLogger.FINEST)) {
   80.19 +                            logger.finest("KeepAlive stream retrieved from the cache, " + ret);
   80.20 +                        }
   80.21                      }
   80.22                  } else {
   80.23                      // We cannot return this connection to the cache as it's
   80.24 @@ -545,6 +552,13 @@
   80.25          serverOutput.flush();
   80.26      }
   80.27  
   80.28 +    public void writeRequests(MessageHeader head,
   80.29 +                              PosterOutputStream pos,
   80.30 +                              boolean streaming) throws IOException {
   80.31 +        this.streaming = streaming;
   80.32 +        writeRequests(head, pos);
   80.33 +    }
   80.34 +
   80.35      /** Parse the first line of the HTTP request.  It usually looks
   80.36          something like: "HTTP/1.0 <number> comment\r\n". */
   80.37  
   80.38 @@ -577,11 +591,11 @@
   80.39              closeServer();
   80.40              cachedHttpClient = false;
   80.41              if (!failedOnce && requests != null) {
   80.42 -                if (httpuc.getRequestMethod().equals("POST") && !retryPostProp) {
   80.43 +                failedOnce = true;
   80.44 +                if (httpuc.getRequestMethod().equals("POST") && (!retryPostProp || streaming)) {
   80.45                      // do not retry the request
   80.46                  }  else {
   80.47                      // try once more
   80.48 -                    failedOnce = true;
   80.49                      openServer();
   80.50                      if (needsTunneling()) {
   80.51                          httpuc.doTunneling();
   80.52 @@ -684,10 +698,10 @@
   80.53                  }
   80.54              } else if (nread != 8) {
   80.55                  if (!failedOnce && requests != null) {
   80.56 -                    if (httpuc.getRequestMethod().equals("POST") && !retryPostProp) {
   80.57 +                    failedOnce = true;
   80.58 +                    if (httpuc.getRequestMethod().equals("POST") && (!retryPostProp || streaming)) {
   80.59                          // do not retry the request
   80.60                      } else {
   80.61 -                        failedOnce = true;
   80.62                          closeServer();
   80.63                          cachedHttpClient = false;
   80.64                          openServer();
    81.1 --- a/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Tue Oct 12 13:34:59 2010 -0400
    81.2 +++ b/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Mon Oct 18 11:25:28 2010 -0400
    81.3 @@ -494,7 +494,7 @@
    81.4          if (logger.isLoggable(PlatformLogger.FINE)) {
    81.5              logger.fine(requests.toString());
    81.6          }
    81.7 -        http.writeRequests(requests, poster);
    81.8 +        http.writeRequests(requests, poster, streaming());
    81.9          if (ps.checkError()) {
   81.10              String proxyHost = http.getProxyHostUsed();
   81.11              int proxyPort = http.getProxyPortUsed();
   81.12 @@ -2825,6 +2825,38 @@
   81.13              }
   81.14          }
   81.15  
   81.16 +        /* skip() calls read() in order to ensure that entire response gets
   81.17 +         * cached. same implementation as InputStream.skip */
   81.18 +
   81.19 +        private byte[] skipBuffer;
   81.20 +        private static final int SKIP_BUFFER_SIZE = 8096;
   81.21 +
   81.22 +        @Override
   81.23 +        public long skip (long n) throws IOException {
   81.24 +
   81.25 +            long remaining = n;
   81.26 +            int nr;
   81.27 +            if (skipBuffer == null)
   81.28 +                skipBuffer = new byte[SKIP_BUFFER_SIZE];
   81.29 +
   81.30 +            byte[] localSkipBuffer = skipBuffer;
   81.31 +
   81.32 +            if (n <= 0) {
   81.33 +                return 0;
   81.34 +            }
   81.35 +
   81.36 +            while (remaining > 0) {
   81.37 +                nr = read(localSkipBuffer, 0,
   81.38 +                          (int) Math.min(SKIP_BUFFER_SIZE, remaining));
   81.39 +                if (nr < 0) {
   81.40 +                    break;
   81.41 +                }
   81.42 +                remaining -= nr;
   81.43 +            }
   81.44 +
   81.45 +            return n - remaining;
   81.46 +        }
   81.47 +
   81.48          @Override
   81.49          public void close () throws IOException {
   81.50              try {
    82.1 --- a/src/share/classes/sun/security/tools/KeyTool.java	Tue Oct 12 13:34:59 2010 -0400
    82.2 +++ b/src/share/classes/sun/security/tools/KeyTool.java	Mon Oct 18 11:25:28 2010 -0400
    82.3 @@ -281,7 +281,7 @@
    82.4          RFC("rfc", null, "output in RFC style"),
    82.5          SIGALG("sigalg", "<sigalg>", "signature algorithm name"),
    82.6          SRCALIAS("srcalias", "<srcalias>", "source alias"),
    82.7 -        SRCKEYPASS("srckeypass", "<arg>", "source keystore password"),
    82.8 +        SRCKEYPASS("srckeypass", "<arg>", "source key password"),
    82.9          SRCKEYSTORE("srckeystore", "<srckeystore>", "source keystore name"),
   82.10          SRCPROTECTED("srcprotected", null, "source keystore password protected"),
   82.11          SRCPROVIDERNAME("srcprovidername", "<srcprovidername>", "source keystore provider name"),
    83.1 --- a/src/share/classes/sun/security/util/Resources.java	Tue Oct 12 13:34:59 2010 -0400
    83.2 +++ b/src/share/classes/sun/security/util/Resources.java	Mon Oct 18 11:25:28 2010 -0400
    83.3 @@ -116,11 +116,9 @@
    83.4          {"X.509 extension",
    83.5                  "X.509 extension"}, //-ext
    83.6          {"output file name",
    83.7 -                "output file name"}, //-file
    83.8 +                "output file name"}, //-file and -outfile
    83.9          {"input file name",
   83.10 -                "input file name"}, //-file
   83.11 -        {"input file name",
   83.12 -                "input file name"}, //-infile
   83.13 +                "input file name"}, //-file and -infile
   83.14          {"key algorithm name",
   83.15                  "key algorithm name"}, //-keyalg
   83.16          {"key password",
   83.17 @@ -133,8 +131,6 @@
   83.18                  "new password"}, //-new
   83.19          {"do not prompt",
   83.20                  "do not prompt"}, //-noprompt
   83.21 -        {"output file name",
   83.22 -                "output file name"}, //-outfile
   83.23          {"password through protected mechanism",
   83.24                  "password through protected mechanism"}, //-protected
   83.25          {"provider argument",
   83.26 @@ -151,8 +147,8 @@
   83.27                  "signature algorithm name"}, //-sigalg
   83.28          {"source alias",
   83.29                  "source alias"}, //-srcalias
   83.30 -        {"source keystore password",
   83.31 -                "source keystore password"}, //-srckeypass
   83.32 +        {"source key password",
   83.33 +                "source key password"}, //-srckeypass
   83.34          {"source keystore name",
   83.35                  "source keystore name"}, //-srckeystore
   83.36          {"source keystore password protected",
   83.37 @@ -276,8 +272,6 @@
   83.38                  "Alias <{0}> has no certificate"},
   83.39          {"Key pair not generated, alias <alias> already exists",
   83.40                  "Key pair not generated, alias <{0}> already exists"},
   83.41 -        {"Cannot derive signature algorithm",
   83.42 -                "Cannot derive signature algorithm"},
   83.43          {"Generating keysize bit keyAlgName key pair and self-signed certificate (sigAlgName) with a validity of validality days\n\tfor: x500Name",
   83.44                  "Generating {0} bit {1} key pair and self-signed certificate ({2}) with a validity of {3} days\n\tfor: {4}"},
   83.45          {"Enter key password for <alias>", "Enter key password for <{0}>"},
   83.46 @@ -321,8 +315,6 @@
   83.47          {"Failed to parse input", "Failed to parse input"},
   83.48          {"Empty input", "Empty input"},
   83.49          {"Not X.509 certificate", "Not X.509 certificate"},
   83.50 -        {"Cannot derive signature algorithm",
   83.51 -                "Cannot derive signature algorithm"},
   83.52          {"alias has no public key", "{0} has no public key"},
   83.53          {"alias has no X.509 certificate", "{0} has no X.509 certificate"},
   83.54          {"New certificate (self-signed):", "New certificate (self-signed):"},
   83.55 @@ -552,7 +544,6 @@
   83.56          {"package name", "package name"},
   83.57          {"policy type", "policy type"},
   83.58          {"property name", "property name"},
   83.59 -        {"provider name", "provider name"},
   83.60          {"Principal List", "Principal List"},
   83.61          {"Permission List", "Permission List"},
   83.62          {"Code Base", "Code Base"},
    84.1 --- a/src/share/classes/sun/util/locale/BaseLocale.java	Tue Oct 12 13:34:59 2010 -0400
    84.2 +++ b/src/share/classes/sun/util/locale/BaseLocale.java	Mon Oct 18 11:25:28 2010 -0400
    84.3 @@ -64,12 +64,14 @@
    84.4  
    84.5      public static BaseLocale getInstance(String language, String script, String region, String variant) {
    84.6          // JDK uses deprecated ISO639.1 language codes for he, yi and id
    84.7 -        if (AsciiUtil.caseIgnoreMatch(language, "he")) {
    84.8 -            language = "iw";
    84.9 -        } else if (AsciiUtil.caseIgnoreMatch(language, "yi")) {
   84.10 -            language = "ji";
   84.11 -        } else if (AsciiUtil.caseIgnoreMatch(language, "id")) {
   84.12 -            language = "in";
   84.13 +        if (language != null) {
   84.14 +            if (AsciiUtil.caseIgnoreMatch(language, "he")) {
   84.15 +                language = "iw";
   84.16 +            } else if (AsciiUtil.caseIgnoreMatch(language, "yi")) {
   84.17 +                language = "ji";
   84.18 +            } else if (AsciiUtil.caseIgnoreMatch(language, "id")) {
   84.19 +                language = "in";
   84.20 +            }
   84.21          }
   84.22  
   84.23          Key key = new Key(language, script, region, variant);
    85.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    85.2 +++ b/src/share/demo/nio/zipfs/Demo.java	Mon Oct 18 11:25:28 2010 -0400
    85.3 @@ -0,0 +1,664 @@
    85.4 +/*
    85.5 + * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
    85.6 + *
    85.7 + * Redistribution and use in source and binary forms, with or without
    85.8 + * modification, are permitted provided that the following conditions
    85.9 + * are met:
   85.10 + *
   85.11 + *   - Redistributions of source code must retain the above copyright
   85.12 + *     notice, this list of conditions and the following disclaimer.
   85.13 + *
   85.14 + *   - Redistributions in binary form must reproduce the above copyright
   85.15 + *     notice, this list of conditions and the following disclaimer in the
   85.16 + *     documentation and/or other materials provided with the distribution.
   85.17 + *
   85.18 + *   - Neither the name of Oracle nor the names of its
   85.19 + *     contributors may be used to endorse or promote products derived
   85.20 + *     from this software without specific prior written permission.
   85.21 + *
   85.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
   85.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   85.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   85.25 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   85.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   85.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   85.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   85.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   85.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   85.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   85.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   85.33 + */
   85.34 +
   85.35 +import java.io.*;
   85.36 +import java.nio.*;
   85.37 +import java.nio.channels.*;
   85.38 +import java.nio.file.*;
   85.39 +import java.nio.file.attribute.*;
   85.40 +import java.net.*;
   85.41 +import java.text.DateFormat;
   85.42 +import java.text.SimpleDateFormat;
   85.43 +import java.util.*;
   85.44 +
   85.45 +import static java.nio.file.StandardOpenOption.*;
   85.46 +import static java.nio.file.StandardCopyOption.*;
   85.47 +
   85.48 +/*
   85.49 + * ZipFileSystem usage demo
   85.50 + *
   85.51 + * java [-cp .../zipfs.jar:./] Demo action ZipfileName [...]
   85.52 + *
   85.53 + * To deploy the provider, either copy the zipfs.jar into JDK/JRE
   85.54 + * extensions directory or add
   85.55 + *      <JDK_HOME>/demo/nio/ZipFileSystem/zipfs.jar
   85.56 + * into your class path as showed above.
   85.57 + *
   85.58 + * @author Xueming Shen
   85.59 + */
   85.60 +
   85.61 +public class Demo {
   85.62 +
   85.63 +    static enum Action {
   85.64 +        rename,          // <java Demo rename zipfile src dst>
   85.65 +                         // rename entry src to dst inside zipfile
   85.66 +
   85.67 +        movein,          // <java Demo movein zipfile src dst>
   85.68 +                         // move an external src file into zipfile
   85.69 +                         // as entry dst
   85.70 +
   85.71 +        moveout,         // <java Demo moveout zipfile src dst>
   85.72 +                         // move a zipfile entry src out to dst
   85.73 +
   85.74 +        copy,            // <java Demo copy zipfile src dst>
   85.75 +                         // copy entry src to dst inside zipfile
   85.76 +
   85.77 +        copyin,          // <java Demo copyin zipfile src dst>
   85.78 +                         // copy an external src file into zipfile
   85.79 +                         // as entry dst
   85.80 +
   85.81 +        copyout,         // <java Demo copyout zipfile src dst>
   85.82 +                         // copy zipfile entry src" out to file dst
   85.83 +
   85.84 +        zzmove,          // <java Demo zzmove zfsrc zfdst path>
   85.85 +                         // move entry path/dir from zfsrc to zfdst
   85.86 +
   85.87 +        zzcopy,          // <java Demo zzcopy zfsrc zfdst path>
   85.88 +                         // copy path from zipfile zfsrc to zipfile
   85.89 +                         // zfdst
   85.90 +
   85.91 +        attrs,           // <java Demo attrs zipfile path>
   85.92 +                         // printout the attributes of entry path
   85.93 +
   85.94 +        attrsspace,      // <java Demo attrsspace zipfile path>
   85.95 +                         // printout the storespace attrs of entry path
   85.96 +
   85.97 +        setmtime,        // <java Demo setmtime zipfile "MM/dd/yy-HH:mm:ss" path...>
   85.98 +                         // set the lastModifiedTime of entry path
   85.99 +
  85.100 +        lsdir,           // <java Demo lsdir zipfile dir>
  85.101 +                         // list dir's direct child files/dirs
  85.102 +
  85.103 +        mkdir,           // <java Demo mkdir zipfile dir>
  85.104 +
  85.105 +        mkdirs,          // <java Demo mkdirs zipfile dir>
  85.106 +
  85.107 +        rmdirs,          // <java Demo rmdirs zipfile dir>
  85.108 +
  85.109 +        list,            // <java Demo list zipfile [dir]>
  85.110 +                         // recursively list all entries of dir
  85.111 +                         // via DirectoryStream
  85.112 +
  85.113 +        tlist,           // <java Demo tlist zipfile [dir]>
  85.114 +                         // list with buildDirTree=true
  85.115 +
  85.116 +        vlist,           // <java Demo vlist zipfile [dir]>
  85.117 +                         // recursively verbose list all entries of
  85.118 +                         // dir via DirectoryStream
  85.119 +
  85.120 +        walk,            // <java Demo walk zipfile [dir]>
  85.121 +                         // recursively walk all entries of dir
  85.122 +                         // via Files.walkFileTree
  85.123 +
  85.124 +        twalk,           // <java Demo twalk zipfile [dir]>
  85.125 +                         // walk with buildDirTree=true
  85.126 +
  85.127 +        extract,         // <java Demo extract zipfile file [...]>
  85.128 +
  85.129 +        update,          // <java Demo extract zipfile file [...]>
  85.130 +
  85.131 +        delete,          // <java Demo delete zipfile file [...]>
  85.132 +
  85.133 +        add,             // <java Demo add zipfile file [...]>
  85.134 +
  85.135 +        create,          // <java Demo create zipfile file [...]>
  85.136 +                         // create a new zipfile if it doesn't exit
  85.137 +                         // and then add the file(s) into it.
  85.138 +
  85.139 +        attrs2,          // <java Demo attrs2 zipfile file [...]>
  85.140 +                         // test different ways to print attrs
  85.141 +    }
  85.142 +
  85.143 +    public static void main(String[] args) throws Throwable {
  85.144 +
  85.145 +        Action action = Action.valueOf(args[0]);;
  85.146 +        Map<String, Object> env = env = new HashMap<String, Object>();
  85.147 +        if (action == Action.create)
  85.148 +            env.put("createNew", true);
  85.149 +        if (action == Action.tlist || action == Action.twalk)
  85.150 +            env.put("buildDirTree", true);
  85.151 +
  85.152 +        FileSystem fs = FileSystems.newFileSystem(
  85.153 +                            URI.create("zip" + Paths.get(args[1]).toUri().toString().substring(4)),
  85.154 +                            env,
  85.155 +                            null);
  85.156 +        try {
  85.157 +            FileSystem fs2;
  85.158 +            Path path, src, dst;
  85.159 +            boolean isRename = false;
  85.160 +            switch (action) {
  85.161 +            case rename:
  85.162 +                src = fs.getPath(args[2]);
  85.163 +                dst = fs.getPath(args[3]);
  85.164 +                src.moveTo(dst);
  85.165 +                break;
  85.166 +            case moveout:
  85.167 +                src = fs.getPath(args[2]);
  85.168 +                dst = Paths.get(args[3]);
  85.169 +                src.moveTo(dst);
  85.170 +                break;
  85.171 +            case movein:
  85.172 +                src = Paths.get(args[2]);
  85.173 +                dst = fs.getPath(args[3]);
  85.174 +                src.moveTo(dst);
  85.175 +                break;
  85.176 +            case copy:
  85.177 +                src = fs.getPath(args[2]);
  85.178 +                dst = fs.getPath(args[3]);
  85.179 +                src.copyTo(dst);
  85.180 +                break;
  85.181 +            case copyout:
  85.182 +                src = fs.getPath(args[2]);
  85.183 +                dst = Paths.get(args[3]);
  85.184 +                src.copyTo(dst);
  85.185 +                break;
  85.186 +            case copyin:
  85.187 +                src = Paths.get(args[2]);
  85.188 +                dst = fs.getPath(args[3]);
  85.189 +                src.copyTo(dst);
  85.190 +                break;
  85.191 +            case zzmove:
  85.192 +                fs2 = FileSystems.newFileSystem(
  85.193 +                    URI.create("zip" + Paths.get(args[2]).toUri().toString().substring(4)),
  85.194 +                    env,
  85.195 +                    null);
  85.196 +                //sf1.getPath(args[3]).moveTo(fs2.getPath(args[3]));
  85.197 +                z2zmove(fs, fs2, args[3]);
  85.198 +                fs2.close();
  85.199 +                break;
  85.200 +            case zzcopy:
  85.201 +                fs2 = FileSystems.newFileSystem(
  85.202 +                    URI.create("zip" + Paths.get(args[2]).toUri().toString().substring(4)),
  85.203 +                    env,
  85.204 +                    null);
  85.205 +                //sf1.getPath(args[3]).copyTo(fs2.getPath(args[3]));
  85.206 +                z2zcopy(fs, fs2, args[3]);
  85.207 +                fs2.close();
  85.208 +                break;
  85.209 +            case attrs:
  85.210 +                for (int i = 2; i < args.length; i++) {
  85.211 +                    path = fs.getPath(args[i]);
  85.212 +                    System.out.println(
  85.213 +                        Attributes.readBasicFileAttributes(path).toString());
  85.214 +                }
  85.215 +                break;
  85.216 +            case setmtime:
  85.217 +                DateFormat df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss");
  85.218 +                Date newDatetime = df.parse(args[2]);
  85.219 +                for (int i = 3; i < args.length; i++) {
  85.220 +                    path = fs.getPath(args[i]);
  85.221 +                    path.setAttribute("lastModifiedTime",
  85.222 +                                      FileTime.fromMillis(newDatetime.getTime()));
  85.223 +                    System.out.println(
  85.224 +                        Attributes.readBasicFileAttributes(path).toString());
  85.225 +                }
  85.226 +                break;
  85.227 +            case attrsspace:
  85.228 +                path = fs.getPath("/");
  85.229 +                FileStore fstore = path.getFileStore();
  85.230 +                //System.out.println(fstore.getFileStoreAttributeView(FileStoreSpaceAttributeView.class)
  85.231 +                //                         .readAttributes());
  85.232 +                // or
  85.233 +                System.out.printf("filestore[%s]%n", fstore.name());
  85.234 +                System.out.printf("    totalSpace: %d%n",
  85.235 +                                  (Long)fstore.getAttribute("space:totalSpace"));
  85.236 +                System.out.printf("   usableSpace: %d%n",
  85.237 +                                  (Long)fstore.getAttribute("space:usableSpace"));
  85.238 +                System.out.printf("  unallocSpace: %d%n",
  85.239 +                                  (Long)fstore.getAttribute("space:unallocatedSpace"));
  85.240 +                break;
  85.241 +            case list:
  85.242 +            case tlist:
  85.243 +                if (args.length < 3)
  85.244 +                    list(fs.getPath("/"), false);
  85.245 +                else
  85.246 +                    list(fs.getPath(args[2]), false);
  85.247 +                break;
  85.248 +            case vlist:
  85.249 +                if (args.length < 3)
  85.250 +                    list(fs.getPath("/"), true);
  85.251 +                else
  85.252 +                    list(fs.getPath(args[2]), true);
  85.253 +                break;
  85.254 +            case twalk:
  85.255 +            case walk:
  85.256 +                walk(fs.getPath((args.length > 2)? args[2] : "/"));
  85.257 +                break;
  85.258 +            case extract:
  85.259 +                if (args.length == 2) {
  85.260 +                     extract(fs, "/");
  85.261 +                } else {
  85.262 +                    for (int i = 2; i < args.length; i++) {
  85.263 +                        extract(fs, args[i]);
  85.264 +                    }
  85.265 +                }
  85.266 +                break;
  85.267 +            case delete:
  85.268 +                for (int i = 2; i < args.length; i++)
  85.269 +                    fs.getPath(args[i]).delete();
  85.270 +                break;
  85.271 +            case create:
  85.272 +            case add:
  85.273 +            case update:
  85.274 +                for (int i = 2; i < args.length; i++) {
  85.275 +                    update(fs, args[i]);
  85.276 +                }
  85.277 +                break;
  85.278 +            case lsdir:
  85.279 +                path = fs.getPath(args[2]);
  85.280 +                final String fStr = (args.length > 3)?args[3]:"";
  85.281 +                DirectoryStream<Path> ds = path.newDirectoryStream(
  85.282 +                    new DirectoryStream.Filter<Path>() {
  85.283 +                        public boolean accept(Path path) {
  85.284 +                            return path.toString().contains(fStr);
  85.285 +                        }
  85.286 +                    });
  85.287 +                for (Path p : ds)
  85.288 +                    System.out.println(p);
  85.289 +                break;
  85.290 +            case mkdir:
  85.291 +                fs.getPath(args[2]).createDirectory();
  85.292 +                break;
  85.293 +            case mkdirs:
  85.294 +                mkdirs(fs.getPath(args[2]));
  85.295 +                break;
  85.296 +            case attrs2:
  85.297 +                for (int i = 2; i < args.length; i++) {
  85.298 +                    path = fs.getPath(args[i]);
  85.299 +                    System.out.println("-------(1)---------");
  85.300 +                    System.out.println(
  85.301 +                        Attributes.readBasicFileAttributes(path).toString());
  85.302 +                    System.out.println("-------(2)---------");
  85.303 +                    Map<String, ?> map = path.readAttributes("zip:*");
  85.304 +                    for (Map.Entry<String, ?> e : map.entrySet()) {
  85.305 +                        System.out.printf("    %s : %s%n", e.getKey(), e.getValue());
  85.306 +                    }
  85.307 +                    System.out.println("-------(3)---------");
  85.308 +                    map = path.readAttributes("size,lastModifiedTime,isDirectory");
  85.309 +                    for (Map.Entry<String, ?> e : map.entrySet()) {
  85.310 +                        System.out.printf("    %s : %s%n", e.getKey(), e.getValue());
  85.311 +                    }
  85.312 +                }
  85.313 +                break;
  85.314 +            }
  85.315 +        } catch (Exception x) {
  85.316 +            x.printStackTrace();
  85.317 +        } finally {
  85.318 +            if (fs != null)
  85.319 +                fs.close();
  85.320 +        }
  85.321 +    }
  85.322 +
  85.323 +    private static byte[] getBytes(String name) {
  85.324 +        return name.getBytes();
  85.325 +    }
  85.326 +
  85.327 +    private static String getString(byte[] name) {
  85.328 +        return new String(name);
  85.329 +    }
  85.330 +
  85.331 +    private static void walk(Path path) throws IOException
  85.332 +    {
  85.333 +        Files.walkFileTree(
  85.334 +            path,
  85.335 +            new SimpleFileVisitor<Path>() {
  85.336 +                private int indent = 0;
  85.337 +                private void indent() {
  85.338 +                    int n = 0;
  85.339 +                    while (n++ < indent)
  85.340 +                        System.out.printf(" ");
  85.341 +                }
  85.342 +
  85.343 +                @Override
  85.344 +                public FileVisitResult visitFile(Path file,
  85.345 +                                                 BasicFileAttributes attrs)
  85.346 +                {
  85.347 +                    indent();
  85.348 +                    System.out.printf("%s%n", file.getName().toString());
  85.349 +                    return FileVisitResult.CONTINUE;
  85.350 +                }
  85.351 +
  85.352 +                @Override
  85.353 +                public FileVisitResult preVisitDirectory(Path dir,
  85.354 +                                                         BasicFileAttributes attrs)
  85.355 +                {
  85.356 +                    indent();
  85.357 +                    System.out.printf("[%s]%n", dir.toString());
  85.358 +                    indent += 2;
  85.359 +                    return FileVisitResult.CONTINUE;
  85.360 +                }
  85.361 +
  85.362 +                @Override
  85.363 +                public FileVisitResult postVisitDirectory(Path dir,
  85.364 +                                                          IOException ioe)
  85.365 +                {
  85.366 +                    indent -= 2;
  85.367 +                    return FileVisitResult.CONTINUE;
  85.368 +                }
  85.369 +        });
  85.370 +    }
  85.371 +
  85.372 +    private static void update(FileSystem fs, String path) throws Throwable{
  85.373 +        Path src = FileSystems.getDefault().getPath(path);
  85.374 +        if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) {
  85.375 +            DirectoryStream<Path> ds = src.newDirectoryStream();
  85.376 +            for (Path child : ds)
  85.377 +                update(fs, child.toString());
  85.378 +            ds.close();
  85.379 +        } else {
  85.380 +            Path dst = fs.getPath(path);
  85.381 +            Path parent = dst.getParent();
  85.382 +            if (parent != null && parent.notExists())
  85.383 +                mkdirs(parent);
  85.384 +            src.copyTo(dst, REPLACE_EXISTING);
  85.385 +        }
  85.386 +    }
  85.387 +
  85.388 +    private static void extract(FileSystem fs, String path) throws Throwable{
  85.389 +        Path src = fs.getPath(path);
  85.390 +        if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) {
  85.391 +            DirectoryStream<Path> ds = src.newDirectoryStream();
  85.392 +            for (Path child : ds)
  85.393 +                extract(fs, child.toString());
  85.394 +            ds.close();
  85.395 +        } else {
  85.396 +            if (path.startsWith("/"))
  85.397 +                path = path.substring(1);
  85.398 +            Path dst = FileSystems.getDefault().getPath(path);
  85.399 +            Path parent = dst.getParent();
  85.400 +            if (parent.notExists())
  85.401 +                mkdirs(parent);
  85.402 +            src.copyTo(dst, REPLACE_EXISTING);
  85.403 +        }
  85.404 +    }
  85.405 +
  85.406 +    // use DirectoryStream
  85.407 +    private static void z2zcopy(FileSystem src, FileSystem dst, String path)
  85.408 +        throws IOException
  85.409 +    {
  85.410 +        Path srcPath = src.getPath(path);
  85.411 +        Path dstPath = dst.getPath(path);
  85.412 +
  85.413 +        if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) {
  85.414 +            if (!dstPath.exists()) {
  85.415 +                try {
  85.416 +                    mkdirs(dstPath);
  85.417 +                } catch (FileAlreadyExistsException x) {}
  85.418 +            }
  85.419 +            DirectoryStream<Path> ds = srcPath.newDirectoryStream();
  85.420 +            for (Path child : ds) {
  85.421 +                z2zcopy(src, dst,
  85.422 +                        path + (path.endsWith("/")?"":"/") + child.getName());
  85.423 +            }
  85.424 +            ds.close();
  85.425 +        } else {
  85.426 +            //System.out.println("copying..." + path);
  85.427 +            srcPath.copyTo(dstPath);
  85.428 +        }
  85.429 +    }
  85.430 +
  85.431 +    // use TreeWalk to move
  85.432 +    private static void z2zmove(FileSystem src, FileSystem dst, String path)
  85.433 +        throws IOException
  85.434 +    {
  85.435 +        final Path srcPath = src.getPath(path).toAbsolutePath();
  85.436 +        final Path dstPath = dst.getPath(path).toAbsolutePath();
  85.437 +
  85.438 +        Files.walkFileTree(srcPath, new SimpleFileVisitor<Path>() {
  85.439 +
  85.440 +            @Override
  85.441 +            public FileVisitResult visitFile(Path file,
  85.442 +                                            BasicFileAttributes attrs)
  85.443 +            {
  85.444 +                Path dst = srcPath.relativize(file);
  85.445 +                dst = dstPath.resolve(dst);
  85.446 +                try {
  85.447 +                    Path parent = dstPath.getParent();
  85.448 +                    if (parent != null && parent.notExists())
  85.449 +                        mkdirs(parent);
  85.450 +                    file.moveTo(dst);
  85.451 +                } catch (IOException x) {
  85.452 +                    x.printStackTrace();
  85.453 +                }
  85.454 +                return FileVisitResult.CONTINUE;
  85.455 +            }
  85.456 +
  85.457 +            @Override
  85.458 +            public FileVisitResult preVisitDirectory(Path dir,
  85.459 +                                                     BasicFileAttributes attrs)
  85.460 +            {
  85.461 +                Path dst = srcPath.relativize(dir);
  85.462 +                dst = dstPath.resolve(dst);
  85.463 +                try {
  85.464 +
  85.465 +                    if (dst.notExists())
  85.466 +                        mkdirs(dst);
  85.467 +                } catch (IOException x) {
  85.468 +                    x.printStackTrace();
  85.469 +                }
  85.470 +                return FileVisitResult.CONTINUE;
  85.471 +            }
  85.472 +
  85.473 +            @Override
  85.474 +            public FileVisitResult postVisitDirectory(Path dir,
  85.475 +                                                      IOException ioe)
  85.476 +                throws IOException
  85.477 +            {
  85.478 +                try {
  85.479 +                    dir.delete();
  85.480 +                } catch (IOException x) {
  85.481 +                    //x.printStackTrace();
  85.482 +                }
  85.483 +                return FileVisitResult.CONTINUE;
  85.484 +            }
  85.485 +        });
  85.486 +
  85.487 +    }
  85.488 +
  85.489 +    private static void mkdirs(Path path) throws IOException {
  85.490 +        path = path.toAbsolutePath();
  85.491 +        Path parent = path.getParent();
  85.492 +        if (parent != null) {
  85.493 +            if (parent.notExists())
  85.494 +                mkdirs(parent);
  85.495 +        }
  85.496 +        path.createDirectory();
  85.497 +    }
  85.498 +
  85.499 +    private static void rmdirs(Path path) throws IOException {
  85.500 +        while (path != null && path.getNameCount() != 0) {
  85.501 +            path.delete();
  85.502 +            path = path.getParent();
  85.503 +        }
  85.504 +    }
  85.505 +
  85.506 +    private static void list(Path path, boolean verbose ) throws IOException {
  85.507 +        if (verbose)
  85.508 +            System.out.println(Attributes.readBasicFileAttributes(path).toString());
  85.509 +        else
  85.510 +            System.out.printf("  %s%n", path.toString());
  85.511 +        if (path.notExists())
  85.512 +            return;
  85.513 +        if (Attributes.readBasicFileAttributes(path).isDirectory()) {
  85.514 +            DirectoryStream<Path> ds = path.newDirectoryStream();
  85.515 +            for (Path child : ds)
  85.516 +                list(child, verbose);
  85.517 +            ds.close();
  85.518 +        }
  85.519 +    }
  85.520 +
  85.521 +    // check the content of two paths are equal
  85.522 +    private static void checkEqual(Path src, Path dst) throws IOException
  85.523 +    {
  85.524 +        //System.out.printf("checking <%s> vs <%s>...%n",
  85.525 +        //                  src.toString(), dst.toString());
  85.526 +
  85.527 +        //streams
  85.528 +        InputStream isSrc = src.newInputStream();
  85.529 +        InputStream isDst = dst.newInputStream();
  85.530 +        byte[] bufSrc = new byte[8192];
  85.531 +        byte[] bufDst = new byte[8192];
  85.532 +
  85.533 +        try {
  85.534 +            int nSrc = 0;
  85.535 +            while ((nSrc = isSrc.read(bufSrc)) != -1) {
  85.536 +                int nDst = 0;
  85.537 +                while (nDst < nSrc) {
  85.538 +                    int n = isDst.read(bufDst, nDst, nSrc - nDst);
  85.539 +                    if (n == -1) {
  85.540 +                        System.out.printf("checking <%s> vs <%s>...%n",
  85.541 +                                          src.toString(), dst.toString());
  85.542 +                        throw new RuntimeException("CHECK FAILED!");
  85.543 +                    }
  85.544 +                    nDst += n;
  85.545 +                }
  85.546 +                while (--nSrc >= 0) {
  85.547 +                    if (bufSrc[nSrc] != bufDst[nSrc]) {
  85.548 +                        System.out.printf("checking <%s> vs <%s>...%n",
  85.549 +                                          src.toString(), dst.toString());
  85.550 +                        throw new RuntimeException("CHECK FAILED!");
  85.551 +                    }
  85.552 +                    nSrc--;
  85.553 +                }
  85.554 +            }
  85.555 +        } finally {
  85.556 +            isSrc.close();
  85.557 +            isDst.close();
  85.558 +        }
  85.559 +
  85.560 +        // channels
  85.561 +        SeekableByteChannel chSrc = src.newByteChannel();
  85.562 +        SeekableByteChannel chDst = dst.newByteChannel();
  85.563 +        if (chSrc.size() != chDst.size()) {
  85.564 +            System.out.printf("src[%s].size=%d, dst[%s].size=%d%n",
  85.565 +                              chSrc.toString(), chSrc.size(),
  85.566 +                              chDst.toString(), chDst.size());
  85.567 +            throw new RuntimeException("CHECK FAILED!");
  85.568 +        }
  85.569 +        ByteBuffer bbSrc = ByteBuffer.allocate(8192);
  85.570 +        ByteBuffer bbDst = ByteBuffer.allocate(8192);
  85.571 +
  85.572 +        try {
  85.573 +            int nSrc = 0;
  85.574 +            while ((nSrc = chSrc.read(bbSrc)) != -1) {
  85.575 +                int nDst = chDst.read(bbDst);
  85.576 +                if (nSrc != nDst) {
  85.577 +                    System.out.printf("checking <%s> vs <%s>...%n",
  85.578 +                                      src.toString(), dst.toString());
  85.579 +                    throw new RuntimeException("CHECK FAILED!");
  85.580 +                }
  85.581 +                while (--nSrc >= 0) {
  85.582 +                    if (bbSrc.get(nSrc) != bbDst.get(nSrc)) {
  85.583 +                        System.out.printf("checking <%s> vs <%s>...%n",
  85.584 +                                          src.toString(), dst.toString());
  85.585 +                        throw new RuntimeException("CHECK FAILED!");
  85.586 +                    }
  85.587 +                    nSrc--;
  85.588 +                }
  85.589 +                bbSrc.flip();
  85.590 +                bbDst.flip();
  85.591 +            }
  85.592 +        } catch (IOException x) {
  85.593 +            x.printStackTrace();
  85.594 +        } finally {
  85.595 +            chSrc.close();
  85.596 +            chDst.close();
  85.597 +        }
  85.598 +    }
  85.599 +
  85.600 +    private static void fchCopy(Path src, Path dst) throws IOException
  85.601 +    {
  85.602 +        Set<OpenOption> read = new HashSet<>();
  85.603 +        read.add(READ);
  85.604 +        Set<OpenOption> openwrite = new HashSet<>();
  85.605 +        openwrite.add(CREATE_NEW);
  85.606 +        openwrite.add(WRITE);
  85.607 +
  85.608 +        FileChannel srcFc = src.getFileSystem()
  85.609 +                               .provider()
  85.610 +                               .newFileChannel(src, read);
  85.611 +        FileChannel dstFc = dst.getFileSystem()
  85.612 +                               .provider()
  85.613 +                               .newFileChannel(dst, openwrite);
  85.614 +
  85.615 +        try {
  85.616 +            ByteBuffer bb = ByteBuffer.allocate(8192);
  85.617 +            while (srcFc.read(bb) >= 0) {
  85.618 +                bb.flip();
  85.619 +                dstFc.write(bb);
  85.620 +                bb.clear();
  85.621 +            }
  85.622 +        } finally {
  85.623 +            srcFc.close();
  85.624 +            dstFc.close();
  85.625 +        }
  85.626 +    }
  85.627 +
  85.628 +    private static void chCopy(Path src, Path dst) throws IOException
  85.629 +    {
  85.630 +        Set<OpenOption> read = new HashSet<>();
  85.631 +        read.add(READ);
  85.632 +        Set<OpenOption> openwrite = new HashSet<>();
  85.633 +        openwrite.add(CREATE_NEW);
  85.634 +        openwrite.add(WRITE);
  85.635 +
  85.636 +        SeekableByteChannel srcCh = src.newByteChannel(read);
  85.637 +        SeekableByteChannel dstCh = dst.newByteChannel(openwrite);
  85.638 +
  85.639 +        try {
  85.640 +            ByteBuffer bb = ByteBuffer.allocate(8192);
  85.641 +            while (srcCh.read(bb) >= 0) {
  85.642 +                bb.flip();
  85.643 +                dstCh.write(bb);
  85.644 +                bb.clear();
  85.645 +            }
  85.646 +        } finally {
  85.647 +            srcCh.close();
  85.648 +            dstCh.close();
  85.649 +        }
  85.650 +    }
  85.651 +
  85.652 +    private static void streamCopy(Path src, Path dst) throws IOException
  85.653 +    {
  85.654 +        InputStream isSrc = src.newInputStream();
  85.655 +        OutputStream osDst = dst.newOutputStream();
  85.656 +        byte[] buf = new byte[8192];
  85.657 +        try {
  85.658 +            int n = 0;
  85.659 +            while ((n = isSrc.read(buf)) != -1) {
  85.660 +                osDst.write(buf, 0, n);
  85.661 +            }
  85.662 +        } finally {
  85.663 +            isSrc.close();
  85.664 +            osDst.close();
  85.665 +        }
  85.666 +    }
  85.667 +}
    86.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    86.2 +++ b/src/share/demo/nio/zipfs/META-INF/services/java.nio.file.spi.FileSystemProvider	Mon Oct 18 11:25:28 2010 -0400
    86.3 @@ -0,0 +1,3 @@
    86.4 +com.sun.nio.zipfs.ZipFileSystemProvider
    86.5 +com.sun.nio.zipfs.JarFileSystemProvider
    86.6 +
    87.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    87.2 +++ b/src/share/demo/nio/zipfs/README.txt	Mon Oct 18 11:25:28 2010 -0400
    87.3 @@ -0,0 +1,29 @@
    87.4 +ZipFileSystem is a file system provider that treats the contents of a zip or
    87.5 +JAR file as a java.nio.file.FileSystem.
    87.6 +
    87.7 +To deploy the provider you must copy zipfs.jar into your extensions
    87.8 +directory or else add <JDK_HOME>/demo/nio/ZipFileSystem/zipfs.jar
    87.9 +to your class path.
   87.10 +
   87.11 +The factory methods defined by the java.nio.file.FileSystems class can be
   87.12 +used to create a FileSystem, eg:
   87.13 +
   87.14 +   // use file type detection
   87.15 +   Map<String,?> env = Collections.emptyMap();
   87.16 +   Path jarfile = Path.get("foo.jar");
   87.17 +   FileSystem fs = FileSystems.newFileSystem(jarfile, env);
   87.18 +
   87.19 +-or
   87.20 +
   87.21 +   // locate file system by URI
   87.22 +   Map<String,?> env = Collections.emptyMap();
   87.23 +   URI uri = URI.create("zip:///mydir/foo.jar");
   87.24 +   FileSystem fs = FileSystems.newFileSystem(uri, env);
   87.25 +
   87.26 +Once a FileSystem is created then classes in the java.nio.file package
   87.27 +can be used to access files in the zip/JAR file, eg:
   87.28 +
   87.29 +   Path mf = fs.getPath("/META-INF/MANIFEST.MF");
   87.30 +   InputStream in = mf.newInputStream();
   87.31 +
   87.32 +
    88.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    88.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/JarFileSystemProvider.java	Mon Oct 18 11:25:28 2010 -0400
    88.3 @@ -0,0 +1,71 @@
    88.4 +/*
    88.5 + * Copyright 2007-2008 Sun Microsystems, Inc.  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 Sun Microsystems 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 +package com.sun.nio.zipfs;
   88.35 +
   88.36 +import java.nio.file.*;
   88.37 +import java.nio.file.spi.*;
   88.38 +import java.nio.file.attribute.*;
   88.39 +import java.nio.file.spi.FileSystemProvider;
   88.40 +
   88.41 +import java.net.URI;
   88.42 +import java.io.IOException;
   88.43 +import java.net.URISyntaxException;
   88.44 +import java.nio.channels.FileChannel;
   88.45 +import java.util.HashMap;
   88.46 +import java.util.Map;
   88.47 +import java.util.Set;
   88.48 +
   88.49 +public class JarFileSystemProvider extends ZipFileSystemProvider
   88.50 +{
   88.51 +
   88.52 +    @Override
   88.53 +    public String getScheme() {
   88.54 +        return "jar";
   88.55 +    }
   88.56 +
   88.57 +    @Override
   88.58 +    protected Path uriToPath(URI uri) {
   88.59 +        String scheme = uri.getScheme();
   88.60 +        if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) {
   88.61 +            throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'");
   88.62 +        }
   88.63 +        try {
   88.64 +            String uristr = uri.toString();
   88.65 +            int end = uristr.indexOf("!/");
   88.66 +            uristr = uristr.substring(4, (end == -1) ? uristr.length() : end);
   88.67 +            uri = new URI(uristr);
   88.68 +            return Paths.get(new URI("file", uri.getHost(), uri.getPath(), null))
   88.69 +                        .toAbsolutePath();
   88.70 +        } catch (URISyntaxException e) {
   88.71 +            throw new AssertionError(e); //never thrown
   88.72 +        }
   88.73 +    }
   88.74 +}
    89.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    89.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipCoder.java	Mon Oct 18 11:25:28 2010 -0400
    89.3 @@ -0,0 +1,160 @@
    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 +import java.nio.CharBuffer;
   89.39 +import java.nio.charset.Charset;
   89.40 +import java.nio.charset.CharsetDecoder;
   89.41 +import java.nio.charset.CharsetEncoder;
   89.42 +import java.nio.charset.CoderResult;
   89.43 +import java.nio.charset.CodingErrorAction;
   89.44 +import java.util.Arrays;
   89.45 +
   89.46 +/**
   89.47 + * Utility class for zipfile name and comment decoding and encoding
   89.48 + *
   89.49 + * @author  Xueming Shen
   89.50 + */
   89.51 +
   89.52 +final class ZipCoder {
   89.53 +
   89.54 +    String toString(byte[] ba, int length) {
   89.55 +        CharsetDecoder cd = decoder().reset();
   89.56 +        int len = (int)(length * cd.maxCharsPerByte());
   89.57 +        char[] ca = new char[len];
   89.58 +        if (len == 0)
   89.59 +            return new String(ca);
   89.60 +        ByteBuffer bb = ByteBuffer.wrap(ba, 0, length);
   89.61 +        CharBuffer cb = CharBuffer.wrap(ca);
   89.62 +        CoderResult cr = cd.decode(bb, cb, true);
   89.63 +        if (!cr.isUnderflow())
   89.64 +            throw new IllegalArgumentException(cr.toString());
   89.65 +        cr = cd.flush(cb);
   89.66 +        if (!cr.isUnderflow())
   89.67 +            throw new IllegalArgumentException(cr.toString());
   89.68 +        return new String(ca, 0, cb.position());
   89.69 +    }
   89.70 +
   89.71 +    String toString(byte[] ba) {
   89.72 +        return toString(ba, ba.length);
   89.73 +    }
   89.74 +
   89.75 +    byte[] getBytes(String s) {
   89.76 +        CharsetEncoder ce = encoder().reset();
   89.77 +        char[] ca = s.toCharArray();
   89.78 +        int len = (int)(ca.length * ce.maxBytesPerChar());
   89.79 +        byte[] ba = new byte[len];
   89.80 +        if (len == 0)
   89.81 +            return ba;
   89.82 +        ByteBuffer bb = ByteBuffer.wrap(ba);
   89.83 +        CharBuffer cb = CharBuffer.wrap(ca);
   89.84 +        CoderResult cr = ce.encode(cb, bb, true);
   89.85 +        if (!cr.isUnderflow())
   89.86 +            throw new IllegalArgumentException(cr.toString());
   89.87 +        cr = ce.flush(bb);
   89.88 +        if (!cr.isUnderflow())
   89.89 +            throw new IllegalArgumentException(cr.toString());
   89.90 +        if (bb.position() == ba.length)  // defensive copy?
   89.91 +            return ba;
   89.92 +        else
   89.93 +            return Arrays.copyOf(ba, bb.position());
   89.94 +    }
   89.95 +
   89.96 +    // assume invoked only if "this" is not utf8
   89.97 +    byte[] getBytesUTF8(String s) {
   89.98 +        if (isutf8)
   89.99 +            return getBytes(s);
  89.100 +        if (utf8 == null)
  89.101 +            utf8 = new ZipCoder(Charset.forName("UTF-8"));
  89.102 +        return utf8.getBytes(s);
  89.103 +    }
  89.104 +
  89.105 +    String toStringUTF8(byte[] ba, int len) {
  89.106 +        if (isutf8)
  89.107 +            return toString(ba, len);
  89.108 +        if (utf8 == null)
  89.109 +            utf8 = new ZipCoder(Charset.forName("UTF-8"));
  89.110 +        return utf8.toString(ba, len);
  89.111 +    }
  89.112 +
  89.113 +    boolean isUTF8() {
  89.114 +        return isutf8;
  89.115 +    }
  89.116 +
  89.117 +    private Charset cs;
  89.118 +    private boolean isutf8;
  89.119 +    private ZipCoder utf8;
  89.120 +
  89.121 +    private ZipCoder(Charset cs) {
  89.122 +        this.cs = cs;
  89.123 +        this.isutf8 = cs.name().equals("UTF-8");
  89.124 +    }
  89.125 +
  89.126 +    static ZipCoder get(Charset charset) {
  89.127 +        return new ZipCoder(charset);
  89.128 +    }
  89.129 +
  89.130 +    static ZipCoder get(String csn) {
  89.131 +        try {
  89.132 +            return new ZipCoder(Charset.forName(csn));
  89.133 +        } catch (Throwable t) {
  89.134 +            t.printStackTrace();
  89.135 +        }
  89.136 +        return new ZipCoder(Charset.defaultCharset());
  89.137 +    }
  89.138 +
  89.139 +    private final ThreadLocal<CharsetDecoder> decTL = new ThreadLocal<>();
  89.140 +    private final ThreadLocal<CharsetEncoder> encTL = new ThreadLocal<>();
  89.141 +
  89.142 +    private CharsetDecoder decoder() {
  89.143 +        CharsetDecoder dec = decTL.get();
  89.144 +        if (dec == null) {
  89.145 +            dec = cs.newDecoder()
  89.146 +              .onMalformedInput(CodingErrorAction.REPORT)
  89.147 +              .onUnmappableCharacter(CodingErrorAction.REPORT);
  89.148 +            decTL.set(dec);
  89.149 +        }
  89.150 +        return dec;
  89.151 +    }
  89.152 +
  89.153 +    private CharsetEncoder encoder() {
  89.154 +        CharsetEncoder enc = encTL.get();
  89.155 +        if (enc == null) {
  89.156 +            enc = cs.newEncoder()
  89.157 +              .onMalformedInput(CodingErrorAction.REPORT)
  89.158 +              .onUnmappableCharacter(CodingErrorAction.REPORT);
  89.159 +            encTL.set(enc);
  89.160 +        }
  89.161 +        return enc;
  89.162 +    }
  89.163 +}
    90.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    90.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipConstants.java	Mon Oct 18 11:25:28 2010 -0400
    90.3 @@ -0,0 +1,261 @@
    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.ByteBuffer;
   90.38 +
   90.39 +/**
   90.40 + *
   90.41 + * @author Xueming Shen
   90.42 + */
   90.43 +
   90.44 +class ZipConstants {
   90.45 +    /*
   90.46 +     * Compression methods
   90.47 +     */
   90.48 +    static final int METHOD_STORED     = 0;
   90.49 +    static final int METHOD_DEFLATED   = 8;
   90.50 +    static final int METHOD_DEFLATED64 = 9;
   90.51 +    static final int METHOD_BZIP2      = 12;
   90.52 +    static final int METHOD_LZMA       = 14;
   90.53 +    static final int METHOD_LZ77       = 19;
   90.54 +
   90.55 +    /*
   90.56 +     * General purpose big flag
   90.57 +     */
   90.58 +    static final int FLAG_ENCRYPTED  = 0x01;
   90.59 +    static final int FLAG_DATADESCR  = 0x08;    // crc, size and csize in dd
   90.60 +    static final int FLAG_EFS        = 0x800;   // If this bit is set the filename and
   90.61 +                                                // comment fields for this file must be
   90.62 +                                                // encoded using UTF-8.
   90.63 +    /*
   90.64 +     * Header signatures
   90.65 +     */
   90.66 +    static long LOCSIG = 0x04034b50L;   // "PK\003\004"
   90.67 +    static long EXTSIG = 0x08074b50L;   // "PK\007\008"
   90.68 +    static long CENSIG = 0x02014b50L;   // "PK\001\002"
   90.69 +    static long ENDSIG = 0x06054b50L;   // "PK\005\006"
   90.70 +
   90.71 +    /*
   90.72 +     * Header sizes in bytes (including signatures)
   90.73 +     */
   90.74 +    static final int LOCHDR = 30;       // LOC header size
   90.75 +    static final int EXTHDR = 16;       // EXT header size
   90.76 +    static final int CENHDR = 46;       // CEN header size
   90.77 +    static final int ENDHDR = 22;       // END header size
   90.78 +
   90.79 +    /*
   90.80 +     * Local file (LOC) header field offsets
   90.81 +     */
   90.82 +    static final int LOCVER = 4;        // version needed to extract
   90.83 +    static final int LOCFLG = 6;        // general purpose bit flag
   90.84 +    static final int LOCHOW = 8;        // compression method
   90.85 +    static final int LOCTIM = 10;       // modification time
   90.86 +    static final int LOCCRC = 14;       // uncompressed file crc-32 value
   90.87 +    static final int LOCSIZ = 18;       // compressed size
   90.88 +    static final int LOCLEN = 22;       // uncompressed size
   90.89 +    static final int LOCNAM = 26;       // filename length
   90.90 +    static final int LOCEXT = 28;       // extra field length
   90.91 +
   90.92 +    /*
   90.93 +     * Extra local (EXT) header field offsets
   90.94 +     */
   90.95 +    static final int EXTCRC = 4;        // uncompressed file crc-32 value
   90.96 +    static final int EXTSIZ = 8;        // compressed size
   90.97 +    static final int EXTLEN = 12;       // uncompressed size
   90.98 +
   90.99 +    /*
  90.100 +     * Central directory (CEN) header field offsets
  90.101 +     */
  90.102 +    static final int CENVEM = 4;        // version made by
  90.103 +    static final int CENVER = 6;        // version needed to extract
  90.104 +    static final int CENFLG = 8;        // encrypt, decrypt flags
  90.105 +    static final int CENHOW = 10;       // compression method
  90.106 +    static final int CENTIM = 12;       // modification time
  90.107 +    static final int CENCRC = 16;       // uncompressed file crc-32 value
  90.108 +    static final int CENSIZ = 20;       // compressed size
  90.109 +    static final int CENLEN = 24;       // uncompressed size
  90.110 +    static final int CENNAM = 28;       // filename length
  90.111 +    static final int CENEXT = 30;       // extra field length
  90.112 +    static final int CENCOM = 32;       // comment length
  90.113 +    static final int CENDSK = 34;       // disk number start
  90.114 +    static final int CENATT = 36;       // internal file attributes
  90.115 +    static final int CENATX = 38;       // external file attributes
  90.116 +    static final int CENOFF = 42;       // LOC header offset
  90.117 +
  90.118 +    /*
  90.119 +     * End of central directory (END) header field offsets
  90.120 +     */
  90.121 +    static final int ENDSUB = 8;        // number of entries on this disk
  90.122 +    static final int ENDTOT = 10;       // total number of entries
  90.123 +    static final int ENDSIZ = 12;       // central directory size in bytes
  90.124 +    static final int ENDOFF = 16;       // offset of first CEN header
  90.125 +    static final int ENDCOM = 20;       // zip file comment length
  90.126 +
  90.127 +    /*
  90.128 +     * ZIP64 constants
  90.129 +     */
  90.130 +    static final long ZIP64_ENDSIG = 0x06064b50L;  // "PK\006\006"
  90.131 +    static final long ZIP64_LOCSIG = 0x07064b50L;  // "PK\006\007"
  90.132 +    static final int  ZIP64_ENDHDR = 56;           // ZIP64 end header size
  90.133 +    static final int  ZIP64_LOCHDR = 20;           // ZIP64 end loc header size
  90.134 +    static final int  ZIP64_EXTHDR = 24;           // EXT header size
  90.135 +    static final int  ZIP64_EXTID  = 0x0001;       // Extra field Zip64 header ID
  90.136 +
  90.137 +    static final int  ZIP64_MINVAL32 = 0xFFFF;
  90.138 +    static final long ZIP64_MINVAL = 0xFFFFFFFFL;
  90.139 +
  90.140 +    /*
  90.141 +     * Zip64 End of central directory (END) header field offsets
  90.142 +     */
  90.143 +    static final int  ZIP64_ENDLEN = 4;       // size of zip64 end of central dir
  90.144 +    static final int  ZIP64_ENDVEM = 12;      // version made by
  90.145 +    static final int  ZIP64_ENDVER = 14;      // version needed to extract
  90.146 +    static final int  ZIP64_ENDNMD = 16;      // number of this disk
  90.147 +    static final int  ZIP64_ENDDSK = 20;      // disk number of start
  90.148 +    static final int  ZIP64_ENDTOD = 24;      // total number of entries on this disk
  90.149 +    static final int  ZIP64_ENDTOT = 32;      // total number of entries
  90.150 +    static final int  ZIP64_ENDSIZ = 40;      // central directory size in bytes
  90.151 +    static final int  ZIP64_ENDOFF = 48;      // offset of first CEN header
  90.152 +    static final int  ZIP64_ENDEXT = 56;      // zip64 extensible data sector
  90.153 +
  90.154 +    /*
  90.155 +     * Zip64 End of central directory locator field offsets
  90.156 +     */
  90.157 +    static final int  ZIP64_LOCDSK = 4;       // disk number start
  90.158 +    static final int  ZIP64_LOCOFF = 8;       // offset of zip64 end
  90.159 +    static final int  ZIP64_LOCTOT = 16;      // total number of disks
  90.160 +
  90.161 +    /*
  90.162 +     * Zip64 Extra local (EXT) header field offsets
  90.163 +     */
  90.164 +    static final int  ZIP64_EXTCRC = 4;       // uncompressed file crc-32 value
  90.165 +    static final int  ZIP64_EXTSIZ = 8;       // compressed size, 8-byte
  90.166 +    static final int  ZIP64_EXTLEN = 16;      // uncompressed size, 8-byte
  90.167 +
  90.168 +    /*
  90.169 +     * Extra field header ID
  90.170 +     */
  90.171 +    static final int  EXTID_ZIP64 = 0x0001;      // ZIP64
  90.172 +    static final int  EXTID_NTFS  = 0x000a;      // NTFS
  90.173 +    static final int  EXTID_UNIX  = 0x000d;      // UNIX
  90.174 +
  90.175 +
  90.176 +    /*
  90.177 +     * fields access methods
  90.178 +     */
  90.179 +    ///////////////////////////////////////////////////////
  90.180 +    static final int CH(byte[] b, int n) {
  90.181 +       return b[n] & 0xff;
  90.182 +    }
  90.183 +
  90.184 +    static final int SH(byte[] b, int n) {
  90.185 +        return (b[n] & 0xff) | ((b[n + 1] & 0xff) << 8);
  90.186 +    }
  90.187 +
  90.188 +    static final long LG(byte[] b, int n) {
  90.189 +        return ((SH(b, n)) | (SH(b, n + 2) << 16)) & 0xffffffffL;
  90.190 +    }
  90.191 +
  90.192 +    static final long LL(byte[] b, int n) {
  90.193 +        return (LG(b, n)) | (LG(b, n + 4) << 32);
  90.194 +    }
  90.195 +
  90.196 +    static final long GETSIG(byte[] b) {
  90.197 +        return LG(b, 0);
  90.198 +    }
  90.199 +
  90.200 +    // local file (LOC) header fields
  90.201 +    static final long LOCSIG(byte[] b) { return LG(b, 0); } // signature
  90.202 +    static final int  LOCVER(byte[] b) { return SH(b, 4); } // version needed to extract
  90.203 +    static final int  LOCFLG(byte[] b) { return SH(b, 6); } // general purpose bit flags
  90.204 +    static final int  LOCHOW(byte[] b) { return SH(b, 8); } // compression method
  90.205 +    static final long LOCTIM(byte[] b) { return LG(b, 10);} // modification time
  90.206 +    static final long LOCCRC(byte[] b) { return LG(b, 14);} // crc of uncompressed data
  90.207 +    static final long LOCSIZ(byte[] b) { return LG(b, 18);} // compressed data size
  90.208 +    static final long LOCLEN(byte[] b) { return LG(b, 22);} // uncompressed data size
  90.209 +    static final int  LOCNAM(byte[] b) { return SH(b, 26);} // filename length
  90.210 +    static final int  LOCEXT(byte[] b) { return SH(b, 28);} // extra field length
  90.211 +
  90.212 +    // extra local (EXT) header fields
  90.213 +    static final long EXTCRC(byte[] b) { return LG(b, 4);}  // crc of uncompressed data
  90.214 +    static final long EXTSIZ(byte[] b) { return LG(b, 8);}  // compressed size
  90.215 +    static final long EXTLEN(byte[] b) { return LG(b, 12);} // uncompressed size
  90.216 +
  90.217 +    // end of central directory header (END) fields
  90.218 +    static final int  ENDSUB(byte[] b) { return SH(b, 8); }  // number of entries on this disk
  90.219 +    static final int  ENDTOT(byte[] b) { return SH(b, 10);}  // total number of entries
  90.220 +    static final long ENDSIZ(byte[] b) { return LG(b, 12);}  // central directory size
  90.221 +    static final long ENDOFF(byte[] b) { return LG(b, 16);}  // central directory offset
  90.222 +    static final int  ENDCOM(byte[] b) { return SH(b, 20);}  // size of zip file comment
  90.223 +    static final int  ENDCOM(byte[] b, int off) { return SH(b, off + 20);}
  90.224 +
  90.225 +    // zip64 end of central directory recoder fields
  90.226 +    static final long ZIP64_ENDTOD(byte[] b) { return LL(b, 24);}  // total number of entries on disk
  90.227 +    static final long ZIP64_ENDTOT(byte[] b) { return LL(b, 32);}  // total number of entries
  90.228 +    static final long ZIP64_ENDSIZ(byte[] b) { return LL(b, 40);}  // central directory size
  90.229 +    static final long ZIP64_ENDOFF(byte[] b) { return LL(b, 48);}  // central directory offset
  90.230 +    static final long ZIP64_LOCOFF(byte[] b) { return LL(b, 8);}   // zip64 end offset
  90.231 +
  90.232 +    //////////////////////////////////////////
  90.233 +    static final int CH(ByteBuffer b, int pos) {
  90.234 +       return b.get(pos) & 0xff;
  90.235 +    }
  90.236 +    static final int SH(ByteBuffer b, int pos) {
  90.237 +        return b.getShort(pos) & 0xffff;
  90.238 +    }
  90.239 +    static final long LG(ByteBuffer b, int pos) {
  90.240 +        return b.getInt(pos) & 0xffffffffL;
  90.241 +    }
  90.242 +
  90.243 +    // central directory header (END) fields
  90.244 +    static final long CENSIG(ByteBuffer b, int pos) { return LG(b, pos + 0); }
  90.245 +    static final int  CENVEM(ByteBuffer b, int pos) { return SH(b, pos + 4); }
  90.246 +    static final int  CENVER(ByteBuffer b, int pos) { return SH(b, pos + 6); }
  90.247 +    static final int  CENFLG(ByteBuffer b, int pos) { return SH(b, pos + 8); }
  90.248 +    static final int  CENHOW(ByteBuffer b, int pos) { return SH(b, pos + 10);}
  90.249 +    static final long CENTIM(ByteBuffer b, int pos) { return LG(b, pos + 12);}
  90.250 +    static final long CENCRC(ByteBuffer b, int pos) { return LG(b, pos + 16);}
  90.251 +    static final long CENSIZ(ByteBuffer b, int pos) { return LG(b, pos + 20);}
  90.252 +    static final long CENLEN(ByteBuffer b, int pos) { return LG(b, pos + 24);}
  90.253 +    static final int  CENNAM(ByteBuffer b, int pos) { return SH(b, pos + 28);}
  90.254 +    static final int  CENEXT(ByteBuffer b, int pos) { return SH(b, pos + 30);}
  90.255 +    static final int  CENCOM(ByteBuffer b, int pos) { return SH(b, pos + 32);}
  90.256 +    static final int  CENDSK(ByteBuffer b, int pos) { return SH(b, pos + 34);}
  90.257 +    static final int  CENATT(ByteBuffer b, int pos) { return SH(b, pos + 36);}
  90.258 +    static final long CENATX(ByteBuffer b, int pos) { return LG(b, pos + 38);}
  90.259 +    static final long CENOFF(ByteBuffer b, int pos) { return LG(b, pos + 42);}
  90.260 +
  90.261 +    /* The END header is followed by a variable length comment of size < 64k. */
  90.262 +    static final long END_MAXLEN = 0xFFFF + ENDHDR;
  90.263 +    static final int READBLOCKSZ = 128;
  90.264 +}
    91.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    91.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipDirectoryStream.java	Mon Oct 18 11:25:28 2010 -0400
    91.3 @@ -0,0 +1,109 @@
    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 +package com.sun.nio.zipfs;
   91.36 +
   91.37 +import java.nio.file.DirectoryStream;
   91.38 +import java.nio.file.ClosedDirectoryStreamException;
   91.39 +import java.nio.file.NotDirectoryException;
   91.40 +import java.nio.file.Path;
   91.41 +import java.util.Iterator;
   91.42 +import java.util.NoSuchElementException;
   91.43 +import java.io.IOException;
   91.44 +import static com.sun.nio.zipfs.ZipUtils.*;
   91.45 +
   91.46 +/**
   91.47 + *
   91.48 + * @author  Xueming Shen, Rajendra Gutupalli, Jaya Hangal
   91.49 + */
   91.50 +
   91.51 +public class ZipDirectoryStream implements DirectoryStream<Path> {
   91.52 +
   91.53 +    private final ZipFileSystem zipfs;
   91.54 +    private final byte[] path;
   91.55 +    private final DirectoryStream.Filter<? super Path> filter;
   91.56 +    private volatile boolean isClosed;
   91.57 +    private volatile Iterator<Path> itr;
   91.58 +
   91.59 +    ZipDirectoryStream(ZipPath zipPath,
   91.60 +                       DirectoryStream.Filter<? super java.nio.file.Path> filter)
   91.61 +        throws IOException
   91.62 +    {
   91.63 +        this.zipfs = zipPath.getFileSystem();
   91.64 +        this.path = zipPath.getResolvedPath();
   91.65 +        this.filter = filter;
   91.66 +        // sanity check
   91.67 +        if (!zipfs.isDirectory(path))
   91.68 +            throw new NotDirectoryException(zipPath.toString());
   91.69 +    }
   91.70 +
   91.71 +    @Override
   91.72 +    public synchronized Iterator<Path> iterator() {
   91.73 +        if (isClosed)
   91.74 +            throw new ClosedDirectoryStreamException();
   91.75 +        if (itr != null)
   91.76 +            throw new IllegalStateException("Iterator has already been returned");
   91.77 +
   91.78 +        try {
   91.79 +            itr = zipfs.iteratorOf(path, filter);
   91.80 +        } catch (IOException e) {
   91.81 +            throw new IllegalStateException(e);
   91.82 +        }
   91.83 +        return new Iterator<Path>() {
   91.84 +            private Path next;
   91.85 +            @Override
   91.86 +            public boolean hasNext() {
   91.87 +                if (isClosed)
   91.88 +                    return false;
   91.89 +                return itr.hasNext();
   91.90 +            }
   91.91 +
   91.92 +            @Override
   91.93 +            public synchronized Path next() {
   91.94 +                if (isClosed)
   91.95 +                    throw new NoSuchElementException();
   91.96 +                return itr.next();
   91.97 +            }
   91.98 +
   91.99 +            @Override
  91.100 +            public void remove() {
  91.101 +                throw new UnsupportedOperationException();
  91.102 +            }
  91.103 +        };
  91.104 +    }
  91.105 +
  91.106 +    @Override
  91.107 +    public synchronized void close() throws IOException {
  91.108 +        isClosed = true;
  91.109 +    }
  91.110 +
  91.111 +
  91.112 +}
    92.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    92.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributeView.java	Mon Oct 18 11:25:28 2010 -0400
    92.3 @@ -0,0 +1,185 @@
    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.ReadOnlyFileSystemException;
   92.39 +import java.nio.file.attribute.BasicFileAttributeView;
   92.40 +import java.nio.file.attribute.FileAttributeView;
   92.41 +import java.nio.file.attribute.FileTime;
   92.42 +import java.io.IOException;
   92.43 +import java.util.LinkedHashMap;
   92.44 +
   92.45 +/*
   92.46 + * @author  Xueming Shen, Rajendra Gutupalli, Jaya Hangal
   92.47 + */
   92.48 +
   92.49 +public class ZipFileAttributeView implements BasicFileAttributeView
   92.50 +{
   92.51 +    private static enum AttrID {
   92.52 +        size,
   92.53 +        creationTime,
   92.54 +        lastAccessTime,
   92.55 +        lastModifiedTime,
   92.56 +        isDirectory,
   92.57 +        isRegularFile,
   92.58 +        isSymbolicLink,
   92.59 +        isOther,
   92.60 +        fileKey,
   92.61 +        compressedSize,
   92.62 +        crc,
   92.63 +        method
   92.64 +    };
   92.65 +
   92.66 +    private final ZipPath path;
   92.67 +    private final boolean isZipView;
   92.68 +
   92.69 +    private ZipFileAttributeView(ZipPath path, boolean isZipView) {
   92.70 +        this.path = path;
   92.71 +        this.isZipView = isZipView;
   92.72 +    }
   92.73 +
   92.74 +    static <V extends FileAttributeView> V get(ZipPath path, Class<V> type) {
   92.75 +        if (type == null)
   92.76 +            throw new NullPointerException();
   92.77 +        if (type == BasicFileAttributeView.class)
   92.78 +            return (V)new ZipFileAttributeView(path, false);
   92.79 +        if (type == ZipFileAttributeView.class)
   92.80 +            return (V)new ZipFileAttributeView(path, true);
   92.81 +        return null;
   92.82 +    }
   92.83 +
   92.84 +    static ZipFileAttributeView get(ZipPath path, String type) {
   92.85 +        if (type == null)
   92.86 +            throw new NullPointerException();
   92.87 +        if (type.equals("basic"))
   92.88 +            return new ZipFileAttributeView(path, false);
   92.89 +        if (type.equals("zip"))
   92.90 +            return new ZipFileAttributeView(path, true);
   92.91 +        return null;
   92.92 +    }
   92.93 +
   92.94 +    @Override
   92.95 +    public String name() {
   92.96 +        return isZipView ? "zip" : "basic";
   92.97 +    }
   92.98 +
   92.99 +    public ZipFileAttributes readAttributes() throws IOException
  92.100 +    {
  92.101 +        return path.getAttributes();
  92.102 +    }
  92.103 +
  92.104 +    @Override
  92.105 +    public void setTimes(FileTime lastModifiedTime,
  92.106 +                         FileTime lastAccessTime,
  92.107 +                         FileTime createTime)
  92.108 +        throws IOException
  92.109 +    {
  92.110 +        path.setTimes(lastModifiedTime, lastAccessTime, createTime);
  92.111 +    }
  92.112 +
  92.113 +    void setAttribute(String attribute, Object value)
  92.114 +        throws IOException
  92.115 +    {
  92.116 +        try {
  92.117 +            if (AttrID.valueOf(attribute) == AttrID.lastModifiedTime)
  92.118 +                setTimes ((FileTime)value, null, null);
  92.119 +            return;
  92.120 +        } catch (IllegalArgumentException x) {}
  92.121 +        throw new UnsupportedOperationException("'" + attribute +
  92.122 +            "' is unknown or read-only attribute");
  92.123 +    }
  92.124 +
  92.125 +    public Object getAttribute(String attribute, boolean domap)
  92.126 +        throws IOException
  92.127 +    {
  92.128 +        ZipFileAttributes zfas = readAttributes();
  92.129 +        if (!domap) {
  92.130 +            try {
  92.131 +                return attribute(AttrID.valueOf(attribute), zfas);
  92.132 +            } catch (IllegalArgumentException x) {}
  92.133 +            return null;
  92.134 +        }
  92.135 +        LinkedHashMap<String, Object> map = new LinkedHashMap<>();
  92.136 +        if ("*".equals(attribute)) {
  92.137 +            for (AttrID id : AttrID.values()) {
  92.138 +                try {
  92.139 +                    map.put(id.name(), attribute(id, zfas));
  92.140 +                } catch (IllegalArgumentException x) {}
  92.141 +            }
  92.142 +        } else {
  92.143 +            String[] as = attribute.split(",");
  92.144 +            for (String a : as) {
  92.145 +                try {
  92.146 +                    map.put(a, attribute(AttrID.valueOf(a), zfas));
  92.147 +                } catch (IllegalArgumentException x) {}
  92.148 +            }
  92.149 +        }
  92.150 +        return map;
  92.151 +    }
  92.152 +
  92.153 +    Object attribute(AttrID id, ZipFileAttributes zfas) {
  92.154 +        switch (id) {
  92.155 +        case size:
  92.156 +            return zfas.size();
  92.157 +        case creationTime:
  92.158 +            return zfas.creationTime();
  92.159 +        case lastAccessTime:
  92.160 +            return zfas.lastAccessTime();
  92.161 +        case lastModifiedTime:
  92.162 +            return zfas.lastModifiedTime();
  92.163 +        case isDirectory:
  92.164 +            return zfas.isDirectory();
  92.165 +        case isRegularFile:
  92.166 +            return zfas.isRegularFile();
  92.167 +        case isSymbolicLink:
  92.168 +            return zfas.isSymbolicLink();
  92.169 +        case isOther:
  92.170 +            return zfas.isOther();
  92.171 +        case fileKey:
  92.172 +            return zfas.fileKey();
  92.173 +        case compressedSize:
  92.174 +            if (isZipView)
  92.175 +                return zfas.compressedSize();
  92.176 +            break;
  92.177 +        case crc:
  92.178 +            if (isZipView)
  92.179 +                return zfas.crc();
  92.180 +            break;
  92.181 +        case method:
  92.182 +            if (isZipView)
  92.183 +                return zfas.method();
  92.184 +            break;
  92.185 +        }
  92.186 +        return null;
  92.187 +    }
  92.188 +}
    93.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    93.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributes.java	Mon Oct 18 11:25:28 2010 -0400
    93.3 @@ -0,0 +1,156 @@
    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 +
   93.36 +package com.sun.nio.zipfs;
   93.37 +
   93.38 +import java.nio.file.attribute.BasicFileAttributes;
   93.39 +import java.nio.file.attribute.FileTime;
   93.40 +import java.util.Arrays;
   93.41 +import java.util.Formatter;
   93.42 +import static com.sun.nio.zipfs.ZipUtils.*;
   93.43 +
   93.44 +/**
   93.45 + *
   93.46 + * @author  Xueming Shen, Rajendra Gutupalli,Jaya Hangal
   93.47 + */
   93.48 +
   93.49 +public class ZipFileAttributes implements BasicFileAttributes
   93.50 +
   93.51 +{
   93.52 +    private final ZipFileSystem.Entry e;
   93.53 +
   93.54 +    ZipFileAttributes(ZipFileSystem.Entry e) {
   93.55 +        this.e = e;
   93.56 +    }
   93.57 +
   93.58 +    ///////// basic attributes ///////////
   93.59 +    @Override
   93.60 +    public FileTime creationTime() {
   93.61 +        if (e.ctime != -1)
   93.62 +            return FileTime.fromMillis(dosToJavaTime(e.ctime));
   93.63 +        return null;
   93.64 +    }
   93.65 +
   93.66 +    @Override
   93.67 +    public boolean isDirectory() {
   93.68 +        return e.isDir();
   93.69 +    }
   93.70 +
   93.71 +    @Override
   93.72 +    public boolean isOther() {
   93.73 +        return false;
   93.74 +    }
   93.75 +
   93.76 +    @Override
   93.77 +    public boolean isRegularFile() {
   93.78 +        return !e.isDir();
   93.79 +    }
   93.80 +
   93.81 +    @Override
   93.82 +    public FileTime lastAccessTime() {
   93.83 +        if (e.atime != -1)
   93.84 +            return FileTime.fromMillis(dosToJavaTime(e.atime));
   93.85 +        return null;
   93.86 +    }
   93.87 +
   93.88 +    @Override
   93.89 +    public FileTime lastModifiedTime() {
   93.90 +        return FileTime.fromMillis(dosToJavaTime(e.mtime));
   93.91 +    }
   93.92 +
   93.93 +    @Override
   93.94 +    public long size() {
   93.95 +        return e.size;
   93.96 +    }
   93.97 +
   93.98 +    @Override
   93.99 +    public boolean isSymbolicLink() {
  93.100 +        return false;
  93.101 +    }
  93.102 +
  93.103 +    @Override
  93.104 +    public Object fileKey() {
  93.105 +        return null;
  93.106 +    }
  93.107 +
  93.108 +    ///////// zip entry attributes ///////////
  93.109 +    public byte[] name() {
  93.110 +        return Arrays.copyOf(e.name, e.name.length);
  93.111 +    }
  93.112 +
  93.113 +    public long compressedSize() {
  93.114 +        return e.csize;
  93.115 +    }
  93.116 +
  93.117 +    public long crc() {
  93.118 +        return e.crc;
  93.119 +    }
  93.120 +
  93.121 +    public int method() {
  93.122 +        return e.method;
  93.123 +    }
  93.124 +
  93.125 +    public byte[] extra() {
  93.126 +        if (e.extra != null)
  93.127 +            return Arrays.copyOf(e.extra, e.extra.length);
  93.128 +        return null;
  93.129 +    }
  93.130 +
  93.131 +    public byte[] comment() {
  93.132 +        if (e.comment != null)
  93.133 +            return Arrays.copyOf(e.comment, e.comment.length);
  93.134 +        return null;
  93.135 +    }
  93.136 +
  93.137 +    public String toString() {
  93.138 +        StringBuilder sb = new StringBuilder();
  93.139 +        Formatter fm = new Formatter(sb);
  93.140 +        fm.format("[/%s]%n", new String(e.name));  // TBD encoding
  93.141 +        fm.format("    creationTime    : %s%n", creationTime());
  93.142 +        if (lastAccessTime() != null)
  93.143 +            fm.format("    lastAccessTime  : %tc%n", lastAccessTime().toMillis());
  93.144 +        else
  93.145 +            fm.format("    lastAccessTime  : null%n");
  93.146 +        fm.format("    lastModifiedTime: %tc%n", lastModifiedTime().toMillis());
  93.147 +        fm.format("    isRegularFile   : %b%n", isRegularFile());
  93.148 +        fm.format("    isDirectory     : %b%n", isDirectory());
  93.149 +        fm.format("    isSymbolicLink  : %b%n", isSymbolicLink());
  93.150 +        fm.format("    isOther         : %b%n", isOther());
  93.151 +        fm.format("    fileKey         : %s%n", fileKey());
  93.152 +        fm.format("    size            : %d%n", size());
  93.153 +        fm.format("    compressedSize  : %d%n", compressedSize());
  93.154 +        fm.format("    crc             : %x%n", crc());
  93.155 +        fm.format("    method          : %d%n", method());
  93.156 +        fm.close();
  93.157 +        return sb.toString();
  93.158 +    }
  93.159 +}
    94.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    94.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileStore.java	Mon Oct 18 11:25:28 2010 -0400
    94.3 @@ -0,0 +1,157 @@
    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.IOException;
   94.38 +import java.nio.file.FileStore;
   94.39 +import java.nio.file.FileSystems;
   94.40 +import java.nio.file.Path;
   94.41 +import java.nio.file.attribute.FileAttributeView;
   94.42 +import java.nio.file.attribute.FileStoreAttributeView;
   94.43 +import java.nio.file.attribute.FileStoreSpaceAttributeView;
   94.44 +import java.nio.file.attribute.FileStoreSpaceAttributes;
   94.45 +import java.nio.file.attribute.Attributes;
   94.46 +import java.nio.file.attribute.BasicFileAttributeView;
   94.47 +import java.util.Formatter;
   94.48 +
   94.49 +/*
   94.50 + *
   94.51 + * @author  Xueming Shen, Rajendra Gutupalli, Jaya Hangal
   94.52 + */
   94.53 +
   94.54 +public class ZipFileStore extends FileStore {
   94.55 +
   94.56 +    private final ZipFileSystem zfs;
   94.57 +
   94.58 +    ZipFileStore(ZipPath zpath) {
   94.59 +        this.zfs = (ZipFileSystem)zpath.getFileSystem();
   94.60 +    }
   94.61 +
   94.62 +    @Override
   94.63 +    public String name() {
   94.64 +        return zfs.toString() + "/";
   94.65 +    }
   94.66 +
   94.67 +    @Override
   94.68 +    public String type() {
   94.69 +        return "zipfs";
   94.70 +    }
   94.71 +
   94.72 +    @Override
   94.73 +    public boolean isReadOnly() {
   94.74 +        return zfs.isReadOnly();
   94.75 +    }
   94.76 +
   94.77 +    @Override
   94.78 +    public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) {
   94.79 +        return (type == BasicFileAttributeView.class ||
   94.80 +                type == ZipFileAttributeView.class);
   94.81 +    }
   94.82 +
   94.83 +    @Override
   94.84 +    public boolean supportsFileAttributeView(String name) {
   94.85 +        return name.equals("basic") || name.equals("zip");
   94.86 +    }
   94.87 +
   94.88 +    @Override
   94.89 +    @SuppressWarnings("unchecked")
   94.90 +    public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> type) {
   94.91 +        if (type == null)
   94.92 +            throw new NullPointerException();
   94.93 +        if (type == FileStoreSpaceAttributeView.class)
   94.94 +            return (V) new ZipFileStoreAttributeView(this);
   94.95 +        return null;
   94.96 +    }
   94.97 +
   94.98 +    @Override
   94.99 +    public Object getAttribute(String attribute) throws IOException {
  94.100 +         if (attribute.equals("space:totalSpace"))
  94.101 +               return new ZipFileStoreAttributeView(this).readAttributes().totalSpace();
  94.102 +         if (attribute.equals("space:usableSpace"))
  94.103 +               return new ZipFileStoreAttributeView(this).readAttributes().usableSpace();
  94.104 +         if (attribute.equals("space:unallocatedSpace"))
  94.105 +               return new ZipFileStoreAttributeView(this).readAttributes().unallocatedSpace();
  94.106 +         throw new UnsupportedOperationException("does not support the given attribute");
  94.107 +    }
  94.108 +
  94.109 +    private static class ZipFileStoreAttributeView implements FileStoreSpaceAttributeView {
  94.110 +
  94.111 +        private final ZipFileStore fileStore;
  94.112 +
  94.113 +        public ZipFileStoreAttributeView(ZipFileStore fileStore) {
  94.114 +            this.fileStore = fileStore;
  94.115 +        }
  94.116 +
  94.117 +        @Override
  94.118 +        public String name() {
  94.119 +            return "space";
  94.120 +        }
  94.121 +
  94.122 +        @Override
  94.123 +        public FileStoreSpaceAttributes readAttributes() throws IOException {
  94.124 +            final String file = fileStore.name();
  94.125 +            Path path = FileSystems.getDefault().getPath(file);
  94.126 +            final long size = Attributes.readBasicFileAttributes(path).size();
  94.127 +            final FileStore fstore = path.getFileStore();
  94.128 +            final FileStoreSpaceAttributes fstoreAttrs =
  94.129 +                Attributes.readFileStoreSpaceAttributes(fstore);
  94.130 +            return new FileStoreSpaceAttributes() {
  94.131 +                public long totalSpace() {
  94.132 +                    return size;
  94.133 +                }
  94.134 +
  94.135 +                public long usableSpace() {
  94.136 +                    if (!fstore.isReadOnly())
  94.137 +                        return fstoreAttrs.usableSpace();
  94.138 +                    return 0;
  94.139 +                }
  94.140 +
  94.141 +                public long unallocatedSpace() {
  94.142 +                    if (!fstore.isReadOnly())
  94.143 +                        return fstoreAttrs.unallocatedSpace();
  94.144 +                    return 0;
  94.145 +                }
  94.146 +
  94.147 +                public String toString() {
  94.148 +                    StringBuilder sb = new StringBuilder();
  94.149 +                    Formatter fm = new Formatter(sb);
  94.150 +                    fm.format("FileStoreSpaceAttributes[%s]%n", file);
  94.151 +                    fm.format("      totalSpace: %d%n", totalSpace());
  94.152 +                    fm.format("     usableSpace: %d%n", usableSpace());
  94.153 +                    fm.format("    unallocSpace: %d%n", unallocatedSpace());
  94.154 +                    fm.close();
  94.155 +                    return sb.toString();
  94.156 +                }
  94.157 +            };
  94.158 +        }
  94.159 +    }
  94.160 +}
    95.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    95.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystem.java	Mon Oct 18 11:25:28 2010 -0400
    95.3 @@ -0,0 +1,2257 @@
    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.ByteArrayInputStream;
   95.38 +import java.io.ByteArrayOutputStream;
   95.39 +import java.io.EOFException;
   95.40 +import java.io.File;
   95.41 +import java.io.FileInputStream;
   95.42 +import java.io.IOException;
   95.43 +import java.io.InputStream;
   95.44 +import java.io.OutputStream;
   95.45 +import java.nio.ByteBuffer;
   95.46 +import java.nio.ByteOrder;
   95.47 +import java.nio.MappedByteBuffer;
   95.48 +import java.nio.channels.*;
   95.49 +import java.nio.file.*;
   95.50 +import java.nio.file.attribute.*;
   95.51 +import java.nio.file.spi.*;
   95.52 +import java.net.URI;
   95.53 +import java.util.*;
   95.54 +import java.util.regex.Pattern;
   95.55 +import java.util.zip.CRC32;
   95.56 +import java.util.zip.Inflater;
   95.57 +import java.util.zip.Deflater;
   95.58 +import java.util.zip.InflaterInputStream;
   95.59 +import java.util.zip.DeflaterOutputStream;
   95.60 +import java.util.zip.ZipException;
   95.61 +import java.util.zip.ZipError;
   95.62 +import static java.lang.Boolean.*;
   95.63 +import static com.sun.nio.zipfs.ZipConstants.*;
   95.64 +import static com.sun.nio.zipfs.ZipUtils.*;
   95.65 +import static java.nio.file.StandardOpenOption.*;
   95.66 +import static java.nio.file.StandardCopyOption.*;
   95.67 +
   95.68 +/**
   95.69 + * A FileSystem built on a zip file
   95.70 + *
   95.71 + * @author Xueming Shen
   95.72 + */
   95.73 +
   95.74 +public class ZipFileSystem extends FileSystem {
   95.75 +
   95.76 +    private final ZipFileSystemProvider provider;
   95.77 +    private final ZipPath defaultdir;
   95.78 +    private boolean readOnly = false;
   95.79 +    private final Path zfpath;
   95.80 +    private final ZipCoder zc;
   95.81 +
   95.82 +    private final Object lock = new Object();
   95.83 +
   95.84 +    // configurable by env map
   95.85 +    private final String  defaultDir;    // default dir for the file system
   95.86 +    private final String  nameEncoding;  // default encoding for name/comment
   95.87 +    private final boolean buildDirTree;  // build a dir tree for directoryStream ops
   95.88 +    private final boolean useTempFile;   // use a temp file for newOS, default
   95.89 +                                         // is to use BAOS for better performance
   95.90 +    private final boolean createNew;     // create a new zip if not exists
   95.91 +
   95.92 +    ZipFileSystem(ZipFileSystemProvider provider,
   95.93 +                  Path zfpath,
   95.94 +                  Map<String, ?> env)
   95.95 +        throws IOException
   95.96 +    {
   95.97 +        // configurable env setup
   95.98 +        this.buildDirTree = TRUE.equals(env.get("buildDirTree"));
   95.99 +        this.useTempFile = TRUE.equals(env.get("useTempFile"));
  95.100 +        this.createNew = TRUE.equals(env.get("createNew"));
  95.101 +        this.nameEncoding = env.containsKey("nameEncoding") ?
  95.102 +                            (String)env.get("nameEncoding") : "UTF-8";
  95.103 +        this.defaultDir = env.containsKey("default.dir") ?
  95.104 +                          (String)env.get("default.dir") : "/";
  95.105 +        if (this.defaultDir.charAt(0) != '/')
  95.106 +            throw new IllegalArgumentException("default dir should be absolute");
  95.107 +
  95.108 +        this.provider = provider;
  95.109 +        this.zfpath = zfpath;
  95.110 +        if (zfpath.notExists()) {
  95.111 +            if (createNew) {
  95.112 +                OutputStream os = zfpath.newOutputStream(CREATE_NEW, WRITE);
  95.113 +                new END().write(os, 0);
  95.114 +                os.close();
  95.115 +            } else {
  95.116 +                throw new FileSystemNotFoundException(zfpath.toString());
  95.117 +            }
  95.118 +        }
  95.119 +        zfpath.checkAccess(AccessMode.READ); // sm and existence check
  95.120 +        try {
  95.121 +            zfpath.checkAccess(AccessMode.WRITE);
  95.122 +        } catch (AccessDeniedException x) {
  95.123 +            this.readOnly = true;
  95.124 +        }
  95.125 +        this.zc = ZipCoder.get(nameEncoding);
  95.126 +        this.defaultdir = new ZipPath(this, getBytes(defaultDir));
  95.127 +        initZipFile();
  95.128 +    }
  95.129 +
  95.130 +    @Override
  95.131 +    public FileSystemProvider provider() {
  95.132 +        return provider;
  95.133 +    }
  95.134 +
  95.135 +    @Override
  95.136 +    public String getSeparator() {
  95.137 +        return "/";
  95.138 +    }
  95.139 +
  95.140 +    @Override
  95.141 +    public boolean isOpen() {
  95.142 +        return isOpen;
  95.143 +    }
  95.144 +
  95.145 +    @Override
  95.146 +    public boolean isReadOnly() {
  95.147 +        return readOnly;
  95.148 +    }
  95.149 +
  95.150 +    private void checkWritable() throws IOException {
  95.151 +        if (readOnly)
  95.152 +            throw new ReadOnlyFileSystemException();
  95.153 +    }
  95.154 +
  95.155 +    @Override
  95.156 +    public Iterable<Path> getRootDirectories() {
  95.157 +        ArrayList<Path> pathArr = new ArrayList<>();
  95.158 +        pathArr.add(new ZipPath(this, new byte[]{'/'}));
  95.159 +        return pathArr;
  95.160 +    }
  95.161 +
  95.162 +    ZipPath getDefaultDir() {  // package private
  95.163 +        return defaultdir;
  95.164 +    }
  95.165 +
  95.166 +    @Override
  95.167 +    public ZipPath getPath(String path) {
  95.168 +        if (path.length() == 0)
  95.169 +            throw new InvalidPathException(path, "path should not be empty");
  95.170 +        return new ZipPath(this, getBytes(path));
  95.171 +    }
  95.172 +
  95.173 +    @Override
  95.174 +    public UserPrincipalLookupService getUserPrincipalLookupService() {
  95.175 +        throw new UnsupportedOperationException();
  95.176 +    }
  95.177 +
  95.178 +    @Override
  95.179 +    public WatchService newWatchService() {
  95.180 +        throw new UnsupportedOperationException();
  95.181 +    }
  95.182 +
  95.183 +    FileStore getFileStore(ZipPath path) {
  95.184 +        return new ZipFileStore(path);
  95.185 +    }
  95.186 +
  95.187 +    @Override
  95.188 +    public Iterable<FileStore> getFileStores() {
  95.189 +        ArrayList<FileStore> list = new ArrayList<FileStore>(1);
  95.190 +        list.add(new ZipFileStore(new ZipPath(this, new byte[]{'/'})));
  95.191 +        return list;
  95.192 +    }
  95.193 +
  95.194 +    private static final Set<String> supportedFileAttributeViews =
  95.195 +            Collections.unmodifiableSet(
  95.196 +                new HashSet<String>(Arrays.asList("basic", "zip")));
  95.197 +
  95.198 +    @Override
  95.199 +    public Set<String> supportedFileAttributeViews() {
  95.200 +        return supportedFileAttributeViews;
  95.201 +    }
  95.202 +
  95.203 +    @Override
  95.204 +    public String toString() {
  95.205 +        return zfpath.toString();
  95.206 +    }
  95.207 +
  95.208 +    Path getZipFile() {
  95.209 +        return zfpath;
  95.210 +    }
  95.211 +
  95.212 +    private static final String GLOB_SYNTAX = "glob";
  95.213 +    private static final String REGEX_SYNTAX = "regex";
  95.214 +
  95.215 +    @Override
  95.216 +    public PathMatcher getPathMatcher(String syntaxAndInput) {
  95.217 +        int pos = syntaxAndInput.indexOf(':');
  95.218 +        if (pos <= 0 || pos == syntaxAndInput.length()) {
  95.219 +            throw new IllegalArgumentException();
  95.220 +        }
  95.221 +        String syntax = syntaxAndInput.substring(0, pos);
  95.222 +        String input = syntaxAndInput.substring(pos + 1);
  95.223 +        String expr;
  95.224 +        if (syntax.equals(GLOB_SYNTAX)) {
  95.225 +            expr = toRegexPattern(input);
  95.226 +        } else {
  95.227 +            if (syntax.equals(REGEX_SYNTAX)) {
  95.228 +                expr = input;
  95.229 +            } else {
  95.230 +                throw new UnsupportedOperationException("Syntax '" + syntax +
  95.231 +                    "' not recognized");
  95.232 +            }
  95.233 +        }
  95.234 +        // return matcher
  95.235 +        final Pattern pattern = Pattern.compile(expr);
  95.236 +        return new PathMatcher() {
  95.237 +            @Override
  95.238 +            public boolean matches(Path path) {
  95.239 +                return pattern.matcher(path.toString()).matches();
  95.240 +            }
  95.241 +        };
  95.242 +    }
  95.243 +
  95.244 +    @Override
  95.245 +    public void close() throws IOException {
  95.246 +        synchronized (lock) {
  95.247 +            if (!isOpen)
  95.248 +                return;
  95.249 +            isOpen = false;
  95.250 +            if (!streams.isEmpty()) {
  95.251 +                synchronized(streams) {
  95.252 +                    for (InputStream is: streams)
  95.253 +                    is.close();
  95.254 +                }
  95.255 +            }
  95.256 +            sync();
  95.257 +            ch.close();
  95.258 +        }
  95.259 +        synchronized (inflaters) {
  95.260 +            for (Inflater inf : inflaters)
  95.261 +                inf.end();
  95.262 +        }
  95.263 +        synchronized (deflaters) {
  95.264 +            for (Deflater def : deflaters)
  95.265 +                def.end();
  95.266 +        }
  95.267 +        for (Path p: tmppaths) {
  95.268 +            try {
  95.269 +                p.deleteIfExists();
  95.270 +            } catch (IOException x) {
  95.271 +                x.printStackTrace();
  95.272 +            }
  95.273 +        }
  95.274 +        provider.removeFileSystem(zfpath);
  95.275 +    }
  95.276 +
  95.277 +    ZipFileAttributes[] getAllAttributes() throws IOException {
  95.278 +        ensureOpen();
  95.279 +        int n = inodes.size();
  95.280 +        ZipFileAttributes[] zes = new ZipFileAttributes[n];
  95.281 +        Iterator<IndexNode> itr = inodes.values().iterator();
  95.282 +        int i = 0;
  95.283 +        while(itr.hasNext()) {
  95.284 +            zes[i++] = new ZipFileAttributes(Entry.readCEN(cen, itr.next().pos));
  95.285 +        }
  95.286 +        return zes;
  95.287 +    }
  95.288 +
  95.289 +    EntryName[] getEntryNames() throws IOException {
  95.290 +        ensureOpen();
  95.291 +        return inodes.keySet().toArray(new EntryName[0]);
  95.292 +    }
  95.293 +
  95.294 +    ZipFileAttributes getFileAttributes(byte[] path)
  95.295 +        throws IOException
  95.296 +    {
  95.297 +        synchronized (lock) {
  95.298 +            Entry e = getEntry0(path);
  95.299 +            if (e == null) {
  95.300 +                if (path.length == 0) {
  95.301 +                    e = new Entry(new byte[0]);  // root
  95.302 +                } else if (buildDirTree) {
  95.303 +                    IndexNode inode = getDirs().get(new EntryName(path));
  95.304 +                    if (inode == null)
  95.305 +                        return null;
  95.306 +                    e = new Entry(inode.name);
  95.307 +                } else {
  95.308 +                    return null;
  95.309 +                }
  95.310 +                e.method = METHOD_STORED;        // STORED for dir
  95.311 +                BasicFileAttributes bfas = Attributes.readBasicFileAttributes(zfpath);
  95.312 +                if (bfas.lastModifiedTime() != null)
  95.313 +                    e.mtime = javaToDosTime(bfas.lastModifiedTime().toMillis());
  95.314 +                if (bfas.lastAccessTime() != null)
  95.315 +                    e.atime = javaToDosTime(bfas.lastAccessTime().toMillis());
  95.316 +                if (bfas.creationTime() != null)
  95.317 +                    e.ctime = javaToDosTime(bfas.creationTime().toMillis());
  95.318 +            }
  95.319 +            return new ZipFileAttributes(e);
  95.320 +        }
  95.321 +    }
  95.322 +
  95.323 +    void setTimes(byte[] path, FileTime mtime, FileTime atime, FileTime ctime)
  95.324 +        throws IOException
  95.325 +    {
  95.326 +        checkWritable();
  95.327 +        synchronized (lock) {
  95.328 +            Entry e = getEntry0(path);    // ensureOpen checked
  95.329 +            if (e == null)
  95.330 +                throw new NoSuchFileException(getString(path));
  95.331 +            if (e.type == Entry.CEN)
  95.332 +                e.type = Entry.COPY;      // copy e
  95.333 +            if (mtime != null)
  95.334 +                e.mtime = javaToDosTime(mtime.toMillis());
  95.335 +            if (atime != null)
  95.336 +                e.atime = javaToDosTime(atime.toMillis());
  95.337 +            if (ctime != null)
  95.338 +                e.ctime = javaToDosTime(ctime.toMillis());
  95.339 +            update(e);
  95.340 +        }
  95.341 +    }
  95.342 +
  95.343 +    boolean exists(byte[] path)
  95.344 +        throws IOException
  95.345 +    {
  95.346 +        return getEntry0(path) != null;
  95.347 +    }
  95.348 +
  95.349 +    boolean isDirectory(byte[] path)
  95.350 +        throws IOException
  95.351 +    {
  95.352 +        synchronized (lock) {
  95.353 +            if (buildDirTree) {
  95.354 +                return getDirs().containsKey(new EntryName(path));
  95.355 +            }
  95.356 +            Entry e = getEntry0(path);
  95.357 +            return (e != null && e.isDir()) || path.length == 0;
  95.358 +        }
  95.359 +    }
  95.360 +
  95.361 +    private ZipPath toZipPath(byte[] path) {
  95.362 +        // make it absolute
  95.363 +        byte[] p = new byte[path.length + 1];
  95.364 +        p[0] = '/';
  95.365 +        System.arraycopy(path, 0, p, 1, path.length);
  95.366 +        return new ZipPath(this, p);
  95.367 +    }
  95.368 +
  95.369 +    // returns the list of child paths of "path"
  95.370 +    Iterator<Path> iteratorOf(byte[] path,
  95.371 +                              DirectoryStream.Filter<? super Path> filter)
  95.372 +        throws IOException
  95.373 +    {
  95.374 +        synchronized (lock) {
  95.375 +            if (buildDirTree) {
  95.376 +                IndexNode inode = getDirs().get(new EntryName(path));
  95.377 +                if (inode == null)
  95.378 +                    throw new NotDirectoryException(getString(path));
  95.379 +                List<Path> list = new ArrayList<Path>();
  95.380 +                IndexNode child = inode.child;
  95.381 +                while (child != null) {
  95.382 +                    ZipPath zp = toZipPath(child.name);
  95.383 +                    if (filter == null || filter.accept(zp))
  95.384 +                        list.add(zp);
  95.385 +                    child = child.sibling;
  95.386 +                }
  95.387 +                return list.iterator();
  95.388 +            }
  95.389 +
  95.390 +            if (!isDirectory(path))
  95.391 +                throw new NotDirectoryException(getString(path));
  95.392 +            List<Path> list = new ArrayList<Path>();
  95.393 +            EntryName[] entries = getEntryNames();
  95.394 +            path = toDirectoryPath(path);
  95.395 +            for (EntryName en :entries) {
  95.396 +                if (!isParentOf(path, en.name))  // is "path" the parent of "name"
  95.397 +                    continue;
  95.398 +                int off = path.length;
  95.399 +                while (off < en.name.length) {
  95.400 +                    if (en.name[off] == '/')
  95.401 +                        break;
  95.402 +                    off++;
  95.403 +                }
  95.404 +                if (off < (en.name.length - 1))
  95.405 +                    continue;
  95.406 +                ZipPath zp = toZipPath(en.name);
  95.407 +                if (filter == null || filter.accept(zp))
  95.408 +                    list.add(zp);
  95.409 +            }
  95.410 +            return list.iterator();
  95.411 +        }
  95.412 +    }
  95.413 +
  95.414 +    void createDirectory(byte[] dir, FileAttribute<?>... attrs)
  95.415 +        throws IOException
  95.416 +    {
  95.417 +        checkWritable();
  95.418 +        dir = toDirectoryPath(dir);
  95.419 +        synchronized (lock) {
  95.420 +            ensureOpen();
  95.421 +            // pseudo root dir, or exiting dir
  95.422 +            if (dir.length == 0 || exists(dir))
  95.423 +                throw new FileAlreadyExistsException(getString(dir));
  95.424 +            checkParents(dir);
  95.425 +
  95.426 +            Entry e = new Entry(dir, Entry.NEW);
  95.427 +            e.method = METHOD_STORED;  // STORED for dir
  95.428 +            update(e);
  95.429 +        }
  95.430 +    }
  95.431 +
  95.432 +    void copyFile(boolean deletesrc, byte[]src, byte[] dst, CopyOption... options)
  95.433 +        throws IOException
  95.434 +    {
  95.435 +        checkWritable();
  95.436 +        if (Arrays.equals(src, dst))
  95.437 +            return;    // do nothing, src and dst are the same
  95.438 +        synchronized (lock) {
  95.439 +            Entry eSrc = getEntry0(src);  // ensureOpen checked
  95.440 +            if (eSrc == null)
  95.441 +                throw new NoSuchFileException(getString(src));
  95.442 +            if (eSrc.isDir()) {    // spec says to create dst dir
  95.443 +                createDirectory(dst);
  95.444 +                return;
  95.445 +            }
  95.446 +            boolean hasReplace = false;
  95.447 +            boolean hasCopyAttrs = false;
  95.448 +            for (CopyOption opt : options) {
  95.449 +                if (opt == REPLACE_EXISTING)
  95.450 +                    hasReplace = true;
  95.451 +                else if (opt == COPY_ATTRIBUTES)
  95.452 +                    hasCopyAttrs = true;
  95.453 +            }
  95.454 +            Entry eDst = getEntry0(dst);
  95.455 +            if (eDst != null) {
  95.456 +                if (!hasReplace)
  95.457 +                    throw new FileAlreadyExistsException(getString(dst));
  95.458 +            } else {
  95.459 +                checkParents(dst);
  95.460 +            }
  95.461 +            Entry u = new Entry(eSrc, Entry.COPY);    // copy eSrc entry
  95.462 +            u.name = dst;                             // change name
  95.463 +            // don't touch the "nlen and elen" here. writeLOC() always
  95.464 +            // re-calculate from "name" and "extra" for the correct length,
  95.465 +            // copyLOCEntry however needs the original lengths to skip the
  95.466 +            // loc header.
  95.467 +            // u.nlen = dst.length;
  95.468 +            if (eSrc.type == Entry.NEW || eSrc.type == Entry.FILECH)
  95.469 +            {
  95.470 +                u.type = eSrc.type;    // make it the same type
  95.471 +                if (!deletesrc) {      // if it's not "rename", just take the data
  95.472 +                    if (eSrc.bytes != null)
  95.473 +                        u.bytes = Arrays.copyOf(eSrc.bytes, eSrc.bytes.length);
  95.474 +                    else if (eSrc.file != null) {
  95.475 +                        u.file = getTempPathForEntry(null);
  95.476 +                        eSrc.file.copyTo(u.file, REPLACE_EXISTING);
  95.477 +                    }
  95.478 +                }
  95.479 +            }
  95.480 +            if (!hasCopyAttrs)
  95.481 +                u.mtime = u.atime= u.ctime = javaToDosTime(System.currentTimeMillis());
  95.482 +            update(u);
  95.483 +            if (deletesrc)
  95.484 +                updateDelete(eSrc);
  95.485 +        }
  95.486 +    }
  95.487 +
  95.488 +    // Returns an output stream for writing the contents into the specified
  95.489 +    // entry.
  95.490 +    OutputStream newOutputStream(byte[] path, OpenOption... options)
  95.491 +        throws IOException
  95.492 +    {
  95.493 +        checkWritable();
  95.494 +        boolean hasCreateNew = false;
  95.495 +        boolean hasCreate = false;
  95.496 +        boolean hasAppend = false;
  95.497 +        for (OpenOption opt: options) {
  95.498 +            if (opt == READ)
  95.499 +                throw new IllegalArgumentException("READ not allowed");
  95.500 +            if (opt == CREATE_NEW)
  95.501 +                hasCreateNew = true;
  95.502 +            if (opt == CREATE)
  95.503 +                hasCreate = true;
  95.504 +            if (opt == APPEND)
  95.505 +                hasAppend = true;
  95.506 +        }
  95.507 +        synchronized (lock) {
  95.508 +            Entry e = getEntry0(path);
  95.509 +            if (e != null) {
  95.510 +                if (e.isDir() || hasCreateNew)
  95.511 +                    throw new FileAlreadyExistsException(getString(path));
  95.512 +                if (hasAppend) {
  95.513 +                    InputStream is = getInputStream(e);
  95.514 +                    OutputStream os = getOutputStream(new Entry(e, Entry.NEW));
  95.515 +                    copyStream(is, os);
  95.516 +                    is.close();
  95.517 +                    return os;
  95.518 +                 }
  95.519 +                 return getOutputStream(new Entry(e, Entry.NEW));
  95.520 +            } else {
  95.521 +                if (!hasCreate && !hasCreateNew)
  95.522 +                    throw new NoSuchFileException(getString(path));
  95.523 +                checkParents(path);
  95.524 +                return getOutputStream(new Entry(path, Entry.NEW));
  95.525 +            }
  95.526 +        }
  95.527 +    }
  95.528 +
  95.529 +    // Returns an input stream for reading the contents of the specified
  95.530 +    // file entry.
  95.531 +    InputStream newInputStream(byte[] path) throws IOException {
  95.532 +        synchronized (lock) {
  95.533 +            Entry e = getEntry0(path);
  95.534 +            if (e == null)
  95.535 +                throw new NoSuchFileException(getString(path));
  95.536 +            if (e.isDir())
  95.537 +                throw new FileSystemException(getString(path), "is a directory", null);
  95.538 +            return getInputStream(e);
  95.539 +        }
  95.540 +    }
  95.541 +
  95.542 +    private void checkOptions(Set<? extends OpenOption> options) {
  95.543 +        // check for options of null type and option is an intance of StandardOpenOption
  95.544 +        for (OpenOption option : options) {
  95.545 +            if (option == null)
  95.546 +                throw new NullPointerException();
  95.547 +            if (!(option instanceof StandardOpenOption))
  95.548 +                throw new IllegalArgumentException();
  95.549 +        }
  95.550 +    }
  95.551 +
  95.552 +    // Returns a Writable/ReadByteChannel for now. Might consdier to use
  95.553 +    // newFileChannel() instead, which dump the entry data into a regular
  95.554 +    // file on the default file system and create a FileChannel on top of
  95.555 +    // it.
  95.556 +    SeekableByteChannel newByteChannel(byte[] path,
  95.557 +                                       Set<? extends OpenOption> options,
  95.558 +                                       FileAttribute<?>... attrs)
  95.559 +        throws IOException
  95.560 +    {
  95.561 +        checkOptions(options);
  95.562 +        if (options.contains(StandardOpenOption.WRITE) ||
  95.563 +            options.contains(StandardOpenOption.APPEND)) {
  95.564 +            checkWritable();
  95.565 +            final WritableByteChannel wbc = Channels.newChannel(newOutputStream(path,
  95.566 +                                                options.toArray(new OpenOption[0])));
  95.567 +            long leftover = 0;;
  95.568 +            if (options.contains(StandardOpenOption.APPEND)) {
  95.569 +                Entry e = getEntry0(path);
  95.570 +                if (e != null && e.size >= 0)
  95.571 +                    leftover = e.size;
  95.572 +            }
  95.573 +            final long offset = leftover;
  95.574 +            return new SeekableByteChannel() {
  95.575 +                long written = offset;
  95.576 +                public boolean isOpen() {
  95.577 +                    return wbc.isOpen();
  95.578 +                }
  95.579 +                public long position() throws IOException {
  95.580 +                    return written;
  95.581 +                }
  95.582 +                public SeekableByteChannel position(long pos) throws IOException {
  95.583 +                    throw new UnsupportedOperationException();
  95.584 +                }
  95.585 +                public int read(ByteBuffer dst) throws IOException {
  95.586 +                    throw new UnsupportedOperationException();
  95.587 +                }
  95.588 +                public SeekableByteChannel truncate(long size) throws IOException {
  95.589 +                    throw new UnsupportedOperationException();
  95.590 +                }
  95.591 +                public int write(ByteBuffer src) throws IOException {
  95.592 +                    int n = wbc.write(src);
  95.593 +                    written += n;
  95.594 +                    return n;
  95.595 +                }
  95.596 +                public long size() throws IOException {
  95.597 +                    return written;
  95.598 +                }
  95.599 +                public void close() throws IOException {
  95.600 +                    wbc.close();
  95.601 +                }
  95.602 +            };
  95.603 +        } else {
  95.604 +            Entry e = getEntry0(path);
  95.605 +            if (e == null || e.isDir())
  95.606 +                throw new NoSuchFileException(getString(path));
  95.607 +            final ReadableByteChannel rbc =
  95.608 +                Channels.newChannel(getInputStream(e));
  95.609 +            final long size = e.size;
  95.610 +            return new SeekableByteChannel() {
  95.611 +                long read = 0;
  95.612 +                public boolean isOpen() {
  95.613 +                    return rbc.isOpen();
  95.614 +                }
  95.615 +                public long position() throws IOException {
  95.616 +                    return read;
  95.617 +                }
  95.618 +                public SeekableByteChannel position(long pos) throws IOException {
  95.619 +                    throw new UnsupportedOperationException();
  95.620 +                }
  95.621 +                public int read(ByteBuffer dst) throws IOException {
  95.622 +                    return rbc.read(dst);
  95.623 +                }
  95.624 +                public SeekableByteChannel truncate(long size) throws IOException {
  95.625 +                    throw new NonWritableChannelException();
  95.626 +                }
  95.627 +                public int write (ByteBuffer src) throws IOException {
  95.628 +                    throw new NonWritableChannelException();
  95.629 +                }
  95.630 +                public long size() throws IOException {
  95.631 +                    return size;
  95.632 +                }
  95.633 +                public void close() throws IOException {
  95.634 +                    rbc.close();
  95.635 +                }
  95.636 +            };
  95.637 +        }
  95.638 +    }
  95.639 +
  95.640 +    // Returns a FileChannel of the specified entry.
  95.641 +    //
  95.642 +    // This implementation creates a temporary file on the default file system,
  95.643 +    // copy the entry data into it if the entry exists, and then create a
  95.644 +    // FileChannel on top of it.
  95.645 +    FileChannel newFileChannel(byte[] path,
  95.646 +                               Set<? extends OpenOption> options,
  95.647 +                               FileAttribute<?>... attrs)
  95.648 +        throws IOException
  95.649 +    {
  95.650 +        checkOptions(options);
  95.651 +        final  boolean forWrite = (options.contains(StandardOpenOption.WRITE) ||
  95.652 +                                   options.contains(StandardOpenOption.APPEND));
  95.653 +        Entry e = getEntry0(path);
  95.654 +        if (forWrite) {
  95.655 +            checkWritable();
  95.656 +            if (e == null) {
  95.657 +                if (!options.contains(StandardOpenOption.CREATE_NEW))
  95.658 +                    throw new NoSuchFileException(getString(path));
  95.659 +            } else {
  95.660 +                if (options.contains(StandardOpenOption.CREATE_NEW))
  95.661 +                    throw new FileAlreadyExistsException(getString(path));
  95.662 +                if (e.isDir())
  95.663 +                    throw new FileAlreadyExistsException("directory <"
  95.664 +                        + getString(path) + "> exists");
  95.665 +            }
  95.666 +            options.remove(StandardOpenOption.CREATE_NEW); // for tmpfile
  95.667 +        } else if (e == null || e.isDir()) {
  95.668 +            throw new NoSuchFileException(getString(path));
  95.669 +        }
  95.670 +
  95.671 +        final boolean isFCH = (e != null && e.type == Entry.FILECH);
  95.672 +        final Path tmpfile = isFCH ? e.file : getTempPathForEntry(path);
  95.673 +        final FileChannel fch = tmpfile.getFileSystem()
  95.674 +                                       .provider()
  95.675 +                                       .newFileChannel(tmpfile, options, attrs);
  95.676 +        final Entry u = isFCH ? e : new Entry(path, tmpfile, Entry.FILECH);
  95.677 +        if (forWrite) {
  95.678 +            u.flag = FLAG_DATADESCR;
  95.679 +            u.method = METHOD_DEFLATED;
  95.680 +        }
  95.681 +        // is there a better way to hook into the FileChannel's close method?
  95.682 +        return new FileChannel() {
  95.683 +            public int write(ByteBuffer src) throws IOException {
  95.684 +                return fch.write(src);
  95.685 +            }
  95.686 +            public long write(ByteBuffer[] srcs, int offset, int length)
  95.687 +                throws IOException
  95.688 +            {
  95.689 +                return fch.write(srcs, offset, length);
  95.690 +            }
  95.691 +            public long position() throws IOException {
  95.692 +                return fch.position();
  95.693 +            }
  95.694 +            public FileChannel position(long newPosition)
  95.695 +                throws IOException
  95.696 +            {
  95.697 +                fch.position(newPosition);
  95.698 +                return this;
  95.699 +            }
  95.700 +            public long size() throws IOException {
  95.701 +                return fch.size();
  95.702 +            }
  95.703 +            public FileChannel truncate(long size)
  95.704 +                throws IOException
  95.705 +            {
  95.706 +                fch.truncate(size);
  95.707 +                return this;
  95.708 +            }
  95.709 +            public void force(boolean metaData)
  95.710 +                throws IOException
  95.711 +            {
  95.712 +                fch.force(metaData);
  95.713 +            }
  95.714 +            public long transferTo(long position, long count,
  95.715 +                                   WritableByteChannel target)
  95.716 +                throws IOException
  95.717 +            {
  95.718 +                return fch.transferTo(position, count, target);
  95.719 +            }
  95.720 +            public long transferFrom(ReadableByteChannel src,
  95.721 +                                     long position, long count)
  95.722 +                throws IOException
  95.723 +            {
  95.724 +                return fch.transferFrom(src, position, count);
  95.725 +            }
  95.726 +            public int read(ByteBuffer dst) throws IOException {
  95.727 +                return fch.read(dst);
  95.728 +            }
  95.729 +            public int read(ByteBuffer dst, long position)
  95.730 +                throws IOException
  95.731 +            {
  95.732 +                return fch.read(dst, position);
  95.733 +            }
  95.734 +            public long read(ByteBuffer[] dsts, int offset, int length)
  95.735 +                throws IOException
  95.736 +            {
  95.737 +                return fch.read(dsts, offset, length);
  95.738 +            }
  95.739 +            public int write(ByteBuffer src, long position)
  95.740 +                throws IOException
  95.741 +            {
  95.742 +               return fch.write(src, position);
  95.743 +            }
  95.744 +            public MappedByteBuffer map(MapMode mode,
  95.745 +                                        long position, long size)
  95.746 +                throws IOException
  95.747 +            {
  95.748 +                throw new UnsupportedOperationException();
  95.749 +            }
  95.750 +            public FileLock lock(long position, long size, boolean shared)
  95.751 +                throws IOException
  95.752 +            {
  95.753 +                return fch.lock(position, size, shared);
  95.754 +            }
  95.755 +            public FileLock tryLock(long position, long size, boolean shared)
  95.756 +                throws IOException
  95.757 +            {
  95.758 +                return fch.tryLock(position, size, shared);
  95.759 +            }
  95.760 +            protected void implCloseChannel() throws IOException {
  95.761 +                fch.close();
  95.762 +                if (forWrite) {
  95.763 +                    u.mtime = javaToDosTime(System.currentTimeMillis());
  95.764 +                    u.size = Attributes.readBasicFileAttributes(u.file).size();
  95.765 +                    update(u);
  95.766 +                } else {
  95.767 +                    if (!isFCH)    // if this is a new fch for reading
  95.768 +                        removeTempPathForEntry(tmpfile);
  95.769 +                }
  95.770 +            }
  95.771 +        };
  95.772 +    }
  95.773 +
  95.774 +    // the outstanding input streams that need to be closed
  95.775 +    private Set<InputStream> streams =
  95.776 +        Collections.synchronizedSet(new HashSet<InputStream>());
  95.777 +
  95.778 +    // the ex-channel and ex-path that need to close when their outstanding
  95.779 +    // input streams are all closed by the obtainers.
  95.780 +    private Set<ExChannelCloser> exChClosers = new HashSet<>();
  95.781 +
  95.782 +    private Set<Path> tmppaths = new HashSet<>();
  95.783 +    private Path getTempPathForEntry(byte[] path) throws IOException {
  95.784 +        Path tmpPath = createTempFileInSameDirectoryAs(zfpath);
  95.785 +        tmppaths.add(tmpPath);
  95.786 +
  95.787 +        if (path != null) {
  95.788 +            Entry e = getEntry0(path);
  95.789 +            if (e != null) {
  95.790 +                InputStream is = newInputStream(path);
  95.791 +                OutputStream os = tmpPath.newOutputStream(WRITE);
  95.792 +                try {
  95.793 +                    copyStream(is, os);
  95.794 +                } finally {
  95.795 +                    is.close();
  95.796 +                    os.close();
  95.797 +                }
  95.798 +            }
  95.799 +        }
  95.800 +        return tmpPath;
  95.801 +    }
  95.802 +
  95.803 +    private void removeTempPathForEntry(Path path) throws IOException {
  95.804 +        path.delete();
  95.805 +        tmppaths.remove(path);
  95.806 +    }
  95.807 +
  95.808 +    // check if all parents really exit. ZIP spec does not require
  95.809 +    // the existence of any "parent directory".
  95.810 +    private void checkParents(byte[] path) throws IOException {
  95.811 +        while ((path = getParent(path)) != null) {
  95.812 +            if (!inodes.containsKey(new EntryName(path)))
  95.813 +                throw new NoSuchFileException(getString(path));
  95.814 +        }
  95.815 +    }
  95.816 +
  95.817 +    private static byte[] getParent(byte[] path) {
  95.818 +        int off = path.length - 1;
  95.819 +        if (off > 0 && path[off] == '/')  // isDirectory
  95.820 +            off--;
  95.821 +        while (off > 0 && path[off] != '/') { off--; }
  95.822 +        if (off == 0)
  95.823 +            return null;                  // top entry
  95.824 +        return Arrays.copyOf(path, off + 1);
  95.825 +    }
  95.826 +
  95.827 +    // If "starter" is the parent directory of "path"
  95.828 +    private static boolean isParentOf(byte[] p, byte[] c) {
  95.829 +        final int plen = p.length;
  95.830 +        if (plen == 0)          // root dir
  95.831 +            return true;
  95.832 +        if (plen  >= c.length)
  95.833 +            return false;
  95.834 +        int n = 0;
  95.835 +        while (n < plen) {
  95.836 +            if (p[n] != c[n])
  95.837 +                return false;
  95.838 +            n++;
  95.839 +        }
  95.840 +        if (p[n - 1] != '/' && (c[n] != '/' || n == c.length - 1))
  95.841 +            return false;
  95.842 +        return true;
  95.843 +    }
  95.844 +
  95.845 +    ///////////////////////////////////////////////////////////////////
  95.846 +    private void initZipFile() throws IOException {
  95.847 +        ch = zfpath.newByteChannel(READ);
  95.848 +        initCEN();
  95.849 +    }
  95.850 +
  95.851 +    private volatile boolean isOpen = true;
  95.852 +    private SeekableByteChannel ch; // channel to the zipfile
  95.853 +    ByteBuffer cen;        // CEN & ENDHDR
  95.854 +    private END  end;
  95.855 +    private long locpos;   // position of first LOC header (usually 0)
  95.856 +
  95.857 +    // name -> pos (in cen), package private for ZipInfo
  95.858 +    LinkedHashMap<EntryName, IndexNode> inodes;
  95.859 +
  95.860 +    byte[] getBytes(String name) {
  95.861 +        return zc.getBytes(name);
  95.862 +    }
  95.863 +    String getString(byte[] name) {
  95.864 +        return zc.toString(name);
  95.865 +    }
  95.866 +
  95.867 +    protected void finalize() throws IOException {
  95.868 +        close();
  95.869 +    }
  95.870 +
  95.871 +    private long getDataPos(Entry e) throws IOException {
  95.872 +        if (e.locoff == -1) {
  95.873 +            Entry e2 = getEntry0(e.name);
  95.874 +            if (e2 == null)
  95.875 +                throw new ZipException("invalid loc for entry <" + e.name + ">");
  95.876 +            e.locoff = e2.locoff;
  95.877 +        }
  95.878 +        byte[] buf = new byte[LOCHDR];
  95.879 +        if (readFullyAt(buf, 0, buf.length, e.locoff) != buf.length)
  95.880 +            throw new ZipException("invalid loc for entry <" + e.name + ">");
  95.881 +        return locpos + e.locoff + LOCHDR + LOCNAM(buf) + LOCEXT(buf);
  95.882 +    }
  95.883 +
  95.884 +    // Reads len bytes of data from the specified offset into buf.
  95.885 +    // Returns the total number of bytes read.
  95.886 +    // Each/every byte read from here (except the cen, which is mapped).
  95.887 +    private long readFullyAt(byte[] buf, int off, long len, long pos)
  95.888 +        throws IOException
  95.889 +    {
  95.890 +        ByteBuffer bb = ByteBuffer.wrap(buf);
  95.891 +        bb.position(off);
  95.892 +        bb.limit((int)(off + len));
  95.893 +        return readFullyAt(bb, pos);
  95.894 +    }
  95.895 +
  95.896 +    private long readFullyAt(ByteBuffer bb, long pos)
  95.897 +        throws IOException
  95.898 +    {
  95.899 +        synchronized(ch) {
  95.900 +            return ch.position(pos).read(bb);
  95.901 +        }
  95.902 +    }
  95.903 +
  95.904 +    // Searches for end of central directory (END) header. The contents of
  95.905 +    // the END header will be read and placed in endbuf. Returns the file
  95.906 +    // position of the END header, otherwise returns -1 if the END header
  95.907 +    // was not found or an error occurred.
  95.908 +    private END findEND() throws IOException
  95.909 +    {
  95.910 +        byte[] buf = new byte[READBLOCKSZ];
  95.911 +        long ziplen = ch.size();
  95.912 +        long minHDR = (ziplen - END_MAXLEN) > 0 ? ziplen - END_MAXLEN : 0;
  95.913 +        long minPos = minHDR - (buf.length - ENDHDR);
  95.914 +
  95.915 +        for (long pos = ziplen - buf.length; pos >= minPos; pos -= (buf.length - ENDHDR))
  95.916 +        {
  95.917 +            int off = 0;
  95.918 +            if (pos < 0) {
  95.919 +                // Pretend there are some NUL bytes before start of file
  95.920 +                off = (int)-pos;
  95.921 +                Arrays.fill(buf, 0, off, (byte)0);
  95.922 +            }
  95.923 +            int len = buf.length - off;
  95.924 +            if (readFullyAt(buf, off, len, pos + off) != len)
  95.925 +                zerror("zip END header not found");
  95.926 +
  95.927 +            // Now scan the block backwards for END header signature
  95.928 +            for (int i = buf.length - ENDHDR; i >= 0; i--) {
  95.929 +                if (buf[i+0] == (byte)'P'    &&
  95.930 +                    buf[i+1] == (byte)'K'    &&
  95.931 +                    buf[i+2] == (byte)'\005' &&
  95.932 +                    buf[i+3] == (byte)'\006' &&
  95.933 +                    (pos + i + ENDHDR + ENDCOM(buf, i) == ziplen)) {
  95.934 +                    // Found END header
  95.935 +                    buf = Arrays.copyOfRange(buf, i, i + ENDHDR);
  95.936 +                    END end = new END();
  95.937 +                    end.endsub = ENDSUB(buf);
  95.938 +                    end.centot = ENDTOT(buf);
  95.939 +                    end.cenlen = ENDSIZ(buf);
  95.940 +                    end.cenoff = ENDOFF(buf);
  95.941 +                    end.comlen = ENDCOM(buf);
  95.942 +                    end.endpos = pos + i;
  95.943 +                    if (end.cenlen == ZIP64_MINVAL ||
  95.944 +                        end.cenoff == ZIP64_MINVAL ||
  95.945 +                        end.centot == ZIP64_MINVAL32)
  95.946 +                    {
  95.947 +                        // need to find the zip64 end;
  95.948 +                        byte[] loc64 = new byte[ZIP64_LOCHDR];
  95.949 +                        if (readFullyAt(loc64, 0, loc64.length, end.endpos - ZIP64_LOCHDR)
  95.950 +                            != loc64.length) {
  95.951 +                            return end;
  95.952 +                        }
  95.953 +                        long end64pos = ZIP64_LOCOFF(loc64);
  95.954 +                        byte[] end64buf = new byte[ZIP64_ENDHDR];
  95.955 +                        if (readFullyAt(end64buf, 0, end64buf.length, end64pos)
  95.956 +                            != end64buf.length) {
  95.957 +                            return end;
  95.958 +                        }
  95.959 +                        // end64 found, re-calcualte everything.
  95.960 +                        end.cenlen = ZIP64_ENDSIZ(end64buf);
  95.961 +                        end.cenoff = ZIP64_ENDOFF(end64buf);
  95.962 +                        end.centot = (int)ZIP64_ENDTOT(end64buf); // assume total < 2g
  95.963 +                        end.endpos = end64pos;
  95.964 +                    }
  95.965 +                    return end;
  95.966 +                }
  95.967 +            }
  95.968 +        }
  95.969 +        zerror("zip END header not found");
  95.970 +        return null; //make compiler happy
  95.971 +    }
  95.972 +
  95.973 +    // Reads zip file central directory. Returns the file position of first
  95.974 +    // CEN header, otherwise returns -1 if an error occured. If zip->msg != NULL
  95.975 +    // then the error was a zip format error and zip->msg has the error text.
  95.976 +    // Always pass in -1 for knownTotal; it's used for a recursive call.
  95.977 +    private long initCEN() throws IOException {
  95.978 +        end = findEND();
  95.979 +        if (end.endpos == 0) {
  95.980 +            inodes = new LinkedHashMap<EntryName, IndexNode>(10);
  95.981 +            locpos = 0;
  95.982 +            return 0;         // only END header present
  95.983 +        }
  95.984 +        if (end.cenlen > end.endpos)
  95.985 +            zerror("invalid END header (bad central directory size)");
  95.986 +        long cenpos = end.endpos - end.cenlen;     // position of CEN table
  95.987 +
  95.988 +        // Get position of first local file (LOC) header, taking into
  95.989 +        // account that there may be a stub prefixed to the zip file.
  95.990 +        locpos = cenpos - end.cenoff;
  95.991 +        if (locpos < 0)
  95.992 +            zerror("invalid END header (bad central directory offset)");
  95.993 +
  95.994 +        // read in the CEN and END
  95.995 +        cen = ByteBuffer.allocate((int)(end.cenlen + ENDHDR));
  95.996 +        if (readFullyAt(cen, cenpos) != end.cenlen + ENDHDR) {
  95.997 +            zerror("read CEN tables failed");
  95.998 +        }
  95.999 +        cen.order(ByteOrder.LITTLE_ENDIAN).flip();
 95.1000 +
 95.1001 +        // Iterate through the entries in the central directory
 95.1002 +        inodes = new LinkedHashMap<EntryName, IndexNode>(end.centot + 1);
 95.1003 +        int pos = 0;
 95.1004 +        int limit = cen.remaining() - ENDHDR;
 95.1005 +        int i = 0;
 95.1006 +        byte[] bBuf = new byte[1024];
 95.1007 +        while (pos < limit) {
 95.1008 +            if (CENSIG(cen, pos) != CENSIG)
 95.1009 +                zerror("invalid CEN header (bad signature)");
 95.1010 +            int method = CENHOW(cen, pos);
 95.1011 +            int nlen   = CENNAM(cen, pos);
 95.1012 +            int elen   = CENEXT(cen, pos);
 95.1013 +            int clen   = CENCOM(cen, pos);
 95.1014 +            if ((CENFLG(cen, pos) & 1) != 0)
 95.1015 +                zerror("invalid CEN header (encrypted entry)");
 95.1016 +            if (method != METHOD_STORED && method != METHOD_DEFLATED)
 95.1017 +                zerror("invalid CEN header (bad compression method: " + method + ")");
 95.1018 +            if (pos + CENHDR + nlen > limit)
 95.1019 +                zerror("invalid CEN header (bad header size)");
 95.1020 +            if (bBuf.length < nlen)
 95.1021 +                 bBuf = new byte[nlen];
 95.1022 +            cen.position(pos + CENHDR);
 95.1023 +            byte[] name = new byte[nlen];
 95.1024 +            cen.get(name);
 95.1025 +            inodes.put(new EntryName(name), new IndexNode(name, pos));
 95.1026 +            // skip ext and comment
 95.1027 +            cen.position(pos += (CENHDR + nlen + elen + clen));
 95.1028 +            i++;
 95.1029 +        }
 95.1030 +        if (cen.remaining() != ENDHDR) {
 95.1031 +            zerror("invalid CEN header (bad header size)");
 95.1032 +        }
 95.1033 +        dirs = null;  // clear the dir map
 95.1034 +        return cenpos;
 95.1035 +    }
 95.1036 +
 95.1037 +    private void ensureOpen() throws IOException {
 95.1038 +        if (!isOpen)
 95.1039 +            throw new ClosedFileSystemException();
 95.1040 +    }
 95.1041 +
 95.1042 +    // Creates a new empty temporary file in the same directory as the
 95.1043 +    // specified file.  A variant of File.createTempFile.
 95.1044 +    private static Path createTempFileInSameDirectoryAs(Path path)
 95.1045 +        throws IOException
 95.1046 +    {
 95.1047 +        Path parent = path.toAbsolutePath().getParent();
 95.1048 +        String dir = (parent == null)? "." : parent.toString();
 95.1049 +        return File.createTempFile("zipfstmp", null, new File(dir)).toPath();
 95.1050 +    }
 95.1051 +
 95.1052 +    ////////////////////update & sync //////////////////////////////////////
 95.1053 +
 95.1054 +    private boolean hasUpdate = false;
 95.1055 +    private void updateDelete(Entry e) {
 95.1056 +        EntryName en = new EntryName(e.name);
 95.1057 +        inodes.remove(en);
 95.1058 +        hasUpdate = true;
 95.1059 +    }
 95.1060 +
 95.1061 +    private void update(Entry e) {
 95.1062 +        EntryName en = new EntryName(e.name);
 95.1063 +        inodes.put(en, e);
 95.1064 +        hasUpdate = true;
 95.1065 +    }
 95.1066 +
 95.1067 +    // copy over the whole LOC entry (header if necessary, data and ext) from
 95.1068 +    // old zip to the new one.
 95.1069 +    private long copyLOCEntry(Entry e, boolean updateHeader,
 95.1070 +                              OutputStream os,
 95.1071 +                              long written, byte[] buf)
 95.1072 +        throws IOException
 95.1073 +    {
 95.1074 +        long locoff = e.locoff;  // where to read
 95.1075 +        e.locoff = written;      // update the e.locoff with new value
 95.1076 +
 95.1077 +        // calculate the size need to write out
 95.1078 +        long size = 0;
 95.1079 +        //  if there is A ext
 95.1080 +        if ((e.flag & FLAG_DATADESCR) != 0) {
 95.1081 +            if (e.size >= ZIP64_MINVAL || e.csize >= ZIP64_MINVAL)
 95.1082 +                size = 24;
 95.1083 +            else
 95.1084 +                size = 16;
 95.1085 +        }
 95.1086 +        if (updateHeader) {       // if we need update the loc header
 95.1087 +            locoff += LOCHDR + e.nlen + e.elen;  // skip header
 95.1088 +            size += e.csize;
 95.1089 +            written = e.writeLOC(os) + size;
 95.1090 +        } else {
 95.1091 +            size += LOCHDR + e.nlen + e.elen + e.csize;
 95.1092 +            written = size;
 95.1093 +        }
 95.1094 +        int n;
 95.1095 +        while (size > 0 &&
 95.1096 +            (n = (int)readFullyAt(buf, 0, buf.length, locoff)) != -1)
 95.1097 +        {
 95.1098 +            if (size < n)
 95.1099 +                n = (int)size;
 95.1100 +            os.write(buf, 0, n);
 95.1101 +            size -= n;
 95.1102 +            locoff += n;
 95.1103 +        }
 95.1104 +        return written;
 95.1105 +    }
 95.1106 +
 95.1107 +    // sync the zip file system, if there is any udpate
 95.1108 +    private void sync() throws IOException {
 95.1109 +        assert Thread.holdsLock(this);
 95.1110 +
 95.1111 +        // check ex-closer
 95.1112 +        if (!exChClosers.isEmpty()) {
 95.1113 +            for (ExChannelCloser ecc : exChClosers) {
 95.1114 +                if (ecc.streams.isEmpty()) {
 95.1115 +                    ecc.ch.close();
 95.1116 +                    ecc.path.delete();
 95.1117 +                    exChClosers.remove(ecc);
 95.1118 +                }
 95.1119 +            }
 95.1120 +        }
 95.1121 +        if (!hasUpdate)
 95.1122 +            return;
 95.1123 +
 95.1124 +        Path tmpFile = createTempFileInSameDirectoryAs(zfpath);
 95.1125 +        OutputStream os = tmpFile.newOutputStream(WRITE);
 95.1126 +        ArrayList<Entry> elist = new ArrayList<>(inodes.size());
 95.1127 +        long written = 0;
 95.1128 +        byte[] buf = new byte[8192];
 95.1129 +        Entry e = null;
 95.1130 +
 95.1131 +        // write loc
 95.1132 +        for (IndexNode inode : inodes.values()) {
 95.1133 +            if (inode instanceof Entry) {    // an updated inode
 95.1134 +                e = (Entry)inode;
 95.1135 +                try {
 95.1136 +                    if (e.type == Entry.COPY) {
 95.1137 +                        // entry copy: the only thing changed is the "name"
 95.1138 +                        // and "nlen" in LOC header, so we udpate/rewrite the
 95.1139 +                        // LOC in new file and simply copy the rest (data and
 95.1140 +                        // ext) without enflating/deflating from the old zip
 95.1141 +                        // file LOC entry.
 95.1142 +                        written += copyLOCEntry(e, true, os, written, buf);
 95.1143 +                    } else {                          // NEW or FILECH
 95.1144 +                        e.locoff = written;
 95.1145 +                        written += e.writeLOC(os);    // write loc header
 95.1146 +                        if (e.bytes != null) {        // in-memory, deflated
 95.1147 +                            os.write(e.bytes);        // already
 95.1148 +                            written += e.bytes.length;
 95.1149 +                        } else if (e.file != null) {  // tmp file
 95.1150 +                            InputStream is = e.file.newInputStream();
 95.1151 +                            int n;
 95.1152 +                            if (e.type == Entry.NEW) {  // deflated already
 95.1153 +                                while ((n = is.read(buf)) != -1) {
 95.1154 +                                    os.write(buf, 0, n);
 95.1155 +                                    written += n;
 95.1156 +                                }
 95.1157 +                            } else if (e.type == Entry.FILECH) {
 95.1158 +                                // the data are not deflated, use ZEOS
 95.1159 +                                OutputStream os2 = new EntryOutputStream(e, os);
 95.1160 +                                while ((n = is.read(buf)) != -1) {
 95.1161 +                                    os2.write(buf, 0, n);
 95.1162 +                                }
 95.1163 +                                os2.close();
 95.1164 +                                written += e.csize;
 95.1165 +                                if ((e.flag & FLAG_DATADESCR) != 0)
 95.1166 +                                    written += e.writeEXT(os);
 95.1167 +                            }
 95.1168 +                            is.close();
 95.1169 +                            e.file.delete();
 95.1170 +                            tmppaths.remove(e.file);
 95.1171 +                        } else {
 95.1172 +                            // dir, 0-length data
 95.1173 +                        }
 95.1174 +                    }
 95.1175 +                    elist.add(e);
 95.1176 +                } catch (IOException x) {
 95.1177 +                    x.printStackTrace();    // skip any in-accurate entry
 95.1178 +                }
 95.1179 +            } else {    // unchanged inode
 95.1180 +                e = Entry.readCEN(cen, inode.pos);
 95.1181 +                try {
 95.1182 +                    written += copyLOCEntry(e, false, os, written, buf);
 95.1183 +                    elist.add(e);
 95.1184 +                } catch (IOException x) {
 95.1185 +                    x.printStackTrace();    // skip any wrong entry
 95.1186 +                }
 95.1187 +            }
 95.1188 +        }
 95.1189 +
 95.1190 +        // now write back the cen and end table
 95.1191 +        end.cenoff = written;
 95.1192 +        for (Entry entry : elist) {
 95.1193 +            written += entry.writeCEN(os);
 95.1194 +        }
 95.1195 +        end.centot = elist.size();
 95.1196 +        end.cenlen = written - end.cenoff;
 95.1197 +        end.write(os, written);
 95.1198 +        os.close();
 95.1199 +
 95.1200 +        if (!streams.isEmpty()) {
 95.1201 +            // There are outstanding input streams open on existing "ch",
 95.1202 +            // so, don't close the "cha" and delete the "file for now, let
 95.1203 +            // the "ex-channel-closer" to handle them
 95.1204 +            ExChannelCloser ecc = new ExChannelCloser(
 95.1205 +                                      createTempFileInSameDirectoryAs(zfpath),
 95.1206 +                                      ch,
 95.1207 +                                      streams);
 95.1208 +            zfpath.moveTo(ecc.path, REPLACE_EXISTING);
 95.1209 +            exChClosers.add(ecc);
 95.1210 +            streams = Collections.synchronizedSet(new HashSet<InputStream>());
 95.1211 +        } else {
 95.1212 +            ch.close();
 95.1213 +            zfpath.delete();
 95.1214 +        }
 95.1215 +        tmpFile.moveTo(zfpath, REPLACE_EXISTING);
 95.1216 +        hasUpdate = false;    // clear
 95.1217 +
 95.1218 +        if (isOpen) {
 95.1219 +            ch = zfpath.newByteChannel(READ); // re-fresh "ch" and "cen"
 95.1220 +            initCEN();
 95.1221 +        }
 95.1222 +        //System.out.println("->sync() done!");
 95.1223 +    }
 95.1224 +
 95.1225 +    private Entry getEntry0(byte[] path) throws IOException {
 95.1226 +        assert Thread.holdsLock(this);
 95.1227 +
 95.1228 +        if (path == null)
 95.1229 +            throw new NullPointerException("path");
 95.1230 +        if (path.length == 0)
 95.1231 +            return null;
 95.1232 +        EntryName en = new EntryName(path);
 95.1233 +        IndexNode inode = null;
 95.1234 +        synchronized (lock) {
 95.1235 +            ensureOpen();
 95.1236 +            if ((inode = inodes.get(en)) == null) {
 95.1237 +                if (path[path.length -1] == '/')  // already has a slash
 95.1238 +                    return null;
 95.1239 +                path = Arrays.copyOf(path, path.length + 1);
 95.1240 +                path[path.length - 1] = '/';
 95.1241 +                en.name(path);
 95.1242 +                if ((inode = inodes.get(en)) == null)
 95.1243 +                    return null;
 95.1244 +            }
 95.1245 +            if (inode instanceof Entry)
 95.1246 +                return (Entry)inode;
 95.1247 +            return Entry.readCEN(cen, inode.pos);
 95.1248 +        }
 95.1249 +    }
 95.1250 +
 95.1251 +    // Test if the "name" a parent directory of any entry (dir empty)
 95.1252 +    boolean isAncestor(byte[] name) {
 95.1253 +        for (Map.Entry<EntryName, IndexNode> entry : inodes.entrySet()) {
 95.1254 +            byte[] ename = entry.getKey().name;
 95.1255 +            if (isParentOf(name, ename))
 95.1256 +                return true;
 95.1257 +        }
 95.1258 +        return false;
 95.1259 +    }
 95.1260 +
 95.1261 +    public void deleteFile(byte[] path, boolean failIfNotExists)
 95.1262 +        throws IOException
 95.1263 +    {
 95.1264 +        checkWritable();
 95.1265 +        synchronized(lock) {
 95.1266 +            Entry e = getEntry0(path);
 95.1267 +            if (e == null) {
 95.1268 +                if (path != null && path.length == 0)
 95.1269 +                    throw new ZipException("root directory </> can't not be delete");
 95.1270 +                if (failIfNotExists)
 95.1271 +                    throw new NoSuchFileException(getString(path));
 95.1272 +            } else {
 95.1273 +                if (e.isDir() && isAncestor(path))
 95.1274 +                    throw new DirectoryNotEmptyException(getString(path));
 95.1275 +                updateDelete(e);
 95.1276 +            }
 95.1277 +        }
 95.1278 +    }
 95.1279 +
 95.1280 +    private static void copyStream(InputStream is, OutputStream os)
 95.1281 +        throws IOException
 95.1282 +    {
 95.1283 +        byte[] copyBuf = new byte[8192];
 95.1284 +        int n;
 95.1285 +        while ((n = is.read(copyBuf)) != -1) {
 95.1286 +            os.write(copyBuf, 0, n);
 95.1287 +        }
 95.1288 +    }
 95.1289 +
 95.1290 +    // Returns an out stream for either
 95.1291 +    // (1) writing the contents of a new entry, if the entry exits, or
 95.1292 +    // (2) updating/replacing the contents of the specified existing entry.
 95.1293 +    private OutputStream getOutputStream(Entry e) throws IOException {
 95.1294 +
 95.1295 +        ensureOpen();
 95.1296 +        if (e.mtime == -1)
 95.1297 +            e.mtime = javaToDosTime(System.currentTimeMillis());
 95.1298 +        if (e.method == -1)
 95.1299 +            e.method = METHOD_DEFLATED;  // TBD:  use default method
 95.1300 +        // store size, compressed size, and crc-32 in LOC header
 95.1301 +        e.flag = 0;
 95.1302 +        if (zc.isUTF8())
 95.1303 +            e.flag |= FLAG_EFS;
 95.1304 +        OutputStream os;
 95.1305 +        if (useTempFile) {
 95.1306 +            e.file = getTempPathForEntry(null);
 95.1307 +            os = e.file.newOutputStream(WRITE);
 95.1308 +        } else {
 95.1309 +            os = new ByteArrayOutputStream((e.size > 0)? (int)e.size : 8192);
 95.1310 +        }
 95.1311 +        return new EntryOutputStream(e, os);
 95.1312 +    }
 95.1313 +
 95.1314 +    private InputStream getInputStream(Entry e)
 95.1315 +        throws IOException
 95.1316 +    {
 95.1317 +        InputStream eis = null;
 95.1318 +
 95.1319 +        if (e.type == Entry.NEW) {
 95.1320 +            if (e.bytes != null)
 95.1321 +                eis = new ByteArrayInputStream(e.bytes);
 95.1322 +            else if (e.file != null)
 95.1323 +                eis = e.file.newInputStream();
 95.1324 +            else
 95.1325 +                throw new ZipException("update entry data is missing");
 95.1326 +        } else if (e.type == Entry.FILECH) {
 95.1327 +            // FILECH result is un-compressed.
 95.1328 +            eis = e.file.newInputStream();
 95.1329 +            // TBD: wrap to hook close()
 95.1330 +            // streams.add(eis);
 95.1331 +            return eis;
 95.1332 +        } else {  // untouced  CEN or COPY
 95.1333 +            eis = new EntryInputStream(e, ch);
 95.1334 +        }
 95.1335 +        if (e.method == METHOD_DEFLATED) {
 95.1336 +            // MORE: Compute good size for inflater stream:
 95.1337 +            long bufSize = e.size + 2; // Inflater likes a bit of slack
 95.1338 +            if (bufSize > 65536)
 95.1339 +                bufSize = 8192;
 95.1340 +            final long size = e.size;;
 95.1341 +            eis = new InflaterInputStream(eis, getInflater(), (int)bufSize) {
 95.1342 +
 95.1343 +                private boolean isClosed = false;
 95.1344 +                public void close() throws IOException {
 95.1345 +                    if (!isClosed) {
 95.1346 +                        releaseInflater(inf);
 95.1347 +                        this.in.close();
 95.1348 +                        isClosed = true;
 95.1349 +                    }
 95.1350 +                }
 95.1351 +                // Override fill() method to provide an extra "dummy" byte
 95.1352 +                // at the end of the input stream. This is required when
 95.1353 +                // using the "nowrap" Inflater option. (it appears the new
 95.1354 +                // zlib in 7 does not need it, but keep it for now)
 95.1355 +                protected void fill() throws IOException {
 95.1356 +                    if (eof) {
 95.1357 +                        throw new EOFException(
 95.1358 +                            "Unexpected end of ZLIB input stream");
 95.1359 +                    }
 95.1360 +                    len = this.in.read(buf, 0, buf.length);
 95.1361 +                    if (len == -1) {
 95.1362 +                        buf[0] = 0;
 95.1363 +                        len = 1;
 95.1364 +                        eof = true;
 95.1365 +                    }
 95.1366 +                    inf.setInput(buf, 0, len);
 95.1367 +                }
 95.1368 +                private boolean eof;
 95.1369 +
 95.1370 +                public int available() throws IOException {
 95.1371 +                    if (isClosed)
 95.1372 +                        return 0;
 95.1373 +                    long avail = size - inf.getBytesWritten();
 95.1374 +                    return avail > (long) Integer.MAX_VALUE ?
 95.1375 +                        Integer.MAX_VALUE : (int) avail;
 95.1376 +                }
 95.1377 +            };
 95.1378 +        } else if (e.method != METHOD_STORED) {
 95.1379 +            throw new ZipException("invalid compression method");
 95.1380 +        }
 95.1381 +        streams.add(eis);
 95.1382 +        return eis;
 95.1383 +    }
 95.1384 +
 95.1385 +    // Inner class implementing the input stream used to read
 95.1386 +    // a (possibly compressed) zip file entry.
 95.1387 +    private class EntryInputStream extends InputStream {
 95.1388 +        private SeekableByteChannel zfch; // local ref to zipfs's "ch". zipfs.ch might
 95.1389 +                                          // point to a new channel after sync()
 95.1390 +        private   long pos;               // current position within entry data
 95.1391 +        protected long rem;               // number of remaining bytes within entry
 95.1392 +        protected long size;              // uncompressed size of this entry
 95.1393 +
 95.1394 +        EntryInputStream(Entry e, SeekableByteChannel zfch)
 95.1395 +            throws IOException
 95.1396 +        {
 95.1397 +            this.zfch = zfch;
 95.1398 +            rem = e.csize;
 95.1399 +            size = e.size;
 95.1400 +            pos = getDataPos(e);
 95.1401 +        }
 95.1402 +        public int read(byte b[], int off, int len) throws IOException {
 95.1403 +            ensureOpen();
 95.1404 +            if (rem == 0) {
 95.1405 +                return -1;
 95.1406 +            }
 95.1407 +            if (len <= 0) {
 95.1408 +                return 0;
 95.1409 +            }
 95.1410 +            if (len > rem) {
 95.1411 +                len = (int) rem;
 95.1412 +            }
 95.1413 +            // readFullyAt()
 95.1414 +            long n = 0;
 95.1415 +            ByteBuffer bb = ByteBuffer.wrap(b);
 95.1416 +            bb.position(off);
 95.1417 +            bb.limit(off + len);
 95.1418 +            synchronized(zfch) {
 95.1419 +                n = zfch.position(pos).read(bb);
 95.1420 +            }
 95.1421 +            if (n > 0) {
 95.1422 +                pos += n;
 95.1423 +                rem -= n;
 95.1424 +            }
 95.1425 +            if (rem == 0) {
 95.1426 +                close();
 95.1427 +            }
 95.1428 +            return (int)n;
 95.1429 +        }
 95.1430 +        public int read() throws IOException {
 95.1431 +            byte[] b = new byte[1];
 95.1432 +            if (read(b, 0, 1) == 1) {
 95.1433 +                return b[0] & 0xff;
 95.1434 +            } else {
 95.1435 +                return -1;
 95.1436 +            }
 95.1437 +        }
 95.1438 +        public long skip(long n) throws IOException {
 95.1439 +            ensureOpen();
 95.1440 +            if (n > rem)
 95.1441 +                n = rem;
 95.1442 +            pos += n;
 95.1443 +            rem -= n;
 95.1444 +            if (rem == 0) {
 95.1445 +                close();
 95.1446 +            }
 95.1447 +            return n;
 95.1448 +        }
 95.1449 +        public int available() {
 95.1450 +            return rem > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) rem;
 95.1451 +        }
 95.1452 +
 95.1453 +        public long size() {
 95.1454 +            return size;
 95.1455 +        }
 95.1456 +        public void close() {
 95.1457 +            rem = 0;
 95.1458 +            streams.remove(this);
 95.1459 +        }
 95.1460 +    }
 95.1461 +
 95.1462 +    class EntryOutputStream extends DeflaterOutputStream
 95.1463 +    {
 95.1464 +        private CRC32 crc;
 95.1465 +        private Entry e;
 95.1466 +        private long written;
 95.1467 +
 95.1468 +        EntryOutputStream(Entry e, OutputStream os)
 95.1469 +            throws IOException
 95.1470 +        {
 95.1471 +            super(os, getDeflater());
 95.1472 +            if (e == null)
 95.1473 +                throw new NullPointerException("Zip entry is null");
 95.1474 +            this.e = e;
 95.1475 +            crc = new CRC32();
 95.1476 +        }
 95.1477 +
 95.1478 +        @Override
 95.1479 +        public void write(byte b[], int off, int len) throws IOException {
 95.1480 +            if (e.type != Entry.FILECH)    // only from sync
 95.1481 +                ensureOpen();
 95.1482 +            if (off < 0 || len < 0 || off > b.length - len) {
 95.1483 +                throw new IndexOutOfBoundsException();
 95.1484 +            } else if (len == 0) {
 95.1485 +                return;
 95.1486 +            }
 95.1487 +            switch (e.method) {
 95.1488 +            case METHOD_DEFLATED:
 95.1489 +                super.write(b, off, len);
 95.1490 +                break;
 95.1491 +            case METHOD_STORED:
 95.1492 +                written += len;
 95.1493 +                out.write(b, off, len);
 95.1494 +                break;
 95.1495 +            default:
 95.1496 +                throw new ZipException("invalid compression method");
 95.1497 +            }
 95.1498 +            crc.update(b, off, len);
 95.1499 +        }
 95.1500 +
 95.1501 +        @Override
 95.1502 +        public void close() throws IOException {
 95.1503 +            // TBD ensureOpen();
 95.1504 +            switch (e.method) {
 95.1505 +            case METHOD_DEFLATED:
 95.1506 +                finish();
 95.1507 +                e.size  = def.getBytesRead();
 95.1508 +                e.csize = def.getBytesWritten();
 95.1509 +                e.crc = crc.getValue();
 95.1510 +                break;
 95.1511 +            case METHOD_STORED:
 95.1512 +                // we already know that both e.size and e.csize are the same
 95.1513 +                e.size = e.csize = written;
 95.1514 +                e.crc = crc.getValue();
 95.1515 +                break;
 95.1516 +            default:
 95.1517 +                throw new ZipException("invalid compression method");
 95.1518 +            }
 95.1519 +            //crc.reset();
 95.1520 +            if (out instanceof ByteArrayOutputStream)
 95.1521 +                e.bytes = ((ByteArrayOutputStream)out).toByteArray();
 95.1522 +
 95.1523 +            if (e.type == Entry.FILECH) {
 95.1524 +                releaseDeflater(def);
 95.1525 +                return;
 95.1526 +            }
 95.1527 +            super.close();
 95.1528 +            releaseDeflater(def);
 95.1529 +            update(e);
 95.1530 +        }
 95.1531 +    }
 95.1532 +
 95.1533 +    private static void zerror(String msg) {
 95.1534 +        throw new ZipError(msg);
 95.1535 +    }
 95.1536 +
 95.1537 +    // Maxmum number of de/inflater we cache
 95.1538 +    private final int MAX_FLATER = 20;
 95.1539 +    // List of available Inflater objects for decompression
 95.1540 +    private List<Inflater> inflaters = new ArrayList<>();
 95.1541 +
 95.1542 +    // Gets an inflater from the list of available inflaters or allocates
 95.1543 +    // a new one.
 95.1544 +    private Inflater getInflater() {
 95.1545 +        synchronized (inflaters) {
 95.1546 +            int size = inflaters.size();
 95.1547 +            if (size > 0) {
 95.1548 +                Inflater inf = (Inflater)inflaters.remove(size - 1);
 95.1549 +                return inf;
 95.1550 +            } else {
 95.1551 +                return new Inflater(true);
 95.1552 +            }
 95.1553 +        }
 95.1554 +    }
 95.1555 +
 95.1556 +    // Releases the specified inflater to the list of available inflaters.
 95.1557 +    private void releaseInflater(Inflater inf) {
 95.1558 +        synchronized (inflaters) {
 95.1559 +            if (inflaters.size() < MAX_FLATER) {
 95.1560 +                inf.reset();
 95.1561 +                inflaters.add(inf);
 95.1562 +            } else {
 95.1563 +                inf.end();
 95.1564 +            }
 95.1565 +        }
 95.1566 +    }
 95.1567 +
 95.1568 +    // List of available Deflater objects for compression
 95.1569 +    private List<Deflater> deflaters = new ArrayList<>();
 95.1570 +
 95.1571 +    // Gets an deflater from the list of available deflaters or allocates
 95.1572 +    // a new one.
 95.1573 +    private Deflater getDeflater() {
 95.1574 +        synchronized (deflaters) {
 95.1575 +            int size = deflaters.size();
 95.1576 +            if (size > 0) {
 95.1577 +                Deflater def = (Deflater)deflaters.remove(size - 1);
 95.1578 +                return def;
 95.1579 +            } else {
 95.1580 +                return new Deflater(Deflater.DEFAULT_COMPRESSION, true);
 95.1581 +            }
 95.1582 +        }
 95.1583 +    }
 95.1584 +
 95.1585 +    // Releases the specified inflater to the list of available inflaters.
 95.1586 +    private void releaseDeflater(Deflater def) {
 95.1587 +        synchronized (deflaters) {
 95.1588 +            if (inflaters.size() < MAX_FLATER) {
 95.1589 +               def.reset();
 95.1590 +               deflaters.add(def);
 95.1591 +            } else {
 95.1592 +               def.end();
 95.1593 +            }
 95.1594 +        }
 95.1595 +    }
 95.1596 +
 95.1597 +    // End of central directory record
 95.1598 +    static class END {
 95.1599 +        int  disknum;
 95.1600 +        int  sdisknum;
 95.1601 +        int  endsub;     // endsub
 95.1602 +        int  centot;     // 4 bytes
 95.1603 +        long cenlen;     // 4 bytes
 95.1604 +        long cenoff;     // 4 bytes
 95.1605 +        int  comlen;     // comment length
 95.1606 +        byte[] comment;
 95.1607 +
 95.1608 +        /* members of Zip64 end of central directory locator */
 95.1609 +        int diskNum;
 95.1610 +        long endpos;
 95.1611 +        int disktot;
 95.1612 +
 95.1613 +        void write(OutputStream os, long offset) throws IOException {
 95.1614 +            boolean hasZip64 = false;
 95.1615 +            long xlen = cenlen;
 95.1616 +            long xoff = cenoff;
 95.1617 +            if (xlen >= ZIP64_MINVAL) {
 95.1618 +                xlen = ZIP64_MINVAL;
 95.1619 +                hasZip64 = true;
 95.1620 +            }
 95.1621 +            if (xoff >= ZIP64_MINVAL) {
 95.1622 +                xoff = ZIP64_MINVAL;
 95.1623 +                hasZip64 = true;
 95.1624 +            }
 95.1625 +            int count = centot;
 95.1626 +            if (count >= ZIP64_MINVAL32) {
 95.1627 +                count = ZIP64_MINVAL32;
 95.1628 +                hasZip64 = true;
 95.1629 +            }
 95.1630 +            if (hasZip64) {
 95.1631 +                long off64 = offset;
 95.1632 +                //zip64 end of central directory record
 95.1633 +                writeInt(os, ZIP64_ENDSIG);       // zip64 END record signature
 95.1634 +                writeLong(os, ZIP64_ENDHDR - 12); // size of zip64 end
 95.1635 +                writeShort(os, 45);               // version made by
 95.1636 +                writeShort(os, 45);               // version needed to extract
 95.1637 +                writeInt(os, 0);                  // number of this disk
 95.1638 +                writeInt(os, 0);                  // central directory start disk
 95.1639 +                writeLong(os, centot);            // number of directory entires on disk
 95.1640 +                writeLong(os, centot);            // number of directory entires
 95.1641 +                writeLong(os, cenlen);            // length of central directory
 95.1642 +                writeLong(os, cenoff);            // offset of central directory
 95.1643 +
 95.1644 +                //zip64 end of central directory locator
 95.1645 +                writeInt(os, ZIP64_LOCSIG);       // zip64 END locator signature
 95.1646 +                writeInt(os, 0);                  // zip64 END start disk
 95.1647 +                writeLong(os, off64);             // offset of zip64 END
 95.1648 +                writeInt(os, 1);                  // total number of disks (?)
 95.1649 +            }
 95.1650 +            writeInt(os, ENDSIG);                 // END record signature
 95.1651 +            writeShort(os, 0);                    // number of this disk
 95.1652 +            writeShort(os, 0);                    // central directory start disk
 95.1653 +            writeShort(os, count);                // number of directory entries on disk
 95.1654 +            writeShort(os, count);                // total number of directory entries
 95.1655 +            writeInt(os, xlen);                   // length of central directory
 95.1656 +            writeInt(os, xoff);                   // offset of central directory
 95.1657 +            if (comment != null) {            // zip file comment
 95.1658 +                writeShort(os, comment.length);
 95.1659 +                writeBytes(os, comment);
 95.1660 +            } else {
 95.1661 +                writeShort(os, 0);
 95.1662 +            }
 95.1663 +        }
 95.1664 +    }
 95.1665 +
 95.1666 +    // wrapper for the byte[] name
 95.1667 +    static class EntryName {
 95.1668 +        byte[] name;
 95.1669 +        int hashcode;    // node is hashable/hashed by its name
 95.1670 +
 95.1671 +        public EntryName (byte[] name) {
 95.1672 +            name(name);
 95.1673 +        }
 95.1674 +
 95.1675 +        void name(byte[] name) {
 95.1676 +            this.name = name;
 95.1677 +            this.hashcode = Arrays.hashCode(name);
 95.1678 +        }
 95.1679 +
 95.1680 +        public boolean equals(Object other) {
 95.1681 +            if (!(other instanceof EntryName))
 95.1682 +                return false;
 95.1683 +            return Arrays.equals(name, ((EntryName)other).name);
 95.1684 +        }
 95.1685 +
 95.1686 +        public int hashCode() {
 95.1687 +            return hashcode;
 95.1688 +        }
 95.1689 +    }
 95.1690 +
 95.1691 +    // can simply use Integer instead, if we don't use it to
 95.1692 +    // build a internal node tree.
 95.1693 +    static class IndexNode {
 95.1694 +        byte[] name;
 95.1695 +        int pos = -1;     // postion in cen table, -1 menas the
 95.1696 +                          // entry does not exists in zip file
 95.1697 +        IndexNode(byte[] name, int pos) {
 95.1698 +            this.name = name;
 95.1699 +            this.pos = pos;
 95.1700 +        }
 95.1701 +
 95.1702 +        IndexNode() {}
 95.1703 +
 95.1704 +        IndexNode sibling;
 95.1705 +        IndexNode child;  // 1st child
 95.1706 +    }
 95.1707 +
 95.1708 +    static class Entry extends IndexNode {
 95.1709 +
 95.1710 +        static final int CEN    = 1;    // entry read from cen
 95.1711 +        static final int NEW    = 2;    // updated contents in bytes or file
 95.1712 +        static final int FILECH = 3;    // fch update in "file"
 95.1713 +        static final int COPY   = 4;    // copy of a CEN entry
 95.1714 +
 95.1715 +        byte[] bytes;      // updated content bytes
 95.1716 +        Path   file;       // use tmp file to store bytes;
 95.1717 +        int    type = CEN; // default is the entry read from cen
 95.1718 +
 95.1719 +        // entry attributes
 95.1720 +        int    version;
 95.1721 +        int    flag;
 95.1722 +        int    method = -1;    // compression method
 95.1723 +        long   mtime  = -1;    // last modification time (in DOS time)
 95.1724 +        long   atime  = -1;    // last access time
 95.1725 +        long   ctime  = -1;    // create time
 95.1726 +        long   crc    = -1;    // crc-32 of entry data
 95.1727 +        long   csize  = -1;    // compressed size of entry data
 95.1728 +        long   size   = -1;    // uncompressed size of entry data
 95.1729 +        int    nlen;
 95.1730 +        int    elen;
 95.1731 +        byte[] extra;
 95.1732 +
 95.1733 +        // loc
 95.1734 +        long   startPos;
 95.1735 +        long   endPos;         // exclusive
 95.1736 +
 95.1737 +        // cen
 95.1738 +        int    versionMade;
 95.1739 +        int    disk;
 95.1740 +        int    attrs;
 95.1741 +        long   attrsEx;
 95.1742 +        long   locoff;
 95.1743 +
 95.1744 +        int    clen;
 95.1745 +        byte[] comment;
 95.1746 +
 95.1747 +        // ZIP64 flag
 95.1748 +        boolean hasZip64;
 95.1749 +
 95.1750 +        Entry() {}
 95.1751 +
 95.1752 +        Entry(byte[] name) {
 95.1753 +            this.name = name;
 95.1754 +            //this.nlen = name.length;
 95.1755 +            this.mtime  = javaToDosTime(System.currentTimeMillis());
 95.1756 +            this.crc       = 0;
 95.1757 +            this.size      = 0;
 95.1758 +            this.csize     = 0;
 95.1759 +            this.method    = METHOD_DEFLATED;
 95.1760 +        }
 95.1761 +
 95.1762 +        Entry(byte[] name, int type) {
 95.1763 +            this(name);
 95.1764 +            this.type = type;
 95.1765 +        }
 95.1766 +
 95.1767 +        Entry (byte[] name, Path file, int type) {
 95.1768 +            this(name, type);
 95.1769 +            this.file = file;
 95.1770 +            this.method = METHOD_STORED;
 95.1771 +        }
 95.1772 +
 95.1773 +        Entry(Entry e) {
 95.1774 +            this.version   = e.version;
 95.1775 +            this.name      = e.name;  // copyOf?
 95.1776 +            this.nlen      = e.nlen;
 95.1777 +            this.ctime     = e.ctime;
 95.1778 +            this.atime     = e.atime;
 95.1779 +            this.mtime     = e.mtime;
 95.1780 +            this.crc       = e.crc;
 95.1781 +            this.size      = e.size;
 95.1782 +            this.csize     = e.csize;
 95.1783 +            this.method    = e.method;
 95.1784 +            this.extra     = (e.extra == null)?
 95.1785 +                             null:Arrays.copyOf(e.extra, e.extra.length);
 95.1786 +            this.elen      = e.elen;
 95.1787 +            this.versionMade = e.versionMade;
 95.1788 +            this.disk      = e.disk;
 95.1789 +            this.attrs     = e.attrs;
 95.1790 +            this.attrsEx   = e.attrsEx;
 95.1791 +            this.locoff    = e.locoff;
 95.1792 +            this.clen      = e.clen;
 95.1793 +            this.comment   = (e.comment == null)?
 95.1794 +                             null:Arrays.copyOf(e.comment, e.comment.length);
 95.1795 +            this.startPos = e.startPos;
 95.1796 +            this.endPos   = e.endPos;
 95.1797 +            this.hasZip64 = e.hasZip64;;
 95.1798 +        }
 95.1799 +
 95.1800 +        Entry (Entry e, int type) {
 95.1801 +            this(e);
 95.1802 +            this.type = type;
 95.1803 +        }
 95.1804 +
 95.1805 +        boolean isDir() {
 95.1806 +            return name != null &&
 95.1807 +                   (name.length == 0 ||
 95.1808 +                    name[name.length - 1] == '/');
 95.1809 +        }
 95.1810 +
 95.1811 +        int version() throws ZipException {
 95.1812 +            if (method == METHOD_DEFLATED)
 95.1813 +                return 20;
 95.1814 +            else if (method == METHOD_STORED)
 95.1815 +                return 10;
 95.1816 +            throw new ZipException("unsupported compression method");
 95.1817 +        }
 95.1818 +
 95.1819 +        ///////////////////// CEN //////////////////////
 95.1820 +        static Entry readCEN(ByteBuffer cen, int pos) throws IOException
 95.1821 +        {
 95.1822 +            return new Entry().cen(cen, pos);
 95.1823 +        }
 95.1824 +
 95.1825 +        private Entry cen(ByteBuffer cen, int pos) throws IOException
 95.1826 +        {
 95.1827 +            if (CENSIG(cen, pos) != CENSIG)
 95.1828 +                zerror("invalid CEN header (bad signature)");
 95.1829 +            versionMade = CENVEM(cen, pos);
 95.1830 +            version     = CENVER(cen, pos);
 95.1831 +            flag        = CENFLG(cen, pos);
 95.1832 +            method      = CENHOW(cen, pos);
 95.1833 +            mtime       = CENTIM(cen, pos);
 95.1834 +            crc         = CENCRC(cen, pos);
 95.1835 +            csize       = CENSIZ(cen, pos);
 95.1836 +            size        = CENLEN(cen, pos);
 95.1837 +            nlen        = CENNAM(cen, pos);
 95.1838 +            elen        = CENEXT(cen, pos);
 95.1839 +            clen        = CENCOM(cen, pos);
 95.1840 +            disk        = CENDSK(cen, pos);
 95.1841 +            attrs       = CENATT(cen, pos);
 95.1842 +            attrsEx     = CENATX(cen, pos);
 95.1843 +            locoff      = CENOFF(cen, pos);
 95.1844 +
 95.1845 +            cen.position(pos + CENHDR);
 95.1846 +            name = new byte[nlen];
 95.1847 +            cen.get(name);
 95.1848 +
 95.1849 +            if (elen > 0) {
 95.1850 +                extra = new byte[elen];
 95.1851 +                cen.get(extra);
 95.1852 +                if (csize == ZIP64_MINVAL || size == ZIP64_MINVAL ||
 95.1853 +                    locoff == ZIP64_MINVAL) {
 95.1854 +                    int off = 0;
 95.1855 +                    while (off + 4 < elen) {
 95.1856 +                        // extra spec: HeaderID+DataSize+Data
 95.1857 +                        int sz = SH(extra, off + 2);
 95.1858 +                        if (SH(extra, off) == EXTID_ZIP64) {
 95.1859 +                            off += 4;
 95.1860 +                            if (size == ZIP64_MINVAL) {
 95.1861 +                                // if invalid zip64 extra fields, just skip
 95.1862 +                                if (sz < 8 || (off + 8) > elen)
 95.1863 +                                    break;
 95.1864 +                                size = LL(extra, off);
 95.1865 +                                sz -= 8;
 95.1866 +                                off += 8;
 95.1867 +                            }
 95.1868 +                            if (csize == ZIP64_MINVAL) {
 95.1869 +                                if (sz < 8 || (off + 8) > elen)
 95.1870 +                                    break;
 95.1871 +                                csize = LL(extra, off);
 95.1872 +                                sz -= 8;
 95.1873 +                                off += 8;
 95.1874 +                            }
 95.1875 +                            if (locoff == ZIP64_MINVAL) {
 95.1876 +                                if (sz < 8 || (off + 8) > elen)
 95.1877 +                                    break;
 95.1878 +                                locoff = LL(extra, off);
 95.1879 +                                sz -= 8;
 95.1880 +                                off += 8;
 95.1881 +                            }
 95.1882 +                            break;
 95.1883 +                        }
 95.1884 +                        off += (sz + 4);
 95.1885 +                    }
 95.1886 +                }
 95.1887 +            }
 95.1888 +            if (clen > 0) {
 95.1889 +                comment = new byte[clen];
 95.1890 +                cen.get(comment);
 95.1891 +            }
 95.1892 +            return this;
 95.1893 +        }
 95.1894 +
 95.1895 +        int writeCEN(OutputStream os) throws IOException
 95.1896 +        {
 95.1897 +            int written  = CENHDR;
 95.1898 +            int version0 = version();
 95.1899 +
 95.1900 +            long csize0  = csize;
 95.1901 +            long size0   = size;
 95.1902 +            long locoff0 = locoff;
 95.1903 +            int e64len   = 0;
 95.1904 +
 95.1905 +            // confirm size/length
 95.1906 +            nlen = (name != null) ? name.length : 0;
 95.1907 +            elen = (extra != null) ? extra.length : 0;
 95.1908 +            clen = (comment != null) ? comment.length : 0;
 95.1909 +
 95.1910 +            boolean hasZip64 = false;
 95.1911 +            if (csize >= ZIP64_MINVAL) {
 95.1912 +                csize0 = ZIP64_MINVAL;
 95.1913 +                e64len += 8;                 // csize(8)
 95.1914 +                hasZip64 = true;
 95.1915 +            }
 95.1916 +            if (size >= ZIP64_MINVAL) {
 95.1917 +                size0 = ZIP64_MINVAL;        // size(8)
 95.1918 +                e64len += 8;
 95.1919 +                hasZip64 = true;
 95.1920 +            }
 95.1921 +            if (locoff >= ZIP64_MINVAL) {
 95.1922 +                locoff0 = ZIP64_MINVAL;
 95.1923 +                e64len += 8;                 // offset(8)
 95.1924 +                hasZip64 = true;
 95.1925 +            }
 95.1926 +            writeInt(os, CENSIG);            // CEN header signature
 95.1927 +            if (hasZip64) {
 95.1928 +                writeShort(os, 45);          // ver 4.5 for zip64
 95.1929 +                writeShort(os, 45);
 95.1930 +            } else {
 95.1931 +                writeShort(os, version0);    // version made by
 95.1932 +                writeShort(os, version0);    // version needed to extract
 95.1933 +            }
 95.1934 +            writeShort(os, flag);            // general purpose bit flag
 95.1935 +            writeShort(os, method);          // compression method
 95.1936 +            writeInt(os, mtime);             // last modification time
 95.1937 +            writeInt(os, crc);               // crc-32
 95.1938 +            writeInt(os, csize0);            // compressed size
 95.1939 +            writeInt(os, size0);             // uncompressed size
 95.1940 +            writeShort(os, name.length);
 95.1941 +
 95.1942 +            if (hasZip64) {
 95.1943 +                // + headid(2) + datasize(2)
 95.1944 +                writeShort(os, e64len + 4 + elen);
 95.1945 +            } else {
 95.1946 +                writeShort(os, elen);
 95.1947 +            }
 95.1948 +            if (comment != null) {
 95.1949 +                writeShort(os, Math.min(clen, 0xffff));
 95.1950 +            } else {
 95.1951 +                writeShort(os, 0);
 95.1952 +            }
 95.1953 +            writeShort(os, 0);              // starting disk number
 95.1954 +            writeShort(os, 0);              // internal file attributes (unused)
 95.1955 +            writeInt(os, 0);                // external file attributes (unused)
 95.1956 +            writeInt(os, locoff0);          // relative offset of local header
 95.1957 +            writeBytes(os, name);
 95.1958 +            if (hasZip64) {
 95.1959 +                writeShort(os, EXTID_ZIP64);// Zip64 extra
 95.1960 +                writeShort(os, e64len);
 95.1961 +                if (size0 == ZIP64_MINVAL)
 95.1962 +                    writeLong(os, size);
 95.1963 +                if (csize0 == ZIP64_MINVAL)
 95.1964 +                    writeLong(os, csize);
 95.1965 +                if (locoff0 == ZIP64_MINVAL)
 95.1966 +                    writeLong(os, locoff);
 95.1967 +            }
 95.1968 +            if (extra != null) {
 95.1969 +                writeBytes(os, extra);
 95.1970 +            }
 95.1971 +            if (comment != null) {
 95.1972 +                //TBD: 0, Math.min(commentBytes.length, 0xffff));
 95.1973 +                writeBytes(os, comment);
 95.1974 +            }
 95.1975 +            return CENHDR + nlen + elen + clen + (hasZip64?(e64len + 4):0);
 95.1976 +        }
 95.1977 +
 95.1978 +        ///////////////////// LOC //////////////////////
 95.1979 +        static Entry readLOC(ZipFileSystem zf, long pos)
 95.1980 +            throws IOException
 95.1981 +        {
 95.1982 +            return readLOC(zf, pos, new byte[1024]);
 95.1983 +        }
 95.1984 +
 95.1985 +        static Entry readLOC(ZipFileSystem zf, long pos, byte[] buf)
 95.1986 +            throws IOException
 95.1987 +        {
 95.1988 +            return new Entry().loc(zf, pos, buf);
 95.1989 +        }
 95.1990 +
 95.1991 +        Entry loc(ZipFileSystem zf, long pos, byte[] buf)
 95.1992 +            throws IOException
 95.1993 +        {
 95.1994 +            assert (buf.length >= LOCHDR);
 95.1995 +            if (zf.readFullyAt(buf, 0, LOCHDR , pos) != LOCHDR) {
 95.1996 +                throw new ZipException("loc: reading failed");
 95.1997 +            }
 95.1998 +            if (LOCSIG(buf) != LOCSIG) {
 95.1999 +                throw new ZipException("loc: wrong sig ->"
 95.2000 +                                       + Long.toString(LOCSIG(buf), 16));
 95.2001 +            }
 95.2002 +            startPos = pos;
 95.2003 +            version  = LOCVER(buf);
 95.2004 +            flag     = LOCFLG(buf);
 95.2005 +            method   = LOCHOW(buf);
 95.2006 +            mtime    = LOCTIM(buf);
 95.2007 +            crc      = LOCCRC(buf);
 95.2008 +            csize    = LOCSIZ(buf);
 95.2009 +            size     = LOCLEN(buf);
 95.2010 +            nlen     = LOCNAM(buf);
 95.2011 +            elen     = LOCEXT(buf);
 95.2012 +
 95.2013 +            name = new byte[nlen];
 95.2014 +            if (zf.readFullyAt(name, 0, nlen, pos + LOCHDR) != nlen) {
 95.2015 +                throw new ZipException("loc: name reading failed");
 95.2016 +            }
 95.2017 +            if (elen > 0) {
 95.2018 +                extra = new byte[elen];
 95.2019 +                if (zf.readFullyAt(extra, 0, elen, pos + LOCHDR + nlen)
 95.2020 +                    != elen) {
 95.2021 +                    throw new ZipException("loc: ext reading failed");
 95.2022 +                }
 95.2023 +            }
 95.2024 +            pos += (LOCHDR + nlen + elen);
 95.2025 +            if ((flag & FLAG_DATADESCR) != 0) {
 95.2026 +                // Data Descriptor
 95.2027 +                Entry e = zf.getEntry0(name);  // get the size/csize from cen
 95.2028 +                if (e == null)
 95.2029 +                    throw new ZipException("loc: name not found in cen");
 95.2030 +                size = e.size;
 95.2031 +                csize = e.csize;
 95.2032 +                pos += (method == METHOD_STORED ? size : csize);
 95.2033 +                if (size >= ZIP64_MINVAL || csize >= ZIP64_MINVAL)
 95.2034 +                    pos += 24;
 95.2035 +                else
 95.2036 +                    pos += 16;
 95.2037 +            } else {
 95.2038 +                boolean hasZip64 = false;
 95.2039 +                if (extra != null &&
 95.2040 +                    (size == ZIP64_MINVAL || csize == ZIP64_MINVAL)) {
 95.2041 +                    // zip64 ext: must include both size and csize
 95.2042 +                    int off = 0;
 95.2043 +                    while (off + 20 < elen) {    // HeaderID+DataSize+Data
 95.2044 +                        int sz = SH(extra, off + 2);
 95.2045 +                        if (SH(extra, off) == EXTID_ZIP64 && sz == 16) {
 95.2046 +                            size = LL(extra, off + 4);
 95.2047 +                            csize = LL(extra, off + 12);
 95.2048 +                            hasZip64 = true;
 95.2049 +                            break;
 95.2050 +                        }
 95.2051 +                        off += (sz + 4);
 95.2052 +                    }
 95.2053 +                }
 95.2054 +                pos += (method == METHOD_STORED ? size : csize);
 95.2055 +            }
 95.2056 +            endPos = pos;
 95.2057 +            return this;
 95.2058 +        }
 95.2059 +
 95.2060 +        int writeLOC(OutputStream os)
 95.2061 +            throws IOException
 95.2062 +        {
 95.2063 +            writeInt(os, LOCSIG);               // LOC header signature
 95.2064 +
 95.2065 +            int version = version();
 95.2066 +            if ((flag & FLAG_DATADESCR) != 0) {
 95.2067 +                writeShort(os, version());      // version needed to extract
 95.2068 +                writeShort(os, flag);           // general purpose bit flag
 95.2069 +                writeShort(os, method);         // compression method
 95.2070 +                writeInt(os, mtime);            // last modification time
 95.2071 +
 95.2072 +                // store size, uncompressed size, and crc-32 in data descriptor
 95.2073 +                // immediately following compressed entry data
 95.2074 +                writeInt(os, 0);
 95.2075 +                writeInt(os, 0);
 95.2076 +                writeInt(os, 0);
 95.2077 +            } else {
 95.2078 +                if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) {
 95.2079 +                    hasZip64 = true;
 95.2080 +                    writeShort(os, 45);         // ver 4.5 for zip64
 95.2081 +                } else {
 95.2082 +                    writeShort(os, version());  // version needed to extract
 95.2083 +                }
 95.2084 +                writeShort(os, flag);           // general purpose bit flag
 95.2085 +                writeShort(os, method);         // compression method
 95.2086 +                writeInt(os, mtime);            // last modification time
 95.2087 +                writeInt(os, crc);              // crc-32
 95.2088 +                if (hasZip64) {
 95.2089 +                    writeInt(os, ZIP64_MINVAL);
 95.2090 +                    writeInt(os, ZIP64_MINVAL);
 95.2091 +                    //TBD:  e.elen += 20;       //headid(2) + size(2) + size(8) + csize(8)
 95.2092 +                } else {
 95.2093 +                    writeInt(os, csize);        // compressed size
 95.2094 +                    writeInt(os, size);         // uncompressed size
 95.2095 +                }
 95.2096 +            }
 95.2097 +            writeShort(os, name.length);
 95.2098 +            writeShort(os, elen + (hasZip64 ? 20 : 0));
 95.2099 +            writeBytes(os, name);
 95.2100 +            if (hasZip64) {
 95.2101 +                // TBD: should we update extra directory?
 95.2102 +                writeShort(os, EXTID_ZIP64);
 95.2103 +                writeShort(os, 16);
 95.2104 +                writeLong(os, size);
 95.2105 +                writeLong(os, csize);
 95.2106 +            }
 95.2107 +            if (extra != null) {
 95.2108 +                writeBytes(os, extra);
 95.2109 +            }
 95.2110 +            return LOCHDR + name.length + elen + (hasZip64 ? 20 : 0);
 95.2111 +        }
 95.2112 +
 95.2113 +        // Data Descriptior
 95.2114 +        int writeEXT(OutputStream os)
 95.2115 +            throws IOException
 95.2116 +        {
 95.2117 +            writeInt(os, EXTSIG);           // EXT header signature
 95.2118 +            writeInt(os, crc);              // crc-32
 95.2119 +            if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) {
 95.2120 +                writeLong(os, csize);
 95.2121 +                writeLong(os, size);
 95.2122 +                return 24;
 95.2123 +            } else {
 95.2124 +                writeInt(os, csize);        // compressed size
 95.2125 +                writeInt(os, size);         // uncompressed size
 95.2126 +                return 16;
 95.2127 +            }
 95.2128 +        }
 95.2129 +
 95.2130 +        // read NTFS, UNIX and ZIP64 data from cen.extra
 95.2131 +        void readExtra() {
 95.2132 +            if (extra == null)
 95.2133 +                return;
 95.2134 +            int elen = extra.length;
 95.2135 +            int off = 0;
 95.2136 +            while (off + 4 < elen) {
 95.2137 +                // extra spec: HeaderID+DataSize+Data
 95.2138 +                int sz = SH(extra, off + 2);
 95.2139 +                int tag = SH(extra, off);
 95.2140 +                off += 4;
 95.2141 +                int pos = off;
 95.2142 +                if (pos + sz > elen)         // invalid data
 95.2143 +                    break;
 95.2144 +                switch (tag) {
 95.2145 +                case EXTID_ZIP64 :
 95.2146 +                    if (size == ZIP64_MINVAL) {
 95.2147 +                        if (pos + 8 > elen)  // invalid zip64 extra
 95.2148 +                            break;           // fields, just skip
 95.2149 +                        size = LL(extra, pos);
 95.2150 +                        pos += 8;
 95.2151 +                    }
 95.2152 +                    if (csize == ZIP64_MINVAL) {
 95.2153 +                        if (pos + 8 > elen)
 95.2154 +                            break;
 95.2155 +                        csize = LL(extra, pos);
 95.2156 +                        pos += 8;
 95.2157 +                    }
 95.2158 +                    if (locoff == ZIP64_MINVAL) {
 95.2159 +                        if (pos + 8 > elen)
 95.2160 +                            break;
 95.2161 +                        locoff = LL(extra, pos);
 95.2162 +                        pos += 8;
 95.2163 +                    }
 95.2164 +                    break;
 95.2165 +                case EXTID_NTFS:
 95.2166 +                    pos += 4;    // reserved 4 bytes
 95.2167 +                    if (SH(extra, pos) !=  0x0001)
 95.2168 +                        break;
 95.2169 +                    if (SH(extra, pos + 2) != 24)
 95.2170 +                        break;
 95.2171 +                    mtime = LL(extra, pos + 4);
 95.2172 +                    atime = LL(extra, pos + 12);
 95.2173 +                    ctime = LL(extra, pos + 20);
 95.2174 +                    break;
 95.2175 +                case EXTID_UNIX:
 95.2176 +                    atime = LG(extra, pos);
 95.2177 +                    mtime = LG(extra, pos + 4);
 95.2178 +                    break;
 95.2179 +                default:    // unknow
 95.2180 +                }
 95.2181 +                off += sz;
 95.2182 +            }
 95.2183 +        }
 95.2184 +    }
 95.2185 +
 95.2186 +    private static class ExChannelCloser  {
 95.2187 +        Path path;
 95.2188 +        SeekableByteChannel ch;
 95.2189 +        Set<InputStream> streams;
 95.2190 +        ExChannelCloser(Path path,
 95.2191 +                        SeekableByteChannel ch,
 95.2192 +                        Set<InputStream> streams)
 95.2193 +        {
 95.2194 +            this.path = path;
 95.2195 +            this.ch = ch;
 95.2196 +            this.streams = streams;
 95.2197 +        }
 95.2198 +    }
 95.2199 +
 95.2200 +    // ZIP directory has two issues:
 95.2201 +    // (1) ZIP spec does not require the ZIP file to include
 95.2202 +    //     directory entry
 95.2203 +    // (2) all entries are not stored/organized in a "tree"
 95.2204 +    //     structure.
 95.2205 +    // A possible solution is to build the node tree ourself as
 95.2206 +    // implemented below.
 95.2207 +    private HashMap<EntryName, IndexNode> dirs;
 95.2208 +    private IndexNode root;
 95.2209 +    private IndexNode addToDir(EntryName child) {
 95.2210 +        IndexNode cinode = dirs.get(child);
 95.2211 +        if (cinode != null)
 95.2212 +            return cinode;
 95.2213 +
 95.2214 +        byte[] cname = child.name;
 95.2215 +        byte[] pname = getParent(cname);
 95.2216 +        IndexNode pinode;
 95.2217 +
 95.2218 +        if (pname != null)
 95.2219 +            pinode = addToDir(new EntryName(pname));
 95.2220 +        else
 95.2221 +            pinode = root;
 95.2222 +        cinode = inodes.get(child);
 95.2223 +        if (cname[cname.length -1] != '/') {  // not a dir
 95.2224 +            cinode.sibling = pinode.child;
 95.2225 +            pinode.child = cinode;
 95.2226 +            return null;
 95.2227 +        }
 95.2228 +        cinode = dirs.get(child);
 95.2229 +        if (cinode == null)  // pseudo directry entry
 95.2230 +            cinode = new IndexNode(cname, -1);
 95.2231 +        cinode.sibling = pinode.child;
 95.2232 +        pinode.child = cinode;
 95.2233 +
 95.2234 +        dirs.put(child, cinode);
 95.2235 +        return cinode;
 95.2236 +    }
 95.2237 +
 95.2238 +    private HashMap<EntryName, IndexNode> getDirs()
 95.2239 +        throws IOException
 95.2240 +    {
 95.2241 +        if (hasUpdate)
 95.2242 +            sync();
 95.2243 +        if (dirs != null)
 95.2244 +            return dirs;
 95.2245 +        dirs = new HashMap<EntryName, IndexNode>();
 95.2246 +        byte[] empty = new byte[0];
 95.2247 +        root = new IndexNode(empty, -1);
 95.2248 +        dirs.put(new EntryName(empty), root);
 95.2249 +
 95.2250 +        EntryName[] names = inodes.keySet().toArray(new EntryName[0]);
 95.2251 +        int i = names.length;
 95.2252 +        while (--i >= 0) {
 95.2253 +            addToDir(names[i]);
 95.2254 +        }
 95.2255 +        // for (int i EntryName en : inodes.keySet()) {
 95.2256 +        //     addToDir(en);
 95.2257 +        // }
 95.2258 +        return dirs;
 95.2259 +    }
 95.2260 +}
    96.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    96.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystemProvider.java	Mon Oct 18 11:25:28 2010 -0400
    96.3 @@ -0,0 +1,152 @@
    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.IOException;
   96.38 +import java.nio.channels.FileChannel;
   96.39 +import java.nio.file.FileRef;
   96.40 +import java.nio.file.FileSystem;
   96.41 +import java.nio.file.FileSystemNotFoundException;
   96.42 +import java.nio.file.FileSystemAlreadyExistsException;
   96.43 +import java.nio.file.OpenOption;
   96.44 +import java.nio.file.Path;
   96.45 +import java.nio.file.Paths;
   96.46 +import java.nio.file.ProviderMismatchException;
   96.47 +import java.nio.file.attribute.FileAttribute;
   96.48 +import java.nio.file.spi.FileSystemProvider;
   96.49 +import java.net.URI;
   96.50 +import java.net.URISyntaxException;
   96.51 +import java.util.HashMap;
   96.52 +import java.util.Map;
   96.53 +import java.util.Set;
   96.54 +
   96.55 +/*
   96.56 + *
   96.57 + * @author  Xueming Shen, Rajendra Gutupalli, Jaya Hangal
   96.58 + */
   96.59 +
   96.60 +public class ZipFileSystemProvider extends FileSystemProvider {
   96.61 +    private final Map<Path, ZipFileSystem> filesystems = new HashMap<>();
   96.62 +
   96.63 +    public ZipFileSystemProvider() {}
   96.64 +
   96.65 +    @Override
   96.66 +    public String getScheme() {
   96.67 +        return "zip";
   96.68 +    }
   96.69 +
   96.70 +    protected Path uriToPath(URI uri) {
   96.71 +        String scheme = uri.getScheme();
   96.72 +        if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) {
   96.73 +            throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'");
   96.74 +        }
   96.75 +        try {
   96.76 +            return Paths.get(new URI("file", uri.getHost(), uri.getPath(), null))
   96.77 +                        .toAbsolutePath();
   96.78 +        } catch (URISyntaxException e) {
   96.79 +            throw new AssertionError(e); //never thrown
   96.80 +        }
   96.81 +    }
   96.82 +
   96.83 +    @Override
   96.84 +    public FileSystem newFileSystem(URI uri, Map<String, ?> env)
   96.85 +        throws IOException
   96.86 +    {
   96.87 +        return newFileSystem(uriToPath(uri), env);
   96.88 +    }
   96.89 +
   96.90 +    @Override
   96.91 +    public FileSystem newFileSystem(FileRef file, Map<String, ?> env)
   96.92 +        throws IOException
   96.93 +    {
   96.94 +        if (!(file instanceof Path))
   96.95 +            throw new UnsupportedOperationException();
   96.96 +        Path path = (Path)file;
   96.97 +        if (!path.toUri().getScheme().equalsIgnoreCase("file")) {
   96.98 +            throw new UnsupportedOperationException();
   96.99 +        }
  96.100 +        return newFileSystem(path, env);
  96.101 +    }
  96.102 +
  96.103 +    private FileSystem newFileSystem(Path path, Map<String, ?> env)
  96.104 +        throws IOException
  96.105 +    {
  96.106 +        synchronized(filesystems) {
  96.107 +            if (filesystems.containsKey(path))
  96.108 +                throw new FileSystemAlreadyExistsException();
  96.109 +            ZipFileSystem zipfs = new ZipFileSystem(this, path, env);
  96.110 +            filesystems.put(path, zipfs);
  96.111 +            return zipfs;
  96.112 +        }
  96.113 +    }
  96.114 +
  96.115 +    @Override
  96.116 +    public Path getPath(URI uri) {
  96.117 +        FileSystem fs = getFileSystem(uri);
  96.118 +        String fragment = uri.getFragment();
  96.119 +        if (fragment == null) {
  96.120 +            throw new IllegalArgumentException("URI: "
  96.121 +                + uri
  96.122 +                + " does not contain path fragment ex. zip:///c:/foo.zip#/BAR");
  96.123 +        }
  96.124 +        return fs.getPath(fragment);
  96.125 +    }
  96.126 +
  96.127 +    @Override
  96.128 +    public FileChannel newFileChannel(Path path,
  96.129 +            Set<? extends OpenOption> options,
  96.130 +            FileAttribute<?>... attrs)
  96.131 +            throws IOException
  96.132 +    {
  96.133 +        if (path == null)
  96.134 +            throw new NullPointerException("path is null");
  96.135 +        if (path instanceof ZipPath)
  96.136 +            return ((ZipPath)path).newFileChannel(options, attrs);
  96.137 +        throw new ProviderMismatchException();
  96.138 +    }
  96.139 +
  96.140 +    @Override
  96.141 +    public FileSystem getFileSystem(URI uri) {
  96.142 +        synchronized (filesystems) {
  96.143 +            ZipFileSystem zipfs = filesystems.get(uriToPath(uri));
  96.144 +            if (zipfs == null)
  96.145 +                throw new FileSystemNotFoundException();
  96.146 +            return zipfs;
  96.147 +        }
  96.148 +    }
  96.149 +
  96.150 +    void removeFileSystem(Path zfpath) {
  96.151 +        synchronized (filesystems) {
  96.152 +            filesystems.remove(zfpath);
  96.153 +        }
  96.154 +    }
  96.155 +}
    97.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    97.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipInfo.java	Mon Oct 18 11:25:28 2010 -0400
    97.3 @@ -0,0 +1,132 @@
    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.PrintStream;
   97.38 +import java.nio.file.Paths;
   97.39 +import java.util.Collections;
   97.40 +import java.util.Iterator;
   97.41 +import java.util.Map;
   97.42 +import com.sun.nio.zipfs.ZipFileSystem.Entry;
   97.43 +import static com.sun.nio.zipfs.ZipConstants.*;
   97.44 +import static com.sun.nio.zipfs.ZipUtils.*;
   97.45 +
   97.46 +/**
   97.47 + * Print the loc and cen tables of the ZIP file
   97.48 + *
   97.49 + * @author  Xueming Shen
   97.50 + */
   97.51 +
   97.52 +public class ZipInfo {
   97.53 +
   97.54 +    public static void main(String[] args) throws Throwable {
   97.55 +        if (args.length < 2) {
   97.56 +            print("Usage: java ZipInfo [cen|loc] zfname");
   97.57 +        } else {
   97.58 +            Map<String, ?> env = Collections.emptyMap();
   97.59 +            ZipFileSystem zfs = (ZipFileSystem)(new ZipFileSystemProvider()
   97.60 +                                    .newFileSystem(Paths.get(args[1]), env));
   97.61 +
   97.62 +            long pos = 0;
   97.63 +
   97.64 +            if ("loc".equals(args[0])) {
   97.65 +                print("[Local File Header]%n");
   97.66 +                byte[] buf = new byte[1024];
   97.67 +                for (int i = 0; i < zfs.getEntryNames().length; i++) {
   97.68 +                    Entry loc = Entry.readLOC(zfs, pos, buf);
   97.69 +                    print("--------loc[%x]--------%n", pos);
   97.70 +                    printLOC(loc);
   97.71 +                    pos = loc.endPos;
   97.72 +                }
   97.73 +            } if ("cen".equals(args[0])) {
   97.74 +                int i = 0;
   97.75 +                Iterator<ZipFileSystem.IndexNode> itr = zfs.inodes.values().iterator();
   97.76 +                print("[Central Directory Header]%n");
   97.77 +                while (itr.hasNext()) {
   97.78 +                    Entry cen = Entry.readCEN(zfs.cen, itr.next().pos);
   97.79 +                    print("--------cen[%d]--------%n", i);
   97.80 +                    printCEN(cen);
   97.81 +                    i++;
   97.82 +                }
   97.83 +            }
   97.84 +            zfs.close();
   97.85 +        }
   97.86 +    }
   97.87 +
   97.88 +    static void print(String fmt, Object... objs) {
   97.89 +        System.out.printf(fmt, objs);
   97.90 +    }
   97.91 +
   97.92 +    static void printLOC(Entry loc) {
   97.93 +        print("  [%x, %x]%n", loc.startPos, loc.endPos);
   97.94 +        print("  Signature   :     %8x%n", LOCSIG);
   97.95 +        print("  Version     :         %4x    [%d.%d]%n",
   97.96 +                  loc.version, loc. version/10, loc. version%10);
   97.97 +        print("  Flag        :         %4x%n", loc.flag);
   97.98 +        print("  Method      :         %4x%n", loc. method);
   97.99 +        print("  LastMTime   :     %8x    [%tc]%n",
  97.100 +                  loc.mtime, dosToJavaTime(loc.mtime));
  97.101 +        print("  CRC         :     %8x%n", loc.crc);
  97.102 +        print("  CSize       :     %8x%n", loc.csize);
  97.103 +        print("  Size        :     %8x%n", loc.size);
  97.104 +        print("  NameLength  :         %4x    [%s]%n",
  97.105 +                  loc.nlen, new String(loc.name));
  97.106 +        print("  ExtraLength :         %4x%n", loc.elen);
  97.107 +        if (loc.hasZip64)
  97.108 +            print(" *ZIP64*%n");
  97.109 +    }
  97.110 +
  97.111 +    static void printCEN(Entry cen) {
  97.112 +        print("  Signature   :     %08x%n", CENSIG);
  97.113 +        print("  VerMadeby   :         %4x    [%d.%d]%n",
  97.114 +                  cen.versionMade, cen.versionMade/10, cen.versionMade%10);
  97.115 +        print("  VerExtract  :         %4x    [%d.%d]%n",
  97.116 +                  cen.version, cen.version/10, cen.version%10);
  97.117 +        print("  Flag        :         %4x%n", cen.flag);
  97.118 +        print("  Method      :         %4x%n", cen.method);
  97.119 +        print("  LastMTime   :     %8x    [%tc]%n",
  97.120 +                  cen.mtime, dosToJavaTime(cen.mtime));
  97.121 +        print("  CRC         :     %8x%n", cen.crc);
  97.122 +        print("  CSize       :     %8x%n", cen.csize);
  97.123 +        print("  Size        :     %8x%n", cen.size);
  97.124 +        print("  NameLen     :         %4x    [%s]%n",
  97.125 +                  cen.nlen, new String(cen.name));
  97.126 +        print("  ExtraLen    :         %4x%n", cen.elen);
  97.127 +        print("  CommentLen  :         %4x%n", cen.clen);
  97.128 +        print("  DiskStart   :         %4x%n", cen.disk);
  97.129 +        print("  Attrs       :         %4x%n", cen.attrs);
  97.130 +        print("  AttrsEx     :     %8x%n", cen.attrsEx);
  97.131 +        print("  LocOff      :     %8x%n", cen.locoff);
  97.132 +        if (cen.hasZip64)
  97.133 +            print(" *ZIP64*%n");
  97.134 +    }
  97.135 +}
    98.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    98.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipPath.java	Mon Oct 18 11:25:28 2010 -0400
    98.3 @@ -0,0 +1,964 @@
    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.File;
   98.38 +import java.io.FilterInputStream;
   98.39 +import java.io.IOException;
   98.40 +import java.io.InputStream;
   98.41 +import java.io.OutputStream;
   98.42 +import java.net.URI;
   98.43 +import java.nio.ByteBuffer;
   98.44 +import java.nio.channels.FileChannel;
   98.45 +import java.nio.channels.SeekableByteChannel;
   98.46 +import java.nio.file.*;
   98.47 +import java.nio.file.DirectoryStream.Filter;
   98.48 +import java.nio.file.spi.FileSystemProvider;
   98.49 +import java.nio.file.attribute.BasicFileAttributeView;
   98.50 +import java.nio.file.attribute.FileAttribute;
   98.51 +import java.nio.file.attribute.FileAttributeView;
   98.52 +import java.nio.file.attribute.FileTime;
   98.53 +import java.util.*;
   98.54 +import java.util.regex.Matcher;
   98.55 +import java.util.regex.Pattern;
   98.56 +import static java.nio.file.StandardOpenOption.*;
   98.57 +import static java.nio.file.StandardCopyOption.*;
   98.58 +
   98.59 +/**
   98.60 + *
   98.61 + * @author  Xueming Shen, Rajendra Gutupalli,Jaya Hangal
   98.62 + */
   98.63 +
   98.64 +public class ZipPath extends Path {
   98.65 +
   98.66 +    private final ZipFileSystem zfs;
   98.67 +    private final byte[] path;
   98.68 +    private volatile int[] offsets;
   98.69 +    private int hashcode = 0;  // cached hashcode (created lazily)
   98.70 +
   98.71 +    ZipPath(ZipFileSystem zfs, byte[] path) {
   98.72 +        this(zfs, path, false);
   98.73 +    }
   98.74 +
   98.75 +    ZipPath(ZipFileSystem zfs, byte[] path, boolean normalized)
   98.76 +    {
   98.77 +        this.zfs = zfs;
   98.78 +        if (normalized)
   98.79 +            this.path = path;
   98.80 +        else
   98.81 +            this.path = normalize(path);
   98.82 +    }
   98.83 +
   98.84 +    @Override
   98.85 +    public ZipPath getRoot() {
   98.86 +        if (this.isAbsolute())
   98.87 +            return new ZipPath(zfs, new byte[]{path[0]});
   98.88 +        else
   98.89 +            return null;
   98.90 +    }
   98.91 +
   98.92 +    @Override
   98.93 +    public Path getName() {
   98.94 +        initOffsets();
   98.95 +        int count = offsets.length;
   98.96 +        if (count == 0)
   98.97 +            return null;  // no elements so no name
   98.98 +        if (count == 1 && path[0] != '/')
   98.99 +            return this;
  98.100 +        int lastOffset = offsets[count-1];
  98.101 +        int len = path.length - lastOffset;
  98.102 +        byte[] result = new byte[len];
  98.103 +        System.arraycopy(path, lastOffset, result, 0, len);
  98.104 +        return new ZipPath(zfs, result);
  98.105 +    }
  98.106 +
  98.107 +    @Override
  98.108 +    public ZipPath getParent() {
  98.109 +        initOffsets();
  98.110 +        int count = offsets.length;
  98.111 +        if (count == 0)    // no elements so no parent
  98.112 +            return null;
  98.113 +        int len = offsets[count-1] - 1;
  98.114 +        if (len <= 0)      // parent is root only (may be null)
  98.115 +            return getRoot();
  98.116 +        byte[] result = new byte[len];
  98.117 +        System.arraycopy(path, 0, result, 0, len);
  98.118 +        return new ZipPath(zfs, result);
  98.119 +    }
  98.120 +
  98.121 +    @Override
  98.122 +    public int getNameCount() {
  98.123 +        initOffsets();
  98.124 +        return offsets.length;
  98.125 +    }
  98.126 +
  98.127 +    @Override
  98.128 +    public ZipPath getName(int index) {
  98.129 +        initOffsets();
  98.130 +        if (index < 0 || index >= offsets.length)
  98.131 +            throw new IllegalArgumentException();
  98.132 +        int begin = offsets[index];
  98.133 +        int len;
  98.134 +        if (index == (offsets.length-1))
  98.135 +            len = path.length - begin;
  98.136 +        else
  98.137 +            len = offsets[index+1] - begin - 1;
  98.138 +        // construct result
  98.139 +        byte[] result = new byte[len];
  98.140 +        System.arraycopy(path, begin, result, 0, len);
  98.141 +        return new ZipPath(zfs, result);
  98.142 +    }
  98.143 +
  98.144 +    @Override
  98.145 +    public ZipPath subpath(int beginIndex, int endIndex) {
  98.146 +        initOffsets();
  98.147 +        if (beginIndex < 0 ||
  98.148 +            beginIndex >=  offsets.length ||
  98.149 +            endIndex > offsets.length ||
  98.150 +            beginIndex >= endIndex)
  98.151 +            throw new IllegalArgumentException();
  98.152 +
  98.153 +        // starting offset and length
  98.154 +        int begin = offsets[beginIndex];
  98.155 +        int len;
  98.156 +        if (endIndex == offsets.length)
  98.157 +            len = path.length - begin;
  98.158 +        else
  98.159 +            len = offsets[endIndex] - begin - 1;
  98.160 +        // construct result
  98.161 +        byte[] result = new byte[len];
  98.162 +        System.arraycopy(path, begin, result, 0, len);
  98.163 +        return new ZipPath(zfs, result);
  98.164 +    }
  98.165 +
  98.166 +    @Override
  98.167 +    public ZipPath toRealPath(boolean resolveLinks) throws IOException {
  98.168 +        ZipPath realPath = new ZipPath(zfs, getResolvedPath());
  98.169 +        realPath.checkAccess();
  98.170 +        return realPath;
  98.171 +    }
  98.172 +
  98.173 +    @Override
  98.174 +    public boolean isHidden() {
  98.175 +        return false;
  98.176 +    }
  98.177 +
  98.178 +    @Override
  98.179 +    public ZipPath toAbsolutePath() {
  98.180 +        if (isAbsolute()) {
  98.181 +            return this;
  98.182 +        } else {
  98.183 +            //add / bofore the existing path
  98.184 +            byte[] defaultdir = zfs.getDefaultDir().path;
  98.185 +            int defaultlen = defaultdir.length;
  98.186 +            boolean endsWith = (defaultdir[defaultlen - 1] == '/');
  98.187 +            byte[] t = null;
  98.188 +            if (endsWith)
  98.189 +                t = new byte[defaultlen + path.length];
  98.190 +            else
  98.191 +                t = new byte[defaultlen + 1 + path.length];
  98.192 +            System.arraycopy(defaultdir, 0, t, 0, defaultlen);
  98.193 +            if (!endsWith)
  98.194 +                t[defaultlen++] = '/';
  98.195 +            System.arraycopy(path, 0, t, defaultlen, path.length);
  98.196 +            return new ZipPath(zfs, t, true);  // normalized
  98.197 +        }
  98.198 +    }
  98.199 +
  98.200 +    @Override
  98.201 +    public URI toUri() {
  98.202 +        String zfPath = zfs.toString();
  98.203 +        if (File.separatorChar == '\\')  // replace all separators by '/'
  98.204 +            zfPath = "/" + zfPath.replace("\\", "/");
  98.205 +        try {
  98.206 +            return new URI("zip", "",
  98.207 +                           zfPath,
  98.208 +                           zfs.getString(toAbsolutePath().path));
  98.209 +        } catch (Exception ex) {
  98.210 +            throw new AssertionError(ex);
  98.211 +        }
  98.212 +    }
  98.213 +
  98.214 +    private boolean equalsNameAt(ZipPath other, int index) {
  98.215 +        int mbegin = offsets[index];
  98.216 +        int mlen = 0;
  98.217 +        if (index == (offsets.length-1))
  98.218 +            mlen = path.length - mbegin;
  98.219 +        else
  98.220 +            mlen = offsets[index + 1] - mbegin - 1;
  98.221 +        int obegin = other.offsets[index];
  98.222 +        int olen = 0;
  98.223 +        if (index == (other.offsets.length - 1))
  98.224 +            olen = other.path.length - obegin;
  98.225 +        else
  98.226 +            olen = other.offsets[index + 1] - obegin - 1;
  98.227 +        if (mlen != olen)
  98.228 +            return false;
  98.229 +        int n = 0;
  98.230 +        while(n < mlen) {
  98.231 +            if (path[mbegin + n] != other.path[obegin + n])
  98.232 +                return false;
  98.233 +            n++;
  98.234 +        }
  98.235 +        return true;
  98.236 +    }
  98.237 +
  98.238 +    @Override
  98.239 +    public Path relativize(Path other) {
  98.240 +        final ZipPath o = checkPath(other);
  98.241 +        if (o.equals(this))
  98.242 +            return null;
  98.243 +        if (/* this.getFileSystem() != o.getFileSystem() || */
  98.244 +            this.isAbsolute() != o.isAbsolute()) {
  98.245 +            throw new IllegalArgumentException();
  98.246 +        }
  98.247 +        int mc = this.getNameCount();
  98.248 +        int oc = o.getNameCount();
  98.249 +        int n = Math.min(mc, oc);
  98.250 +        int i = 0;
  98.251 +        while (i < n) {
  98.252 +            if (!equalsNameAt(o, i))
  98.253 +                break;
  98.254 +            i++;
  98.255 +        }
  98.256 +        int dotdots = mc - i;
  98.257 +        int len = dotdots * 3 - 1;
  98.258 +        if (i < oc)
  98.259 +            len += (o.path.length - o.offsets[i] + 1);
  98.260 +        byte[] result = new byte[len];
  98.261 +
  98.262 +        int pos = 0;
  98.263 +        while (dotdots > 0) {
  98.264 +            result[pos++] = (byte)'.';
  98.265 +            result[pos++] = (byte)'.';
  98.266 +            if (pos < len)       // no tailing slash at the end
  98.267 +                result[pos++] = (byte)'/';
  98.268 +            dotdots--;
  98.269 +        }
  98.270 +        if (i < oc)
  98.271 +            System.arraycopy(o.path, o.offsets[i],
  98.272 +                             result, pos,
  98.273 +                             o.path.length - o.offsets[i]);
  98.274 +        return new ZipPath(getFileSystem(), result);
  98.275 +    }
  98.276 +
  98.277 +    @Override
  98.278 +    public ZipFileSystem getFileSystem() {
  98.279 +        return zfs;
  98.280 +    }
  98.281 +
  98.282 +    @Override
  98.283 +    public boolean isAbsolute() {
  98.284 +        return (this.path[0] == '/');
  98.285 +    }
  98.286 +
  98.287 +    @Override
  98.288 +    public ZipPath resolve(Path other) {
  98.289 +        if (other == null)
  98.290 +            return this;
  98.291 +        final ZipPath o = checkPath(other);
  98.292 +        if (o.isAbsolute())
  98.293 +            return o;
  98.294 +        byte[] resolved = null;
  98.295 +        if (this.path[path.length - 1] == '/') {
  98.296 +            resolved = new byte[path.length + o.path.length];
  98.297 +            System.arraycopy(path, 0, resolved, 0, path.length);
  98.298 +            System.arraycopy(o.path, 0, resolved, path.length, o.path.length);
  98.299 +        } else {
  98.300 +            resolved = new byte[path.length + 1 + o.path.length];
  98.301 +            System.arraycopy(path, 0, resolved, 0, path.length);
  98.302 +            resolved[path.length] = '/';
  98.303 +            System.arraycopy(o.path, 0, resolved, path.length + 1, o.path.length);
  98.304 +        }
  98.305 +        return new ZipPath(zfs, resolved);
  98.306 +    }
  98.307 +
  98.308 +    @Override
  98.309 +    public ZipPath resolve(String other) {
  98.310 +        return resolve(getFileSystem().getPath(other));
  98.311 +    }
  98.312 +
  98.313 +    @Override
  98.314 +    public boolean startsWith(Path other) {
  98.315 +        final ZipPath o = checkPath(other);
  98.316 +        if (o.isAbsolute() != this.isAbsolute())
  98.317 +            return false;
  98.318 +        final int oCount = o.getNameCount();
  98.319 +        if (getNameCount() < oCount)
  98.320 +            return false;
  98.321 +        for (int i = 0; i < oCount; i++) {
  98.322 +            if (!o.getName(i).equals(getName(i)))
  98.323 +                return false;
  98.324 +        }
  98.325 +        return true;
  98.326 +    }
  98.327 +
  98.328 +    @Override
  98.329 +    public boolean endsWith(Path other) {
  98.330 +        final ZipPath o = checkPath(other);
  98.331 +        if (o.isAbsolute())
  98.332 +            return this.isAbsolute() ? this.equals(o) : false;
  98.333 +        int i = o.getNameCount();
  98.334 +        int j = this.getNameCount();
  98.335 +        if (j < i)
  98.336 +            return false;
  98.337 +        for (--i, --j; i >= 0; i--, j--) {
  98.338 +            if (!o.getName(i).equals(this.getName(j)))
  98.339 +                return false;
  98.340 +        }
  98.341 +        return true;
  98.342 +    }
  98.343 +
  98.344 +    @Override
  98.345 +    public Path normalize() {
  98.346 +        byte[] resolved = getResolved();
  98.347 +        if (resolved == path)    // no change
  98.348 +            return this;
  98.349 +        if (resolved.length == 0)
  98.350 +            return null;
  98.351 +        return new ZipPath(zfs, resolved, true);
  98.352 +    }
  98.353 +
  98.354 +    private ZipPath checkPath(Path path) {
  98.355 +        if (path == null)
  98.356 +            throw new NullPointerException();
  98.357 +        if (!(path instanceof ZipPath))
  98.358 +            throw new ProviderMismatchException();
  98.359 +        return (ZipPath) path;
  98.360 +    }
  98.361 +
  98.362 +    // create offset list if not already created
  98.363 +    private void initOffsets() {
  98.364 +        if (offsets == null) {
  98.365 +            int count, index;
  98.366 +            // count names
  98.367 +            count = 0;
  98.368 +            index = 0;
  98.369 +            while (index < path.length) {
  98.370 +                byte c = path[index++];
  98.371 +                if (c != '/') {
  98.372 +                    count++;
  98.373 +                    while (index < path.length && path[index] != '/')
  98.374 +                        index++;
  98.375 +                }
  98.376 +            }
  98.377 +            // populate offsets
  98.378 +            int[] result = new int[count];
  98.379 +            count = 0;
  98.380 +            index = 0;
  98.381 +            while (index < path.length) {
  98.382 +                byte c = path[index];
  98.383 +                if (c == '/') {
  98.384 +                    index++;
  98.385 +                } else {
  98.386 +                    result[count++] = index++;
  98.387 +                    while (index < path.length && path[index] != '/')
  98.388 +                        index++;
  98.389 +                }
  98.390 +            }
  98.391 +            synchronized (this) {
  98.392 +                if (offsets == null)
  98.393 +                    offsets = result;
  98.394 +            }
  98.395 +        }
  98.396 +    }
  98.397 +
  98.398 +    // resolved path for locating zip entry inside the zip file,
  98.399 +    // the result path does not contain ./ and .. components
  98.400 +    private volatile byte[] resolved = null;
  98.401 +    byte[] getResolvedPath() {
  98.402 +        byte[] r = resolved;
  98.403 +        if (r == null) {
  98.404 +            if (isAbsolute())
  98.405 +                r = getResolved();
  98.406 +            else
  98.407 +                r = toAbsolutePath().getResolvedPath();
  98.408 +            if (r[0] == '/')
  98.409 +                r = Arrays.copyOfRange(r, 1, r.length);
  98.410 +            resolved = r;
  98.411 +        }
  98.412 +        return resolved;
  98.413 +    }
  98.414 +
  98.415 +    // removes redundant slashs, replace "\" to zip separator "/"
  98.416 +    // and check for invalid characters
  98.417 +    private byte[] normalize(byte[] path) {
  98.418 +        if (path.length == 0)
  98.419 +            return path;
  98.420 +        byte prevC = 0;
  98.421 +        for (int i = 0; i < path.length; i++) {
  98.422 +            byte c = path[i];
  98.423 +            if (c == '\\')
  98.424 +                return normalize(path, i);
  98.425 +            if (c == (byte)'/' && prevC == '/')
  98.426 +                return normalize(path, i - 1);
  98.427 +            if (c == '\u0000')
  98.428 +                throw new InvalidPathException(zfs.getString(path),
  98.429 +                                               "Path: nul character not allowed");
  98.430 +            prevC = c;
  98.431 +        }
  98.432 +        return path;
  98.433 +    }
  98.434 +
  98.435 +    private byte[] normalize(byte[] path, int off) {
  98.436 +        byte[] to = new byte[path.length];
  98.437 +        int n = 0;
  98.438 +        while (n < off) {
  98.439 +            to[n] = path[n];
  98.440 +            n++;
  98.441 +        }
  98.442 +        int m = n;
  98.443 +        byte prevC = 0;
  98.444 +        while (n < path.length) {
  98.445 +            byte c = path[n++];
  98.446 +            if (c == (byte)'\\')
  98.447 +                c = (byte)'/';
  98.448 +            if (c == (byte)'/' && prevC == (byte)'/')
  98.449 +                continue;
  98.450 +            if (c == '\u0000')
  98.451 +                throw new InvalidPathException(zfs.getString(path),
  98.452 +                                               "Path: nul character not allowed");
  98.453 +            to[m++] = c;
  98.454 +            prevC = c;
  98.455 +        }
  98.456 +        if (m > 1 && to[m - 1] == '/')
  98.457 +            m--;
  98.458 +        return (m == to.length)? to : Arrays.copyOf(to, m);
  98.459 +    }
  98.460 +
  98.461 +    // Remove DotSlash(./) and resolve DotDot (..) components
  98.462 +    private byte[] getResolved() {
  98.463 +        if (path.length == 0)
  98.464 +            return path;
  98.465 +        for (int i = 0; i < path.length; i++) {
  98.466 +            byte c = path[i];
  98.467 +            if (c == (byte)'.')
  98.468 +                return resolve0();
  98.469 +        }
  98.470 +        return path;
  98.471 +    }
  98.472 +
  98.473 +    // TBD: performance, avoid initOffsets
  98.474 +    private byte[] resolve0() {
  98.475 +        byte[] to = new byte[path.length];
  98.476 +        int nc = getNameCount();
  98.477 +        int[] lastM = new int[nc];
  98.478 +        int lastMOff = -1;
  98.479 +        int m = 0;
  98.480 +        for (int i = 0; i < nc; i++) {
  98.481 +            int n = offsets[i];
  98.482 +            int len = (i == offsets.length - 1)?
  98.483 +                      (path.length - n):(offsets[i + 1] - n - 1);
  98.484 +            if (len == 1 && path[n] == (byte)'.')
  98.485 +                continue;
  98.486 +            if (len == 2 && path[n] == '.' && path[n + 1] == '.') {
  98.487 +                if (lastMOff >= 0) {
  98.488 +                    m = lastM[lastMOff--];  // retreat
  98.489 +                    continue;
  98.490 +                }
  98.491 +                if (path[0] == '/') {  // "/../xyz" skip
  98.492 +                    if (m == 0)
  98.493 +                        to[m++] = '/';
  98.494 +                } else {               // "../xyz" -> "../xyz"
  98.495 +                    if (m != 0 && to[m-1] != '/')
  98.496 +                        to[m++] = '/';
  98.497 +                    while (len-- > 0)
  98.498 +                        to[m++] = path[n++];
  98.499 +                }
  98.500 +                continue;
  98.501 +            }
  98.502 +            if (m == 0 && path[0] == '/' ||   // absolute path
  98.503 +                m != 0 && to[m-1] != '/') {   // not the first name
  98.504 +                to[m++] = '/';
  98.505 +            }
  98.506 +            lastM[++lastMOff] = m;
  98.507 +            while (len-- > 0)
  98.508 +                to[m++] = path[n++];
  98.509 +        }
  98.510 +        if (m > 1 && to[m - 1] == '/')
  98.511 +            m--;
  98.512 +        return (m == to.length)? to : Arrays.copyOf(to, m);
  98.513 +    }
  98.514 +
  98.515 +    @Override
  98.516 +    public String toString() {
  98.517 +        return zfs.getString(path);
  98.518 +    }
  98.519 +
  98.520 +    @Override
  98.521 +    public int hashCode() {
  98.522 +        int h = hashcode;
  98.523 +        if (h == 0)
  98.524 +            hashcode = h = Arrays.hashCode(path);
  98.525 +        return h;
  98.526 +    }
  98.527 +
  98.528 +    @Override
  98.529 +    public boolean equals(Object obj) {
  98.530 +        return obj != null &&
  98.531 +               obj instanceof ZipPath &&
  98.532 +               this.zfs == ((ZipPath)obj).zfs &&
  98.533 +               compareTo((Path) obj) == 0;
  98.534 +    }
  98.535 +
  98.536 +    @Override
  98.537 +    public int compareTo(Path other) {
  98.538 +        final ZipPath o = checkPath(other);
  98.539 +        int len1 = this.path.length;
  98.540 +        int len2 = o.path.length;
  98.541 +
  98.542 +        int n = Math.min(len1, len2);
  98.543 +        byte v1[] = this.path;
  98.544 +        byte v2[] = o.path;
  98.545 +
  98.546 +        int k = 0;
  98.547 +        while (k < n) {
  98.548 +            int c1 = v1[k] & 0xff;
  98.549 +            int c2 = v2[k] & 0xff;
  98.550 +            if (c1 != c2)
  98.551 +                return c1 - c2;
  98.552 +            k++;
  98.553 +        }
  98.554 +        return len1 - len2;
  98.555 +    }
  98.556 +
  98.557 +    @Override
  98.558 +    public Path createSymbolicLink(
  98.559 +            Path target, FileAttribute<?>... attrs) throws IOException {
  98.560 +        throw new UnsupportedOperationException("Not supported.");
  98.561 +    }
  98.562 +
  98.563 +    @Override
  98.564 +    public Path createLink(
  98.565 +            Path existing) throws IOException {
  98.566 +        throw new UnsupportedOperationException("Not supported.");
  98.567 +    }
  98.568 +
  98.569 +    @Override
  98.570 +    public Path readSymbolicLink() throws IOException {
  98.571 +        throw new UnsupportedOperationException("Not supported.");
  98.572 +    }
  98.573 +
  98.574 +    @Override
  98.575 +    public Path createDirectory(FileAttribute<?>... attrs)
  98.576 +        throws IOException
  98.577 +    {
  98.578 +        zfs.createDirectory(getResolvedPath(), attrs);
  98.579 +        return this;
  98.580 +    }
  98.581 +
  98.582 +    public final Path createFile(FileAttribute<?>... attrs)
  98.583 +        throws IOException
  98.584 +    {
  98.585 +        OutputStream os = newOutputStream(CREATE_NEW, WRITE);
  98.586 +        try {
  98.587 +            os.close();
  98.588 +        } catch (IOException x) {}
  98.589 +        return this;
  98.590 +    }
  98.591 +
  98.592 +    @Override
  98.593 +    public InputStream newInputStream(OpenOption... options)
  98.594 +            throws IOException {
  98.595 +        if (options.length > 0) {
  98.596 +            for (OpenOption opt : options) {
  98.597 +                if (opt != READ)
  98.598 +                    throw new UnsupportedOperationException("'" + opt + "' not allowed");
  98.599 +            }
  98.600 +        }
  98.601 +        return zfs.newInputStream(getResolvedPath());
  98.602 +    }
  98.603 +
  98.604 +    private static final DirectoryStream.Filter<Path> acceptAllFilter =
  98.605 +        new DirectoryStream.Filter<Path>() {
  98.606 +            @Override public boolean accept(Path entry) { return true; }
  98.607 +        };
  98.608 +
  98.609 +    @Override
  98.610 +    public final DirectoryStream<Path> newDirectoryStream() throws IOException {
  98.611 +        return newDirectoryStream(acceptAllFilter);
  98.612 +    }
  98.613 +
  98.614 +    @Override
  98.615 +    public DirectoryStream<Path> newDirectoryStream(Filter<? super Path> filter)
  98.616 +        throws IOException
  98.617 +    {
  98.618 +        return new ZipDirectoryStream(this, filter);
  98.619 +    }
  98.620 +
  98.621 +    @Override
  98.622 +    public final DirectoryStream<Path> newDirectoryStream(String glob)
  98.623 +        throws IOException
  98.624 +    {
  98.625 +        // avoid creating a matcher if all entries are required.
  98.626 +        if (glob.equals("*"))
  98.627 +            return newDirectoryStream();
  98.628 +
  98.629 +        // create a matcher and return a filter that uses it.
  98.630 +        final PathMatcher matcher = getFileSystem().getPathMatcher("glob:" + glob);
  98.631 +        DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
  98.632 +            @Override
  98.633 +            public boolean accept(Path entry)  {
  98.634 +                return matcher.matches(entry.getName());
  98.635 +            }
  98.636 +        };
  98.637 +        return newDirectoryStream(filter);
  98.638 +    }
  98.639 +
  98.640 +    @Override
  98.641 +    public final void delete() throws IOException {
  98.642 +        zfs.deleteFile(getResolvedPath(), true);
  98.643 +    }
  98.644 +
  98.645 +    @Override
  98.646 +    public final void deleteIfExists() throws IOException {
  98.647 +        zfs.deleteFile(getResolvedPath(), false);
  98.648 +    }
  98.649 +
  98.650 +    ZipFileAttributes getAttributes() throws IOException
  98.651 +    {
  98.652 +        ZipFileAttributes zfas = zfs.getFileAttributes(getResolvedPath());
  98.653 +        if (zfas == null)
  98.654 +            throw new NoSuchFileException(toString());
  98.655 +        return zfas;
  98.656 +    }
  98.657 +
  98.658 +    @Override
  98.659 +    @SuppressWarnings("unchecked")
  98.660 +    public <V extends FileAttributeView> V getFileAttributeView(Class<V> type,
  98.661 +                                                                LinkOption... options)
  98.662 +    {
  98.663 +        return (V)ZipFileAttributeView.get(this, type);
  98.664 +    }
  98.665 +
  98.666 +    @Override
  98.667 +    public void setAttribute(String attribute,
  98.668 +                             Object value,
  98.669 +                             LinkOption... options)
  98.670 +        throws IOException
  98.671 +    {
  98.672 +        String type = null;
  98.673 +        String attr = null;
  98.674 +        int colonPos = attribute.indexOf(':');
  98.675 +        if (colonPos == -1) {
  98.676 +            type = "basic";
  98.677 +            attr = attribute;
  98.678 +        } else {
  98.679 +            type = attribute.substring(0, colonPos++);
  98.680 +            attr = attribute.substring(colonPos);
  98.681 +        }
  98.682 +        ZipFileAttributeView view = ZipFileAttributeView.get(this, type);
  98.683 +        if (view == null)
  98.684 +            throw new UnsupportedOperationException("view <" + view + "> is not supported");
  98.685 +        view.setAttribute(attr, value);
  98.686 +    }
  98.687 +
  98.688 +    void setTimes(FileTime mtime, FileTime atime, FileTime ctime)
  98.689 +        throws IOException
  98.690 +    {
  98.691 +        zfs.setTimes(getResolvedPath(), mtime, atime, ctime);
  98.692 +    }
  98.693 +
  98.694 +    private Object getAttributesImpl(String attribute, boolean domap)
  98.695 +        throws IOException
  98.696 +    {
  98.697 +        String view = null;
  98.698 +        String attr = null;
  98.699 +        int colonPos = attribute.indexOf(':');
  98.700 +        if (colonPos == -1) {
  98.701 +            view = "basic";
  98.702 +            attr = attribute;
  98.703 +        } else {
  98.704 +            view = attribute.substring(0, colonPos++);
  98.705 +            attr = attribute.substring(colonPos);
  98.706 +        }
  98.707 +        ZipFileAttributeView zfv = ZipFileAttributeView.get(this, view);
  98.708 +        if (zfv == null) {
  98.709 +            throw new UnsupportedOperationException("view not supported");
  98.710 +        }
  98.711 +        return zfv.getAttribute(attr, domap);
  98.712 +    }
  98.713 +
  98.714 +    @Override
  98.715 +    public Object getAttribute(String attribute, LinkOption... options)
  98.716 +        throws IOException
  98.717 +    {
  98.718 +        return getAttributesImpl(attribute, false);
  98.719 +    }
  98.720 +
  98.721 +    @Override
  98.722 +    public Map<String,?> readAttributes(String attribute, LinkOption... options)
  98.723 +        throws IOException
  98.724 +    {
  98.725 +        return (Map<String, ?>)getAttributesImpl(attribute, true);
  98.726 +    }
  98.727 +
  98.728 +    @Override
  98.729 +    public FileStore getFileStore() throws IOException {
  98.730 +        // each ZipFileSystem only has one root (as requested for now)
  98.731 +        if (exists())
  98.732 +            return zfs.getFileStore(this);
  98.733 +        throw new NoSuchFileException(zfs.getString(path));
  98.734 +    }
  98.735 +
  98.736 +    @Override
  98.737 +    public boolean isSameFile(Path other) throws IOException {
  98.738 +        if (other == null ||
  98.739 +            this.getFileSystem() != other.getFileSystem())
  98.740 +            return false;
  98.741 +        this.checkAccess();
  98.742 +        other.checkAccess();
  98.743 +        return Arrays.equals(this.getResolvedPath(),
  98.744 +                             ((ZipPath)other).getResolvedPath());
  98.745 +    }
  98.746 +
  98.747 +    public WatchKey register(
  98.748 +            WatchService watcher,
  98.749 +            WatchEvent.Kind<?>[] events,
  98.750 +            WatchEvent.Modifier... modifiers) {
  98.751 +        if (watcher == null || events == null || modifiers == null) {
  98.752 +            throw new NullPointerException();
  98.753 +        }
  98.754 +        throw new UnsupportedOperationException();
  98.755 +    }
  98.756 +
  98.757 +    @Override
  98.758 +    public WatchKey register(WatchService watcher, WatchEvent.Kind<?>... events) {
  98.759 +        return register(watcher, events, new WatchEvent.Modifier[0]);
  98.760 +    }
  98.761 +
  98.762 +    @Override
  98.763 +    public Iterator<Path> iterator() {
  98.764 +        return new Iterator<Path>() {
  98.765 +            private int i = 0;
  98.766 +
  98.767 +            @Override
  98.768 +            public boolean hasNext() {
  98.769 +                return (i < getNameCount());
  98.770 +            }
  98.771 +
  98.772 +            @Override
  98.773 +            public Path next() {
  98.774 +                if (i < getNameCount()) {
  98.775 +                    Path result = getName(i);
  98.776 +                    i++;
  98.777 +                    return result;
  98.778 +                } else {
  98.779 +                    throw new NoSuchElementException();
  98.780 +                }
  98.781 +            }
  98.782 +
  98.783 +            @Override
  98.784 +            public void remove() {
  98.785 +                throw new ReadOnlyFileSystemException();
  98.786 +            }
  98.787 +        };
  98.788 +    }
  98.789 +
  98.790 +    @Override
  98.791 +    public SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
  98.792 +                                              FileAttribute<?>... attrs)
  98.793 +        throws IOException
  98.794 +    {
  98.795 +        return zfs.newByteChannel(getResolvedPath(), options, attrs);
  98.796 +    }
  98.797 +
  98.798 +
  98.799 +    FileChannel newFileChannel(Set<? extends OpenOption> options,
  98.800 +                               FileAttribute<?>... attrs)
  98.801 +        throws IOException
  98.802 +    {
  98.803 +        return zfs.newFileChannel(getResolvedPath(), options, attrs);
  98.804 +    }
  98.805 +
  98.806 +    @Override
  98.807 +    public SeekableByteChannel newByteChannel(OpenOption... options)
  98.808 +            throws IOException {
  98.809 +        Set<OpenOption> set = new HashSet<OpenOption>(options.length);
  98.810 +        Collections.addAll(set, options);
  98.811 +        return newByteChannel(set);
  98.812 +    }
  98.813 +
  98.814 +    @Override
  98.815 +    public void checkAccess(AccessMode... modes) throws IOException {
  98.816 +        boolean w = false;
  98.817 +        boolean x = false;
  98.818 +        for (AccessMode mode : modes) {
  98.819 +            switch (mode) {
  98.820 +                case READ:
  98.821 +                    break;
  98.822 +                case WRITE:
  98.823 +                    w = true;
  98.824 +                    break;
  98.825 +                case EXECUTE:
  98.826 +                    x = true;
  98.827 +                    break;
  98.828 +                default:
  98.829 +                    throw new UnsupportedOperationException();
  98.830 +            }
  98.831 +        }
  98.832 +        ZipFileAttributes attrs = zfs.getFileAttributes(getResolvedPath());
  98.833 +        if (attrs == null && (path.length != 1 || path[0] != '/'))
  98.834 +            throw new NoSuchFileException(toString());
  98.835 +        if (w) {
  98.836 +            if (zfs.isReadOnly())
  98.837 +                throw new AccessDeniedException(toString());
  98.838 +        }
  98.839 +        if (x)
  98.840 +            throw new AccessDeniedException(toString());
  98.841 +
  98.842 +    }
  98.843 +
  98.844 +    @Override
  98.845 +    public boolean exists() {
  98.846 +        if (path.length == 1 && path[0] == '/')
  98.847 +            return true;
  98.848 +        try {
  98.849 +            return zfs.exists(getResolvedPath());
  98.850 +        } catch (IOException x) {}
  98.851 +        return false;
  98.852 +    }
  98.853 +
  98.854 +    @Override
  98.855 +    public boolean notExists() {
  98.856 +        return !exists();
  98.857 +    }
  98.858 +
  98.859 +
  98.860 +    @Override
  98.861 +    public OutputStream newOutputStream(OpenOption... options)
  98.862 +        throws IOException
  98.863 +    {
  98.864 +        if (options.length == 0)
  98.865 +            return zfs.newOutputStream(getResolvedPath(),
  98.866 +                                       CREATE_NEW, WRITE);
  98.867 +        return zfs.newOutputStream(getResolvedPath(), options);
  98.868 +    }
  98.869 +
  98.870 +    @Override
  98.871 +    public Path moveTo(Path target, CopyOption... options)
  98.872 +        throws IOException
  98.873 +    {
  98.874 +        if (this.zfs.provider() == target.getFileSystem().provider() &&
  98.875 +            this.zfs.getZipFile().isSameFile(((ZipPath)target).zfs.getZipFile()))
  98.876 +        {
  98.877 +            zfs.copyFile(true,
  98.878 +                         getResolvedPath(),
  98.879 +                         ((ZipPath)target).getResolvedPath(),
  98.880 +                         options);
  98.881 +        } else {
  98.882 +            copyToTarget(target, options);
  98.883 +            delete();
  98.884 +        }
  98.885 +        return target;
  98.886 +    }
  98.887 +
  98.888 +    @Override
  98.889 +    public Path copyTo(Path target, CopyOption... options)
  98.890 +        throws IOException
  98.891 +    {
  98.892 +        if (this.zfs.provider() == target.getFileSystem().provider() &&
  98.893 +            this.zfs.getZipFile().isSameFile(((ZipPath)target).zfs.getZipFile()))
  98.894 +        {
  98.895 +            zfs.copyFile(false,
  98.896 +                         getResolvedPath(),
  98.897 +                         ((ZipPath)target).getResolvedPath(),
  98.898 +                         options);
  98.899 +        } else {
  98.900 +            copyToTarget(target, options);
  98.901 +        }
  98.902 +        return target;
  98.903 +    }
  98.904 +
  98.905 +    private void copyToTarget(Path target, CopyOption... options)
  98.906 +        throws IOException
  98.907 +    {
  98.908 +        boolean replaceExisting = false;
  98.909 +        boolean copyAttrs = false;
  98.910 +        for (CopyOption opt : options) {
  98.911 +            if (opt == REPLACE_EXISTING)
  98.912 +                replaceExisting = true;
  98.913 +            else if (opt == COPY_ATTRIBUTES)
  98.914 +                copyAttrs = false;
  98.915 +        }
  98.916 +        // attributes of source file
  98.917 +        ZipFileAttributes zfas = getAttributes();
  98.918 +        // check if target exists
  98.919 +        boolean exists;
  98.920 +        if (replaceExisting) {
  98.921 +            try {
  98.922 +                target.deleteIfExists();
  98.923 +                exists = false;
  98.924 +            } catch (DirectoryNotEmptyException x) {
  98.925 +                exists = true;
  98.926 +            }
  98.927 +        } else {
  98.928 +            exists = target.exists();
  98.929 +        }
  98.930 +        if (exists)
  98.931 +            throw new FileAlreadyExistsException(target.toString());
  98.932 +
  98.933 +        if (zfas.isDirectory()) {
  98.934 +            // create directory or file
  98.935 +            target.createDirectory();
  98.936 +        } else {
  98.937 +            InputStream is = zfs.newInputStream(getResolvedPath());
  98.938 +            try {
  98.939 +                OutputStream os = target.newOutputStream();
  98.940 +                try {
  98.941 +                    byte[] buf = new byte[8192];
  98.942 +                    int n = 0;
  98.943 +                    while ((n = is.read(buf)) != -1) {
  98.944 +                        os.write(buf, 0, n);
  98.945 +                    }
  98.946 +                } finally {
  98.947 +                    os.close();
  98.948 +                }
  98.949 +            } finally {
  98.950 +                is.close();
  98.951 +            }
  98.952 +        }
  98.953 +        if (copyAttrs) {
  98.954 +            BasicFileAttributeView view =
  98.955 +                target.getFileAttributeView(BasicFileAttributeView.class);
  98.956 +            try {
  98.957 +                view.setTimes(zfas.lastModifiedTime(), null, null);
  98.958 +            } catch (IOException x) {
  98.959 +                // rollback?
  98.960 +                try {
  98.961 +                    target.delete();
  98.962 +                } catch (IOException ignore) { }
  98.963 +                throw x;
  98.964 +            }
  98.965 +        }
  98.966 +    }
  98.967 +}
    99.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    99.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipUtils.java	Mon Oct 18 11:25:28 2010 -0400
    99.3 @@ -0,0 +1,289 @@
    99.4 +/*
    99.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
    99.6 + *
    99.7 + * Redistribution and use in source and binary forms, with or without
    99.8 + * modification, are permitted provided that the following conditions
    99.9 + * are met:
   99.10 + *
   99.11 + *   - Redistributions of source code must retain the above copyright
   99.12 + *     notice, this list of conditions and the following disclaimer.
   99.13 + *
   99.14 + *   - Redistributions in binary form must reproduce the above copyright
   99.15 + *     notice, this list of conditions and the following disclaimer in the
   99.16 + *     documentation and/or other materials provided with the distribution.
   99.17 + *
   99.18 + *   - Neither the name of Oracle nor the names of its
   99.19 + *     contributors may be used to endorse or promote products derived
   99.20 + *     from this software without specific prior written permission.
   99.21 + *
   99.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
   99.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   99.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   99.25 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   99.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   99.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   99.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   99.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   99.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   99.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   99.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   99.33 + */
   99.34 +
   99.35 +package com.sun.nio.zipfs;
   99.36 +
   99.37 +import java.io.IOException;
   99.38 +import java.io.OutputStream;
   99.39 +import java.util.Arrays;
   99.40 +import java.util.Date;
   99.41 +import java.util.regex.PatternSyntaxException;
   99.42 +
   99.43 +/**
   99.44 + *
   99.45 + * @author Xueming Shen
   99.46 + */
   99.47 +
   99.48 +class ZipUtils {
   99.49 +
   99.50 +    /*
   99.51 +     * Writes a 16-bit short to the output stream in little-endian byte order.
   99.52 +     */
   99.53 +    public static void writeShort(OutputStream os, int v) throws IOException {
   99.54 +        os.write((v >>> 0) & 0xff);
   99.55 +        os.write((v >>> 8) & 0xff);
   99.56 +    }
   99.57 +
   99.58 +    /*
   99.59 +     * Writes a 32-bit int to the output stream in little-endian byte order.
   99.60 +     */
   99.61 +    public static void writeInt(OutputStream os, long v) throws IOException {
   99.62 +        os.write((int)((v >>>  0) & 0xff));
   99.63 +        os.write((int)((v >>>  8) & 0xff));
   99.64 +        os.write((int)((v >>> 16) & 0xff));
   99.65 +        os.write((int)((v >>> 24) & 0xff));
   99.66 +    }
   99.67 +
   99.68 +    /*
   99.69 +     * Writes a 64-bit int to the output stream in little-endian byte order.
   99.70 +     */
   99.71 +    public static void writeLong(OutputStream os, long v) throws IOException {
   99.72 +        os.write((int)((v >>>  0) & 0xff));
   99.73 +        os.write((int)((v >>>  8) & 0xff));
   99.74 +        os.write((int)((v >>> 16) & 0xff));
   99.75 +        os.write((int)((v >>> 24) & 0xff));
   99.76 +        os.write((int)((v >>> 32) & 0xff));
   99.77 +        os.write((int)((v >>> 40) & 0xff));
   99.78 +        os.write((int)((v >>> 48) & 0xff));
   99.79 +        os.write((int)((v >>> 56) & 0xff));
   99.80 +    }
   99.81 +
   99.82 +    /*
   99.83 +     * Writes an array of bytes to the output stream.
   99.84 +     */
   99.85 +    public static void writeBytes(OutputStream os, byte[] b)
   99.86 +        throws IOException
   99.87 +    {
   99.88 +        os.write(b, 0, b.length);
   99.89 +    }
   99.90 +
   99.91 +    /*
   99.92 +     * Writes an array of bytes to the output stream.
   99.93 +     */
   99.94 +    public static void writeBytes(OutputStream os, byte[] b, int off, int len)
   99.95 +        throws IOException
   99.96 +    {
   99.97 +        os.write(b, off, len);
   99.98 +    }
   99.99 +
  99.100 +    /*
  99.101 +     * Append a slash at the end, if it does not have one yet
  99.102 +     */
  99.103 +    public static byte[] toDirectoryPath(byte[] dir) {
  99.104 +        if (dir.length != 0 && dir[dir.length - 1] != '/') {
  99.105 +            dir = Arrays.copyOf(dir, dir.length + 1);
  99.106 +            dir[dir.length - 1] = '/';
  99.107 +        }
  99.108 +        return dir;
  99.109 +    }
  99.110 +
  99.111 +    /*
  99.112 +     * Converts DOS time to Java time (number of milliseconds since epoch).
  99.113 +     */
  99.114 +    public static long dosToJavaTime(long dtime) {
  99.115 +        Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80),
  99.116 +                          (int)(((dtime >> 21) & 0x0f) - 1),
  99.117 +                          (int)((dtime >> 16) & 0x1f),
  99.118 +                          (int)((dtime >> 11) & 0x1f),
  99.119 +                          (int)((dtime >> 5) & 0x3f),
  99.120 +                          (int)((dtime << 1) & 0x3e));
  99.121 +        return d.getTime();
  99.122 +    }
  99.123 +
  99.124 +    /*
  99.125 +     * Converts Java time to DOS time.
  99.126 +     */
  99.127 +    public static long javaToDosTime(long time) {
  99.128 +        Date d = new Date(time);
  99.129 +        int year = d.getYear() + 1900;
  99.130 +        if (year < 1980) {
  99.131 +            return (1 << 21) | (1 << 16);
  99.132 +        }
  99.133 +        return (year - 1980) << 25 | (d.getMonth() + 1) << 21 |
  99.134 +               d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 |
  99.135 +               d.getSeconds() >> 1;
  99.136 +    }
  99.137 +
  99.138 +    private static final String regexMetaChars = ".^$+{[]|()";
  99.139 +    private static final String globMetaChars = "\\*?[{";
  99.140 +    private static boolean isRegexMeta(char c) {
  99.141 +        return regexMetaChars.indexOf(c) != -1;
  99.142 +    }
  99.143 +    private static boolean isGlobMeta(char c) {
  99.144 +        return globMetaChars.indexOf(c) != -1;
  99.145 +    }
  99.146 +    private static char EOL = 0;  //TBD
  99.147 +    private static char next(String glob, int i) {
  99.148 +        if (i < glob.length()) {
  99.149 +            return glob.charAt(i);
  99.150 +        }
  99.151 +        return EOL;
  99.152 +    }
  99.153 +
  99.154 +    /*
  99.155 +     * Creates a regex pattern from the given glob expression.
  99.156 +     *
  99.157 +     * @throws  PatternSyntaxException
  99.158 +     */
  99.159 +    public static String toRegexPattern(String globPattern) {
  99.160 +        boolean inGroup = false;
  99.161 +        StringBuilder regex = new StringBuilder("^");
  99.162 +
  99.163 +        int i = 0;
  99.164 +        while (i < globPattern.length()) {
  99.165 +            char c = globPattern.charAt(i++);
  99.166 +            switch (c) {
  99.167 +                case '\\':
  99.168 +                    // escape special characters
  99.169 +                    if (i == globPattern.length()) {
  99.170 +                        throw new PatternSyntaxException("No character to escape",
  99.171 +                                globPattern, i - 1);
  99.172 +                    }
  99.173 +                    char next = globPattern.charAt(i++);
  99.174 +                    if (isGlobMeta(next) || isRegexMeta(next)) {
  99.175 +                        regex.append('\\');
  99.176 +                    }
  99.177 +                    regex.append(next);
  99.178 +                    break;
  99.179 +                case '/':
  99.180 +                    regex.append(c);
  99.181 +                    break;
  99.182 +                case '[':
  99.183 +                    // don't match name separator in class
  99.184 +                    regex.append("[[^/]&&[");
  99.185 +                    if (next(globPattern, i) == '^') {
  99.186 +                        // escape the regex negation char if it appears
  99.187 +                        regex.append("\\^");
  99.188 +                        i++;
  99.189 +                    } else {
  99.190 +                        // negation
  99.191 +                        if (next(globPattern, i) == '!') {
  99.192 +                            regex.append('^');
  99.193 +                            i++;
  99.194 +                        }
  99.195 +                        // hyphen allowed at start
  99.196 +                        if (next(globPattern, i) == '-') {
  99.197 +                            regex.append('-');
  99.198 +                            i++;
  99.199 +                        }
  99.200 +                    }
  99.201 +                    boolean hasRangeStart = false;
  99.202 +                    char last = 0;
  99.203 +                    while (i < globPattern.length()) {
  99.204 +                        c = globPattern.charAt(i++);
  99.205 +                        if (c == ']') {
  99.206 +                            break;
  99.207 +                        }
  99.208 +                        if (c == '/') {
  99.209 +                            throw new PatternSyntaxException("Explicit 'name separator' in class",
  99.210 +                                    globPattern, i - 1);
  99.211 +                        }
  99.212 +                        // TBD: how to specify ']' in a class?
  99.213 +                        if (c == '\\' || c == '[' ||
  99.214 +                                c == '&' && next(globPattern, i) == '&') {
  99.215 +                            // escape '\', '[' or "&&" for regex class
  99.216 +                            regex.append('\\');
  99.217 +                        }
  99.218 +                        regex.append(c);
  99.219 +
  99.220 +                        if (c == '-') {
  99.221 +                            if (!hasRangeStart) {
  99.222 +                                throw new PatternSyntaxException("Invalid range",
  99.223 +                                        globPattern, i - 1);
  99.224 +                            }
  99.225 +                            if ((c = next(globPattern, i++)) == EOL || c == ']') {
  99.226 +                                break;
  99.227 +                            }
  99.228 +                            if (c < last) {
  99.229 +                                throw new PatternSyntaxException("Invalid range",
  99.230 +                                        globPattern, i - 3);
  99.231 +                            }
  99.232 +                            regex.append(c);
  99.233 +                            hasRangeStart = false;
  99.234 +                        } else {
  99.235 +                            hasRangeStart = true;
  99.236 +                            last = c;
  99.237 +                        }
  99.238 +                    }
  99.239 +                    if (c != ']') {
  99.240 +                        throw new PatternSyntaxException("Missing ']", globPattern, i - 1);
  99.241 +                    }
  99.242 +                    regex.append("]]");
  99.243 +                    break;
  99.244 +                case '{':
  99.245 +                    if (inGroup) {
  99.246 +                        throw new PatternSyntaxException("Cannot nest groups",
  99.247 +                                globPattern, i - 1);
  99.248 +                    }
  99.249 +                    regex.append("(?:(?:");
  99.250 +                    inGroup = true;
  99.251 +                    break;
  99.252 +                case '}':
  99.253 +                    if (inGroup) {
  99.254 +                        regex.append("))");
  99.255 +                        inGroup = false;
  99.256 +                    } else {
  99.257 +                        regex.append('}');
  99.258 +                    }
  99.259 +                    break;
  99.260 +                case ',':
  99.261 +                    if (inGroup) {
  99.262 +                        regex.append(")|(?:");
  99.263 +                    } else {
  99.264 +                        regex.append(',');
  99.265 +                    }
  99.266 +                    break;
  99.267 +                case '*':
  99.268 +                    if (next(globPattern, i) == '*') {
  99.269 +                        // crosses directory boundaries
  99.270 +                        regex.append(".*");
  99.271 +                        i++;
  99.272 +                    } else {
  99.273 +                        // within directory boundary
  99.274 +                        regex.append("[^/]*");
  99.275 +                    }
  99.276 +                    break;
  99.277 +                case '?':
  99.278 +                   regex.append("[^/]");
  99.279 +                   break;
  99.280 +                default:
  99.281 +                    if (isRegexMeta(c)) {
  99.282 +                        regex.append('\\');
  99.283 +                    }
  99.284 +                    regex.append(c);
  99.285 +            }
  99.286 +        }
  99.287 +        if (inGroup) {
  99.288 +            throw new PatternSyntaxException("Missing '}", globPattern, i - 1);
  99.289 +        }
  99.290 +        return regex.append('$').toString();
  99.291 +    }
  99.292 +}
   100.1 --- a/src/share/native/java/lang/System.c	Tue Oct 12 13:34:59 2010 -0400
   100.2 +++ b/src/share/native/java/lang/System.c	Mon Oct 18 11:25:28 2010 -0400
   100.3 @@ -97,14 +97,20 @@
   100.4      } else ((void) 0)
   100.5  
   100.6  #ifndef VENDOR /* Third party may overwrite this. */
   100.7 -#define VENDOR "Sun Microsystems Inc."
   100.8 -#define VENDOR_URL "http://java.sun.com/"
   100.9 +#define VENDOR "Oracle Corporation"
  100.10 +#define VENDOR_URL "http://java.oracle.com/"
  100.11  #define VENDOR_URL_BUG "http://java.sun.com/cgi-bin/bugreport.cgi"
  100.12  #endif
  100.13  
  100.14  #define JAVA_MAX_SUPPORTED_VERSION 51
  100.15  #define JAVA_MAX_SUPPORTED_MINOR_VERSION 0
  100.16  
  100.17 +#ifdef JAVA_SPECIFICATION_VENDOR /* Third party may NOT overwrite this. */
  100.18 +  #error "ERROR: No override of JAVA_SPECIFICATION_VENDOR is allowed"
  100.19 +#else
  100.20 +  #define JAVA_SPECIFICATION_VENDOR "Oracle Corporation"
  100.21 +#endif
  100.22 +
  100.23  static int fmtdefault; // boolean value
  100.24  jobject fillI18nProps(JNIEnv *env, jobject props, char *baseKey,
  100.25                        char *platformDispVal, char *platformFmtVal,
  100.26 @@ -185,7 +191,8 @@
  100.27              JDK_MAJOR_VERSION "." JDK_MINOR_VERSION);
  100.28      PUTPROP(props, "java.specification.name",
  100.29              "Java Platform API Specification");
  100.30 -    PUTPROP(props, "java.specification.vendor", "Sun Microsystems Inc.");
  100.31 +    PUTPROP(props, "java.specification.vendor",
  100.32 +            JAVA_SPECIFICATION_VENDOR);
  100.33  
  100.34      PUTPROP(props, "java.version", RELEASE);
  100.35      PUTPROP(props, "java.vendor", VENDOR);
  100.36 @@ -239,7 +246,7 @@
  100.37      /* Printing properties */
  100.38      /* Note: java.awt.printerjob is an implementation private property which
  100.39       * just happens to have a java.* name because it is referenced in
  100.40 -     * a java.awt class. It is the mechanism by which the Sun implementation
  100.41 +     * a java.awt class. It is the mechanism by which the implementation
  100.42       * finds the appropriate class in the JRE for the platform.
  100.43       * It is explicitly not designed to be overridden by clients as
  100.44       * a way of replacing the implementation class, and in any case
  100.45 @@ -267,7 +274,7 @@
  100.46      /* Java2D properties */
  100.47      /* Note: java.awt.graphicsenv is an implementation private property which
  100.48       * just happens to have a java.* name because it is referenced in
  100.49 -     * a java.awt class. It is the mechanism by which the Sun implementation
  100.50 +     * a java.awt class. It is the mechanism by which the implementation
  100.51       * finds the appropriate class in the JRE for the platform.
  100.52       * It is explicitly not designed to be overridden by clients as
  100.53       * a way of replacing the implementation class, and in any case
   101.1 --- a/src/share/sample/nio/file/Chmod.java	Tue Oct 12 13:34:59 2010 -0400
   101.2 +++ b/src/share/sample/nio/file/Chmod.java	Mon Oct 18 11:25:28 2010 -0400
   101.3 @@ -285,18 +285,12 @@
   101.4          }
   101.5  
   101.6          @Override
   101.7 -        public FileVisitResult preVisitDirectory(FileRef dir) {
   101.8 +        public FileVisitResult preVisitDirectory(FileRef dir, BasicFileAttributes attrs) {
   101.9              chmod(dir, changer);
  101.10              return CONTINUE;
  101.11          }
  101.12  
  101.13          @Override
  101.14 -        public FileVisitResult preVisitDirectoryFailed(FileRef dir, IOException exc) {
  101.15 -            System.err.println("WARNING: " + exc);
  101.16 -            return CONTINUE;
  101.17 -        }
  101.18 -
  101.19 -        @Override
  101.20          public FileVisitResult visitFile(FileRef file, BasicFileAttributes attrs) {
  101.21              chmod(file, changer);
  101.22              return CONTINUE;
   102.1 --- a/src/share/sample/nio/file/Copy.java	Tue Oct 12 13:34:59 2010 -0400
   102.2 +++ b/src/share/sample/nio/file/Copy.java	Mon Oct 18 11:25:28 2010 -0400
   102.3 @@ -85,7 +85,7 @@
   102.4          }
   102.5  
   102.6          @Override
   102.7 -        public FileVisitResult preVisitDirectory(Path dir) {
   102.8 +        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
   102.9              // before visiting entries in a directory we copy the directory
  102.10              // (okay if directory already exists).
  102.11              CopyOption[] options = (preserve) ?
  102.12 @@ -104,19 +104,9 @@
  102.13          }
  102.14  
  102.15          @Override
  102.16 -        public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
  102.17 -            System.err.format("Unable to copy: %s: %s%n", dir, exc);
  102.18 -            return CONTINUE;
  102.19 -        }
  102.20 -
  102.21 -        @Override
  102.22          public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
  102.23 -            if (attrs.isDirectory()) {
  102.24 -                System.err.println("cycle detected: " + file);
  102.25 -            } else {
  102.26 -                copyFile(file, target.resolve(source.relativize(file)),
  102.27 -                         prompt, preserve);
  102.28 -            }
  102.29 +            copyFile(file, target.resolve(source.relativize(file)),
  102.30 +                     prompt, preserve);
  102.31              return CONTINUE;
  102.32          }
  102.33  
  102.34 @@ -137,7 +127,11 @@
  102.35  
  102.36          @Override
  102.37          public FileVisitResult visitFileFailed(Path file, IOException exc) {
  102.38 -            System.err.format("Unable to copy: %s: %s%n", file, exc);
  102.39 +            if (exc instanceof FileSystemLoopException) {
  102.40 +                System.err.println("cycle detected: " + file);
  102.41 +            } else {
  102.42 +                System.err.format("Unable to copy: %s: %s%n", file, exc);
  102.43 +            }
  102.44              return CONTINUE;
  102.45          }
  102.46      }
   103.1 --- a/src/share/sample/nio/file/WatchDir.java	Tue Oct 12 13:34:59 2010 -0400
   103.2 +++ b/src/share/sample/nio/file/WatchDir.java	Mon Oct 18 11:25:28 2010 -0400
   103.3 @@ -78,12 +78,10 @@
   103.4          // register directory and sub-directories
   103.5          Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
   103.6              @Override
   103.7 -            public FileVisitResult preVisitDirectory(Path dir) {
   103.8 -                try {
   103.9 -                    register(dir);
  103.10 -                } catch (IOException x) {
  103.11 -                    throw new IOError(x);
  103.12 -                }
  103.13 +            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
  103.14 +                throws IOException
  103.15 +            {
  103.16 +                register(dir);
  103.17                  return FileVisitResult.CONTINUE;
  103.18              }
  103.19          });
   104.1 --- a/src/solaris/classes/java/lang/UNIXProcess.java.linux	Tue Oct 12 13:34:59 2010 -0400
   104.2 +++ b/src/solaris/classes/java/lang/UNIXProcess.java.linux	Mon Oct 18 11:25:28 2010 -0400
   104.3 @@ -176,7 +176,13 @@
   104.4              }});
   104.5      }
   104.6  
   104.7 -    synchronized void processExited(int exitcode) {
   104.8 +    void processExited(int exitcode) {
   104.9 +        synchronized (this) {
  104.10 +            this.exitcode = exitcode;
  104.11 +            hasExited = true;
  104.12 +            notifyAll();
  104.13 +        }
  104.14 +
  104.15          if (stdout instanceof ProcessPipeInputStream)
  104.16              ((ProcessPipeInputStream) stdout).processExited();
  104.17  
  104.18 @@ -185,10 +191,6 @@
  104.19  
  104.20          if (stdin instanceof ProcessPipeOutputStream)
  104.21              ((ProcessPipeOutputStream) stdin).processExited();
  104.22 -
  104.23 -        this.exitcode = exitcode;
  104.24 -        hasExited = true;
  104.25 -        notifyAll();
  104.26      }
  104.27  
  104.28      public OutputStream getOutputStream() {
   105.1 --- a/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java	Tue Oct 12 13:34:59 2010 -0400
   105.2 +++ b/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java	Mon Oct 18 11:25:28 2010 -0400
   105.3 @@ -64,7 +64,10 @@
   105.4              accessor.setFile(fd, null);
   105.5              accessor.setFiles(fd, null, null);
   105.6          } else {
   105.7 -            accessor.setDirectory(fd, directory);
   105.8 +            // Fix 6987233: add the trailing slash if it's absent
   105.9 +            accessor.setDirectory(fd, directory +
  105.10 +                    (directory.endsWith(File.separator) ?
  105.11 +                     "" : File.separator));
  105.12              accessor.setFile(fd, filenames[0]);
  105.13              accessor.setFiles(fd, directory, filenames);
  105.14          }
   106.1 --- a/src/solaris/classes/sun/awt/X11/XBaseWindow.java	Tue Oct 12 13:34:59 2010 -0400
   106.2 +++ b/src/solaris/classes/sun/awt/X11/XBaseWindow.java	Mon Oct 18 11:25:28 2010 -0400
   106.3 @@ -705,12 +705,8 @@
   106.4              throw new IllegalStateException("Attempt to resize uncreated window");
   106.5          }
   106.6          insLog.fine("Setting bounds on " + this + " to (" + x + ", " + y + "), " + width + "x" + height);
   106.7 -        if (width <= 0) {
   106.8 -            width = 1;
   106.9 -        }
  106.10 -        if (height <= 0) {
  106.11 -            height = 1;
  106.12 -        }
  106.13 +        width = Math.max(MIN_SIZE, width);
  106.14 +        height = Math.max(MIN_SIZE, height);
  106.15          XToolkit.awtLock();
  106.16          try {
  106.17               XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), getWindow(), x,y,width,height);
   107.1 --- a/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java	Tue Oct 12 13:34:59 2010 -0400
   107.2 +++ b/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java	Mon Oct 18 11:25:28 2010 -0400
   107.3 @@ -763,12 +763,8 @@
   107.4      }
   107.5  
   107.6      private void checkShellRectSize(Rectangle shellRect) {
   107.7 -        if (shellRect.width < 0) {
   107.8 -            shellRect.width = 1;
   107.9 -        }
  107.10 -        if (shellRect.height < 0) {
  107.11 -            shellRect.height = 1;
  107.12 -        }
  107.13 +        shellRect.width = Math.max(MIN_SIZE, shellRect.width);
  107.14 +        shellRect.height = Math.max(MIN_SIZE, shellRect.height);
  107.15      }
  107.16  
  107.17      private void checkShellRectPos(Rectangle shellRect) {
   108.1 --- a/src/solaris/classes/sun/awt/X11/XEmbeddedFrame.java	Tue Oct 12 13:34:59 2010 -0400
   108.2 +++ b/src/solaris/classes/sun/awt/X11/XEmbeddedFrame.java	Mon Oct 18 11:25:28 2010 -0400
   108.3 @@ -28,9 +28,12 @@
   108.4  import sun.awt.EmbeddedFrame;
   108.5  import java.awt.*;
   108.6  import java.awt.AWTKeyStroke;
   108.7 +import java.util.logging.Logger;
   108.8  
   108.9  public class XEmbeddedFrame extends EmbeddedFrame {
  108.10  
  108.11 +    private static final Logger log = Logger.getLogger(XEmbeddedFrame.class.getName());
  108.12 +
  108.13      long handle;
  108.14      public XEmbeddedFrame() {
  108.15      }
  108.16 @@ -70,6 +73,21 @@
  108.17          this(handle, supportsXEmbed, false);
  108.18      }
  108.19  
  108.20 +    /*
  108.21 +     * The method shouldn't be called in case of active XEmbed.
  108.22 +     */
  108.23 +    public boolean traverseIn(boolean direction) {
  108.24 +        XEmbeddedFramePeer peer = (XEmbeddedFramePeer)getPeer();
  108.25 +        if (peer != null) {
  108.26 +            if (peer.supportsXEmbed() && peer.isXEmbedActive()) {
  108.27 +                log.fine("The method shouldn't be called when XEmbed is active!");
  108.28 +            } else {
  108.29 +                return super.traverseIn(direction);
  108.30 +            }
  108.31 +        }
  108.32 +        return false;
  108.33 +    }
  108.34 +
  108.35      protected boolean traverseOut(boolean direction) {
  108.36          XEmbeddedFramePeer xefp = (XEmbeddedFramePeer) getPeer();
  108.37          if (direction == FORWARD) {
  108.38 @@ -81,6 +99,20 @@
  108.39          return true;
  108.40      }
  108.41  
  108.42 +    /*
  108.43 +     * The method shouldn't be called in case of active XEmbed.
  108.44 +     */
  108.45 +    public void synthesizeWindowActivation(boolean doActivate) {
  108.46 +        XEmbeddedFramePeer peer = (XEmbeddedFramePeer)getPeer();
  108.47 +        if (peer != null) {
  108.48 +            if (peer.supportsXEmbed() && peer.isXEmbedActive()) {
  108.49 +                log.fine("The method shouldn't be called when XEmbed is active!");
  108.50 +            } else {
  108.51 +                peer.synthesizeFocusInOut(doActivate);
  108.52 +            }
  108.53 +        }
  108.54 +    }
  108.55 +
  108.56      public void registerAccelerator(AWTKeyStroke stroke) {
  108.57          XEmbeddedFramePeer xefp = (XEmbeddedFramePeer) getPeer();
  108.58          if (xefp != null) {
   109.1 --- a/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java	Tue Oct 12 13:34:59 2010 -0400
   109.2 +++ b/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java	Mon Oct 18 11:25:28 2010 -0400
   109.3 @@ -35,6 +35,8 @@
   109.4  import sun.awt.EmbeddedFrame;
   109.5  import sun.awt.SunToolkit;
   109.6  
   109.7 +import static sun.awt.X11.XConstants.*;
   109.8 +
   109.9  public class XEmbeddedFramePeer extends XFramePeer {
  109.10  
  109.11      private static final PlatformLogger xembedLog = PlatformLogger.getLogger("sun.awt.X11.xembed.XEmbeddedFramePeer");
  109.12 @@ -305,4 +307,20 @@
  109.13          EmbeddedFrame frame = (EmbeddedFrame)target;
  109.14          frame.notifyModalBlocked(blocker, blocked);
  109.15      }
  109.16 +
  109.17 +    public void synthesizeFocusInOut(boolean doFocus) {
  109.18 +        XFocusChangeEvent xev = new XFocusChangeEvent();
  109.19 +
  109.20 +        XToolkit.awtLock();
  109.21 +        try {
  109.22 +            xev.set_type(doFocus ? FocusIn : FocusOut);
  109.23 +            xev.set_window(getFocusProxy().getWindow());
  109.24 +            xev.set_mode(NotifyNormal);
  109.25 +            XlibWrapper.XSendEvent(XToolkit.getDisplay(), getFocusProxy().getWindow(), false,
  109.26 +                                   NoEventMask, xev.pData);
  109.27 +        } finally {
  109.28 +            XToolkit.awtUnlock();
  109.29 +            xev.dispose();
  109.30 +        }
  109.31 +    }
  109.32  }
   110.1 --- a/src/solaris/classes/sun/awt/X11/XToolkit.java	Tue Oct 12 13:34:59 2010 -0400
   110.2 +++ b/src/solaris/classes/sun/awt/X11/XToolkit.java	Mon Oct 18 11:25:28 2010 -0400
   110.3 @@ -1482,8 +1482,19 @@
   110.4          try {
   110.5              if (numberOfButtons == 0) {
   110.6                  numberOfButtons = getNumberOfButtonsImpl();
   110.7 +                numberOfButtons = (numberOfButtons > MAX_BUTTONS_SUPPORTED)? MAX_BUTTONS_SUPPORTED : numberOfButtons;
   110.8 +                //4th and 5th buttons are for wheel and shouldn't be reported as buttons.
   110.9 +                //If we have more than 3 physical buttons and a wheel, we report N-2 buttons.
  110.10 +                //If we have 3 physical buttons and a wheel, we report 3 buttons.
  110.11 +                //If we have 1,2,3 physical buttons, we report it as is i.e. 1,2 or 3 respectively.
  110.12 +                if (numberOfButtons >=5) {
  110.13 +                    numberOfButtons -= 2;
  110.14 +                } else if (numberOfButtons == 4 || numberOfButtons ==5){
  110.15 +                    numberOfButtons = 3;
  110.16 +                }
  110.17              }
  110.18 -            return (numberOfButtons > MAX_BUTTONS_SUPPORTED)? MAX_BUTTONS_SUPPORTED : numberOfButtons;
  110.19 +            //Assume don't have to re-query the number again and again.
  110.20 +            return numberOfButtons;
  110.21          } finally {
  110.22              awtUnlock();
  110.23          }
   111.1 --- a/src/solaris/classes/sun/nio/fs/LinuxFileStore.java	Tue Oct 12 13:34:59 2010 -0400
   111.2 +++ b/src/solaris/classes/sun/nio/fs/LinuxFileStore.java	Mon Oct 18 11:25:28 2010 -0400
   111.3 @@ -156,9 +156,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 false;
  111.11 -    }
  111.12  }
   112.1 --- a/src/solaris/classes/sun/nio/fs/SolarisFileStore.java	Tue Oct 12 13:34:59 2010 -0400
   112.2 +++ b/src/solaris/classes/sun/nio/fs/SolarisFileStore.java	Mon Oct 18 11:25:28 2010 -0400
   112.3 @@ -108,9 +108,4 @@
   112.4              return supportsFileAttributeView(UserDefinedFileAttributeView.class);
   112.5          return super.supportsFileAttributeView(name);
   112.6      }
   112.7 -
   112.8 -    @Override
   112.9 -    boolean isLoopback() {
  112.10 -        return type().equals("lofs");
  112.11 -    }
  112.12  }
   113.1 --- a/src/solaris/classes/sun/nio/fs/UnixFileStore.java	Tue Oct 12 13:34:59 2010 -0400
   113.2 +++ b/src/solaris/classes/sun/nio/fs/UnixFileStore.java	Mon Oct 18 11:25:28 2010 -0400
   113.3 @@ -76,12 +76,6 @@
   113.4       */
   113.5      abstract UnixMountEntry findMountEntry() throws IOException;
   113.6  
   113.7 -    /**
   113.8 -     * Returns true if this file store represents a loopback file system that
   113.9 -     * will have the same device ID as underlying file system.
  113.10 -     */
  113.11 -    abstract boolean isLoopback();
  113.12 -
  113.13      UnixPath file() {
  113.14          return file;
  113.15      }
  113.16 @@ -169,22 +163,13 @@
  113.17          if (!(ob instanceof UnixFileStore))
  113.18              return false;
  113.19          UnixFileStore other = (UnixFileStore)ob;
  113.20 -        if (dev != other.dev)
  113.21 -            return false;
  113.22 -        // deviceIDs are equal but they may not be equal if one or both of
  113.23 -        // them is a loopback file system
  113.24 -        boolean thisIsLoopback = isLoopback();
  113.25 -        if (thisIsLoopback != other.isLoopback())
  113.26 -            return false;  // one, but not both, are lofs
  113.27 -        if (!thisIsLoopback)
  113.28 -            return true;    // neither is lofs
  113.29 -        // both are lofs so compare mount points
  113.30 -        return Arrays.equals(this.entry.dir(), other.entry.dir());
  113.31 +        return (this.dev == other.dev) &&
  113.32 +               Arrays.equals(this.entry.dir(), other.entry.dir());
  113.33      }
  113.34  
  113.35      @Override
  113.36      public int hashCode() {
  113.37 -        return (int)(dev ^ (dev >>> 32));
  113.38 +        return (int)(dev ^ (dev >>> 32)) ^ Arrays.hashCode(entry.dir());
  113.39      }
  113.40  
  113.41      @Override
   114.1 --- a/src/solaris/native/java/io/io_util_md.c	Tue Oct 12 13:34:59 2010 -0400
   114.2 +++ b/src/solaris/native/java/io/io_util_md.c	Mon Oct 18 11:25:28 2010 -0400
   114.3 @@ -83,8 +83,6 @@
   114.4              close(devnull);
   114.5          }
   114.6      } else if (JVM_Close(fd) == -1) {
   114.7 -            SET_FD(this, fd, fid); // restore fd
   114.8 -            printf("JVM_Close returned -1\n");
   114.9 -            JNU_ThrowIOExceptionWithLastError(env, "close failed");
  114.10 +        JNU_ThrowIOExceptionWithLastError(env, "close failed");
  114.11      }
  114.12  }
   115.1 --- a/src/solaris/native/java/net/Inet6AddressImpl.c	Tue Oct 12 13:34:59 2010 -0400
   115.2 +++ b/src/solaris/native/java/net/Inet6AddressImpl.c	Mon Oct 18 11:25:28 2010 -0400
   115.3 @@ -124,7 +124,7 @@
   115.4  static int initialized = 0;
   115.5  
   115.6  /*
   115.7 - * Find an internet address for a given hostname.  Not this this
   115.8 + * Find an internet address for a given hostname.  Note that this
   115.9   * code only works for addresses of type INET. The translation
  115.10   * of %d.%d.%d.%d to an address (int) occurs in java now, so the
  115.11   * String "host" shouldn't *ever* be a %d.%d.%d.%d string
  115.12 @@ -200,7 +200,7 @@
  115.13           */
  115.14          if (isspace((unsigned char)hostname[0])) {
  115.15              JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
  115.16 -                            (char *)hostname);
  115.17 +                            hostname);
  115.18              JNU_ReleaseStringPlatformChars(env, host, hostname);
  115.19              return NULL;
  115.20          }
  115.21 @@ -210,8 +210,7 @@
  115.22  
  115.23          if (error) {
  115.24              /* report error */
  115.25 -            JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
  115.26 -                            (char *)hostname);
  115.27 +            ThrowUnknownHostExceptionWithGaiError(env, hostname, error);
  115.28              JNU_ReleaseStringPlatformChars(env, host, hostname);
  115.29              return NULL;
  115.30          } else {
  115.31 @@ -407,7 +406,7 @@
  115.32              addr |= ((caddr[1] <<16) & 0xff0000);
  115.33              addr |= ((caddr[2] <<8) & 0xff00);
  115.34              addr |= (caddr[3] & 0xff);
  115.35 -            memset((char *) &him4, 0, sizeof(him4));
  115.36 +            memset((void *) &him4, 0, sizeof(him4));
  115.37              him4.sin_addr.s_addr = (uint32_t) htonl(addr);
  115.38              him4.sin_family = AF_INET;
  115.39              sa = (struct sockaddr *) &him4;
  115.40 @@ -417,7 +416,7 @@
  115.41               * For IPv6 address construct a sockaddr_in6 structure.
  115.42               */
  115.43              (*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr);
  115.44 -            memset((char *) &him6, 0, sizeof(him6));
  115.45 +            memset((void *) &him6, 0, sizeof(him6));
  115.46              memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) );
  115.47              him6.sin6_family = AF_INET6;
  115.48              sa = (struct sockaddr *) &him6 ;
  115.49 @@ -579,8 +578,8 @@
  115.50                                                           ifArray, ttl);
  115.51      }
  115.52  
  115.53 -    memset((char *) caddr, 0, 16);
  115.54 -    memset((char *) &him6, 0, sizeof(him6));
  115.55 +    memset((void *) caddr, 0, 16);
  115.56 +    memset((void *) &him6, 0, sizeof(him6));
  115.57      (*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr);
  115.58      memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) );
  115.59      him6.sin6_family = AF_INET6;
  115.60 @@ -600,8 +599,8 @@
  115.61       * for it.
  115.62       */
  115.63      if (!(IS_NULL(ifArray))) {
  115.64 -      memset((char *) caddr, 0, 16);
  115.65 -      memset((char *) &inf6, 0, sizeof(inf6));
  115.66 +      memset((void *) caddr, 0, 16);
  115.67 +      memset((void *) &inf6, 0, sizeof(inf6));
  115.68        (*env)->GetByteArrayRegion(env, ifArray, 0, 16, caddr);
  115.69        memcpy((void *)&(inf6.sin6_addr), caddr, sizeof(struct in6_addr) );
  115.70        inf6.sin6_family = AF_INET6;
   116.1 --- a/src/solaris/native/java/net/net_util_md.c	Tue Oct 12 13:34:59 2010 -0400
   116.2 +++ b/src/solaris/native/java/net/net_util_md.c	Mon Oct 18 11:25:28 2010 -0400
   116.3 @@ -61,6 +61,7 @@
   116.4  
   116.5  getaddrinfo_f getaddrinfo_ptr = NULL;
   116.6  freeaddrinfo_f freeaddrinfo_ptr = NULL;
   116.7 +gai_strerror_f gai_strerror_ptr = NULL;
   116.8  getnameinfo_f getnameinfo_ptr = NULL;
   116.9  
  116.10  /*
  116.11 @@ -342,11 +343,14 @@
  116.12      freeaddrinfo_ptr = (freeaddrinfo_f)
  116.13          JVM_FindLibraryEntry(RTLD_DEFAULT, "freeaddrinfo");
  116.14  
  116.15 +    gai_strerror_ptr = (gai_strerror_f)
  116.16 +        JVM_FindLibraryEntry(RTLD_DEFAULT, "gai_strerror");
  116.17 +
  116.18      getnameinfo_ptr = (getnameinfo_f)
  116.19          JVM_FindLibraryEntry(RTLD_DEFAULT, "getnameinfo");
  116.20  
  116.21      if (freeaddrinfo_ptr == NULL || getnameinfo_ptr == NULL) {
  116.22 -        /* Wee need all 3 of them */
  116.23 +        /* We need all 3 of them */
  116.24          getaddrinfo_ptr = NULL;
  116.25      }
  116.26  
  116.27 @@ -355,6 +359,35 @@
  116.28  #endif /* AF_INET6 */
  116.29  }
  116.30  
  116.31 +void ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
  116.32 +                                           const char* hostname,
  116.33 +                                           int gai_error)
  116.34 +{
  116.35 +    int size;
  116.36 +    char *buf;
  116.37 +    const char *format = "%s: %s";
  116.38 +    const char *error_string =
  116.39 +        (gai_strerror_ptr == NULL) ? NULL : (*gai_strerror_ptr)(gai_error);
  116.40 +    if (error_string == NULL)
  116.41 +        error_string = "unknown error";
  116.42 +
  116.43 +    size = strlen(format) + strlen(hostname) + strlen(error_string) + 2;
  116.44 +    buf = (char *) malloc(size);
  116.45 +    if (buf) {
  116.46 +        jstring s;
  116.47 +        sprintf(buf, format, hostname, error_string);
  116.48 +        s = JNU_NewStringPlatform(env, buf);
  116.49 +        if (s != NULL) {
  116.50 +            jobject x = JNU_NewObjectByName(env,
  116.51 +                                            "java/net/UnknownHostException",
  116.52 +                                            "(Ljava/lang/String;)V", s);
  116.53 +            if (x != NULL)
  116.54 +                (*env)->Throw(env, x);
  116.55 +        }
  116.56 +        free(buf);
  116.57 +    }
  116.58 +}
  116.59 +
  116.60  void
  116.61  NET_AllocSockaddr(struct sockaddr **him, int *len) {
  116.62  #ifdef AF_INET6
  116.63 @@ -1173,19 +1206,26 @@
  116.64      }
  116.65  
  116.66      /*
  116.67 -     * SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On Solaris need to
  116.68 -     * ensure that value is <= max_buf as otherwise we get
  116.69 -     * an invalid argument.
  116.70 +     * SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On Solaris we may need to clamp
  116.71 +     * the value when it exceeds the system limit.
  116.72       */
  116.73  #ifdef __solaris__
  116.74      if (level == SOL_SOCKET) {
  116.75          if (opt == SO_SNDBUF || opt == SO_RCVBUF) {
  116.76              int sotype, arglen;
  116.77              int *bufsize, maxbuf;
  116.78 +            int ret;
  116.79 +
  116.80 +            /* Attempt with the original size */
  116.81 +            ret = setsockopt(fd, level, opt, arg, len);
  116.82 +            if ((ret == 0) || (ret == -1 && errno != ENOBUFS))
  116.83 +                return ret;
  116.84 +
  116.85 +            /* Exceeded system limit so clamp and retry */
  116.86  
  116.87              if (!init_max_buf) {
  116.88 -                tcp_max_buf = getParam("/dev/tcp", "tcp_max_buf", 64*1024);
  116.89 -                udp_max_buf = getParam("/dev/udp", "udp_max_buf", 64*1024);
  116.90 +                tcp_max_buf = getParam("/dev/tcp", "tcp_max_buf", 1024*1024);
  116.91 +                udp_max_buf = getParam("/dev/udp", "udp_max_buf", 2048*1024);
  116.92                  init_max_buf = 1;
  116.93              }
  116.94  
   117.1 --- a/src/solaris/native/java/net/net_util_md.h	Tue Oct 12 13:34:59 2010 -0400
   117.2 +++ b/src/solaris/native/java/net/net_util_md.h	Mon Oct 18 11:25:28 2010 -0400
   117.3 @@ -84,11 +84,13 @@
   117.4  
   117.5  /* needed from libsocket on Solaris 8 */
   117.6  
   117.7 -typedef int (*getaddrinfo_f)(const char *nodename, const char  *servname,
   117.8 -     const struct addrinfo *hints, struct addrinfo **res);
   117.9 +typedef int (*getaddrinfo_f)(const char *nodename, const char *servname,
  117.10 +    const struct addrinfo *hints, struct addrinfo **res);
  117.11  
  117.12  typedef void (*freeaddrinfo_f)(struct addrinfo *);
  117.13  
  117.14 +typedef const char * (*gai_strerror_f)(int ecode);
  117.15 +
  117.16  typedef int (*getnameinfo_f)(const struct sockaddr *, size_t,
  117.17      char *, size_t, char *, size_t, int);
  117.18  
  117.19 @@ -96,6 +98,10 @@
  117.20  extern freeaddrinfo_f freeaddrinfo_ptr;
  117.21  extern getnameinfo_f getnameinfo_ptr;
  117.22  
  117.23 +void ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
  117.24 +                                           const char* hostname,
  117.25 +                                           int gai_error);
  117.26 +
  117.27  /* do we have address translation support */
  117.28  
  117.29  extern jboolean NET_addrtransAvailable();
   118.1 --- a/src/solaris/native/sun/awt/awt_InputMethod.c	Tue Oct 12 13:34:59 2010 -0400
   118.2 +++ b/src/solaris/native/sun/awt/awt_InputMethod.c	Mon Oct 18 11:25:28 2010 -0400
   118.3 @@ -1473,6 +1473,10 @@
   118.4  static void DestroyXIMCallback(XIM im, XPointer client_data, XPointer call_data) {
   118.5      /* mark that XIM server was destroyed */
   118.6      X11im = NULL;
   118.7 +    JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
   118.8 +    /* free the old pX11IMData and set it to null. this also avoids crashing
   118.9 +     * the jvm if the XIM server reappears */
  118.10 +    X11InputMethodData *pX11IMData = getX11InputMethodData(env, currentX11InputMethodInstance);
  118.11  }
  118.12  
  118.13  /*
   119.1 --- a/src/windows/classes/sun/awt/windows/WComponentPeer.java	Tue Oct 12 13:34:59 2010 -0400
   119.2 +++ b/src/windows/classes/sun/awt/windows/WComponentPeer.java	Mon Oct 18 11:25:28 2010 -0400
   119.3 @@ -556,24 +556,26 @@
   119.4  
   119.5          Component target = (Component)getTarget();
   119.6          Window window = SunToolkit.getContainingWindow(target);
   119.7 -        if (window != null && !window.isOpaque()) {
   119.8 -            // Non-opaque windows do not support heavyweight children.
   119.9 -            // Redirect all painting to the Window's Graphics instead.
  119.10 -            // The caller is responsible for calling the
  119.11 -            // WindowPeer.updateWindow() after painting has finished.
  119.12 -            int x = 0, y = 0;
  119.13 -            for (Component c = target; c != window; c = c.getParent()) {
  119.14 -                x += c.getX();
  119.15 -                y += c.getY();
  119.16 -            }
  119.17 -
  119.18 +        if (window != null) {
  119.19              Graphics g =
  119.20                  ((WWindowPeer)window.getPeer()).getTranslucentGraphics();
  119.21 +            // getTranslucentGraphics() returns non-null value for non-opaque windows only
  119.22 +            if (g != null) {
  119.23 +                // Non-opaque windows do not support heavyweight children.
  119.24 +                // Redirect all painting to the Window's Graphics instead.
  119.25 +                // The caller is responsible for calling the
  119.26 +                // WindowPeer.updateWindow() after painting has finished.
  119.27 +                int x = 0, y = 0;
  119.28 +                for (Component c = target; c != window; c = c.getParent()) {
  119.29 +                    x += c.getX();
  119.30 +                    y += c.getY();
  119.31 +                }
  119.32  
  119.33 -            g.translate(x, y);
  119.34 -            g.clipRect(0, 0, target.getWidth(), target.getHeight());
  119.35 +                g.translate(x, y);
  119.36 +                g.clipRect(0, 0, target.getWidth(), target.getHeight());
  119.37  
  119.38 -            return g;
  119.39 +                return g;
  119.40 +            }
  119.41          }
  119.42  
  119.43          SurfaceData surfaceData = this.surfaceData;
   120.1 --- a/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java	Tue Oct 12 13:34:59 2010 -0400
   120.2 +++ b/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java	Mon Oct 18 11:25:28 2010 -0400
   120.3 @@ -191,9 +191,20 @@
   120.4      public void activateEmbeddingTopLevel() {
   120.5      }
   120.6  
   120.7 -    public void synthesizeWindowActivation(boolean doActivate) {
   120.8 -        ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(doActivate);
   120.9 +    public void synthesizeWindowActivation(final boolean doActivate) {
  120.10 +        if (!doActivate || EventQueue.isDispatchThread()) {
  120.11 +            ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(doActivate);
  120.12 +        } else {
  120.13 +            // To avoid focus concurrence b/w IE and EmbeddedFrame
  120.14 +            // activation is postponed by means of posting it to EDT.
  120.15 +            EventQueue.invokeLater(new Runnable() {
  120.16 +                    public void run() {
  120.17 +                        ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(true);
  120.18 +                    }
  120.19 +                });
  120.20 +        }
  120.21      }
  120.22 +
  120.23      public void registerAccelerator(AWTKeyStroke stroke) {}
  120.24      public void unregisterAccelerator(AWTKeyStroke stroke) {}
  120.25  
   121.1 --- a/src/windows/classes/sun/awt/windows/WWindowPeer.java	Tue Oct 12 13:34:59 2010 -0400
   121.2 +++ b/src/windows/classes/sun/awt/windows/WWindowPeer.java	Mon Oct 18 11:25:28 2010 -0400
   121.3 @@ -595,16 +595,6 @@
   121.4      }
   121.5  
   121.6      @Override
   121.7 -    public Graphics getGraphics() {
   121.8 -        synchronized (getStateLock()) {
   121.9 -            if (!isOpaque) {
  121.10 -                return getTranslucentGraphics();
  121.11 -            }
  121.12 -        }
  121.13 -        return super.getGraphics();
  121.14 -    }
  121.15 -
  121.16 -    @Override
  121.17      public void setBackground(Color c) {
  121.18          super.setBackground(c);
  121.19          synchronized (getStateLock()) {
   122.1 --- a/src/windows/lib/tzmappings	Tue Oct 12 13:34:59 2010 -0400
   122.2 +++ b/src/windows/lib/tzmappings	Mon Oct 18 11:25:28 2010 -0400
   122.3 @@ -1,5 +1,4 @@
   122.4  #
   122.5 -# 
   122.6  # This file describes mapping information between Windows and Java
   122.7  # time zones.
   122.8  # Format: Each line should include a colon separated fields of Windows
   122.9 @@ -11,7 +10,7 @@
  122.10  #                            NOTE
  122.11  # This table format is not a public interface of any Java
  122.12  # platforms. No applications should depend on this file in any form.
  122.13 -# 
  122.14 +#
  122.15  # This table has been generated by a program and should not be edited
  122.16  # manually.
  122.17  #
  122.18 @@ -84,8 +83,8 @@
  122.19  Ekaterinburg Standard Time:10,11::Asia/Yekaterinburg:
  122.20  West Asia:10,11:UZ:Asia/Tashkent:
  122.21  West Asia Standard Time:10,11:UZ:Asia/Tashkent:
  122.22 -Central Asia:12,13::Asia/Dhaka:
  122.23 -Central Asia Standard Time:12,13::Asia/Dhaka:
  122.24 +Central Asia:12,13::Asia/Almaty:
  122.25 +Central Asia Standard Time:12,13::Asia/Almaty:
  122.26  N. Central Asia Standard Time:12,13::Asia/Novosibirsk:
  122.27  Bangkok:14,15::Asia/Bangkok:
  122.28  Bangkok Standard Time:14,15::Asia/Bangkok:
  122.29 @@ -167,22 +166,27 @@
  122.30  Greenwich Standard Time:88,89::GMT:
  122.31  Argentina Standard Time:900,900::America/Buenos_Aires:
  122.32  Azerbaijan Standard Time:901,901:AZ:Asia/Baku:
  122.33 -Central Brazilian Standard Time:902,902:BR:America/Manaus:
  122.34 -Central Standard Time (Mexico):903,903::America/Mexico_City:
  122.35 -Georgian Standard Time:904,904:GE:Asia/Tbilisi:
  122.36 -Jordan Standard Time:905,905:JO:Asia/Amman:
  122.37 -Mauritius Standard Time:906,906:MU:Indian/Mauritius:
  122.38 -Middle East Standard Time:907,907:LB:Asia/Beirut:
  122.39 -Montevideo Standard Time:908,908:UY:America/Montevideo:
  122.40 -Morocco Standard Time:909,909:MA:Africa/Casablanca:
  122.41 -Mountain Standard Time (Mexico):910,910:MX:America/Chihuahua:
  122.42 -Namibia Standard Time:911,911:NA:Africa/Windhoek:
  122.43 -Pacific Standard Time (Mexico):912,912:MX:America/Tijuana:
  122.44 -Pakistan Standard Time:913,913::Asia/Karachi:
  122.45 -UTC:914,914::UTC:
  122.46 -Venezuela Standard Time:915,915::America/Caracas:
  122.47 -Kamchatka Standard Time:916,916:RU:Asia/Kamchatka:
  122.48 -Paraguay Standard Time:917,917:PY:America/Asuncion:
  122.49 -Western Brazilian Standard Time:918,918:BR:America/Rio_Branco:
  122.50 -Ulaanbaatar Standard Time:919,919::Asia/Ulaanbaatar:
  122.51 -Armenian Standard Time:920,920:AM:Asia/Yerevan:
  122.52 +Bangladesh Standard Time:902,902::Asia/Dhaka:
  122.53 +Central Brazilian Standard Time:903,903:BR:America/Manaus:
  122.54 +Central Standard Time (Mexico):904,904::America/Mexico_City:
  122.55 +Georgian Standard Time:905,905:GE:Asia/Tbilisi:
  122.56 +Jordan Standard Time:906,906:JO:Asia/Amman:
  122.57 +Kamchatka Standard Time:907,907:RU:Asia/Kamchatka:
  122.58 +Mauritius Standard Time:908,908:MU:Indian/Mauritius:
  122.59 +Middle East Standard Time:909,909:LB:Asia/Beirut:
  122.60 +Montevideo Standard Time:910,910:UY:America/Montevideo:
  122.61 +Morocco Standard Time:911,911:MA:Africa/Casablanca:
  122.62 +Mountain Standard Time (Mexico):912,912:MX:America/Chihuahua:
  122.63 +Namibia Standard Time:913,913:NA:Africa/Windhoek:
  122.64 +Pacific Standard Time (Mexico):914,914:MX:America/Tijuana:
  122.65 +Pakistan Standard Time:915,915::Asia/Karachi:
  122.66 +Paraguay Standard Time:916,916:PY:America/Asuncion:
  122.67 +Syria Standard Time:917,917:SY:Asia/Damascus:
  122.68 +UTC:918,918::UTC:
  122.69 +UTC+12:919,919::GMT+1200:
  122.70 +UTC-02:920,920::GMT-0200:
  122.71 +UTC-11:921,921::GMT-1100:
  122.72 +Ulaanbaatar Standard Time:922,922::Asia/Ulaanbaatar:
  122.73 +Venezuela Standard Time:923,923::America/Caracas:
  122.74 +Western Brazilian Standard Time:924,924:BR:America/Rio_Branco:
  122.75 +Armenian Standard Time:925,925:AM:Asia/Yerevan:
   123.1 --- a/src/windows/native/java/io/io_util_md.c	Tue Oct 12 13:34:59 2010 -0400
   123.2 +++ b/src/windows/native/java/io/io_util_md.c	Mon Oct 18 11:25:28 2010 -0400
   123.3 @@ -531,7 +531,6 @@
   123.4      SET_FD(this, -1, fid);
   123.5  
   123.6      if (CloseHandle(h) == 0) { /* Returns zero on failure */
   123.7 -        SET_FD(this, fd, fid); // restore fd
   123.8          JNU_ThrowIOExceptionWithLastError(env, "close failed");
   123.9      }
  123.10      return 0;
   124.1 --- a/src/windows/native/sun/net/spi/DefaultProxySelector.c	Tue Oct 12 13:34:59 2010 -0400
   124.2 +++ b/src/windows/native/sun/net/spi/DefaultProxySelector.c	Mon Oct 18 11:25:28 2010 -0400
   124.3 @@ -250,6 +250,10 @@
   124.4            return proxy;
   124.5          }
   124.6        }
   124.7 +    } else {
   124.8 +      /* ProxyEnable == 0 or Query failed      */
   124.9 +      /* close the handle to the registry key  */
  124.10 +      RegCloseKey(hKey);
  124.11      }
  124.12    }
  124.13  
   125.1 --- a/src/windows/native/sun/windows/awt_Component.cpp	Tue Oct 12 13:34:59 2010 -0400
   125.2 +++ b/src/windows/native/sun/windows/awt_Component.cpp	Mon Oct 18 11:25:28 2010 -0400
   125.3 @@ -2329,6 +2329,19 @@
   125.4      MSG msg;
   125.5      InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
   125.6  
   125.7 +    AwtWindow *toplevel = GetContainer();
   125.8 +    if (toplevel && !toplevel->IsSimpleWindow()) {
   125.9 +        /*
  125.10 +         * The frame should be focused by click in case it is
  125.11 +         * the active window but not the focused window. See 6886678.
  125.12 +         */
  125.13 +        if (toplevel->GetHWnd() == ::GetActiveWindow() &&
  125.14 +            toplevel->GetHWnd() != AwtComponent::GetFocusedWindow())
  125.15 +        {
  125.16 +            toplevel->AwtSetActiveWindow();
  125.17 +        }
  125.18 +    }
  125.19 +
  125.20      SendMouseEvent(java_awt_event_MouseEvent_MOUSE_PRESSED, now, x, y,
  125.21                     GetJavaModifiers(), clickCount, JNI_FALSE,
  125.22                     GetButton(button), &msg);
   126.1 --- a/src/windows/native/sun/windows/awt_Desktop.cpp	Tue Oct 12 13:34:59 2010 -0400
   126.2 +++ b/src/windows/native/sun/windows/awt_Desktop.cpp	Mon Oct 18 11:25:28 2010 -0400
   126.3 @@ -59,15 +59,17 @@
   126.4                      FORMAT_MESSAGE_FROM_SYSTEM  |
   126.5                      FORMAT_MESSAGE_IGNORE_INSERTS,
   126.6                      NULL,
   126.7 -                    GetLastError(),
   126.8 +                    (int)retval,
   126.9                      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  126.10                      (LPTSTR)&buffer,
  126.11                      0,
  126.12                      NULL );
  126.13  
  126.14 -        jstring errmsg = JNU_NewStringPlatform(env, buffer, len);
  126.15 -        LocalFree(buffer);
  126.16 -        return errmsg;
  126.17 +        if (buffer) {
  126.18 +            jstring errmsg = JNU_NewStringPlatform(env, buffer);
  126.19 +            LocalFree(buffer);
  126.20 +            return errmsg;
  126.21 +        }
  126.22      }
  126.23  
  126.24      return NULL;
   127.1 --- a/src/windows/native/sun/windows/awt_DesktopProperties.cpp	Tue Oct 12 13:34:59 2010 -0400
   127.2 +++ b/src/windows/native/sun/windows/awt_DesktopProperties.cpp	Mon Oct 18 11:25:28 2010 -0400
   127.3 @@ -505,7 +505,8 @@
   127.4      SetIntegerProperty(TEXT("win.drag.width"), cxdrag);
   127.5      SetIntegerProperty(TEXT("win.drag.height"), cydrag);
   127.6      SetIntegerProperty(TEXT("DnD.gestureMotionThreshold"), max(cxdrag, cydrag)/2);
   127.7 -    SetIntegerProperty(TEXT("awt.mouse.numButtons"), GetSystemMetrics(SM_CMOUSEBUTTONS));
   127.8 +    SetIntegerProperty(TEXT("awt.mouse.numButtons"), AwtToolkit::GetNumberOfButtons());
   127.9 +
  127.10      SetIntegerProperty(TEXT("awt.multiClickInterval"), GetDoubleClickTime());
  127.11  
  127.12      // BEGIN cross-platform properties
   128.1 --- a/src/windows/native/sun/windows/awt_Toolkit.cpp	Tue Oct 12 13:34:59 2010 -0400
   128.2 +++ b/src/windows/native/sun/windows/awt_Toolkit.cpp	Mon Oct 18 11:25:28 2010 -0400
   128.3 @@ -133,6 +133,8 @@
   128.4  
   128.5  static LPCTSTR szAwtToolkitClassName = TEXT("SunAwtToolkit");
   128.6  
   128.7 +static const int MOUSE_BUTTONS_WINDOWS_SUPPORTED = 5; //three standard buttons + XBUTTON1 + XBUTTON2.
   128.8 +
   128.9  UINT AwtToolkit::GetMouseKeyState()
  128.10  {
  128.11      static BOOL mbSwapped = ::GetSystemMetrics(SM_SWAPBUTTON);
  128.12 @@ -2310,5 +2312,9 @@
  128.13  
  128.14  JNIEXPORT jint JNICALL Java_sun_awt_windows_WToolkit_getNumberOfButtonsImpl
  128.15  (JNIEnv *, jobject self) {
  128.16 -    return GetSystemMetrics(SM_CMOUSEBUTTONS);
  128.17 +    return AwtToolkit::GetNumberOfButtons();
  128.18  }
  128.19 +
  128.20 +UINT AwtToolkit::GetNumberOfButtons() {
  128.21 +    return MOUSE_BUTTONS_WINDOWS_SUPPORTED;
  128.22 +}
   129.1 --- a/src/windows/native/sun/windows/awt_Toolkit.h	Tue Oct 12 13:34:59 2010 -0400
   129.2 +++ b/src/windows/native/sun/windows/awt_Toolkit.h	Mon Oct 18 11:25:28 2010 -0400
   129.3 @@ -185,6 +185,7 @@
   129.4      BOOL IsDynamicLayoutActive();
   129.5      BOOL areExtraMouseButtonsEnabled();
   129.6      void setExtraMouseButtonsEnabled(BOOL enable);
   129.7 +    static UINT GetNumberOfButtons();
   129.8  
   129.9      INLINE BOOL localPump() { return m_localPump; }
  129.10      INLINE BOOL VerifyComponents() { return FALSE; } // TODO: Use new DebugHelper class to set this flag
   130.1 --- a/test/ProblemList.txt	Tue Oct 12 13:34:59 2010 -0400
   130.2 +++ b/test/ProblemList.txt	Mon Oct 18 11:25:28 2010 -0400
   130.3 @@ -165,6 +165,12 @@
   130.4  #  very small tests and could greatly benefit from a samevm test run.
   130.5  #  So a large batch of beans tests are currently run with othervm mode.
   130.6  
   130.7 +# Filed 6986807
   130.8 +java/beans/Introspector/TestTypeResolver.java   		generic-all
   130.9 +
  130.10 +# Filed 6986813
  130.11 +java/beans/Introspector/memory/Test4508780.java			generic-all
  130.12 +
  130.13  # Linux, some kind of problems with X11 display
  130.14  java/beans/PropertyChangeSupport/Test4682386.java		generic-all
  130.15  java/beans/PropertyChangeSupport/TestSynchronization.java	generic-all
  130.16 @@ -493,6 +499,9 @@
  130.17  
  130.18  # jdk_security
  130.19  
  130.20 +# Filed 6986868
  130.21 +sun/security/tools/jarsigner/crl.sh				generic-all
  130.22 +
  130.23  # Filed 6951285, not sure how often this fails, last was Linux 64bit Fedora 9
  130.24  sun/security/krb5/auto/MaxRetries.java				generic-all
  130.25  
  130.26 @@ -689,10 +698,22 @@
  130.27  
  130.28  # jdk_tools
  130.29  
  130.30 +# Filed 6952105
  130.31 +com/sun/jdi/SuspendThreadTest.java				generic-all
  130.32 +
  130.33 +# Filed 6986875
  130.34 +sun/tools/jps/jps-Vvml.sh					generic-all
  130.35 +
  130.36 +# Filed 6979016
  130.37 +sun/tools/jconsole/ResourceCheckTest.sh				generic-all
  130.38 +
  130.39  ############################################################################
  130.40  
  130.41  # jdk_util
  130.42  
  130.43 +# Filed 6933803
  130.44 +java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java	generic-all
  130.45 +
  130.46  # Fails with assertion error on windows
  130.47  #   11 separate stacktraces created... file reuse problem?
  130.48  java/util/zip/ZipFile/ReadLongZipFileName.java			generic-all
   131.1 --- a/test/com/sun/security/sasl/ntlm/NTLMTest.java	Tue Oct 12 13:34:59 2010 -0400
   131.2 +++ b/test/com/sun/security/sasl/ntlm/NTLMTest.java	Mon Oct 18 11:25:28 2010 -0400
   131.3 @@ -31,8 +31,6 @@
   131.4  import javax.security.auth.callback.*;
   131.5  import java.util.*;
   131.6  
   131.7 -import com.sun.security.ntlm.NTLMException;
   131.8 -
   131.9  public class NTLMTest {
  131.10  
  131.11      private static final String MECH = "NTLM";
  131.12 @@ -95,19 +93,13 @@
  131.13              checkVersion("LM/NTLM", "LMv2");
  131.14              throw new Exception("Should not succeed");
  131.15          } catch (SaslException se) {
  131.16 -            NTLMException ne = (NTLMException)se.getCause();
  131.17 -            if (ne.errorCode() != NTLMException.AUTH_FAILED) {
  131.18 -                throw new Exception("Failed false");
  131.19 -            }
  131.20 +            // OK
  131.21          }
  131.22          try {
  131.23              checkVersion("LMv2/NTLMv2", "LM");
  131.24              throw new Exception("Should not succeed");
  131.25          } catch (SaslException se) {
  131.26 -            NTLMException ne = (NTLMException)se.getCause();
  131.27 -            if (ne.errorCode() != NTLMException.AUTH_FAILED) {
  131.28 -                throw new Exception("Failed false");
  131.29 -            }
  131.30 +            // OK
  131.31          }
  131.32  
  131.33      }
   132.1 --- a/test/com/sun/servicetag/JavaServiceTagTest.java	Tue Oct 12 13:34:59 2010 -0400
   132.2 +++ b/test/com/sun/servicetag/JavaServiceTagTest.java	Mon Oct 18 11:25:28 2010 -0400
   132.3 @@ -124,8 +124,9 @@
   132.4              throw new RuntimeException("Unexpected platform_arch: " +
   132.5                  st.getPlatformArch());
   132.6          }
   132.7 +        String vendor = System.getProperty("java.vendor");
   132.8          if (!st.getProductVendor().
   132.9 -                equals("Sun Microsystems")) {
  132.10 +                equals(vendor)) {
  132.11              throw new RuntimeException("Unexpected product_vendor: " +
  132.12                  st.getProductVendor());
  132.13          }
   133.1 --- a/test/com/sun/servicetag/JavaServiceTagTest1.java	Tue Oct 12 13:34:59 2010 -0400
   133.2 +++ b/test/com/sun/servicetag/JavaServiceTagTest1.java	Mon Oct 18 11:25:28 2010 -0400
   133.3 @@ -196,8 +196,10 @@
   133.4              throw new RuntimeException("Unexpected platform_arch: " +
   133.5                  st.getPlatformArch());
   133.6          }
   133.7 +
   133.8 +        String vendor = System.getProperty("java.vendor");
   133.9          if (!st.getProductVendor().
  133.10 -                equals("Sun Microsystems")) {
  133.11 +                equals(vendor)) {
  133.12              throw new RuntimeException("Unexpected product_vendor: " +
  133.13                  st.getProductVendor());
  133.14          }
   134.1 --- a/test/com/sun/servicetag/Util.java	Tue Oct 12 13:34:59 2010 -0400
   134.2 +++ b/test/com/sun/servicetag/Util.java	Mon Oct 18 11:25:28 2010 -0400
   134.3 @@ -162,6 +162,8 @@
   134.4          for (ServiceTag st : svcTags) {
   134.5              ServiceTag st1 = stMap.get(st.getInstanceURN());
   134.6              if (!matches(st, st1)) {
   134.7 +                System.err.println(st);
   134.8 +                System.err.println(st1);
   134.9                  throw new RuntimeException("ServiceTag in the registry " +
  134.10                      "does not match the one in the map");
  134.11              }
   135.1 --- a/test/com/sun/servicetag/environ.properties	Tue Oct 12 13:34:59 2010 -0400
   135.2 +++ b/test/com/sun/servicetag/environ.properties	Mon Oct 18 11:25:28 2010 -0400
   135.3 @@ -4,6 +4,6 @@
   135.4  osVersion=5.10
   135.5  osArchitecture=sparc
   135.6  systemModel=Sun-Fire-V440
   135.7 -systemManufacturer=Sun Microsystems
   135.8 -cpuManufacturer=Sun Microsystems
   135.9 +systemManufacturer=Oracle Corporation
  135.10 +cpuManufacturer=Oracle Corporation
  135.11  serialNumber=BEL078932
   136.1 --- a/test/com/sun/servicetag/missing-environ-field.xml	Tue Oct 12 13:34:59 2010 -0400
   136.2 +++ b/test/com/sun/servicetag/missing-environ-field.xml	Mon Oct 18 11:25:28 2010 -0400
   136.3 @@ -19,7 +19,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-12 06:15:11 GMT</timestamp>
  136.11  <container>global</container>
  136.12 @@ -34,7 +34,7 @@
  136.13  <product_parent_urn>urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3</product_parent_urn>
  136.14  <product_parent>Java Platform Standard Edition 6 (Java SE 6)</product_parent>
  136.15  <product_defined_inst_id>id=1.6.0_05-b01 sparc,dir=/myjdk/solaris-i586</product_defined_inst_id>
  136.16 -<product_vendor>Sun Microsystems</product_vendor>
  136.17 +<product_vendor>Oracle Corporation</product_vendor>
  136.18  <platform_arch>i386</platform_arch>
  136.19  <timestamp>2007-11-12 06:15:11 GMT</timestamp>
  136.20  <container>global</container>
   137.1 --- a/test/com/sun/servicetag/newer-registry-version.xml	Tue Oct 12 13:34:59 2010 -0400
   137.2 +++ b/test/com/sun/servicetag/newer-registry-version.xml	Mon Oct 18 11:25:28 2010 -0400
   137.3 @@ -20,7 +20,7 @@
   137.4  <product_parent_urn>urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3</product_parent_urn>
   137.5  <product_parent>Java Platform Standard Edition 6 (Java SE 6)</product_parent>
   137.6  <product_defined_inst_id>id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc</product_defined_inst_id>
   137.7 -<product_vendor>Sun Microsystems</product_vendor>
   137.8 +<product_vendor>Oracle Corporation</product_vendor>
   137.9  <platform_arch>sparc</platform_arch>
  137.10  <timestamp>2007-11-13 00:49:01 GMT</timestamp>
  137.11  <container>global</container>
   138.1 --- a/test/com/sun/servicetag/registration.xml	Tue Oct 12 13:34:59 2010 -0400
   138.2 +++ b/test/com/sun/servicetag/registration.xml	Mon Oct 18 11:25:28 2010 -0400
   138.3 @@ -7,8 +7,8 @@
   138.4  <osVersion>5.10</osVersion>
   138.5  <osArchitecture>sparc</osArchitecture>
   138.6  <systemModel>Sun-Fire-V440</systemModel>
   138.7 -<systemManufacturer>Sun Microsystems</systemManufacturer>
   138.8 -<cpuManufacturer>Sun Microsystems</cpuManufacturer>
   138.9 +<systemManufacturer>Oracle Corporation</systemManufacturer>
  138.10 +<cpuManufacturer>Oracle Corporation</cpuManufacturer>
  138.11  <serialNumber>BEL078932</serialNumber>
  138.12  </environment>
  138.13  <registry urn="urn:st:9543ffaa-a4f1-4f77-b2d1-f561922d4e4a" version="1.0">
  138.14 @@ -20,7 +20,7 @@
  138.15  <product_parent_urn>urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3</product_parent_urn>
  138.16  <product_parent>Java Platform Standard Edition 6 (Java SE 6)</product_parent>
  138.17  <product_defined_inst_id>id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc</product_defined_inst_id>
  138.18 -<product_vendor>Sun Microsystems</product_vendor>
  138.19 +<product_vendor>Oracle Corporation</product_vendor>
  138.20  <platform_arch>sparc</platform_arch>
  138.21  <timestamp>2007-11-13 00:49:01 GMT</timestamp>
  138.22  <container>global</container>
  138.23 @@ -35,7 +35,7 @@
  138.24  <product_parent_urn>urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3</product_parent_urn>
  138.25  <product_parent>Java Platform Standard Edition 6 (Java SE 6)</product_parent>
  138.26  <product_defined_inst_id>id=1.6.0_05-b01 i386,dir=/myjdk/solaris-i586</product_defined_inst_id>
  138.27 -<product_vendor>Sun Microsystems</product_vendor>
  138.28 +<product_vendor>Oracle Corporation</product_vendor>
  138.29  <platform_arch>i386</platform_arch>
  138.30  <timestamp>2007-11-13 00:49:01 GMT</timestamp>
  138.31  <container>global</container>
  138.32 @@ -50,7 +50,7 @@
  138.33  <product_parent_urn>urn:uuid:596ffcfa-63d5-11d7-9886-ac816a682f92</product_parent_urn>
  138.34  <product_parent>Solaris Operating System</product_parent>
  138.35  <product_defined_inst_id/>
  138.36 -<product_vendor>Sun Microsystems</product_vendor>
  138.37 +<product_vendor>Oracle Corporation</product_vendor>
  138.38  <platform_arch>sparc</platform_arch>
  138.39  <timestamp>2007-11-13 00:49:01 GMT</timestamp>
  138.40  <container>global</container>
   139.1 --- a/test/com/sun/servicetag/servicetag1.properties	Tue Oct 12 13:34:59 2010 -0400
   139.2 +++ b/test/com/sun/servicetag/servicetag1.properties	Mon Oct 18 11:25:28 2010 -0400
   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-internal-b00 sparc,dir=/myjdk/solaris-sparc
   139.7 -product_vendor=Sun Microsystems
   139.8 +product_vendor=Oracle Corporation
   139.9  platform_arch=sparc
  139.10  timestamp=2007-11-12 05:19:40 GMT
  139.11  container=global
   140.1 --- a/test/com/sun/servicetag/servicetag2.properties	Tue Oct 12 13:34:59 2010 -0400
   140.2 +++ b/test/com/sun/servicetag/servicetag2.properties	Mon Oct 18 11:25:28 2010 -0400
   140.3 @@ -5,7 +5,7 @@
   140.4  product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3
   140.5  product_parent=Java Platform Standard Edition 6 (Java SE 6)
   140.6  product_defined_inst_id=id=1.6.0_05-b01 i386,dir=/myjdk/solaris-i586
   140.7 -product_vendor=Sun Microsystems
   140.8 +product_vendor=Oracle Corporation
   140.9  platform_arch=i386
  140.10  timestamp=2007-11-12 06:12:21 GMT
  140.11  container=global
   141.1 --- a/test/com/sun/servicetag/servicetag3.properties	Tue Oct 12 13:34:59 2010 -0400
   141.2 +++ b/test/com/sun/servicetag/servicetag3.properties	Mon Oct 18 11:25:28 2010 -0400
   141.3 @@ -5,7 +5,7 @@
   141.4  product_parent_urn=urn:uuid:596ffcfa-63d5-11d7-9886-ac816a682f92
   141.5  product_parent=Solaris Operating System
   141.6  product_defined_inst_id=
   141.7 -product_vendor=Sun Microsystems
   141.8 +product_vendor=Oracle Corporation
   141.9  platform_arch=sparc
  141.10  timestamp=2007-06-20 22:07:11 GMT
  141.11  container=global
   142.1 --- a/test/com/sun/servicetag/servicetag4.properties	Tue Oct 12 13:34:59 2010 -0400
   142.2 +++ b/test/com/sun/servicetag/servicetag4.properties	Mon Oct 18 11:25:28 2010 -0400
   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_05-b01 amd64,dir=/myjdk/linux-amd64
   142.7 -product_vendor=Sun Microsystems
   142.8 +product_vendor=Oracle Corporation
   142.9  platform_arch=x64
  142.10  timestamp=2007-12-12 05:19:40 GMT
  142.11  container=global
   143.1 --- a/test/com/sun/servicetag/servicetag5.properties	Tue Oct 12 13:34:59 2010 -0400
   143.2 +++ b/test/com/sun/servicetag/servicetag5.properties	Mon Oct 18 11:25:28 2010 -0400
   143.3 @@ -5,7 +5,7 @@
   143.4  product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3
   143.5  product_parent=Java Platform Standard Edition 6 (Java SE 6)
   143.6  product_defined_inst_id=id=1.6.0_06-b06 i386,dir=/w/mchung/bundles/jdk1.6.0_05/jre
   143.7 -product_vendor=Sun Microsystems
   143.8 +product_vendor=Oracle Corporation
   143.9  platform_arch=x86
  143.10  timestamp=2007-11-29 17:59:42 GMT
  143.11  container=global
   144.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   144.2 +++ b/test/demo/zipfs/Basic.java	Mon Oct 18 11:25:28 2010 -0400
   144.3 @@ -0,0 +1,159 @@
   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.nio.file.attribute.*;
  144.29 +import java.nio.file.spi.FileSystemProvider;
  144.30 +import java.util.*;
  144.31 +import java.net.URI;
  144.32 +import java.io.IOException;
  144.33 +
  144.34 +/**
  144.35 + * Basic test for zip provider
  144.36 + */
  144.37 +
  144.38 +public class Basic {
  144.39 +    public static void main(String[] args) throws Exception {
  144.40 +        Path zipfile = Paths.get(args[0]);
  144.41 +
  144.42 +        // Test: zip should should be returned in provider list
  144.43 +        boolean found = false;
  144.44 +
  144.45 +        for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
  144.46 +            if (provider.getScheme().equalsIgnoreCase("zip")) {
  144.47 +                found = true;
  144.48 +                break;
  144.49 +            }
  144.50 +        }
  144.51 +        if (!found)
  144.52 +            throw new RuntimeException("'zip' provider not installed");
  144.53 +
  144.54 +        // Test: FileSystems#newFileSystem(FileRef)
  144.55 +        Map<String,?> env = new HashMap<String,Object>();
  144.56 +        FileSystems.newFileSystem(zipfile, env, null).close();
  144.57 +
  144.58 +        // Test: FileSystems#newFileSystem(URI)
  144.59 +        URI uri = URI.create("zip" + zipfile.toUri().toString().substring(4));
  144.60 +        FileSystem fs = FileSystems.newFileSystem(uri, env, null);
  144.61 +
  144.62 +        // Test: exercise toUri method
  144.63 +        String expected = uri.toString() + "#/foo";
  144.64 +        String actual = fs.getPath("/foo").toUri().toString();
  144.65 +        if (!actual.equals(expected)) {
  144.66 +            throw new RuntimeException("toUri returned '" + actual +
  144.67 +                "', expected '" + expected + "'");
  144.68 +        }
  144.69 +
  144.70 +        // Test: exercise directory iterator and retrieval of basic attributes
  144.71 +        Files.walkFileTree(fs.getPath("/"), new FileTreePrinter());
  144.72 +
  144.73 +        // Test: DirectoryStream
  144.74 +        found = false;
  144.75 +        DirectoryStream<Path> stream = fs.getPath("/").newDirectoryStream();
  144.76 +        try {
  144.77 +            for (Path entry: stream) {
  144.78 +                found = entry.toString().equals("/META-INF/");
  144.79 +                if (found) break;
  144.80 +            }
  144.81 +        } finally {
  144.82 +            stream.close();
  144.83 +        }
  144.84 +
  144.85 +        if (!found)
  144.86 +            throw new RuntimeException("Expected file not found");
  144.87 +
  144.88 +        // Test: copy file from zip file to current (scratch) directory
  144.89 +        Path source = fs.getPath("/META-INF/services/java.nio.file.spi.FileSystemProvider");
  144.90 +        if (source.exists()) {
  144.91 +            Path target = Paths.get(source.getName().toString());
  144.92 +            source.copyTo(target, StandardCopyOption.REPLACE_EXISTING);
  144.93 +            try {
  144.94 +                long s1 = Attributes.readBasicFileAttributes(source).size();
  144.95 +                long s2 = Attributes.readBasicFileAttributes(target).size();
  144.96 +                if (s2 != s1)
  144.97 +                    throw new RuntimeException("target size != source size");
  144.98 +            } finally {
  144.99 +                target.delete();
 144.100 +            }
 144.101 +        }
 144.102 +
 144.103 +        // Test: FileStore
 144.104 +        FileStore store = fs.getPath("/").getFileStore();
 144.105 +        if (!store.supportsFileAttributeView("basic"))
 144.106 +            throw new RuntimeException("BasicFileAttributeView should be supported");
 144.107 +
 144.108 +        // Test: ClosedFileSystemException
 144.109 +        fs.close();
 144.110 +        if (fs.isOpen())
 144.111 +            throw new RuntimeException("FileSystem should be closed");
 144.112 +        try {
 144.113 +            fs.getPath("/missing").checkAccess(AccessMode.READ);
 144.114 +        } catch (ClosedFileSystemException x) { }
 144.115 +    }
 144.116 +
 144.117 +    // FileVisitor that pretty prints a file tree
 144.118 +    static class FileTreePrinter extends SimpleFileVisitor<Path> {
 144.119 +        private int indent = 0;
 144.120 +
 144.121 +        private void indent() {
 144.122 +            StringBuilder sb = new StringBuilder(indent);
 144.123 +            for (int i=0; i<indent; i++) sb.append(" ");
 144.124 +            System.out.print(sb);
 144.125 +        }
 144.126 +
 144.127 +        @Override
 144.128 +        public FileVisitResult preVisitDirectory(Path dir,
 144.129 +                                                 BasicFileAttributes attrs)
 144.130 +        {
 144.131 +            if (dir.getName() != null) {
 144.132 +                indent();
 144.133 +                System.out.println(dir.getName() + "/");
 144.134 +                indent++;
 144.135 +            }
 144.136 +            return FileVisitResult.CONTINUE;
 144.137 +        }
 144.138 +
 144.139 +        @Override
 144.140 +        public FileVisitResult visitFile(Path file,
 144.141 +                                         BasicFileAttributes attrs)
 144.142 +        {
 144.143 +            indent();
 144.144 +            System.out.print(file.getName());
 144.145 +            if (attrs.isRegularFile())
 144.146 +                System.out.format(" (%d)", attrs.size());
 144.147 +            System.out.println();
 144.148 +            return FileVisitResult.CONTINUE;
 144.149 +        }
 144.150 +
 144.151 +        @Override
 144.152 +        public FileVisitResult postVisitDirectory(Path dir, IOException exc)
 144.153 +            throws IOException
 144.154 +        {
 144.155 +            if (exc != null)
 144.156 +                super.postVisitDirectory(dir, exc);
 144.157 +            if (dir.getName() != null)
 144.158 +                indent--;
 144.159 +            return FileVisitResult.CONTINUE;
 144.160 +        }
 144.161 +    }
 144.162 +}
   145.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   145.2 +++ b/test/demo/zipfs/PathOps.java	Mon Oct 18 11:25:28 2010 -0400
   145.3 @@ -0,0 +1,416 @@
   145.4 +/*
   145.5 + * Copyright (c) 2009, 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.nio.file.*;
  145.28 +import java.net.*;
  145.29 +import java.util.*;
  145.30 +import java.io.IOException;
  145.31 +
  145.32 +/**
  145.33 + * Tests path operations for zip provider.
  145.34 + */
  145.35 +
  145.36 +public class PathOps {
  145.37 +
  145.38 +    static final java.io.PrintStream out = System.out;
  145.39 +    static FileSystem fs;
  145.40 +
  145.41 +    private String input;
  145.42 +    private Path path;
  145.43 +    private Exception exc;
  145.44 +
  145.45 +    private PathOps(String s) {
  145.46 +        out.println();
  145.47 +        input = s;
  145.48 +        try {
  145.49 +            path = fs.getPath(s);
  145.50 +            out.format("%s -> %s", s, path);
  145.51 +        } catch (Exception x) {
  145.52 +            exc = x;
  145.53 +            out.format("%s -> %s", s, x);
  145.54 +        }
  145.55 +        out.println();
  145.56 +    }
  145.57 +
  145.58 +    Path path() {
  145.59 +        return path;
  145.60 +    }
  145.61 +
  145.62 +    void fail() {
  145.63 +        throw new RuntimeException("PathOps failed");
  145.64 +    }
  145.65 +
  145.66 +    void checkPath() {
  145.67 +        if (path == null) {
  145.68 +            throw new InternalError("path is null");
  145.69 +        }
  145.70 +    }
  145.71 +
  145.72 +    void check(Object result, String expected) {
  145.73 +        out.format("\tExpected: %s\n", expected);
  145.74 +        out.format("\tActual: %s\n",  result);
  145.75 +        if (result == null) {
  145.76 +            if (expected == null) return;
  145.77 +        } else {
  145.78 +            // compare string representations
  145.79 +            if (expected != null && result.toString().equals(expected.toString()))
  145.80 +                return;
  145.81 +        }
  145.82 +        fail();
  145.83 +    }
  145.84 +
  145.85 +    void check(Object result, boolean expected) {
  145.86 +        check(result, Boolean.toString(expected));
  145.87 +    }
  145.88 +
  145.89 +    PathOps root(String expected) {
  145.90 +        out.println("check root");
  145.91 +        checkPath();
  145.92 +        check(path.getRoot(), expected);
  145.93 +        return this;
  145.94 +    }
  145.95 +
  145.96 +    PathOps parent(String expected) {
  145.97 +        out.println("check parent");
  145.98 +        checkPath();
  145.99 +        check(path.getParent(), expected);
 145.100 +        return this;
 145.101 +    }
 145.102 +
 145.103 +    PathOps name(String expected) {
 145.104 +        out.println("check name");
 145.105 +        checkPath();
 145.106 +        check(path.getName(), expected);
 145.107 +        return this;
 145.108 +    }
 145.109 +
 145.110 +    PathOps element(int index, String expected) {
 145.111 +        out.format("check element %d\n", index);
 145.112 +        checkPath();
 145.113 +        check(path.getName(index), expected);
 145.114 +        return this;
 145.115 +    }
 145.116 +
 145.117 +    PathOps subpath(int startIndex, int endIndex, String expected) {
 145.118 +        out.format("test subpath(%d,%d)\n", startIndex, endIndex);
 145.119 +        checkPath();
 145.120 +        check(path.subpath(startIndex, endIndex), expected);
 145.121 +        return this;
 145.122 +    }
 145.123 +
 145.124 +    PathOps starts(String prefix) {
 145.125 +        out.format("test startsWith with %s\n", prefix);
 145.126 +        checkPath();
 145.127 +        Path s = fs.getPath(prefix);
 145.128 +        check(path.startsWith(s), true);
 145.129 +        return this;
 145.130 +    }
 145.131 +
 145.132 +    PathOps notStarts(String prefix) {
 145.133 +        out.format("test not startsWith with %s\n", prefix);
 145.134 +        checkPath();
 145.135 +        Path s = fs.getPath(prefix);
 145.136 +        check(path.startsWith(s), false);
 145.137 +        return this;
 145.138 +    }
 145.139 +
 145.140 +    PathOps ends(String suffix) {
 145.141 +        out.format("test endsWith %s\n", suffix);
 145.142 +        checkPath();
 145.143 +        Path s = fs.getPath(suffix);
 145.144 +        check(path.endsWith(s), true);
 145.145 +        return this;
 145.146 +    }
 145.147 +
 145.148 +    PathOps notEnds(String suffix) {
 145.149 +        out.format("test not endsWith %s\n", suffix);
 145.150 +        checkPath();
 145.151 +        Path s = fs.getPath(suffix);
 145.152 +        check(path.endsWith(s), false);
 145.153 +        return this;
 145.154 +    }
 145.155 +
 145.156 +    PathOps absolute() {
 145.157 +        out.println("check path is absolute");
 145.158 +        checkPath();
 145.159 +        check(path.isAbsolute(), true);
 145.160 +        return this;
 145.161 +    }
 145.162 +
 145.163 +    PathOps notAbsolute() {
 145.164 +        out.println("check path is not absolute");
 145.165 +        checkPath();
 145.166 +        check(path.isAbsolute(), false);
 145.167 +        return this;
 145.168 +    }
 145.169 +
 145.170 +    PathOps resolve(String other, String expected) {
 145.171 +        out.format("test resolve %s\n", other);
 145.172 +        checkPath();
 145.173 +        check(path.resolve(other), expected);
 145.174 +        return this;
 145.175 +    }
 145.176 +
 145.177 +    PathOps relativize(String other, String expected) {
 145.178 +        out.format("test relativize %s\n", other);
 145.179 +        checkPath();
 145.180 +        Path that = fs.getPath(other);
 145.181 +        check(path.relativize(that), expected);
 145.182 +        return this;
 145.183 +    }
 145.184 +
 145.185 +    PathOps normalize(String expected) {
 145.186 +        out.println("check normalized path");
 145.187 +        checkPath();
 145.188 +        check(path.normalize(), expected);
 145.189 +        return this;
 145.190 +    }
 145.191 +
 145.192 +    PathOps string(String expected) {
 145.193 +        out.println("check string representation");
 145.194 +        checkPath();
 145.195 +        check(path, expected);
 145.196 +        return this;
 145.197 +    }
 145.198 +
 145.199 +    PathOps invalid() {
 145.200 +        if (!(exc instanceof InvalidPathException)) {
 145.201 +            out.println("InvalidPathException not thrown as expected");
 145.202 +            fail();
 145.203 +        }
 145.204 +        return this;
 145.205 +    }
 145.206 +
 145.207 +    static PathOps test(String s) {
 145.208 +        return new PathOps(s);
 145.209 +    }
 145.210 +
 145.211 +    // -- PathOpss --
 145.212 +
 145.213 +    static void header(String s) {
 145.214 +        out.println();
 145.215 +        out.println();
 145.216 +        out.println("-- " + s + " --");
 145.217 +    }
 145.218 +
 145.219 +    static void doPathOpTests() {
 145.220 +        header("Path operations");
 145.221 +
 145.222 +        // all components
 145.223 +        test("/a/b/c")
 145.224 +            .root("/")
 145.225 +            .parent("/a/b")
 145.226 +            .name("c");
 145.227 +
 145.228 +        // root component only
 145.229 +        test("/")
 145.230 +            .root("/")
 145.231 +            .parent(null)
 145.232 +            .name(null);
 145.233 +
 145.234 +        // no root component
 145.235 +        test("a/b")
 145.236 +            .root(null)
 145.237 +            .parent("a")
 145.238 +            .name("b");
 145.239 +
 145.240 +        // name component only
 145.241 +        test("foo")
 145.242 +            .root(null)
 145.243 +            .parent(null)
 145.244 +            .name("foo");
 145.245 +
 145.246 +        // startsWith
 145.247 +        test("/")
 145.248 +            .starts("/")
 145.249 +            .notStarts("/foo");
 145.250 +        test("/foo")
 145.251 +            .starts("/")
 145.252 +            .starts("/foo")
 145.253 +            .notStarts("/f");
 145.254 +        test("/foo/bar")
 145.255 +            .starts("/")
 145.256 +            .starts("/foo")
 145.257 +            .starts("/foo/bar")
 145.258 +            .notStarts("/f")
 145.259 +            .notStarts("foo")
 145.260 +            .notStarts("foo/bar");
 145.261 +        test("foo")
 145.262 +            .starts("foo")
 145.263 +            .notStarts("f");
 145.264 +        test("foo/bar")
 145.265 +            .starts("foo")
 145.266 +            .starts("foo/bar")
 145.267 +            .notStarts("f")
 145.268 +            .notStarts("/foo")
 145.269 +            .notStarts("/foo/bar");
 145.270 +
 145.271 +        // endsWith
 145.272 +        test("/")
 145.273 +            .ends("/")
 145.274 +            .notEnds("foo")
 145.275 +            .notEnds("/foo");
 145.276 +        test("/foo")
 145.277 +            .ends("foo")
 145.278 +            .ends("/foo")
 145.279 +            .notEnds("/");
 145.280 +        test("/foo/bar")
 145.281 +            .ends("bar")
 145.282 +            .ends("foo/bar")
 145.283 +            .ends("/foo/bar")
 145.284 +            .notEnds("/bar");
 145.285 +        test("foo")
 145.286 +            .ends("foo");
 145.287 +        test("foo/bar")
 145.288 +            .ends("bar")
 145.289 +            .ends("foo/bar");
 145.290 +
 145.291 +        // elements
 145.292 +        test("a/b/c")
 145.293 +            .element(0,"a")
 145.294 +            .element(1,"b")
 145.295 +            .element(2,"c");
 145.296 +
 145.297 +        // isAbsolute
 145.298 +        test("/")
 145.299 +            .absolute();
 145.300 +        test("/tmp")
 145.301 +            .absolute();
 145.302 +        test("tmp")
 145.303 +            .notAbsolute();
 145.304 +
 145.305 +        // resolve
 145.306 +        test("/tmp")
 145.307 +            .resolve("foo", "/tmp/foo")
 145.308 +            .resolve("/foo", "/foo");
 145.309 +        test("tmp")
 145.310 +            .resolve("foo", "tmp/foo")
 145.311 +            .resolve("/foo", "/foo");
 145.312 +
 145.313 +        // relativize
 145.314 +        test("/a/b/c")
 145.315 +            .relativize("/a/b/c", null)
 145.316 +            .relativize("/a/b/c/d/e", "d/e")
 145.317 +            .relativize("/a/x", "../../x");
 145.318 +
 145.319 +        // normalize
 145.320 +        test("/")
 145.321 +            .normalize("/");
 145.322 +        test("foo")
 145.323 +            .normalize("foo");
 145.324 +        test("/foo")
 145.325 +            .normalize("/foo");
 145.326 +        test(".")
 145.327 +            .normalize(null);
 145.328 +        test("..")
 145.329 +            .normalize("..");
 145.330 +        test("/..")
 145.331 +            .normalize("/");
 145.332 +        test("/../..")
 145.333 +            .normalize("/");
 145.334 +        test("foo/.")
 145.335 +            .normalize("foo");
 145.336 +        test("./foo")
 145.337 +            .normalize("foo");
 145.338 +        test("foo/..")
 145.339 +            .normalize(null);
 145.340 +        test("../foo")
 145.341 +            .normalize("../foo");
 145.342 +        test("../../foo")
 145.343 +            .normalize("../../foo");
 145.344 +        test("foo/bar/..")
 145.345 +            .normalize("foo");
 145.346 +        test("foo/bar/gus/../..")
 145.347 +            .normalize("foo");
 145.348 +        test("/foo/bar/gus/../..")
 145.349 +            .normalize("/foo");
 145.350 +
 145.351 +        // invalid
 145.352 +        test("foo\u0000bar")
 145.353 +            .invalid();
 145.354 +        test("\u0000foo")
 145.355 +            .invalid();
 145.356 +        test("bar\u0000")
 145.357 +            .invalid();
 145.358 +        test("//foo\u0000bar")
 145.359 +            .invalid();
 145.360 +        test("//\u0000foo")
 145.361 +            .invalid();
 145.362 +        test("//bar\u0000")
 145.363 +            .invalid();
 145.364 +
 145.365 +        // normalization
 145.366 +        test("//foo//bar")
 145.367 +            .string("/foo/bar")
 145.368 +            .root("/")
 145.369 +            .parent("/foo")
 145.370 +            .name("bar");
 145.371 +    }
 145.372 +
 145.373 +    static void npes() {
 145.374 +        header("NullPointerException");
 145.375 +
 145.376 +        Path path = fs.getPath("foo");
 145.377 +
 145.378 +        try {
 145.379 +            path.resolve((String)null);
 145.380 +            throw new RuntimeException("NullPointerException not thrown");
 145.381 +        } catch (NullPointerException npe) {
 145.382 +        }
 145.383 +
 145.384 +        try {
 145.385 +            path.relativize(null);
 145.386 +            throw new RuntimeException("NullPointerException not thrown");
 145.387 +        } catch (NullPointerException npe) {
 145.388 +        }
 145.389 +
 145.390 +        try {
 145.391 +            path.compareTo(null);
 145.392 +            throw new RuntimeException("NullPointerException not thrown");
 145.393 +        } catch (NullPointerException npe) {
 145.394 +        }
 145.395 +
 145.396 +        try {
 145.397 +            path.startsWith(null);
 145.398 +            throw new RuntimeException("NullPointerException not thrown");
 145.399 +        } catch (NullPointerException npe) {
 145.400 +        }
 145.401 +
 145.402 +        try {
 145.403 +            path.endsWith(null);
 145.404 +            throw new RuntimeException("NullPointerException not thrown");
 145.405 +        } catch (NullPointerException npe) {
 145.406 +        }
 145.407 +
 145.408 +    }
 145.409 +
 145.410 +    public static void main(String[] args) throws Throwable {
 145.411 +
 145.412 +        Path zipfile = Paths.get(args[0]);
 145.413 +        Map<String,?> env = new HashMap<String,Object>();
 145.414 +        fs = FileSystems.newFileSystem(zipfile, env, null);
 145.415 +        npes();
 145.416 +        doPathOpTests();
 145.417 +        fs.close();
 145.418 +    }
 145.419 +}
   146.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   146.2 +++ b/test/demo/zipfs/ZipFSTester.java	Mon Oct 18 11:25:28 2010 -0400
   146.3 @@ -0,0 +1,633 @@
   146.4 +/*
   146.5 + * Copyright (c) 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 +
  146.27 +import java.io.*;
  146.28 +import java.nio.*;
  146.29 +import java.nio.channels.*;
  146.30 +import java.nio.file.*;
  146.31 +import java.nio.file.attribute.*;
  146.32 +import java.net.*;
  146.33 +import java.util.*;
  146.34 +
  146.35 +import static java.nio.file.StandardOpenOption.*;
  146.36 +import static java.nio.file.StandardCopyOption.*;
  146.37 +
  146.38 +/*
  146.39 + * Tests various zipfs operations.
  146.40 + */
  146.41 +
  146.42 +public class ZipFSTester {
  146.43 +
  146.44 +    public static void main(String[] args) throws Throwable {
  146.45 +        FileSystem fs = null;
  146.46 +        try {
  146.47 +            fs = newZipFileSystem(Paths.get(args[0]), new HashMap<String, Object>());
  146.48 +            test(fs);
  146.49 +            test2(fs);   // more tests
  146.50 +        } finally {
  146.51 +            if (fs != null)
  146.52 +                fs.close();
  146.53 +        }
  146.54 +    }
  146.55 +
  146.56 +    static void test(FileSystem fs)
  146.57 +        throws Exception
  146.58 +    {
  146.59 +        Random rdm = new Random();
  146.60 +
  146.61 +        // clone a fs and test on it
  146.62 +        Path tmpfsPath = getTempPath();
  146.63 +        Map<String, Object> env = new HashMap<String, Object>();
  146.64 +        env.put("createNew", true);
  146.65 +        FileSystem fs0 = newZipFileSystem(tmpfsPath, env);
  146.66 +        z2zcopy(fs, fs0, "/", 0);
  146.67 +        fs0.close();                // sync to file
  146.68 +
  146.69 +        fs = newZipFileSystem(tmpfsPath, new HashMap<String, Object>());
  146.70 +
  146.71 +        try {
  146.72 +            // prepare a src
  146.73 +            Path src = getTempPath();
  146.74 +            String tmpName = src.toString();
  146.75 +            OutputStream os = src.newOutputStream();
  146.76 +            byte[] bits = new byte[12345];
  146.77 +            rdm.nextBytes(bits);
  146.78 +            os.write(bits);
  146.79 +            os.close();
  146.80 +
  146.81 +            // copyin
  146.82 +            Path dst = getPathWithParents(fs, tmpName);
  146.83 +            src.copyTo(dst);
  146.84 +            checkEqual(src, dst);
  146.85 +
  146.86 +            // copy
  146.87 +            Path dst2 = getPathWithParents(fs, "/xyz" + rdm.nextInt(100) +
  146.88 +                                           "/efg" + rdm.nextInt(100) + "/foo.class");
  146.89 +            dst.copyTo(dst2);
  146.90 +            //dst.moveTo(dst2);
  146.91 +            checkEqual(src, dst2);
  146.92 +
  146.93 +            // delete
  146.94 +            dst.delete();
  146.95 +            if (dst.exists())
  146.96 +                throw new RuntimeException("Failed!");
  146.97 +
  146.98 +            // moveout
  146.99 +            Path dst3 = Paths.get(tmpName + "_Tmp");
 146.100 +            dst2.moveTo(dst3);
 146.101 +            checkEqual(src, dst3);
 146.102 +
 146.103 +            // delete
 146.104 +            if (dst2.exists())
 146.105 +                throw new RuntimeException("Failed!");
 146.106 +            dst3.delete();
 146.107 +            if (dst3.exists())
 146.108 +                throw new RuntimeException("Failed!");
 146.109 +
 146.110 +            // newInputStream on dir
 146.111 +            Path parent = dst2.getParent();
 146.112 +            try {
 146.113 +                parent.newInputStream();
 146.114 +                throw new RuntimeException("Failed");
 146.115 +            } catch (FileSystemException e) {
 146.116 +                e.printStackTrace();    // expected fse
 146.117 +            }
 146.118 +
 146.119 +            // rmdirs
 146.120 +            try {
 146.121 +                rmdirs(parent);
 146.122 +            } catch (IOException x) {
 146.123 +                x.printStackTrace();
 146.124 +            }
 146.125 +
 146.126 +            // newFileChannel() copy in, out and verify via fch
 146.127 +            fchCopy(src, dst);    // in
 146.128 +            checkEqual(src, dst);
 146.129 +            Path tmp = Paths.get(tmpName + "_Tmp");
 146.130 +            fchCopy(dst, tmp);   //  out
 146.131 +            checkEqual(src, tmp);
 146.132 +            tmp.delete();
 146.133 +
 146.134 +            // test channels
 146.135 +            channel(fs, dst);
 146.136 +            dst.delete();
 146.137 +            src.delete();
 146.138 +        } finally {
 146.139 +            if (fs != null)
 146.140 +                fs.close();
 146.141 +            if (tmpfsPath.exists())
 146.142 +                tmpfsPath.delete();
 146.143 +        }
 146.144 +    }
 146.145 +
 146.146 +    static void test2(FileSystem fs) throws Exception {
 146.147 +
 146.148 +        Path fs1Path = getTempPath();
 146.149 +        Path fs2Path = getTempPath();
 146.150 +        Path fs3Path = getTempPath();
 146.151 +
 146.152 +        if (fs1Path.exists())
 146.153 +            fs1Path.delete();
 146.154 +        if (fs2Path.exists())
 146.155 +            fs2Path.delete();
 146.156 +        if (fs3Path.exists())
 146.157 +            fs3Path.delete();
 146.158 +
 146.159 +        // create a new filesystem, copy everything from fs
 146.160 +        Map<String, Object> env = new HashMap<String, Object>();
 146.161 +        env.put("createNew", true);
 146.162 +        FileSystem fs0 = newZipFileSystem(fs1Path, env);
 146.163 +
 146.164 +        final FileSystem fs2 = newZipFileSystem(fs2Path, env);
 146.165 +        final FileSystem fs3 = newZipFileSystem(fs3Path, env);
 146.166 +
 146.167 +        System.out.println("copy src: fs -> fs0...");
 146.168 +        z2zcopy(fs, fs0, "/", 0);   // copy fs -> fs1
 146.169 +        fs0.close();                // dump to file
 146.170 +
 146.171 +        System.out.println("open fs0 as fs1");
 146.172 +        env = new HashMap<String, Object>();
 146.173 +        final FileSystem fs1 = newZipFileSystem(fs1Path, env);
 146.174 +
 146.175 +        System.out.println("listing...");
 146.176 +        final ArrayList<String> files = new ArrayList<>();
 146.177 +        final ArrayList<String> dirs = new ArrayList<>();
 146.178 +        list(fs1.getPath("/"), files, dirs);
 146.179 +
 146.180 +        Thread t0 = new Thread(new Runnable() {
 146.181 +            public void run() {
 146.182 +                List<String> list = new ArrayList<>(dirs);
 146.183 +                Collections.shuffle(list);
 146.184 +                for (String path : list) {
 146.185 +                    try {
 146.186 +                        z2zcopy(fs1, fs2, path, 0);
 146.187 +                    } catch (Exception x) {
 146.188 +                        x.printStackTrace();
 146.189 +                    }
 146.190 +                }
 146.191 +            }
 146.192 +
 146.193 +        });
 146.194 +
 146.195 +        Thread t1 = new Thread(new Runnable() {
 146.196 +            public void run() {
 146.197 +                List<String> list = new ArrayList<>(dirs);
 146.198 +                Collections.shuffle(list);
 146.199 +                for (String path : list) {
 146.200 +                    try {
 146.201 +                        z2zcopy(fs1, fs2, path, 1);
 146.202 +                    } catch (Exception x) {
 146.203 +                        x.printStackTrace();
 146.204 +                    }
 146.205 +                }
 146.206 +            }
 146.207 +
 146.208 +        });
 146.209 +
 146.210 +        Thread t2 = new Thread(new Runnable() {
 146.211 +            public void run() {
 146.212 +                List<String> list = new ArrayList<>(dirs);
 146.213 +                Collections.shuffle(list);
 146.214 +                for (String path : list) {
 146.215 +                    try {
 146.216 +                        z2zcopy(fs1, fs2, path, 2);
 146.217 +                    } catch (Exception x) {
 146.218 +                        x.printStackTrace();
 146.219 +                    }
 146.220 +                }
 146.221 +            }
 146.222 +
 146.223 +        });
 146.224 +
 146.225 +        Thread t3 = new Thread(new Runnable() {
 146.226 +            public void run() {
 146.227 +                List<String> list = new ArrayList<>(files);
 146.228 +                Collections.shuffle(list);
 146.229 +                while (!list.isEmpty()) {
 146.230 +                    Iterator<String> itr = list.iterator();
 146.231 +                    while (itr.hasNext()) {
 146.232 +                        String path = itr.next();
 146.233 +                        try {
 146.234 +                            if (fs2.getPath(path).exists()) {
 146.235 +                                z2zmove(fs2, fs3, path);
 146.236 +                                itr.remove();
 146.237 +                            }
 146.238 +                        } catch (FileAlreadyExistsException x){
 146.239 +                            itr.remove();
 146.240 +                        } catch (Exception x) {
 146.241 +                            x.printStackTrace();
 146.242 +                        }
 146.243 +                    }
 146.244 +                }
 146.245 +            }
 146.246 +
 146.247 +        });
 146.248 +
 146.249 +        System.out.println("copying/removing...");
 146.250 +        t0.start(); t1.start(); t2.start(); t3.start();
 146.251 +        t0.join(); t1.join(); t2.join(); t3.join();
 146.252 +
 146.253 +        System.out.println("closing: fs1, fs2");
 146.254 +        fs1.close();
 146.255 +        fs2.close();
 146.256 +
 146.257 +        int failed = 0;
 146.258 +        System.out.println("checkEqual: fs vs fs3");
 146.259 +        for (String path : files) {
 146.260 +            try {
 146.261 +                checkEqual(fs.getPath(path), fs3.getPath(path));
 146.262 +            } catch (IOException x) {
 146.263 +                //x.printStackTrace();
 146.264 +                failed++;
 146.265 +            }
 146.266 +        }
 146.267 +        System.out.println("closing: fs3");
 146.268 +        fs3.close();
 146.269 +
 146.270 +        System.out.println("opening: fs3 as fs4");
 146.271 +        FileSystem fs4 = newZipFileSystem(fs3Path, env);
 146.272 +
 146.273 +
 146.274 +        ArrayList<String> files2 = new ArrayList<>();
 146.275 +        ArrayList<String> dirs2 = new ArrayList<>();
 146.276 +        list(fs4.getPath("/"), files2, dirs2);
 146.277 +
 146.278 +        System.out.println("checkEqual: fs vs fs4");
 146.279 +        for (String path : files2) {
 146.280 +            checkEqual(fs.getPath(path), fs4.getPath(path));
 146.281 +        }
 146.282 +        System.out.println("walking: fs4");
 146.283 +        walk(fs4.getPath("/"));
 146.284 +        System.out.println("closing: fs4");
 146.285 +        fs4.close();
 146.286 +
 146.287 +        System.out.printf("failed=%d%n", failed);
 146.288 +
 146.289 +        fs1Path.delete();
 146.290 +        fs2Path.delete();
 146.291 +        fs3Path.delete();
 146.292 +    }
 146.293 +
 146.294 +    private static FileSystem newZipFileSystem(Path path, Map<String, ?> env)
 146.295 +        throws IOException
 146.296 +    {
 146.297 +        return FileSystems.newFileSystem(
 146.298 +                   URI.create("zip" +
 146.299 +                               path.toUri().toString().substring(4)),
 146.300 +                   env,
 146.301 +                   null);
 146.302 +    }
 146.303 +
 146.304 +    private static Path getTempPath() throws IOException
 146.305 +    {
 146.306 +        File tmp = File.createTempFile("testzipfs_", "zip");
 146.307 +        tmp.delete();    // we need a clean path, no file
 146.308 +        return tmp.toPath();
 146.309 +    }
 146.310 +
 146.311 +    private static void list(Path path, List<String> files, List<String> dirs )
 146.312 +        throws IOException
 146.313 +    {
 146.314 +        if (Attributes.readBasicFileAttributes(path).isDirectory()) {
 146.315 +            DirectoryStream<Path> ds = path.newDirectoryStream();
 146.316 +            for (Path child : ds)
 146.317 +                list(child, files, dirs);
 146.318 +            ds.close();
 146.319 +            dirs.add(path.toString());
 146.320 +        } else {
 146.321 +            files.add(path.toString());
 146.322 +        }
 146.323 +    }
 146.324 +
 146.325 +    private static void z2zcopy(FileSystem src, FileSystem dst, String path,
 146.326 +                                int method)
 146.327 +        throws IOException
 146.328 +    {
 146.329 +        Path srcPath = src.getPath(path);
 146.330 +        Path dstPath = dst.getPath(path);
 146.331 +
 146.332 +        if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) {
 146.333 +            if (!dstPath.exists()) {
 146.334 +                try {
 146.335 +                    mkdirs(dstPath);
 146.336 +                } catch (FileAlreadyExistsException x) {}
 146.337 +            }
 146.338 +            DirectoryStream<Path> ds = srcPath.newDirectoryStream();
 146.339 +            for (Path child : ds) {
 146.340 +                z2zcopy(src, dst,
 146.341 +                        path + (path.endsWith("/")?"":"/") + child.getName(),
 146.342 +                        method);
 146.343 +            }
 146.344 +            ds.close();
 146.345 +        } else {
 146.346 +            try {
 146.347 +                if (dstPath.exists())
 146.348 +                    return;
 146.349 +                switch (method) {
 146.350 +                case 0:
 146.351 +                    srcPath.copyTo(dstPath);
 146.352 +                    break;
 146.353 +                case 1:
 146.354 +                    chCopy(srcPath, dstPath);
 146.355 +                    break;
 146.356 +                case 2:
 146.357 +                    //fchCopy(srcPath, dstPath);
 146.358 +                    streamCopy(srcPath, dstPath);
 146.359 +                    break;
 146.360 +                }
 146.361 +            } catch (FileAlreadyExistsException x) {}
 146.362 +        }
 146.363 +    }
 146.364 +
 146.365 +    private static void z2zmove(FileSystem src, FileSystem dst, String path)
 146.366 +        throws IOException
 146.367 +    {
 146.368 +        Path srcPath = src.getPath(path);
 146.369 +        Path dstPath = dst.getPath(path);
 146.370 +
 146.371 +        if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) {
 146.372 +            if (!dstPath.exists())
 146.373 +                mkdirs(dstPath);
 146.374 +            DirectoryStream<Path> ds = srcPath.newDirectoryStream();
 146.375 +            for (Path child : ds) {
 146.376 +                z2zmove(src, dst,
 146.377 +                        path + (path.endsWith("/")?"":"/") + child.getName());
 146.378 +            }
 146.379 +            ds.close();
 146.380 +        } else {
 146.381 +            //System.out.println("moving..." + path);
 146.382 +            Path parent = dstPath.getParent();
 146.383 +            if (parent != null && parent.notExists())
 146.384 +                mkdirs(parent);
 146.385 +            srcPath.moveTo(dstPath);
 146.386 +        }
 146.387 +    }
 146.388 +
 146.389 +    private static void walk(Path path) throws IOException
 146.390 +    {
 146.391 +        Files.walkFileTree(
 146.392 +            path,
 146.393 +            new SimpleFileVisitor<Path>() {
 146.394 +                private int indent = 0;
 146.395 +                private void indent() {
 146.396 +                    int n = 0;
 146.397 +                    while (n++ < indent)
 146.398 +                        System.out.printf(" ");
 146.399 +                }
 146.400 +
 146.401 +                @Override
 146.402 +                public FileVisitResult visitFile(Path file,
 146.403 +                                                 BasicFileAttributes attrs)
 146.404 +                {
 146.405 +                    indent();
 146.406 +                    System.out.printf("%s%n", file.getName().toString());
 146.407 +                    return FileVisitResult.CONTINUE;
 146.408 +                }
 146.409 +
 146.410 +                @Override
 146.411 +                public FileVisitResult preVisitDirectory(Path dir,
 146.412 +                                                         BasicFileAttributes attrs)
 146.413 +                {
 146.414 +                    indent();
 146.415 +                    System.out.printf("[%s]%n", dir.toString());
 146.416 +                    indent += 2;
 146.417 +                    return FileVisitResult.CONTINUE;
 146.418 +                }
 146.419 +
 146.420 +                @Override
 146.421 +                public FileVisitResult postVisitDirectory(Path dir,
 146.422 +                                                          IOException ioe)
 146.423 +                    throws IOException
 146.424 +                {
 146.425 +                    indent -= 2;
 146.426 +                    return FileVisitResult.CONTINUE;
 146.427 +                }
 146.428 +        });
 146.429 +    }
 146.430 +
 146.431 +    private static void mkdirs(Path path) throws IOException {
 146.432 +        path = path.toAbsolutePath();
 146.433 +        Path parent = path.getParent();
 146.434 +        if (parent != null) {
 146.435 +            if (parent.notExists())
 146.436 +                mkdirs(parent);
 146.437 +        }
 146.438 +        path.createDirectory();
 146.439 +    }
 146.440 +
 146.441 +    private static void rmdirs(Path path) throws IOException {
 146.442 +        while (path != null && path.getNameCount() != 0) {
 146.443 +            path.delete();
 146.444 +            path = path.getParent();
 146.445 +        }
 146.446 +    }
 146.447 +
 146.448 +    // check the content of two paths are equal
 146.449 +    private static void checkEqual(Path src, Path dst) throws IOException
 146.450 +    {
 146.451 +        //System.out.printf("checking <%s> vs <%s>...%n",
 146.452 +        //                  src.toString(), dst.toString());
 146.453 +
 146.454 +        //streams
 146.455 +        InputStream isSrc = src.newInputStream();
 146.456 +        InputStream isDst = dst.newInputStream();
 146.457 +        byte[] bufSrc = new byte[8192];
 146.458 +        byte[] bufDst = new byte[8192];
 146.459 +
 146.460 +        try {
 146.461 +            int nSrc = 0;
 146.462 +            while ((nSrc = isSrc.read(bufSrc)) != -1) {
 146.463 +                int nDst = 0;
 146.464 +                while (nDst < nSrc) {
 146.465 +                    int n = isDst.read(bufDst, nDst, nSrc - nDst);
 146.466 +                    if (n == -1) {
 146.467 +                        System.out.printf("checking <%s> vs <%s>...%n",
 146.468 +                                          src.toString(), dst.toString());
 146.469 +                        throw new RuntimeException("CHECK FAILED!");
 146.470 +                    }
 146.471 +                    nDst += n;
 146.472 +                }
 146.473 +                while (--nSrc >= 0) {
 146.474 +                    if (bufSrc[nSrc] != bufDst[nSrc]) {
 146.475 +                        System.out.printf("checking <%s> vs <%s>...%n",
 146.476 +                                          src.toString(), dst.toString());
 146.477 +                        throw new RuntimeException("CHECK FAILED!");
 146.478 +                    }
 146.479 +                    nSrc--;
 146.480 +                }
 146.481 +            }
 146.482 +        } finally {
 146.483 +            isSrc.close();
 146.484 +            isDst.close();
 146.485 +        }
 146.486 +
 146.487 +        // channels
 146.488 +        SeekableByteChannel chSrc = src.newByteChannel();
 146.489 +        SeekableByteChannel chDst = dst.newByteChannel();
 146.490 +        if (chSrc.size() != chDst.size()) {
 146.491 +            System.out.printf("src[%s].size=%d, dst[%s].size=%d%n",
 146.492 +                              chSrc.toString(), chSrc.size(),
 146.493 +                              chDst.toString(), chDst.size());
 146.494 +            throw new RuntimeException("CHECK FAILED!");
 146.495 +        }
 146.496 +        ByteBuffer bbSrc = ByteBuffer.allocate(8192);
 146.497 +        ByteBuffer bbDst = ByteBuffer.allocate(8192);
 146.498 +
 146.499 +        try {
 146.500 +            int nSrc = 0;
 146.501 +            while ((nSrc = chSrc.read(bbSrc)) != -1) {
 146.502 +                int nDst = chDst.read(bbDst);
 146.503 +                if (nSrc != nDst) {
 146.504 +                    System.out.printf("checking <%s> vs <%s>...%n",
 146.505 +                                      src.toString(), dst.toString());
 146.506 +                    throw new RuntimeException("CHECK FAILED!");
 146.507 +                }
 146.508 +                while (--nSrc >= 0) {
 146.509 +                    if (bbSrc.get(nSrc) != bbDst.get(nSrc)) {
 146.510 +                        System.out.printf("checking <%s> vs <%s>...%n",
 146.511 +                                          src.toString(), dst.toString());
 146.512 +                        throw new RuntimeException("CHECK FAILED!");
 146.513 +                    }
 146.514 +                    nSrc--;
 146.515 +                }
 146.516 +                bbSrc.flip();
 146.517 +                bbDst.flip();
 146.518 +            }
 146.519 +        } catch (IOException x) {
 146.520 +            x.printStackTrace();
 146.521 +        } finally {
 146.522 +            chSrc.close();
 146.523 +            chDst.close();
 146.524 +        }
 146.525 +    }
 146.526 +
 146.527 +    private static void fchCopy(Path src, Path dst) throws IOException
 146.528 +    {
 146.529 +        Set<OpenOption> read = new HashSet<>();
 146.530 +        read.add(READ);
 146.531 +        Set<OpenOption> openwrite = new HashSet<>();
 146.532 +        openwrite.add(CREATE_NEW);
 146.533 +        openwrite.add(WRITE);
 146.534 +
 146.535 +        FileChannel srcFc = src.getFileSystem()
 146.536 +                               .provider()
 146.537 +                               .newFileChannel(src, read);
 146.538 +        FileChannel dstFc = dst.getFileSystem()
 146.539 +                               .provider()
 146.540 +                               .newFileChannel(dst, openwrite);
 146.541 +
 146.542 +        try {
 146.543 +            ByteBuffer bb = ByteBuffer.allocate(8192);
 146.544 +            while (srcFc.read(bb) >= 0) {
 146.545 +                bb.flip();
 146.546 +                dstFc.write(bb);
 146.547 +                bb.clear();
 146.548 +            }
 146.549 +        } finally {
 146.550 +            srcFc.close();
 146.551 +            dstFc.close();
 146.552 +        }
 146.553 +    }
 146.554 +
 146.555 +    private static void chCopy(Path src, Path dst) throws IOException
 146.556 +    {
 146.557 +        Set<OpenOption> read = new HashSet<>();
 146.558 +        read.add(READ);
 146.559 +        Set<OpenOption> openwrite = new HashSet<>();
 146.560 +        openwrite.add(CREATE_NEW);
 146.561 +        openwrite.add(WRITE);
 146.562 +
 146.563 +        SeekableByteChannel srcCh = src.newByteChannel(read);
 146.564 +        SeekableByteChannel dstCh = dst.newByteChannel(openwrite);
 146.565 +
 146.566 +        try {
 146.567 +            ByteBuffer bb = ByteBuffer.allocate(8192);
 146.568 +            while (srcCh.read(bb) >= 0) {
 146.569 +                bb.flip();
 146.570 +                dstCh.write(bb);
 146.571 +                bb.clear();
 146.572 +            }
 146.573 +        } finally {
 146.574 +            srcCh.close();
 146.575 +            dstCh.close();
 146.576 +        }
 146.577 +    }
 146.578 +
 146.579 +    private static void streamCopy(Path src, Path dst) throws IOException
 146.580 +    {
 146.581 +        InputStream isSrc = src.newInputStream();
 146.582 +        OutputStream osDst = dst.newOutputStream();
 146.583 +        byte[] buf = new byte[8192];
 146.584 +        try {
 146.585 +            int n = 0;
 146.586 +            while ((n = isSrc.read(buf)) != -1) {
 146.587 +                osDst.write(buf, 0, n);
 146.588 +            }
 146.589 +        } finally {
 146.590 +            isSrc.close();
 146.591 +            osDst.close();
 146.592 +        }
 146.593 +    }
 146.594 +
 146.595 +    static void channel(FileSystem fs, Path path)
 146.596 +        throws Exception
 146.597 +    {
 146.598 +        System.out.println("test ByteChannel...");
 146.599 +        SeekableByteChannel sbc = path.newByteChannel();
 146.600 +        Set<OpenOption> read = new HashSet<>();
 146.601 +        read.add(READ);
 146.602 +        System.out.printf("   sbc[0]: pos=%d, size=%d%n", sbc.position(), sbc.size());
 146.603 +        ByteBuffer bb = ByteBuffer.allocate((int)sbc.size());
 146.604 +        int n = sbc.read(bb);
 146.605 +        System.out.printf("   sbc[1]: read=%d, pos=%d, size=%d%n",
 146.606 +                          n, sbc.position(), sbc.size());
 146.607 +        ByteBuffer bb2 = ByteBuffer.allocate((int)sbc.size());
 146.608 +        int N = 120;
 146.609 +        sbc.close();
 146.610 +
 146.611 +        // sbc.position(pos) is not supported in current version
 146.612 +        // try the FileChannel
 146.613 +        sbc = fs.provider().newFileChannel(path, read);
 146.614 +        sbc.position(N);
 146.615 +        System.out.printf("   sbc[2]: pos=%d, size=%d%n",
 146.616 +                          sbc.position(), sbc.size());
 146.617 +        bb2.limit(100);
 146.618 +        n = sbc.read(bb2);
 146.619 +        System.out.printf("   sbc[3]: read=%d, pos=%d, size=%d%n",
 146.620 +                          n, sbc.position(), sbc.size());
 146.621 +        System.out.printf("   sbc[4]: bb[%d]=%d, bb1[0]=%d%n",
 146.622 +                          N, bb.get(N) & 0xff, bb2.get(0) & 0xff);
 146.623 +        sbc.close();
 146.624 +    }
 146.625 +
 146.626 +    // create parents if does not exist
 146.627 +    static Path getPathWithParents(FileSystem fs, String name)
 146.628 +        throws Exception
 146.629 +    {
 146.630 +        Path path = fs.getPath(name);
 146.631 +        Path parent = path.getParent();
 146.632 +        if (parent != null && parent.notExists())
 146.633 +            mkdirs(parent);
 146.634 +        return path;
 146.635 +    }
 146.636 +}
   147.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   147.2 +++ b/test/demo/zipfs/basic.sh	Mon Oct 18 11:25:28 2010 -0400
   147.3 @@ -0,0 +1,73 @@
   147.4 +#
   147.5 +# Copyright (c) 2009, 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.
  147.11 +# 
  147.12 +# This code is distributed in the hope that it will be useful, but WITHOUT
  147.13 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  147.14 +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  147.15 +# version 2 for more details (a copy is included in the LICENSE file that
  147.16 +# accompanied this code).
  147.17 +# 
  147.18 +# You should have received a copy of the GNU General Public License version
  147.19 +# 2 along with this work; if not, write to the Free Software Foundation,
  147.20 +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  147.21 +# 
  147.22 +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  147.23 +# or visit www.oracle.com if you need additional information or have any
  147.24 +# questions.
  147.25 +#
  147.26 +# @test
  147.27 +# @bug 6990846
  147.28 +# @summary Test ZipFileSystem demo
  147.29 +# @build Basic PathOps ZipFSTester
  147.30 +# @run shell basic.sh
  147.31 +
  147.32 +if [ -z "${TESTJAVA}" ]; then
  147.33 +    echo "Test must be run with jtreg"
  147.34 +    exit 0
  147.35 +fi
  147.36 +
  147.37 +ZIPFS="${TESTJAVA}/demo/nio/zipfs/zipfs.jar"
  147.38 +if [ ! -r "${ZIPFS}" ]; then
  147.39 +    echo "${ZIPFS} not found"
  147.40 +    exit 0
  147.41 +fi
  147.42 +
  147.43 +OS=`uname -s`
  147.44 +case "$OS" in
  147.45 +    Windows_* )
  147.46 +        CLASSPATH="${TESTCLASSES};${ZIPFS}"
  147.47 +        ;;
  147.48 +    * )
  147.49 +        CLASSPATH="${TESTCLASSES}:${ZIPFS}"
  147.50 +        ;;
  147.51 +esac
  147.52 +export CLASSPATH
  147.53 +
  147.54 +failures=0
  147.55 +
  147.56 +go() {
  147.57 +    echo ""
  147.58 +    ${TESTJAVA}/bin/java $1 $2 $3 2>&1
  147.59 +    if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
  147.60 +}
  147.61 +
  147.62 +# Run the tests
  147.63 +
  147.64 +go Basic "${ZIPFS}"
  147.65 +go PathOps "${ZIPFS}"
  147.66 +go ZipFSTester "${ZIPFS}"
  147.67 +
  147.68 +#
  147.69 +# Results
  147.70 +#
  147.71 +
  147.72 +if [ $failures -gt 0 ];
  147.73 +then echo "$failures tests failed";
  147.74 +else echo "All tests passed";
  147.75 +fi
  147.76 +exit $failures
   148.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   148.2 +++ b/test/java/awt/Focus/FocusOwnerFrameOnClick/FocusOwnerFrameOnClick.java	Mon Oct 18 11:25:28 2010 -0400
   148.3 @@ -0,0 +1,125 @@
   148.4 +/*
   148.5 + * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
   148.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   148.7 + *
   148.8 + * This code is free software; you can redistribute it and/or modify it
   148.9 + * under the terms of the GNU General Public License version 2 only, as
  148.10 + * published by the Free Software Foundation.  Oracle designates this
  148.11 + * particular file as subject to the "Classpath" exception as provided
  148.12 + * by Oracle in the LICENSE file that accompanied this code.
  148.13 + *
  148.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
  148.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  148.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  148.17 + * version 2 for more details (a copy is included in the LICENSE file that
  148.18 + * accompanied this code).
  148.19 + *
  148.20 + * You should have received a copy of the GNU General Public License version
  148.21 + * 2 along with this work; if not, write to the Free Software Foundation,
  148.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  148.23 + *
  148.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  148.25 + * or visit www.oracle.com if you need additional information or have any
  148.26 + * questions.
  148.27 + */
  148.28 +
  148.29 +/*
  148.30 +  @test      FocusOwnerFrameOnClick.java %W% %E%
  148.31 +  @bug       6886678
  148.32 +  @summary   Tests that clicking an owner frame switches focus from its owned window.
  148.33 +  @author    Anton Tarasov: area=awt.focus
  148.34 +  @library   ../../regtesthelpers
  148.35 +  @build     Util
  148.36 +  @run       main FocusOwnerFrameOnClick
  148.37 +*/
  148.38 +
  148.39 +import java.awt.*;
  148.40 +import java.awt.event.*;
  148.41 +import java.applet.Applet;
  148.42 +import java.util.concurrent.atomic.AtomicBoolean;
  148.43 +import java.lang.reflect.InvocationTargetException;
  148.44 +import test.java.awt.regtesthelpers.Util;
  148.45 +
  148.46 +public class FocusOwnerFrameOnClick extends Applet {
  148.47 +    Robot robot;
  148.48 +    Frame frame = new Frame("Frame");
  148.49 +    Window window = new Window(frame);
  148.50 +    Button fButton = new Button("fButton");
  148.51 +    Button wButton = new Button("wButton");
  148.52 +
  148.53 +    AtomicBoolean focused = new AtomicBoolean(false);
  148.54 +
  148.55 +    public static void main(String[] args) {
  148.56 +        FocusOwnerFrameOnClick app = new FocusOwnerFrameOnClick();
  148.57 +        app.init();
  148.58 +        app.start();
  148.59 +    }
  148.60 +
  148.61 +    public void init() {
  148.62 +        robot = Util.createRobot();
  148.63 +
  148.64 +        frame.setLayout(new FlowLayout());
  148.65 +        frame.setSize(200, 200);
  148.66 +        frame.add(fButton);
  148.67 +
  148.68 +        window.setLocation(300, 0);
  148.69 +        window.add(wButton);
  148.70 +        window.pack();
  148.71 +    }
  148.72 +
  148.73 +    public void start() {
  148.74 +        frame.setVisible(true);
  148.75 +        Util.waitForIdle(robot);
  148.76 +
  148.77 +        window.setVisible(true);
  148.78 +        Util.waitForIdle(robot);
  148.79 +
  148.80 +        if (!wButton.hasFocus()) {
  148.81 +            if (!Util.trackFocusGained(wButton, new Runnable() {
  148.82 +                    public void run() {
  148.83 +                        Util.clickOnComp(wButton, robot);
  148.84 +                    }
  148.85 +                }, 2000, false))
  148.86 +            {
  148.87 +                throw new TestErrorException("wButton didn't gain focus on showing");
  148.88 +            }
  148.89 +        }
  148.90 +
  148.91 +        Runnable clickAction = new Runnable() {
  148.92 +                public void run() {
  148.93 +                    Point loc = fButton.getLocationOnScreen();
  148.94 +                    Dimension dim = fButton.getSize();
  148.95 +
  148.96 +                    robot.mouseMove(loc.x, loc.y + dim.height + 20);
  148.97 +                    robot.delay(50);
  148.98 +                    robot.mousePress(InputEvent.BUTTON1_MASK);
  148.99 +                    robot.delay(50);
 148.100 +                    robot.mouseRelease(InputEvent.BUTTON1_MASK);
 148.101 +                }
 148.102 +            };
 148.103 +
 148.104 +        if (!Util.trackWindowGainedFocus(frame, clickAction, 2000, true)) {
 148.105 +            throw new TestFailedException("The frame wasn't focused on click");
 148.106 +        }
 148.107 +
 148.108 +        System.out.println("Test passed.");
 148.109 +    }
 148.110 +}
 148.111 +
 148.112 +/**
 148.113 + * Thrown when the behavior being verified is found wrong.
 148.114 + */
 148.115 +class TestFailedException extends RuntimeException {
 148.116 +    TestFailedException(String msg) {
 148.117 +        super("Test failed: " + msg);
 148.118 +    }
 148.119 +}
 148.120 +
 148.121 +/**
 148.122 + * Thrown when an error not related to the behavior being verified is encountered.
 148.123 + */
 148.124 +class TestErrorException extends RuntimeException {
 148.125 +    TestErrorException(String msg) {
 148.126 +        super("Unexpected error: " + msg);
 148.127 +    }
 148.128 +}
   149.1 --- a/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java	Tue Oct 12 13:34:59 2010 -0400
   149.2 +++ b/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java	Mon Oct 18 11:25:28 2010 -0400
   149.3 @@ -21,16 +21,15 @@
   149.4      static final int SHIFT = 1;
   149.5      static final int CTRL = 2;
   149.6      static final int ALT = 3;
   149.7 -    static CheckingModifierAdapter adapterTest1;
   149.8 -    static CheckingModifierAdapter adapterTest2;
   149.9 -    static CheckingModifierAdapter adapterTest3;
  149.10 -    static CheckingModifierAdapter adapterTest4;
  149.11 +    static CheckingModifierAdapterExtra adapterTest1;
  149.12 +    static CheckingModifierAdapterExtra adapterTest2;
  149.13 +    static CheckingModifierAdapterExtra adapterTest3;
  149.14 +    static CheckingModifierAdapterExtra adapterTest4;
  149.15  
  149.16      static boolean debug = true; //dump all errors (debug) or throw first(under jtreg) exception
  149.17      static boolean autorun = false; //use robot or manual run
  149.18      static int testModifier = NONE;
  149.19  
  149.20 -    static int [] mouseButtons;
  149.21      static int [] mouseButtonDownMasks;
  149.22  
  149.23      //an arrays representing a modifiersEx of extra mouse buttons while using ALT/CTRL/SHIFT or none of them
  149.24 @@ -39,7 +38,6 @@
  149.25      static int [] modifiersExStandardCTRL;
  149.26      static int [] modifiersExStandardALT;
  149.27  
  149.28 -    //    final static int [] mouseButtons = new int [] {MouseEvent.BUTTON1_MASK, MouseEvent.BUTTON2_MASK, MouseEvent.BUTTON3_MASK};
  149.29      // BUTTON1, 2, 3 press-release.
  149.30      final static int  modifiersStandard = 0; //InputEvent.BUTTON_DOWN_MASK;
  149.31  
  149.32 @@ -56,7 +54,7 @@
  149.33  
  149.34          if (modifiersEx != curStandardExModifiers[index]){
  149.35  //            System.out.println(">>>>>>>>>>>>>>> Pressed. modifiersEx "+modifiersEx +" : "+!= curStandardExModifiers");
  149.36 -            MessageLogger.reportError("Test failed :  Pressed. modifiersEx != curStandardExModifiers");
  149.37 +            MessageLogger.reportError("Test failed :  Pressed. modifiersEx != curStandardExModifiers. Got: " + modifiersEx + " , Expected: " + curStandardExModifiers[index]);
  149.38          }
  149.39  
  149.40       //check event.paramString() output
  149.41 @@ -168,7 +166,7 @@
  149.42          }
  149.43  
  149.44          if (modifiersEx != curStandardExModifiers[index]){
  149.45 -            MessageLogger.reportError("Test failed :  Released. modifiersEx != curStandardExModifiers");
  149.46 +            MessageLogger.reportError("Test failed :  Released. modifiersEx != curStandardExModifiers. Got: " + modifiersEx + " , Expected: " + curStandardExModifiers[index]);
  149.47          }
  149.48  
  149.49       //check event.paramString() output
  149.50 @@ -191,7 +189,7 @@
  149.51          }
  149.52  
  149.53          if (modifiersEx != curStandardExModifiers[index]){
  149.54 -            MessageLogger.reportError("Test failed :  Clicked. modifiersEx != curStandardExModifiers");
  149.55 +            MessageLogger.reportError("Test failed :  Clicked. modifiersEx != curStandardExModifiers. Got: " + modifiersEx + " , Expected: " + curStandardExModifiers[index]);
  149.56          }
  149.57  
  149.58       //check event.paramString() output
  149.59 @@ -275,11 +273,11 @@
  149.60          this.addMouseListener(adapterTest1);
  149.61          robot.delay(1000);
  149.62          robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
  149.63 -        for (int i = 3; i< mouseButtons.length; i++){
  149.64 -            System.out.println("testNONE() => " +mouseButtons[i] );
  149.65 -            robot.mousePress(mouseButtons[i]);
  149.66 +        for (int i = 3; i< mouseButtonDownMasks.length; i++){
  149.67 +            System.out.println("testNONE() => " +mouseButtonDownMasks[i] );
  149.68 +            robot.mousePress(mouseButtonDownMasks[i]);
  149.69              robot.delay(100);
  149.70 -            robot.mouseRelease(mouseButtons[i]);
  149.71 +            robot.mouseRelease(mouseButtonDownMasks[i]);
  149.72          }
  149.73          robot.delay(1000);
  149.74          this.removeMouseListener(adapterTest1);
  149.75 @@ -289,12 +287,12 @@
  149.76          this.addMouseListener(adapterTest2);
  149.77          robot.delay(1000);
  149.78          robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
  149.79 -        for (int i = 3; i< mouseButtons.length; i++){
  149.80 +        for (int i = 3; i< mouseButtonDownMasks.length; i++){
  149.81              robot.keyPress(KeyEvent.VK_SHIFT);
  149.82 -            System.out.println("testSHIFT() => " +mouseButtons[i] );
  149.83 -            robot.mousePress(mouseButtons[i]);
  149.84 +            System.out.println("testSHIFT() => " +mouseButtonDownMasks[i] );
  149.85 +            robot.mousePress(mouseButtonDownMasks[i]);
  149.86              robot.delay(100);
  149.87 -            robot.mouseRelease(mouseButtons[i]);
  149.88 +            robot.mouseRelease(mouseButtonDownMasks[i]);
  149.89              robot.keyRelease(KeyEvent.VK_SHIFT);
  149.90          }
  149.91          robot.delay(1000);
  149.92 @@ -305,12 +303,12 @@
  149.93          this.addMouseListener(adapterTest3);
  149.94          robot.delay(1000);
  149.95          robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
  149.96 -        for (int i = 3; i< mouseButtons.length; i++){
  149.97 +        for (int i = 3; i< mouseButtonDownMasks.length; i++){
  149.98              robot.keyPress(KeyEvent.VK_CONTROL);
  149.99 -            System.out.println("testCTRL() => " +mouseButtons[i] );
 149.100 -            robot.mousePress(mouseButtons[i]);
 149.101 +            System.out.println("testCTRL() => " +mouseButtonDownMasks[i] );
 149.102 +            robot.mousePress(mouseButtonDownMasks[i]);
 149.103              robot.delay(100);
 149.104 -            robot.mouseRelease(mouseButtons[i]);
 149.105 +            robot.mouseRelease(mouseButtonDownMasks[i]);
 149.106              robot.keyRelease(KeyEvent.VK_CONTROL);
 149.107          }
 149.108          robot.delay(1000);
 149.109 @@ -321,12 +319,12 @@
 149.110          this.addMouseListener(adapterTest4);
 149.111          robot.delay(1000);
 149.112          robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
 149.113 -        for (int i = 3; i< mouseButtons.length; i++){
 149.114 +        for (int i = 3; i< mouseButtonDownMasks.length; i++){
 149.115              robot.keyPress(KeyEvent.VK_ALT);
 149.116 -            System.out.println("testALT() => " +mouseButtons[i] );
 149.117 -            robot.mousePress(mouseButtons[i]);
 149.118 +            System.out.println("testALT() => " +mouseButtonDownMasks[i] );
 149.119 +            robot.mousePress(mouseButtonDownMasks[i]);
 149.120              robot.delay(100);
 149.121 -            robot.mouseRelease(mouseButtons[i]);
 149.122 +            robot.mouseRelease(mouseButtonDownMasks[i]);
 149.123              robot.keyRelease(KeyEvent.VK_ALT);
 149.124          }
 149.125          robot.delay(1000);
 149.126 @@ -368,52 +366,52 @@
 149.127      }
 149.128  
 149.129      public static void initAdapters(){
 149.130 -        adapterTest1 = new CheckingModifierAdapter(NONE);
 149.131 -        adapterTest2 = new CheckingModifierAdapter(SHIFT);
 149.132 -        adapterTest3 = new CheckingModifierAdapter(CTRL);
 149.133 -        adapterTest4 = new CheckingModifierAdapter(ALT);
 149.134 +        adapterTest1 = new CheckingModifierAdapterExtra(NONE);
 149.135 +        adapterTest2 = new CheckingModifierAdapterExtra(SHIFT);
 149.136 +        adapterTest3 = new CheckingModifierAdapterExtra(CTRL);
 149.137 +        adapterTest4 = new CheckingModifierAdapterExtra(ALT);
 149.138      }
 149.139  
 149.140      public static void initVars(){
 149.141 -        int [] tmp = new int [MouseInfo.getNumberOfButtons()];
 149.142 -        for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
 149.143 -            tmp[i] = InputEvent.getMaskForButton(i+1);
 149.144 -            //            System.out.println("TEST: "+tmp[i]);
 149.145 +        //Init the array of the mouse button masks. It will be used for generating mouse events.
 149.146 +        mouseButtonDownMasks = new int [MouseInfo.getNumberOfButtons()];
 149.147 +        for (int i = 0; i < mouseButtonDownMasks.length; i++){
 149.148 +            mouseButtonDownMasks[i] = InputEvent.getMaskForButton(i+1);
 149.149 +            System.out.println("MouseArray [i] == "+mouseButtonDownMasks[i]);
 149.150          }
 149.151  
 149.152 -        mouseButtons = Arrays.copyOf(tmp, tmp.length);
 149.153 -
 149.154 -        for (int i = 0; i < mouseButtons.length; i++){
 149.155 -            System.out.println("MouseArray [i] == "+mouseButtons[i]);
 149.156 -        }
 149.157 -
 149.158 -        mouseButtonDownMasks = Arrays.copyOf(tmp, tmp.length);
 149.159 -
 149.160          // So we need to get the number of extra buttons on the mouse:  "MouseInfo.getNumberOfButtons() - 3"
 149.161          // and multyply on 3 because each button will generate three events : PRESS, RELEASE and CLICK.
 149.162 -        tmp = new int [(MouseInfo.getNumberOfButtons()-3)*3];
 149.163 +        int [] tmp = new int [(MouseInfo.getNumberOfButtons()-3)*3];
 149.164 +
 149.165 +        //Fill array of expected results for the case when mouse buttons are only used (no-modifier keys)
 149.166          Arrays.fill(tmp, 0);
 149.167 -
 149.168          for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
 149.169              tmp[i] = mouseButtonDownMasks[j];
 149.170          }
 149.171          modifiersExStandard = Arrays.copyOf(tmp, tmp.length);
 149.172  
 149.173 +        //Fill array of expected results for the case when mouse buttons are only used with SHIFT modifier key
 149.174          Arrays.fill(tmp, InputEvent.SHIFT_DOWN_MASK);
 149.175 -        for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){
 149.176 -            tmp[i] = tmp[j] | mouseButtonDownMasks[j];
 149.177 +        for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
 149.178 +            System.out.println("modifiersExStandardSHIFT FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]);
 149.179 +            tmp[i] = tmp[i] | mouseButtonDownMasks[j];
 149.180          }
 149.181          modifiersExStandardSHIFT = Arrays.copyOf(tmp, tmp.length);
 149.182  
 149.183 +        //Fill array of expected results for the case when mouse buttons are only used with CTRL modifier key
 149.184          Arrays.fill(tmp, InputEvent.CTRL_DOWN_MASK);
 149.185 -        for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){
 149.186 -            tmp[i] = tmp[j] | mouseButtonDownMasks[j];
 149.187 +        for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
 149.188 +            System.out.println("modifiersExStandardCTRL FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]);
 149.189 +            tmp[i] = tmp[i] | mouseButtonDownMasks[j];
 149.190          }
 149.191          modifiersExStandardCTRL = Arrays.copyOf(tmp, tmp.length);
 149.192  
 149.193 +        //Fill array of expected results for the case when mouse buttons are only used with ALT modifier key
 149.194          Arrays.fill(tmp, InputEvent.ALT_DOWN_MASK);
 149.195 -        for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){
 149.196 -            tmp[i] = tmp[j] | mouseButtonDownMasks[j];
 149.197 +        for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
 149.198 +            System.out.println("modifiersExStandardALT FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]);
 149.199 +            tmp[i] = tmp[i] | mouseButtonDownMasks[j];
 149.200          }
 149.201          modifiersExStandardALT = Arrays.copyOf(tmp, tmp.length);
 149.202      }
 149.203 @@ -436,9 +434,9 @@
 149.204  /* A class that invoke appropriate verification
 149.205   * routine with current modifier.
 149.206   */
 149.207 -class CheckingModifierAdapter extends MouseAdapter{
 149.208 +class CheckingModifierAdapterExtra extends MouseAdapter{
 149.209      int modifier;
 149.210 -    public CheckingModifierAdapter(int modifier){
 149.211 +    public CheckingModifierAdapterExtra(int modifier){
 149.212          this.modifier = modifier;
 149.213      }
 149.214  
   150.1 --- a/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java	Tue Oct 12 13:34:59 2010 -0400
   150.2 +++ b/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java	Mon Oct 18 11:25:28 2010 -0400
   150.3 @@ -90,7 +90,7 @@
   150.4          int [] buttonMasks = new int[MouseInfo.getNumberOfButtons()]; // = InputEvent.getButtonDownMasks();
   150.5          for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
   150.6              buttonMasks[i] = InputEvent.getMaskForButton(i+1);
   150.7 -            System.out.println("TEST: "+buttonMasks[i]);
   150.8 +            System.out.println("TEST: buttonMasks["+ i +"] = " + buttonMasks[i]);
   150.9          }
  150.10  
  150.11          for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
   151.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   151.2 +++ b/test/java/awt/image/GetSamplesTest.java	Mon Oct 18 11:25:28 2010 -0400
   151.3 @@ -0,0 +1,121 @@
   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     6735275
  151.30 + * @summary Test verifies that SampleModel.getSamples() throws an appropriate
  151.31 + *           exception if coordinates are not in bounds.
  151.32 + *
  151.33 + * @run     main GetSamplesTest
  151.34 + */
  151.35 +
  151.36 +import java.awt.image.BandedSampleModel;
  151.37 +import java.awt.image.ComponentSampleModel;
  151.38 +import java.awt.image.DataBuffer;
  151.39 +import java.awt.image.MultiPixelPackedSampleModel;
  151.40 +import java.awt.image.PixelInterleavedSampleModel;
  151.41 +import java.awt.image.SampleModel;
  151.42 +import java.awt.image.SinglePixelPackedSampleModel;
  151.43 +import java.util.Vector;
  151.44 +
  151.45 +public class GetSamplesTest {
  151.46 +
  151.47 +    public static int width = 100;
  151.48 +    public static int height = 100;
  151.49 +    public static int dataType = DataBuffer.TYPE_BYTE;
  151.50 +    public static int numBands = 4;
  151.51 +
  151.52 +    public static void main(String[] args) {
  151.53 +        Vector<Class<? extends SampleModel>> classes = new Vector<Class<? extends SampleModel>>();
  151.54 +
  151.55 +        classes.add(ComponentSampleModel.class);
  151.56 +        classes.add(MultiPixelPackedSampleModel.class);
  151.57 +        classes.add(SinglePixelPackedSampleModel.class);
  151.58 +        classes.add(BandedSampleModel.class);
  151.59 +        classes.add(PixelInterleavedSampleModel.class);
  151.60 +
  151.61 +        for (Class<? extends SampleModel> c : classes) {
  151.62 +            doTest(c);
  151.63 +        }
  151.64 +    }
  151.65 +    private static void doTest(Class<? extends SampleModel> c) {
  151.66 +        System.out.println("Test for: " + c.getName());
  151.67 +        SampleModel sm = createSampleModel(c);
  151.68 +
  151.69 +        DataBuffer db = sm.createDataBuffer();
  151.70 +
  151.71 +        int[] iArray = new int[ width * height + numBands];
  151.72 +        float[] fArray = new float[ width * height + numBands];
  151.73 +        double[] dArray = new double[ width * height + numBands];
  151.74 +
  151.75 +        boolean iOk = false;
  151.76 +        boolean fOk = false;
  151.77 +        boolean dOk = false;
  151.78 +
  151.79 +        try {
  151.80 +            sm.getSamples(Integer.MAX_VALUE, 0, 1, 1, 0, iArray, db);
  151.81 +        } catch (ArrayIndexOutOfBoundsException e) {
  151.82 +            System.out.println(e.getMessage());
  151.83 +            iOk = true;
  151.84 +        }
  151.85 +
  151.86 +        try {
  151.87 +            sm.getSamples(Integer.MAX_VALUE, 0, 1, 1, 0, fArray, db);
  151.88 +        } catch (ArrayIndexOutOfBoundsException e) {
  151.89 +            System.out.println(e.getMessage());
  151.90 +            fOk = true;
  151.91 +        }
  151.92 +
  151.93 +        try {
  151.94 +            sm.getSamples(0, Integer.MAX_VALUE, 1, 1, 0, dArray, db);
  151.95 +        } catch (ArrayIndexOutOfBoundsException e) {
  151.96 +            System.out.println(e.getMessage());
  151.97 +            dOk = true;
  151.98 +        }
  151.99 +        if (!iOk || !fOk || !dOk) {
 151.100 +            throw new RuntimeException("Test for " + c.getSimpleName() +
 151.101 +                    " failed: iOk=" + iOk + "; fOk=" + fOk + "; dOk=" + dOk);
 151.102 +        }
 151.103 +    }
 151.104 +
 151.105 +    private static SampleModel createSampleModel(Class<? extends SampleModel> cls) {
 151.106 +        SampleModel res = null;
 151.107 +
 151.108 +        if (cls == ComponentSampleModel.class) {
 151.109 +            res = new ComponentSampleModel(dataType, width, height, 4, width * 4, new int[] { 0, 1, 2, 3 } );
 151.110 +        } else if (cls == MultiPixelPackedSampleModel.class) {
 151.111 +            res = new MultiPixelPackedSampleModel(dataType, width, height, 4);
 151.112 +        } else if (cls == SinglePixelPackedSampleModel.class) {
 151.113 +            res = new SinglePixelPackedSampleModel(dataType, width, height,
 151.114 +                    new int[]{ 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff });
 151.115 +        } else if (cls == BandedSampleModel.class) {
 151.116 +            res = new BandedSampleModel(dataType, width, height, numBands);
 151.117 +        } else if (cls == PixelInterleavedSampleModel.class) {
 151.118 +            res = new PixelInterleavedSampleModel(dataType, width, height, 4, width * 4, new int[] { 0, 1, 2, 3 });
 151.119 +        } else {
 151.120 +            throw new RuntimeException("Unknown class " + cls);
 151.121 +        }
 151.122 +        return res;
 151.123 +    }
 151.124 +}
   152.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   152.2 +++ b/test/java/beans/Introspector/6976577/Test6976577.java	Mon Oct 18 11:25:28 2010 -0400
   152.3 @@ -0,0 +1,71 @@
   152.4 +/*
   152.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
   152.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   152.7 + *
   152.8 + * This code is free software; you can redistribute it and/or modify it
   152.9 + * under the terms of the GNU General Public License version 2 only, as
  152.10 + * published by the Free Software Foundation.
  152.11 + *
  152.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  152.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  152.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  152.15 + * version 2 for more details (a copy is included in the LICENSE file that
  152.16 + * accompanied this code).
  152.17 + *
  152.18 + * You should have received a copy of the GNU General Public License version
  152.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  152.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  152.21 + *
  152.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  152.23 + * or visit www.oracle.com if you need additional information or have any
  152.24 + * questions.
  152.25 + */
  152.26 +
  152.27 +/*
  152.28 + * @test
  152.29 + * @bug 6976577
  152.30 + * @summary Tests public methods in non-public beans
  152.31 + * @author Sergey Malenkov
  152.32 + */
  152.33 +
  152.34 +import test.Accessor;
  152.35 +
  152.36 +import java.beans.EventSetDescriptor;
  152.37 +import java.beans.IndexedPropertyDescriptor;
  152.38 +import java.beans.PropertyDescriptor;
  152.39 +import java.lang.reflect.Method;
  152.40 +
  152.41 +public class Test6976577 {
  152.42 +
  152.43 +    public static void main(String[] args) throws Exception {
  152.44 +        Class<?> bt = Accessor.getBeanType();
  152.45 +        Class<?> lt = Accessor.getListenerType();
  152.46 +
  152.47 +        // test PropertyDescriptor
  152.48 +        PropertyDescriptor pd = new PropertyDescriptor("boolean", bt);
  152.49 +        test(pd.getReadMethod());
  152.50 +        test(pd.getWriteMethod());
  152.51 +
  152.52 +        // test IndexedPropertyDescriptor
  152.53 +        IndexedPropertyDescriptor ipd = new IndexedPropertyDescriptor("indexed", bt);
  152.54 +        test(ipd.getReadMethod());
  152.55 +        test(ipd.getWriteMethod());
  152.56 +        test(ipd.getIndexedReadMethod());
  152.57 +        test(ipd.getIndexedWriteMethod());
  152.58 +
  152.59 +        // test EventSetDescriptor
  152.60 +        EventSetDescriptor esd = new EventSetDescriptor(bt, "test", lt, "process");
  152.61 +        test(esd.getAddListenerMethod());
  152.62 +        test(esd.getRemoveListenerMethod());
  152.63 +        test(esd.getGetListenerMethod());
  152.64 +        test(esd.getListenerMethods());
  152.65 +    }
  152.66 +
  152.67 +    private static void test(Method... methods) {
  152.68 +        for (Method method : methods) {
  152.69 +            if (method == null) {
  152.70 +                throw new Error("public method is not found");
  152.71 +            }
  152.72 +        }
  152.73 +    }
  152.74 +}
   153.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   153.2 +++ b/test/java/beans/Introspector/6976577/test/Accessor.java	Mon Oct 18 11:25:28 2010 -0400
   153.3 @@ -0,0 +1,81 @@
   153.4 +package test;
   153.5 +
   153.6 +import java.beans.PropertyChangeListener;
   153.7 +import java.beans.PropertyChangeSupport;
   153.8 +import java.util.EventListener;
   153.9 +import java.util.TooManyListenersException;
  153.10 +
  153.11 +public class Accessor {
  153.12 +
  153.13 +    public static Class<?> getBeanType() {
  153.14 +        return Bean.class;
  153.15 +    }
  153.16 +
  153.17 +    public static Class<?> getListenerType() {
  153.18 +        return TestListener.class;
  153.19 +    }
  153.20 +}
  153.21 +
  153.22 +interface TestEvent {
  153.23 +}
  153.24 +
  153.25 +interface TestListener extends EventListener {
  153.26 +    void process(TestEvent event);
  153.27 +}
  153.28 +
  153.29 +class Bean {
  153.30 +
  153.31 +    private boolean b;
  153.32 +    private int[] indexed;
  153.33 +    private TestListener listener;
  153.34 +    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
  153.35 +
  153.36 +    public void addPropertyChangeListener(PropertyChangeListener listener) {
  153.37 +        this.pcs.addPropertyChangeListener(listener);
  153.38 +    }
  153.39 +
  153.40 +    public void addTestListener(TestListener listener) throws TooManyListenersException {
  153.41 +        if (listener != null) {
  153.42 +            if (this.listener != null) {
  153.43 +                throw new TooManyListenersException();
  153.44 +            }
  153.45 +            this.listener = listener;
  153.46 +        }
  153.47 +    }
  153.48 +
  153.49 +    public void removeTestListener(TestListener listener) {
  153.50 +        if (this.listener == listener) {
  153.51 +            this.listener = null;
  153.52 +        }
  153.53 +    }
  153.54 +
  153.55 +    public TestListener[] getTestListeners() {
  153.56 +        return (this.listener != null)
  153.57 +                ? new TestListener[] { this.listener }
  153.58 +                : new TestListener[0];
  153.59 +    }
  153.60 +
  153.61 +    public boolean isBoolean() {
  153.62 +        return this.b;
  153.63 +    }
  153.64 +
  153.65 +    public void setBoolean(boolean b) {
  153.66 +        this.b = b;
  153.67 +    }
  153.68 +
  153.69 +    public int[] getIndexed() {
  153.70 +        return this.indexed;
  153.71 +    }
  153.72 +
  153.73 +    public void setIndexed(int[] values) {
  153.74 +        this.indexed = values;
  153.75 +    }
  153.76 +
  153.77 +    public int getIndexed(int index) {
  153.78 +        return this.indexed[index];
  153.79 +    }
  153.80 +
  153.81 +    public void setIndexed(int index, int value) {
  153.82 +        this.indexed[index] = value;
  153.83 +    }
  153.84 +}
   154.1 --- a/test/java/lang/ProcessBuilder/Basic.java	Tue Oct 12 13:34:59 2010 -0400
   154.2 +++ b/test/java/lang/ProcessBuilder/Basic.java	Mon Oct 18 11:25:28 2010 -0400
   154.3 @@ -1825,6 +1825,64 @@
   154.4          } catch (Throwable t) { unexpected(t); }
   154.5  
   154.6          //----------------------------------------------------------------
   154.7 +        // Check that subprocesses which create subprocesses of their
   154.8 +        // own do not cause parent to hang waiting for file
   154.9 +        // descriptors to be closed.
  154.10 +        //----------------------------------------------------------------
  154.11 +        try {
  154.12 +            if (Unix.is()
  154.13 +                && new File("/bin/bash").exists()
  154.14 +                && new File("/bin/sleep").exists()) {
  154.15 +                final String[] cmd = { "/bin/bash", "-c", "(/bin/sleep 6666)" };
  154.16 +                final ProcessBuilder pb = new ProcessBuilder(cmd);
  154.17 +                final Process p = pb.start();
  154.18 +                final InputStream stdout = p.getInputStream();
  154.19 +                final InputStream stderr = p.getErrorStream();
  154.20 +                final OutputStream stdin = p.getOutputStream();
  154.21 +                final Thread reader = new Thread() {
  154.22 +                    public void run() {
  154.23 +                        try { stdout.read(); }
  154.24 +                        catch (IOException e) {
  154.25 +                            // e.printStackTrace();
  154.26 +                            if (EnglishUnix.is() &&
  154.27 +                                ! (e.getMessage().matches(".*Bad file descriptor.*")))
  154.28 +                                unexpected(e);
  154.29 +                        }
  154.30 +                        catch (Throwable t) { unexpected(t); }}};
  154.31 +                reader.setDaemon(true);
  154.32 +                reader.start();
  154.33 +                Thread.sleep(100);
  154.34 +                p.destroy();
  154.35 +                // Subprocess is now dead, but file descriptors remain open.
  154.36 +                check(p.waitFor() != 0);
  154.37 +                check(p.exitValue() != 0);
  154.38 +                stdout.close();
  154.39 +                stderr.close();
  154.40 +                stdin.close();
  154.41 +                //----------------------------------------------------------
  154.42 +                // There remain unsolved issues with asynchronous close.
  154.43 +                // Here's a highly non-portable experiment to demonstrate:
  154.44 +                //----------------------------------------------------------
  154.45 +                if (Boolean.getBoolean("wakeupJeff!")) {
  154.46 +                    System.out.println("wakeupJeff!");
  154.47 +                    // Initialize signal handler for INTERRUPT_SIGNAL.
  154.48 +                    new FileInputStream("/bin/sleep").getChannel().close();
  154.49 +                    // Send INTERRUPT_SIGNAL to every thread in this java.
  154.50 +                    String[] wakeupJeff = {
  154.51 +                        "/bin/bash", "-c",
  154.52 +                        "/bin/ps --noheaders -Lfp $PPID | " +
  154.53 +                        "/usr/bin/perl -nale 'print $F[3]' | " +
  154.54 +                        // INTERRUPT_SIGNAL == 62 on my machine du jour.
  154.55 +                        "/usr/bin/xargs kill -62"
  154.56 +                    };
  154.57 +                    new ProcessBuilder(wakeupJeff).start().waitFor();
  154.58 +                    // If wakeupJeff worked, reader probably got EBADF.
  154.59 +                    reader.join();
  154.60 +                }
  154.61 +            }
  154.62 +        } catch (Throwable t) { unexpected(t); }
  154.63 +
  154.64 +        //----------------------------------------------------------------
  154.65          // Attempt to start process with insufficient permissions fails.
  154.66          //----------------------------------------------------------------
  154.67          try {
   155.1 --- a/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java	Tue Oct 12 13:34:59 2010 -0400
   155.2 +++ b/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java	Mon Oct 18 11:25:28 2010 -0400
   155.3 @@ -29,7 +29,9 @@
   155.4  
   155.5  import java.nio.channels.*;
   155.6  import java.net.*;
   155.7 +import static java.net.StandardSocketOption.*;
   155.8  import java.io.IOException;
   155.9 +import java.util.Set;
  155.10  import java.util.concurrent.ExecutionException;
  155.11  import java.util.concurrent.Future;
  155.12  import java.util.concurrent.atomic.AtomicReference;
  155.13 @@ -39,6 +41,7 @@
  155.14      public static void main(String[] args) throws Exception {
  155.15          testBind();
  155.16          testAccept();
  155.17 +        testSocketOptions();
  155.18      }
  155.19  
  155.20      static void testBind() throws Exception {
  155.21 @@ -131,4 +134,39 @@
  155.22          }
  155.23  
  155.24      }
  155.25 +
  155.26 +    static void testSocketOptions() throws Exception {
  155.27 +        System.out.println("-- socket options --");
  155.28 +        AsynchronousServerSocketChannel ch = AsynchronousServerSocketChannel.open();
  155.29 +        try {
  155.30 +            // check supported options
  155.31 +            Set<SocketOption<?>> options = ch.supportedOptions();
  155.32 +            if (!options.contains(SO_REUSEADDR))
  155.33 +                throw new RuntimeException("SO_REUSEADDR should be supported");
  155.34 +            if (!options.contains(SO_RCVBUF))
  155.35 +                throw new RuntimeException("SO_RCVBUF should be supported");
  155.36 +
  155.37 +            // allowed to change when not bound
  155.38 +            ch.setOption(SO_RCVBUF, 256*1024);     // can't check
  155.39 +            int before = ch.getOption(SO_RCVBUF);
  155.40 +            int after = ch.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
  155.41 +            if (after < before)
  155.42 +                 throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
  155.43 +            ch.setOption(SO_REUSEADDR, true);
  155.44 +            checkOption(ch, SO_REUSEADDR, true);
  155.45 +            ch.setOption(SO_REUSEADDR, false);
  155.46 +            checkOption(ch, SO_REUSEADDR, false);
  155.47 +        } finally {
  155.48 +            ch.close();
  155.49 +        }
  155.50 +    }
  155.51 +
  155.52 +    static void checkOption(AsynchronousServerSocketChannel ch,
  155.53 +                            SocketOption name, Object expectedValue)
  155.54 +        throws IOException
  155.55 +    {
  155.56 +        Object value = ch.getOption(name);
  155.57 +        if (!value.equals(expectedValue))
  155.58 +            throw new RuntimeException("value not as expected");
  155.59 +    }
  155.60  }
   156.1 --- a/test/java/nio/channels/AsynchronousSocketChannel/Basic.java	Tue Oct 12 13:34:59 2010 -0400
   156.2 +++ b/test/java/nio/channels/AsynchronousSocketChannel/Basic.java	Mon Oct 18 11:25:28 2010 -0400
   156.3 @@ -121,8 +121,20 @@
   156.4          AsynchronousSocketChannel ch = AsynchronousSocketChannel.open()
   156.5              .setOption(SO_RCVBUF, 128*1024)
   156.6              .setOption(SO_SNDBUF, 128*1024)
   156.7 -            .setOption(SO_REUSEADDR, true)
   156.8 -            .bind(new InetSocketAddress(0));
   156.9 +            .setOption(SO_REUSEADDR, true);
  156.10 +
  156.11 +        // check SO_SNDBUF/SO_RCVBUF limits
  156.12 +        int before, after;
  156.13 +        before = ch.getOption(SO_SNDBUF);
  156.14 +        after = ch.setOption(SO_SNDBUF, Integer.MAX_VALUE).getOption(SO_SNDBUF);
  156.15 +        if (after < before)
  156.16 +            throw new RuntimeException("setOption caused SO_SNDBUF to decrease");
  156.17 +        before = ch.getOption(SO_RCVBUF);
  156.18 +        after = ch.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
  156.19 +        if (after < before)
  156.20 +            throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
  156.21 +
  156.22 +        ch.bind(new InetSocketAddress(0));
  156.23  
  156.24          // default values
  156.25          if ((Boolean)ch.getOption(SO_KEEPALIVE))
   157.1 --- a/test/java/nio/channels/DatagramChannel/SocketOptionTests.java	Tue Oct 12 13:34:59 2010 -0400
   157.2 +++ b/test/java/nio/channels/DatagramChannel/SocketOptionTests.java	Mon Oct 18 11:25:28 2010 -0400
   157.3 @@ -68,8 +68,17 @@
   157.4          checkOption(dc, SO_BROADCAST, true);
   157.5          dc.setOption(SO_BROADCAST, false);
   157.6          checkOption(dc, SO_BROADCAST, false);
   157.7 -        dc.setOption(SO_SNDBUF, 16*1024);       // can't check
   157.8 -        dc.setOption(SO_RCVBUF, 16*1024);       // can't check
   157.9 +        dc.setOption(SO_SNDBUF, 128*1024);       // can't check
  157.10 +        dc.setOption(SO_RCVBUF, 128*1024);       // can't check
  157.11 +        int before, after;
  157.12 +        before = dc.getOption(SO_SNDBUF);
  157.13 +        after = dc.setOption(SO_SNDBUF, Integer.MAX_VALUE).getOption(SO_SNDBUF);
  157.14 +        if (after < before)
  157.15 +            throw new RuntimeException("setOption caused SO_SNDBUF to decrease");
  157.16 +        before = dc.getOption(SO_RCVBUF);
  157.17 +        after = dc.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
  157.18 +        if (after < before)
  157.19 +            throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
  157.20          dc.setOption(SO_REUSEADDR, true);
  157.21          checkOption(dc, SO_REUSEADDR, true);
  157.22          dc.setOption(SO_REUSEADDR, false);
   158.1 --- a/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java	Tue Oct 12 13:34:59 2010 -0400
   158.2 +++ b/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java	Mon Oct 18 11:25:28 2010 -0400
   158.3 @@ -56,6 +56,10 @@
   158.4  
   158.5          // allowed to change when not bound
   158.6          ssc.setOption(SO_RCVBUF, 256*1024);     // can't check
   158.7 +        int before = ssc.getOption(SO_RCVBUF);
   158.8 +        int after = ssc.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
   158.9 +        if (after < before)
  158.10 +            throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
  158.11          ssc.setOption(SO_REUSEADDR, true);
  158.12          checkOption(ssc, SO_REUSEADDR, true);
  158.13          ssc.setOption(SO_REUSEADDR, false);
   159.1 --- a/test/java/nio/channels/SocketChannel/SocketOptionTests.java	Tue Oct 12 13:34:59 2010 -0400
   159.2 +++ b/test/java/nio/channels/SocketChannel/SocketOptionTests.java	Mon Oct 18 11:25:28 2010 -0400
   159.3 @@ -70,6 +70,15 @@
   159.4          checkOption(sc, SO_KEEPALIVE, false);
   159.5          sc.setOption(SO_SNDBUF, 128*1024);      // can't check
   159.6          sc.setOption(SO_RCVBUF, 256*1024);      // can't check
   159.7 +        int before, after;
   159.8 +        before = sc.getOption(SO_SNDBUF);
   159.9 +        after = sc.setOption(SO_SNDBUF, Integer.MAX_VALUE).getOption(SO_SNDBUF);
  159.10 +        if (after < before)
  159.11 +            throw new RuntimeException("setOption caused SO_SNDBUF to decrease");
  159.12 +        before = sc.getOption(SO_RCVBUF);
  159.13 +        after = sc.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
  159.14 +        if (after < before)
  159.15 +            throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
  159.16          sc.setOption(SO_REUSEADDR, true);
  159.17          checkOption(sc, SO_REUSEADDR, true);
  159.18          sc.setOption(SO_REUSEADDR, false);
   160.1 --- a/test/java/nio/file/FileStore/Basic.java	Tue Oct 12 13:34:59 2010 -0400
   160.2 +++ b/test/java/nio/file/FileStore/Basic.java	Mon Oct 18 11:25:28 2010 -0400
   160.3 @@ -22,7 +22,7 @@
   160.4   */
   160.5  
   160.6  /* @test
   160.7 - * @bug 4313887 6873621
   160.8 + * @bug 4313887 6873621 6979526
   160.9   * @summary Unit test for java.nio.file.FileStore
  160.10   * @library ..
  160.11   */
   161.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   161.2 +++ b/test/java/nio/file/Files/MaxDepth.java	Mon Oct 18 11:25:28 2010 -0400
   161.3 @@ -0,0 +1,67 @@
   161.4 +/*
   161.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
   161.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   161.7 + *
   161.8 + * This code is free software; you can redistribute it and/or modify it
   161.9 + * under the terms of the GNU General Public License version 2 only, as
  161.10 + * published by the Free Software Foundation.
  161.11 + *
  161.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  161.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  161.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  161.15 + * version 2 for more details (a copy is included in the LICENSE file that
  161.16 + * accompanied this code).
  161.17 + *
  161.18 + * You should have received a copy of the GNU General Public License version
  161.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  161.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  161.21 + *
  161.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  161.23 + * or visit www.oracle.com if you need additional information or have any
  161.24 + * questions.
  161.25 + */
  161.26 +
  161.27 +import java.nio.file.*;
  161.28 +import java.nio.file.attribute.*;
  161.29 +import java.io.IOException;
  161.30 +import java.util.*;
  161.31 +
  161.32 +/**
  161.33 + * Unit test for Files.walkFileTree to test maxDepth parameter
  161.34 + */
  161.35 +
  161.36 +public class MaxDepth {
  161.37 +    public static void main(String[] args) throws Exception {
  161.38 +        final Path top = Paths.get(args[0]);
  161.39 +
  161.40 +        for (int i=0; i<5; i++) {
  161.41 +            Set<FileVisitOption> opts = Collections.emptySet();
  161.42 +            final int maxDepth = i;
  161.43 +            Files.walkFileTree(top, opts, maxDepth, new SimpleFileVisitor<Path>() {
  161.44 +                // compute depth based on relative path to top directory
  161.45 +                private int depth(Path file) {
  161.46 +                    Path rp = file.relativize(top);
  161.47 +                    return (rp == null) ? 0 : rp.getNameCount();
  161.48 +                }
  161.49 +
  161.50 +                @Override
  161.51 +                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
  161.52 +                    int d = depth(dir);
  161.53 +                    if (d == maxDepth)
  161.54 +                        throw new RuntimeException("Should not open directories at maxDepth");
  161.55 +                    if (d > maxDepth)
  161.56 +                        throw new RuntimeException("Too deep");
  161.57 +                    return FileVisitResult.CONTINUE;
  161.58 +                }
  161.59 +
  161.60 +                @Override
  161.61 +                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
  161.62 +                    int d = depth(file);
  161.63 +                    if (d > maxDepth)
  161.64 +                        throw new RuntimeException("Too deep");
  161.65 +                    return FileVisitResult.CONTINUE;
  161.66 +                }
  161.67 +            });
  161.68 +        }
  161.69 +    }
  161.70 +}
   162.1 --- a/test/java/nio/file/Files/Misc.java	Tue Oct 12 13:34:59 2010 -0400
   162.2 +++ b/test/java/nio/file/Files/Misc.java	Mon Oct 18 11:25:28 2010 -0400
   162.3 @@ -30,6 +30,7 @@
   162.4  
   162.5  import java.nio.file.*;
   162.6  import java.nio.file.attribute.Attributes;
   162.7 +import java.nio.file.attribute.BasicFileAttributes;
   162.8  import java.io.IOException;
   162.9  import java.util.*;
  162.10  
  162.11 @@ -117,25 +118,25 @@
  162.12  
  162.13          SimpleFileVisitor<Path> visitor = new SimpleFileVisitor<Path>() { };
  162.14          boolean ranTheGauntlet = false;
  162.15 -        try { visitor.preVisitDirectory(null);
  162.16 +        BasicFileAttributes attrs = Attributes.readBasicFileAttributes(Paths.get("."));
  162.17 +
  162.18 +        try { visitor.preVisitDirectory(null, attrs);
  162.19          } catch (NullPointerException x0) {
  162.20 -        try { visitor.preVisitDirectoryFailed(null, new IOException());
  162.21 +        try { visitor.preVisitDirectory(dir, null);
  162.22          } catch (NullPointerException x1) {
  162.23 -        try { visitor.preVisitDirectoryFailed(dir, null);
  162.24 +        try { visitor.visitFile(null, attrs);
  162.25          } catch (NullPointerException x2) {
  162.26 -        try { visitor.visitFile(null, Attributes.readBasicFileAttributes(Paths.get(".")));
  162.27 +        try {  visitor.visitFile(dir, null);
  162.28          } catch (NullPointerException x3) {
  162.29 -        try {  visitor.visitFile(dir, null);
  162.30 +        try { visitor.visitFileFailed(null, new IOException());
  162.31          } catch (NullPointerException x4) {
  162.32 -        try { visitor.visitFileFailed(null, new IOException());
  162.33 +        try { visitor.visitFileFailed(dir, null);
  162.34          } catch (NullPointerException x5) {
  162.35 -        try { visitor.visitFileFailed(dir, null);
  162.36 +        try { visitor.postVisitDirectory(null, new IOException());
  162.37          } catch (NullPointerException x6) {
  162.38 -        try { visitor.postVisitDirectory(null, new IOException());
  162.39 -        } catch (NullPointerException x7) {
  162.40              // if we get here then all visit* methods threw NPE as expected
  162.41              ranTheGauntlet = true;
  162.42 -        }}}}}}}}
  162.43 +        }}}}}}}
  162.44          if (!ranTheGauntlet)
  162.45              throw new RuntimeException("A visit method did not throw NPE");
  162.46      }
   163.1 --- a/test/java/nio/file/Files/PrintFileTree.java	Tue Oct 12 13:34:59 2010 -0400
   163.2 +++ b/test/java/nio/file/Files/PrintFileTree.java	Mon Oct 18 11:25:28 2010 -0400
   163.3 @@ -56,29 +56,34 @@
   163.4  
   163.5          final boolean reportCycles = printCycles;
   163.6          Files.walkFileTree(dir, options, Integer.MAX_VALUE, new FileVisitor<FileRef>() {
   163.7 -            public FileVisitResult preVisitDirectory(FileRef dir) {
   163.8 +            @Override
   163.9 +            public FileVisitResult preVisitDirectory(FileRef dir, BasicFileAttributes attrs) {
  163.10                  System.out.println(dir);
  163.11                  return FileVisitResult.CONTINUE;
  163.12              }
  163.13 -            public FileVisitResult preVisitDirectoryFailed(FileRef dir, IOException exc) {
  163.14 -                exc.printStackTrace();
  163.15 -                return FileVisitResult.CONTINUE;
  163.16 -            }
  163.17 +            @Override
  163.18              public FileVisitResult visitFile(FileRef file, BasicFileAttributes attrs) {
  163.19                  if (!attrs.isDirectory() || reportCycles)
  163.20                      System.out.println(file);
  163.21                  return FileVisitResult.CONTINUE;
  163.22              }
  163.23 -            public FileVisitResult postVisitDirectory(FileRef dir, IOException exc) {
  163.24 -                if (exc != null) {
  163.25 -                    exc.printStackTrace();
  163.26 -                    return FileVisitResult.TERMINATE;
  163.27 -                }
  163.28 +            @Override
  163.29 +            public FileVisitResult postVisitDirectory(FileRef dir, IOException exc)
  163.30 +                throws IOException
  163.31 +            {
  163.32 +                if (exc != null)
  163.33 +                    throw exc;
  163.34                  return FileVisitResult.CONTINUE;
  163.35              }
  163.36 -            public FileVisitResult visitFileFailed(FileRef file, IOException exc) {
  163.37 -                exc.printStackTrace();
  163.38 -                return FileVisitResult.TERMINATE;
  163.39 +            @Override
  163.40 +            public FileVisitResult visitFileFailed(FileRef file, IOException exc)
  163.41 +                throws IOException
  163.42 +            {
  163.43 +                if (reportCycles && (exc instanceof FileSystemLoopException)) {
  163.44 +                    System.out.println(file);
  163.45 +                    return FileVisitResult.CONTINUE;
  163.46 +                }
  163.47 +                throw exc;
  163.48              }
  163.49          });
  163.50      }
   164.1 --- a/test/java/nio/file/Files/SkipSiblings.java	Tue Oct 12 13:34:59 2010 -0400
   164.2 +++ b/test/java/nio/file/Files/SkipSiblings.java	Mon Oct 18 11:25:28 2010 -0400
   164.3 @@ -54,32 +54,28 @@
   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                  check(dir);
  164.13                  if (skip(dir))
  164.14                      return FileVisitResult.SKIP_SIBLINGS;
  164.15                  return FileVisitResult.CONTINUE;
  164.16              }
  164.17 -            public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
  164.18 -                throw new RuntimeException(exc);
  164.19 -            }
  164.20 -
  164.21 +            @Override
  164.22              public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
  164.23                  check(file);
  164.24                  if (skip(file))
  164.25                      return FileVisitResult.SKIP_SIBLINGS;
  164.26                  return FileVisitResult.CONTINUE;
  164.27              }
  164.28 +            @Override
  164.29              public FileVisitResult postVisitDirectory(Path dir, IOException x) {
  164.30                  if (x != null)
  164.31                      throw new RuntimeException(x);
  164.32                  check(dir);
  164.33                  return FileVisitResult.CONTINUE;
  164.34              }
  164.35 -            public FileVisitResult visitFileFailed(Path file, IOException x) {
  164.36 -                throw new RuntimeException(x);
  164.37 -            }
  164.38          });
  164.39      }
  164.40  }
   165.1 --- a/test/java/nio/file/Files/TerminateWalk.java	Tue Oct 12 13:34:59 2010 -0400
   165.2 +++ b/test/java/nio/file/Files/TerminateWalk.java	Mon Oct 18 11:25:28 2010 -0400
   165.3 @@ -49,22 +49,19 @@
   165.4      public static void main(String[] args) throws Exception {
   165.5          Path dir = Paths.get(args[0]);
   165.6  
   165.7 -        Files.walkFileTree(dir, new FileVisitor<Path>() {
   165.8 -            public FileVisitResult preVisitDirectory(Path dir) {
   165.9 +        Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
  165.10 +            @Override
  165.11 +            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
  165.12                  return maybeTerminate();
  165.13              }
  165.14 -            public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
  165.15 -                return maybeTerminate();
  165.16 -            }
  165.17 +            @Override
  165.18              public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
  165.19                  return maybeTerminate();
  165.20              }
  165.21 +            @Override
  165.22              public FileVisitResult postVisitDirectory(Path dir, IOException x) {
  165.23                  return maybeTerminate();
  165.24              }
  165.25 -            public FileVisitResult visitFileFailed(Path file, IOException x) {
  165.26 -                return maybeTerminate();
  165.27 -            }
  165.28          });
  165.29      }
  165.30  }
   166.1 --- a/test/java/nio/file/Files/WalkWithSecurity.java	Tue Oct 12 13:34:59 2010 -0400
   166.2 +++ b/test/java/nio/file/Files/WalkWithSecurity.java	Mon Oct 18 11:25:28 2010 -0400
   166.3 @@ -116,7 +116,7 @@
   166.4          }
   166.5  
   166.6          @Override
   166.7 -        public FileVisitResult preVisitDirectory(Path dir) {
   166.8 +        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
   166.9              System.out.println(dir);
  166.10              count++;
  166.11              return FileVisitResult.CONTINUE;
   167.1 --- a/test/java/nio/file/Files/walk_file_tree.sh	Tue Oct 12 13:34:59 2010 -0400
   167.2 +++ b/test/java/nio/file/Files/walk_file_tree.sh	Mon Oct 18 11:25:28 2010 -0400
   167.3 @@ -22,9 +22,9 @@
   167.4  #
   167.5  
   167.6  # @test
   167.7 -# @bug 4313887
   167.8 +# @bug 4313887 6907737
   167.9  # @summary Unit test for walkFileTree method
  167.10 -# @build CreateFileTree PrintFileTree SkipSiblings TerminateWalk
  167.11 +# @build CreateFileTree PrintFileTree SkipSiblings TerminateWalk MaxDepth
  167.12  # @run shell walk_file_tree.sh
  167.13  
  167.14  # if TESTJAVA isn't set then we assume an interactive run.
  167.15 @@ -84,6 +84,10 @@
  167.16  $JAVA TerminateWalk "$ROOT"
  167.17  if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
  167.18  
  167.19 +# test maxDepth
  167.20 +$JAVA MaxDepth "$ROOT"
  167.21 +if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
  167.22 +
  167.23  # clean-up
  167.24  rm -r "$ROOT"
  167.25  
   168.1 --- a/test/java/nio/file/TestUtil.java	Tue Oct 12 13:34:59 2010 -0400
   168.2 +++ b/test/java/nio/file/TestUtil.java	Mon Oct 18 11:25:28 2010 -0400
   168.3 @@ -44,15 +44,10 @@
   168.4          return createTemporaryDirectory(System.getProperty("java.io.tmpdir"));
   168.5      }
   168.6  
   168.7 -    static void removeAll(Path dir) {
   168.8 +    static void removeAll(Path dir) throws IOException {
   168.9          Files.walkFileTree(dir, new FileVisitor<Path>() {
  168.10              @Override
  168.11 -            public FileVisitResult preVisitDirectory(Path dir) {
  168.12 -                return FileVisitResult.CONTINUE;
  168.13 -            }
  168.14 -            @Override
  168.15 -            public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
  168.16 -                System.err.format("Error occured accessing directory %s\n", dir, exc);
  168.17 +            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
  168.18                  return FileVisitResult.CONTINUE;
  168.19              }
  168.20              @Override
   169.1 --- a/test/java/util/Collection/BiggernYours.java	Tue Oct 12 13:34:59 2010 -0400
   169.2 +++ b/test/java/util/Collection/BiggernYours.java	Mon Oct 18 11:25:28 2010 -0400
   169.3 @@ -174,6 +174,11 @@
   169.4                  public int size() {return randomize(super.size());}});
   169.5  
   169.6          testCollections(
   169.7 +            new ConcurrentLinkedDeque(),
   169.8 +            new ConcurrentLinkedDeque() {
   169.9 +                public int size() {return randomize(super.size());}});
  169.10 +
  169.11 +        testCollections(
  169.12              new ConcurrentLinkedQueue(),
  169.13              new ConcurrentLinkedQueue() {
  169.14                  public int size() {return randomize(super.size());}});
   170.1 --- a/test/java/util/Collection/IteratorAtEnd.java	Tue Oct 12 13:34:59 2010 -0400
   170.2 +++ b/test/java/util/Collection/IteratorAtEnd.java	Mon Oct 18 11:25:28 2010 -0400
   170.3 @@ -48,6 +48,7 @@
   170.4          testCollection(new PriorityQueue());
   170.5          testCollection(new LinkedBlockingQueue());
   170.6          testCollection(new ArrayBlockingQueue(100));
   170.7 +        testCollection(new ConcurrentLinkedDeque());
   170.8          testCollection(new ConcurrentLinkedQueue());
   170.9          testCollection(new LinkedTransferQueue());
  170.10  
   171.1 --- a/test/java/util/Collection/MOAT.java	Tue Oct 12 13:34:59 2010 -0400
   171.2 +++ b/test/java/util/Collection/MOAT.java	Mon Oct 18 11:25:28 2010 -0400
   171.3 @@ -75,6 +75,7 @@
   171.4          testCollection(new ArrayBlockingQueue<Integer>(20));
   171.5          testCollection(new LinkedBlockingQueue<Integer>(20));
   171.6          testCollection(new LinkedBlockingDeque<Integer>(20));
   171.7 +        testCollection(new ConcurrentLinkedDeque<Integer>());
   171.8          testCollection(new ConcurrentLinkedQueue<Integer>());
   171.9          testCollection(new LinkedTransferQueue<Integer>());
  171.10          testCollection(new ConcurrentSkipListSet<Integer>());
  171.11 @@ -431,8 +432,9 @@
  171.12          q.poll();
  171.13          equal(q.size(), 4);
  171.14          checkFunctionalInvariants(q);
  171.15 -        if ((q instanceof LinkedBlockingQueue) ||
  171.16 -            (q instanceof LinkedBlockingDeque) ||
  171.17 +        if ((q instanceof LinkedBlockingQueue)   ||
  171.18 +            (q instanceof LinkedBlockingDeque)   ||
  171.19 +            (q instanceof ConcurrentLinkedDeque) ||
  171.20              (q instanceof ConcurrentLinkedQueue)) {
  171.21              testQueueIteratorRemove(q);
  171.22          }
   172.1 --- a/test/java/util/Collections/RacingCollections.java	Tue Oct 12 13:34:59 2010 -0400
   172.2 +++ b/test/java/util/Collections/RacingCollections.java	Mon Oct 18 11:25:28 2010 -0400
   172.3 @@ -235,6 +235,7 @@
   172.4              new ArrayList<Queue<Integer>>(newConcurrentDeques());
   172.5          list.add(new LinkedBlockingQueue<Integer>(10));
   172.6          list.add(new LinkedTransferQueue<Integer>());
   172.7 +        list.add(new ConcurrentLinkedQueue<Integer>());
   172.8          return list;
   172.9      }
  172.10  
  172.11 @@ -248,6 +249,7 @@
  172.12      private static List<Deque<Integer>> newConcurrentDeques() {
  172.13          List<Deque<Integer>> list = new ArrayList<Deque<Integer>>();
  172.14          list.add(new LinkedBlockingDeque<Integer>(10));
  172.15 +        list.add(new ConcurrentLinkedDeque<Integer>());
  172.16          return list;
  172.17      }
  172.18  
   173.1 --- a/test/java/util/Deque/ChorusLine.java	Tue Oct 12 13:34:59 2010 -0400
   173.2 +++ b/test/java/util/Deque/ChorusLine.java	Mon Oct 18 11:25:28 2010 -0400
   173.3 @@ -129,6 +129,7 @@
   173.4          deqs.add(new ArrayDeque<Integer>());
   173.5          deqs.add(new LinkedList<Integer>());
   173.6          deqs.add(new LinkedBlockingDeque<Integer>());
   173.7 +        deqs.add(new ConcurrentLinkedDeque<Integer>());
   173.8  
   173.9          equal(deqs);
  173.10  
   174.1 --- a/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java	Tue Oct 12 13:34:59 2010 -0400
   174.2 +++ b/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java	Mon Oct 18 11:25:28 2010 -0400
   174.3 @@ -55,6 +55,7 @@
   174.4  
   174.5      Collection<Queue<Integer>> concurrentQueues() {
   174.6          List<Queue<Integer>> queues = new ArrayList<Queue<Integer>>();
   174.7 +        queues.add(new ConcurrentLinkedDeque<Integer>());
   174.8          queues.add(new ConcurrentLinkedQueue<Integer>());
   174.9          queues.add(new ArrayBlockingQueue<Integer>(items, false));
  174.10          //queues.add(new ArrayBlockingQueue<Integer>(count, true));
  174.11 @@ -105,7 +106,7 @@
  174.12          final Queue<Integer> queue;
  174.13          final CyclicBarrier barrier;
  174.14          int items;
  174.15 -        Stage (Queue<Integer> q, CyclicBarrier b, int items) {
  174.16 +        Stage(Queue<Integer> q, CyclicBarrier b, int items) {
  174.17              queue = q;
  174.18              barrier = b;
  174.19              this.items = items;
   175.1 --- a/test/java/util/concurrent/ConcurrentQueues/GCRetention.java	Tue Oct 12 13:34:59 2010 -0400
   175.2 +++ b/test/java/util/concurrent/ConcurrentQueues/GCRetention.java	Mon Oct 18 11:25:28 2010 -0400
   175.3 @@ -40,6 +40,7 @@
   175.4  
   175.5  import java.util.concurrent.ArrayBlockingQueue;
   175.6  import java.util.concurrent.ConcurrentHashMap;
   175.7 +import java.util.concurrent.ConcurrentLinkedDeque;
   175.8  import java.util.concurrent.ConcurrentLinkedQueue;
   175.9  import java.util.concurrent.LinkedBlockingDeque;
  175.10  import java.util.concurrent.LinkedBlockingQueue;
  175.11 @@ -62,6 +63,7 @@
  175.12  
  175.13      Collection<Queue<Boolean>> queues() {
  175.14          List<Queue<Boolean>> queues = new ArrayList<Queue<Boolean>>();
  175.15 +        queues.add(new ConcurrentLinkedDeque<Boolean>());
  175.16          queues.add(new ConcurrentLinkedQueue<Boolean>());
  175.17          queues.add(new ArrayBlockingQueue<Boolean>(count, false));
  175.18          queues.add(new ArrayBlockingQueue<Boolean>(count, true));
   176.1 --- a/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java	Tue Oct 12 13:34:59 2010 -0400
   176.2 +++ b/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java	Mon Oct 18 11:25:28 2010 -0400
   176.3 @@ -48,6 +48,7 @@
   176.4          test(new LinkedBlockingQueue(20));
   176.5          test(new LinkedBlockingDeque());
   176.6          test(new LinkedBlockingDeque(20));
   176.7 +        test(new ConcurrentLinkedDeque());
   176.8          test(new ConcurrentLinkedQueue());
   176.9          test(new LinkedTransferQueue());
  176.10          // Other concurrent queues (e.g. ArrayBlockingQueue) do not
   177.1 --- a/test/java/util/concurrent/ConcurrentQueues/OfferRemoveLoops.java	Tue Oct 12 13:34:59 2010 -0400
   177.2 +++ b/test/java/util/concurrent/ConcurrentQueues/OfferRemoveLoops.java	Mon Oct 18 11:25:28 2010 -0400
   177.3 @@ -55,6 +55,7 @@
   177.4          testQueue(new LinkedBlockingDeque());
   177.5          testQueue(new ArrayBlockingQueue(10));
   177.6          testQueue(new PriorityBlockingQueue(10));
   177.7 +        testQueue(new ConcurrentLinkedDeque());
   177.8          testQueue(new ConcurrentLinkedQueue());
   177.9          testQueue(new LinkedTransferQueue());
  177.10      }
   178.1 --- a/test/java/util/concurrent/ConcurrentQueues/RemovePollRace.java	Tue Oct 12 13:34:59 2010 -0400
   178.2 +++ b/test/java/util/concurrent/ConcurrentQueues/RemovePollRace.java	Mon Oct 18 11:25:28 2010 -0400
   178.3 @@ -41,6 +41,7 @@
   178.4  
   178.5  import java.util.concurrent.ArrayBlockingQueue;
   178.6  import java.util.concurrent.ConcurrentHashMap;
   178.7 +import java.util.concurrent.ConcurrentLinkedDeque;
   178.8  import java.util.concurrent.ConcurrentLinkedQueue;
   178.9  import java.util.concurrent.CountDownLatch;
  178.10  import java.util.concurrent.LinkedBlockingDeque;
  178.11 @@ -62,6 +63,7 @@
  178.12  
  178.13      Collection<Queue<Boolean>> concurrentQueues() {
  178.14          List<Queue<Boolean>> queues = new ArrayList<Queue<Boolean>>();
  178.15 +        queues.add(new ConcurrentLinkedDeque<Boolean>());
  178.16          queues.add(new ConcurrentLinkedQueue<Boolean>());
  178.17          queues.add(new ArrayBlockingQueue<Boolean>(count, false));
  178.18          queues.add(new ArrayBlockingQueue<Boolean>(count, true));
   179.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   179.2 +++ b/test/javax/swing/JComboBox/6632953/bug6632953.java	Mon Oct 18 11:25:28 2010 -0400
   179.3 @@ -0,0 +1,44 @@
   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 6632953
  179.29 + * @summary MetalComboBoxUI.getBaseline(JComponent, int, int) throws IAE for valid width/height
  179.30 + * @author Alexander Potochkin
  179.31 + */
  179.32 +
  179.33 +import javax.swing.JComboBox;
  179.34 +import javax.swing.plaf.metal.MetalComboBoxUI;
  179.35 +
  179.36 +public class bug6632953 {
  179.37 +
  179.38 +    public static void main(String... args) throws Exception {
  179.39 +        MetalComboBoxUI ui = new MetalComboBoxUI();
  179.40 +        ui.installUI(new JComboBox());
  179.41 +        ui.getBaseline(new JComboBox(), 0, 0);
  179.42 +        ui.getBaseline(new JComboBox(), 1, 1);
  179.43 +        ui.getBaseline(new JComboBox(), 2, 2);
  179.44 +        ui.getBaseline(new JComboBox(), 3, 3);
  179.45 +        ui.getBaseline(new JComboBox(), 4, 4);
  179.46 +    }
  179.47 +}
   180.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   180.2 +++ b/test/javax/swing/JScrollBar/6542335/bug6542335.java	Mon Oct 18 11:25:28 2010 -0400
   180.3 @@ -0,0 +1,92 @@
   180.4 +/*
   180.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
   180.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   180.7 + *
   180.8 + * This code is free software; you can redistribute it and/or modify it
   180.9 + * under the terms of the GNU General Public License version 2 only, as
  180.10 + * published by the Free Software Foundation.
  180.11 + *
  180.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  180.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  180.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  180.15 + * version 2 for more details (a copy is included in the LICENSE file that
  180.16 + * accompanied this code).
  180.17 + *
  180.18 + * You should have received a copy of the GNU General Public License version
  180.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  180.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  180.21 + *
  180.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  180.23 + * or visit www.oracle.com if you need additional information or have any
  180.24 + * questions.
  180.25 + */
  180.26 +
  180.27 +/* @test
  180.28 +   @bug 6542335
  180.29 +   @summary different behavior on knob of scroll bar between 1.4.2 and 5.0
  180.30 +   @author  Alexander Potochkin
  180.31 +   @run main bug6542335
  180.32 +*/
  180.33 +
  180.34 +import sun.awt.SunToolkit;
  180.35 +
  180.36 +import javax.swing.*;
  180.37 +import javax.swing.plaf.basic.BasicScrollBarUI;
  180.38 +import java.awt.*;
  180.39 +import java.awt.event.InputEvent;
  180.40 +
  180.41 +public class bug6542335 {
  180.42 +    private static JScrollBar sb;
  180.43 +    private static MyScrollBarUI ui;
  180.44 +
  180.45 +    public static void main(String[] args) throws Exception {
  180.46 +        Robot robot = new Robot();
  180.47 +        robot.setAutoDelay(10);
  180.48 +
  180.49 +        SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
  180.50 +
  180.51 +        SwingUtilities.invokeAndWait(new Runnable() {
  180.52 +            public void run() {
  180.53 +                final JFrame frame = new JFrame("bug6542335");
  180.54 +                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  180.55 +
  180.56 +                sb = new JScrollBar(0, 0, 1, 0, 1);
  180.57 +
  180.58 +                ui = new MyScrollBarUI();
  180.59 +                sb.setUI(ui);
  180.60 +
  180.61 +                sb.setPreferredSize(new Dimension(200, 17));
  180.62 +                DefaultBoundedRangeModel rangeModel = new DefaultBoundedRangeModel();
  180.63 +                rangeModel.setMaximum(100);
  180.64 +                rangeModel.setMinimum(0);
  180.65 +                rangeModel.setExtent(50);
  180.66 +                rangeModel.setValue(50);
  180.67 +
  180.68 +                sb.setModel(rangeModel);
  180.69 +                frame.add(sb);
  180.70 +
  180.71 +                frame.setSize(200, 100);
  180.72 +                frame.setVisible(true);
  180.73 +            }
  180.74 +        });
  180.75 +
  180.76 +        Rectangle thumbBounds = new Rectangle(ui.getThumbBounds());
  180.77 +
  180.78 +        toolkit.realSync();
  180.79 +        Point l = sb.getLocationOnScreen();
  180.80 +        robot.mouseMove(l.x + (int) (0.75 * sb.getWidth()), l.y + sb.getHeight()/2);
  180.81 +        robot.mousePress(InputEvent.BUTTON1_MASK);
  180.82 +        robot.mouseRelease(InputEvent.BUTTON1_MASK);
  180.83 +        toolkit.realSync();
  180.84 +
  180.85 +        if (!thumbBounds.equals(ui.getThumbBounds())) {
  180.86 +            throw new RuntimeException("Test failed");
  180.87 +        }
  180.88 +    }
  180.89 +
  180.90 +    static class MyScrollBarUI extends BasicScrollBarUI {
  180.91 +        public Rectangle getThumbBounds() {
  180.92 +            return super.getThumbBounds();
  180.93 +        }
  180.94 +    }
  180.95 +}
   181.1 --- a/test/javax/swing/JTable/Test6888156.java	Tue Oct 12 13:34:59 2010 -0400
   181.2 +++ b/test/javax/swing/JTable/Test6888156.java	Mon Oct 18 11:25:28 2010 -0400
   181.3 @@ -1,5 +1,5 @@
   181.4  /*
   181.5 - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
   181.6 + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
   181.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   181.8   *
   181.9   * This code is free software; you can redistribute it and/or modify it
  181.10 @@ -71,14 +71,14 @@
  181.11          table = new JTable(model);
  181.12      }
  181.13  
  181.14 -    public void test(final LookAndFeel laf) throws Exception {
  181.15 +    public void test(final String laf) throws Exception {
  181.16          SwingUtilities.invokeAndWait(new Runnable() {
  181.17              @Override public void run() {
  181.18                  try {
  181.19 +                    System.out.println(laf);
  181.20                      UIManager.setLookAndFeel(laf);
  181.21 -                } catch (UnsupportedLookAndFeelException e) {
  181.22 -                    System.err.println(laf.getDescription() +
  181.23 -                                       " is unsupported; continuing");
  181.24 +                } catch (Exception e) {
  181.25 +                    System.err.println(laf + " is unsupported; continuing");
  181.26                      return;
  181.27                  }
  181.28                  SwingUtilities.updateComponentTreeUI(table);
  181.29 @@ -92,8 +92,10 @@
  181.30  
  181.31      public static void main(String[] args) throws Exception {
  181.32          Test6888156 t = new Test6888156();
  181.33 -        t.test(new javax.swing.plaf.nimbus.NimbusLookAndFeel());
  181.34 -        t.test(new com.sun.java.swing.plaf.gtk.GTKLookAndFeel());
  181.35 +        t.test("javax.swing.plaf.nimbus.NimbusLookAndFeel");
  181.36 +        t.test("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
  181.37 +        for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
  181.38 +            t.test(laf.getClassName());
  181.39 +        }
  181.40      }
  181.41  }
  181.42 -
   182.1 --- a/test/javax/swing/JTextArea/6940863/bug6940863.java	Tue Oct 12 13:34:59 2010 -0400
   182.2 +++ b/test/javax/swing/JTextArea/6940863/bug6940863.java	Mon Oct 18 11:25:28 2010 -0400
   182.3 @@ -56,6 +56,7 @@
   182.4      public static void main(String[] args) throws Exception {
   182.5          if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) {
   182.6              System.out.println("The test is suitable only for Windows OS. Skipped");
   182.7 +            return;
   182.8          }
   182.9  
  182.10          UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
   183.1 --- a/test/sun/net/www/http/ChunkedInputStream/ChunkedCharEncoding.sh	Tue Oct 12 13:34:59 2010 -0400
   183.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   183.3 @@ -1,62 +0,0 @@
   183.4 -#
   183.5 -# Copyright (c) 2006, 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 - # @test
  183.28 - # @bug 6502503
  183.29 - # @run shell/timeout=140 ChunkedCharEncoding.sh
  183.30 - # @summary Http URL connection don't work when default encoding is Cp037: HTTP Transfer-Encoding:chunked
  183.31 -
  183.32 -OS=`uname -s`
  183.33 -case "$OS" in
  183.34 -  SunOS | Linux )
  183.35 -    PS=":"
  183.36 -    FS="/"
  183.37 -    ;;
  183.38 -  CYGWIN* )
  183.39 -    PS=";"
  183.40 -    FS="/"
  183.41 -    ;;
  183.42 -  Windows* )
  183.43 -    PS=";"
  183.44 -    FS="\\"
  183.45 -    ;;
  183.46 -  * )
  183.47 -    echo "Unrecognized system!"
  183.48 -    exit 1;
  183.49 -    ;;
  183.50 -esac
  183.51 -
  183.52 -# compile
  183.53 -${TESTJAVA}${FS}bin${FS}javac -d . ${TESTSRC}${FS}TestAvailable.java
  183.54 -
  183.55 -# run with CP037 encoding specified. 
  183.56 -${TESTJAVA}${FS}bin${FS}java -Dfile.encoding=Cp037 TestAvailable 2>&1 
  183.57 -
  183.58 -result=$?
  183.59 -if [ "$result" -ne "0" ]; then
  183.60 -    exit 1
  183.61 -fi
  183.62 -
  183.63 -# no failures, exit.
  183.64 -exit 0
  183.65 -
   184.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   184.2 +++ b/test/sun/net/www/http/HttpClient/StreamingRetry.java	Mon Oct 18 11:25:28 2010 -0400
   184.3 @@ -0,0 +1,89 @@
   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 +/*
  184.28 + * @test
  184.29 + * @bug 6672144
  184.30 + * @summary HttpURLConnection.getInputStream sends POST request after failed chunked send
  184.31 + */
  184.32 +
  184.33 +import java.net.HttpURLConnection;
  184.34 +import java.net.ServerSocket;
  184.35 +import java.net.URL;
  184.36 +import java.io.IOException;
  184.37 +import java.io.InputStream;
  184.38 +import java.io.OutputStream;
  184.39 +
  184.40 +public class StreamingRetry implements Runnable {
  184.41 +    static final int ACCEPT_TIMEOUT = 20 * 1000; // 20 seconds
  184.42 +    ServerSocket ss;
  184.43 +
  184.44 +    public static void main(String[] args) throws IOException {
  184.45 +        (new StreamingRetry()).instanceMain();
  184.46 +    }
  184.47 +
  184.48 +    void instanceMain() throws IOException {
  184.49 +        test();
  184.50 +        if (failed > 0) throw new RuntimeException("Some tests failed");
  184.51 +    }
  184.52 +
  184.53 +    void test() throws IOException {
  184.54 +        ss = new ServerSocket(0);
  184.55 +        ss.setSoTimeout(ACCEPT_TIMEOUT);
  184.56 +        int port = ss.getLocalPort();
  184.57 +
  184.58 +        (new Thread(this)).start();
  184.59 +
  184.60 +        try {
  184.61 +            URL url = new URL("http://localhost:" + port + "/");
  184.62 +            HttpURLConnection uc = (HttpURLConnection) url.openConnection();
  184.63 +            uc.setDoOutput(true);
  184.64 +            uc.setChunkedStreamingMode(4096);
  184.65 +            OutputStream os = uc.getOutputStream();
  184.66 +            os.write("Hello there".getBytes());
  184.67 +
  184.68 +            InputStream is = uc.getInputStream();
  184.69 +            is.close();
  184.70 +        } catch (IOException expected) {
  184.71 +            //expected.printStackTrace();
  184.72 +        } finally {
  184.73 +            ss.close();
  184.74 +        }
  184.75 +    }
  184.76 +
  184.77 +    // Server
  184.78 +    public void run() {
  184.79 +        try {
  184.80 +            (ss.accept()).close();
  184.81 +            (ss.accept()).close();
  184.82 +            ss.close();
  184.83 +            fail("The server shouldn't accept a second connection");
  184.84 +         } catch (IOException e) {
  184.85 +            //OK, the clien will close the server socket if successfull
  184.86 +        }
  184.87 +    }
  184.88 +
  184.89 +    volatile int failed = 0;
  184.90 +    void fail() {failed++; Thread.dumpStack();}
  184.91 +    void fail(String msg) {System.err.println(msg); fail();}
  184.92 +}
   185.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   185.2 +++ b/test/sun/net/www/protocol/http/6550798/TestCache.java	Mon Oct 18 11:25:28 2010 -0400
   185.3 @@ -0,0 +1,133 @@
   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 +import java.net.*;
  185.28 +import java.io.*;
  185.29 +import java.io.IOException;
  185.30 +import java.io.InputStream;
  185.31 +import java.io.OutputStream;
  185.32 +import java.io.FileInputStream;
  185.33 +import java.io.FileOutputStream;
  185.34 +import java.io.BufferedInputStream;
  185.35 +import java.io.ByteArrayInputStream;
  185.36 +import java.io.PrintStream;
  185.37 +import java.io.InputStream;
  185.38 +import java.io.File;
  185.39 +import java.net.CacheRequest;
  185.40 +import java.net.CacheResponse;
  185.41 +import java.net.ResponseCache;
  185.42 +import java.net.URI;
  185.43 +import java.net.URL;
  185.44 +import java.net.URLConnection;
  185.45 +import java.util.ArrayList;
  185.46 +import java.util.HashMap;
  185.47 +import java.util.Map;
  185.48 +import java.util.List;
  185.49 +import java.util.Iterator;
  185.50 +import java.util.StringTokenizer;
  185.51 +import java.util.jar.JarInputStream;
  185.52 +import java.util.jar.JarFile;
  185.53 +import java.security.AccessController;
  185.54 +import java.security.PrivilegedAction;
  185.55 +import java.security.PrivilegedExceptionAction;
  185.56 +import java.security.PrivilegedActionException;
  185.57 +import java.security.Principal;
  185.58 +import java.security.cert.Certificate;
  185.59 +import javax.net.ssl.SSLPeerUnverifiedException;
  185.60 +
  185.61 +public class TestCache extends java.net.ResponseCache {
  185.62 +    private boolean inCacheHandler = false;
  185.63 +    private boolean _downloading = false;
  185.64 +
  185.65 +    public static volatile boolean fail = false;
  185.66 +
  185.67 +    public static void reset() {
  185.68 +        // Set system wide cache handler
  185.69 +        System.out.println("install deploy cache handler");
  185.70 +        ResponseCache.setDefault(new TestCache());
  185.71 +    }
  185.72 +
  185.73 +    public synchronized CacheResponse get(final URI uri, String rqstMethod,
  185.74 +            Map requestHeaders) throws IOException {
  185.75 +        System.out.println("get: " + uri);
  185.76 +        Thread.currentThread().dumpStack();
  185.77 +        return null;
  185.78 +    }
  185.79 +
  185.80 +    public synchronized CacheRequest put(URI uri, URLConnection conn)
  185.81 +    throws IOException {
  185.82 +        System.out.println("put: " + uri);
  185.83 +        Thread.currentThread().dumpStack();
  185.84 +        URL url = uri.toURL();
  185.85 +        return new DeployCacheRequest(url, conn);
  185.86 +
  185.87 +    }
  185.88 +}
  185.89 +
  185.90 +class DeployByteArrayOutputStream extends java.io.ByteArrayOutputStream {
  185.91 +
  185.92 +    private URL _url;
  185.93 +    private URLConnection _conn;
  185.94 +
  185.95 +    DeployByteArrayOutputStream(URL url, URLConnection conn) {
  185.96 +        _url = url;
  185.97 +        _conn = conn;
  185.98 +    }
  185.99 +
 185.100 +
 185.101 +    public void close() throws IOException {
 185.102 +
 185.103 +        System.out.println("contentLength: " + _conn.getContentLength());
 185.104 +        System.out.println("byte array size: " + size());
 185.105 +        if ( _conn.getContentLength() == size()) {
 185.106 +            System.out.println("correct content length");
 185.107 +        } else {
 185.108 +            System.out.println("wrong content length");
 185.109 +            System.out.println("TEST FAILED");
 185.110 +            TestCache.fail = true;
 185.111 +        }
 185.112 +        super.close();
 185.113 +    }
 185.114 +}
 185.115 +
 185.116 +class DeployCacheRequest extends java.net.CacheRequest {
 185.117 +
 185.118 +    private URL _url;
 185.119 +    private URLConnection _conn;
 185.120 +    private boolean _downloading = false;
 185.121 +
 185.122 +    DeployCacheRequest(URL url, URLConnection conn) {
 185.123 +        System.out.println("DeployCacheRequest ctor for: " + url);
 185.124 +        _url = url;
 185.125 +        _conn = conn;
 185.126 +    }
 185.127 +
 185.128 +    public void abort() {
 185.129 +        System.out.println("abort called");
 185.130 +    }
 185.131 +
 185.132 +    public OutputStream getBody() throws IOException {
 185.133 +        System.out.println("getBody called");
 185.134 +        return new DeployByteArrayOutputStream(_url, _conn);
 185.135 +    }
 185.136 +}
   186.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   186.2 +++ b/test/sun/net/www/protocol/http/6550798/test.java	Mon Oct 18 11:25:28 2010 -0400
   186.3 @@ -0,0 +1,90 @@
   186.4 +/*
   186.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
   186.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   186.7 + *
   186.8 + * This code is free software; you can redistribute it and/or modify it
   186.9 + * under the terms of the GNU General Public License version 2 only, as
  186.10 + * published by the Free Software Foundation.
  186.11 + *
  186.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  186.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  186.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  186.15 + * version 2 for more details (a copy is included in the LICENSE file that
  186.16 + * accompanied this code).
  186.17 + *
  186.18 + * You should have received a copy of the GNU General Public License version
  186.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  186.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  186.21 + *
  186.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  186.23 + * or visit www.oracle.com if you need additional information or have any
  186.24 + * questions.
  186.25 + */
  186.26 +
  186.27 +/**
  186.28 + * @test
  186.29 + * @bug 6550798
  186.30 + * @summary Using InputStream.skip with ResponseCache will cause partial data to be cached
  186.31 + * @run main/othervm test
  186.32 + */
  186.33 +
  186.34 +import java.net.*;
  186.35 +import com.sun.net.httpserver.*;
  186.36 +import java.io.*;
  186.37 +
  186.38 +public class test {
  186.39 +
  186.40 +    final static int LEN = 16 * 1024;
  186.41 +
  186.42 +    public static void main(String[] args)  throws Exception {
  186.43 +
  186.44 +        TestCache.reset();
  186.45 +        HttpServer s = HttpServer.create (new InetSocketAddress(0), 10);
  186.46 +        s.createContext ("/", new HttpHandler () {
  186.47 +            public void handle (HttpExchange e) {
  186.48 +                try {
  186.49 +                    byte[] buf = new byte [LEN];
  186.50 +                    OutputStream o = e.getResponseBody();
  186.51 +                    e.sendResponseHeaders(200, LEN);
  186.52 +                    o.write (buf);
  186.53 +                    e.close();
  186.54 +                } catch (IOException ex) {
  186.55 +                    ex.printStackTrace();
  186.56 +                    TestCache.fail = true;
  186.57 +                }
  186.58 +            }
  186.59 +        });
  186.60 +        s.start();
  186.61 +
  186.62 +        System.out.println("http request with cache hander");
  186.63 +        URL u = new URL("http://127.0.0.1:"+s.getAddress().getPort()+"/f");
  186.64 +        URLConnection conn = u.openConnection();
  186.65 +
  186.66 +        InputStream is = null;
  186.67 +        try {
  186.68 +            // this calls into TestCache.get
  186.69 +            byte[] buf = new byte[8192];
  186.70 +            is = new BufferedInputStream(conn.getInputStream());
  186.71 +
  186.72 +            is.skip(1000);
  186.73 +
  186.74 +            while (is.read(buf) != -1) {
  186.75 +            }
  186.76 +        } finally {
  186.77 +            if (is != null) {
  186.78 +                // this calls into TestCache.put
  186.79 +                // TestCache.put will check if the resource
  186.80 +                // should be cached
  186.81 +                is.close();
  186.82 +            }
  186.83 +            s.stop(0);
  186.84 +        }
  186.85 +
  186.86 +        if (TestCache.fail) {
  186.87 +            System.out.println ("TEST FAILED");
  186.88 +            throw new RuntimeException ();
  186.89 +        } else {
  186.90 +            System.out.println ("TEST OK");
  186.91 +        }
  186.92 +    }
  186.93 +}
   187.1 --- a/test/sun/security/tools/jarsigner/crl.sh	Tue Oct 12 13:34:59 2010 -0400
   187.2 +++ b/test/sun/security/tools/jarsigner/crl.sh	Mon Oct 18 11:25:28 2010 -0400
   187.3 @@ -63,7 +63,15 @@
   187.4  $KT -alias b -dname CN=b -keyalg rsa -genkey -validity 300
   187.5  $KT -alias b -gencrl -id 5:1 -id 6:2 -file crl3
   187.6  
   187.7 -$TESTJAVA${FS}bin${FS}jrunscript -e 'println(new File("crl1").toURI())' > uri
   187.8 +cat > ToURI.java <<EOF
   187.9 +class ToURI {
  187.10 +    public static void main(String[] args) throws Exception {
  187.11 +        System.out.println(new java.io.File("crl1").toURI());
  187.12 +    }
  187.13 +}
  187.14 +EOF
  187.15 +$TESTJAVA${FS}bin${FS}javac ToURI.java
  187.16 +$TESTJAVA${FS}bin${FS}java ToURI > uri
  187.17  $KT -alias c -dname CN=c -keyalg rsa -genkey -validity 300 \
  187.18      -ext crl=uri:`cat uri`
  187.19