1.1 --- a/make/Makefile Thu Oct 07 15:12:19 2010 -0700
1.2 +++ b/make/Makefile Tue Oct 12 12:51:48 2010 -0700
1.3 @@ -75,7 +75,6 @@
1.4 import_fastdebug -- copy in the fastdebug components \n\
1.5 import_debug -- copy in the debug components \n\
1.6 modules -- build the jdk and jre module images (experimental) \n\
1.7 -sccs_get -- make sure all SCCS files are up-to-date (need SCCS) \n\
1.8 create_links -- create softlinks in Solaris 32bit build to 64bit dirs \n\
1.9 "
1.10
1.11 @@ -278,21 +277,6 @@
1.12 $(OUTPUTDIR) $(TEMPDIR):
1.13 $(MKDIR) -p $@
1.14
1.15 -# cleanup everything. If the workspace is not being built by the control
1.16 -# workspace, and if it is a Teamware workspace, then see if there are
1.17 -# any files which are not under SCCS control.
1.18 -clean clobber::
1.19 -ifndef EXTERNALSANITYCONTROL
1.20 - @if [ -d $(TOPDIR)/Codemgr_wsdata ]; then \
1.21 - $(ECHO) '\nPerforming workspace scan for remnant files.\n' \
1.22 - ' Any files listed below are not under SCCS control in the workspace\n' \
1.23 - ' and you should review them and possibly remove them manually:' ; \
1.24 - $(FIND) $(TOPDIR)/make $(TOPDIR)/src -type f | \
1.25 - $(SED) 's+SCCS/[ps]\.++' | $(SORT) | $(UNIQ) -c | $(NAWK) '$$1<2 {print $$2;}' ; \
1.26 - $(ECHO) 'End of workspace scan.' ; \
1.27 - fi
1.28 -endif
1.29 -
1.30 # this should be the last rule in this file:
1.31 all::
1.32 @if [ -r $(WARNING_FILE) ]; then \
1.33 @@ -341,16 +325,70 @@
1.34 include $(BUILDDIR)/common/internal/BinaryPlugs.gmk
1.35
1.36 #
1.37 -# Get top level sccs_get rule
1.38 +# Test rule
1.39 #
1.40 -include $(BUILDDIR)/common/Rules-SCCS.gmk
1.41
1.42 +.NOTPARALLEL: test_run
1.43 +
1.44 +test:
1.45 + $(MAKE) test_run
1.46 +
1.47 +test_run: test_clean test_start test_summary
1.48 +
1.49 +test_start:
1.50 + @$(ECHO) "Tests started at `$(DATE)`"
1.51 +
1.52 +test_clean:
1.53 + $(RM) $(OUTPUTDIR)/test_failures.txt $(OUTPUTDIR)/test_log.txt
1.54 +
1.55 +test_summary: $(OUTPUTDIR)/test_failures.txt
1.56 + @$(ECHO) "#################################################"
1.57 + @$(ECHO) "Tests completed at `$(DATE)`"
1.58 + @( $(EGREP) '^TEST STATS:' $(OUTPUTDIR)/test_log.txt \
1.59 + || $(ECHO) "No TEST STATS seen in log" )
1.60 + @$(ECHO) "For complete details see: $(OUTPUTDIR)/test_log.txt"
1.61 + @$(ECHO) "#################################################"
1.62 + @if [ -s $< ] ; then \
1.63 + $(ECHO) "ERROR: Test failure count: `$(CAT) $< | $(WC) -l`"; \
1.64 + $(CAT) $<; \
1.65 + exit 1; \
1.66 + else \
1.67 + $(ECHO) "Success! No failures detected"; \
1.68 + fi
1.69 +
1.70 +# Get failure list from log
1.71 +$(OUTPUTDIR)/test_failures.txt: $(OUTPUTDIR)/test_log.txt
1.72 + @$(RM) $@
1.73 + @( $(EGREP) '^FAILED:' $< || $(ECHO) "" ) | $(NAWK) 'length>0' > $@
1.74 +
1.75 +# Get log file of all tests run
1.76 +JDK_TO_TEST := $(shell \
1.77 + if [ -d "$(ABS_OUTPUTDIR)/j2sdk-image" ] ; then \
1.78 + $(ECHO) "$(ABS_OUTPUTDIR)/j2sdk-image"; \
1.79 + elif [ -d "$(ABS_OUTPUTDIR)/bin" ] ; then \
1.80 + $(ECHO) "$(ABS_OUTPUTDIR)"; \
1.81 + elif [ "$(PRODUCT_HOME)" != "" -a -d "$(PRODUCT_HOME)/bin" ] ; then \
1.82 + $(ECHO) "$(PRODUCT_HOME)"; \
1.83 + fi \
1.84 +)
1.85 +
1.86 +TEST_TARGETS=jdk_all
1.87 +$(OUTPUTDIR)/test_log.txt:
1.88 + $(RM) $@
1.89 + ( $(CD) ../test && \
1.90 + $(MAKE) NO_STOPPING=- PRODUCT_HOME=$(JDK_TO_TEST) $(TEST_TARGETS) \
1.91 + ) | tee $@
1.92 +
1.93 +#
1.94 # JPRT rules
1.95 +#
1.96 +
1.97 include jprt.gmk
1.98
1.99 #
1.100 # Phonies to avoid accidents.
1.101 #
1.102 .PHONY: all build clean clobber optimized debug fastdebug create_links \
1.103 - import import_product import_fastdebug import_debug
1.104 + import import_product import_fastdebug import_debug \
1.105 + test test_run test_start test_clean test_summary
1.106
2.1 --- a/make/common/Cscope.gmk Thu Oct 07 15:12:19 2010 -0700
2.2 +++ b/make/common/Cscope.gmk Tue Oct 12 12:51:48 2010 -0700
2.3 @@ -76,7 +76,7 @@
2.4 # What files should we include? A simple rule might be just those files under
2.5 # SCM control, however this would miss files we create like the opcodes and
2.6 # CClassHeaders. The following attempts to find everything that is *useful*.
2.7 -# (.del files are created by sccsrm, demo directories contain many .java files
2.8 +# (demo directories contain many .java files
2.9 # that probably aren't useful for development, and the pkgarchive may contain
2.10 # duplicates of files within the source hierarchy). The ordering of the .raw
2.11 # file is an attempt to make cscope display the most relevant files first.
3.1 --- a/make/common/Defs.gmk Thu Oct 07 15:12:19 2010 -0700
3.2 +++ b/make/common/Defs.gmk Tue Oct 12 12:51:48 2010 -0700
3.3 @@ -334,7 +334,7 @@
3.4 DOCSDIRSUFFIX =
3.5
3.6 # The MESSAGE, WARNING and ERROR files are used to store sanityck and
3.7 -# SCCS check messages, warnings and errors.
3.8 +# warnings and errors.
3.9 ifndef ERROR_FILE
3.10 ERROR_FILE = $(OUTPUTDIR)/sanityCheckErrors.txt
3.11 endif
3.12 @@ -634,38 +634,6 @@
3.13
3.14 VERSION_DEFINES = -DRELEASE='"$(RELEASE)"'
3.15
3.16 -# Note: As a rule, GNU Make rules should not appear in any of the
3.17 -# Defs*.gmk files. These were added for Kestrel-Solaris and do address
3.18 -# a TeamWare bug. They should be moved elsewhere for Merlin.
3.19 -#
3.20 -# Override gnumake built-in rules which do sccs get operations badly.
3.21 -# (They put the checked out code in the current directory, not in the
3.22 -# directory of the original file.)
3.23 -# Since this is a symptom of a teamware failure, complain and die on the spot.
3.24 -
3.25 -# This message immediately goes to stdout and the build terminates.
3.26 -define SCCS-trouble
3.27 -$(error \
3.28 -"ERROR: File $@ referenced while building in $(CURRENT_DIRECTORY) \
3.29 - is out of date with respect to its SCCS file $<. \
3.30 - This can happen from an unresolved Teamware conflict, a file movement, or \
3.31 - a failure in which SCCS files are updated but the 'sccs get' was not done. \
3.32 - You should double check for other out of date files in your workspace. \
3.33 - Or run: cd $(TOPDIR) && $(MAKE) sccs_get")
3.34 -endef
3.35 -
3.36 -%:: s.%
3.37 - @$(SCCS-trouble)
3.38 -%:: SCCS/s.%
3.39 - @$(SCCS-trouble)
3.40 - @$(ECHO) " is out of date with respect to its SCCS file." >> $(WARNING_FILE)
3.41 - @$(ECHO) " This file may be from an unresolved Teamware conflict." >> $(WARNING_FILE)
3.42 - @$(ECHO) " This is also a symptom of a Teamware bringover/putback failure" >> $(WARNING_FILE)
3.43 - @$(ECHO) " in which SCCS files are updated but not checked out." >> $(WARNING_FILE)
3.44 - @$(ECHO) " Check for other out of date files in your workspace." >> $(WARNING_FILE)
3.45 - @$(ECHO) "" >> $(WARNING_FILE)
3.46 - @#exit 666
3.47 -
3.48 ifdef INSANE
3.49 export INSANE
3.50 endif
4.1 --- a/make/common/Rules-SCCS.gmk Thu Oct 07 15:12:19 2010 -0700
4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
4.3 @@ -1,70 +0,0 @@
4.4 -#
4.5 -# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
4.6 -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4.7 -#
4.8 -# This code is free software; you can redistribute it and/or modify it
4.9 -# under the terms of the GNU General Public License version 2 only, as
4.10 -# published by the Free Software Foundation. Oracle designates this
4.11 -# particular file as subject to the "Classpath" exception as provided
4.12 -# by Oracle in the LICENSE file that accompanied this code.
4.13 -#
4.14 -# This code is distributed in the hope that it will be useful, but WITHOUT
4.15 -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4.16 -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4.17 -# version 2 for more details (a copy is included in the LICENSE file that
4.18 -# accompanied this code).
4.19 -#
4.20 -# You should have received a copy of the GNU General Public License version
4.21 -# 2 along with this work; if not, write to the Free Software Foundation,
4.22 -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
4.23 -#
4.24 -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
4.25 -# or visit www.oracle.com if you need additional information or have any
4.26 -# questions.
4.27 -#
4.28 -
4.29 -#
4.30 -# Only get these rules if SCCS is available
4.31 -#
4.32 -
4.33 -ifdef SCCS
4.34 -
4.35 -# SCCS command to extract out latest source
4.36 -SCCS_GET=$(SCCS) get -s
4.37 -
4.38 -#
4.39 -# Make sure all files in workspace are fresh
4.40 -#
4.41 -TEMP_ALL_FILES=$(JDK_TOPDIR)/temp_filelist
4.42 -$(TEMP_ALL_FILES): $(JDK_TOPDIR)/Codemgr_wsdata/nametable
4.43 - $(prep-target)
4.44 - @$(CUT) -d' ' -f1 $< \
4.45 - | $(GREP) -v '^VERSION' \
4.46 - | $(GREP) -v '^deleted_files' \
4.47 - | $(GREP) -v '^Codemgr_wsdata' > $@
4.48 -
4.49 -sccs_get: $(TEMP_ALL_FILES)
4.50 - @$(PRINTF) "Workspace has %d files\n" `$(CAT) $< | $(WC) -l`
4.51 - @count=0; \
4.52 - for i in `$(CAT) $<` ; do \
4.53 - f=$(JDK_TOPDIR)/$$i; \
4.54 - count=`$(EXPR) $$count '+' 1`; \
4.55 - if [ `$(EXPR) $$count '%' 100` = 0 ] ; then \
4.56 - $(PRINTF) "\rChecked $$count files"; \
4.57 - fi; \
4.58 - if [ ! -f $$f ] ; then \
4.59 - $(PRINTF) "\r$(SCCS_GET) $$f\n"; \
4.60 - (cd `$(DIRNAME) $$f` && $(SCCS_GET) `$(BASENAME) $$f`); \
4.61 - elif /usr/bin/test $$f -ot `$(DIRNAME) $$f`/SCCS/s.`$(BASENAME) $$f` ; then \
4.62 - $(PRINTF) "\r$(SCCS_GET) $$f\n"; \
4.63 - (cd `$(DIRNAME) $$f` && $(SCCS_GET) `$(BASENAME) $$f`); \
4.64 - fi; \
4.65 - done; \
4.66 - $(PRINTF) "\rChecked $$count files\n"
4.67 -
4.68 -#
4.69 -# Phonies to avoid accidents.
4.70 -#
4.71 -.PHONY: sccs_get
4.72 -
4.73 -endif
5.1 --- a/make/common/shared/Defs-utils.gmk Thu Oct 07 15:12:19 2010 -0700
5.2 +++ b/make/common/shared/Defs-utils.gmk Tue Oct 12 12:51:48 2010 -0700
5.3 @@ -33,7 +33,7 @@
5.4 # UTILS_COMMAND_PATH
5.5 # /usr/bin/
5.6 # UTILS_USR_BIN_PATH
5.7 -# /usr/ccs/bin/ (sccs, m4, lex, yacc, as, ar, strip, mcs)
5.8 +# /usr/ccs/bin/ (m4, lex, yacc, as, ar, strip, mcs)
5.9 # UTILS_CCS_BIN_PATH
5.10 # Dev Tools: zip, unzip, etc that we may have special versions of
5.11 # UTILS_DEVTOOL_PATH
5.12 @@ -117,7 +117,6 @@
5.13 RMDIR = $(UTILS_COMMAND_PATH)rmdir
5.14 RPM = $(UTILS_COMMAND_PATH)rpm
5.15 RPMBUILD = $(UTILS_COMMAND_PATH)rpmbuild
5.16 -SCCS = $(UTILS_CCS_BIN_PATH)sccs
5.17 SED = $(UTILS_COMMAND_PATH)sed
5.18 SH = $(UTILS_COMMAND_PATH)sh
5.19 SHOWREV = $(UTILS_USR_BIN_PATH)showrev
5.20 @@ -183,7 +182,7 @@
5.21 NAWK = $(USRBIN_PATH)gawk
5.22 # Intrinsic unix command, with backslash-escaped character interpretation
5.23 ECHO = /bin/echo -e
5.24 - # These are really in UTILS_USR_BIN_PATH on Linux (only sccs is not)
5.25 + # These are really in UTILS_USR_BIN_PATH on Linux
5.26 AR = $(UTILS_USR_BIN_PATH)ar
5.27 AS = $(UTILS_USR_BIN_PATH)as
5.28 LD = $(UTILS_USR_BIN_PATH)ld
6.1 --- a/make/common/shared/Defs.gmk Thu Oct 07 15:12:19 2010 -0700
6.2 +++ b/make/common/shared/Defs.gmk Tue Oct 12 12:51:48 2010 -0700
6.3 @@ -219,7 +219,7 @@
6.4 PRODUCT_NAME = Java(TM)
6.5 PRODUCT_SUFFIX = SE Runtime Environment
6.6 JDK_RC_PLATFORM_NAME = Platform SE
6.7 - COMPANY_NAME = Oracle
6.8 + COMPANY_NAME = Oracle Corporation
6.9 endif
6.10
6.11 RUNTIME_NAME = $(PRODUCT_NAME) $(PRODUCT_SUFFIX)
7.1 --- a/make/java/java/FILES_java.gmk Thu Oct 07 15:12:19 2010 -0700
7.2 +++ b/make/java/java/FILES_java.gmk Tue Oct 12 12:51:48 2010 -0700
7.3 @@ -284,6 +284,7 @@
7.4 java/util/concurrent/CancellationException.java \
7.5 java/util/concurrent/CompletionService.java \
7.6 java/util/concurrent/ConcurrentHashMap.java \
7.7 + java/util/concurrent/ConcurrentLinkedDeque.java \
7.8 java/util/concurrent/ConcurrentLinkedQueue.java \
7.9 java/util/concurrent/ConcurrentMap.java \
7.10 java/util/concurrent/ConcurrentNavigableMap.java \
8.1 --- a/make/jprt.properties Thu Oct 07 15:12:19 2010 -0700
8.2 +++ b/make/jprt.properties Tue Oct 12 12:51:48 2010 -0700
8.3 @@ -25,43 +25,265 @@
8.4
8.5 # Properties for jprt
8.6
8.7 -# Use whatever release that the submitted job requests
8.8 +# At submit time, the release supplied will be in jprt.submit.release
8.9 +# and will be one of the official release names defined in jprt.
8.10 +# jprt supports property value expansion using ${property.name} syntax.
8.11 +
8.12 +# This tells jprt what default release we want to build
8.13 jprt.tools.default.release=${jprt.submit.release}
8.14
8.15 # The different build flavors we want, we override here so we just get these 2
8.16 jprt.build.flavors=product,fastdebug
8.17
8.18 -# Standard test target for everybody
8.19 -jprt.test.targets=*-*-*-jvm98
8.20 +# Define the Windows we want (temporary)
8.21 +jprt.my.windows.i586.jdk7b107=windows_i586_5.0
8.22 +jprt.my.windows.i586.jdk7temp=windows_i586_5.0
8.23 +jprt.my.windows.i586.jdk7=windows_i586_5.1
8.24 +jprt.my.windows.i586=${jprt.my.windows.i586.${jprt.tools.default.release}}
8.25
8.26 -# Test targets in test/Makefile (some longer running tests only test c2)
8.27 -jprt.make.rule.test.targets= \
8.28 - *-product-*-jdk_beans1, \
8.29 - *-product-*-jdk_beans2, \
8.30 - *-product-*-jdk_beans3, \
8.31 - *-product-*-jdk_io, \
8.32 - *-product-*-jdk_lang, \
8.33 - *-product-*-jdk_management1, \
8.34 - *-product-*-jdk_management2, \
8.35 - *-product-*-jdk_math, \
8.36 - *-product-*-jdk_misc, \
8.37 - *-product-*-jdk_net, \
8.38 - *-product-*-jdk_nio1, \
8.39 - *-product-*-jdk_nio2, \
8.40 - *-product-*-jdk_nio3, \
8.41 - *-product-*-jdk_security1, \
8.42 - *-product-*-jdk_security2, \
8.43 - *-product-*-jdk_security3, \
8.44 - *-product-*-jdk_text, \
8.45 - *-product-*-jdk_tools1, \
8.46 - *-product-*-jdk_tools2, \
8.47 - *-product-*-jdk_util
8.48 +# Standard list of jprt build targets for this source tree
8.49 +jprt.build.targets= \
8.50 + solaris_sparc_5.10-{product|fastdebug}, \
8.51 + solaris_sparcv9_5.10-{product|fastdebug}, \
8.52 + solaris_i586_5.10-{product|fastdebug}, \
8.53 + solaris_x64_5.10-{product|fastdebug}, \
8.54 + linux_i586_2.6-{product|fastdebug}, \
8.55 + linux_x64_2.6-{product|fastdebug}, \
8.56 + ${jprt.my.windows.i586}-{product|fastdebug}, \
8.57 + windows_x64_5.2-{product|fastdebug}
8.58
8.59 -# Some of these are crashing Xvfb or windows manager, need dedicated DISPLAY per test batch
8.60 -jprt2.make.rule.test.targets= \
8.61 - *-product-*-jdk_awt, \
8.62 - *-product-*-jdk_rmi, \
8.63 - *-product-*-jdk_swing, \
8.64 +# Standard vm test target
8.65 +jprt.test.targets= \
8.66 + solaris_sparc_5.10-product-c1-jvm98, \
8.67 + solaris_sparcv9_5.10-product-c2-jvm98, \
8.68 + solaris_i586_5.10-product-c1-jvm98, \
8.69 + solaris_x64_5.10-product-c2-jvm98, \
8.70 + linux_i586_2.6-product-{c1|c2}-jvm98, \
8.71 + linux_x64_2.6-product-c2-jvm98, \
8.72 + ${jprt.my.windows.i586}-product-c1-jvm98, \
8.73 + windows_x64_5.2-product-c2-jvm98
8.74 +
8.75 +# User can select the test set with jprt submit "-testset name" option
8.76 +jprt.my.test.set=${jprt.test.set}
8.77 +
8.78 +# Default jdk test targets in test/Makefile (no fastdebug & limited c2)
8.79 +jprt.make.rule.default.test.targets= \
8.80 + \
8.81 + solaris_sparc_5.10-product-c1-jdk_beans1, \
8.82 + solaris_sparcv9_5.10-product-c2-jdk_beans1, \
8.83 + solaris_i586_5.10-product-c1-jdk_beans1, \
8.84 + solaris_x64_5.10-product-c2-jdk_beans1, \
8.85 + linux_i586_2.6-product-{c1|c2}-jdk_beans1, \
8.86 + linux_x64_2.6-product-c2-jdk_beans1, \
8.87 + ${jprt.my.windows.i586}-product-c1-jdk_beans1, \
8.88 + windows_x64_5.2-product-c2-jdk_beans1, \
8.89 + \
8.90 + solaris_sparc_5.10-product-c1-jdk_io, \
8.91 + solaris_sparcv9_5.10-product-c2-jdk_io, \
8.92 + solaris_i586_5.10-product-c1-jdk_io, \
8.93 + solaris_x64_5.10-product-c2-jdk_io, \
8.94 + linux_i586_2.6-product-{c1|c2}-jdk_io, \
8.95 + linux_x64_2.6-product-c2-jdk_io, \
8.96 + ${jprt.my.windows.i586}-product-c1-jdk_io, \
8.97 + windows_x64_5.2-product-c2-jdk_io, \
8.98 + \
8.99 + solaris_sparc_5.10-product-c1-jdk_lang, \
8.100 + solaris_sparcv9_5.10-product-c2-jdk_lang, \
8.101 + solaris_i586_5.10-product-c1-jdk_lang, \
8.102 + solaris_x64_5.10-product-c2-jdk_lang, \
8.103 + linux_i586_2.6-product-{c1|c2}-jdk_lang, \
8.104 + linux_x64_2.6-product-c2-jdk_lang, \
8.105 + ${jprt.my.windows.i586}-product-c1-jdk_lang, \
8.106 + windows_x64_5.2-product-c2-jdk_lang, \
8.107 + \
8.108 + solaris_sparc_5.10-product-c1-jdk_math, \
8.109 + solaris_sparcv9_5.10-product-c2-jdk_math, \
8.110 + solaris_i586_5.10-product-c1-jdk_math, \
8.111 + solaris_x64_5.10-product-c2-jdk_math, \
8.112 + linux_i586_2.6-product-{c1|c2}-jdk_math, \
8.113 + linux_x64_2.6-product-c2-jdk_math, \
8.114 + ${jprt.my.windows.i586}-product-c1-jdk_math, \
8.115 + windows_x64_5.2-product-c2-jdk_math, \
8.116 + \
8.117 + solaris_sparc_5.10-product-c1-jdk_misc, \
8.118 + solaris_sparcv9_5.10-product-c2-jdk_misc, \
8.119 + solaris_i586_5.10-product-c1-jdk_misc, \
8.120 + solaris_x64_5.10-product-c2-jdk_misc, \
8.121 + linux_i586_2.6-product-{c1|c2}-jdk_misc, \
8.122 + linux_x64_2.6-product-c2-jdk_misc, \
8.123 + ${jprt.my.windows.i586}-product-c1-jdk_misc, \
8.124 + windows_x64_5.2-product-c2-jdk_misc, \
8.125 + \
8.126 + solaris_sparc_5.10-product-c1-jdk_net, \
8.127 + solaris_sparcv9_5.10-product-c2-jdk_net, \
8.128 + solaris_i586_5.10-product-c1-jdk_net, \
8.129 + solaris_x64_5.10-product-c2-jdk_net, \
8.130 + linux_i586_2.6-product-{c1|c2}-jdk_net, \
8.131 + linux_x64_2.6-product-c2-jdk_net, \
8.132 + ${jprt.my.windows.i586}-product-c1-jdk_net, \
8.133 + windows_x64_5.2-product-c2-jdk_net, \
8.134 + \
8.135 + solaris_sparc_5.10-product-c1-jdk_nio1, \
8.136 + solaris_sparcv9_5.10-product-c2-jdk_nio1, \
8.137 + solaris_i586_5.10-product-c1-jdk_nio1, \
8.138 + solaris_x64_5.10-product-c2-jdk_nio1, \
8.139 + linux_i586_2.6-product-{c1|c2}-jdk_nio1, \
8.140 + linux_x64_2.6-product-c2-jdk_nio1, \
8.141 + ${jprt.my.windows.i586}-product-c1-jdk_nio1, \
8.142 + windows_x64_5.2-product-c2-jdk_nio1, \
8.143 + \
8.144 + solaris_sparc_5.10-product-c1-jdk_nio2, \
8.145 + solaris_sparcv9_5.10-product-c2-jdk_nio2, \
8.146 + solaris_i586_5.10-product-c1-jdk_nio2, \
8.147 + solaris_x64_5.10-product-c2-jdk_nio2, \
8.148 + linux_i586_2.6-product-{c1|c2}-jdk_nio2, \
8.149 + linux_x64_2.6-product-c2-jdk_nio2, \
8.150 + ${jprt.my.windows.i586}-product-c1-jdk_nio2, \
8.151 + windows_x64_5.2-product-c2-jdk_nio2, \
8.152 + \
8.153 + solaris_sparc_5.10-product-c1-jdk_nio3, \
8.154 + solaris_sparcv9_5.10-product-c2-jdk_nio3, \
8.155 + solaris_i586_5.10-product-c1-jdk_nio3, \
8.156 + solaris_x64_5.10-product-c2-jdk_nio3, \
8.157 + linux_i586_2.6-product-{c1|c2}-jdk_nio3, \
8.158 + linux_x64_2.6-product-c2-jdk_nio3, \
8.159 + ${jprt.my.windows.i586}-product-c1-jdk_nio3, \
8.160 + windows_x64_5.2-product-c2-jdk_nio3, \
8.161 + \
8.162 + solaris_sparc_5.10-product-c1-jdk_security1, \
8.163 + solaris_sparcv9_5.10-product-c2-jdk_security1, \
8.164 + solaris_i586_5.10-product-c1-jdk_security1, \
8.165 + solaris_x64_5.10-product-c2-jdk_security1, \
8.166 + linux_i586_2.6-product-{c1|c2}-jdk_security1, \
8.167 + linux_x64_2.6-product-c2-jdk_security1, \
8.168 + ${jprt.my.windows.i586}-product-c1-jdk_security1, \
8.169 + windows_x64_5.2-product-c2-jdk_security1, \
8.170 + \
8.171 + solaris_sparc_5.10-product-c1-jdk_text, \
8.172 + solaris_sparcv9_5.10-product-c2-jdk_text, \
8.173 + solaris_i586_5.10-product-c1-jdk_text, \
8.174 + solaris_x64_5.10-product-c2-jdk_text, \
8.175 + linux_i586_2.6-product-{c1|c2}-jdk_text, \
8.176 + linux_x64_2.6-product-c2-jdk_text, \
8.177 + ${jprt.my.windows.i586}-product-c1-jdk_text, \
8.178 + windows_x64_5.2-product-c2-jdk_text, \
8.179 + \
8.180 + solaris_sparc_5.10-product-c1-jdk_tools1, \
8.181 + solaris_sparcv9_5.10-product-c2-jdk_tools1, \
8.182 + solaris_i586_5.10-product-c1-jdk_tools1, \
8.183 + solaris_x64_5.10-product-c2-jdk_tools1, \
8.184 + linux_i586_2.6-product-{c1|c2}-jdk_tools1, \
8.185 + linux_x64_2.6-product-c2-jdk_tools1, \
8.186 + ${jprt.my.windows.i586}-product-c1-jdk_tools1, \
8.187 + windows_x64_5.2-product-c2-jdk_tools1, \
8.188 + \
8.189 + solaris_sparc_5.10-product-c1-jdk_util, \
8.190 + solaris_sparcv9_5.10-product-c2-jdk_util, \
8.191 + solaris_i586_5.10-product-c1-jdk_util, \
8.192 + solaris_x64_5.10-product-c2-jdk_util, \
8.193 + linux_i586_2.6-product-{c1|c2}-jdk_util, \
8.194 + linux_x64_2.6-product-c2-jdk_util, \
8.195 + ${jprt.my.windows.i586}-product-c1-jdk_util, \
8.196 + windows_x64_5.2-product-c2-jdk_util
8.197 +
8.198 +# All jdk test targets in test/Makefile (still no fastdebug & limited c2)
8.199 +jprt.make.rule.all.test.targets= \
8.200 + \
8.201 + ${jprt.make.rule.default.test.targets}, \
8.202 + \
8.203 + solaris_sparc_5.10-product-c1-jdk_awt, \
8.204 + solaris_sparcv9_5.10-product-c2-jdk_awt, \
8.205 + solaris_i586_5.10-product-c1-jdk_awt, \
8.206 + solaris_x64_5.10-product-c2-jdk_awt, \
8.207 + linux_i586_2.6-product-{c1|c2}-jdk_awt, \
8.208 + linux_x64_2.6-product-c2-jdk_awt, \
8.209 + ${jprt.my.windows.i586}-product-c1-jdk_awt, \
8.210 + windows_x64_5.2-product-c2-jdk_awt, \
8.211 + \
8.212 + solaris_sparc_5.10-product-c1-jdk_beans2, \
8.213 + solaris_sparcv9_5.10-product-c2-jdk_beans2, \
8.214 + solaris_i586_5.10-product-c1-jdk_beans2, \
8.215 + solaris_x64_5.10-product-c2-jdk_beans2, \
8.216 + linux_i586_2.6-product-{c1|c2}-jdk_beans2, \
8.217 + linux_x64_2.6-product-c2-jdk_beans2, \
8.218 + ${jprt.my.windows.i586}-product-c1-jdk_beans2, \
8.219 + windows_x64_5.2-product-c2-jdk_beans2, \
8.220 + \
8.221 + solaris_sparc_5.10-product-c1-jdk_beans3, \
8.222 + solaris_sparcv9_5.10-product-c2-jdk_beans3, \
8.223 + solaris_i586_5.10-product-c1-jdk_beans3, \
8.224 + solaris_x64_5.10-product-c2-jdk_beans3, \
8.225 + linux_i586_2.6-product-{c1|c2}-jdk_beans3, \
8.226 + linux_x64_2.6-product-c2-jdk_beans3, \
8.227 + ${jprt.my.windows.i586}-product-c1-jdk_beans3, \
8.228 + windows_x64_5.2-product-c2-jdk_beans3, \
8.229 + \
8.230 + solaris_sparc_5.10-product-c1-jdk_management1, \
8.231 + solaris_sparcv9_5.10-product-c2-jdk_management1, \
8.232 + solaris_i586_5.10-product-c1-jdk_management1, \
8.233 + solaris_x64_5.10-product-c2-jdk_management1, \
8.234 + linux_i586_2.6-product-{c1|c2}-jdk_management1, \
8.235 + linux_x64_2.6-product-c2-jdk_management1, \
8.236 + ${jprt.my.windows.i586}-product-c1-jdk_management1, \
8.237 + windows_x64_5.2-product-c2-jdk_management1, \
8.238 + \
8.239 + solaris_sparc_5.10-product-c1-jdk_management2, \
8.240 + solaris_sparcv9_5.10-product-c2-jdk_management2, \
8.241 + solaris_i586_5.10-product-c1-jdk_management2, \
8.242 + solaris_x64_5.10-product-c2-jdk_management2, \
8.243 + linux_i586_2.6-product-{c1|c2}-jdk_management2, \
8.244 + linux_x64_2.6-product-c2-jdk_management2, \
8.245 + ${jprt.my.windows.i586}-product-c1-jdk_management2, \
8.246 + windows_x64_5.2-product-c2-jdk_management2, \
8.247 + \
8.248 + solaris_sparc_5.10-product-c1-jdk_rmi, \
8.249 + solaris_sparcv9_5.10-product-c2-jdk_rmi, \
8.250 + solaris_i586_5.10-product-c1-jdk_rmi, \
8.251 + solaris_x64_5.10-product-c2-jdk_rmi, \
8.252 + linux_i586_2.6-product-{c1|c2}-jdk_rmi, \
8.253 + linux_x64_2.6-product-c2-jdk_rmi, \
8.254 + ${jprt.my.windows.i586}-product-c1-jdk_rmi, \
8.255 + windows_x64_5.2-product-c2-jdk_rmi, \
8.256 + \
8.257 + solaris_sparc_5.10-product-c1-jdk_security2, \
8.258 + solaris_sparcv9_5.10-product-c2-jdk_security2, \
8.259 + solaris_i586_5.10-product-c1-jdk_security2, \
8.260 + solaris_x64_5.10-product-c2-jdk_security2, \
8.261 + linux_i586_2.6-product-{c1|c2}-jdk_security2, \
8.262 + linux_x64_2.6-product-c2-jdk_security2, \
8.263 + ${jprt.my.windows.i586}-product-c1-jdk_security2, \
8.264 + windows_x64_5.2-product-c2-jdk_security2, \
8.265 + \
8.266 + solaris_sparc_5.10-product-c1-jdk_security3, \
8.267 + solaris_sparcv9_5.10-product-c2-jdk_security3, \
8.268 + solaris_i586_5.10-product-c1-jdk_security3, \
8.269 + solaris_x64_5.10-product-c2-jdk_security3, \
8.270 + linux_i586_2.6-product-{c1|c2}-jdk_security3, \
8.271 + linux_x64_2.6-product-c2-jdk_security3, \
8.272 + ${jprt.my.windows.i586}-product-c1-jdk_security3, \
8.273 + windows_x64_5.2-product-c2-jdk_security3, \
8.274 + \
8.275 + solaris_sparc_5.10-product-c1-jdk_swing, \
8.276 + solaris_sparcv9_5.10-product-c2-jdk_swing, \
8.277 + solaris_i586_5.10-product-c1-jdk_swing, \
8.278 + solaris_x64_5.10-product-c2-jdk_swing, \
8.279 + linux_i586_2.6-product-{c1|c2}-jdk_swing, \
8.280 + linux_x64_2.6-product-c2-jdk_swing, \
8.281 + ${jprt.my.windows.i586}-product-c1-jdk_swing, \
8.282 + windows_x64_5.2-product-c2-jdk_swing, \
8.283 + \
8.284 + solaris_sparc_5.10-product-c1-jdk_tools2, \
8.285 + solaris_sparcv9_5.10-product-c2-jdk_tools2, \
8.286 + solaris_i586_5.10-product-c1-jdk_tools2, \
8.287 + solaris_x64_5.10-product-c2-jdk_tools2, \
8.288 + linux_i586_2.6-product-{c1|c2}-jdk_tools2, \
8.289 + linux_x64_2.6-product-c2-jdk_tools2, \
8.290 + ${jprt.my.windows.i586}-product-c1-jdk_tools2, \
8.291 + windows_x64_5.2-product-c2-jdk_tools2
8.292 +
8.293 +# Select list to use (allow for testset to be empty too)
8.294 +jprt.make.rule..test.targets=${jprt.make.rule.default.test.targets}
8.295 +jprt.make.rule.test.targets=${jprt.make.rule.${jprt.my.test.set}.test.targets}
8.296
8.297 # Directories to be excluded from the source bundles
8.298 jprt.bundle.exclude.src.dirs=build dist webrev
9.1 --- a/make/mkdemo/Makefile Thu Oct 07 15:12:19 2010 -0700
9.2 +++ b/make/mkdemo/Makefile Tue Oct 12 12:51:48 2010 -0700
9.3 @@ -31,7 +31,7 @@
9.4 PRODUCT = demos
9.5 include $(BUILDDIR)/common/Defs.gmk
9.6
9.7 -SUBDIRS = jni
9.8 +SUBDIRS = jni nio
9.9 SUBDIRS_desktop = applets jfc
9.10 SUBDIRS_management = management
9.11 SUBDIRS_misc = scripting
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/make/mkdemo/nio/Makefile Tue Oct 12 12:51:48 2010 -0700
10.3 @@ -0,0 +1,39 @@
10.4 +#
10.5 +# Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
10.6 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10.7 +#
10.8 +# This code is free software; you can redistribute it and/or modify it
10.9 +# under the terms of the GNU General Public License version 2 only, as
10.10 +# published by the Free Software Foundation. Oracle designates this
10.11 +# particular file as subject to the "Classpath" exception as provided
10.12 +# by Oracle in the LICENSE file that accompanied this code.
10.13 +#
10.14 +# This code is distributed in the hope that it will be useful, but WITHOUT
10.15 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10.16 +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
10.17 +# version 2 for more details (a copy is included in the LICENSE file that
10.18 +# accompanied this code).
10.19 +#
10.20 +# You should have received a copy of the GNU General Public License version
10.21 +# 2 along with this work; if not, write to the Free Software Foundation,
10.22 +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
10.23 +#
10.24 +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
10.25 +# or visit www.oracle.com if you need additional information or have any
10.26 +# questions.
10.27 +#
10.28 +
10.29 +#
10.30 +# Makefile for building the jfc demos
10.31 +#
10.32 +
10.33 +BUILDDIR = ../..
10.34 +PRODUCT = demos
10.35 +include $(BUILDDIR)/common/Defs.gmk
10.36 +
10.37 +SUBDIRS = zipfs
10.38 +include $(BUILDDIR)/common/Subdirs.gmk
10.39 +
10.40 +all build clean clobber::
10.41 + $(SUBDIRS-loop)
10.42 +
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/make/mkdemo/nio/zipfs/Makefile Tue Oct 12 12:51:48 2010 -0700
11.3 @@ -0,0 +1,44 @@
11.4 +#
11.5 +# Copyright (c) 1997, 2002, Oracle and/or its affiliates. All rights reserved.
11.6 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
11.7 +#
11.8 +# This code is free software; you can redistribute it and/or modify it
11.9 +# under the terms of the GNU General Public License version 2 only, as
11.10 +# published by the Free Software Foundation. Oracle designates this
11.11 +# particular file as subject to the "Classpath" exception as provided
11.12 +# by Oracle in the LICENSE file that accompanied this code.
11.13 +#
11.14 +# This code is distributed in the hope that it will be useful, but WITHOUT
11.15 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11.16 +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11.17 +# version 2 for more details (a copy is included in the LICENSE file that
11.18 +# accompanied this code).
11.19 +#
11.20 +# You should have received a copy of the GNU General Public License version
11.21 +# 2 along with this work; if not, write to the Free Software Foundation,
11.22 +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
11.23 +#
11.24 +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
11.25 +# or visit www.oracle.com if you need additional information or have any
11.26 +# questions.
11.27 +#
11.28 +
11.29 +#
11.30 +# Makefile to build the ZipFileSystem demo.
11.31 +#
11.32 +
11.33 +BUILDDIR = ../../..
11.34 +PRODUCT = demo/zipfs
11.35 +DEMONAME = zipfs
11.36 +include $(BUILDDIR)/common/Defs.gmk
11.37 +
11.38 +DEMO_ROOT = $(SHARE_SRC)/demo/nio/$(DEMONAME)
11.39 +DEMO_TOPFILES = ./README.txt
11.40 +DEMO_SRCDIR = $(DEMO_ROOT)
11.41 +DEMO_DESTDIR = $(DEMODIR)/nio/$(DEMONAME)
11.42 +
11.43 +#
11.44 +# Demo jar building rules.
11.45 +#
11.46 +include $(BUILDDIR)/common/Demo.gmk
11.47 +
12.1 --- a/make/sun/cmm/lcms/Makefile Thu Oct 07 15:12:19 2010 -0700
12.2 +++ b/make/sun/cmm/lcms/Makefile Tue Oct 12 12:51:48 2010 -0700
12.3 @@ -80,7 +80,12 @@
12.4 vpath %.c $(SHARE_SRC)/native/sun/java2d
12.5
12.6 ifeq ($(PLATFORM), windows)
12.7 -OTHER_CFLAGS += -DCMS_IS_WINDOWS_ -Dsqrtf=sqrt
12.8 +OTHER_CFLAGS += -DCMS_IS_WINDOWS_
12.9 +
12.10 +ifeq ($(COMPILER_VERSION), VS2003)
12.11 +OTHER_CFLAGS += -Dsqrtf=sqrt
12.12 +endif
12.13 +
12.14 OTHER_LDLIBS = $(OBJDIR)/../../../sun.awt/awt/$(OBJDIRNAME)/awt.lib
12.15 OTHER_INCLUDES += -I$(SHARE_SRC)/native/sun/java2d \
12.16 -I$(SHARE_SRC)/native/sun/awt/debug
13.1 --- a/src/share/classes/com/sun/rowset/CachedRowSetImpl.java Thu Oct 07 15:12:19 2010 -0700
13.2 +++ b/src/share/classes/com/sun/rowset/CachedRowSetImpl.java Tue Oct 12 12:51:48 2010 -0700
13.3 @@ -525,7 +525,7 @@
13.4
13.5 iMatchColumns = new Vector(10);
13.6 for(int i = 0; i < 10 ; i++) {
13.7 - iMatchColumns.add(i,new Integer(-1));
13.8 + iMatchColumns.add(i,Integer.valueOf(-1));
13.9 }
13.10
13.11 strMatchColumns = new Vector(10);
13.12 @@ -889,7 +889,12 @@
13.13 success = false;
13.14 } else {
13.15 tWriter = (TransactionalWriter)rowSetWriter;
13.16 - ((CachedRowSetWriter)tWriter).commit(this, updateOnInsert);
13.17 + if (tWriter instanceof CachedRowSetWriter) {
13.18 + ((CachedRowSetWriter)tWriter).commit(this, updateOnInsert);
13.19 + } else {
13.20 + tWriter.commit();
13.21 + }
13.22 +
13.23 success = true;
13.24 }
13.25 }
13.26 @@ -1294,7 +1299,7 @@
13.27 tMap = new TreeMap();
13.28
13.29 for (int i = 0; i<numRows; i++) {
13.30 - tMap.put(new Integer(i), rvh.get(i));
13.31 + tMap.put(Integer.valueOf(i), rvh.get(i));
13.32 }
13.33
13.34 return (tMap.values());
13.35 @@ -1806,7 +1811,7 @@
13.36 return (byte)0;
13.37 }
13.38 try {
13.39 - return ((new Byte(value.toString())).byteValue());
13.40 + return ((Byte.valueOf(value.toString())).byteValue());
13.41 } catch (NumberFormatException ex) {
13.42 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.bytefail").toString(),
13.43 new Object[] {value.toString().trim(), columnIndex}));
13.44 @@ -1850,7 +1855,7 @@
13.45 }
13.46
13.47 try {
13.48 - return ((new Short(value.toString().trim())).shortValue());
13.49 + return ((Short.valueOf(value.toString().trim())).shortValue());
13.50 } catch (NumberFormatException ex) {
13.51 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.shortfail").toString(),
13.52 new Object[] {value.toString().trim(), columnIndex}));
13.53 @@ -1893,7 +1898,7 @@
13.54 }
13.55
13.56 try {
13.57 - return ((new Integer(value.toString().trim())).intValue());
13.58 + return ((Integer.valueOf(value.toString().trim())).intValue());
13.59 } catch (NumberFormatException ex) {
13.60 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.intfail").toString(),
13.61 new Object[] {value.toString().trim(), columnIndex}));
13.62 @@ -1936,7 +1941,7 @@
13.63 return (long)0;
13.64 }
13.65 try {
13.66 - return ((new Long(value.toString().trim())).longValue());
13.67 + return ((Long.valueOf(value.toString().trim())).longValue());
13.68 } catch (NumberFormatException ex) {
13.69 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.longfail").toString(),
13.70 new Object[] {value.toString().trim(), columnIndex}));
13.71 @@ -4014,18 +4019,18 @@
13.72 try {
13.73 switch (trgType) {
13.74 case java.sql.Types.BIT:
13.75 - Integer i = new Integer(srcObj.toString().trim());
13.76 - return i.equals(new Integer((int)0)) ?
13.77 - new Boolean(false) :
13.78 - new Boolean(true);
13.79 + Integer i = Integer.valueOf(srcObj.toString().trim());
13.80 + return i.equals(Integer.valueOf((int)0)) ?
13.81 + Boolean.valueOf(false) :
13.82 + Boolean.valueOf(true);
13.83 case java.sql.Types.TINYINT:
13.84 - return new Byte(srcObj.toString().trim());
13.85 + return Byte.valueOf(srcObj.toString().trim());
13.86 case java.sql.Types.SMALLINT:
13.87 - return new Short(srcObj.toString().trim());
13.88 + return Short.valueOf(srcObj.toString().trim());
13.89 case java.sql.Types.INTEGER:
13.90 - return new Integer(srcObj.toString().trim());
13.91 + return Integer.valueOf(srcObj.toString().trim());
13.92 case java.sql.Types.BIGINT:
13.93 - return new Long(srcObj.toString().trim());
13.94 + return Long.valueOf(srcObj.toString().trim());
13.95 case java.sql.Types.NUMERIC:
13.96 case java.sql.Types.DECIMAL:
13.97 return new BigDecimal(srcObj.toString().trim());
13.98 @@ -4037,7 +4042,7 @@
13.99 case java.sql.Types.CHAR:
13.100 case java.sql.Types.VARCHAR:
13.101 case java.sql.Types.LONGVARCHAR:
13.102 - return new String(srcObj.toString());
13.103 + return srcObj.toString();
13.104 default:
13.105 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()+ trgType);
13.106 }
13.107 @@ -4134,7 +4139,7 @@
13.108 case java.sql.Types.CHAR:
13.109 case java.sql.Types.VARCHAR:
13.110 case java.sql.Types.LONGVARCHAR:
13.111 - return new String(srcObj.toString());
13.112 + return srcObj.toString();
13.113 default:
13.114 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());
13.115 }
13.116 @@ -4181,12 +4186,12 @@
13.117 try {
13.118 switch (trgType) {
13.119 case java.sql.Types.BIT:
13.120 - Integer i = new Integer(srcObj.toString().trim());
13.121 - return i.equals(new Integer((int)0)) ?
13.122 - new Boolean(false) :
13.123 - new Boolean(true);
13.124 + Integer i = Integer.valueOf(srcObj.toString().trim());
13.125 + return i.equals(Integer.valueOf((int)0)) ?
13.126 + Boolean.valueOf(false) :
13.127 + Boolean.valueOf(true);
13.128 case java.sql.Types.BOOLEAN:
13.129 - return new Boolean(srcObj.toString().trim());
13.130 + return Boolean.valueOf(srcObj.toString().trim());
13.131 default:
13.132 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()+ trgType);
13.133 }
13.134 @@ -4260,7 +4265,7 @@
13.135 checkIndex(columnIndex);
13.136 // make sure the cursor is on a valid row
13.137 checkCursor();
13.138 - Object obj = convertBoolean(new Boolean(x),
13.139 + Object obj = convertBoolean(Boolean.valueOf(x),
13.140 java.sql.Types.BIT,
13.141 RowSetMD.getColumnType(columnIndex));
13.142
13.143 @@ -4296,7 +4301,7 @@
13.144 // make sure the cursor is on a valid row
13.145 checkCursor();
13.146
13.147 - Object obj = convertNumeric(new Byte(x),
13.148 + Object obj = convertNumeric(Byte.valueOf(x),
13.149 java.sql.Types.TINYINT,
13.150 RowSetMD.getColumnType(columnIndex));
13.151
13.152 @@ -4332,7 +4337,7 @@
13.153 // make sure the cursor is on a valid row
13.154 checkCursor();
13.155
13.156 - Object obj = convertNumeric(new Short(x),
13.157 + Object obj = convertNumeric(Short.valueOf(x),
13.158 java.sql.Types.SMALLINT,
13.159 RowSetMD.getColumnType(columnIndex));
13.160
13.161 @@ -4367,7 +4372,7 @@
13.162 checkIndex(columnIndex);
13.163 // make sure the cursor is on a valid row
13.164 checkCursor();
13.165 - Object obj = convertNumeric(new Integer(x),
13.166 + Object obj = convertNumeric(Integer.valueOf(x),
13.167 java.sql.Types.INTEGER,
13.168 RowSetMD.getColumnType(columnIndex));
13.169
13.170 @@ -4403,7 +4408,7 @@
13.171 // make sure the cursor is on a valid row
13.172 checkCursor();
13.173
13.174 - Object obj = convertNumeric(new Long(x),
13.175 + Object obj = convertNumeric(Long.valueOf(x),
13.176 java.sql.Types.BIGINT,
13.177 RowSetMD.getColumnType(columnIndex));
13.178
13.179 @@ -6429,7 +6434,7 @@
13.180 if (tabName == null)
13.181 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.tablename").toString());
13.182 else
13.183 - tableName = new String(tabName);
13.184 + tableName = tabName;
13.185 }
13.186
13.187 /**
13.188 @@ -6940,7 +6945,7 @@
13.189 }
13.190
13.191 for( int i = 0;i < columnIdxes.length ;i++) {
13.192 - iMatchColumns.set(i,new Integer(-1));
13.193 + iMatchColumns.set(i,Integer.valueOf(-1));
13.194 }
13.195 }
13.196
13.197 @@ -7049,7 +7054,7 @@
13.198 }
13.199 }
13.200 for(int i = 0 ;i < columnIdxes.length; i++) {
13.201 - iMatchColumns.add(i,new Integer(columnIdxes[i]));
13.202 + iMatchColumns.add(i,Integer.valueOf(columnIdxes[i]));
13.203 }
13.204 }
13.205
13.206 @@ -7104,7 +7109,7 @@
13.207 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols1").toString());
13.208 } else {
13.209 // set iMatchColumn
13.210 - iMatchColumns.set(0, new Integer(columnIdx));
13.211 + iMatchColumns.set(0, Integer.valueOf(columnIdx));
13.212 //strMatchColumn = null;
13.213 }
13.214 }
13.215 @@ -7126,7 +7131,7 @@
13.216 */
13.217 public void setMatchColumn(String columnName) throws SQLException {
13.218 // validate, if col is ok to be set
13.219 - if(columnName.equals(null) || ((columnName = columnName.trim()) == "" )) {
13.220 + if(columnName == null || (columnName= columnName.trim()).equals("") ) {
13.221 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols2").toString());
13.222 } else {
13.223 // set strMatchColumn
13.224 @@ -7151,13 +7156,13 @@
13.225 */
13.226 public void unsetMatchColumn(int columnIdx) throws SQLException {
13.227 // check if we are unsetting the SAME column
13.228 - if(! iMatchColumns.get(0).equals(new Integer(columnIdx) ) ) {
13.229 + if(! iMatchColumns.get(0).equals(Integer.valueOf(columnIdx) ) ) {
13.230 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch").toString());
13.231 } else if(strMatchColumns.get(0) != null) {
13.232 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch1").toString());
13.233 } else {
13.234 // that is, we are unsetting it.
13.235 - iMatchColumns.set(0, new Integer(-1));
13.236 + iMatchColumns.set(0, Integer.valueOf(-1));
13.237 }
13.238 }
13.239
14.1 --- a/src/share/classes/com/sun/rowset/FilteredRowSetImpl.java Thu Oct 07 15:12:19 2010 -0700
14.2 +++ b/src/share/classes/com/sun/rowset/FilteredRowSetImpl.java Tue Oct 12 12:51:48 2010 -0700
14.3 @@ -499,7 +499,7 @@
14.4
14.5 if(onInsertRow) {
14.6 if(p != null) {
14.7 - bool = p.evaluate(new Integer(x),columnIndex);
14.8 + bool = p.evaluate(Integer.valueOf(x),columnIndex);
14.9
14.10 if(!bool) {
14.11 throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
14.12 @@ -566,7 +566,7 @@
14.13
14.14 if(onInsertRow) {
14.15 if(p != null) {
14.16 - bool = p.evaluate(new Boolean(x) , columnIndex);
14.17 + bool = p.evaluate(Boolean.valueOf(x) , columnIndex);
14.18
14.19 if(!bool) {
14.20 throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
14.21 @@ -634,7 +634,7 @@
14.22
14.23 if(onInsertRow) {
14.24 if(p != null) {
14.25 - bool = p.evaluate(new Byte(x),columnIndex);
14.26 + bool = p.evaluate(Byte.valueOf(x),columnIndex);
14.27
14.28 if(!bool) {
14.29 throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
14.30 @@ -703,7 +703,7 @@
14.31
14.32 if(onInsertRow) {
14.33 if(p != null) {
14.34 - bool = p.evaluate(new Short(x), columnIndex);
14.35 + bool = p.evaluate(Short.valueOf(x), columnIndex);
14.36
14.37 if(!bool) {
14.38 throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
14.39 @@ -771,7 +771,7 @@
14.40
14.41 if(onInsertRow) {
14.42 if(p != null) {
14.43 - bool = p.evaluate(new Long(x), columnIndex);
14.44 + bool = p.evaluate(Long.valueOf(x), columnIndex);
14.45
14.46 if(!bool) {
14.47 throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
14.48 @@ -1106,12 +1106,12 @@
14.49 public void updateBytes(int columnIndex , byte []x) throws SQLException {
14.50
14.51 boolean bool;
14.52 - String val = new String();
14.53 + String val = "";
14.54
14.55 Byte [] obj_arr = new Byte[x.length];
14.56
14.57 for(int i = 0; i < x.length; i++) {
14.58 - obj_arr[i] = new Byte(x[i]);
14.59 + obj_arr[i] = Byte.valueOf(x[i]);
14.60 val = val.concat(obj_arr[i].toString());
14.61 }
14.62
15.1 --- a/src/share/classes/com/sun/rowset/JdbcRowSetImpl.java Thu Oct 07 15:12:19 2010 -0700
15.2 +++ b/src/share/classes/com/sun/rowset/JdbcRowSetImpl.java Tue Oct 12 12:51:48 2010 -0700
15.3 @@ -215,7 +215,7 @@
15.4
15.5 iMatchColumns = new Vector(10);
15.6 for(int i = 0; i < 10 ; i++) {
15.7 - iMatchColumns.add(i,new Integer(-1));
15.8 + iMatchColumns.add(i,Integer.valueOf(-1));
15.9 }
15.10
15.11 strMatchColumns = new Vector(10);
15.12 @@ -288,7 +288,7 @@
15.13
15.14 iMatchColumns = new Vector(10);
15.15 for(int i = 0; i < 10 ; i++) {
15.16 - iMatchColumns.add(i,new Integer(-1));
15.17 + iMatchColumns.add(i,Integer.valueOf(-1));
15.18 }
15.19
15.20 strMatchColumns = new Vector(10);
15.21 @@ -375,7 +375,7 @@
15.22
15.23 iMatchColumns = new Vector(10);
15.24 for(int i = 0; i < 10 ; i++) {
15.25 - iMatchColumns.add(i,new Integer(-1));
15.26 + iMatchColumns.add(i,Integer.valueOf(-1));
15.27 }
15.28
15.29 strMatchColumns = new Vector(10);
15.30 @@ -465,7 +465,7 @@
15.31
15.32 iMatchColumns = new Vector(10);
15.33 for(int i = 0; i < 10 ; i++) {
15.34 - iMatchColumns.add(i,new Integer(-1));
15.35 + iMatchColumns.add(i,Integer.valueOf(-1));
15.36 }
15.37
15.38 strMatchColumns = new Vector(10);
15.39 @@ -3754,7 +3754,7 @@
15.40 }
15.41
15.42 for( int i = 0;i < columnIdxes.length ;i++) {
15.43 - iMatchColumns.set(i,new Integer(-1));
15.44 + iMatchColumns.set(i,Integer.valueOf(-1));
15.45 }
15.46 }
15.47
15.48 @@ -3863,7 +3863,7 @@
15.49 }
15.50 }
15.51 for(int i = 0 ;i < columnIdxes.length; i++) {
15.52 - iMatchColumns.add(i,new Integer(columnIdxes[i]));
15.53 + iMatchColumns.add(i,Integer.valueOf(columnIdxes[i]));
15.54 }
15.55 }
15.56
15.57 @@ -3918,7 +3918,7 @@
15.58 throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.matchcols1").toString());
15.59 } else {
15.60 // set iMatchColumn
15.61 - iMatchColumns.set(0, new Integer(columnIdx));
15.62 + iMatchColumns.set(0, Integer.valueOf(columnIdx));
15.63 //strMatchColumn = null;
15.64 }
15.65 }
15.66 @@ -3940,7 +3940,7 @@
15.67 */
15.68 public void setMatchColumn(String columnName) throws SQLException {
15.69 // validate, if col is ok to be set
15.70 - if(columnName.equals(null) || ((columnName = columnName.trim()) == "" )) {
15.71 + if(columnName == null || (columnName= columnName.trim()).equals("")) {
15.72 throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.matchcols2").toString());
15.73 } else {
15.74 // set strMatchColumn
15.75 @@ -3965,13 +3965,13 @@
15.76 */
15.77 public void unsetMatchColumn(int columnIdx) throws SQLException {
15.78 // check if we are unsetting the SAME column
15.79 - if(! iMatchColumns.get(0).equals(new Integer(columnIdx) ) ) {
15.80 + if(! iMatchColumns.get(0).equals(Integer.valueOf(columnIdx) ) ) {
15.81 throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.unsetmatch").toString());
15.82 } else if(strMatchColumns.get(0) != null) {
15.83 throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.usecolname").toString());
15.84 } else {
15.85 // that is, we are unsetting it.
15.86 - iMatchColumns.set(0, new Integer(-1));
15.87 + iMatchColumns.set(0, Integer.valueOf(-1));
15.88 }
15.89 }
15.90
16.1 --- a/src/share/classes/com/sun/rowset/JoinRowSetImpl.java Thu Oct 07 15:12:19 2010 -0700
16.2 +++ b/src/share/classes/com/sun/rowset/JoinRowSetImpl.java Tue Oct 12 12:51:48 2010 -0700
16.3 @@ -33,6 +33,8 @@
16.4 import java.util.*;
16.5
16.6 import javax.sql.rowset.*;
16.7 +import javax.sql.rowset.spi.SyncProvider;
16.8 +import javax.sql.rowset.spi.SyncProviderException;
16.9
16.10 /**
16.11 * The standard implementation of the <code>JoinRowSet</code>
16.12 @@ -550,7 +552,7 @@
16.13 // This 'if' will be removed after all joins are implemented.
16.14 throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.notsupported").toString());
16.15 } else {
16.16 - Integer Intgr = new Integer(JoinRowSet.INNER_JOIN);
16.17 + Integer Intgr = Integer.valueOf(JoinRowSet.INNER_JOIN);
16.18 vecJoinType.add(Intgr);
16.19 }
16.20 } else {
16.21 @@ -874,8 +876,8 @@
16.22
16.23 String strWhereClause = "Select ";
16.24 String whereClause;
16.25 - String tabName= null;
16.26 - String strTabName = null;
16.27 + String tabName= "";
16.28 + String strTabName = "";
16.29 int sz,cols;
16.30 int j;
16.31 CachedRowSetImpl crs;
16.32 @@ -889,8 +891,6 @@
16.33 // tableNameX.(rowsetX.getMatchColumnName()) ==
16.34 // tableNameZ.(rowsetZ.getMatchColumnName()));
16.35
16.36 - tabName = new String();
16.37 - strTabName = new String();
16.38 sz = vecRowSetsInJOIN.size();
16.39 for(int i=0;i<sz; i++) {
16.40 crs = (CachedRowSetImpl)vecRowSetsInJOIN.get(i);
16.41 @@ -4311,6 +4311,27 @@
16.42 return crsInternal.createCopySchema();
16.43 }
16.44
16.45 + /**
16.46 + * {@inheritDoc}
16.47 + */
16.48 + public void setSyncProvider(String providerStr) throws SQLException {
16.49 + crsInternal.setSyncProvider(providerStr);
16.50 + }
16.51 +
16.52 + /**
16.53 + * {@inheritDoc}
16.54 + */
16.55 + public void acceptChanges() throws SyncProviderException {
16.56 + crsInternal.acceptChanges();
16.57 + }
16.58 +
16.59 + /**
16.60 + * {@inheritDoc}
16.61 + */
16.62 + public SyncProvider getSyncProvider() throws SQLException {
16.63 + return crsInternal.getSyncProvider();
16.64 + }
16.65 +
16.66 /**
16.67 * This method re populates the resBundle
16.68 * during the deserialization process
17.1 --- a/src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java Thu Oct 07 15:12:19 2010 -0700
17.2 +++ b/src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java Tue Oct 12 12:51:48 2010 -0700
17.3 @@ -338,11 +338,11 @@
17.4 if (crs.rowDeleted()) {
17.5 // The row has been deleted.
17.6 if (conflict = (deleteOriginalRow(crs, this.crsResolve)) == true) {
17.7 - status.add(rows, new Integer(SyncResolver.DELETE_ROW_CONFLICT));
17.8 + status.add(rows, Integer.valueOf(SyncResolver.DELETE_ROW_CONFLICT));
17.9 } else {
17.10 // delete happened without any occurrence of conflicts
17.11 // so update status accordingly
17.12 - status.add(rows, new Integer(SyncResolver.NO_ROW_CONFLICT));
17.13 + status.add(rows, Integer.valueOf(SyncResolver.NO_ROW_CONFLICT));
17.14 }
17.15
17.16 } else if (crs.rowInserted()) {
17.17 @@ -350,20 +350,20 @@
17.18
17.19 pstmtIns = con.prepareStatement(insertCmd);
17.20 if ( (conflict = insertNewRow(crs, pstmtIns, this.crsResolve)) == true) {
17.21 - status.add(rows, new Integer(SyncResolver.INSERT_ROW_CONFLICT));
17.22 + status.add(rows, Integer.valueOf(SyncResolver.INSERT_ROW_CONFLICT));
17.23 } else {
17.24 // insert happened without any occurrence of conflicts
17.25 // so update status accordingly
17.26 - status.add(rows, new Integer(SyncResolver.NO_ROW_CONFLICT));
17.27 + status.add(rows, Integer.valueOf(SyncResolver.NO_ROW_CONFLICT));
17.28 }
17.29 } else if (crs.rowUpdated()) {
17.30 // The row has been updated.
17.31 if ( conflict = (updateOriginalRow(crs)) == true) {
17.32 - status.add(rows, new Integer(SyncResolver.UPDATE_ROW_CONFLICT));
17.33 + status.add(rows, Integer.valueOf(SyncResolver.UPDATE_ROW_CONFLICT));
17.34 } else {
17.35 // update happened without any occurrence of conflicts
17.36 // so update status accordingly
17.37 - status.add(rows, new Integer(SyncResolver.NO_ROW_CONFLICT));
17.38 + status.add(rows, Integer.valueOf(SyncResolver.NO_ROW_CONFLICT));
17.39 }
17.40
17.41 } else {
17.42 @@ -375,7 +375,7 @@
17.43 * that is fine.
17.44 **/
17.45 int icolCount = crs.getMetaData().getColumnCount();
17.46 - status.add(rows, new Integer(SyncResolver.NO_ROW_CONFLICT));
17.47 + status.add(rows, Integer.valueOf(SyncResolver.NO_ROW_CONFLICT));
17.48
17.49 this.crsResolve.moveToInsertRow();
17.50 for(int cols=0;cols<iColCount;cols++) {
17.51 @@ -398,7 +398,7 @@
17.52 boolean boolConf = false;
17.53 for (int j=1;j<status.size();j++){
17.54 // ignore status for index = 0 which is set to null
17.55 - if(! ((status.get(j)).equals(new Integer(SyncResolver.NO_ROW_CONFLICT)))) {
17.56 + if(! ((status.get(j)).equals(Integer.valueOf(SyncResolver.NO_ROW_CONFLICT)))) {
17.57 // there is at least one conflict which needs to be resolved
17.58 boolConf = true;
17.59 break;
17.60 @@ -541,7 +541,7 @@
17.61 // how many fields need to be updated
17.62 int colsNotChanged = 0;
17.63 Vector cols = new Vector();
17.64 - String updateExec = new String(updateCmd);
17.65 + String updateExec = updateCmd;
17.66 Object orig;
17.67 Object curr;
17.68 Object rsval;
17.69 @@ -652,7 +652,7 @@
17.70 updateExec += ", ";
17.71 }
17.72 updateExec += crs.getMetaData().getColumnName(i);
17.73 - cols.add(new Integer(i));
17.74 + cols.add(Integer.valueOf(i));
17.75 updateExec += " = ? ";
17.76 first = false;
17.77
17.78 @@ -698,7 +698,7 @@
17.79 updateExec += ", ";
17.80 }
17.81 updateExec += crs.getMetaData().getColumnName(i);
17.82 - cols.add(new Integer(i));
17.83 + cols.add(Integer.valueOf(i));
17.84 updateExec += " = ? ";
17.85 flag = false;
17.86 } else {
17.87 @@ -1184,7 +1184,7 @@
17.88 // trim all the leading and trailing whitespaces,
17.89 // white spaces can never be catalog, schema or a table name.
17.90
17.91 - String cmd = new String();
17.92 + String cmd = "";
17.93
17.94 catalog = catalog.trim();
17.95 schema = schema.trim();
18.1 --- a/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java Thu Oct 07 15:12:19 2010 -0700
18.2 +++ b/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java Tue Oct 12 12:51:48 2010 -0700
18.3 @@ -248,7 +248,7 @@
18.4 String strProvider = strProviderInstance.substring(0, (caller.getSyncProvider()).toString().indexOf("@"));
18.5
18.6 propString("sync-provider-name", strProvider);
18.7 - propString("sync-provider-vendor", "Sun Microsystems Inc.");
18.8 + propString("sync-provider-vendor", "Oracle Corporation");
18.9 propString("sync-provider-version", "1.0");
18.10 propInteger("sync-provider-grade", caller.getSyncProvider().getProviderGrade());
18.11 propInteger("data-source-lock", caller.getSyncProvider().getDataSourceLock());
18.12 @@ -387,7 +387,7 @@
18.13 if (caller.wasNull())
18.14 writeNull();
18.15 else
18.16 - writeInteger(caller.getInt(idx));
18.17 + writeInteger(i);
18.18 break;
18.19 case java.sql.Types.BIGINT:
18.20 long l = caller.getLong(idx);
18.21 @@ -574,7 +574,7 @@
18.22 }
18.23
18.24 private void writeBoolean(boolean b) throws java.io.IOException {
18.25 - writer.write(new Boolean(b).toString());
18.26 + writer.write(Boolean.valueOf(b).toString());
18.27 }
18.28
18.29 private void writeFloat(float f) throws java.io.IOException {
18.30 @@ -641,7 +641,7 @@
18.31 return null;
18.32 }
18.33 char []charStr = s.toCharArray();
18.34 - String specialStr = new String();
18.35 + String specialStr = "";
18.36
18.37 for(int i = 0; i < charStr.length; i++) {
18.38 if(charStr[i] == '&') {
19.1 --- a/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java Thu Oct 07 15:12:19 2010 -0700
19.2 +++ b/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java Tue Oct 12 12:51:48 2010 -0700
19.3 @@ -441,9 +441,9 @@
19.4 updates = new Vector();
19.5
19.6 // start out with the empty string
19.7 - columnValue = new String("");
19.8 - propertyValue = new String("");
19.9 - metaDataValue = new String("");
19.10 + columnValue = "";
19.11 + propertyValue = "";
19.12 + metaDataValue = "";
19.13
19.14 nullVal = false;
19.15 idx = 0;
19.16 @@ -481,21 +481,21 @@
19.17 items = properties.length;
19.18
19.19 for (i=0;i<items;i++) {
19.20 - propMap.put(properties[i], new Integer(i));
19.21 + propMap.put(properties[i], Integer.valueOf(i));
19.22 }
19.23
19.24 colDefMap = new HashMap();
19.25 items = colDef.length;
19.26
19.27 for (i=0;i<items;i++) {
19.28 - colDefMap.put(colDef[i], new Integer(i));
19.29 + colDefMap.put(colDef[i], Integer.valueOf(i));
19.30 }
19.31
19.32 dataMap = new HashMap();
19.33 items = data.length;
19.34
19.35 for (i=0;i<items;i++) {
19.36 - dataMap.put(data[i], new Integer(i));
19.37 + dataMap.put(data[i], Integer.valueOf(i));
19.38 }
19.39
19.40 //Initialize connection map here
19.41 @@ -686,7 +686,7 @@
19.42 }
19.43
19.44 // propertyValue need to be reset to an empty string
19.45 - propertyValue = new String("");
19.46 + propertyValue = "";
19.47 setTag(-1);
19.48 break;
19.49 case METADATA:
19.50 @@ -710,7 +710,7 @@
19.51
19.52 }
19.53 // metaDataValue needs to be reset to an empty string
19.54 - metaDataValue = new String("");
19.55 + metaDataValue = "";
19.56 }
19.57 setTag(-1);
19.58 break;
19.59 @@ -736,7 +736,7 @@
19.60 insertValue(tempStr);
19.61 }
19.62 // columnValue now need to be reset to the empty string
19.63 - columnValue = new String("");
19.64 + columnValue = "";
19.65 } catch (SQLException ex) {
19.66 throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errinsert").toString(), ex.getMessage()));
19.67 }
19.68 @@ -981,7 +981,7 @@
19.69
19.70 private boolean getBooleanValue(String s) {
19.71
19.72 - return new Boolean(s).booleanValue();
19.73 + return Boolean.valueOf(s).booleanValue();
19.74 }
19.75
19.76 private java.math.BigDecimal getBigDecimalValue(String s) {
19.77 @@ -1316,7 +1316,7 @@
19.78 **/
19.79
19.80 tempUpdate = tempUpdate.concat(new String(ch,start,len));
19.81 - upd[0] = new Integer(idx);
19.82 + upd[0] = Integer.valueOf(idx);
19.83 upd[1] = tempUpdate;
19.84 //updates.add(upd);
19.85
20.1 --- a/src/share/classes/com/sun/rowset/providers/RIOptimisticProvider.java Thu Oct 07 15:12:19 2010 -0700
20.2 +++ b/src/share/classes/com/sun/rowset/providers/RIOptimisticProvider.java Tue Oct 12 12:51:48 2010 -0700
20.3 @@ -93,14 +93,14 @@
20.4 private CachedRowSetWriter writer;
20.5
20.6 /**
20.7 - * The unique provider indentifier.
20.8 + * The unique provider identifier.
20.9 */
20.10 private String providerID = "com.sun.rowset.providers.RIOptimisticProvider";
20.11
20.12 /**
20.13 * The vendor name of this SyncProvider implementation
20.14 */
20.15 - private String vendorName = "Sun Microsystems Inc.";
20.16 + private String vendorName = "Oracle Corporation";
20.17
20.18 /**
20.19 * The version number of this SyncProvider implementation
20.20 @@ -236,8 +236,8 @@
20.21 }
20.22
20.23 /**
20.24 - * Returns the vendor name of the Reference Implemntation Optimistic
20.25 - * Syncchronication Provider
20.26 + * Returns the vendor name of the Reference Implementation Optimistic
20.27 + * Synchronization Provider
20.28 *
20.29 * @return the <code>String</code> detailing the vendor name of this
20.30 * SyncProvider
21.1 --- a/src/share/classes/com/sun/rowset/providers/RIXMLProvider.java Thu Oct 07 15:12:19 2010 -0700
21.2 +++ b/src/share/classes/com/sun/rowset/providers/RIXMLProvider.java Tue Oct 12 12:51:48 2010 -0700
21.3 @@ -1,5 +1,5 @@
21.4 /*
21.5 - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
21.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
21.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
21.8 *
21.9 * This code is free software; you can redistribute it and/or modify it
21.10 @@ -85,7 +85,7 @@
21.11 /**
21.12 * The vendor name of this SyncProvider implementation.
21.13 */
21.14 - private String vendorName = "Sun Microsystems Inc.";
21.15 + private String vendorName = "Oracle Corporation";
21.16
21.17 /**
21.18 * The version number of this SyncProvider implementation.
22.1 --- a/src/share/classes/com/sun/servicetag/Installer.java Thu Oct 07 15:12:19 2010 -0700
22.2 +++ b/src/share/classes/com/sun/servicetag/Installer.java Tue Oct 12 12:51:48 2010 -0700
22.3 @@ -43,7 +43,8 @@
22.4 "servicetag.dir.path";
22.5 private static String SVCTAG_ENABLE_REGISTRATION =
22.6 "servicetag.registration.enabled";
22.7 - private final static String SUN_VENDOR = "Sun Microsystems";
22.8 + private final static String ORACLE = "Oracle";
22.9 + private final static String SUN = "Sun Microsystems";
22.10 private final static String REGISTRATION_XML = "registration.xml";
22.11 private final static String SERVICE_TAG_FILE = "servicetag";
22.12 private final static String REGISTRATION_HTML_NAME = "register";
22.13 @@ -84,9 +85,10 @@
22.14
22.15 // Implementation of ServiceTag.getJavaServiceTag(String) method
22.16 static ServiceTag getJavaServiceTag(String source) throws IOException {
22.17 - if (!System.getProperty("java.vendor").startsWith(SUN_VENDOR)) {
22.18 + String vendor = System.getProperty("java.vendor", "");
22.19 + if (!vendor.startsWith(SUN) && !vendor.startsWith(ORACLE)) {
22.20 // Products bundling this implementation may run on
22.21 - // Mac OS which is not a Sun JDK
22.22 + // Mac OS which is not a Sun/Oracle JDK
22.23 return null;
22.24 }
22.25 boolean cleanup = false;
22.26 @@ -365,7 +367,7 @@
22.27 props.getProperty("servicetag.parent.name"),
22.28 props.getProperty("servicetag.parent.urn"),
22.29 getProductDefinedId(),
22.30 - SUN_VENDOR,
22.31 + System.getProperty("java.vendor"),
22.32 System.getProperty("os.arch"),
22.33 getZoneName(),
22.34 svcTagSource);
23.1 --- a/src/share/classes/com/sun/servicetag/RegistrationData.java Thu Oct 07 15:12:19 2010 -0700
23.2 +++ b/src/share/classes/com/sun/servicetag/RegistrationData.java Tue Oct 12 12:51:48 2010 -0700
23.3 @@ -80,12 +80,12 @@
23.4 * <tr>
23.5 * <td><tt>systemManufacturer</tt></td>
23.6 * <td>System manufacturer</td>
23.7 - * <td> e.g. Sun Microsystems</td>
23.8 + * <td> e.g. Oracle Corporation</td>
23.9 * </tr>
23.10 * <tr>
23.11 * <td><tt>cpuManufacturer</tt></td>
23.12 * <td>CPU manufacturer</td>
23.13 - * <td> e.g. Sun Microsystems</td>
23.14 + * <td> e.g. Oracle Corporation</td>
23.15 * </tr>
23.16 * <tr>
23.17 * <td><tt>serialNumber</tt></td>
24.1 --- a/src/share/classes/com/sun/servicetag/Registry.java Thu Oct 07 15:12:19 2010 -0700
24.2 +++ b/src/share/classes/com/sun/servicetag/Registry.java Tue Oct 12 12:51:48 2010 -0700
24.3 @@ -90,7 +90,7 @@
24.4 stclient = getWindowsStClientFile();
24.5 } else {
24.6 if (isVerbose()) {
24.7 - System.out.println("Running on non-Sun JDK");
24.8 + System.out.println("Running on unsupported platform");
24.9 }
24.10 }
24.11 initialized = true;
25.1 --- a/src/share/classes/com/sun/servicetag/SolarisSystemEnvironment.java Thu Oct 07 15:12:19 2010 -0700
25.2 +++ b/src/share/classes/com/sun/servicetag/SolarisSystemEnvironment.java Tue Oct 12 12:51:48 2010 -0700
25.3 @@ -44,6 +44,7 @@
25.4 * Solaris implementation of the SystemEnvironment class.
25.5 */
25.6 class SolarisSystemEnvironment extends SystemEnvironment {
25.7 + private static final String ORACLE = "Oracle Corporation";
25.8 SolarisSystemEnvironment() {
25.9 setHostId(getCommandOutput("/usr/bin/hostid"));
25.10 setSystemModel(getCommandOutput("/usr/bin/uname", "-i"));
25.11 @@ -59,7 +60,7 @@
25.12 private String getSolarisCpuManufacturer() {
25.13 // not fully accurate, this could be another manufacturer (fujitsu for example)
25.14 if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) {
25.15 - return "Sun Microsystems, Inc";
25.16 + return ORACLE;
25.17 }
25.18
25.19 // if we're here, then we'll try smbios (type 4)
25.20 @@ -73,7 +74,7 @@
25.21 private String getSolarisSystemManufacturer() {
25.22 // not fully accurate, this could be another manufacturer (fujitsu for example)
25.23 if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) {
25.24 - return "Sun Microsystems, Inc";
25.25 + return ORACLE;
25.26 }
25.27
25.28 // if we're here, then we'll try smbios (type 1)
25.29 @@ -117,7 +118,7 @@
25.30 // ID SIZE TYPE
25.31 // 1 150 SMB_TYPE_SYSTEM (system information)
25.32 //
25.33 - // Manufacturer: Sun Microsystems
25.34 + // Manufacturer: Oracle Corporation
25.35 // Product: Sun Fire X4600
25.36 // Version: To Be Filled By O.E.M.
25.37 // Serial Number: 00:14:4F:45:0C:2A
26.1 --- a/src/share/classes/java/awt/Dialog.java Thu Oct 07 15:12:19 2010 -0700
26.2 +++ b/src/share/classes/java/awt/Dialog.java Tue Oct 12 12:51:48 2010 -0700
26.3 @@ -1068,7 +1068,7 @@
26.4 modalityPushed();
26.5 try {
26.6 EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
26.7 - secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 5000);
26.8 + secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 0);
26.9 if (!secondaryLoop.enter()) {
26.10 secondaryLoop = null;
26.11 }
27.1 --- a/src/share/classes/java/awt/KeyboardFocusManager.java Thu Oct 07 15:12:19 2010 -0700
27.2 +++ b/src/share/classes/java/awt/KeyboardFocusManager.java Tue Oct 12 12:51:48 2010 -0700
27.3 @@ -142,6 +142,9 @@
27.4 public void removeLastFocusRequest(Component heavyweight) {
27.5 KeyboardFocusManager.removeLastFocusRequest(heavyweight);
27.6 }
27.7 + public void setMostRecentFocusOwner(Window window, Component component) {
27.8 + KeyboardFocusManager.setMostRecentFocusOwner(window, component);
27.9 + }
27.10 }
27.11 );
27.12 }
28.1 --- a/src/share/classes/java/awt/event/ActionEvent.java Thu Oct 07 15:12:19 2010 -0700
28.2 +++ b/src/share/classes/java/awt/event/ActionEvent.java Tue Oct 12 12:51:48 2010 -0700
28.3 @@ -51,7 +51,7 @@
28.4 * in the range from {@code ACTION_FIRST} to {@code ACTION_LAST}.
28.5 *
28.6 * @see ActionListener
28.7 - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/eventmodel.html">Tutorial: Java 1.1 Event Model</a>
28.8 + * @see <a href="http://java.sun.com/docs/books/tutorial/uiswing/events/actionlistener.html">Tutorial: How to Write an Action Listener</a>
28.9 *
28.10 * @author Carl Quinn
28.11 * @since 1.1
29.1 --- a/src/share/classes/java/awt/image/SampleModel.java Thu Oct 07 15:12:19 2010 -0700
29.2 +++ b/src/share/classes/java/awt/image/SampleModel.java Tue Oct 12 12:51:48 2010 -0700
29.3 @@ -937,14 +937,22 @@
29.4 int iArray[], DataBuffer data) {
29.5 int pixels[];
29.6 int Offset=0;
29.7 + int x1 = x + w;
29.8 + int y1 = y + h;
29.9 +
29.10 + if (x < 0 || x1 < x || x1 > width ||
29.11 + y < 0 || y1 < y || y1 > height)
29.12 + {
29.13 + throw new ArrayIndexOutOfBoundsException("Invalid coordinates.");
29.14 + }
29.15
29.16 if (iArray != null)
29.17 pixels = iArray;
29.18 else
29.19 pixels = new int[w * h];
29.20
29.21 - for(int i=y; i<(h+y); i++) {
29.22 - for (int j=x; j<(w+x); j++) {
29.23 + for(int i=y; i<y1; i++) {
29.24 + for (int j=x; j<x1; j++) {
29.25 pixels[Offset++] = getSample(j, i, b, data);
29.26 }
29.27 }
29.28 @@ -978,14 +986,22 @@
29.29 DataBuffer data) {
29.30 float pixels[];
29.31 int Offset=0;
29.32 + int x1 = x + w;
29.33 + int y1 = y + h;
29.34 +
29.35 + if (x < 0 || x1 < x || x1 > width ||
29.36 + y < 0 || y1 < y || y1 > height)
29.37 + {
29.38 + throw new ArrayIndexOutOfBoundsException("Invalid coordinates");
29.39 + }
29.40
29.41 if (fArray != null)
29.42 pixels = fArray;
29.43 else
29.44 pixels = new float[w * h];
29.45
29.46 - for (int i=y; i<(h+y); i++) {
29.47 - for (int j=x; j<(w+x); j++) {
29.48 + for (int i=y; i<y1; i++) {
29.49 + for (int j=x; j<x1; j++) {
29.50 pixels[Offset++] = getSampleFloat(j, i, b, data);
29.51 }
29.52 }
29.53 @@ -1019,14 +1035,22 @@
29.54 DataBuffer data) {
29.55 double pixels[];
29.56 int Offset=0;
29.57 + int x1 = x + w;
29.58 + int y1 = y + h;
29.59 +
29.60 + if (x < 0 || x1 < x || x1 > width ||
29.61 + y < 0 || y1 < y || y1 > height)
29.62 + {
29.63 + throw new ArrayIndexOutOfBoundsException("Invalid coordinates");
29.64 + }
29.65
29.66 if (dArray != null)
29.67 pixels = dArray;
29.68 else
29.69 pixels = new double[w * h];
29.70
29.71 - for (int i=y; i<(y+h); i++) {
29.72 - for (int j=x; j<(x+w); j++) {
29.73 + for (int i=y; i<y1; i++) {
29.74 + for (int j=x; j<x1; j++) {
29.75 pixels[Offset++] = getSampleDouble(j, i, b, data);
29.76 }
29.77 }
30.1 --- a/src/share/classes/java/beans/EventSetDescriptor.java Thu Oct 07 15:12:19 2010 -0700
30.2 +++ b/src/share/classes/java/beans/EventSetDescriptor.java Tue Oct 12 12:51:48 2010 -0700
30.3 @@ -176,8 +176,9 @@
30.4 setRemoveListenerMethod(getMethod(sourceClass, removeListenerMethodName, 1));
30.5
30.6 // Be more forgiving of not finding the getListener method.
30.7 - if (getListenerMethodName != null) {
30.8 - setGetListenerMethod(Introspector.findInstanceMethod(sourceClass, getListenerMethodName));
30.9 + Method method = Introspector.findMethod(sourceClass, getListenerMethodName, 0);
30.10 + if (method != null) {
30.11 + setGetListenerMethod(method);
30.12 }
30.13 }
30.14
31.1 --- a/src/share/classes/java/beans/IndexedPropertyDescriptor.java Thu Oct 07 15:12:19 2010 -0700
31.2 +++ b/src/share/classes/java/beans/IndexedPropertyDescriptor.java Tue Oct 12 12:51:48 2010 -0700
31.3 @@ -189,11 +189,13 @@
31.4 indexedReadMethodName = Introspector.GET_PREFIX + getBaseName();
31.5 }
31.6 }
31.7 - indexedReadMethod = Introspector.findInstanceMethod(cls, indexedReadMethodName, int.class);
31.8 +
31.9 + Class[] args = { int.class };
31.10 + indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args);
31.11 if (indexedReadMethod == null) {
31.12 // no "is" method, so look for a "get" method.
31.13 indexedReadMethodName = Introspector.GET_PREFIX + getBaseName();
31.14 - indexedReadMethod = Introspector.findInstanceMethod(cls, indexedReadMethodName, int.class);
31.15 + indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args);
31.16 }
31.17 setIndexedReadMethod0(indexedReadMethod);
31.18 }
31.19 @@ -265,7 +267,9 @@
31.20 if (indexedWriteMethodName == null) {
31.21 indexedWriteMethodName = Introspector.SET_PREFIX + getBaseName();
31.22 }
31.23 - indexedWriteMethod = Introspector.findInstanceMethod(cls, indexedWriteMethodName, int.class, type);
31.24 +
31.25 + Class[] args = (type == null) ? null : new Class[] { int.class, type };
31.26 + indexedWriteMethod = Introspector.findMethod(cls, indexedWriteMethodName, 2, args);
31.27 if (indexedWriteMethod != null) {
31.28 if (!indexedWriteMethod.getReturnType().equals(void.class)) {
31.29 indexedWriteMethod = null;
32.1 --- a/src/share/classes/java/beans/Introspector.java Thu Oct 07 15:12:19 2010 -0700
32.2 +++ b/src/share/classes/java/beans/Introspector.java Tue Oct 12 12:51:48 2010 -0700
32.3 @@ -28,7 +28,6 @@
32.4 import com.sun.beans.WeakCache;
32.5 import com.sun.beans.finder.BeanInfoFinder;
32.6 import com.sun.beans.finder.ClassFinder;
32.7 -import com.sun.beans.finder.MethodFinder;
32.8
32.9 import java.lang.ref.Reference;
32.10 import java.lang.ref.SoftReference;
32.11 @@ -843,8 +842,8 @@
32.12 Method read = result.getReadMethod();
32.13
32.14 if (read == null && write != null) {
32.15 - read = findInstanceMethod(result.getClass0(),
32.16 - GET_PREFIX + NameGenerator.capitalize(result.getName()));
32.17 + read = findMethod(result.getClass0(),
32.18 + GET_PREFIX + NameGenerator.capitalize(result.getName()), 0);
32.19 if (read != null) {
32.20 try {
32.21 result.setReadMethod(read);
32.22 @@ -854,9 +853,9 @@
32.23 }
32.24 }
32.25 if (write == null && read != null) {
32.26 - write = findInstanceMethod(result.getClass0(),
32.27 - SET_PREFIX + NameGenerator.capitalize(result.getName()),
32.28 - FeatureDescriptor.getReturnType(result.getClass0(), read));
32.29 + write = findMethod(result.getClass0(),
32.30 + SET_PREFIX + NameGenerator.capitalize(result.getName()), 1,
32.31 + new Class[] { FeatureDescriptor.getReturnType(result.getClass0(), read) });
32.32 if (write != null) {
32.33 try {
32.34 result.setWriteMethod(write);
32.35 @@ -1280,27 +1279,90 @@
32.36 // Package private support methods.
32.37 //======================================================================
32.38
32.39 - static Method findMethod(Class<?> type, String name, int args) {
32.40 - for (Method method : type.getMethods()) {
32.41 - if (method.getName().equals(name) && (args == method.getParameterTypes().length)) {
32.42 - try {
32.43 - return MethodFinder.findAccessibleMethod(method);
32.44 + /**
32.45 + * Internal support for finding a target methodName with a given
32.46 + * parameter list on a given class.
32.47 + */
32.48 + private static Method internalFindMethod(Class start, String methodName,
32.49 + int argCount, Class args[]) {
32.50 + // For overriden methods we need to find the most derived version.
32.51 + // So we start with the given class and walk up the superclass chain.
32.52 +
32.53 + Method method = null;
32.54 +
32.55 + for (Class cl = start; cl != null; cl = cl.getSuperclass()) {
32.56 + Method methods[] = getPublicDeclaredMethods(cl);
32.57 + for (int i = 0; i < methods.length; i++) {
32.58 + method = methods[i];
32.59 + if (method == null) {
32.60 + continue;
32.61 }
32.62 - catch (NoSuchMethodException exception) {
32.63 - // continue search for a method with the specified count of parameters
32.64 +
32.65 + // make sure method signature matches.
32.66 + Class params[] = FeatureDescriptor.getParameterTypes(start, method);
32.67 + if (method.getName().equals(methodName) &&
32.68 + params.length == argCount) {
32.69 + if (args != null) {
32.70 + boolean different = false;
32.71 + if (argCount > 0) {
32.72 + for (int j = 0; j < argCount; j++) {
32.73 + if (params[j] != args[j]) {
32.74 + different = true;
32.75 + continue;
32.76 + }
32.77 + }
32.78 + if (different) {
32.79 + continue;
32.80 + }
32.81 + }
32.82 + }
32.83 + return method;
32.84 }
32.85 }
32.86 }
32.87 - return null;
32.88 + method = null;
32.89 +
32.90 + // Now check any inherited interfaces. This is necessary both when
32.91 + // the argument class is itself an interface, and when the argument
32.92 + // class is an abstract class.
32.93 + Class ifcs[] = start.getInterfaces();
32.94 + for (int i = 0 ; i < ifcs.length; i++) {
32.95 + // Note: The original implementation had both methods calling
32.96 + // the 3 arg method. This is preserved but perhaps it should
32.97 + // pass the args array instead of null.
32.98 + method = internalFindMethod(ifcs[i], methodName, argCount, null);
32.99 + if (method != null) {
32.100 + break;
32.101 + }
32.102 + }
32.103 + return method;
32.104 }
32.105
32.106 - static Method findInstanceMethod(Class<?> type, String name, Class<?>... args) {
32.107 - try {
32.108 - return MethodFinder.findInstanceMethod(type, name, args);
32.109 - }
32.110 - catch (NoSuchMethodException exception) {
32.111 + /**
32.112 + * Find a target methodName on a given class.
32.113 + */
32.114 + static Method findMethod(Class cls, String methodName, int argCount) {
32.115 + return findMethod(cls, methodName, argCount, null);
32.116 + }
32.117 +
32.118 + /**
32.119 + * Find a target methodName with specific parameter list on a given class.
32.120 + * <p>
32.121 + * Used in the contructors of the EventSetDescriptor,
32.122 + * PropertyDescriptor and the IndexedPropertyDescriptor.
32.123 + * <p>
32.124 + * @param cls The Class object on which to retrieve the method.
32.125 + * @param methodName Name of the method.
32.126 + * @param argCount Number of arguments for the desired method.
32.127 + * @param args Array of argument types for the method.
32.128 + * @return the method or null if not found
32.129 + */
32.130 + static Method findMethod(Class cls, String methodName, int argCount,
32.131 + Class args[]) {
32.132 + if (methodName == null) {
32.133 return null;
32.134 }
32.135 + return internalFindMethod(cls, methodName, argCount, args);
32.136 }
32.137
32.138 /**
33.1 --- a/src/share/classes/java/beans/MethodDescriptor.java Thu Oct 07 15:12:19 2010 -0700
33.2 +++ b/src/share/classes/java/beans/MethodDescriptor.java Tue Oct 12 12:51:48 2010 -0700
33.3 @@ -90,13 +90,13 @@
33.4 // Find methods for up to 2 params. We are guessing here.
33.5 // This block should never execute unless the classloader
33.6 // that loaded the argument classes disappears.
33.7 - method = Introspector.findMethod(cls, name, i);
33.8 + method = Introspector.findMethod(cls, name, i, null);
33.9 if (method != null) {
33.10 break;
33.11 }
33.12 }
33.13 } else {
33.14 - method = Statement.getMethod(cls, name, params);
33.15 + method = Introspector.findMethod(cls, name, params.length, params);
33.16 }
33.17 setMethod(method);
33.18 }
34.1 --- a/src/share/classes/java/beans/PropertyDescriptor.java Thu Oct 07 15:12:19 2010 -0700
34.2 +++ b/src/share/classes/java/beans/PropertyDescriptor.java Tue Oct 12 12:51:48 2010 -0700
34.3 @@ -112,7 +112,8 @@
34.4 // If this class or one of its base classes allow PropertyChangeListener,
34.5 // then we assume that any properties we discover are "bound".
34.6 // See Introspector.getTargetPropertyInfo() method.
34.7 - this.bound = null != Introspector.findInstanceMethod(beanClass, "addPropertyChangeListener", PropertyChangeListener.class);
34.8 + Class[] args = { PropertyChangeListener.class };
34.9 + this.bound = null != Introspector.findMethod(beanClass, "addPropertyChangeListener", args.length, args);
34.10 }
34.11
34.12 /**
34.13 @@ -223,10 +224,10 @@
34.14 // property type is. For booleans, there can be "is" and "get"
34.15 // methods. If an "is" method exists, this is the official
34.16 // reader method so look for this one first.
34.17 - readMethod = Introspector.findInstanceMethod(cls, readMethodName);
34.18 + readMethod = Introspector.findMethod(cls, readMethodName, 0);
34.19 if (readMethod == null) {
34.20 readMethodName = Introspector.GET_PREFIX + getBaseName();
34.21 - readMethod = Introspector.findInstanceMethod(cls, readMethodName);
34.22 + readMethod = Introspector.findMethod(cls, readMethodName, 0);
34.23 }
34.24 try {
34.25 setReadMethod(readMethod);
34.26 @@ -291,7 +292,8 @@
34.27 writeMethodName = Introspector.SET_PREFIX + getBaseName();
34.28 }
34.29
34.30 - writeMethod = Introspector.findInstanceMethod(cls, writeMethodName, type);
34.31 + Class[] args = (type == null) ? null : new Class[] { type };
34.32 + writeMethod = Introspector.findMethod(cls, writeMethodName, 1, args);
34.33 if (writeMethod != null) {
34.34 if (!writeMethod.getReturnType().equals(void.class)) {
34.35 writeMethod = null;
35.1 --- a/src/share/classes/java/lang/System.java Thu Oct 07 15:12:19 2010 -0700
35.2 +++ b/src/share/classes/java/lang/System.java Tue Oct 12 12:51:48 2010 -0700
35.3 @@ -1101,22 +1101,12 @@
35.4 lineSeparator = props.getProperty("line.separator");
35.5 sun.misc.Version.init();
35.6
35.7 - // Workaround until DownloadManager initialization is revisited.
35.8 - // Make JavaLangAccess available early enough for internal
35.9 - // Shutdown hooks to be registered
35.10 - setJavaLangAccess();
35.11 -
35.12 // Gets and removes system properties that configure the Integer
35.13 // cache used to support the object identity semantics of autoboxing.
35.14 // At this time, the size of the cache may be controlled by the
35.15 // vm option -XX:AutoBoxCacheMax=<size>.
35.16 Integer.getAndRemoveCacheProperties();
35.17
35.18 - // Load the zip library now in order to keep java.util.zip.ZipFile
35.19 - // from trying to use itself to load this library later.
35.20 - loadLibrary("zip");
35.21 -
35.22 -
35.23 FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
35.24 FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
35.25 FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
35.26 @@ -1124,6 +1114,10 @@
35.27 setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
35.28 setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true));
35.29
35.30 + // Load the zip library now in order to keep java.util.zip.ZipFile
35.31 + // from trying to use itself to load this library later.
35.32 + loadLibrary("zip");
35.33 +
35.34 // Setup Java signal handlers for HUP, TERM, and INT (where available).
35.35 Terminator.setup();
35.36
35.37 @@ -1153,6 +1147,9 @@
35.38 // way as other threads; we must do it ourselves here.
35.39 Thread current = Thread.currentThread();
35.40 current.getThreadGroup().add(current);
35.41 +
35.42 + // register shared secrets
35.43 + setJavaLangAccess();
35.44 }
35.45
35.46 private static void setJavaLangAccess() {
36.1 --- a/src/share/classes/java/net/InetAddress.java Thu Oct 07 15:12:19 2010 -0700
36.2 +++ b/src/share/classes/java/net/InetAddress.java Tue Oct 12 12:51:48 2010 -0700
36.3 @@ -677,19 +677,20 @@
36.4
36.5 static InetAddressImpl impl;
36.6
36.7 - private static HashMap lookupTable = new HashMap();
36.8 + private static HashMap<String, InetAddress[]> lookupTable
36.9 + = new HashMap<String, InetAddress[]>();
36.10
36.11 /**
36.12 * Represents a cache entry
36.13 */
36.14 static final class CacheEntry {
36.15
36.16 - CacheEntry(Object address, long expiration) {
36.17 - this.address = address;
36.18 + CacheEntry(InetAddress[] addresses, long expiration) {
36.19 + this.addresses = addresses;
36.20 this.expiration = expiration;
36.21 }
36.22
36.23 - Object address;
36.24 + InetAddress[] addresses;
36.25 long expiration;
36.26 }
36.27
36.28 @@ -698,7 +699,7 @@
36.29 * at creation time.
36.30 */
36.31 static final class Cache {
36.32 - private LinkedHashMap cache;
36.33 + private LinkedHashMap<String, CacheEntry> cache;
36.34 private Type type;
36.35
36.36 enum Type {Positive, Negative};
36.37 @@ -708,7 +709,7 @@
36.38 */
36.39 public Cache(Type type) {
36.40 this.type = type;
36.41 - cache = new LinkedHashMap();
36.42 + cache = new LinkedHashMap<String, CacheEntry>();
36.43 }
36.44
36.45 private int getPolicy() {
36.46 @@ -724,7 +725,7 @@
36.47 * entry then for this host then the entry will be
36.48 * replaced.
36.49 */
36.50 - public Cache put(String host, Object address) {
36.51 + public Cache put(String host, InetAddress[] addresses) {
36.52 int policy = getPolicy();
36.53 if (policy == InetAddressCachePolicy.NEVER) {
36.54 return this;
36.55 @@ -736,12 +737,10 @@
36.56
36.57 // As we iterate in insertion order we can
36.58 // terminate when a non-expired entry is found.
36.59 - LinkedList expired = new LinkedList();
36.60 - Iterator i = cache.keySet().iterator();
36.61 + LinkedList<String> expired = new LinkedList<String>();
36.62 long now = System.currentTimeMillis();
36.63 - while (i.hasNext()) {
36.64 - String key = (String)i.next();
36.65 - CacheEntry entry = (CacheEntry)cache.get(key);
36.66 + for (String key : cache.keySet()) {
36.67 + CacheEntry entry = cache.get(key);
36.68
36.69 if (entry.expiration >= 0 && entry.expiration < now) {
36.70 expired.add(key);
36.71 @@ -750,9 +749,8 @@
36.72 }
36.73 }
36.74
36.75 - i = expired.iterator();
36.76 - while (i.hasNext()) {
36.77 - cache.remove(i.next());
36.78 + for (String key : expired) {
36.79 + cache.remove(key);
36.80 }
36.81 }
36.82
36.83 @@ -766,7 +764,7 @@
36.84 } else {
36.85 expiration = System.currentTimeMillis() + (policy * 1000);
36.86 }
36.87 - CacheEntry entry = new CacheEntry(address, expiration);
36.88 + CacheEntry entry = new CacheEntry(addresses, expiration);
36.89 cache.put(host, entry);
36.90 return this;
36.91 }
36.92 @@ -780,7 +778,7 @@
36.93 if (policy == InetAddressCachePolicy.NEVER) {
36.94 return null;
36.95 }
36.96 - CacheEntry entry = (CacheEntry)cache.get(host);
36.97 + CacheEntry entry = cache.get(host);
36.98
36.99 // check if entry has expired
36.100 if (entry != null && policy != InetAddressCachePolicy.FOREVER) {
36.101 @@ -814,42 +812,41 @@
36.102 }
36.103
36.104 /*
36.105 - * Cache the given hostname and address.
36.106 + * Cache the given hostname and addresses.
36.107 */
36.108 - private static void cacheAddress(String hostname, Object address,
36.109 - boolean success) {
36.110 + private static void cacheAddresses(String hostname,
36.111 + InetAddress[] addresses,
36.112 + boolean success) {
36.113 hostname = hostname.toLowerCase();
36.114 synchronized (addressCache) {
36.115 cacheInitIfNeeded();
36.116 if (success) {
36.117 - addressCache.put(hostname, address);
36.118 + addressCache.put(hostname, addresses);
36.119 } else {
36.120 - negativeCache.put(hostname, address);
36.121 + negativeCache.put(hostname, addresses);
36.122 }
36.123 }
36.124 }
36.125
36.126 /*
36.127 * Lookup hostname in cache (positive & negative cache). If
36.128 - * found return address, null if not found.
36.129 + * found return addresses, null if not found.
36.130 */
36.131 - private static Object getCachedAddress(String hostname) {
36.132 + private static InetAddress[] getCachedAddresses(String hostname) {
36.133 hostname = hostname.toLowerCase();
36.134
36.135 // search both positive & negative caches
36.136
36.137 synchronized (addressCache) {
36.138 - CacheEntry entry;
36.139 -
36.140 cacheInitIfNeeded();
36.141
36.142 - entry = addressCache.get(hostname);
36.143 + CacheEntry entry = addressCache.get(hostname);
36.144 if (entry == null) {
36.145 entry = negativeCache.get(hostname);
36.146 }
36.147
36.148 if (entry != null) {
36.149 - return entry.address;
36.150 + return entry.addresses;
36.151 }
36.152 }
36.153
36.154 @@ -911,7 +908,7 @@
36.155
36.156 static {
36.157 // create the impl
36.158 - impl = (new InetAddressImplFactory()).create();
36.159 + impl = InetAddressImplFactory.create();
36.160
36.161 // get name service if provided and requested
36.162 String provider = null;;
36.163 @@ -931,7 +928,7 @@
36.164 }
36.165
36.166 // if not designate any name services provider,
36.167 - // creat a default one
36.168 + // create a default one
36.169 if (nameServices.size() == 0) {
36.170 NameService ns = createNSProvider("default");
36.171 nameServices.add(ns);
36.172 @@ -939,7 +936,7 @@
36.173 }
36.174
36.175 /**
36.176 - * Create an InetAddress based on the provided host name and IP address
36.177 + * Creates an InetAddress based on the provided host name and IP address.
36.178 * No name service is checked for the validity of the address.
36.179 *
36.180 * <p> The host name can either be a machine name, such as
36.181 @@ -1067,13 +1064,13 @@
36.182
36.183 boolean ipv6Expected = false;
36.184 if (host.charAt(0) == '[') {
36.185 - // This is supposed to be an IPv6 litteral
36.186 + // This is supposed to be an IPv6 literal
36.187 if (host.length() > 2 && host.charAt(host.length()-1) == ']') {
36.188 host = host.substring(1, host.length() -1);
36.189 ipv6Expected = true;
36.190 } else {
36.191 // This was supposed to be a IPv6 address, but it's not!
36.192 - throw new UnknownHostException(host);
36.193 + throw new UnknownHostException(host + ": invalid IPv6 address");
36.194 }
36.195 }
36.196
36.197 @@ -1180,8 +1177,6 @@
36.198 throws UnknownHostException {
36.199 /* If it gets here it is presumed to be a hostname */
36.200 /* Cache.get can return: null, unknownAddress, or InetAddress[] */
36.201 - Object obj = null;
36.202 - Object objcopy = null;
36.203
36.204 /* make sure the connection to the host is allowed, before we
36.205 * give out a hostname
36.206 @@ -1193,26 +1188,23 @@
36.207 }
36.208 }
36.209
36.210 - obj = getCachedAddress(host);
36.211 + InetAddress[] addresses = getCachedAddresses(host);
36.212
36.213 /* If no entry in cache, then do the host lookup */
36.214 - if (obj == null) {
36.215 - obj = getAddressFromNameService(host);
36.216 + if (addresses == null) {
36.217 + addresses = getAddressesFromNameService(host);
36.218 }
36.219
36.220 - if (obj == unknown_array)
36.221 + if (addresses == unknown_array)
36.222 throw new UnknownHostException(host);
36.223
36.224 - /* Make a copy of the InetAddress array */
36.225 - objcopy = ((InetAddress [])obj).clone();
36.226 -
36.227 - return (InetAddress [])objcopy;
36.228 + return addresses.clone();
36.229 }
36.230
36.231 - private static Object getAddressFromNameService(String host)
36.232 + private static InetAddress[] getAddressesFromNameService(String host)
36.233 throws UnknownHostException
36.234 {
36.235 - Object obj = null;
36.236 + InetAddress[] addresses = null;
36.237 boolean success = false;
36.238 UnknownHostException ex = null;
36.239
36.240 @@ -1226,16 +1218,16 @@
36.241 // would be blocked until the host is removed
36.242 // from the lookupTable. Then this thread
36.243 // should try to look up the addressCache.
36.244 - // i) if it found the address in the
36.245 + // i) if it found the addresses in the
36.246 // addressCache, checkLookupTable() would
36.247 - // return the address.
36.248 - // ii) if it didn't find the address in the
36.249 + // return the addresses.
36.250 + // ii) if it didn't find the addresses in the
36.251 // addressCache for any reason,
36.252 // it should add the host in the
36.253 // lookupTable and return null so the
36.254 // following code would do a lookup itself.
36.255 - if ((obj = checkLookupTable(host)) == null) {
36.256 - // This is the first thread which looks up the address
36.257 + if ((addresses = checkLookupTable(host)) == null) {
36.258 + // This is the first thread which looks up the addresses
36.259 // this host or the cache entry for this host has been
36.260 // expired so this thread should do the lookup.
36.261 for (NameService nameService : nameServices) {
36.262 @@ -1246,26 +1238,26 @@
36.263 * allocating space when the lookup fails.
36.264 */
36.265
36.266 - obj = nameService.lookupAllHostAddr(host);
36.267 + addresses = nameService.lookupAllHostAddr(host);
36.268 success = true;
36.269 break;
36.270 } catch (UnknownHostException uhe) {
36.271 if (host.equalsIgnoreCase("localhost")) {
36.272 InetAddress[] local = new InetAddress[] { impl.loopbackAddress() };
36.273 - obj = local;
36.274 + addresses = local;
36.275 success = true;
36.276 break;
36.277 }
36.278 else {
36.279 - obj = unknown_array;
36.280 + addresses = unknown_array;
36.281 success = false;
36.282 ex = uhe;
36.283 }
36.284 }
36.285 }
36.286
36.287 - // Cache the address.
36.288 - cacheAddress(host, obj, success);
36.289 + // Cache the addresses.
36.290 + cacheAddresses(host, addresses, success);
36.291 // Delete the host from the lookupTable, and
36.292 // notify all threads waiting for the monitor
36.293 // for lookupTable.
36.294 @@ -1274,13 +1266,13 @@
36.295 throw ex;
36.296 }
36.297
36.298 - return obj;
36.299 + return addresses;
36.300 }
36.301
36.302
36.303 - private static Object checkLookupTable(String host) {
36.304 - // make sure obj is null.
36.305 - Object obj = null;
36.306 + private static InetAddress[] checkLookupTable(String host) {
36.307 + // make sure addresses is null.
36.308 + InetAddress[] addresses = null;
36.309
36.310 synchronized (lookupTable) {
36.311 // If the host isn't in the lookupTable, add it in the
36.312 @@ -1288,11 +1280,11 @@
36.313 // the lookup.
36.314 if (lookupTable.containsKey(host) == false) {
36.315 lookupTable.put(host, null);
36.316 - return obj;
36.317 + return addresses;
36.318 }
36.319
36.320 // If the host is in the lookupTable, it means that another
36.321 - // thread is trying to look up the address of this host.
36.322 + // thread is trying to look up the addresses of this host.
36.323 // This thread should wait.
36.324 while (lookupTable.containsKey(host)) {
36.325 try {
36.326 @@ -1302,18 +1294,18 @@
36.327 }
36.328 }
36.329
36.330 - // The other thread has finished looking up the address of
36.331 - // the host. This thread should retry to get the address
36.332 - // from the addressCache. If it doesn't get the address from
36.333 - // the cache, it will try to look up the address itself.
36.334 - obj = getCachedAddress(host);
36.335 - if (obj == null) {
36.336 + // The other thread has finished looking up the addresses of
36.337 + // the host. This thread should retry to get the addresses
36.338 + // from the addressCache. If it doesn't get the addresses from
36.339 + // the cache, it will try to look up the addresses itself.
36.340 + addresses = getCachedAddresses(host);
36.341 + if (addresses == null) {
36.342 synchronized (lookupTable) {
36.343 lookupTable.put(host, null);
36.344 }
36.345 }
36.346
36.347 - return obj;
36.348 + return addresses;
36.349 }
36.350
36.351 private static void updateLookupTable(String host) {
36.352 @@ -1396,15 +1388,20 @@
36.353 cachedLocalHost = null;
36.354 }
36.355
36.356 - // we are calling getAddressFromNameService directly
36.357 + // we are calling getAddressesFromNameService directly
36.358 // to avoid getting localHost from cache
36.359 if (ret == null) {
36.360 InetAddress[] localAddrs;
36.361 try {
36.362 localAddrs =
36.363 - (InetAddress[]) InetAddress.getAddressFromNameService(local);
36.364 + InetAddress.getAddressesFromNameService(local);
36.365 } catch (UnknownHostException uhe) {
36.366 - throw new UnknownHostException(local + ": " + uhe.getMessage());
36.367 + // Rethrow with a more informative error message.
36.368 + UnknownHostException uhe2 =
36.369 + new UnknownHostException(local + ": " +
36.370 + uhe.getMessage());
36.371 + uhe2.initCause(uhe);
36.372 + throw uhe2;
36.373 }
36.374 cachedLocalHost = localAddrs[0];
36.375 cacheTime = now;
36.376 @@ -1434,8 +1431,8 @@
36.377 /*
36.378 * Load and instantiate an underlying impl class
36.379 */
36.380 - static Object loadImpl(String implName) {
36.381 - Object impl;
36.382 + static InetAddressImpl loadImpl(String implName) {
36.383 + Object impl = null;
36.384
36.385 /*
36.386 * Property "impl.prefix" will be prepended to the classname
36.387 @@ -1446,7 +1443,6 @@
36.388 */
36.389 String prefix = AccessController.doPrivileged(
36.390 new GetPropertyAction("impl.prefix", ""));
36.391 - impl = null;
36.392 try {
36.393 impl = Class.forName("java.net." + prefix + implName).newInstance();
36.394 } catch (ClassNotFoundException e) {
36.395 @@ -1471,7 +1467,7 @@
36.396 }
36.397 }
36.398
36.399 - return impl;
36.400 + return (InetAddressImpl) impl;
36.401 }
36.402
36.403 private void readObjectNoData (ObjectInputStream s) throws
36.404 @@ -1498,13 +1494,8 @@
36.405 class InetAddressImplFactory {
36.406
36.407 static InetAddressImpl create() {
36.408 - Object o;
36.409 - if (isIPv6Supported()) {
36.410 - o = InetAddress.loadImpl("Inet6AddressImpl");
36.411 - } else {
36.412 - o = InetAddress.loadImpl("Inet4AddressImpl");
36.413 - }
36.414 - return (InetAddressImpl)o;
36.415 + return InetAddress.loadImpl(isIPv6Supported() ?
36.416 + "Inet6AddressImpl" : "Inet4AddressImpl");
36.417 }
36.418
36.419 static native boolean isIPv6Supported();
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
37.2 +++ b/src/share/classes/java/nio/file/FileSystemLoopException.java Tue Oct 12 12:51:48 2010 -0700
37.3 @@ -0,0 +1,50 @@
37.4 +/*
37.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
37.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
37.7 + *
37.8 + * This code is free software; you can redistribute it and/or modify it
37.9 + * under the terms of the GNU General Public License version 2 only, as
37.10 + * published by the Free Software Foundation. Oracle designates this
37.11 + * particular file as subject to the "Classpath" exception as provided
37.12 + * by Oracle in the LICENSE file that accompanied this code.
37.13 + *
37.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
37.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
37.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
37.17 + * version 2 for more details (a copy is included in the LICENSE file that
37.18 + * accompanied this code).
37.19 + *
37.20 + * You should have received a copy of the GNU General Public License version
37.21 + * 2 along with this work; if not, write to the Free Software Foundation,
37.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
37.23 + *
37.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
37.25 + * or visit www.oracle.com if you need additional information or have any
37.26 + * questions.
37.27 + */
37.28 +
37.29 +package java.nio.file;
37.30 +
37.31 +/**
37.32 + * Checked exception thrown when a file system loop, or cycle, is encountered.
37.33 + *
37.34 + * @since 1.7
37.35 + * @see Files#walkFileTree
37.36 + */
37.37 +
37.38 +public class FileSystemLoopException
37.39 + extends FileSystemException
37.40 +{
37.41 + private static final long serialVersionUID = 4843039591949217617L;
37.42 +
37.43 + /**
37.44 + * Constructs an instance of this class.
37.45 + *
37.46 + * @param file
37.47 + * a string identifying the file causing the cycle or {@code null} if
37.48 + * not known
37.49 + */
37.50 + public FileSystemLoopException(String file) {
37.51 + super(file);
37.52 + }
37.53 +}
38.1 --- a/src/share/classes/java/nio/file/FileTreeWalker.java Thu Oct 07 15:12:19 2010 -0700
38.2 +++ b/src/share/classes/java/nio/file/FileTreeWalker.java Tue Oct 12 12:51:48 2010 -0700
38.3 @@ -38,7 +38,6 @@
38.4
38.5 class FileTreeWalker {
38.6 private final boolean followLinks;
38.7 - private final boolean detectCycles;
38.8 private final LinkOption[] linkOptions;
38.9 private final FileVisitor<? super Path> visitor;
38.10 private final int maxDepth;
38.11 @@ -48,17 +47,15 @@
38.12 int maxDepth)
38.13 {
38.14 boolean fl = false;
38.15 - boolean dc = false;
38.16 for (FileVisitOption option: options) {
38.17 + // will throw NPE if options contains null
38.18 switch (option) {
38.19 - case FOLLOW_LINKS : fl = true; break;
38.20 - case DETECT_CYCLES : dc = true; break;
38.21 + case FOLLOW_LINKS : fl = true; break;
38.22 default:
38.23 throw new AssertionError("Should not get here");
38.24 }
38.25 }
38.26 this.followLinks = fl;
38.27 - this.detectCycles = fl | dc;
38.28 this.linkOptions = (fl) ? new LinkOption[0] :
38.29 new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
38.30 this.visitor = visitor;
38.31 @@ -68,13 +65,11 @@
38.32 /**
38.33 * Walk file tree starting at the given file
38.34 */
38.35 - void walk(Path start) {
38.36 + void walk(Path start) throws IOException {
38.37 FileVisitResult result = walk(start,
38.38 0,
38.39 new ArrayList<AncestorDirectory>());
38.40 - if (result == null) {
38.41 - throw new NullPointerException("Visitor returned 'null'");
38.42 - }
38.43 + Objects.nonNull(result, "FileVisitor returned null");
38.44 }
38.45
38.46 /**
38.47 @@ -88,11 +83,8 @@
38.48 private FileVisitResult walk(Path file,
38.49 int depth,
38.50 List<AncestorDirectory> ancestors)
38.51 + throws IOException
38.52 {
38.53 - // depth check
38.54 - if (depth > maxDepth)
38.55 - return FileVisitResult.CONTINUE;
38.56 -
38.57 // if attributes are cached then use them if possible
38.58 BasicFileAttributes attrs = null;
38.59 if ((depth > 0) &&
38.60 @@ -137,13 +129,13 @@
38.61 return visitor.visitFileFailed(file, exc);
38.62 }
38.63
38.64 - // file is not a directory so invoke visitFile method
38.65 - if (!attrs.isDirectory()) {
38.66 + // at maximum depth or file is not a directory
38.67 + if (depth >= maxDepth || !attrs.isDirectory()) {
38.68 return visitor.visitFile(file, attrs);
38.69 }
38.70
38.71 - // check for cycles
38.72 - if (detectCycles) {
38.73 + // check for cycles when following links
38.74 + if (followLinks) {
38.75 Object key = attrs.fileKey();
38.76
38.77 // if this directory and ancestor has a file key then we compare
38.78 @@ -153,19 +145,23 @@
38.79 if (key != null && ancestorKey != null) {
38.80 if (key.equals(ancestorKey)) {
38.81 // cycle detected
38.82 - return visitor.visitFile(file, attrs);
38.83 + return visitor.visitFileFailed(file,
38.84 + new FileSystemLoopException(file.toString()));
38.85 }
38.86 } else {
38.87 + boolean isSameFile = false;
38.88 try {
38.89 - if (file.isSameFile(ancestor.file())) {
38.90 - // cycle detected
38.91 - return visitor.visitFile(file, attrs);
38.92 - }
38.93 + isSameFile = file.isSameFile(ancestor.file());
38.94 } catch (IOException x) {
38.95 // ignore
38.96 } catch (SecurityException x) {
38.97 // ignore
38.98 }
38.99 + if (isSameFile) {
38.100 + // cycle detected
38.101 + return visitor.visitFileFailed(file,
38.102 + new FileSystemLoopException(file.toString()));
38.103 + }
38.104 }
38.105 }
38.106
38.107 @@ -181,7 +177,7 @@
38.108 try {
38.109 stream = file.newDirectoryStream();
38.110 } catch (IOException x) {
38.111 - return visitor.preVisitDirectoryFailed(file, x);
38.112 + return visitor.visitFileFailed(file, x);
38.113 } catch (SecurityException x) {
38.114 // ignore, as per spec
38.115 return FileVisitResult.CONTINUE;
38.116 @@ -192,20 +188,14 @@
38.117
38.118 // invoke preVisitDirectory and then visit each entry
38.119 try {
38.120 - result = visitor.preVisitDirectory(file);
38.121 + result = visitor.preVisitDirectory(file, attrs);
38.122 if (result != FileVisitResult.CONTINUE) {
38.123 return result;
38.124 }
38.125
38.126 - // if an I/O occurs during iteration then a CME is thrown. We
38.127 - // need to distinguish this from a CME thrown by the visitor.
38.128 - boolean inAction = false;
38.129 -
38.130 try {
38.131 for (Path entry: stream) {
38.132 - inAction = true;
38.133 result = walk(entry, depth+1, ancestors);
38.134 - inAction = false;
38.135
38.136 // returning null will cause NPE to be thrown
38.137 if (result == null || result == FileVisitResult.TERMINATE)
38.138 @@ -215,17 +205,9 @@
38.139 if (result == FileVisitResult.SKIP_SIBLINGS)
38.140 break;
38.141 }
38.142 - } catch (ConcurrentModificationException x) {
38.143 - // if CME thrown because the iteration failed then remember
38.144 - // the IOException so that it is notified to postVisitDirectory
38.145 - if (!inAction) {
38.146 - // iteration failed
38.147 - Throwable t = x.getCause();
38.148 - if (t instanceof IOException)
38.149 - ioe = (IOException)t;
38.150 - }
38.151 - if (ioe == null)
38.152 - throw x;
38.153 + } catch (DirectoryIteratorException e) {
38.154 + // IOException will be notified to postVisitDirectory
38.155 + ioe = e.getCause();
38.156 }
38.157 } finally {
38.158 try {
38.159 @@ -238,7 +220,7 @@
38.160
38.161 } finally {
38.162 // remove key from trail if doing cycle detection
38.163 - if (detectCycles) {
38.164 + if (followLinks) {
38.165 ancestors.remove(ancestors.size()-1);
38.166 }
38.167 }
39.1 --- a/src/share/classes/java/nio/file/FileVisitOption.java Thu Oct 07 15:12:19 2010 -0700
39.2 +++ b/src/share/classes/java/nio/file/FileVisitOption.java Tue Oct 12 12:51:48 2010 -0700
39.3 @@ -37,9 +37,5 @@
39.4 /**
39.5 * Follow symbolic links.
39.6 */
39.7 - FOLLOW_LINKS,
39.8 - /**
39.9 - * Detect cycles in the file tree.
39.10 - */
39.11 - DETECT_CYCLES;
39.12 + FOLLOW_LINKS;
39.13 }
40.1 --- a/src/share/classes/java/nio/file/FileVisitor.java Thu Oct 07 15:12:19 2010 -0700
40.2 +++ b/src/share/classes/java/nio/file/FileVisitor.java Tue Oct 12 12:51:48 2010 -0700
40.3 @@ -40,33 +40,28 @@
40.4 * Path start = ...
40.5 * Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
40.6 * @Override
40.7 - * public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
40.8 - * try {
40.9 - * file.delete();
40.10 - * } catch (IOException exc) {
40.11 - * // failed to delete, do error handling here
40.12 - * }
40.13 + * public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
40.14 + * throws IOException
40.15 + * {
40.16 + * file.delete();
40.17 * return FileVisitResult.CONTINUE;
40.18 * }
40.19 * @Override
40.20 - * public FileVisitResult postVisitDirectory(Path dir, IOException e) {
40.21 - * if (e == null) {
40.22 - * try {
40.23 - * dir.delete();
40.24 - * } catch (IOException exc) {
40.25 - * // failed to delete, do error handling here
40.26 - * }
40.27 - * } else {
40.28 + * public FileVisitResult postVisitDirectory(Path dir, IOException e)
40.29 + * throws IOException
40.30 + * {
40.31 + * if (e != null) {
40.32 * // directory iteration failed
40.33 + * throw e;
40.34 * }
40.35 + * dir.delete();
40.36 * return FileVisitResult.CONTINUE;
40.37 * }
40.38 * });
40.39 * </pre>
40.40 - * <p> Furthermore, suppose we want to copy a file tree rooted at a source
40.41 - * directory to a target location. In that case, symbolic links should be
40.42 - * followed and the target directory should be created before the entries in
40.43 - * the directory are copied.
40.44 + * <p> Furthermore, suppose we want to copy a file tree to a target location.
40.45 + * In that case, symbolic links should be followed and the target directory
40.46 + * should be created before the entries in the directory are copied.
40.47 * <pre>
40.48 * final Path source = ...
40.49 * final Path target = ...
40.50 @@ -74,25 +69,21 @@
40.51 * Files.walkFileTree(source, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
40.52 * new SimpleFileVisitor<Path>() {
40.53 * @Override
40.54 - * public FileVisitResult preVisitDirectory(Path dir) {
40.55 + * public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
40.56 + * throws IOException
40.57 + * {
40.58 * try {
40.59 * dir.copyTo(target.resolve(source.relativize(dir)));
40.60 * } catch (FileAlreadyExistsException e) {
40.61 * // ignore
40.62 - * } catch (IOException e) {
40.63 - * // copy failed, do error handling here
40.64 - * // skip rest of directory and descendants
40.65 - * return SKIP_SUBTREE;
40.66 * }
40.67 * return CONTINUE;
40.68 * }
40.69 * @Override
40.70 - * public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
40.71 - * try {
40.72 - * file.copyTo(target.resolve(source.relativize(file)));
40.73 - * } catch (IOException e) {
40.74 - * // copy failed, do error handling here
40.75 - * }
40.76 + * public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
40.77 + * throws IOException
40.78 + * {
40.79 + * file.copyTo(target.resolve(source.relativize(file)));
40.80 * return CONTINUE;
40.81 * }
40.82 * });
40.83 @@ -114,22 +105,16 @@
40.84 *
40.85 * @param dir
40.86 * a reference to the directory
40.87 + * @param attrs
40.88 + * the directory's basic attributes
40.89 *
40.90 * @return the visit result
40.91 + *
40.92 + * @throws IOException
40.93 + * if an I/O error occurs
40.94 */
40.95 - FileVisitResult preVisitDirectory(T dir);
40.96 -
40.97 - /**
40.98 - * Invoked for a directory that could not be opened.
40.99 - *
40.100 - * @param dir
40.101 - * a reference to the directory
40.102 - * @param exc
40.103 - * the I/O exception thrown from the attempt to open the directory
40.104 - *
40.105 - * @return the visit result
40.106 - */
40.107 - FileVisitResult preVisitDirectoryFailed(T dir, IOException exc);
40.108 + FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
40.109 + throws IOException;
40.110
40.111 /**
40.112 * Invoked for a file in a directory.
40.113 @@ -140,21 +125,30 @@
40.114 * the file's basic attributes
40.115 *
40.116 * @return the visit result
40.117 + *
40.118 + * @throws IOException
40.119 + * if an I/O error occurs
40.120 */
40.121 - FileVisitResult visitFile(T file, BasicFileAttributes attrs);
40.122 + FileVisitResult visitFile(T file, BasicFileAttributes attrs)
40.123 + throws IOException;
40.124
40.125 /**
40.126 - * Invoked for a file when its basic file attributes could not be read.
40.127 + * Invoked for a file that could not be visited. This method is invoked
40.128 + * if the file's attributes could not be read, the file is a directory
40.129 + * that could not be opened, and other reasons.
40.130 *
40.131 * @param file
40.132 * a reference to the file
40.133 * @param exc
40.134 - * the I/O exception thrown from the attempt to read the file
40.135 - * attributes
40.136 + * the I/O exception that prevented the file from being visited
40.137 *
40.138 * @return the visit result
40.139 + *
40.140 + * @throws IOException
40.141 + * if an I/O error occurs
40.142 */
40.143 - FileVisitResult visitFileFailed(T file, IOException exc);
40.144 + FileVisitResult visitFileFailed(T file, IOException exc)
40.145 + throws IOException;
40.146
40.147 /**
40.148 * Invoked for a directory after entries in the directory, and all of their
40.149 @@ -171,6 +165,10 @@
40.150 * of the directory to complete prematurely
40.151 *
40.152 * @return the visit result
40.153 + *
40.154 + * @throws IOException
40.155 + * if an I/O error occurs
40.156 */
40.157 - FileVisitResult postVisitDirectory(T dir, IOException exc);
40.158 + FileVisitResult postVisitDirectory(T dir, IOException exc)
40.159 + throws IOException;
40.160 }
41.1 --- a/src/share/classes/java/nio/file/Files.java Thu Oct 07 15:12:19 2010 -0700
41.2 +++ b/src/share/classes/java/nio/file/Files.java Tue Oct 12 12:51:48 2010 -0700
41.3 @@ -135,9 +135,9 @@
41.4 * FileVisitor} invoked for each file encountered. File tree traversal
41.5 * completes when all accessible files in the tree have been visited, or a
41.6 * visit method returns a result of {@link FileVisitResult#TERMINATE
41.7 - * TERMINATE}. Where a visit method terminates due an uncaught error or
41.8 - * runtime exception then the traversal is terminated and the error or
41.9 - * exception is propagated to the caller of this method.
41.10 + * TERMINATE}. Where a visit method terminates due an {@code IOException},
41.11 + * an uncaught error, or runtime exception, then the traversal is terminated
41.12 + * and the error or exception is propagated to the caller of this method.
41.13 *
41.14 * <p> For each file encountered this method attempts to gets its {@link
41.15 * java.nio.file.attribute.BasicFileAttributes}. If the file is not a
41.16 @@ -146,12 +146,10 @@
41.17 * due to an I/O exception, then the {@link FileVisitor#visitFileFailed
41.18 * visitFileFailed} method is invoked with the I/O exception.
41.19 *
41.20 - * <p> Where the file is a directory, this method attempts to open it by
41.21 - * invoking its {@link Path#newDirectoryStream newDirectoryStream} method.
41.22 - * Where the directory could not be opened, due to an {@code IOException},
41.23 - * then the {@link FileVisitor#preVisitDirectoryFailed preVisitDirectoryFailed}
41.24 - * method is invoked with the I/O exception, after which, the file tree walk
41.25 - * continues, by default, at the next <em>sibling</em> of the directory.
41.26 + * <p> Where the file is a directory, and the directory could not be opened,
41.27 + * then the {@code visitFileFailed} method is invoked with the I/O exception,
41.28 + * after which, the file tree walk continues, by default, at the next
41.29 + * <em>sibling</em> of the directory.
41.30 *
41.31 * <p> Where the directory is opened successfully, then the entries in the
41.32 * directory, and their <em>descendants</em> are visited. When all entries
41.33 @@ -171,26 +169,25 @@
41.34 * method is invoked as specified above).
41.35 *
41.36 * <p> If the {@code options} parameter contains the {@link
41.37 - * FileVisitOption#DETECT_CYCLES DETECT_CYCLES} or {@link
41.38 - * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} options then this method keeps
41.39 + * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then this method keeps
41.40 * track of directories visited so that cycles can be detected. A cycle
41.41 * arises when there is an entry in a directory that is an ancestor of the
41.42 * directory. Cycle detection is done by recording the {@link
41.43 * java.nio.file.attribute.BasicFileAttributes#fileKey file-key} of directories,
41.44 * or if file keys are not available, by invoking the {@link Path#isSameFile
41.45 * isSameFile} method to test if a directory is the same file as an
41.46 - * ancestor. When a cycle is detected the {@link FileVisitor#visitFile
41.47 - * visitFile} is invoked with the attributes of the directory. The {@link
41.48 - * java.nio.file.attribute.BasicFileAttributes#isDirectory isDirectory}
41.49 - * method may be used to test if the file is a directory and that a cycle is
41.50 - * detected. The {@code preVisitDirectory} and {@code postVisitDirectory}
41.51 - * methods are not invoked.
41.52 + * ancestor. When a cycle is detected it is treated as an I/O error, and the
41.53 + * {@link FileVisitor#visitFileFailed visitFileFailed} method is invoked with
41.54 + * an instance of {@link FileSystemLoopException}.
41.55 *
41.56 * <p> The {@code maxDepth} parameter is the maximum number of levels of
41.57 * directories to visit. A value of {@code 0} means that only the starting
41.58 * file is visited, unless denied by the security manager. A value of
41.59 * {@link Integer#MAX_VALUE MAX_VALUE} may be used to indicate that all
41.60 - * levels should be visited.
41.61 + * levels should be visited. The {@code visitFile} method is invoked for all
41.62 + * files, including directories, encountered at {@code maxDepth}, unless the
41.63 + * basic file attributes cannot be read, in which case the {@code
41.64 + * visitFileFailed} method is invoked.
41.65 *
41.66 * <p> If a visitor returns a result of {@code null} then {@code
41.67 * NullPointerException} is thrown.
41.68 @@ -215,11 +212,14 @@
41.69 * In the case of the default provider, the {@link
41.70 * SecurityManager#checkRead(String) checkRead} method is invoked
41.71 * to check read access to the directory.
41.72 + * @throws IOException
41.73 + * If an I/O error is thrown by a visitor method
41.74 */
41.75 public static void walkFileTree(Path start,
41.76 Set<FileVisitOption> options,
41.77 int maxDepth,
41.78 FileVisitor<? super Path> visitor)
41.79 + throws IOException
41.80 {
41.81 if (maxDepth < 0)
41.82 throw new IllegalArgumentException("'maxDepth' is negative");
41.83 @@ -245,8 +245,12 @@
41.84 * In the case of the default provider, the {@link
41.85 * SecurityManager#checkRead(String) checkRead} method is invoked
41.86 * to check read access to the directory.
41.87 + * @throws IOException
41.88 + * If an I/O error is thrown by a visitor method
41.89 */
41.90 - public static void walkFileTree(Path start, FileVisitor<? super Path> visitor) {
41.91 + public static void walkFileTree(Path start, FileVisitor<? super Path> visitor)
41.92 + throws IOException
41.93 + {
41.94 walkFileTree(start,
41.95 EnumSet.noneOf(FileVisitOption.class),
41.96 Integer.MAX_VALUE,
42.1 --- a/src/share/classes/java/nio/file/SimpleFileVisitor.java Thu Oct 07 15:12:19 2010 -0700
42.2 +++ b/src/share/classes/java/nio/file/SimpleFileVisitor.java Tue Oct 12 12:51:48 2010 -0700
42.3 @@ -27,7 +27,7 @@
42.4
42.5 import java.nio.file.attribute.BasicFileAttributes;
42.6 import java.io.IOException;
42.7 -import java.io.IOError;
42.8 +import java.util.Objects;
42.9
42.10 /**
42.11 * A simple visitor of files with default behavior to visit all files and to
42.12 @@ -48,70 +48,47 @@
42.13 }
42.14
42.15 /**
42.16 - * Throws NullPointerException if obj is null.
42.17 - */
42.18 - private static void checkNotNull(Object obj) {
42.19 - if (obj == null)
42.20 - throw new NullPointerException();
42.21 - }
42.22 -
42.23 - /**
42.24 * Invoked for a directory before entries in the directory are visited.
42.25 *
42.26 * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
42.27 * CONTINUE}.
42.28 */
42.29 @Override
42.30 - public FileVisitResult preVisitDirectory(T dir) {
42.31 - checkNotNull(dir);
42.32 + public FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
42.33 + throws IOException
42.34 + {
42.35 + Objects.nonNull(dir);
42.36 + Objects.nonNull(attrs);
42.37 return FileVisitResult.CONTINUE;
42.38 }
42.39
42.40 /**
42.41 - * Invoked for a directory that could not be opened.
42.42 - *
42.43 - * <p> Unless overridden, this method throws {@link IOError} with the I/O
42.44 - * exception as cause.
42.45 - *
42.46 - * @throws IOError
42.47 - * with the I/O exception thrown when the attempt to open the
42.48 - * directory failed
42.49 - */
42.50 - @Override
42.51 - public FileVisitResult preVisitDirectoryFailed(T dir, IOException exc) {
42.52 - checkNotNull(dir);
42.53 - checkNotNull(exc);
42.54 - throw new IOError(exc);
42.55 - }
42.56 -
42.57 - /**
42.58 * Invoked for a file in a directory.
42.59 *
42.60 * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
42.61 * CONTINUE}.
42.62 */
42.63 @Override
42.64 - public FileVisitResult visitFile(T file, BasicFileAttributes attrs) {
42.65 - checkNotNull(file);
42.66 - checkNotNull(attrs);
42.67 + public FileVisitResult visitFile(T file, BasicFileAttributes attrs)
42.68 + throws IOException
42.69 + {
42.70 + Objects.nonNull(file);
42.71 + Objects.nonNull(attrs);
42.72 return FileVisitResult.CONTINUE;
42.73 }
42.74
42.75 /**
42.76 - * Invoked for a file when its basic file attributes could not be read.
42.77 + * Invoked for a file that could not be visited.
42.78 *
42.79 - * <p> Unless overridden, this method throws {@link IOError} with the I/O
42.80 - * exception as cause.
42.81 - *
42.82 - * @throws IOError
42.83 - * with the I/O exception thrown when the attempt to read the file
42.84 - * attributes failed
42.85 + * <p> Unless overridden, this method re-throws the I/O exception that prevented
42.86 + * the file from being visited.
42.87 */
42.88 @Override
42.89 - public FileVisitResult visitFileFailed(T file, IOException exc) {
42.90 - checkNotNull(file);
42.91 - checkNotNull(exc);
42.92 - throw new IOError(exc);
42.93 + public FileVisitResult visitFileFailed(T file, IOException exc)
42.94 + throws IOException
42.95 + {
42.96 + Objects.nonNull(file);
42.97 + throw exc;
42.98 }
42.99
42.100 /**
42.101 @@ -120,18 +97,16 @@
42.102 *
42.103 * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
42.104 * CONTINUE} if the directory iteration completes without an I/O exception;
42.105 - * otherwise this method throws {@link IOError} with the I/O exception as
42.106 - * cause.
42.107 - *
42.108 - * @throws IOError
42.109 - * with the I/O exception thrown when iteration of the directory
42.110 - * completed prematurely due to an I/O error
42.111 + * otherwise this method re-throws the I/O exception that caused the iteration
42.112 + * of the directory to terminate prematurely.
42.113 */
42.114 @Override
42.115 - public FileVisitResult postVisitDirectory(T dir, IOException exc) {
42.116 - checkNotNull(dir);
42.117 + public FileVisitResult postVisitDirectory(T dir, IOException exc)
42.118 + throws IOException
42.119 + {
42.120 + Objects.nonNull(dir);
42.121 if (exc != null)
42.122 - throw new IOError(exc);
42.123 + throw exc;
42.124 return FileVisitResult.CONTINUE;
42.125 }
42.126 }
43.1 --- a/src/share/classes/java/sql/DatabaseMetaData.java Thu Oct 07 15:12:19 2010 -0700
43.2 +++ b/src/share/classes/java/sql/DatabaseMetaData.java Tue Oct 12 12:51:48 2010 -0700
43.3 @@ -3643,7 +3643,7 @@
43.4
43.5 /**
43.6 * Retrieves whether a generated key will always be returned if the column
43.7 - * name(s) or indexe(s) specified for the auto generated key column(s)
43.8 + * name(s) or index(es) specified for the auto generated key column(s)
43.9 * are valid and the statement succeeds. The key that is returned may or
43.10 * may not be based on the column(s) for the auto generated key.
43.11 * Consult your JDBC driver documentation for additional details.
44.1 --- a/src/share/classes/java/sql/Statement.java Thu Oct 07 15:12:19 2010 -0700
44.2 +++ b/src/share/classes/java/sql/Statement.java Tue Oct 12 12:51:48 2010 -0700
44.3 @@ -1051,9 +1051,9 @@
44.4
44.5 /**
44.6 * Returns a value indicating whether this {@code Statement} will be
44.7 - * closed when all dependent objects such as resultsets are closed.
44.8 + * closed when all its dependent result sets are closed.
44.9 * @return {@code true} if the {@code Statement} will be closed when all
44.10 - * of its dependent objects are closed; {@code false} otherwise
44.11 + * of its dependent result sets are closed; {@code false} otherwise
44.12 * @throws SQLException if this method is called on a closed
44.13 * {@code Statement}
44.14 * @since 1.7
45.1 --- a/src/share/classes/java/util/Locale.java Thu Oct 07 15:12:19 2010 -0700
45.2 +++ b/src/share/classes/java/util/Locale.java Tue Oct 12 12:51:48 2010 -0700
45.3 @@ -569,6 +569,9 @@
45.4 * @exception NullPointerException thrown if any argument is null.
45.5 */
45.6 public Locale(String language, String country, String variant) {
45.7 + if (language== null || country == null || variant == null) {
45.8 + throw new NullPointerException();
45.9 + }
45.10 _baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), "", country, variant);
45.11 _extensions = getCompatibilityExtensions(language, "", country, variant);
45.12 }
46.1 --- a/src/share/classes/java/util/ResourceBundle.java Thu Oct 07 15:12:19 2010 -0700
46.2 +++ b/src/share/classes/java/util/ResourceBundle.java Tue Oct 12 12:51:48 2010 -0700
46.3 @@ -293,16 +293,6 @@
46.4 = new ConcurrentHashMap<CacheKey, BundleReference>(INITIAL_CACHE_SIZE);
46.5
46.6 /**
46.7 - * This ConcurrentMap is used to keep multiple threads from loading the
46.8 - * same bundle concurrently. The table entries are <CacheKey, Thread>
46.9 - * where CacheKey is the key for the bundle that is under construction
46.10 - * and Thread is the thread that is constructing the bundle.
46.11 - * This list is manipulated in findBundleInCache and putBundleInCache.
46.12 - */
46.13 - private static final ConcurrentMap<CacheKey, Thread> underConstruction
46.14 - = new ConcurrentHashMap<CacheKey, Thread>();
46.15 -
46.16 - /**
46.17 * Queue for reference objects referring to class loaders or bundles.
46.18 */
46.19 private static final ReferenceQueue referenceQueue = new ReferenceQueue();
46.20 @@ -1381,7 +1371,7 @@
46.21 boolean expiredBundle = false;
46.22
46.23 // First, look up the cache to see if it's in the cache, without
46.24 - // declaring beginLoading.
46.25 + // attempting to load bundle.
46.26 cacheKey.setLocale(targetLocale);
46.27 ResourceBundle bundle = findBundleInCache(cacheKey, control);
46.28 if (isValidBundle(bundle)) {
46.29 @@ -1408,56 +1398,25 @@
46.30 CacheKey constKey = (CacheKey) cacheKey.clone();
46.31
46.32 try {
46.33 - // Try declaring loading. If beginLoading() returns true,
46.34 - // then we can proceed. Otherwise, we need to take a look
46.35 - // at the cache again to see if someone else has loaded
46.36 - // the bundle and put it in the cache while we've been
46.37 - // waiting for other loading work to complete.
46.38 - while (!beginLoading(constKey)) {
46.39 - bundle = findBundleInCache(cacheKey, control);
46.40 - if (bundle == null) {
46.41 - continue;
46.42 + bundle = loadBundle(cacheKey, formats, control, expiredBundle);
46.43 + if (bundle != null) {
46.44 + if (bundle.parent == null) {
46.45 + bundle.setParent(parent);
46.46 }
46.47 - if (bundle == NONEXISTENT_BUNDLE) {
46.48 - // If the bundle is NONEXISTENT_BUNDLE, the bundle doesn't exist.
46.49 - return parent;
46.50 - }
46.51 - expiredBundle = bundle.expired;
46.52 - if (!expiredBundle) {
46.53 - if (bundle.parent == parent) {
46.54 - return bundle;
46.55 - }
46.56 - BundleReference bundleRef = cacheList.get(cacheKey);
46.57 - if (bundleRef != null && bundleRef.get() == bundle) {
46.58 - cacheList.remove(cacheKey, bundleRef);
46.59 - }
46.60 - }
46.61 + bundle.locale = targetLocale;
46.62 + bundle = putBundleInCache(cacheKey, bundle, control);
46.63 + return bundle;
46.64 }
46.65
46.66 - try {
46.67 - bundle = loadBundle(cacheKey, formats, control, expiredBundle);
46.68 - if (bundle != null) {
46.69 - if (bundle.parent == null) {
46.70 - bundle.setParent(parent);
46.71 - }
46.72 - bundle.locale = targetLocale;
46.73 - bundle = putBundleInCache(cacheKey, bundle, control);
46.74 - return bundle;
46.75 - }
46.76 -
46.77 - // Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle
46.78 - // instance for the locale.
46.79 - putBundleInCache(cacheKey, NONEXISTENT_BUNDLE, control);
46.80 - } finally {
46.81 - endLoading(constKey);
46.82 - }
46.83 + // Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle
46.84 + // instance for the locale.
46.85 + putBundleInCache(cacheKey, NONEXISTENT_BUNDLE, control);
46.86 } finally {
46.87 if (constKey.getCause() instanceof InterruptedException) {
46.88 Thread.currentThread().interrupt();
46.89 }
46.90 }
46.91 }
46.92 - assert underConstruction.get(cacheKey) != Thread.currentThread();
46.93 return parent;
46.94 }
46.95
46.96 @@ -1465,7 +1424,6 @@
46.97 List<String> formats,
46.98 Control control,
46.99 boolean reload) {
46.100 - assert underConstruction.get(cacheKey) == Thread.currentThread();
46.101
46.102 // Here we actually load the bundle in the order of formats
46.103 // specified by the getFormats() value.
46.104 @@ -1498,7 +1456,6 @@
46.105 break;
46.106 }
46.107 }
46.108 - assert underConstruction.get(cacheKey) == Thread.currentThread();
46.109
46.110 return bundle;
46.111 }
46.112 @@ -1530,57 +1487,6 @@
46.113 }
46.114
46.115 /**
46.116 - * Declares the beginning of actual resource bundle loading. This method
46.117 - * returns true if the declaration is successful and the current thread has
46.118 - * been put in underConstruction. If someone else has already begun
46.119 - * loading, this method waits until that loading work is complete and
46.120 - * returns false.
46.121 - */
46.122 - private static final boolean beginLoading(CacheKey constKey) {
46.123 - Thread me = Thread.currentThread();
46.124 - Thread worker;
46.125 - // We need to declare by putting the current Thread (me) to
46.126 - // underConstruction that we are working on loading the specified
46.127 - // resource bundle. If we are already working the loading, it means
46.128 - // that the resource loading requires a recursive call. In that case,
46.129 - // we have to proceed. (4300693)
46.130 - if (((worker = underConstruction.putIfAbsent(constKey, me)) == null)
46.131 - || worker == me) {
46.132 - return true;
46.133 - }
46.134 -
46.135 - // If someone else is working on the loading, wait until
46.136 - // the Thread finishes the bundle loading.
46.137 - synchronized (worker) {
46.138 - while (underConstruction.get(constKey) == worker) {
46.139 - try {
46.140 - worker.wait();
46.141 - } catch (InterruptedException e) {
46.142 - // record the interruption
46.143 - constKey.setCause(e);
46.144 - }
46.145 - }
46.146 - }
46.147 - return false;
46.148 - }
46.149 -
46.150 - /**
46.151 - * Declares the end of the bundle loading. This method calls notifyAll
46.152 - * for those who are waiting for this completion.
46.153 - */
46.154 - private static final void endLoading(CacheKey constKey) {
46.155 - // Remove this Thread from the underConstruction map and wake up
46.156 - // those who have been waiting for me to complete this bundle
46.157 - // loading.
46.158 - Thread me = Thread.currentThread();
46.159 - assert (underConstruction.get(constKey) == me);
46.160 - underConstruction.remove(constKey);
46.161 - synchronized (me) {
46.162 - me.notifyAll();
46.163 - }
46.164 - }
46.165 -
46.166 - /**
46.167 * Throw a MissingResourceException with proper message
46.168 */
46.169 private static final void throwMissingResourceException(String baseName,
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
47.2 +++ b/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java Tue Oct 12 12:51:48 2010 -0700
47.3 @@ -0,0 +1,1445 @@
47.4 +/*
47.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
47.6 + *
47.7 + * This code is free software; you can redistribute it and/or modify it
47.8 + * under the terms of the GNU General Public License version 2 only, as
47.9 + * published by the Free Software Foundation. Oracle designates this
47.10 + * particular file as subject to the "Classpath" exception as provided
47.11 + * by Oracle in the LICENSE file that accompanied this code.
47.12 + *
47.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
47.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
47.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
47.16 + * version 2 for more details (a copy is included in the LICENSE file that
47.17 + * accompanied this code).
47.18 + *
47.19 + * You should have received a copy of the GNU General Public License version
47.20 + * 2 along with this work; if not, write to the Free Software Foundation,
47.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
47.22 + *
47.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
47.24 + * or visit www.oracle.com if you need additional information or have any
47.25 + * questions.
47.26 + */
47.27 +
47.28 +/*
47.29 + * This file is available under and governed by the GNU General Public
47.30 + * License version 2 only, as published by the Free Software Foundation.
47.31 + * However, the following notice accompanied the original version of this
47.32 + * file:
47.33 + *
47.34 + * Written by Doug Lea and Martin Buchholz with assistance from members of
47.35 + * JCP JSR-166 Expert Group and released to the public domain, as explained
47.36 + * at http://creativecommons.org/licenses/publicdomain
47.37 + */
47.38 +
47.39 +package java.util.concurrent;
47.40 +
47.41 +import java.util.AbstractCollection;
47.42 +import java.util.ArrayList;
47.43 +import java.util.Collection;
47.44 +import java.util.ConcurrentModificationException;
47.45 +import java.util.Deque;
47.46 +import java.util.Iterator;
47.47 +import java.util.NoSuchElementException;
47.48 +import java.util.Queue;
47.49 +
47.50 +/**
47.51 + * An unbounded concurrent {@linkplain Deque deque} based on linked nodes.
47.52 + * Concurrent insertion, removal, and access operations execute safely
47.53 + * across multiple threads.
47.54 + * A {@code ConcurrentLinkedDeque} is an appropriate choice when
47.55 + * many threads will share access to a common collection.
47.56 + * Like most other concurrent collection implementations, this class
47.57 + * does not permit the use of {@code null} elements.
47.58 + *
47.59 + * <p>Iterators are <i>weakly consistent</i>, returning elements
47.60 + * reflecting the state of the deque at some point at or since the
47.61 + * creation of the iterator. They do <em>not</em> throw {@link
47.62 + * java.util.ConcurrentModificationException
47.63 + * ConcurrentModificationException}, and may proceed concurrently with
47.64 + * other operations.
47.65 + *
47.66 + * <p>Beware that, unlike in most collections, the {@code size}
47.67 + * method is <em>NOT</em> a constant-time operation. Because of the
47.68 + * asynchronous nature of these deques, determining the current number
47.69 + * of elements requires a traversal of the elements.
47.70 + *
47.71 + * <p>This class and its iterator implement all of the <em>optional</em>
47.72 + * methods of the {@link Deque} and {@link Iterator} interfaces.
47.73 + *
47.74 + * <p>Memory consistency effects: As with other concurrent collections,
47.75 + * actions in a thread prior to placing an object into a
47.76 + * {@code ConcurrentLinkedDeque}
47.77 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
47.78 + * actions subsequent to the access or removal of that element from
47.79 + * the {@code ConcurrentLinkedDeque} in another thread.
47.80 + *
47.81 + * <p>This class is a member of the
47.82 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
47.83 + * Java Collections Framework</a>.
47.84 + *
47.85 + * @since 1.7
47.86 + * @author Doug Lea
47.87 + * @author Martin Buchholz
47.88 + * @param <E> the type of elements held in this collection
47.89 + */
47.90 +
47.91 +public class ConcurrentLinkedDeque<E>
47.92 + extends AbstractCollection<E>
47.93 + implements Deque<E>, java.io.Serializable {
47.94 +
47.95 + /*
47.96 + * This is an implementation of a concurrent lock-free deque
47.97 + * supporting interior removes but not interior insertions, as
47.98 + * required to support the entire Deque interface.
47.99 + *
47.100 + * We extend the techniques developed for ConcurrentLinkedQueue and
47.101 + * LinkedTransferQueue (see the internal docs for those classes).
47.102 + * Understanding the ConcurrentLinkedQueue implementation is a
47.103 + * prerequisite for understanding the implementation of this class.
47.104 + *
47.105 + * The data structure is a symmetrical doubly-linked "GC-robust"
47.106 + * linked list of nodes. We minimize the number of volatile writes
47.107 + * using two techniques: advancing multiple hops with a single CAS
47.108 + * and mixing volatile and non-volatile writes of the same memory
47.109 + * locations.
47.110 + *
47.111 + * A node contains the expected E ("item") and links to predecessor
47.112 + * ("prev") and successor ("next") nodes:
47.113 + *
47.114 + * class Node<E> { volatile Node<E> prev, next; volatile E item; }
47.115 + *
47.116 + * A node p is considered "live" if it contains a non-null item
47.117 + * (p.item != null). When an item is CASed to null, the item is
47.118 + * atomically logically deleted from the collection.
47.119 + *
47.120 + * At any time, there is precisely one "first" node with a null
47.121 + * prev reference that terminates any chain of prev references
47.122 + * starting at a live node. Similarly there is precisely one
47.123 + * "last" node terminating any chain of next references starting at
47.124 + * a live node. The "first" and "last" nodes may or may not be live.
47.125 + * The "first" and "last" nodes are always mutually reachable.
47.126 + *
47.127 + * A new element is added atomically by CASing the null prev or
47.128 + * next reference in the first or last node to a fresh node
47.129 + * containing the element. The element's node atomically becomes
47.130 + * "live" at that point.
47.131 + *
47.132 + * A node is considered "active" if it is a live node, or the
47.133 + * first or last node. Active nodes cannot be unlinked.
47.134 + *
47.135 + * A "self-link" is a next or prev reference that is the same node:
47.136 + * p.prev == p or p.next == p
47.137 + * Self-links are used in the node unlinking process. Active nodes
47.138 + * never have self-links.
47.139 + *
47.140 + * A node p is active if and only if:
47.141 + *
47.142 + * p.item != null ||
47.143 + * (p.prev == null && p.next != p) ||
47.144 + * (p.next == null && p.prev != p)
47.145 + *
47.146 + * The deque object has two node references, "head" and "tail".
47.147 + * The head and tail are only approximations to the first and last
47.148 + * nodes of the deque. The first node can always be found by
47.149 + * following prev pointers from head; likewise for tail. However,
47.150 + * it is permissible for head and tail to be referring to deleted
47.151 + * nodes that have been unlinked and so may not be reachable from
47.152 + * any live node.
47.153 + *
47.154 + * There are 3 stages of node deletion;
47.155 + * "logical deletion", "unlinking", and "gc-unlinking".
47.156 + *
47.157 + * 1. "logical deletion" by CASing item to null atomically removes
47.158 + * the element from the collection, and makes the containing node
47.159 + * eligible for unlinking.
47.160 + *
47.161 + * 2. "unlinking" makes a deleted node unreachable from active
47.162 + * nodes, and thus eventually reclaimable by GC. Unlinked nodes
47.163 + * may remain reachable indefinitely from an iterator.
47.164 + *
47.165 + * Physical node unlinking is merely an optimization (albeit a
47.166 + * critical one), and so can be performed at our convenience. At
47.167 + * any time, the set of live nodes maintained by prev and next
47.168 + * links are identical, that is, the live nodes found via next
47.169 + * links from the first node is equal to the elements found via
47.170 + * prev links from the last node. However, this is not true for
47.171 + * nodes that have already been logically deleted - such nodes may
47.172 + * be reachable in one direction only.
47.173 + *
47.174 + * 3. "gc-unlinking" takes unlinking further by making active
47.175 + * nodes unreachable from deleted nodes, making it easier for the
47.176 + * GC to reclaim future deleted nodes. This step makes the data
47.177 + * structure "gc-robust", as first described in detail by Boehm
47.178 + * (http://portal.acm.org/citation.cfm?doid=503272.503282).
47.179 + *
47.180 + * GC-unlinked nodes may remain reachable indefinitely from an
47.181 + * iterator, but unlike unlinked nodes, are never reachable from
47.182 + * head or tail.
47.183 + *
47.184 + * Making the data structure GC-robust will eliminate the risk of
47.185 + * unbounded memory retention with conservative GCs and is likely
47.186 + * to improve performance with generational GCs.
47.187 + *
47.188 + * When a node is dequeued at either end, e.g. via poll(), we would
47.189 + * like to break any references from the node to active nodes. We
47.190 + * develop further the use of self-links that was very effective in
47.191 + * other concurrent collection classes. The idea is to replace
47.192 + * prev and next pointers with special values that are interpreted
47.193 + * to mean off-the-list-at-one-end. These are approximations, but
47.194 + * good enough to preserve the properties we want in our
47.195 + * traversals, e.g. we guarantee that a traversal will never visit
47.196 + * the same element twice, but we don't guarantee whether a
47.197 + * traversal that runs out of elements will be able to see more
47.198 + * elements later after enqueues at that end. Doing gc-unlinking
47.199 + * safely is particularly tricky, since any node can be in use
47.200 + * indefinitely (for example by an iterator). We must ensure that
47.201 + * the nodes pointed at by head/tail never get gc-unlinked, since
47.202 + * head/tail are needed to get "back on track" by other nodes that
47.203 + * are gc-unlinked. gc-unlinking accounts for much of the
47.204 + * implementation complexity.
47.205 + *
47.206 + * Since neither unlinking nor gc-unlinking are necessary for
47.207 + * correctness, there are many implementation choices regarding
47.208 + * frequency (eagerness) of these operations. Since volatile
47.209 + * reads are likely to be much cheaper than CASes, saving CASes by
47.210 + * unlinking multiple adjacent nodes at a time may be a win.
47.211 + * gc-unlinking can be performed rarely and still be effective,
47.212 + * since it is most important that long chains of deleted nodes
47.213 + * are occasionally broken.
47.214 + *
47.215 + * The actual representation we use is that p.next == p means to
47.216 + * goto the first node (which in turn is reached by following prev
47.217 + * pointers from head), and p.next == null && p.prev == p means
47.218 + * that the iteration is at an end and that p is a (final static)
47.219 + * dummy node, NEXT_TERMINATOR, and not the last active node.
47.220 + * Finishing the iteration when encountering such a TERMINATOR is
47.221 + * good enough for read-only traversals, so such traversals can use
47.222 + * p.next == null as the termination condition. When we need to
47.223 + * find the last (active) node, for enqueueing a new node, we need
47.224 + * to check whether we have reached a TERMINATOR node; if so,
47.225 + * restart traversal from tail.
47.226 + *
47.227 + * The implementation is completely directionally symmetrical,
47.228 + * except that most public methods that iterate through the list
47.229 + * follow next pointers ("forward" direction).
47.230 + *
47.231 + * We believe (without full proof) that all single-element deque
47.232 + * operations (e.g., addFirst, peekLast, pollLast) are linearizable
47.233 + * (see Herlihy and Shavit's book). However, some combinations of
47.234 + * operations are known not to be linearizable. In particular,
47.235 + * when an addFirst(A) is racing with pollFirst() removing B, it is
47.236 + * possible for an observer iterating over the elements to observe
47.237 + * A B C and subsequently observe A C, even though no interior
47.238 + * removes are ever performed. Nevertheless, iterators behave
47.239 + * reasonably, providing the "weakly consistent" guarantees.
47.240 + *
47.241 + * Empirically, microbenchmarks suggest that this class adds about
47.242 + * 40% overhead relative to ConcurrentLinkedQueue, which feels as
47.243 + * good as we can hope for.
47.244 + */
47.245 +
47.246 + private static final long serialVersionUID = 876323262645176354L;
47.247 +
47.248 + /**
47.249 + * A node from which the first node on list (that is, the unique node p
47.250 + * with p.prev == null && p.next != p) can be reached in O(1) time.
47.251 + * Invariants:
47.252 + * - the first node is always O(1) reachable from head via prev links
47.253 + * - all live nodes are reachable from the first node via succ()
47.254 + * - head != null
47.255 + * - (tmp = head).next != tmp || tmp != head
47.256 + * - head is never gc-unlinked (but may be unlinked)
47.257 + * Non-invariants:
47.258 + * - head.item may or may not be null
47.259 + * - head may not be reachable from the first or last node, or from tail
47.260 + */
47.261 + private transient volatile Node<E> head;
47.262 +
47.263 + /**
47.264 + * A node from which the last node on list (that is, the unique node p
47.265 + * with p.next == null && p.prev != p) can be reached in O(1) time.
47.266 + * Invariants:
47.267 + * - the last node is always O(1) reachable from tail via next links
47.268 + * - all live nodes are reachable from the last node via pred()
47.269 + * - tail != null
47.270 + * - tail is never gc-unlinked (but may be unlinked)
47.271 + * Non-invariants:
47.272 + * - tail.item may or may not be null
47.273 + * - tail may not be reachable from the first or last node, or from head
47.274 + */
47.275 + private transient volatile Node<E> tail;
47.276 +
47.277 + private final static Node<Object> PREV_TERMINATOR, NEXT_TERMINATOR;
47.278 +
47.279 + static {
47.280 + PREV_TERMINATOR = new Node<Object>(null);
47.281 + PREV_TERMINATOR.next = PREV_TERMINATOR;
47.282 + NEXT_TERMINATOR = new Node<Object>(null);
47.283 + NEXT_TERMINATOR.prev = NEXT_TERMINATOR;
47.284 + }
47.285 +
47.286 + @SuppressWarnings("unchecked")
47.287 + Node<E> prevTerminator() {
47.288 + return (Node<E>) PREV_TERMINATOR;
47.289 + }
47.290 +
47.291 + @SuppressWarnings("unchecked")
47.292 + Node<E> nextTerminator() {
47.293 + return (Node<E>) NEXT_TERMINATOR;
47.294 + }
47.295 +
47.296 + static final class Node<E> {
47.297 + volatile Node<E> prev;
47.298 + volatile E item;
47.299 + volatile Node<E> next;
47.300 +
47.301 + /**
47.302 + * Constructs a new node. Uses relaxed write because item can
47.303 + * only be seen after publication via casNext or casPrev.
47.304 + */
47.305 + Node(E item) {
47.306 + UNSAFE.putObject(this, itemOffset, item);
47.307 + }
47.308 +
47.309 + boolean casItem(E cmp, E val) {
47.310 + return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
47.311 + }
47.312 +
47.313 + void lazySetNext(Node<E> val) {
47.314 + UNSAFE.putOrderedObject(this, nextOffset, val);
47.315 + }
47.316 +
47.317 + boolean casNext(Node<E> cmp, Node<E> val) {
47.318 + return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
47.319 + }
47.320 +
47.321 + void lazySetPrev(Node<E> val) {
47.322 + UNSAFE.putOrderedObject(this, prevOffset, val);
47.323 + }
47.324 +
47.325 + boolean casPrev(Node<E> cmp, Node<E> val) {
47.326 + return UNSAFE.compareAndSwapObject(this, prevOffset, cmp, val);
47.327 + }
47.328 +
47.329 + // Unsafe mechanics
47.330 +
47.331 + private static final sun.misc.Unsafe UNSAFE =
47.332 + sun.misc.Unsafe.getUnsafe();
47.333 + private static final long prevOffset =
47.334 + objectFieldOffset(UNSAFE, "prev", Node.class);
47.335 + private static final long itemOffset =
47.336 + objectFieldOffset(UNSAFE, "item", Node.class);
47.337 + private static final long nextOffset =
47.338 + objectFieldOffset(UNSAFE, "next", Node.class);
47.339 + }
47.340 +
47.341 + /**
47.342 + * Links e as first element.
47.343 + */
47.344 + private void linkFirst(E e) {
47.345 + checkNotNull(e);
47.346 + final Node<E> newNode = new Node<E>(e);
47.347 +
47.348 + restartFromHead:
47.349 + for (;;)
47.350 + for (Node<E> h = head, p = h, q;;) {
47.351 + if ((q = p.prev) != null &&
47.352 + (q = (p = q).prev) != null)
47.353 + // Check for head updates every other hop.
47.354 + // If p == q, we are sure to follow head instead.
47.355 + p = (h != (h = head)) ? h : q;
47.356 + else if (p.next == p) // PREV_TERMINATOR
47.357 + continue restartFromHead;
47.358 + else {
47.359 + // p is first node
47.360 + newNode.lazySetNext(p); // CAS piggyback
47.361 + if (p.casPrev(null, newNode)) {
47.362 + // Successful CAS is the linearization point
47.363 + // for e to become an element of this deque,
47.364 + // and for newNode to become "live".
47.365 + if (p != h) // hop two nodes at a time
47.366 + casHead(h, newNode); // Failure is OK.
47.367 + return;
47.368 + }
47.369 + // Lost CAS race to another thread; re-read prev
47.370 + }
47.371 + }
47.372 + }
47.373 +
47.374 + /**
47.375 + * Links e as last element.
47.376 + */
47.377 + private void linkLast(E e) {
47.378 + checkNotNull(e);
47.379 + final Node<E> newNode = new Node<E>(e);
47.380 +
47.381 + restartFromTail:
47.382 + for (;;)
47.383 + for (Node<E> t = tail, p = t, q;;) {
47.384 + if ((q = p.next) != null &&
47.385 + (q = (p = q).next) != null)
47.386 + // Check for tail updates every other hop.
47.387 + // If p == q, we are sure to follow tail instead.
47.388 + p = (t != (t = tail)) ? t : q;
47.389 + else if (p.prev == p) // NEXT_TERMINATOR
47.390 + continue restartFromTail;
47.391 + else {
47.392 + // p is last node
47.393 + newNode.lazySetPrev(p); // CAS piggyback
47.394 + if (p.casNext(null, newNode)) {
47.395 + // Successful CAS is the linearization point
47.396 + // for e to become an element of this deque,
47.397 + // and for newNode to become "live".
47.398 + if (p != t) // hop two nodes at a time
47.399 + casTail(t, newNode); // Failure is OK.
47.400 + return;
47.401 + }
47.402 + // Lost CAS race to another thread; re-read next
47.403 + }
47.404 + }
47.405 + }
47.406 +
47.407 + private final static int HOPS = 2;
47.408 +
47.409 + /**
47.410 + * Unlinks non-null node x.
47.411 + */
47.412 + void unlink(Node<E> x) {
47.413 + // assert x != null;
47.414 + // assert x.item == null;
47.415 + // assert x != PREV_TERMINATOR;
47.416 + // assert x != NEXT_TERMINATOR;
47.417 +
47.418 + final Node<E> prev = x.prev;
47.419 + final Node<E> next = x.next;
47.420 + if (prev == null) {
47.421 + unlinkFirst(x, next);
47.422 + } else if (next == null) {
47.423 + unlinkLast(x, prev);
47.424 + } else {
47.425 + // Unlink interior node.
47.426 + //
47.427 + // This is the common case, since a series of polls at the
47.428 + // same end will be "interior" removes, except perhaps for
47.429 + // the first one, since end nodes cannot be unlinked.
47.430 + //
47.431 + // At any time, all active nodes are mutually reachable by
47.432 + // following a sequence of either next or prev pointers.
47.433 + //
47.434 + // Our strategy is to find the unique active predecessor
47.435 + // and successor of x. Try to fix up their links so that
47.436 + // they point to each other, leaving x unreachable from
47.437 + // active nodes. If successful, and if x has no live
47.438 + // predecessor/successor, we additionally try to gc-unlink,
47.439 + // leaving active nodes unreachable from x, by rechecking
47.440 + // that the status of predecessor and successor are
47.441 + // unchanged and ensuring that x is not reachable from
47.442 + // tail/head, before setting x's prev/next links to their
47.443 + // logical approximate replacements, self/TERMINATOR.
47.444 + Node<E> activePred, activeSucc;
47.445 + boolean isFirst, isLast;
47.446 + int hops = 1;
47.447 +
47.448 + // Find active predecessor
47.449 + for (Node<E> p = prev; ; ++hops) {
47.450 + if (p.item != null) {
47.451 + activePred = p;
47.452 + isFirst = false;
47.453 + break;
47.454 + }
47.455 + Node<E> q = p.prev;
47.456 + if (q == null) {
47.457 + if (p.next == p)
47.458 + return;
47.459 + activePred = p;
47.460 + isFirst = true;
47.461 + break;
47.462 + }
47.463 + else if (p == q)
47.464 + return;
47.465 + else
47.466 + p = q;
47.467 + }
47.468 +
47.469 + // Find active successor
47.470 + for (Node<E> p = next; ; ++hops) {
47.471 + if (p.item != null) {
47.472 + activeSucc = p;
47.473 + isLast = false;
47.474 + break;
47.475 + }
47.476 + Node<E> q = p.next;
47.477 + if (q == null) {
47.478 + if (p.prev == p)
47.479 + return;
47.480 + activeSucc = p;
47.481 + isLast = true;
47.482 + break;
47.483 + }
47.484 + else if (p == q)
47.485 + return;
47.486 + else
47.487 + p = q;
47.488 + }
47.489 +
47.490 + // TODO: better HOP heuristics
47.491 + if (hops < HOPS
47.492 + // always squeeze out interior deleted nodes
47.493 + && (isFirst | isLast))
47.494 + return;
47.495 +
47.496 + // Squeeze out deleted nodes between activePred and
47.497 + // activeSucc, including x.
47.498 + skipDeletedSuccessors(activePred);
47.499 + skipDeletedPredecessors(activeSucc);
47.500 +
47.501 + // Try to gc-unlink, if possible
47.502 + if ((isFirst | isLast) &&
47.503 +
47.504 + // Recheck expected state of predecessor and successor
47.505 + (activePred.next == activeSucc) &&
47.506 + (activeSucc.prev == activePred) &&
47.507 + (isFirst ? activePred.prev == null : activePred.item != null) &&
47.508 + (isLast ? activeSucc.next == null : activeSucc.item != null)) {
47.509 +
47.510 + updateHead(); // Ensure x is not reachable from head
47.511 + updateTail(); // Ensure x is not reachable from tail
47.512 +
47.513 + // Finally, actually gc-unlink
47.514 + x.lazySetPrev(isFirst ? prevTerminator() : x);
47.515 + x.lazySetNext(isLast ? nextTerminator() : x);
47.516 + }
47.517 + }
47.518 + }
47.519 +
47.520 + /**
47.521 + * Unlinks non-null first node.
47.522 + */
47.523 + private void unlinkFirst(Node<E> first, Node<E> next) {
47.524 + // assert first != null;
47.525 + // assert next != null;
47.526 + // assert first.item == null;
47.527 + for (Node<E> o = null, p = next, q;;) {
47.528 + if (p.item != null || (q = p.next) == null) {
47.529 + if (o != null && p.prev != p && first.casNext(next, p)) {
47.530 + skipDeletedPredecessors(p);
47.531 + if (first.prev == null &&
47.532 + (p.next == null || p.item != null) &&
47.533 + p.prev == first) {
47.534 +
47.535 + updateHead(); // Ensure o is not reachable from head
47.536 + updateTail(); // Ensure o is not reachable from tail
47.537 +
47.538 + // Finally, actually gc-unlink
47.539 + o.lazySetNext(o);
47.540 + o.lazySetPrev(prevTerminator());
47.541 + }
47.542 + }
47.543 + return;
47.544 + }
47.545 + else if (p == q)
47.546 + return;
47.547 + else {
47.548 + o = p;
47.549 + p = q;
47.550 + }
47.551 + }
47.552 + }
47.553 +
47.554 + /**
47.555 + * Unlinks non-null last node.
47.556 + */
47.557 + private void unlinkLast(Node<E> last, Node<E> prev) {
47.558 + // assert last != null;
47.559 + // assert prev != null;
47.560 + // assert last.item == null;
47.561 + for (Node<E> o = null, p = prev, q;;) {
47.562 + if (p.item != null || (q = p.prev) == null) {
47.563 + if (o != null && p.next != p && last.casPrev(prev, p)) {
47.564 + skipDeletedSuccessors(p);
47.565 + if (last.next == null &&
47.566 + (p.prev == null || p.item != null) &&
47.567 + p.next == last) {
47.568 +
47.569 + updateHead(); // Ensure o is not reachable from head
47.570 + updateTail(); // Ensure o is not reachable from tail
47.571 +
47.572 + // Finally, actually gc-unlink
47.573 + o.lazySetPrev(o);
47.574 + o.lazySetNext(nextTerminator());
47.575 + }
47.576 + }
47.577 + return;
47.578 + }
47.579 + else if (p == q)
47.580 + return;
47.581 + else {
47.582 + o = p;
47.583 + p = q;
47.584 + }
47.585 + }
47.586 + }
47.587 +
47.588 + /**
47.589 + * Guarantees that any node which was unlinked before a call to
47.590 + * this method will be unreachable from head after it returns.
47.591 + * Does not guarantee to eliminate slack, only that head will
47.592 + * point to a node that was active while this method was running.
47.593 + */
47.594 + private final void updateHead() {
47.595 + // Either head already points to an active node, or we keep
47.596 + // trying to cas it to the first node until it does.
47.597 + Node<E> h, p, q;
47.598 + restartFromHead:
47.599 + while ((h = head).item == null && (p = h.prev) != null) {
47.600 + for (;;) {
47.601 + if ((q = p.prev) == null ||
47.602 + (q = (p = q).prev) == null) {
47.603 + // It is possible that p is PREV_TERMINATOR,
47.604 + // but if so, the CAS is guaranteed to fail.
47.605 + if (casHead(h, p))
47.606 + return;
47.607 + else
47.608 + continue restartFromHead;
47.609 + }
47.610 + else if (h != head)
47.611 + continue restartFromHead;
47.612 + else
47.613 + p = q;
47.614 + }
47.615 + }
47.616 + }
47.617 +
47.618 + /**
47.619 + * Guarantees that any node which was unlinked before a call to
47.620 + * this method will be unreachable from tail after it returns.
47.621 + * Does not guarantee to eliminate slack, only that tail will
47.622 + * point to a node that was active while this method was running.
47.623 + */
47.624 + private final void updateTail() {
47.625 + // Either tail already points to an active node, or we keep
47.626 + // trying to cas it to the last node until it does.
47.627 + Node<E> t, p, q;
47.628 + restartFromTail:
47.629 + while ((t = tail).item == null && (p = t.next) != null) {
47.630 + for (;;) {
47.631 + if ((q = p.next) == null ||
47.632 + (q = (p = q).next) == null) {
47.633 + // It is possible that p is NEXT_TERMINATOR,
47.634 + // but if so, the CAS is guaranteed to fail.
47.635 + if (casTail(t, p))
47.636 + return;
47.637 + else
47.638 + continue restartFromTail;
47.639 + }
47.640 + else if (t != tail)
47.641 + continue restartFromTail;
47.642 + else
47.643 + p = q;
47.644 + }
47.645 + }
47.646 + }
47.647 +
47.648 + private void skipDeletedPredecessors(Node<E> x) {
47.649 + whileActive:
47.650 + do {
47.651 + Node<E> prev = x.prev;
47.652 + // assert prev != null;
47.653 + // assert x != NEXT_TERMINATOR;
47.654 + // assert x != PREV_TERMINATOR;
47.655 + Node<E> p = prev;
47.656 + findActive:
47.657 + for (;;) {
47.658 + if (p.item != null)
47.659 + break findActive;
47.660 + Node<E> q = p.prev;
47.661 + if (q == null) {
47.662 + if (p.next == p)
47.663 + continue whileActive;
47.664 + break findActive;
47.665 + }
47.666 + else if (p == q)
47.667 + continue whileActive;
47.668 + else
47.669 + p = q;
47.670 + }
47.671 +
47.672 + // found active CAS target
47.673 + if (prev == p || x.casPrev(prev, p))
47.674 + return;
47.675 +
47.676 + } while (x.item != null || x.next == null);
47.677 + }
47.678 +
47.679 + private void skipDeletedSuccessors(Node<E> x) {
47.680 + whileActive:
47.681 + do {
47.682 + Node<E> next = x.next;
47.683 + // assert next != null;
47.684 + // assert x != NEXT_TERMINATOR;
47.685 + // assert x != PREV_TERMINATOR;
47.686 + Node<E> p = next;
47.687 + findActive:
47.688 + for (;;) {
47.689 + if (p.item != null)
47.690 + break findActive;
47.691 + Node<E> q = p.next;
47.692 + if (q == null) {
47.693 + if (p.prev == p)
47.694 + continue whileActive;
47.695 + break findActive;
47.696 + }
47.697 + else if (p == q)
47.698 + continue whileActive;
47.699 + else
47.700 + p = q;
47.701 + }
47.702 +
47.703 + // found active CAS target
47.704 + if (next == p || x.casNext(next, p))
47.705 + return;
47.706 +
47.707 + } while (x.item != null || x.prev == null);
47.708 + }
47.709 +
47.710 + /**
47.711 + * Returns the successor of p, or the first node if p.next has been
47.712 + * linked to self, which will only be true if traversing with a
47.713 + * stale pointer that is now off the list.
47.714 + */
47.715 + final Node<E> succ(Node<E> p) {
47.716 + // TODO: should we skip deleted nodes here?
47.717 + Node<E> q = p.next;
47.718 + return (p == q) ? first() : q;
47.719 + }
47.720 +
47.721 + /**
47.722 + * Returns the predecessor of p, or the last node if p.prev has been
47.723 + * linked to self, which will only be true if traversing with a
47.724 + * stale pointer that is now off the list.
47.725 + */
47.726 + final Node<E> pred(Node<E> p) {
47.727 + Node<E> q = p.prev;
47.728 + return (p == q) ? last() : q;
47.729 + }
47.730 +
47.731 + /**
47.732 + * Returns the first node, the unique node p for which:
47.733 + * p.prev == null && p.next != p
47.734 + * The returned node may or may not be logically deleted.
47.735 + * Guarantees that head is set to the returned node.
47.736 + */
47.737 + Node<E> first() {
47.738 + restartFromHead:
47.739 + for (;;)
47.740 + for (Node<E> h = head, p = h, q;;) {
47.741 + if ((q = p.prev) != null &&
47.742 + (q = (p = q).prev) != null)
47.743 + // Check for head updates every other hop.
47.744 + // If p == q, we are sure to follow head instead.
47.745 + p = (h != (h = head)) ? h : q;
47.746 + else if (p == h
47.747 + // It is possible that p is PREV_TERMINATOR,
47.748 + // but if so, the CAS is guaranteed to fail.
47.749 + || casHead(h, p))
47.750 + return p;
47.751 + else
47.752 + continue restartFromHead;
47.753 + }
47.754 + }
47.755 +
47.756 + /**
47.757 + * Returns the last node, the unique node p for which:
47.758 + * p.next == null && p.prev != p
47.759 + * The returned node may or may not be logically deleted.
47.760 + * Guarantees that tail is set to the returned node.
47.761 + */
47.762 + Node<E> last() {
47.763 + restartFromTail:
47.764 + for (;;)
47.765 + for (Node<E> t = tail, p = t, q;;) {
47.766 + if ((q = p.next) != null &&
47.767 + (q = (p = q).next) != null)
47.768 + // Check for tail updates every other hop.
47.769 + // If p == q, we are sure to follow tail instead.
47.770 + p = (t != (t = tail)) ? t : q;
47.771 + else if (p == t
47.772 + // It is possible that p is NEXT_TERMINATOR,
47.773 + // but if so, the CAS is guaranteed to fail.
47.774 + || casTail(t, p))
47.775 + return p;
47.776 + else
47.777 + continue restartFromTail;
47.778 + }
47.779 + }
47.780 +
47.781 + // Minor convenience utilities
47.782 +
47.783 + /**
47.784 + * Throws NullPointerException if argument is null.
47.785 + *
47.786 + * @param v the element
47.787 + */
47.788 + private static void checkNotNull(Object v) {
47.789 + if (v == null)
47.790 + throw new NullPointerException();
47.791 + }
47.792 +
47.793 + /**
47.794 + * Returns element unless it is null, in which case throws
47.795 + * NoSuchElementException.
47.796 + *
47.797 + * @param v the element
47.798 + * @return the element
47.799 + */
47.800 + private E screenNullResult(E v) {
47.801 + if (v == null)
47.802 + throw new NoSuchElementException();
47.803 + return v;
47.804 + }
47.805 +
47.806 + /**
47.807 + * Creates an array list and fills it with elements of this list.
47.808 + * Used by toArray.
47.809 + *
47.810 + * @return the arrayList
47.811 + */
47.812 + private ArrayList<E> toArrayList() {
47.813 + ArrayList<E> list = new ArrayList<E>();
47.814 + for (Node<E> p = first(); p != null; p = succ(p)) {
47.815 + E item = p.item;
47.816 + if (item != null)
47.817 + list.add(item);
47.818 + }
47.819 + return list;
47.820 + }
47.821 +
47.822 + /**
47.823 + * Constructs an empty deque.
47.824 + */
47.825 + public ConcurrentLinkedDeque() {
47.826 + head = tail = new Node<E>(null);
47.827 + }
47.828 +
47.829 + /**
47.830 + * Constructs a deque initially containing the elements of
47.831 + * the given collection, added in traversal order of the
47.832 + * collection's iterator.
47.833 + *
47.834 + * @param c the collection of elements to initially contain
47.835 + * @throws NullPointerException if the specified collection or any
47.836 + * of its elements are null
47.837 + */
47.838 + public ConcurrentLinkedDeque(Collection<? extends E> c) {
47.839 + // Copy c into a private chain of Nodes
47.840 + Node<E> h = null, t = null;
47.841 + for (E e : c) {
47.842 + checkNotNull(e);
47.843 + Node<E> newNode = new Node<E>(e);
47.844 + if (h == null)
47.845 + h = t = newNode;
47.846 + else {
47.847 + t.lazySetNext(newNode);
47.848 + newNode.lazySetPrev(t);
47.849 + t = newNode;
47.850 + }
47.851 + }
47.852 + initHeadTail(h, t);
47.853 + }
47.854 +
47.855 + /**
47.856 + * Initializes head and tail, ensuring invariants hold.
47.857 + */
47.858 + private void initHeadTail(Node<E> h, Node<E> t) {
47.859 + if (h == t) {
47.860 + if (h == null)
47.861 + h = t = new Node<E>(null);
47.862 + else {
47.863 + // Avoid edge case of a single Node with non-null item.
47.864 + Node<E> newNode = new Node<E>(null);
47.865 + t.lazySetNext(newNode);
47.866 + newNode.lazySetPrev(t);
47.867 + t = newNode;
47.868 + }
47.869 + }
47.870 + head = h;
47.871 + tail = t;
47.872 + }
47.873 +
47.874 + /**
47.875 + * Inserts the specified element at the front of this deque.
47.876 + *
47.877 + * @throws NullPointerException {@inheritDoc}
47.878 + */
47.879 + public void addFirst(E e) {
47.880 + linkFirst(e);
47.881 + }
47.882 +
47.883 + /**
47.884 + * Inserts the specified element at the end of this deque.
47.885 + *
47.886 + * <p>This method is equivalent to {@link #add}.
47.887 + *
47.888 + * @throws NullPointerException {@inheritDoc}
47.889 + */
47.890 + public void addLast(E e) {
47.891 + linkLast(e);
47.892 + }
47.893 +
47.894 + /**
47.895 + * Inserts the specified element at the front of this deque.
47.896 + *
47.897 + * @return {@code true} always
47.898 + * @throws NullPointerException {@inheritDoc}
47.899 + */
47.900 + public boolean offerFirst(E e) {
47.901 + linkFirst(e);
47.902 + return true;
47.903 + }
47.904 +
47.905 + /**
47.906 + * Inserts the specified element at the end of this deque.
47.907 + *
47.908 + * <p>This method is equivalent to {@link #add}.
47.909 + *
47.910 + * @return {@code true} always
47.911 + * @throws NullPointerException {@inheritDoc}
47.912 + */
47.913 + public boolean offerLast(E e) {
47.914 + linkLast(e);
47.915 + return true;
47.916 + }
47.917 +
47.918 + public E peekFirst() {
47.919 + for (Node<E> p = first(); p != null; p = succ(p)) {
47.920 + E item = p.item;
47.921 + if (item != null)
47.922 + return item;
47.923 + }
47.924 + return null;
47.925 + }
47.926 +
47.927 + public E peekLast() {
47.928 + for (Node<E> p = last(); p != null; p = pred(p)) {
47.929 + E item = p.item;
47.930 + if (item != null)
47.931 + return item;
47.932 + }
47.933 + return null;
47.934 + }
47.935 +
47.936 + /**
47.937 + * @throws NoSuchElementException {@inheritDoc}
47.938 + */
47.939 + public E getFirst() {
47.940 + return screenNullResult(peekFirst());
47.941 + }
47.942 +
47.943 + /**
47.944 + * @throws NoSuchElementException {@inheritDoc}
47.945 + */
47.946 + public E getLast() {
47.947 + return screenNullResult(peekLast());
47.948 + }
47.949 +
47.950 + public E pollFirst() {
47.951 + for (Node<E> p = first(); p != null; p = succ(p)) {
47.952 + E item = p.item;
47.953 + if (item != null && p.casItem(item, null)) {
47.954 + unlink(p);
47.955 + return item;
47.956 + }
47.957 + }
47.958 + return null;
47.959 + }
47.960 +
47.961 + public E pollLast() {
47.962 + for (Node<E> p = last(); p != null; p = pred(p)) {
47.963 + E item = p.item;
47.964 + if (item != null && p.casItem(item, null)) {
47.965 + unlink(p);
47.966 + return item;
47.967 + }
47.968 + }
47.969 + return null;
47.970 + }
47.971 +
47.972 + /**
47.973 + * @throws NoSuchElementException {@inheritDoc}
47.974 + */
47.975 + public E removeFirst() {
47.976 + return screenNullResult(pollFirst());
47.977 + }
47.978 +
47.979 + /**
47.980 + * @throws NoSuchElementException {@inheritDoc}
47.981 + */
47.982 + public E removeLast() {
47.983 + return screenNullResult(pollLast());
47.984 + }
47.985 +
47.986 + // *** Queue and stack methods ***
47.987 +
47.988 + /**
47.989 + * Inserts the specified element at the tail of this deque.
47.990 + *
47.991 + * @return {@code true} (as specified by {@link Queue#offer})
47.992 + * @throws NullPointerException if the specified element is null
47.993 + */
47.994 + public boolean offer(E e) {
47.995 + return offerLast(e);
47.996 + }
47.997 +
47.998 + /**
47.999 + * Inserts the specified element at the tail of this deque.
47.1000 + *
47.1001 + * @return {@code true} (as specified by {@link Collection#add})
47.1002 + * @throws NullPointerException if the specified element is null
47.1003 + */
47.1004 + public boolean add(E e) {
47.1005 + return offerLast(e);
47.1006 + }
47.1007 +
47.1008 + public E poll() { return pollFirst(); }
47.1009 + public E remove() { return removeFirst(); }
47.1010 + public E peek() { return peekFirst(); }
47.1011 + public E element() { return getFirst(); }
47.1012 + public void push(E e) { addFirst(e); }
47.1013 + public E pop() { return removeFirst(); }
47.1014 +
47.1015 + /**
47.1016 + * Removes the first element {@code e} such that
47.1017 + * {@code o.equals(e)}, if such an element exists in this deque.
47.1018 + * If the deque does not contain the element, it is unchanged.
47.1019 + *
47.1020 + * @param o element to be removed from this deque, if present
47.1021 + * @return {@code true} if the deque contained the specified element
47.1022 + * @throws NullPointerException if the specified element is {@code null}
47.1023 + */
47.1024 + public boolean removeFirstOccurrence(Object o) {
47.1025 + checkNotNull(o);
47.1026 + for (Node<E> p = first(); p != null; p = succ(p)) {
47.1027 + E item = p.item;
47.1028 + if (item != null && o.equals(item) && p.casItem(item, null)) {
47.1029 + unlink(p);
47.1030 + return true;
47.1031 + }
47.1032 + }
47.1033 + return false;
47.1034 + }
47.1035 +
47.1036 + /**
47.1037 + * Removes the last element {@code e} such that
47.1038 + * {@code o.equals(e)}, if such an element exists in this deque.
47.1039 + * If the deque does not contain the element, it is unchanged.
47.1040 + *
47.1041 + * @param o element to be removed from this deque, if present
47.1042 + * @return {@code true} if the deque contained the specified element
47.1043 + * @throws NullPointerException if the specified element is {@code null}
47.1044 + */
47.1045 + public boolean removeLastOccurrence(Object o) {
47.1046 + checkNotNull(o);
47.1047 + for (Node<E> p = last(); p != null; p = pred(p)) {
47.1048 + E item = p.item;
47.1049 + if (item != null && o.equals(item) && p.casItem(item, null)) {
47.1050 + unlink(p);
47.1051 + return true;
47.1052 + }
47.1053 + }
47.1054 + return false;
47.1055 + }
47.1056 +
47.1057 + /**
47.1058 + * Returns {@code true} if this deque contains at least one
47.1059 + * element {@code e} such that {@code o.equals(e)}.
47.1060 + *
47.1061 + * @param o element whose presence in this deque is to be tested
47.1062 + * @return {@code true} if this deque contains the specified element
47.1063 + */
47.1064 + public boolean contains(Object o) {
47.1065 + if (o == null) return false;
47.1066 + for (Node<E> p = first(); p != null; p = succ(p)) {
47.1067 + E item = p.item;
47.1068 + if (item != null && o.equals(item))
47.1069 + return true;
47.1070 + }
47.1071 + return false;
47.1072 + }
47.1073 +
47.1074 + /**
47.1075 + * Returns {@code true} if this collection contains no elements.
47.1076 + *
47.1077 + * @return {@code true} if this collection contains no elements
47.1078 + */
47.1079 + public boolean isEmpty() {
47.1080 + return peekFirst() == null;
47.1081 + }
47.1082 +
47.1083 + /**
47.1084 + * Returns the number of elements in this deque. If this deque
47.1085 + * contains more than {@code Integer.MAX_VALUE} elements, it
47.1086 + * returns {@code Integer.MAX_VALUE}.
47.1087 + *
47.1088 + * <p>Beware that, unlike in most collections, this method is
47.1089 + * <em>NOT</em> a constant-time operation. Because of the
47.1090 + * asynchronous nature of these deques, determining the current
47.1091 + * number of elements requires traversing them all to count them.
47.1092 + * Additionally, it is possible for the size to change during
47.1093 + * execution of this method, in which case the returned result
47.1094 + * will be inaccurate. Thus, this method is typically not very
47.1095 + * useful in concurrent applications.
47.1096 + *
47.1097 + * @return the number of elements in this deque
47.1098 + */
47.1099 + public int size() {
47.1100 + int count = 0;
47.1101 + for (Node<E> p = first(); p != null; p = succ(p))
47.1102 + if (p.item != null)
47.1103 + // Collection.size() spec says to max out
47.1104 + if (++count == Integer.MAX_VALUE)
47.1105 + break;
47.1106 + return count;
47.1107 + }
47.1108 +
47.1109 + /**
47.1110 + * Removes the first element {@code e} such that
47.1111 + * {@code o.equals(e)}, if such an element exists in this deque.
47.1112 + * If the deque does not contain the element, it is unchanged.
47.1113 + *
47.1114 + * @param o element to be removed from this deque, if present
47.1115 + * @return {@code true} if the deque contained the specified element
47.1116 + * @throws NullPointerException if the specified element is {@code null}
47.1117 + */
47.1118 + public boolean remove(Object o) {
47.1119 + return removeFirstOccurrence(o);
47.1120 + }
47.1121 +
47.1122 + /**
47.1123 + * Appends all of the elements in the specified collection to the end of
47.1124 + * this deque, in the order that they are returned by the specified
47.1125 + * collection's iterator. Attempts to {@code addAll} of a deque to
47.1126 + * itself result in {@code IllegalArgumentException}.
47.1127 + *
47.1128 + * @param c the elements to be inserted into this deque
47.1129 + * @return {@code true} if this deque changed as a result of the call
47.1130 + * @throws NullPointerException if the specified collection or any
47.1131 + * of its elements are null
47.1132 + * @throws IllegalArgumentException if the collection is this deque
47.1133 + */
47.1134 + public boolean addAll(Collection<? extends E> c) {
47.1135 + if (c == this)
47.1136 + // As historically specified in AbstractQueue#addAll
47.1137 + throw new IllegalArgumentException();
47.1138 +
47.1139 + // Copy c into a private chain of Nodes
47.1140 + Node<E> beginningOfTheEnd = null, last = null;
47.1141 + for (E e : c) {
47.1142 + checkNotNull(e);
47.1143 + Node<E> newNode = new Node<E>(e);
47.1144 + if (beginningOfTheEnd == null)
47.1145 + beginningOfTheEnd = last = newNode;
47.1146 + else {
47.1147 + last.lazySetNext(newNode);
47.1148 + newNode.lazySetPrev(last);
47.1149 + last = newNode;
47.1150 + }
47.1151 + }
47.1152 + if (beginningOfTheEnd == null)
47.1153 + return false;
47.1154 +
47.1155 + // Atomically append the chain at the tail of this collection
47.1156 + restartFromTail:
47.1157 + for (;;)
47.1158 + for (Node<E> t = tail, p = t, q;;) {
47.1159 + if ((q = p.next) != null &&
47.1160 + (q = (p = q).next) != null)
47.1161 + // Check for tail updates every other hop.
47.1162 + // If p == q, we are sure to follow tail instead.
47.1163 + p = (t != (t = tail)) ? t : q;
47.1164 + else if (p.prev == p) // NEXT_TERMINATOR
47.1165 + continue restartFromTail;
47.1166 + else {
47.1167 + // p is last node
47.1168 + beginningOfTheEnd.lazySetPrev(p); // CAS piggyback
47.1169 + if (p.casNext(null, beginningOfTheEnd)) {
47.1170 + // Successful CAS is the linearization point
47.1171 + // for all elements to be added to this queue.
47.1172 + if (!casTail(t, last)) {
47.1173 + // Try a little harder to update tail,
47.1174 + // since we may be adding many elements.
47.1175 + t = tail;
47.1176 + if (last.next == null)
47.1177 + casTail(t, last);
47.1178 + }
47.1179 + return true;
47.1180 + }
47.1181 + // Lost CAS race to another thread; re-read next
47.1182 + }
47.1183 + }
47.1184 + }
47.1185 +
47.1186 + /**
47.1187 + * Removes all of the elements from this deque.
47.1188 + */
47.1189 + public void clear() {
47.1190 + while (pollFirst() != null)
47.1191 + ;
47.1192 + }
47.1193 +
47.1194 + /**
47.1195 + * Returns an array containing all of the elements in this deque, in
47.1196 + * proper sequence (from first to last element).
47.1197 + *
47.1198 + * <p>The returned array will be "safe" in that no references to it are
47.1199 + * maintained by this deque. (In other words, this method must allocate
47.1200 + * a new array). The caller is thus free to modify the returned array.
47.1201 + *
47.1202 + * <p>This method acts as bridge between array-based and collection-based
47.1203 + * APIs.
47.1204 + *
47.1205 + * @return an array containing all of the elements in this deque
47.1206 + */
47.1207 + public Object[] toArray() {
47.1208 + return toArrayList().toArray();
47.1209 + }
47.1210 +
47.1211 + /**
47.1212 + * Returns an array containing all of the elements in this deque,
47.1213 + * in proper sequence (from first to last element); the runtime
47.1214 + * type of the returned array is that of the specified array. If
47.1215 + * the deque fits in the specified array, it is returned therein.
47.1216 + * Otherwise, a new array is allocated with the runtime type of
47.1217 + * the specified array and the size of this deque.
47.1218 + *
47.1219 + * <p>If this deque fits in the specified array with room to spare
47.1220 + * (i.e., the array has more elements than this deque), the element in
47.1221 + * the array immediately following the end of the deque is set to
47.1222 + * {@code null}.
47.1223 + *
47.1224 + * <p>Like the {@link #toArray()} method, this method acts as
47.1225 + * bridge between array-based and collection-based APIs. Further,
47.1226 + * this method allows precise control over the runtime type of the
47.1227 + * output array, and may, under certain circumstances, be used to
47.1228 + * save allocation costs.
47.1229 + *
47.1230 + * <p>Suppose {@code x} is a deque known to contain only strings.
47.1231 + * The following code can be used to dump the deque into a newly
47.1232 + * allocated array of {@code String}:
47.1233 + *
47.1234 + * <pre>
47.1235 + * String[] y = x.toArray(new String[0]);</pre>
47.1236 + *
47.1237 + * Note that {@code toArray(new Object[0])} is identical in function to
47.1238 + * {@code toArray()}.
47.1239 + *
47.1240 + * @param a the array into which the elements of the deque are to
47.1241 + * be stored, if it is big enough; otherwise, a new array of the
47.1242 + * same runtime type is allocated for this purpose
47.1243 + * @return an array containing all of the elements in this deque
47.1244 + * @throws ArrayStoreException if the runtime type of the specified array
47.1245 + * is not a supertype of the runtime type of every element in
47.1246 + * this deque
47.1247 + * @throws NullPointerException if the specified array is null
47.1248 + */
47.1249 + public <T> T[] toArray(T[] a) {
47.1250 + return toArrayList().toArray(a);
47.1251 + }
47.1252 +
47.1253 + /**
47.1254 + * Returns an iterator over the elements in this deque in proper sequence.
47.1255 + * The elements will be returned in order from first (head) to last (tail).
47.1256 + *
47.1257 + * <p>The returned {@code Iterator} is a "weakly consistent" iterator that
47.1258 + * will never throw {@link java.util.ConcurrentModificationException
47.1259 + * ConcurrentModificationException},
47.1260 + * and guarantees to traverse elements as they existed upon
47.1261 + * construction of the iterator, and may (but is not guaranteed to)
47.1262 + * reflect any modifications subsequent to construction.
47.1263 + *
47.1264 + * @return an iterator over the elements in this deque in proper sequence
47.1265 + */
47.1266 + public Iterator<E> iterator() {
47.1267 + return new Itr();
47.1268 + }
47.1269 +
47.1270 + /**
47.1271 + * Returns an iterator over the elements in this deque in reverse
47.1272 + * sequential order. The elements will be returned in order from
47.1273 + * last (tail) to first (head).
47.1274 + *
47.1275 + * <p>The returned {@code Iterator} is a "weakly consistent" iterator that
47.1276 + * will never throw {@link java.util.ConcurrentModificationException
47.1277 + * ConcurrentModificationException},
47.1278 + * and guarantees to traverse elements as they existed upon
47.1279 + * construction of the iterator, and may (but is not guaranteed to)
47.1280 + * reflect any modifications subsequent to construction.
47.1281 + *
47.1282 + * @return an iterator over the elements in this deque in reverse order
47.1283 + */
47.1284 + public Iterator<E> descendingIterator() {
47.1285 + return new DescendingItr();
47.1286 + }
47.1287 +
47.1288 + private abstract class AbstractItr implements Iterator<E> {
47.1289 + /**
47.1290 + * Next node to return item for.
47.1291 + */
47.1292 + private Node<E> nextNode;
47.1293 +
47.1294 + /**
47.1295 + * nextItem holds on to item fields because once we claim
47.1296 + * that an element exists in hasNext(), we must return it in
47.1297 + * the following next() call even if it was in the process of
47.1298 + * being removed when hasNext() was called.
47.1299 + */
47.1300 + private E nextItem;
47.1301 +
47.1302 + /**
47.1303 + * Node returned by most recent call to next. Needed by remove.
47.1304 + * Reset to null if this element is deleted by a call to remove.
47.1305 + */
47.1306 + private Node<E> lastRet;
47.1307 +
47.1308 + abstract Node<E> startNode();
47.1309 + abstract Node<E> nextNode(Node<E> p);
47.1310 +
47.1311 + AbstractItr() {
47.1312 + advance();
47.1313 + }
47.1314 +
47.1315 + /**
47.1316 + * Sets nextNode and nextItem to next valid node, or to null
47.1317 + * if no such.
47.1318 + */
47.1319 + private void advance() {
47.1320 + lastRet = nextNode;
47.1321 +
47.1322 + Node<E> p = (nextNode == null) ? startNode() : nextNode(nextNode);
47.1323 + for (;; p = nextNode(p)) {
47.1324 + if (p == null) {
47.1325 + // p might be active end or TERMINATOR node; both are OK
47.1326 + nextNode = null;
47.1327 + nextItem = null;
47.1328 + break;
47.1329 + }
47.1330 + E item = p.item;
47.1331 + if (item != null) {
47.1332 + nextNode = p;
47.1333 + nextItem = item;
47.1334 + break;
47.1335 + }
47.1336 + }
47.1337 + }
47.1338 +
47.1339 + public boolean hasNext() {
47.1340 + return nextItem != null;
47.1341 + }
47.1342 +
47.1343 + public E next() {
47.1344 + E item = nextItem;
47.1345 + if (item == null) throw new NoSuchElementException();
47.1346 + advance();
47.1347 + return item;
47.1348 + }
47.1349 +
47.1350 + public void remove() {
47.1351 + Node<E> l = lastRet;
47.1352 + if (l == null) throw new IllegalStateException();
47.1353 + l.item = null;
47.1354 + unlink(l);
47.1355 + lastRet = null;
47.1356 + }
47.1357 + }
47.1358 +
47.1359 + /** Forward iterator */
47.1360 + private class Itr extends AbstractItr {
47.1361 + Node<E> startNode() { return first(); }
47.1362 + Node<E> nextNode(Node<E> p) { return succ(p); }
47.1363 + }
47.1364 +
47.1365 + /** Descending iterator */
47.1366 + private class DescendingItr extends AbstractItr {
47.1367 + Node<E> startNode() { return last(); }
47.1368 + Node<E> nextNode(Node<E> p) { return pred(p); }
47.1369 + }
47.1370 +
47.1371 + /**
47.1372 + * Saves the state to a stream (that is, serializes it).
47.1373 + *
47.1374 + * @serialData All of the elements (each an {@code E}) in
47.1375 + * the proper order, followed by a null
47.1376 + * @param s the stream
47.1377 + */
47.1378 + private void writeObject(java.io.ObjectOutputStream s)
47.1379 + throws java.io.IOException {
47.1380 +
47.1381 + // Write out any hidden stuff
47.1382 + s.defaultWriteObject();
47.1383 +
47.1384 + // Write out all elements in the proper order.
47.1385 + for (Node<E> p = first(); p != null; p = succ(p)) {
47.1386 + E item = p.item;
47.1387 + if (item != null)
47.1388 + s.writeObject(item);
47.1389 + }
47.1390 +
47.1391 + // Use trailing null as sentinel
47.1392 + s.writeObject(null);
47.1393 + }
47.1394 +
47.1395 + /**
47.1396 + * Reconstitutes the instance from a stream (that is, deserializes it).
47.1397 + * @param s the stream
47.1398 + */
47.1399 + private void readObject(java.io.ObjectInputStream s)
47.1400 + throws java.io.IOException, ClassNotFoundException {
47.1401 + s.defaultReadObject();
47.1402 +
47.1403 + // Read in elements until trailing null sentinel found
47.1404 + Node<E> h = null, t = null;
47.1405 + Object item;
47.1406 + while ((item = s.readObject()) != null) {
47.1407 + @SuppressWarnings("unchecked")
47.1408 + Node<E> newNode = new Node<E>((E) item);
47.1409 + if (h == null)
47.1410 + h = t = newNode;
47.1411 + else {
47.1412 + t.lazySetNext(newNode);
47.1413 + newNode.lazySetPrev(t);
47.1414 + t = newNode;
47.1415 + }
47.1416 + }
47.1417 + initHeadTail(h, t);
47.1418 + }
47.1419 +
47.1420 + // Unsafe mechanics
47.1421 +
47.1422 + private static final sun.misc.Unsafe UNSAFE =
47.1423 + sun.misc.Unsafe.getUnsafe();
47.1424 + private static final long headOffset =
47.1425 + objectFieldOffset(UNSAFE, "head", ConcurrentLinkedDeque.class);
47.1426 + private static final long tailOffset =
47.1427 + objectFieldOffset(UNSAFE, "tail", ConcurrentLinkedDeque.class);
47.1428 +
47.1429 + private boolean casHead(Node<E> cmp, Node<E> val) {
47.1430 + return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
47.1431 + }
47.1432 +
47.1433 + private boolean casTail(Node<E> cmp, Node<E> val) {
47.1434 + return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val);
47.1435 + }
47.1436 +
47.1437 + static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
47.1438 + String field, Class<?> klazz) {
47.1439 + try {
47.1440 + return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
47.1441 + } catch (NoSuchFieldException e) {
47.1442 + // Convert Exception to corresponding Error
47.1443 + NoSuchFieldError error = new NoSuchFieldError(field);
47.1444 + error.initCause(e);
47.1445 + throw error;
47.1446 + }
47.1447 + }
47.1448 +}
48.1 --- a/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java Thu Oct 07 15:12:19 2010 -0700
48.2 +++ b/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java Tue Oct 12 12:51:48 2010 -0700
48.3 @@ -28,9 +28,9 @@
48.4 * However, the following notice accompanied the original version of this
48.5 * file:
48.6 *
48.7 - * Written by Doug Lea with assistance from members of JCP JSR-166
48.8 - * Expert Group and released to the public domain, as explained at
48.9 - * http://creativecommons.org/licenses/publicdomain
48.10 + * Written by Doug Lea and Martin Buchholz with assistance from members of
48.11 + * JCP JSR-166 Expert Group and released to the public domain, as explained
48.12 + * at http://creativecommons.org/licenses/publicdomain
48.13 */
48.14
48.15 package java.util.concurrent;
48.16 @@ -53,7 +53,8 @@
48.17 * operations obtain elements at the head of the queue.
48.18 * A {@code ConcurrentLinkedQueue} is an appropriate choice when
48.19 * many threads will share access to a common collection.
48.20 - * This queue does not permit {@code null} elements.
48.21 + * Like most other concurrent collection implementations, this class
48.22 + * does not permit the use of {@code null} elements.
48.23 *
48.24 * <p>This implementation employs an efficient "wait-free"
48.25 * algorithm based on one described in <a
48.26 @@ -61,14 +62,20 @@
48.27 * Fast, and Practical Non-Blocking and Blocking Concurrent Queue
48.28 * Algorithms</a> by Maged M. Michael and Michael L. Scott.
48.29 *
48.30 + * <p>Iterators are <i>weakly consistent</i>, returning elements
48.31 + * reflecting the state of the queue at some point at or since the
48.32 + * creation of the iterator. They do <em>not</em> throw {@link
48.33 + * ConcurrentModificationException}, and may proceed concurrently with
48.34 + * other operations. Elements contained in the queue since the creation
48.35 + * of the iterator will be returned exactly once.
48.36 + *
48.37 * <p>Beware that, unlike in most collections, the {@code size} method
48.38 * is <em>NOT</em> a constant-time operation. Because of the
48.39 * asynchronous nature of these queues, determining the current number
48.40 * of elements requires a traversal of the elements.
48.41 *
48.42 - * <p>This class and its iterator implement all of the
48.43 - * <em>optional</em> methods of the {@link Collection} and {@link
48.44 - * Iterator} interfaces.
48.45 + * <p>This class and its iterator implement all of the <em>optional</em>
48.46 + * methods of the {@link Queue} and {@link Iterator} interfaces.
48.47 *
48.48 * <p>Memory consistency effects: As with other concurrent
48.49 * collections, actions in a thread prior to placing an object into a
48.50 @@ -132,9 +139,10 @@
48.51 *
48.52 * Both head and tail are permitted to lag. In fact, failing to
48.53 * update them every time one could is a significant optimization
48.54 - * (fewer CASes). This is controlled by local "hops" variables
48.55 - * that only trigger helping-CASes after experiencing multiple
48.56 - * lags.
48.57 + * (fewer CASes). As with LinkedTransferQueue (see the internal
48.58 + * documentation for that class), we use a slack threshold of two;
48.59 + * that is, we update head/tail when the current pointer appears
48.60 + * to be two or more steps away from the first/last node.
48.61 *
48.62 * Since head and tail are updated concurrently and independently,
48.63 * it is possible for tail to lag behind head (why not)?
48.64 @@ -148,8 +156,8 @@
48.65 * this is merely an optimization.
48.66 *
48.67 * When constructing a Node (before enqueuing it) we avoid paying
48.68 - * for a volatile write to item by using lazySet instead of a
48.69 - * normal write. This allows the cost of enqueue to be
48.70 + * for a volatile write to item by using Unsafe.putObject instead
48.71 + * of a normal write. This allows the cost of enqueue to be
48.72 * "one-and-a-half" CASes.
48.73 *
48.74 * Both head and tail may or may not point to a Node with a
48.75 @@ -161,38 +169,25 @@
48.76 */
48.77
48.78 private static class Node<E> {
48.79 - private volatile E item;
48.80 - private volatile Node<E> next;
48.81 + volatile E item;
48.82 + volatile Node<E> next;
48.83
48.84 + /**
48.85 + * Constructs a new node. Uses relaxed write because item can
48.86 + * only be seen after publication via casNext.
48.87 + */
48.88 Node(E item) {
48.89 - // Piggyback on imminent casNext()
48.90 - lazySetItem(item);
48.91 - }
48.92 -
48.93 - E getItem() {
48.94 - return item;
48.95 + UNSAFE.putObject(this, itemOffset, item);
48.96 }
48.97
48.98 boolean casItem(E cmp, E val) {
48.99 return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
48.100 }
48.101
48.102 - void setItem(E val) {
48.103 - item = val;
48.104 - }
48.105 -
48.106 - void lazySetItem(E val) {
48.107 - UNSAFE.putOrderedObject(this, itemOffset, val);
48.108 - }
48.109 -
48.110 void lazySetNext(Node<E> val) {
48.111 UNSAFE.putOrderedObject(this, nextOffset, val);
48.112 }
48.113
48.114 - Node<E> getNext() {
48.115 - return next;
48.116 - }
48.117 -
48.118 boolean casNext(Node<E> cmp, Node<E> val) {
48.119 return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
48.120 }
48.121 @@ -219,7 +214,7 @@
48.122 * - it is permitted for tail to lag behind head, that is, for tail
48.123 * to not be reachable from head!
48.124 */
48.125 - private transient volatile Node<E> head = new Node<E>(null);
48.126 + private transient volatile Node<E> head;
48.127
48.128 /**
48.129 * A node from which the last node on list (that is, the unique
48.130 @@ -233,25 +228,41 @@
48.131 * to not be reachable from head!
48.132 * - tail.next may or may not be self-pointing to tail.
48.133 */
48.134 - private transient volatile Node<E> tail = head;
48.135 + private transient volatile Node<E> tail;
48.136
48.137
48.138 /**
48.139 * Creates a {@code ConcurrentLinkedQueue} that is initially empty.
48.140 */
48.141 - public ConcurrentLinkedQueue() {}
48.142 + public ConcurrentLinkedQueue() {
48.143 + head = tail = new Node<E>(null);
48.144 + }
48.145
48.146 /**
48.147 * Creates a {@code ConcurrentLinkedQueue}
48.148 * initially containing the elements of the given collection,
48.149 * added in traversal order of the collection's iterator.
48.150 + *
48.151 * @param c the collection of elements to initially contain
48.152 * @throws NullPointerException if the specified collection or any
48.153 * of its elements are null
48.154 */
48.155 public ConcurrentLinkedQueue(Collection<? extends E> c) {
48.156 - for (E e : c)
48.157 - add(e);
48.158 + Node<E> h = null, t = null;
48.159 + for (E e : c) {
48.160 + checkNotNull(e);
48.161 + Node<E> newNode = new Node<E>(e);
48.162 + if (h == null)
48.163 + h = t = newNode;
48.164 + else {
48.165 + t.lazySetNext(newNode);
48.166 + t = newNode;
48.167 + }
48.168 + }
48.169 + if (h == null)
48.170 + h = t = new Node<E>(null);
48.171 + head = h;
48.172 + tail = t;
48.173 }
48.174
48.175 // Have to override just to update the javadoc
48.176 @@ -267,13 +278,6 @@
48.177 }
48.178
48.179 /**
48.180 - * We don't bother to update head or tail pointers if fewer than
48.181 - * HOPS links from "true" location. We assume that volatile
48.182 - * writes are significantly more expensive than volatile reads.
48.183 - */
48.184 - private static final int HOPS = 1;
48.185 -
48.186 - /**
48.187 * Try to CAS head to p. If successful, repoint old head to itself
48.188 * as sentinel for succ(), below.
48.189 */
48.190 @@ -288,7 +292,7 @@
48.191 * stale pointer that is now off the list.
48.192 */
48.193 final Node<E> succ(Node<E> p) {
48.194 - Node<E> next = p.getNext();
48.195 + Node<E> next = p.next;
48.196 return (p == next) ? head : next;
48.197 }
48.198
48.199 @@ -299,68 +303,75 @@
48.200 * @throws NullPointerException if the specified element is null
48.201 */
48.202 public boolean offer(E e) {
48.203 - if (e == null) throw new NullPointerException();
48.204 - Node<E> n = new Node<E>(e);
48.205 - retry:
48.206 + checkNotNull(e);
48.207 + final Node<E> newNode = new Node<E>(e);
48.208 +
48.209 + for (Node<E> t = tail, p = t;;) {
48.210 + Node<E> q = p.next;
48.211 + if (q == null) {
48.212 + // p is last node
48.213 + if (p.casNext(null, newNode)) {
48.214 + // Successful CAS is the linearization point
48.215 + // for e to become an element of this queue,
48.216 + // and for newNode to become "live".
48.217 + if (p != t) // hop two nodes at a time
48.218 + casTail(t, newNode); // Failure is OK.
48.219 + return true;
48.220 + }
48.221 + // Lost CAS race to another thread; re-read next
48.222 + }
48.223 + else if (p == q)
48.224 + // We have fallen off list. If tail is unchanged, it
48.225 + // will also be off-list, in which case we need to
48.226 + // jump to head, from which all live nodes are always
48.227 + // reachable. Else the new tail is a better bet.
48.228 + p = (t != (t = tail)) ? t : head;
48.229 + else
48.230 + // Check for tail updates after two hops.
48.231 + p = (p != t && t != (t = tail)) ? t : q;
48.232 + }
48.233 + }
48.234 +
48.235 + public E poll() {
48.236 + restartFromHead:
48.237 for (;;) {
48.238 - Node<E> t = tail;
48.239 - Node<E> p = t;
48.240 - for (int hops = 0; ; hops++) {
48.241 - Node<E> next = succ(p);
48.242 - if (next != null) {
48.243 - if (hops > HOPS && t != tail)
48.244 - continue retry;
48.245 - p = next;
48.246 - } else if (p.casNext(null, n)) {
48.247 - if (hops >= HOPS)
48.248 - casTail(t, n); // Failure is OK.
48.249 - return true;
48.250 - } else {
48.251 - p = succ(p);
48.252 + for (Node<E> h = head, p = h, q;;) {
48.253 + E item = p.item;
48.254 +
48.255 + if (item != null && p.casItem(item, null)) {
48.256 + // Successful CAS is the linearization point
48.257 + // for item to be removed from this queue.
48.258 + if (p != h) // hop two nodes at a time
48.259 + updateHead(h, ((q = p.next) != null) ? q : p);
48.260 + return item;
48.261 }
48.262 + else if ((q = p.next) == null) {
48.263 + updateHead(h, p);
48.264 + return null;
48.265 + }
48.266 + else if (p == q)
48.267 + continue restartFromHead;
48.268 + else
48.269 + p = q;
48.270 }
48.271 }
48.272 }
48.273
48.274 - public E poll() {
48.275 - Node<E> h = head;
48.276 - Node<E> p = h;
48.277 - for (int hops = 0; ; hops++) {
48.278 - E item = p.getItem();
48.279 -
48.280 - if (item != null && p.casItem(item, null)) {
48.281 - if (hops >= HOPS) {
48.282 - Node<E> q = p.getNext();
48.283 - updateHead(h, (q != null) ? q : p);
48.284 + public E peek() {
48.285 + restartFromHead:
48.286 + for (;;) {
48.287 + for (Node<E> h = head, p = h, q;;) {
48.288 + E item = p.item;
48.289 + if (item != null || (q = p.next) == null) {
48.290 + updateHead(h, p);
48.291 + return item;
48.292 }
48.293 - return item;
48.294 + else if (p == q)
48.295 + continue restartFromHead;
48.296 + else
48.297 + p = q;
48.298 }
48.299 - Node<E> next = succ(p);
48.300 - if (next == null) {
48.301 - updateHead(h, p);
48.302 - break;
48.303 - }
48.304 - p = next;
48.305 }
48.306 - return null;
48.307 - }
48.308 -
48.309 - public E peek() {
48.310 - Node<E> h = head;
48.311 - Node<E> p = h;
48.312 - E item;
48.313 - for (;;) {
48.314 - item = p.getItem();
48.315 - if (item != null)
48.316 - break;
48.317 - Node<E> next = succ(p);
48.318 - if (next == null) {
48.319 - break;
48.320 - }
48.321 - p = next;
48.322 - }
48.323 - updateHead(h, p);
48.324 - return item;
48.325 }
48.326
48.327 /**
48.328 @@ -372,24 +383,20 @@
48.329 * of losing a race to a concurrent poll().
48.330 */
48.331 Node<E> first() {
48.332 - Node<E> h = head;
48.333 - Node<E> p = h;
48.334 - Node<E> result;
48.335 + restartFromHead:
48.336 for (;;) {
48.337 - E item = p.getItem();
48.338 - if (item != null) {
48.339 - result = p;
48.340 - break;
48.341 + for (Node<E> h = head, p = h, q;;) {
48.342 + boolean hasItem = (p.item != null);
48.343 + if (hasItem || (q = p.next) == null) {
48.344 + updateHead(h, p);
48.345 + return hasItem ? p : null;
48.346 + }
48.347 + else if (p == q)
48.348 + continue restartFromHead;
48.349 + else
48.350 + p = q;
48.351 }
48.352 - Node<E> next = succ(p);
48.353 - if (next == null) {
48.354 - result = null;
48.355 - break;
48.356 - }
48.357 - p = next;
48.358 }
48.359 - updateHead(h, p);
48.360 - return result;
48.361 }
48.362
48.363 /**
48.364 @@ -410,18 +417,20 @@
48.365 * <em>NOT</em> a constant-time operation. Because of the
48.366 * asynchronous nature of these queues, determining the current
48.367 * number of elements requires an O(n) traversal.
48.368 + * Additionally, if elements are added or removed during execution
48.369 + * of this method, the returned result may be inaccurate. Thus,
48.370 + * this method is typically not very useful in concurrent
48.371 + * applications.
48.372 *
48.373 * @return the number of elements in this queue
48.374 */
48.375 public int size() {
48.376 int count = 0;
48.377 - for (Node<E> p = first(); p != null; p = succ(p)) {
48.378 - if (p.getItem() != null) {
48.379 - // Collections.size() spec says to max out
48.380 + for (Node<E> p = first(); p != null; p = succ(p))
48.381 + if (p.item != null)
48.382 + // Collection.size() spec says to max out
48.383 if (++count == Integer.MAX_VALUE)
48.384 break;
48.385 - }
48.386 - }
48.387 return count;
48.388 }
48.389
48.390 @@ -436,9 +445,8 @@
48.391 public boolean contains(Object o) {
48.392 if (o == null) return false;
48.393 for (Node<E> p = first(); p != null; p = succ(p)) {
48.394 - E item = p.getItem();
48.395 - if (item != null &&
48.396 - o.equals(item))
48.397 + E item = p.item;
48.398 + if (item != null && o.equals(item))
48.399 return true;
48.400 }
48.401 return false;
48.402 @@ -459,7 +467,7 @@
48.403 if (o == null) return false;
48.404 Node<E> pred = null;
48.405 for (Node<E> p = first(); p != null; p = succ(p)) {
48.406 - E item = p.getItem();
48.407 + E item = p.item;
48.408 if (item != null &&
48.409 o.equals(item) &&
48.410 p.casItem(item, null)) {
48.411 @@ -474,6 +482,69 @@
48.412 }
48.413
48.414 /**
48.415 + * Appends all of the elements in the specified collection to the end of
48.416 + * this queue, in the order that they are returned by the specified
48.417 + * collection's iterator. Attempts to {@code addAll} of a queue to
48.418 + * itself result in {@code IllegalArgumentException}.
48.419 + *
48.420 + * @param c the elements to be inserted into this queue
48.421 + * @return {@code true} if this queue changed as a result of the call
48.422 + * @throws NullPointerException if the specified collection or any
48.423 + * of its elements are null
48.424 + * @throws IllegalArgumentException if the collection is this queue
48.425 + */
48.426 + public boolean addAll(Collection<? extends E> c) {
48.427 + if (c == this)
48.428 + // As historically specified in AbstractQueue#addAll
48.429 + throw new IllegalArgumentException();
48.430 +
48.431 + // Copy c into a private chain of Nodes
48.432 + Node<E> beginningOfTheEnd = null, last = null;
48.433 + for (E e : c) {
48.434 + checkNotNull(e);
48.435 + Node<E> newNode = new Node<E>(e);
48.436 + if (beginningOfTheEnd == null)
48.437 + beginningOfTheEnd = last = newNode;
48.438 + else {
48.439 + last.lazySetNext(newNode);
48.440 + last = newNode;
48.441 + }
48.442 + }
48.443 + if (beginningOfTheEnd == null)
48.444 + return false;
48.445 +
48.446 + // Atomically append the chain at the tail of this collection
48.447 + for (Node<E> t = tail, p = t;;) {
48.448 + Node<E> q = p.next;
48.449 + if (q == null) {
48.450 + // p is last node
48.451 + if (p.casNext(null, beginningOfTheEnd)) {
48.452 + // Successful CAS is the linearization point
48.453 + // for all elements to be added to this queue.
48.454 + if (!casTail(t, last)) {
48.455 + // Try a little harder to update tail,
48.456 + // since we may be adding many elements.
48.457 + t = tail;
48.458 + if (last.next == null)
48.459 + casTail(t, last);
48.460 + }
48.461 + return true;
48.462 + }
48.463 + // Lost CAS race to another thread; re-read next
48.464 + }
48.465 + else if (p == q)
48.466 + // We have fallen off list. If tail is unchanged, it
48.467 + // will also be off-list, in which case we need to
48.468 + // jump to head, from which all live nodes are always
48.469 + // reachable. Else the new tail is a better bet.
48.470 + p = (t != (t = tail)) ? t : head;
48.471 + else
48.472 + // Check for tail updates after two hops.
48.473 + p = (p != t && t != (t = tail)) ? t : q;
48.474 + }
48.475 + }
48.476 +
48.477 + /**
48.478 * Returns an array containing all of the elements in this queue, in
48.479 * proper sequence.
48.480 *
48.481 @@ -490,7 +561,7 @@
48.482 // Use ArrayList to deal with resizing.
48.483 ArrayList<E> al = new ArrayList<E>();
48.484 for (Node<E> p = first(); p != null; p = succ(p)) {
48.485 - E item = p.getItem();
48.486 + E item = p.item;
48.487 if (item != null)
48.488 al.add(item);
48.489 }
48.490 @@ -539,7 +610,7 @@
48.491 int k = 0;
48.492 Node<E> p;
48.493 for (p = first(); p != null && k < a.length; p = succ(p)) {
48.494 - E item = p.getItem();
48.495 + E item = p.item;
48.496 if (item != null)
48.497 a[k++] = (T)item;
48.498 }
48.499 @@ -552,7 +623,7 @@
48.500 // If won't fit, use ArrayList version
48.501 ArrayList<E> al = new ArrayList<E>();
48.502 for (Node<E> q = first(); q != null; q = succ(q)) {
48.503 - E item = q.getItem();
48.504 + E item = q.item;
48.505 if (item != null)
48.506 al.add(item);
48.507 }
48.508 @@ -561,7 +632,9 @@
48.509
48.510 /**
48.511 * Returns an iterator over the elements in this queue in proper sequence.
48.512 - * The returned iterator is a "weakly consistent" iterator that
48.513 + * The elements will be returned in order from first (head) to last (tail).
48.514 + *
48.515 + * <p>The returned {@code Iterator} is a "weakly consistent" iterator that
48.516 * will never throw {@link java.util.ConcurrentModificationException
48.517 * ConcurrentModificationException},
48.518 * and guarantees to traverse elements as they existed upon
48.519 @@ -620,7 +693,7 @@
48.520 nextItem = null;
48.521 return x;
48.522 }
48.523 - E item = p.getItem();
48.524 + E item = p.item;
48.525 if (item != null) {
48.526 nextNode = p;
48.527 nextItem = item;
48.528 @@ -648,13 +721,13 @@
48.529 Node<E> l = lastRet;
48.530 if (l == null) throw new IllegalStateException();
48.531 // rely on a future traversal to relink.
48.532 - l.setItem(null);
48.533 + l.item = null;
48.534 lastRet = null;
48.535 }
48.536 }
48.537
48.538 /**
48.539 - * Save the state to a stream (that is, serialize it).
48.540 + * Saves the state to a stream (that is, serializes it).
48.541 *
48.542 * @serialData All of the elements (each an {@code E}) in
48.543 * the proper order, followed by a null
48.544 @@ -668,7 +741,7 @@
48.545
48.546 // Write out all elements in the proper order.
48.547 for (Node<E> p = first(); p != null; p = succ(p)) {
48.548 - Object item = p.getItem();
48.549 + Object item = p.item;
48.550 if (item != null)
48.551 s.writeObject(item);
48.552 }
48.553 @@ -678,25 +751,40 @@
48.554 }
48.555
48.556 /**
48.557 - * Reconstitute the Queue instance from a stream (that is,
48.558 - * deserialize it).
48.559 + * Reconstitutes the instance from a stream (that is, deserializes it).
48.560 * @param s the stream
48.561 */
48.562 private void readObject(java.io.ObjectInputStream s)
48.563 throws java.io.IOException, ClassNotFoundException {
48.564 - // Read in capacity, and any hidden stuff
48.565 s.defaultReadObject();
48.566 - head = new Node<E>(null);
48.567 - tail = head;
48.568 - // Read in all elements and place in queue
48.569 - for (;;) {
48.570 +
48.571 + // Read in elements until trailing null sentinel found
48.572 + Node<E> h = null, t = null;
48.573 + Object item;
48.574 + while ((item = s.readObject()) != null) {
48.575 @SuppressWarnings("unchecked")
48.576 - E item = (E)s.readObject();
48.577 - if (item == null)
48.578 - break;
48.579 - else
48.580 - offer(item);
48.581 + Node<E> newNode = new Node<E>((E) item);
48.582 + if (h == null)
48.583 + h = t = newNode;
48.584 + else {
48.585 + t.lazySetNext(newNode);
48.586 + t = newNode;
48.587 + }
48.588 }
48.589 + if (h == null)
48.590 + h = t = new Node<E>(null);
48.591 + head = h;
48.592 + tail = t;
48.593 + }
48.594 +
48.595 + /**
48.596 + * Throws NullPointerException if argument is null.
48.597 + *
48.598 + * @param v the element
48.599 + */
48.600 + private static void checkNotNull(Object v) {
48.601 + if (v == null)
48.602 + throw new NullPointerException();
48.603 }
48.604
48.605 // Unsafe mechanics
48.606 @@ -715,10 +803,6 @@
48.607 return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
48.608 }
48.609
48.610 - private void lazySetHead(Node<E> val) {
48.611 - UNSAFE.putOrderedObject(this, headOffset, val);
48.612 - }
48.613 -
48.614 static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
48.615 String field, Class<?> klazz) {
48.616 try {
49.1 --- a/src/share/classes/java/util/concurrent/ForkJoinPool.java Thu Oct 07 15:12:19 2010 -0700
49.2 +++ b/src/share/classes/java/util/concurrent/ForkJoinPool.java Tue Oct 12 12:51:48 2010 -0700
49.3 @@ -42,7 +42,6 @@
49.4 import java.util.List;
49.5 import java.util.concurrent.AbstractExecutorService;
49.6 import java.util.concurrent.Callable;
49.7 -import java.util.concurrent.CountDownLatch;
49.8 import java.util.concurrent.ExecutorService;
49.9 import java.util.concurrent.Future;
49.10 import java.util.concurrent.RejectedExecutionException;
49.11 @@ -823,15 +822,13 @@
49.12 (workerCounts & RUNNING_COUNT_MASK) <= 1);
49.13 long startTime = untimed? 0 : System.nanoTime();
49.14 Thread.interrupted(); // clear/ignore interrupt
49.15 - if (eventCount != ec || w.runState != 0 ||
49.16 - runState >= TERMINATING) // recheck after clear
49.17 - break;
49.18 + if (eventCount != ec || w.isTerminating())
49.19 + break; // recheck after clear
49.20 if (untimed)
49.21 LockSupport.park(w);
49.22 else {
49.23 LockSupport.parkNanos(w, SHRINK_RATE_NANOS);
49.24 - if (eventCount != ec || w.runState != 0 ||
49.25 - runState >= TERMINATING)
49.26 + if (eventCount != ec || w.isTerminating())
49.27 break;
49.28 if (System.nanoTime() - startTime >= SHRINK_RATE_NANOS)
49.29 tryShutdownUnusedWorker(ec);
49.30 @@ -899,16 +896,23 @@
49.31 UNSAFE.compareAndSwapInt(this, workerCountsOffset, wc,
49.32 wc + (ONE_RUNNING|ONE_TOTAL))) {
49.33 ForkJoinWorkerThread w = null;
49.34 + Throwable fail = null;
49.35 try {
49.36 w = factory.newThread(this);
49.37 - } finally { // adjust on null or exceptional factory return
49.38 - if (w == null) {
49.39 - decrementWorkerCounts(ONE_RUNNING, ONE_TOTAL);
49.40 - tryTerminate(false); // handle failure during shutdown
49.41 - }
49.42 + } catch (Throwable ex) {
49.43 + fail = ex;
49.44 }
49.45 - if (w == null)
49.46 + if (w == null) { // null or exceptional factory return
49.47 + decrementWorkerCounts(ONE_RUNNING, ONE_TOTAL);
49.48 + tryTerminate(false); // handle failure during shutdown
49.49 + // If originating from an external caller,
49.50 + // propagate exception, else ignore
49.51 + if (fail != null && runState < TERMINATING &&
49.52 + !(Thread.currentThread() instanceof
49.53 + ForkJoinWorkerThread))
49.54 + UNSAFE.throwException(fail);
49.55 break;
49.56 + }
49.57 w.start(recordWorker(w), ueh);
49.58 if ((workerCounts >>> TOTAL_COUNT_SHIFT) >= pc) {
49.59 int c; // advance event count
49.60 @@ -997,8 +1001,12 @@
49.61 boolean active = w.active;
49.62 boolean inactivate = false;
49.63 int pc = parallelism;
49.64 - int rs;
49.65 - while (w.runState == 0 && (rs = runState) < TERMINATING) {
49.66 + while (w.runState == 0) {
49.67 + int rs = runState;
49.68 + if (rs >= TERMINATING) { // propagate shutdown
49.69 + w.shutdown();
49.70 + break;
49.71 + }
49.72 if ((inactivate || (active && (rs & ACTIVE_COUNT_MASK) >= pc)) &&
49.73 UNSAFE.compareAndSwapInt(this, runStateOffset, rs, rs - 1))
49.74 inactivate = active = w.active = false;
49.75 @@ -1126,6 +1134,7 @@
49.76 return true;
49.77 }
49.78
49.79 +
49.80 /**
49.81 * Actions on transition to TERMINATING
49.82 *
49.83 @@ -1149,7 +1158,7 @@
49.84 if (passes > 0 && !w.isTerminated()) {
49.85 w.cancelTasks();
49.86 LockSupport.unpark(w);
49.87 - if (passes > 1) {
49.88 + if (passes > 1 && !w.isInterrupted()) {
49.89 try {
49.90 w.interrupt();
49.91 } catch (SecurityException ignore) {
49.92 @@ -1726,6 +1735,13 @@
49.93 }
49.94
49.95 /**
49.96 + * Returns true if terminating or terminated. Used by ForkJoinWorkerThread.
49.97 + */
49.98 + final boolean isAtLeastTerminating() {
49.99 + return runState >= TERMINATING;
49.100 + }
49.101 +
49.102 + /**
49.103 * Returns {@code true} if this pool has been shut down.
49.104 *
49.105 * @return {@code true} if this pool has been shut down
50.1 --- a/src/share/classes/java/util/concurrent/ForkJoinTask.java Thu Oct 07 15:12:19 2010 -0700
50.2 +++ b/src/share/classes/java/util/concurrent/ForkJoinTask.java Tue Oct 12 12:51:48 2010 -0700
50.3 @@ -55,10 +55,10 @@
50.4 * start other subtasks. As indicated by the name of this class,
50.5 * many programs using {@code ForkJoinTask} employ only methods
50.6 * {@link #fork} and {@link #join}, or derivatives such as {@link
50.7 - * #invokeAll}. However, this class also provides a number of other
50.8 - * methods that can come into play in advanced usages, as well as
50.9 - * extension mechanics that allow support of new forms of fork/join
50.10 - * processing.
50.11 + * #invokeAll(ForkJoinTask...) invokeAll}. However, this class also
50.12 + * provides a number of other methods that can come into play in
50.13 + * advanced usages, as well as extension mechanics that allow
50.14 + * support of new forms of fork/join processing.
50.15 *
50.16 * <p>A {@code ForkJoinTask} is a lightweight form of {@link Future}.
50.17 * The efficiency of {@code ForkJoinTask}s stems from a set of
50.18 @@ -250,7 +250,7 @@
50.19 int s; // the odd construction reduces lock bias effects
50.20 while ((s = status) >= 0) {
50.21 try {
50.22 - synchronized(this) {
50.23 + synchronized (this) {
50.24 if (UNSAFE.compareAndSwapInt(this, statusOffset, s,SIGNAL))
50.25 wait();
50.26 }
50.27 @@ -270,7 +270,7 @@
50.28 int s;
50.29 if ((s = status) >= 0) {
50.30 try {
50.31 - synchronized(this) {
50.32 + synchronized (this) {
50.33 if (UNSAFE.compareAndSwapInt(this, statusOffset, s,SIGNAL))
50.34 wait(millis, 0);
50.35 }
50.36 @@ -288,7 +288,7 @@
50.37 private void externalAwaitDone() {
50.38 int s;
50.39 while ((s = status) >= 0) {
50.40 - synchronized(this) {
50.41 + synchronized (this) {
50.42 if (UNSAFE.compareAndSwapInt(this, statusOffset, s, SIGNAL)){
50.43 boolean interrupted = false;
50.44 while (status >= 0) {
50.45 @@ -669,11 +669,34 @@
50.46 setCompletion(NORMAL);
50.47 }
50.48
50.49 + /**
50.50 + * Waits if necessary for the computation to complete, and then
50.51 + * retrieves its result.
50.52 + *
50.53 + * @return the computed result
50.54 + * @throws CancellationException if the computation was cancelled
50.55 + * @throws ExecutionException if the computation threw an
50.56 + * exception
50.57 + * @throws InterruptedException if the current thread is not a
50.58 + * member of a ForkJoinPool and was interrupted while waiting
50.59 + */
50.60 public final V get() throws InterruptedException, ExecutionException {
50.61 - quietlyJoin();
50.62 - if (Thread.interrupted())
50.63 - throw new InterruptedException();
50.64 - int s = status;
50.65 + int s;
50.66 + if (Thread.currentThread() instanceof ForkJoinWorkerThread) {
50.67 + quietlyJoin();
50.68 + s = status;
50.69 + }
50.70 + else {
50.71 + while ((s = status) >= 0) {
50.72 + synchronized (this) { // interruptible form of awaitDone
50.73 + if (UNSAFE.compareAndSwapInt(this, statusOffset,
50.74 + s, SIGNAL)) {
50.75 + while (status >= 0)
50.76 + wait();
50.77 + }
50.78 + }
50.79 + }
50.80 + }
50.81 if (s < NORMAL) {
50.82 Throwable ex;
50.83 if (s == CANCELLED)
50.84 @@ -684,6 +707,20 @@
50.85 return getRawResult();
50.86 }
50.87
50.88 + /**
50.89 + * Waits if necessary for at most the given time for the computation
50.90 + * to complete, and then retrieves its result, if available.
50.91 + *
50.92 + * @param timeout the maximum time to wait
50.93 + * @param unit the time unit of the timeout argument
50.94 + * @return the computed result
50.95 + * @throws CancellationException if the computation was cancelled
50.96 + * @throws ExecutionException if the computation threw an
50.97 + * exception
50.98 + * @throws InterruptedException if the current thread is not a
50.99 + * member of a ForkJoinPool and was interrupted while waiting
50.100 + * @throws TimeoutException if the wait timed out
50.101 + */
50.102 public final V get(long timeout, TimeUnit unit)
50.103 throws InterruptedException, ExecutionException, TimeoutException {
50.104 Thread t = Thread.currentThread();
50.105 @@ -725,7 +762,7 @@
50.106 long ms = nt / 1000000;
50.107 int ns = (int) (nt % 1000000);
50.108 try {
50.109 - synchronized(this) {
50.110 + synchronized (this) {
50.111 if (status >= 0)
50.112 wait(ms, ns);
50.113 }
51.1 --- a/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java Thu Oct 07 15:12:19 2010 -0700
51.2 +++ b/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java Tue Oct 12 12:51:48 2010 -0700
51.3 @@ -778,11 +778,20 @@
51.4
51.5 // status check methods used mainly by ForkJoinPool
51.6 final boolean isRunning() { return runState == 0; }
51.7 - final boolean isTerminating() { return (runState & TERMINATING) != 0; }
51.8 final boolean isTerminated() { return (runState & TERMINATED) != 0; }
51.9 final boolean isSuspended() { return (runState & SUSPENDED) != 0; }
51.10 final boolean isTrimmed() { return (runState & TRIMMED) != 0; }
51.11
51.12 + final boolean isTerminating() {
51.13 + if ((runState & TERMINATING) != 0)
51.14 + return true;
51.15 + if (pool.isAtLeastTerminating()) { // propagate pool state
51.16 + shutdown();
51.17 + return true;
51.18 + }
51.19 + return false;
51.20 + }
51.21 +
51.22 /**
51.23 * Sets state to TERMINATING. Does NOT unpark or interrupt
51.24 * to wake up if currently blocked. Callers must do so if desired.
52.1 --- a/src/share/classes/java/util/concurrent/RecursiveAction.java Thu Oct 07 15:12:19 2010 -0700
52.2 +++ b/src/share/classes/java/util/concurrent/RecursiveAction.java Tue Oct 12 12:51:48 2010 -0700
52.3 @@ -138,7 +138,7 @@
52.4 * if (right.tryUnfork()) // directly calculate if not stolen
52.5 * sum += right.atLeaf(right.lo, right.hi);
52.6 * else {
52.7 - * right.helpJoin();
52.8 + * right.join();
52.9 * sum += right.result;
52.10 * }
52.11 * right = right.next;
53.1 --- a/src/share/classes/java/util/logging/LogManager.java Thu Oct 07 15:12:19 2010 -0700
53.2 +++ b/src/share/classes/java/util/logging/LogManager.java Tue Oct 12 12:51:48 2010 -0700
53.3 @@ -690,6 +690,11 @@
53.4 * Note that since untrusted code may create loggers with
53.5 * arbitrary names this method should not be relied on to
53.6 * find Loggers for security sensitive logging.
53.7 + * It is also important to note that the Logger associated with the
53.8 + * String {@code name} may be garbage collected at any time if there
53.9 + * is no strong reference to the Logger. The caller of this method
53.10 + * must check the return value for null in order to properly handle
53.11 + * the case where the Logger has been garbage collected.
53.12 * <p>
53.13 * @param name name of the logger
53.14 * @return matching logger or null if none is found
53.15 @@ -713,6 +718,14 @@
53.16 * <p>
53.17 * Note: Loggers may be added dynamically as new classes are loaded.
53.18 * This method only reports on the loggers that are currently registered.
53.19 + * It is also important to note that this method only returns the name
53.20 + * of a Logger, not a strong reference to the Logger itself.
53.21 + * The returned String does nothing to prevent the Logger from being
53.22 + * garbage collected. In particular, if the returned name is passed
53.23 + * to {@code LogManager.getLogger()}, then the caller must check the
53.24 + * return value from {@code LogManager.getLogger()} for null to properly
53.25 + * handle the case where the Logger has been garbage collected in the
53.26 + * time since its name was returned by this method.
53.27 * <p>
53.28 * @return enumeration of logger name strings
53.29 */
54.1 --- a/src/share/classes/java/util/logging/Logger.java Thu Oct 07 15:12:19 2010 -0700
54.2 +++ b/src/share/classes/java/util/logging/Logger.java Tue Oct 12 12:51:48 2010 -0700
54.3 @@ -42,7 +42,10 @@
54.4 * <p>
54.5 * Logger objects may be obtained by calls on one of the getLogger
54.6 * factory methods. These will either create a new Logger or
54.7 - * return a suitable existing Logger.
54.8 + * return a suitable existing Logger. It is important to note that
54.9 + * the Logger returned by one of the {@code getLogger} factory methods
54.10 + * may be garbage collected at any time if a strong reference to the
54.11 + * Logger is not kept.
54.12 * <p>
54.13 * Logging messages will be forwarded to registered Handler
54.14 * objects, which can forward the messages to a variety of
54.15 @@ -210,7 +213,9 @@
54.16 * who are making serious use of the logging package (for example
54.17 * in products) should create and use their own Logger objects,
54.18 * with appropriate names, so that logging can be controlled on a
54.19 - * suitable per-Logger granularity.
54.20 + * suitable per-Logger granularity. Developers also need to keep a
54.21 + * strong reference to their Logger objects to prevent them from
54.22 + * being garbage collected.
54.23 * <p>
54.24 * @deprecated Initialization of this field is prone to deadlocks.
54.25 * The field must be initialized by the Logger class initialization
54.26 @@ -287,6 +292,15 @@
54.27 * based on the LogManager configuration and it will configured
54.28 * to also send logging output to its parent's Handlers. It will
54.29 * be registered in the LogManager global namespace.
54.30 + * <p>
54.31 + * Note: The LogManager may only retain a weak reference to the newly
54.32 + * created Logger. It is important to understand that a previously
54.33 + * created Logger with the given name may be garbage collected at any
54.34 + * time if there is no strong reference to the Logger. In particular,
54.35 + * this means that two back-to-back calls like
54.36 + * {@code getLogger("MyLogger").log(...)} may use different Logger
54.37 + * objects named "MyLogger" if there is no strong reference to the
54.38 + * Logger named "MyLogger" elsewhere in the program.
54.39 *
54.40 * @param name A name for the logger. This should
54.41 * be a dot-separated name and should normally
54.42 @@ -311,6 +325,15 @@
54.43 * output to its parent's Handlers. It will be registered in
54.44 * the LogManager global namespace.
54.45 * <p>
54.46 + * Note: The LogManager may only retain a weak reference to the newly
54.47 + * created Logger. It is important to understand that a previously
54.48 + * created Logger with the given name may be garbage collected at any
54.49 + * time if there is no strong reference to the Logger. In particular,
54.50 + * this means that two back-to-back calls like
54.51 + * {@code getLogger("MyLogger", ...).log(...)} may use different Logger
54.52 + * objects named "MyLogger" if there is no strong reference to the
54.53 + * Logger named "MyLogger" elsewhere in the program.
54.54 + * <p>
54.55 * If the named Logger already exists and does not yet have a
54.56 * localization resource bundle then the given resource bundle
54.57 * name is used. If the named Logger already exists and has
55.1 --- a/src/share/classes/javax/sql/rowset/BaseRowSet.java Thu Oct 07 15:12:19 2010 -0700
55.2 +++ b/src/share/classes/javax/sql/rowset/BaseRowSet.java Tue Oct 12 12:51:48 2010 -0700
55.3 @@ -1,5 +1,5 @@
55.4 /*
55.5 - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
55.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
55.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55.8 *
55.9 * This code is free software; you can redistribute it and/or modify it
55.10 @@ -734,7 +734,7 @@
55.11 throw new SQLException("Set initParams() before setCommand");
55.12 }
55.13 params.clear();
55.14 - command = new String(cmd);
55.15 + command = cmd;
55.16 }
55.17
55.18 }
55.19 @@ -797,7 +797,7 @@
55.20 throw new SQLException("Invalid url string detected. " +
55.21 "Cannot be of length less than 1");
55.22 } else {
55.23 - URL = new String(url);
55.24 + URL = url;
55.25 }
55.26
55.27 dataSource = null;
55.28 @@ -854,7 +854,7 @@
55.29 } else if (name.equals("")) {
55.30 throw new SQLException("DataSource name cannot be empty string");
55.31 } else {
55.32 - dataSource = new String(name);
55.33 + dataSource = name;
55.34 }
55.35
55.36 URL = null;
55.37 @@ -889,7 +889,7 @@
55.38 {
55.39 username = null;
55.40 } else {
55.41 - username = new String(name);
55.42 + username = name;
55.43 }
55.44 }
55.45
55.46 @@ -924,7 +924,7 @@
55.47 {
55.48 password = null;
55.49 } else {
55.50 - password = new String(pass);
55.51 + password = pass;
55.52 }
55.53 }
55.54
55.55 @@ -1563,13 +1563,13 @@
55.56
55.57 nullVal = new Object[2];
55.58 nullVal[0] = null;
55.59 - nullVal[1] = new Integer(sqlType);
55.60 + nullVal[1] = Integer.valueOf(sqlType);
55.61
55.62 if (params == null){
55.63 throw new SQLException("Set initParams() before setNull");
55.64 }
55.65
55.66 - params.put(new Integer(parameterIndex - 1), nullVal);
55.67 + params.put(Integer.valueOf(parameterIndex - 1), nullVal);
55.68 }
55.69
55.70 /**
55.71 @@ -1644,14 +1644,14 @@
55.72
55.73 nullVal = new Object[3];
55.74 nullVal[0] = null;
55.75 - nullVal[1] = new Integer(sqlType);
55.76 - nullVal[2] = new String(typeName);
55.77 + nullVal[1] = Integer.valueOf(sqlType);
55.78 + nullVal[2] = typeName;
55.79
55.80 if(params == null){
55.81 throw new SQLException("Set initParams() before setNull");
55.82 }
55.83
55.84 - params.put(new Integer(parameterIndex - 1), nullVal);
55.85 + params.put(Integer.valueOf(parameterIndex - 1), nullVal);
55.86 }
55.87
55.88
55.89 @@ -1686,7 +1686,7 @@
55.90 throw new SQLException("Set initParams() before setNull");
55.91 }
55.92
55.93 - params.put(new Integer(parameterIndex - 1), new Boolean(x));
55.94 + params.put(Integer.valueOf(parameterIndex - 1), Boolean.valueOf(x));
55.95 }
55.96
55.97 /**
55.98 @@ -1720,7 +1720,7 @@
55.99 throw new SQLException("Set initParams() before setByte");
55.100 }
55.101
55.102 - params.put(new Integer(parameterIndex - 1), new Byte(x));
55.103 + params.put(Integer.valueOf(parameterIndex - 1), Byte.valueOf(x));
55.104 }
55.105
55.106 /**
55.107 @@ -1754,7 +1754,7 @@
55.108 throw new SQLException("Set initParams() before setShort");
55.109 }
55.110
55.111 - params.put(new Integer(parameterIndex - 1), new Short(x));
55.112 + params.put(Integer.valueOf(parameterIndex - 1), Short.valueOf(x));
55.113 }
55.114
55.115 /**
55.116 @@ -1786,7 +1786,7 @@
55.117 if(params == null){
55.118 throw new SQLException("Set initParams() before setInt");
55.119 }
55.120 - params.put(new Integer(parameterIndex - 1), new Integer(x));
55.121 + params.put(Integer.valueOf(parameterIndex - 1), Integer.valueOf(x));
55.122 }
55.123
55.124 /**
55.125 @@ -1818,7 +1818,7 @@
55.126 if(params == null){
55.127 throw new SQLException("Set initParams() before setLong");
55.128 }
55.129 - params.put(new Integer(parameterIndex - 1), new Long(x));
55.130 + params.put(Integer.valueOf(parameterIndex - 1), Long.valueOf(x));
55.131 }
55.132
55.133 /**
55.134 @@ -1850,7 +1850,7 @@
55.135 if(params == null){
55.136 throw new SQLException("Set initParams() before setFloat");
55.137 }
55.138 - params.put(new Integer(parameterIndex - 1), new Float(x));
55.139 + params.put(Integer.valueOf(parameterIndex - 1), new Float(x));
55.140 }
55.141
55.142 /**
55.143 @@ -1882,7 +1882,7 @@
55.144 if(params == null){
55.145 throw new SQLException("Set initParams() before setDouble");
55.146 }
55.147 - params.put(new Integer(parameterIndex - 1), new Double(x));
55.148 + params.put(Integer.valueOf(parameterIndex - 1), new Double(x));
55.149 }
55.150
55.151 /**
55.152 @@ -1914,7 +1914,7 @@
55.153 if(params == null){
55.154 throw new SQLException("Set initParams() before setBigDecimal");
55.155 }
55.156 - params.put(new Integer(parameterIndex - 1), x);
55.157 + params.put(Integer.valueOf(parameterIndex - 1), x);
55.158 }
55.159
55.160 /**
55.161 @@ -1948,7 +1948,7 @@
55.162 if(params == null){
55.163 throw new SQLException("Set initParams() before setString");
55.164 }
55.165 - params.put(new Integer(parameterIndex - 1), x);
55.166 + params.put(Integer.valueOf(parameterIndex - 1), x);
55.167 }
55.168
55.169 /**
55.170 @@ -1982,7 +1982,7 @@
55.171 if(params == null){
55.172 throw new SQLException("Set initParams() before setBytes");
55.173 }
55.174 - params.put(new Integer(parameterIndex - 1), x);
55.175 + params.put(Integer.valueOf(parameterIndex - 1), x);
55.176 }
55.177
55.178 /**
55.179 @@ -2024,7 +2024,7 @@
55.180 if(params == null){
55.181 throw new SQLException("Set initParams() before setDate");
55.182 }
55.183 - params.put(new Integer(parameterIndex - 1), x);
55.184 + params.put(Integer.valueOf(parameterIndex - 1), x);
55.185 }
55.186
55.187 /**
55.188 @@ -2069,7 +2069,7 @@
55.189 throw new SQLException("Set initParams() before setTime");
55.190 }
55.191
55.192 - params.put(new Integer(parameterIndex - 1), x);
55.193 + params.put(Integer.valueOf(parameterIndex - 1), x);
55.194 }
55.195
55.196 /**
55.197 @@ -2112,7 +2112,7 @@
55.198 throw new SQLException("Set initParams() before setTimestamp");
55.199 }
55.200
55.201 - params.put(new Integer(parameterIndex - 1), x);
55.202 + params.put(Integer.valueOf(parameterIndex - 1), x);
55.203 }
55.204
55.205 /**
55.206 @@ -2185,14 +2185,14 @@
55.207
55.208 asciiStream = new Object[3];
55.209 asciiStream[0] = x;
55.210 - asciiStream[1] = new Integer(length);
55.211 - asciiStream[2] = new Integer(ASCII_STREAM_PARAM);
55.212 + asciiStream[1] = Integer.valueOf(length);
55.213 + asciiStream[2] = Integer.valueOf(ASCII_STREAM_PARAM);
55.214
55.215 if(params == null){
55.216 throw new SQLException("Set initParams() before setAsciiStream");
55.217 }
55.218
55.219 - params.put(new Integer(parameterIndex - 1), asciiStream);
55.220 + params.put(Integer.valueOf(parameterIndex - 1), asciiStream);
55.221 }
55.222
55.223 /**
55.224 @@ -2290,13 +2290,13 @@
55.225
55.226 binaryStream = new Object[3];
55.227 binaryStream[0] = x;
55.228 - binaryStream[1] = new Integer(length);
55.229 - binaryStream[2] = new Integer(BINARY_STREAM_PARAM);
55.230 + binaryStream[1] = Integer.valueOf(length);
55.231 + binaryStream[2] = Integer.valueOf(BINARY_STREAM_PARAM);
55.232 if(params == null){
55.233 throw new SQLException("Set initParams() before setBinaryStream");
55.234 }
55.235
55.236 - params.put(new Integer(parameterIndex - 1), binaryStream);
55.237 + params.put(Integer.valueOf(parameterIndex - 1), binaryStream);
55.238 }
55.239
55.240
55.241 @@ -2396,12 +2396,12 @@
55.242
55.243 unicodeStream = new Object[3];
55.244 unicodeStream[0] = x;
55.245 - unicodeStream[1] = new Integer(length);
55.246 - unicodeStream[2] = new Integer(UNICODE_STREAM_PARAM);
55.247 + unicodeStream[1] = Integer.valueOf(length);
55.248 + unicodeStream[2] = Integer.valueOf(UNICODE_STREAM_PARAM);
55.249 if(params == null){
55.250 throw new SQLException("Set initParams() before setUnicodeStream");
55.251 }
55.252 - params.put(new Integer(parameterIndex - 1), unicodeStream);
55.253 + params.put(Integer.valueOf(parameterIndex - 1), unicodeStream);
55.254 }
55.255
55.256 /**
55.257 @@ -2475,11 +2475,11 @@
55.258
55.259 charStream = new Object[2];
55.260 charStream[0] = reader;
55.261 - charStream[1] = new Integer(length);
55.262 + charStream[1] = Integer.valueOf(length);
55.263 if(params == null){
55.264 throw new SQLException("Set initParams() before setCharacterStream");
55.265 }
55.266 - params.put(new Integer(parameterIndex - 1), charStream);
55.267 + params.put(Integer.valueOf(parameterIndex - 1), charStream);
55.268 }
55.269
55.270 /**
55.271 @@ -2591,12 +2591,12 @@
55.272
55.273 obj = new Object[3];
55.274 obj[0] = x;
55.275 - obj[1] = new Integer(targetSqlType);
55.276 - obj[2] = new Integer(scale);
55.277 + obj[1] = Integer.valueOf(targetSqlType);
55.278 + obj[2] = Integer.valueOf(scale);
55.279 if(params == null){
55.280 throw new SQLException("Set initParams() before setObject");
55.281 }
55.282 - params.put(new Integer(parameterIndex - 1), obj);
55.283 + params.put(Integer.valueOf(parameterIndex - 1), obj);
55.284 }
55.285
55.286 /**
55.287 @@ -2654,11 +2654,11 @@
55.288
55.289 obj = new Object[2];
55.290 obj[0] = x;
55.291 - obj[1] = new Integer(targetSqlType);
55.292 + obj[1] = Integer.valueOf(targetSqlType);
55.293 if (params == null){
55.294 throw new SQLException("Set initParams() before setObject");
55.295 }
55.296 - params.put(new Integer(parameterIndex - 1), obj);
55.297 + params.put(Integer.valueOf(parameterIndex - 1), obj);
55.298 }
55.299
55.300 /**
55.301 @@ -2726,7 +2726,7 @@
55.302 if (params == null) {
55.303 throw new SQLException("Set initParams() before setObject");
55.304 }
55.305 - params.put(new Integer(parameterIndex - 1), x);
55.306 + params.put(Integer.valueOf(parameterIndex - 1), x);
55.307 }
55.308
55.309 /**
55.310 @@ -2773,7 +2773,7 @@
55.311 if (params == null) {
55.312 throw new SQLException("Set initParams() before setRef");
55.313 }
55.314 - params.put(new Integer(parameterIndex - 1), new SerialRef(ref));
55.315 + params.put(Integer.valueOf(parameterIndex - 1), new SerialRef(ref));
55.316 }
55.317
55.318 /**
55.319 @@ -2817,7 +2817,7 @@
55.320 if(params == null){
55.321 throw new SQLException("Set initParams() before setBlob");
55.322 }
55.323 - params.put(new Integer(parameterIndex - 1), new SerialBlob(x));
55.324 + params.put(Integer.valueOf(parameterIndex - 1), new SerialBlob(x));
55.325 }
55.326
55.327 /**
55.328 @@ -2862,7 +2862,7 @@
55.329 if(params == null){
55.330 throw new SQLException("Set initParams() before setClob");
55.331 }
55.332 - params.put(new Integer(parameterIndex - 1), new SerialClob(x));
55.333 + params.put(Integer.valueOf(parameterIndex - 1), new SerialClob(x));
55.334 }
55.335
55.336 /**
55.337 @@ -2910,7 +2910,7 @@
55.338 if (params == null){
55.339 throw new SQLException("Set initParams() before setArray");
55.340 }
55.341 - params.put(new Integer(parameterIndex - 1), new SerialArray(array));
55.342 + params.put(Integer.valueOf(parameterIndex - 1), new SerialArray(array));
55.343 }
55.344
55.345 /**
55.346 @@ -2975,7 +2975,7 @@
55.347 if(params == null){
55.348 throw new SQLException("Set initParams() before setDate");
55.349 }
55.350 - params.put(new Integer(parameterIndex - 1), date);
55.351 + params.put(Integer.valueOf(parameterIndex - 1), date);
55.352 }
55.353
55.354 /**
55.355 @@ -3041,7 +3041,7 @@
55.356 if(params == null){
55.357 throw new SQLException("Set initParams() before setTime");
55.358 }
55.359 - params.put(new Integer(parameterIndex - 1), time);
55.360 + params.put(Integer.valueOf(parameterIndex - 1), time);
55.361 }
55.362
55.363 /**
55.364 @@ -3107,7 +3107,7 @@
55.365 if(params == null){
55.366 throw new SQLException("Set initParams() before setTimestamp");
55.367 }
55.368 - params.put(new Integer(parameterIndex - 1), timestamp);
55.369 + params.put(Integer.valueOf(parameterIndex - 1), timestamp);
55.370 }
55.371
55.372 /**
55.373 @@ -3181,7 +3181,7 @@
55.374
55.375 Object[] paramsArray = new Object[params.size()];
55.376 for (int i = 0; i < params.size(); i++) {
55.377 - paramsArray[i] = params.get(new Integer(i));
55.378 + paramsArray[i] = params.get(Integer.valueOf(i));
55.379 if (paramsArray[i] == null) {
55.380 throw new SQLException("missing parameter: " + (i + 1));
55.381 } //end if
56.1 --- a/src/share/classes/javax/sql/rowset/CachedRowSet.java Thu Oct 07 15:12:19 2010 -0700
56.2 +++ b/src/share/classes/javax/sql/rowset/CachedRowSet.java Tue Oct 12 12:51:48 2010 -0700
56.3 @@ -39,7 +39,7 @@
56.4 * <code>CachedRowSet</code> must implement.
56.5 * <P>
56.6 * The reference implementation of the <code>CachedRowSet</code> interface provided
56.7 - * by Sun Microsystems is a standard implementation. Developers may use this implementation
56.8 + * by Oracle Corporation is a standard implementation. Developers may use this implementation
56.9 * just as it is, they may extend it, or they may choose to write their own implementations
56.10 * of this interface.
56.11 * <P>
56.12 @@ -1623,4 +1623,3 @@
56.13 public boolean previousPage() throws SQLException;
56.14
56.15 }
56.16 -
57.1 --- a/src/share/classes/javax/sql/rowset/RowSetMetaDataImpl.java Thu Oct 07 15:12:19 2010 -0700
57.2 +++ b/src/share/classes/javax/sql/rowset/RowSetMetaDataImpl.java Tue Oct 12 12:51:48 2010 -0700
57.3 @@ -1,5 +1,5 @@
57.4 /*
57.5 - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
57.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
57.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
57.8 *
57.9 * This code is free software; you can redistribute it and/or modify it
57.10 @@ -306,9 +306,9 @@
57.11 public void setColumnLabel(int columnIndex, String label) throws SQLException {
57.12 checkColRange(columnIndex);
57.13 if (label != null) {
57.14 - colInfo[columnIndex].columnLabel = new String(label);
57.15 + colInfo[columnIndex].columnLabel = label;
57.16 } else {
57.17 - colInfo[columnIndex].columnLabel = new String("");
57.18 + colInfo[columnIndex].columnLabel = "";
57.19 }
57.20 }
57.21
57.22 @@ -326,9 +326,9 @@
57.23 public void setColumnName(int columnIndex, String columnName) throws SQLException {
57.24 checkColRange(columnIndex);
57.25 if (columnName != null) {
57.26 - colInfo[columnIndex].columnName = new String(columnName);
57.27 + colInfo[columnIndex].columnName = columnName;
57.28 } else {
57.29 - colInfo[columnIndex].columnName = new String("");
57.30 + colInfo[columnIndex].columnName = "";
57.31 }
57.32 }
57.33
57.34 @@ -348,9 +348,9 @@
57.35 public void setSchemaName(int columnIndex, String schemaName) throws SQLException {
57.36 checkColRange(columnIndex);
57.37 if (schemaName != null ) {
57.38 - colInfo[columnIndex].schemaName = new String(schemaName);
57.39 + colInfo[columnIndex].schemaName = schemaName;
57.40 } else {
57.41 - colInfo[columnIndex].schemaName = new String("");
57.42 + colInfo[columnIndex].schemaName = "";
57.43 }
57.44 }
57.45
57.46 @@ -411,9 +411,9 @@
57.47 public void setTableName(int columnIndex, String tableName) throws SQLException {
57.48 checkColRange(columnIndex);
57.49 if (tableName != null) {
57.50 - colInfo[columnIndex].tableName = new String(tableName);
57.51 + colInfo[columnIndex].tableName = tableName;
57.52 } else {
57.53 - colInfo[columnIndex].tableName = new String("");
57.54 + colInfo[columnIndex].tableName = "";
57.55 }
57.56 }
57.57
57.58 @@ -432,9 +432,9 @@
57.59 public void setCatalogName(int columnIndex, String catalogName) throws SQLException {
57.60 checkColRange(columnIndex);
57.61 if (catalogName != null)
57.62 - colInfo[columnIndex].catName = new String(catalogName);
57.63 + colInfo[columnIndex].catName = catalogName;
57.64 else
57.65 - colInfo[columnIndex].catName = new String("");
57.66 + colInfo[columnIndex].catName = "";
57.67 }
57.68
57.69 /**
57.70 @@ -474,9 +474,9 @@
57.71 throws SQLException {
57.72 checkColRange(columnIndex);
57.73 if (typeName != null) {
57.74 - colInfo[columnIndex].colTypeName = new String(typeName);
57.75 + colInfo[columnIndex].colTypeName = typeName;
57.76 } else {
57.77 - colInfo[columnIndex].colTypeName = new String("");
57.78 + colInfo[columnIndex].colTypeName = "";
57.79 }
57.80 }
57.81
57.82 @@ -827,7 +827,7 @@
57.83 * or the given column number is out of bounds
57.84 */
57.85 public String getColumnClassName(int columnIndex) throws SQLException {
57.86 - String className = (new String()).getClass().getName();
57.87 + String className = String.class.getName();
57.88
57.89 int sqlType = getColumnType(columnIndex);
57.90
57.91 @@ -835,65 +835,62 @@
57.92
57.93 case Types.NUMERIC:
57.94 case Types.DECIMAL:
57.95 - className = (new java.math.BigDecimal(0)).getClass().getName ();
57.96 + className = java.math.BigDecimal.class.getName();
57.97 break;
57.98
57.99 case Types.BIT:
57.100 - className = (new Boolean(false)).getClass().getName ();
57.101 + className = java.lang.Boolean.class.getName();
57.102 break;
57.103
57.104 case Types.TINYINT:
57.105 - className = (new Byte("0")).getClass().getName ();
57.106 + className = java.lang.Byte.class.getName();
57.107 break;
57.108
57.109 case Types.SMALLINT:
57.110 - className = (new Short("0")).getClass().getName ();
57.111 + className = java.lang.Short.class.getName();
57.112 break;
57.113
57.114 case Types.INTEGER:
57.115 - className = (new Integer(0)).getClass().getName ();
57.116 + className = java.lang.Integer.class.getName();
57.117 break;
57.118
57.119 case Types.BIGINT:
57.120 - className = (new Long(0)).getClass().getName ();
57.121 + className = java.lang.Long.class.getName();
57.122 break;
57.123
57.124 case Types.REAL:
57.125 - className = (new Float(0)).getClass().getName ();
57.126 + className = java.lang.Float.class.getName();
57.127 break;
57.128
57.129 case Types.FLOAT:
57.130 case Types.DOUBLE:
57.131 - className = (new Double(0)).getClass().getName();
57.132 + className = java.lang.Double.class.getName();
57.133 break;
57.134
57.135 case Types.BINARY:
57.136 case Types.VARBINARY:
57.137 case Types.LONGVARBINARY:
57.138 - byte[] b = {};
57.139 - className = (b.getClass()).getName();
57.140 + className = "byte[]";
57.141 break;
57.142
57.143 case Types.DATE:
57.144 - className = (new java.sql.Date(123456)).getClass().getName ();
57.145 + className = java.sql.Date.class.getName();
57.146 break;
57.147
57.148 case Types.TIME:
57.149 - className = (new java.sql.Time(123456)).getClass().getName ();
57.150 + className = java.sql.Time.class.getName();
57.151 break;
57.152
57.153 case Types.TIMESTAMP:
57.154 - className = (new java.sql.Timestamp(123456)).getClass().getName ();
57.155 + className = java.sql.Timestamp.class.getName();
57.156 break;
57.157
57.158 case Types.BLOB:
57.159 - byte[] blob = {};
57.160 - className = (blob.getClass()).getName();
57.161 + className = java.sql.Blob.class.getName();
57.162 break;
57.163
57.164 case Types.CLOB:
57.165 - char[] c = {};
57.166 - className = (c.getClass()).getName();
57.167 + className = java.sql.Clob.class.getName();
57.168 break;
57.169 }
57.170
58.1 --- a/src/share/classes/javax/sql/rowset/RowSetProvider.java Thu Oct 07 15:12:19 2010 -0700
58.2 +++ b/src/share/classes/javax/sql/rowset/RowSetProvider.java Tue Oct 12 12:51:48 2010 -0700
58.3 @@ -29,7 +29,6 @@
58.4 import java.security.PrivilegedAction;
58.5 import java.sql.SQLException;
58.6 import java.util.ServiceLoader;
58.7 -import javax.sql.rowset.RowSetFactory;
58.8
58.9 /**
58.10 * A factory API that enables applications to obtain a
58.11 @@ -82,15 +81,15 @@
58.12 * the <code>RowSetFactory</code> implementation class to load:</p>
58.13 * <ul>
58.14 * <li>
58.15 - * The System property {@code javax.sql.rowset.RowsetFactory}. For example:
58.16 + * The System property {@code javax.sql.rowset.RowSetFactory}. For example:
58.17 * <ul>
58.18 * <li>
58.19 - * -Djavax.sql.rowset.RowsetFactory=com.sun.rowset.RowSetFactoryImpl
58.20 + * -Djavax.sql.rowset.RowSetFactory=com.sun.rowset.RowSetFactoryImpl
58.21 * </li>
58.22 * </ul>
58.23 * <li>
58.24 - * The ServiceLocator API. The ServiceLocator API will look
58.25 - * for a classname in the file
58.26 + * The {@link ServiceLoader} API. The {@code ServiceLoader} API will look
58.27 + * for a class name in the file
58.28 * {@code META-INF/services/javax.sql.rowset.RowSetFactory}
58.29 * in jars available to the runtime. For example, to have the the RowSetFactory
58.30 * implementation {@code com.sun.rowset.RowSetFactoryImpl } loaded, the
58.31 @@ -271,7 +270,7 @@
58.32 /**
58.33 * Returns the requested System Property. If a {@code SecurityException}
58.34 * occurs, just return NULL
58.35 - * @param propName - System property to retreive
58.36 + * @param propName - System property to retrieve
58.37 * @return The System property value or NULL if the property does not exist
58.38 * or a {@code SecurityException} occurs.
58.39 */
59.1 --- a/src/share/classes/javax/sql/rowset/WebRowSet.java Thu Oct 07 15:12:19 2010 -0700
59.2 +++ b/src/share/classes/javax/sql/rowset/WebRowSet.java Tue Oct 12 12:51:48 2010 -0700
59.3 @@ -1,5 +1,5 @@
59.4 /*
59.5 - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
59.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
59.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
59.8 *
59.9 * This code is free software; you can redistribute it and/or modify it
59.10 @@ -115,7 +115,7 @@
59.11 * <<font color=red>url</font>>jdbc:thin:oracle<<font color=red>/url</font>>
59.12 * <<font color=red>sync-provider</font>>
59.13 * <<font color=red>sync-provider-name</font>>.com.rowset.provider.RIOptimisticProvider<<font color=red>/sync-provider-name</font>>
59.14 - * <<font color=red>sync-provider-vendor</font>>Sun Microsystems<<font color=red>/sync-provider-vendor</font>>
59.15 + * <<font color=red>sync-provider-vendor</font>>Oracle Corporation<<font color=red>/sync-provider-vendor</font>>
59.16 * <<font color=red>sync-provider-version</font>>1.0<<font color=red>/sync-provider-name</font>>
59.17 * <<font color=red>sync-provider-grade</font>>LOW<<font color=red>/sync-provider-grade</font>>
59.18 * <<font color=red>data-source-lock</font>>NONE<<font color=red>/data-source-lock</font>>
59.19 @@ -489,7 +489,7 @@
59.20 * tags and their valid values for a <code>WebRowSet</code> implementation.
59.21 */
59.22 public static String PUBLIC_XML_SCHEMA =
59.23 - "--//Sun Microsystems, Inc.//XSD Schema//EN";
59.24 + "--//Oracle Corporation//XSD Schema//EN";
59.25
59.26 /**
59.27 * The URL for the XML Schema definition file that defines the XML tags and
60.1 --- a/src/share/classes/javax/sql/rowset/rowset.properties Thu Oct 07 15:12:19 2010 -0700
60.2 +++ b/src/share/classes/javax/sql/rowset/rowset.properties Tue Oct 12 12:51:48 2010 -0700
60.3 @@ -3,10 +3,10 @@
60.4
60.5 # Optimistic synchonriztaion provider
60.6 rowset.provider.classname.0=com.sun.rowset.providers.RIOptimisticProvider
60.7 -rowset.provider.vendor.0=Sun Microsystems Inc
60.8 +rowset.provider.vendor.0=Oracle Corporation
60.9 rowset.provider.version.0=1.0
60.10
60.11 # XML Provider using standard XML schema
60.12 rowset.provider.classname.1=com.sun.rowset.providers.RIXMLProvider
60.13 -rowset.provider.vendor.1=Sun Microsystems Inc.
60.14 +rowset.provider.vendor.1=Oracle Corporation
60.15 rowset.provider.version.1=1.0
61.1 --- a/src/share/classes/javax/sql/rowset/serial/SQLOutputImpl.java Thu Oct 07 15:12:19 2010 -0700
61.2 +++ b/src/share/classes/javax/sql/rowset/serial/SQLOutputImpl.java Tue Oct 12 12:51:48 2010 -0700
61.3 @@ -1,5 +1,5 @@
61.4 /*
61.5 - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
61.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
61.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
61.8 *
61.9 * This code is free software; you can redistribute it and/or modify it
61.10 @@ -137,7 +137,7 @@
61.11 * values of a UDT to the database.
61.12 */
61.13 public void writeBoolean(boolean x) throws SQLException {
61.14 - attribs.add(new Boolean(x));
61.15 + attribs.add(Boolean.valueOf(x));
61.16 }
61.17
61.18 /**
61.19 @@ -151,7 +151,7 @@
61.20 * values of a UDT to the database.
61.21 */
61.22 public void writeByte(byte x) throws SQLException {
61.23 - attribs.add(new Byte(x));
61.24 + attribs.add(Byte.valueOf(x));
61.25 }
61.26
61.27 /**
61.28 @@ -165,7 +165,7 @@
61.29 * values of a UDT to the database.
61.30 */
61.31 public void writeShort(short x) throws SQLException {
61.32 - attribs.add(new Short(x));
61.33 + attribs.add(Short.valueOf(x));
61.34 }
61.35
61.36 /**
61.37 @@ -179,7 +179,7 @@
61.38 * values of a UDT to the database.
61.39 */
61.40 public void writeInt(int x) throws SQLException {
61.41 - attribs.add(new Integer(x));
61.42 + attribs.add(Integer.valueOf(x));
61.43 }
61.44
61.45 /**
61.46 @@ -193,7 +193,7 @@
61.47 * values of a UDT to the database.
61.48 */
61.49 public void writeLong(long x) throws SQLException {
61.50 - attribs.add(new Long(x));
61.51 + attribs.add(Long.valueOf(x));
61.52 }
61.53
61.54 /**
62.1 --- a/src/share/classes/javax/sql/rowset/serial/SerialRef.java Thu Oct 07 15:12:19 2010 -0700
62.2 +++ b/src/share/classes/javax/sql/rowset/serial/SerialRef.java Tue Oct 12 12:51:48 2010 -0700
62.3 @@ -1,5 +1,5 @@
62.4 /*
62.5 - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
62.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
62.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
62.8 *
62.9 * This code is free software; you can redistribute it and/or modify it
62.10 @@ -77,7 +77,7 @@
62.11 throw new SQLException("Cannot instantiate a SerialRef object " +
62.12 "that returns a null base type name");
62.13 } else {
62.14 - baseTypeName = new String(ref.getBaseTypeName());
62.15 + baseTypeName = ref.getBaseTypeName();
62.16 }
62.17 }
62.18
62.19 @@ -110,7 +110,7 @@
62.20 throws SerialException
62.21 {
62.22 map = new Hashtable(map);
62.23 - if (!object.equals(null)) {
62.24 + if (object != null) {
62.25 return map.get(object);
62.26 } else {
62.27 throw new SerialException("The object is not set");
63.1 --- a/src/share/classes/javax/sql/rowset/serial/SerialStruct.java Thu Oct 07 15:12:19 2010 -0700
63.2 +++ b/src/share/classes/javax/sql/rowset/serial/SerialStruct.java Tue Oct 12 12:51:48 2010 -0700
63.3 @@ -1,5 +1,5 @@
63.4 /*
63.5 - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
63.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
63.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
63.8 *
63.9 * This code is free software; you can redistribute it and/or modify it
63.10 @@ -94,7 +94,7 @@
63.11 try {
63.12
63.13 // get the type name
63.14 - SQLTypeName = new String(in.getSQLTypeName());
63.15 + SQLTypeName = in.getSQLTypeName();
63.16 System.out.println("SQLTypeName: " + SQLTypeName);
63.17
63.18 // get the attributes of the struct
63.19 @@ -137,7 +137,7 @@
63.20 try {
63.21
63.22 //set the type name
63.23 - SQLTypeName = new String(in.getSQLTypeName());
63.24 + SQLTypeName = in.getSQLTypeName();
63.25
63.26 Vector tmp = new Vector();
63.27 in.writeSQL(new SQLOutputImpl(tmp, map));
63.28 @@ -247,7 +247,7 @@
63.29 }
63.30
63.31 /**
63.32 - * The identifier that assists in the serialization of this
63.33 + * The identifier that assists in the serialization of this
63.34 * <code>SerialStruct</code> object.
63.35 */
63.36 static final long serialVersionUID = -8322445504027483372L;
64.1 --- a/src/share/classes/javax/sql/rowset/spi/SyncFactory.java Thu Oct 07 15:12:19 2010 -0700
64.2 +++ b/src/share/classes/javax/sql/rowset/spi/SyncFactory.java Tue Oct 12 12:51:48 2010 -0700
64.3 @@ -125,12 +125,12 @@
64.4 *
64.5 * # Optimistic synchronization provider
64.6 * rowset.provider.classname.0=com.sun.rowset.providers.RIOptimisticProvider
64.7 - * rowset.provider.vendor.0=Sun Microsystems Inc
64.8 + * rowset.provider.vendor.0=Oracle Corporation
64.9 * rowset.provider.version.0=1.0
64.10 *
64.11 * # XML Provider using standard XML schema
64.12 * rowset.provider.classname.1=com.sun.rowset.providers.RIXMLProvider
64.13 - * rowset.provider.vendor.1=Sun Microsystems Inc.
64.14 + * rowset.provider.vendor.1=Oracle Corporation
64.15 * rowset.provider.version.1=1.0
64.16 * </PRE>
64.17 * The <code>SyncFactory</code> checks this file and registers the
64.18 @@ -369,7 +369,7 @@
64.19 try {
64.20
64.21 // check if user is supplying his Synchronisation Provider
64.22 - // Implementation if not use Sun's implementation.
64.23 + // Implementation if not using Oracle's implementation.
64.24 // properties.load(new FileInputStream(ROWSET_PROPERTIES));
64.25
64.26 // The rowset.properties needs to be in jdk/jre/lib when
65.1 --- a/src/share/classes/javax/sql/rowset/spi/SyncProvider.java Thu Oct 07 15:12:19 2010 -0700
65.2 +++ b/src/share/classes/javax/sql/rowset/spi/SyncProvider.java Tue Oct 12 12:51:48 2010 -0700
65.3 @@ -91,8 +91,8 @@
65.4 * </pre>
65.5 * <p>
65.6 * A vendor can register a <code>SyncProvider</code> implementation class name
65.7 - * with Sun Microsystems, Inc. by sending email to jdbc@sun.com.
65.8 - * Sun will maintain a database listing the
65.9 + * with Oracle Corporation by sending email to jdbc@sun.com.
65.10 + * Oracle will maintain a database listing the
65.11 * available <code>SyncProvider</code> implementations for use with compliant
65.12 * <code>RowSet</code> implementations. This database will be similar to the
65.13 * one already maintained to list available JDBC drivers.
66.1 --- a/src/share/classes/javax/sql/rowset/spi/package.html Thu Oct 07 15:12:19 2010 -0700
66.2 +++ b/src/share/classes/javax/sql/rowset/spi/package.html Tue Oct 12 12:51:48 2010 -0700
66.3 @@ -8,7 +8,7 @@
66.4 <meta name="GENERATOR"
66.5 content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
66.6 <!--
66.7 -Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
66.8 +Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
66.9 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
66.10
66.11 This code is free software; you can redistribute it and/or modify it
66.12 @@ -199,7 +199,7 @@
66.13 Vendors may develop a <tt>SyncProvider</tt> implementation with any one of the possible
66.14 levels of synchronization, thus giving <code>RowSet</code> objects a choice of
66.15 synchronization mechanisms. A vendor can make its implementation available by
66.16 -registering the fully qualified class name with Sun Microsystems at
66.17 +registering the fully qualified class name with Oracle Corporation at
66.18 <code>jdbc@sun.com</code>. This process is discussed in further detail below.
66.19 <P>
66.20
67.1 --- a/src/share/classes/javax/swing/GroupLayout.java Thu Oct 07 15:12:19 2010 -0700
67.2 +++ b/src/share/classes/javax/swing/GroupLayout.java Tue Oct 12 12:51:48 2010 -0700
67.3 @@ -1464,8 +1464,8 @@
67.4 * <= {@code pref} <= {@code max}.
67.5 * <p>
67.6 * Similarly any methods that take a {@code Component} throw a
67.7 - * {@code NullPointerException} if passed {@code null} and any methods
67.8 - * that take a {@code Group} throw an {@code IllegalArgumentException} if
67.9 + * {@code IllegalArgumentException} if passed {@code null} and any methods
67.10 + * that take a {@code Group} throw an {@code NullPointerException} if
67.11 * passed {@code null}.
67.12 *
67.13 * @see #createSequentialGroup
68.1 --- a/src/share/classes/javax/swing/JComponent.java Thu Oct 07 15:12:19 2010 -0700
68.2 +++ b/src/share/classes/javax/swing/JComponent.java Tue Oct 12 12:51:48 2010 -0700
68.3 @@ -4787,6 +4787,17 @@
68.4 * @see RepaintManager#addDirtyRegion
68.5 */
68.6 public void repaint(long tm, int x, int y, int width, int height) {
68.7 + Container p = this;
68.8 + while ((p = p.getParent()) instanceof JComponent) {
68.9 + JComponent jp = (JComponent) p;
68.10 + if (jp.isPaintingOrigin()) {
68.11 + Rectangle rectangle = SwingUtilities.convertRectangle(
68.12 + this, new Rectangle(x, y, width, height), jp);
68.13 + jp.repaint(tm,
68.14 + rectangle.x, rectangle.y, rectangle.width, rectangle.height);
68.15 + return;
68.16 + }
68.17 + }
68.18 RepaintManager.currentManager(this).addDirtyRegion(this, x, y, width, height);
68.19 }
68.20
69.1 --- a/src/share/classes/javax/swing/JDesktopPane.java Thu Oct 07 15:12:19 2010 -0700
69.2 +++ b/src/share/classes/javax/swing/JDesktopPane.java Tue Oct 12 12:51:48 2010 -0700
69.3 @@ -215,7 +215,8 @@
69.4
69.5 /**
69.6 * Sets the <code>DesktopManger</code> that will handle
69.7 - * desktop-specific UI actions.
69.8 + * desktop-specific UI actions. This may be overridden by
69.9 + * {@code LookAndFeel}.
69.10 *
69.11 * @param d the <code>DesktopManager</code> to use
69.12 *
70.1 --- a/src/share/classes/javax/swing/JLayer.java Thu Oct 07 15:12:19 2010 -0700
70.2 +++ b/src/share/classes/javax/swing/JLayer.java Tue Oct 12 12:51:48 2010 -0700
70.3 @@ -25,17 +25,17 @@
70.4
70.5 package javax.swing;
70.6
70.7 +import sun.awt.AWTAccessor;
70.8 +
70.9 import javax.swing.plaf.LayerUI;
70.10 +import javax.swing.border.Border;
70.11 import java.awt.*;
70.12 import java.awt.event.*;
70.13 import java.beans.PropertyChangeEvent;
70.14 import java.beans.PropertyChangeListener;
70.15 import java.io.IOException;
70.16 import java.io.ObjectInputStream;
70.17 -import java.io.Serializable;
70.18 -import java.lang.ref.WeakReference;
70.19 import java.util.ArrayList;
70.20 -import java.util.Iterator;
70.21 import java.security.AccessController;
70.22 import java.security.PrivilegedAction;
70.23
70.24 @@ -156,8 +156,6 @@
70.25 private LayerUI<? super V> layerUI;
70.26 private JPanel glassPane;
70.27 private boolean isPainting;
70.28 - private static final DefaultLayerLayout sharedLayoutInstance =
70.29 - new DefaultLayerLayout();
70.30 private long eventMask;
70.31
70.32 private static final LayerEventController eventController =
70.33 @@ -165,7 +163,7 @@
70.34
70.35 /**
70.36 * Creates a new {@code JLayer} object with a {@code null} view component
70.37 - * and {@code null} {@link javax.swing.plaf.LayerUI}.
70.38 + * and default {@link javax.swing.plaf.LayerUI}.
70.39 *
70.40 * @see #setView
70.41 * @see #setUI
70.42 @@ -176,14 +174,14 @@
70.43
70.44 /**
70.45 * Creates a new {@code JLayer} object
70.46 - * with {@code null} {@link javax.swing.plaf.LayerUI}.
70.47 + * with default {@link javax.swing.plaf.LayerUI}.
70.48 *
70.49 * @param view the component to be decorated by this {@code JLayer}
70.50 *
70.51 * @see #setUI
70.52 */
70.53 public JLayer(V view) {
70.54 - this(view, null);
70.55 + this(view, new LayerUI<V>());
70.56 }
70.57
70.58 /**
70.59 @@ -195,7 +193,6 @@
70.60 * to be used by this {@code JLayer}
70.61 */
70.62 public JLayer(V view, LayerUI<V> ui) {
70.63 - setLayout(sharedLayoutInstance);
70.64 setGlassPane(createGlassPane());
70.65 setView(view);
70.66 setUI(ui);
70.67 @@ -279,10 +276,15 @@
70.68 */
70.69 public void setGlassPane(JPanel glassPane) {
70.70 Component oldGlassPane = getGlassPane();
70.71 + boolean isGlassPaneVisible = false;
70.72 if (oldGlassPane != null) {
70.73 + isGlassPaneVisible = oldGlassPane.isVisible();
70.74 super.remove(oldGlassPane);
70.75 }
70.76 if (glassPane != null) {
70.77 + AWTAccessor.getComponentAccessor().setMixingCutoutShape(glassPane,
70.78 + new Rectangle());
70.79 + glassPane.setVisible(isGlassPaneVisible);
70.80 super.addImpl(glassPane, null, 0);
70.81 }
70.82 this.glassPane = glassPane;
70.83 @@ -303,6 +305,40 @@
70.84 }
70.85
70.86 /**
70.87 + * Sets the layout manager for this container. This method is
70.88 + * overridden to prevent the layout manager from being set.
70.89 + * <p/>Note: If {@code mgr} is non-{@code null}, this
70.90 + * method will throw an exception as layout managers are not supported on
70.91 + * a {@code JLayer}.
70.92 + *
70.93 + * @param mgr the specified layout manager
70.94 + * @exception IllegalArgumentException this method is not supported
70.95 + */
70.96 + public void setLayout(LayoutManager mgr) {
70.97 + if (mgr != null) {
70.98 + throw new IllegalArgumentException("JLayer.setLayout() not supported");
70.99 + }
70.100 + }
70.101 +
70.102 + /**
70.103 + * A non-{@code null] border, or non-zero insets, isn't supported, to prevent the geometry
70.104 + * of this component from becoming complex enough to inhibit
70.105 + * subclassing of {@code LayerUI} class. To create a {@code JLayer} with a border,
70.106 + * add it to a {@code JPanel} that has a border.
70.107 + * <p/>Note: If {@code border} is non-{@code null}, this
70.108 + * method will throw an exception as borders are not supported on
70.109 + * a {@code JLayer}.
70.110 + *
70.111 + * @param border the {@code Border} to set
70.112 + * @exception IllegalArgumentException this method is not supported
70.113 + */
70.114 + public void setBorder(Border border) {
70.115 + if (border != null) {
70.116 + throw new IllegalArgumentException("JLayer.setBorder() not supported");
70.117 + }
70.118 + }
70.119 +
70.120 + /**
70.121 * This method is not supported by {@code JLayer}
70.122 * and always throws {@code UnsupportedOperationException}
70.123 *
70.124 @@ -341,6 +377,32 @@
70.125 }
70.126
70.127 /**
70.128 + * Always returns {@code true} to cause painting to originate from {@code JLayer},
70.129 + * or one of its ancestors.
70.130 + *
70.131 + * @return true
70.132 + * @see JComponent#isPaintingOrigin()
70.133 + */
70.134 + boolean isPaintingOrigin() {
70.135 + return true;
70.136 + }
70.137 +
70.138 + /**
70.139 + * Delegates repainting to {@link javax.swing.plaf.LayerUI#repaint} method.
70.140 + *
70.141 + * @param tm this parameter is not used
70.142 + * @param x the x value of the dirty region
70.143 + * @param y the y value of the dirty region
70.144 + * @param width the width of the dirty region
70.145 + * @param height the height of the dirty region
70.146 + */
70.147 + public void repaint(long tm, int x, int y, int width, int height) {
70.148 + if (getUI() != null) {
70.149 + getUI().repaint(tm, x, y, width, height, this);
70.150 + }
70.151 + }
70.152 +
70.153 + /**
70.154 * Delegates all painting to the {@link javax.swing.plaf.LayerUI} object.
70.155 *
70.156 * @param g the {@code Graphics} to render to
70.157 @@ -364,14 +426,18 @@
70.158 }
70.159
70.160 /**
70.161 - * To enable the correct painting of the {@code glassPane} and view component,
70.162 - * the {@code JLayer} overrides the default implementation of
70.163 - * this method to return {@code false} when the {@code glassPane} is visible.
70.164 + * The {@code JLayer} overrides the default implementation of
70.165 + * this method (in {@code JComponent}) to return {@code false}.
70.166 + * This ensures
70.167 + * that the drawing machinery will call the {@code JLayer}'s
70.168 + * {@code paint}
70.169 + * implementation rather than messaging the {@code JLayer}'s
70.170 + * children directly.
70.171 *
70.172 - * @return false if {@code JLayer}'s {@code glassPane} is visible
70.173 + * @return false
70.174 */
70.175 public boolean isOptimizedDrawingEnabled() {
70.176 - return glassPane == null || !glassPane.isVisible();
70.177 + return false;
70.178 }
70.179
70.180 /**
70.181 @@ -461,17 +527,16 @@
70.182 /**
70.183 * Returns the preferred size of the viewport for a view component.
70.184 * <p/>
70.185 - * If the ui delegate of this layer is not {@code null}, this method delegates its
70.186 - * implementation to the {@code LayerUI.getPreferredScrollableViewportSize(JLayer)}
70.187 + * If the view component of this layer implements {@link Scrollable}, this method delegates its
70.188 + * implementation to the view component.
70.189 *
70.190 * @return the preferred size of the viewport for a view component
70.191 *
70.192 * @see Scrollable
70.193 - * @see LayerUI#getPreferredScrollableViewportSize(JLayer)
70.194 */
70.195 public Dimension getPreferredScrollableViewportSize() {
70.196 - if (getUI() != null) {
70.197 - return getUI().getPreferredScrollableViewportSize(this);
70.198 + if (getView() instanceof Scrollable) {
70.199 + return ((Scrollable)getView()).getPreferredScrollableViewportSize();
70.200 }
70.201 return getPreferredSize();
70.202 }
70.203 @@ -481,18 +546,17 @@
70.204 * that display logical rows or columns in order to completely expose
70.205 * one block of rows or columns, depending on the value of orientation.
70.206 * <p/>
70.207 - * If the ui delegate of this layer is not {@code null}, this method delegates its
70.208 - * implementation to the {@code LayerUI.getScrollableBlockIncrement(JLayer,Rectangle,int,int)}
70.209 + * If the view component of this layer implements {@link Scrollable}, this method delegates its
70.210 + * implementation to the view component.
70.211 *
70.212 * @return the "block" increment for scrolling in the specified direction
70.213 *
70.214 * @see Scrollable
70.215 - * @see LayerUI#getScrollableBlockIncrement(JLayer, Rectangle, int, int)
70.216 */
70.217 public int getScrollableBlockIncrement(Rectangle visibleRect,
70.218 int orientation, int direction) {
70.219 - if (getUI() != null) {
70.220 - return getUI().getScrollableBlockIncrement(this, visibleRect,
70.221 + if (getView() instanceof Scrollable) {
70.222 + return ((Scrollable)getView()).getScrollableBlockIncrement(visibleRect,
70.223 orientation, direction);
70.224 }
70.225 return (orientation == SwingConstants.VERTICAL) ? visibleRect.height :
70.226 @@ -504,17 +568,16 @@
70.227 * determine the height of the layer, unless the preferred height
70.228 * of the layer is smaller than the height of the viewport.
70.229 * <p/>
70.230 - * If the ui delegate of this layer is not null, this method delegates its
70.231 - * implementation to the {@code LayerUI.getScrollableTracksViewportHeight(JLayer)}
70.232 + * If the view component of this layer implements {@link Scrollable}, this method delegates its
70.233 + * implementation to the view component.
70.234 *
70.235 * @return whether the layer should track the height of the viewport
70.236 *
70.237 * @see Scrollable
70.238 - * @see LayerUI#getScrollableTracksViewportHeight(JLayer)
70.239 */
70.240 public boolean getScrollableTracksViewportHeight() {
70.241 - if (getUI() != null) {
70.242 - return getUI().getScrollableTracksViewportHeight(this);
70.243 + if (getView() instanceof Scrollable) {
70.244 + return ((Scrollable)getView()).getScrollableTracksViewportHeight();
70.245 }
70.246 return false;
70.247 }
70.248 @@ -524,17 +587,16 @@
70.249 * determine the width of the layer, unless the preferred width
70.250 * of the layer is smaller than the width of the viewport.
70.251 * <p/>
70.252 - * If the ui delegate of this layer is not null, this method delegates its
70.253 - * implementation to the {@code LayerUI.getScrollableTracksViewportWidth(JLayer)}
70.254 + * If the view component of this layer implements {@link Scrollable}, this method delegates its
70.255 + * implementation to the view component.
70.256 *
70.257 * @return whether the layer should track the width of the viewport
70.258 *
70.259 * @see Scrollable
70.260 - * @see LayerUI#getScrollableTracksViewportWidth(JLayer)
70.261 */
70.262 public boolean getScrollableTracksViewportWidth() {
70.263 - if (getUI() != null) {
70.264 - return getUI().getScrollableTracksViewportWidth(this);
70.265 + if (getView() instanceof Scrollable) {
70.266 + return ((Scrollable)getView()).getScrollableTracksViewportWidth();
70.267 }
70.268 return false;
70.269 }
70.270 @@ -549,20 +611,19 @@
70.271 * Scrolling containers, like {@code JScrollPane}, will use this method
70.272 * each time the user requests a unit scroll.
70.273 * <p/>
70.274 - * If the ui delegate of this layer is not {@code null}, this method delegates its
70.275 - * implementation to the {@code LayerUI.getScrollableUnitIncrement(JLayer,Rectangle,int,int)}
70.276 + * If the view component of this layer implements {@link Scrollable}, this method delegates its
70.277 + * implementation to the view component.
70.278 *
70.279 * @return The "unit" increment for scrolling in the specified direction.
70.280 * This value should always be positive.
70.281 *
70.282 * @see Scrollable
70.283 - * @see LayerUI#getScrollableUnitIncrement(JLayer, Rectangle, int, int)
70.284 */
70.285 public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation,
70.286 int direction) {
70.287 - if (getUI() != null) {
70.288 - return getUI().getScrollableUnitIncrement(
70.289 - this, visibleRect, orientation, direction);
70.290 + if (getView() instanceof Scrollable) {
70.291 + return ((Scrollable) getView()).getScrollableUnitIncrement(
70.292 + visibleRect, orientation, direction);
70.293 }
70.294 return 1;
70.295 }
70.296 @@ -595,6 +656,16 @@
70.297 }
70.298
70.299 /**
70.300 + * Delegates its functionality to the {@link javax.swing.plaf.LayerUI#doLayout(JLayer)} method,
70.301 + * if {@code LayerUI} is set.
70.302 + */
70.303 + public void doLayout() {
70.304 + if (getUI() != null) {
70.305 + getUI().doLayout(this);
70.306 + }
70.307 + }
70.308 +
70.309 + /**
70.310 * static AWTEventListener to be shared with all AbstractLayerUIs
70.311 */
70.312 private static class LayerEventController implements AWTEventListener {
70.313 @@ -625,8 +696,8 @@
70.314 JLayer l = (JLayer) component;
70.315 LayerUI ui = l.getUI();
70.316 if (ui != null &&
70.317 - isEventEnabled(l.getLayerEventMask(),
70.318 - event.getID())) {
70.319 + isEventEnabled(l.getLayerEventMask(), event.getID()) &&
70.320 + (!(event instanceof InputEvent) || !((InputEvent)event).isConsumed())) {
70.321 ui.eventDispatched(event, l);
70.322 }
70.323 }
70.324 @@ -758,82 +829,4 @@
70.325 return super.contains(x, y);
70.326 }
70.327 }
70.328 -
70.329 - /**
70.330 - * The default layout manager for the {@link javax.swing.JLayer}.<br/>
70.331 - * It places the glassPane on top of the view component
70.332 - * and makes it the same size as {@code JLayer},
70.333 - * it also makes the view component the same size but minus layer's insets<br/>
70.334 - */
70.335 - private static class DefaultLayerLayout implements LayoutManager, Serializable {
70.336 - /**
70.337 - * {@inheritDoc}
70.338 - */
70.339 - public void layoutContainer(Container parent) {
70.340 - JLayer layer = (JLayer) parent;
70.341 - Component view = layer.getView();
70.342 - Component glassPane = layer.getGlassPane();
70.343 - if (view != null) {
70.344 - Insets insets = layer.getInsets();
70.345 - view.setLocation(insets.left, insets.top);
70.346 - view.setSize(layer.getWidth() - insets.left - insets.right,
70.347 - layer.getHeight() - insets.top - insets.bottom);
70.348 - }
70.349 - if (glassPane != null) {
70.350 - glassPane.setLocation(0, 0);
70.351 - glassPane.setSize(layer.getWidth(), layer.getHeight());
70.352 - }
70.353 - }
70.354 -
70.355 - /**
70.356 - * {@inheritDoc}
70.357 - */
70.358 - public Dimension minimumLayoutSize(Container parent) {
70.359 - JLayer layer = (JLayer) parent;
70.360 - Insets insets = layer.getInsets();
70.361 - Dimension ret = new Dimension(insets.left + insets.right,
70.362 - insets.top + insets.bottom);
70.363 - Component view = layer.getView();
70.364 - if (view != null) {
70.365 - Dimension size = view.getMinimumSize();
70.366 - ret.width += size.width;
70.367 - ret.height += size.height;
70.368 - }
70.369 - if (ret.width == 0 || ret.height == 0) {
70.370 - ret.width = ret.height = 4;
70.371 - }
70.372 - return ret;
70.373 - }
70.374 -
70.375 - /**
70.376 - * {@inheritDoc}
70.377 - */
70.378 - public Dimension preferredLayoutSize(Container parent) {
70.379 - JLayer layer = (JLayer) parent;
70.380 - Insets insets = layer.getInsets();
70.381 - Dimension ret = new Dimension(insets.left + insets.right,
70.382 - insets.top + insets.bottom);
70.383 - Component view = layer.getView();
70.384 - if (view != null) {
70.385 - Dimension size = view.getPreferredSize();
70.386 - if (size.width > 0 && size.height > 0) {
70.387 - ret.width += size.width;
70.388 - ret.height += size.height;
70.389 - }
70.390 - }
70.391 - return ret;
70.392 - }
70.393 -
70.394 - /**
70.395 - * {@inheritDoc}
70.396 - */
70.397 - public void addLayoutComponent(String name, Component comp) {
70.398 - }
70.399 -
70.400 - /**
70.401 - * {@inheritDoc}
70.402 - */
70.403 - public void removeLayoutComponent(Component comp) {
70.404 - }
70.405 - }
70.406 }
71.1 --- a/src/share/classes/javax/swing/JTable.java Thu Oct 07 15:12:19 2010 -0700
71.2 +++ b/src/share/classes/javax/swing/JTable.java Tue Oct 12 12:51:48 2010 -0700
71.3 @@ -4574,9 +4574,8 @@
71.4 * @see TableColumnModelListener
71.5 */
71.6 public void columnMoved(TableColumnModelEvent e) {
71.7 - // If I'm currently editing, then I should stop editing
71.8 - if (isEditing()) {
71.9 - removeEditor();
71.10 + if (isEditing() && !getCellEditor().stopCellEditing()) {
71.11 + getCellEditor().cancelCellEditing();
71.12 }
71.13 repaint();
71.14 }
71.15 @@ -4593,8 +4592,8 @@
71.16 * @see TableColumnModelListener
71.17 */
71.18 public void columnMarginChanged(ChangeEvent e) {
71.19 - if (isEditing()) {
71.20 - removeEditor();
71.21 + if (isEditing() && !getCellEditor().stopCellEditing()) {
71.22 + getCellEditor().cancelCellEditing();
71.23 }
71.24 TableColumn resizingColumn = getResizingColumn();
71.25 // Need to do this here, before the parent's
72.1 --- a/src/share/classes/javax/swing/ToolTipManager.java Thu Oct 07 15:12:19 2010 -0700
72.2 +++ b/src/share/classes/javax/swing/ToolTipManager.java Tue Oct 12 12:51:48 2010 -0700
72.3 @@ -459,7 +459,7 @@
72.4 if (insideComponent == null) {
72.5 // Drag exit
72.6 }
72.7 - if (window != null && event.getSource() == window) {
72.8 + if (window != null && event.getSource() == window && insideComponent != null) {
72.9 // if we get an exit and have a heavy window
72.10 // we need to check if it if overlapping the inside component
72.11 Container insideComponentWindow = insideComponent.getTopLevelAncestor();
73.1 --- a/src/share/classes/javax/swing/plaf/LayerUI.java Thu Oct 07 15:12:19 2010 -0700
73.2 +++ b/src/share/classes/javax/swing/plaf/LayerUI.java Tue Oct 12 12:51:48 2010 -0700
73.3 @@ -600,104 +600,6 @@
73.4 }
73.5
73.6 /**
73.7 - * Returns the preferred size of the viewport for a view component.
73.8 - *
73.9 - * @param l the {@code JLayer} component where this UI delegate is being installed
73.10 - * @return the preferred size of the viewport for a view component
73.11 - * @see Scrollable#getPreferredScrollableViewportSize()
73.12 - */
73.13 - public Dimension getPreferredScrollableViewportSize(JLayer<? extends V> l) {
73.14 - if (l.getView() instanceof Scrollable) {
73.15 - return ((Scrollable)l.getView()).getPreferredScrollableViewportSize();
73.16 - }
73.17 - return l.getPreferredSize();
73.18 - }
73.19 -
73.20 - /**
73.21 - * Returns a scroll increment, which is required for components
73.22 - * that display logical rows or columns in order to completely expose
73.23 - * one block of rows or columns, depending on the value of orientation.
73.24 - *
73.25 - * @param l the {@code JLayer} component where this UI delegate is being installed
73.26 - * @param visibleRect The view area visible within the viewport
73.27 - * @param orientation Either SwingConstants.VERTICAL or SwingConstants.HORIZONTAL.
73.28 - * @param direction Less than zero to scroll up/left, greater than zero for down/right.
73.29 - * @return the "block" increment for scrolling in the specified direction
73.30 - * @see Scrollable#getScrollableBlockIncrement(Rectangle, int, int)
73.31 - */
73.32 - public int getScrollableBlockIncrement(JLayer<? extends V> l,
73.33 - Rectangle visibleRect,
73.34 - int orientation, int direction) {
73.35 - if (l.getView() instanceof Scrollable) {
73.36 - return ((Scrollable)l.getView()).getScrollableBlockIncrement(
73.37 - visibleRect,orientation, direction);
73.38 - }
73.39 - return (orientation == SwingConstants.VERTICAL) ? visibleRect.height :
73.40 - visibleRect.width;
73.41 - }
73.42 -
73.43 - /**
73.44 - * Returns {@code false} to indicate that the height of the viewport does not
73.45 - * determine the height of the layer, unless the preferred height
73.46 - * of the layer is smaller than the height of the viewport.
73.47 - *
73.48 - * @param l the {@code JLayer} component where this UI delegate is being installed
73.49 - * @return whether the layer should track the height of the viewport
73.50 - * @see Scrollable#getScrollableTracksViewportHeight()
73.51 - */
73.52 - public boolean getScrollableTracksViewportHeight(JLayer<? extends V> l) {
73.53 - if (l.getView() instanceof Scrollable) {
73.54 - return ((Scrollable)l.getView()).getScrollableTracksViewportHeight();
73.55 - }
73.56 - return false;
73.57 - }
73.58 -
73.59 - /**
73.60 - * Returns {@code false} to indicate that the width of the viewport does not
73.61 - * determine the width of the layer, unless the preferred width
73.62 - * of the layer is smaller than the width of the viewport.
73.63 - *
73.64 - * @param l the {@code JLayer} component where this UI delegate is being installed
73.65 - * @return whether the layer should track the width of the viewport
73.66 - * @see Scrollable
73.67 - * @see LayerUI#getScrollableTracksViewportWidth(JLayer)
73.68 - */
73.69 - public boolean getScrollableTracksViewportWidth(JLayer<? extends V> l) {
73.70 - if (l.getView() instanceof Scrollable) {
73.71 - return ((Scrollable)l.getView()).getScrollableTracksViewportWidth();
73.72 - }
73.73 - return false;
73.74 - }
73.75 -
73.76 - /**
73.77 - * Returns a scroll increment, which is required for components
73.78 - * that display logical rows or columns in order to completely expose
73.79 - * one new row or column, depending on the value of orientation.
73.80 - * Ideally, components should handle a partially exposed row or column
73.81 - * by returning the distance required to completely expose the item.
73.82 - * <p>
73.83 - * Scrolling containers, like JScrollPane, will use this method
73.84 - * each time the user requests a unit scroll.
73.85 - *
73.86 - * @param l the {@code JLayer} component where this UI delegate is being installed
73.87 - * @param visibleRect The view area visible within the viewport
73.88 - * @param orientation Either SwingConstants.VERTICAL or SwingConstants.HORIZONTAL.
73.89 - * @param direction Less than zero to scroll up/left, greater than zero for down/right.
73.90 - * @return The "unit" increment for scrolling in the specified direction.
73.91 - * This value should always be positive.
73.92 - * @see Scrollable#getScrollableUnitIncrement(Rectangle, int, int)
73.93 - */
73.94 - public int getScrollableUnitIncrement(JLayer<? extends V> l,
73.95 - Rectangle visibleRect,
73.96 - int orientation, int direction) {
73.97 - if (l.getView() instanceof Scrollable) {
73.98 - return ((Scrollable)l.getView()).getScrollableUnitIncrement(
73.99 - visibleRect, orientation, direction);
73.100 - }
73.101 - return 1;
73.102 - }
73.103 -
73.104 - /**
73.105 * If the {@code JLayer}'s view component is not {@code null},
73.106 * this calls the view's {@code getBaseline()} method.
73.107 * Otherwise, the default implementation is called.
73.108 @@ -718,7 +620,7 @@
73.109
73.110 /**
73.111 * If the {@code JLayer}'s view component is not {@code null},
73.112 - * this calls the view's {@code getBaselineResizeBehavior()} method.
73.113 + * this returns the result of the view's {@code getBaselineResizeBehavior()} method.
73.114 * Otherwise, the default implementation is called.
73.115 *
73.116 * @param c {@code JLayer} to return baseline resize behavior for
73.117 @@ -732,4 +634,90 @@
73.118 }
73.119 return super.getBaselineResizeBehavior(c);
73.120 }
73.121 +
73.122 + /**
73.123 + * Causes the passed instance of {@code JLayer} to lay out its components.
73.124 + *
73.125 + * @param l the {@code JLayer} component where this UI delegate is being installed
73.126 + */
73.127 + public void doLayout(JLayer<? extends V> l) {
73.128 + Component view = l.getView();
73.129 + if (view != null) {
73.130 + view.setBounds(0, 0, l.getWidth(), l.getHeight());
73.131 + }
73.132 + Component glassPane = l.getGlassPane();
73.133 + if (glassPane != null) {
73.134 + glassPane.setBounds(0, 0, l.getWidth(), l.getHeight());
73.135 + }
73.136 + }
73.137 +
73.138 + /**
73.139 + * If the {@code JLayer}'s view component is not {@code null},
73.140 + * this returns the result of the view's {@code getPreferredSize()} method.
73.141 + * Otherwise, the default implementation is used.
73.142 + *
73.143 + * @param c {@code JLayer} to return preferred size for
73.144 + * @return preferred size for the passed {@code JLayer}
73.145 + */
73.146 + public Dimension getPreferredSize(JComponent c) {
73.147 + JLayer l = (JLayer) c;
73.148 + Component view = l.getView();
73.149 + if (view != null) {
73.150 + return view.getPreferredSize();
73.151 + }
73.152 + return super.getPreferredSize(c);
73.153 + }
73.154 +
73.155 + /**
73.156 + * If the {@code JLayer}'s view component is not {@code null},
73.157 + * this returns the result of the view's {@code getMinimalSize()} method.
73.158 + * Otherwise, the default implementation is used.
73.159 + *
73.160 + * @param c {@code JLayer} to return preferred size for
73.161 + * @return minimal size for the passed {@code JLayer}
73.162 + */
73.163 + public Dimension getMinimumSize(JComponent c) {
73.164 + JLayer l = (JLayer) c;
73.165 + Component view = l.getView();
73.166 + if (view != null) {
73.167 + return view.getMinimumSize();
73.168 + }
73.169 + return super.getMinimumSize(c);
73.170 + }
73.171 +
73.172 + /**
73.173 + * If the {@code JLayer}'s view component is not {@code null},
73.174 + * this returns the result of the view's {@code getMaximumSize()} method.
73.175 + * Otherwise, the default implementation is used.
73.176 + *
73.177 + * @param c {@code JLayer} to return preferred size for
73.178 + * @return maximun size for the passed {@code JLayer}
73.179 + */
73.180 + public Dimension getMaximumSize(JComponent c) {
73.181 + JLayer l = (JLayer) c;
73.182 + Component view = l.getView();
73.183 + if (view != null) {
73.184 + return view.getMaximumSize();
73.185 + }
73.186 + return super.getMaximumSize(c);
73.187 + }
73.188 +
73.189 + /**
73.190 + * Adds the specified region to the dirty region list if the component
73.191 + * is showing. The component will be repainted after all of the
73.192 + * currently pending events have been dispatched.
73.193 + * <p/>
73.194 + * This method is to be overridden when the dirty region needs to be changed.
73.195 + *
73.196 + * @param tm this parameter is not used
73.197 + * @param x the x value of the dirty region
73.198 + * @param y the y value of the dirty region
73.199 + * @param width the width of the dirty region
73.200 + * @param height the height of the dirty region
73.201 + * @see java.awt.Component#isShowing
73.202 + * @see RepaintManager#addDirtyRegion
73.203 + */
73.204 + public void repaint(long tm, int x, int y, int width, int height, JLayer<? extends V> l) {
73.205 + RepaintManager.currentManager(l).addDirtyRegion(l, x, y, width, height);
73.206 + }
73.207 }
74.1 --- a/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java Thu Oct 07 15:12:19 2010 -0700
74.2 +++ b/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java Tue Oct 12 12:51:48 2010 -0700
74.3 @@ -1603,6 +1603,7 @@
74.4 BoundedRangeModel newModel = (BoundedRangeModel)e.getNewValue();
74.5 oldModel.removeChangeListener(modelListener);
74.6 newModel.addChangeListener(modelListener);
74.7 + scrollBarValue = scrollbar.getValue();
74.8 scrollbar.repaint();
74.9 scrollbar.revalidate();
74.10 } else if ("orientation" == propertyName) {
75.1 --- a/src/share/classes/javax/swing/plaf/metal/MetalComboBoxUI.java Thu Oct 07 15:12:19 2010 -0700
75.2 +++ b/src/share/classes/javax/swing/plaf/metal/MetalComboBoxUI.java Tue Oct 12 12:51:48 2010 -0700
75.3 @@ -144,7 +144,7 @@
75.4 */
75.5 public int getBaseline(JComponent c, int width, int height) {
75.6 int baseline;
75.7 - if (MetalLookAndFeel.usingOcean()) {
75.8 + if (MetalLookAndFeel.usingOcean() && height >= 4) {
75.9 height -= 4;
75.10 baseline = super.getBaseline(c, width, height);
75.11 if (baseline >= 0) {
76.1 --- a/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java Thu Oct 07 15:12:19 2010 -0700
76.2 +++ b/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java Tue Oct 12 12:51:48 2010 -0700
76.3 @@ -115,6 +115,9 @@
76.4 return new SynthTabbedPaneUI();
76.5 }
76.6
76.7 + private SynthTabbedPaneUI() {
76.8 + }
76.9 +
76.10 private boolean scrollableTabLayoutEnabled() {
76.11 return (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT);
76.12 }
77.1 --- a/src/share/classes/sun/awt/AWTAccessor.java Thu Oct 07 15:12:19 2010 -0700
77.2 +++ b/src/share/classes/sun/awt/AWTAccessor.java Tue Oct 12 12:51:48 2010 -0700
77.3 @@ -344,6 +344,11 @@
77.4 * Removes the last focus request for the heavyweight from the queue.
77.5 */
77.6 void removeLastFocusRequest(Component heavyweight);
77.7 +
77.8 + /*
77.9 + * Sets the most recent focus owner in the window.
77.10 + */
77.11 + void setMostRecentFocusOwner(Window window, Component component);
77.12 }
77.13
77.14 /*
78.1 --- a/src/share/classes/sun/awt/EmbeddedFrame.java Thu Oct 07 15:12:19 2010 -0700
78.2 +++ b/src/share/classes/sun/awt/EmbeddedFrame.java Tue Oct 12 12:51:48 2010 -0700
78.3 @@ -70,7 +70,10 @@
78.4 // JDK 1.1 compatibility
78.5 private static final long serialVersionUID = 2967042741780317130L;
78.6
78.7 - // Use these in traverseOut method to determine directions
78.8 + /*
78.9 + * The constants define focus traversal directions.
78.10 + * Use them in {@code traverseIn}, {@code traverseOut} methods.
78.11 + */
78.12 protected static final boolean FORWARD = true;
78.13 protected static final boolean BACKWARD = false;
78.14
78.15 @@ -284,6 +287,41 @@
78.16 }
78.17
78.18 /**
78.19 + * This method is called by the embedder when we should receive focus as element
78.20 + * of the traversal chain. The method requests focus on:
78.21 + * 1. the first Component of this EmbeddedFrame if user moves focus forward
78.22 + * in the focus traversal cycle.
78.23 + * 2. the last Component of this EmbeddedFrame if user moves focus backward
78.24 + * in the focus traversal cycle.
78.25 + *
78.26 + * The direction parameter specifies which of the two mentioned cases is
78.27 + * happening. Use FORWARD and BACKWARD constants defined in the EmbeddedFrame class
78.28 + * to avoid confusing boolean values.
78.29 + *
78.30 + * A concrete implementation of this method is defined in the platform-dependent
78.31 + * subclasses.
78.32 + *
78.33 + * @param direction FORWARD or BACKWARD
78.34 + * @return true, if the EmbeddedFrame wants to get focus, false otherwise.
78.35 + */
78.36 + public boolean traverseIn(boolean direction) {
78.37 + Component comp = null;
78.38 +
78.39 + if (direction == FORWARD) {
78.40 + comp = getFocusTraversalPolicy().getFirstComponent(this);
78.41 + } else {
78.42 + comp = getFocusTraversalPolicy().getLastComponent(this);
78.43 + }
78.44 + if (comp != null) {
78.45 + // comp.requestFocus(); - Leads to a hung.
78.46 +
78.47 + AWTAccessor.getKeyboardFocusManagerAccessor().setMostRecentFocusOwner(this, comp);
78.48 + synthesizeWindowActivation(true);
78.49 + }
78.50 + return (null != comp);
78.51 + }
78.52 +
78.53 + /**
78.54 * This method is called from dispatchKeyEvent in the following two cases:
78.55 * 1. The focus is on the first Component of this EmbeddedFrame and we are
78.56 * about to transfer the focus backward.
79.1 --- a/src/share/classes/sun/net/www/http/HttpClient.java Thu Oct 07 15:12:19 2010 -0700
79.2 +++ b/src/share/classes/sun/net/www/http/HttpClient.java Tue Oct 12 12:51:48 2010 -0700
79.3 @@ -55,6 +55,9 @@
79.4 // Http data we send with the headers
79.5 PosterOutputStream poster = null;
79.6
79.7 + // true if we are in streaming mode (fixed length or chunked)
79.8 + boolean streaming;
79.9 +
79.10 // if we've had one io error
79.11 boolean failedOnce = false;
79.12
79.13 @@ -275,6 +278,10 @@
79.14 ret.cachedHttpClient = true;
79.15 assert ret.inCache;
79.16 ret.inCache = false;
79.17 + PlatformLogger logger = HttpURLConnection.getHttpLogger();
79.18 + if (logger.isLoggable(PlatformLogger.FINEST)) {
79.19 + logger.finest("KeepAlive stream retrieved from the cache, " + ret);
79.20 + }
79.21 }
79.22 } else {
79.23 // We cannot return this connection to the cache as it's
79.24 @@ -545,6 +552,13 @@
79.25 serverOutput.flush();
79.26 }
79.27
79.28 + public void writeRequests(MessageHeader head,
79.29 + PosterOutputStream pos,
79.30 + boolean streaming) throws IOException {
79.31 + this.streaming = streaming;
79.32 + writeRequests(head, pos);
79.33 + }
79.34 +
79.35 /** Parse the first line of the HTTP request. It usually looks
79.36 something like: "HTTP/1.0 <number> comment\r\n". */
79.37
79.38 @@ -577,11 +591,11 @@
79.39 closeServer();
79.40 cachedHttpClient = false;
79.41 if (!failedOnce && requests != null) {
79.42 - if (httpuc.getRequestMethod().equals("POST") && !retryPostProp) {
79.43 + failedOnce = true;
79.44 + if (httpuc.getRequestMethod().equals("POST") && (!retryPostProp || streaming)) {
79.45 // do not retry the request
79.46 } else {
79.47 // try once more
79.48 - failedOnce = true;
79.49 openServer();
79.50 if (needsTunneling()) {
79.51 httpuc.doTunneling();
79.52 @@ -684,10 +698,10 @@
79.53 }
79.54 } else if (nread != 8) {
79.55 if (!failedOnce && requests != null) {
79.56 - if (httpuc.getRequestMethod().equals("POST") && !retryPostProp) {
79.57 + failedOnce = true;
79.58 + if (httpuc.getRequestMethod().equals("POST") && (!retryPostProp || streaming)) {
79.59 // do not retry the request
79.60 } else {
79.61 - failedOnce = true;
79.62 closeServer();
79.63 cachedHttpClient = false;
79.64 openServer();
80.1 --- a/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Thu Oct 07 15:12:19 2010 -0700
80.2 +++ b/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Tue Oct 12 12:51:48 2010 -0700
80.3 @@ -494,7 +494,7 @@
80.4 if (logger.isLoggable(PlatformLogger.FINE)) {
80.5 logger.fine(requests.toString());
80.6 }
80.7 - http.writeRequests(requests, poster);
80.8 + http.writeRequests(requests, poster, streaming());
80.9 if (ps.checkError()) {
80.10 String proxyHost = http.getProxyHostUsed();
80.11 int proxyPort = http.getProxyPortUsed();
80.12 @@ -2825,6 +2825,38 @@
80.13 }
80.14 }
80.15
80.16 + /* skip() calls read() in order to ensure that entire response gets
80.17 + * cached. same implementation as InputStream.skip */
80.18 +
80.19 + private byte[] skipBuffer;
80.20 + private static final int SKIP_BUFFER_SIZE = 8096;
80.21 +
80.22 + @Override
80.23 + public long skip (long n) throws IOException {
80.24 +
80.25 + long remaining = n;
80.26 + int nr;
80.27 + if (skipBuffer == null)
80.28 + skipBuffer = new byte[SKIP_BUFFER_SIZE];
80.29 +
80.30 + byte[] localSkipBuffer = skipBuffer;
80.31 +
80.32 + if (n <= 0) {
80.33 + return 0;
80.34 + }
80.35 +
80.36 + while (remaining > 0) {
80.37 + nr = read(localSkipBuffer, 0,
80.38 + (int) Math.min(SKIP_BUFFER_SIZE, remaining));
80.39 + if (nr < 0) {
80.40 + break;
80.41 + }
80.42 + remaining -= nr;
80.43 + }
80.44 +
80.45 + return n - remaining;
80.46 + }
80.47 +
80.48 @Override
80.49 public void close () throws IOException {
80.50 try {
81.1 --- a/src/share/classes/sun/security/tools/KeyTool.java Thu Oct 07 15:12:19 2010 -0700
81.2 +++ b/src/share/classes/sun/security/tools/KeyTool.java Tue Oct 12 12:51:48 2010 -0700
81.3 @@ -281,7 +281,7 @@
81.4 RFC("rfc", null, "output in RFC style"),
81.5 SIGALG("sigalg", "<sigalg>", "signature algorithm name"),
81.6 SRCALIAS("srcalias", "<srcalias>", "source alias"),
81.7 - SRCKEYPASS("srckeypass", "<arg>", "source keystore password"),
81.8 + SRCKEYPASS("srckeypass", "<arg>", "source key password"),
81.9 SRCKEYSTORE("srckeystore", "<srckeystore>", "source keystore name"),
81.10 SRCPROTECTED("srcprotected", null, "source keystore password protected"),
81.11 SRCPROVIDERNAME("srcprovidername", "<srcprovidername>", "source keystore provider name"),
82.1 --- a/src/share/classes/sun/security/util/Resources.java Thu Oct 07 15:12:19 2010 -0700
82.2 +++ b/src/share/classes/sun/security/util/Resources.java Tue Oct 12 12:51:48 2010 -0700
82.3 @@ -116,11 +116,9 @@
82.4 {"X.509 extension",
82.5 "X.509 extension"}, //-ext
82.6 {"output file name",
82.7 - "output file name"}, //-file
82.8 + "output file name"}, //-file and -outfile
82.9 {"input file name",
82.10 - "input file name"}, //-file
82.11 - {"input file name",
82.12 - "input file name"}, //-infile
82.13 + "input file name"}, //-file and -infile
82.14 {"key algorithm name",
82.15 "key algorithm name"}, //-keyalg
82.16 {"key password",
82.17 @@ -133,8 +131,6 @@
82.18 "new password"}, //-new
82.19 {"do not prompt",
82.20 "do not prompt"}, //-noprompt
82.21 - {"output file name",
82.22 - "output file name"}, //-outfile
82.23 {"password through protected mechanism",
82.24 "password through protected mechanism"}, //-protected
82.25 {"provider argument",
82.26 @@ -151,8 +147,8 @@
82.27 "signature algorithm name"}, //-sigalg
82.28 {"source alias",
82.29 "source alias"}, //-srcalias
82.30 - {"source keystore password",
82.31 - "source keystore password"}, //-srckeypass
82.32 + {"source key password",
82.33 + "source key password"}, //-srckeypass
82.34 {"source keystore name",
82.35 "source keystore name"}, //-srckeystore
82.36 {"source keystore password protected",
82.37 @@ -276,8 +272,6 @@
82.38 "Alias <{0}> has no certificate"},
82.39 {"Key pair not generated, alias <alias> already exists",
82.40 "Key pair not generated, alias <{0}> already exists"},
82.41 - {"Cannot derive signature algorithm",
82.42 - "Cannot derive signature algorithm"},
82.43 {"Generating keysize bit keyAlgName key pair and self-signed certificate (sigAlgName) with a validity of validality days\n\tfor: x500Name",
82.44 "Generating {0} bit {1} key pair and self-signed certificate ({2}) with a validity of {3} days\n\tfor: {4}"},
82.45 {"Enter key password for <alias>", "Enter key password for <{0}>"},
82.46 @@ -321,8 +315,6 @@
82.47 {"Failed to parse input", "Failed to parse input"},
82.48 {"Empty input", "Empty input"},
82.49 {"Not X.509 certificate", "Not X.509 certificate"},
82.50 - {"Cannot derive signature algorithm",
82.51 - "Cannot derive signature algorithm"},
82.52 {"alias has no public key", "{0} has no public key"},
82.53 {"alias has no X.509 certificate", "{0} has no X.509 certificate"},
82.54 {"New certificate (self-signed):", "New certificate (self-signed):"},
82.55 @@ -552,7 +544,6 @@
82.56 {"package name", "package name"},
82.57 {"policy type", "policy type"},
82.58 {"property name", "property name"},
82.59 - {"provider name", "provider name"},
82.60 {"Principal List", "Principal List"},
82.61 {"Permission List", "Permission List"},
82.62 {"Code Base", "Code Base"},
83.1 --- a/src/share/classes/sun/util/locale/BaseLocale.java Thu Oct 07 15:12:19 2010 -0700
83.2 +++ b/src/share/classes/sun/util/locale/BaseLocale.java Tue Oct 12 12:51:48 2010 -0700
83.3 @@ -64,12 +64,14 @@
83.4
83.5 public static BaseLocale getInstance(String language, String script, String region, String variant) {
83.6 // JDK uses deprecated ISO639.1 language codes for he, yi and id
83.7 - if (AsciiUtil.caseIgnoreMatch(language, "he")) {
83.8 - language = "iw";
83.9 - } else if (AsciiUtil.caseIgnoreMatch(language, "yi")) {
83.10 - language = "ji";
83.11 - } else if (AsciiUtil.caseIgnoreMatch(language, "id")) {
83.12 - language = "in";
83.13 + if (language != null) {
83.14 + if (AsciiUtil.caseIgnoreMatch(language, "he")) {
83.15 + language = "iw";
83.16 + } else if (AsciiUtil.caseIgnoreMatch(language, "yi")) {
83.17 + language = "ji";
83.18 + } else if (AsciiUtil.caseIgnoreMatch(language, "id")) {
83.19 + language = "in";
83.20 + }
83.21 }
83.22
83.23 Key key = new Key(language, script, region, variant);
84.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
84.2 +++ b/src/share/demo/nio/zipfs/Demo.java Tue Oct 12 12:51:48 2010 -0700
84.3 @@ -0,0 +1,664 @@
84.4 +/*
84.5 + * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
84.6 + *
84.7 + * Redistribution and use in source and binary forms, with or without
84.8 + * modification, are permitted provided that the following conditions
84.9 + * are met:
84.10 + *
84.11 + * - Redistributions of source code must retain the above copyright
84.12 + * notice, this list of conditions and the following disclaimer.
84.13 + *
84.14 + * - Redistributions in binary form must reproduce the above copyright
84.15 + * notice, this list of conditions and the following disclaimer in the
84.16 + * documentation and/or other materials provided with the distribution.
84.17 + *
84.18 + * - Neither the name of Oracle nor the names of its
84.19 + * contributors may be used to endorse or promote products derived
84.20 + * from this software without specific prior written permission.
84.21 + *
84.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
84.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
84.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
84.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
84.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
84.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
84.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
84.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
84.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
84.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
84.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
84.33 + */
84.34 +
84.35 +import java.io.*;
84.36 +import java.nio.*;
84.37 +import java.nio.channels.*;
84.38 +import java.nio.file.*;
84.39 +import java.nio.file.attribute.*;
84.40 +import java.net.*;
84.41 +import java.text.DateFormat;
84.42 +import java.text.SimpleDateFormat;
84.43 +import java.util.*;
84.44 +
84.45 +import static java.nio.file.StandardOpenOption.*;
84.46 +import static java.nio.file.StandardCopyOption.*;
84.47 +
84.48 +/*
84.49 + * ZipFileSystem usage demo
84.50 + *
84.51 + * java [-cp .../zipfs.jar:./] Demo action ZipfileName [...]
84.52 + *
84.53 + * To deploy the provider, either copy the zipfs.jar into JDK/JRE
84.54 + * extensions directory or add
84.55 + * <JDK_HOME>/demo/nio/ZipFileSystem/zipfs.jar
84.56 + * into your class path as showed above.
84.57 + *
84.58 + * @author Xueming Shen
84.59 + */
84.60 +
84.61 +public class Demo {
84.62 +
84.63 + static enum Action {
84.64 + rename, // <java Demo rename zipfile src dst>
84.65 + // rename entry src to dst inside zipfile
84.66 +
84.67 + movein, // <java Demo movein zipfile src dst>
84.68 + // move an external src file into zipfile
84.69 + // as entry dst
84.70 +
84.71 + moveout, // <java Demo moveout zipfile src dst>
84.72 + // move a zipfile entry src out to dst
84.73 +
84.74 + copy, // <java Demo copy zipfile src dst>
84.75 + // copy entry src to dst inside zipfile
84.76 +
84.77 + copyin, // <java Demo copyin zipfile src dst>
84.78 + // copy an external src file into zipfile
84.79 + // as entry dst
84.80 +
84.81 + copyout, // <java Demo copyout zipfile src dst>
84.82 + // copy zipfile entry src" out to file dst
84.83 +
84.84 + zzmove, // <java Demo zzmove zfsrc zfdst path>
84.85 + // move entry path/dir from zfsrc to zfdst
84.86 +
84.87 + zzcopy, // <java Demo zzcopy zfsrc zfdst path>
84.88 + // copy path from zipfile zfsrc to zipfile
84.89 + // zfdst
84.90 +
84.91 + attrs, // <java Demo attrs zipfile path>
84.92 + // printout the attributes of entry path
84.93 +
84.94 + attrsspace, // <java Demo attrsspace zipfile path>
84.95 + // printout the storespace attrs of entry path
84.96 +
84.97 + setmtime, // <java Demo setmtime zipfile "MM/dd/yy-HH:mm:ss" path...>
84.98 + // set the lastModifiedTime of entry path
84.99 +
84.100 + lsdir, // <java Demo lsdir zipfile dir>
84.101 + // list dir's direct child files/dirs
84.102 +
84.103 + mkdir, // <java Demo mkdir zipfile dir>
84.104 +
84.105 + mkdirs, // <java Demo mkdirs zipfile dir>
84.106 +
84.107 + rmdirs, // <java Demo rmdirs zipfile dir>
84.108 +
84.109 + list, // <java Demo list zipfile [dir]>
84.110 + // recursively list all entries of dir
84.111 + // via DirectoryStream
84.112 +
84.113 + tlist, // <java Demo tlist zipfile [dir]>
84.114 + // list with buildDirTree=true
84.115 +
84.116 + vlist, // <java Demo vlist zipfile [dir]>
84.117 + // recursively verbose list all entries of
84.118 + // dir via DirectoryStream
84.119 +
84.120 + walk, // <java Demo walk zipfile [dir]>
84.121 + // recursively walk all entries of dir
84.122 + // via Files.walkFileTree
84.123 +
84.124 + twalk, // <java Demo twalk zipfile [dir]>
84.125 + // walk with buildDirTree=true
84.126 +
84.127 + extract, // <java Demo extract zipfile file [...]>
84.128 +
84.129 + update, // <java Demo extract zipfile file [...]>
84.130 +
84.131 + delete, // <java Demo delete zipfile file [...]>
84.132 +
84.133 + add, // <java Demo add zipfile file [...]>
84.134 +
84.135 + create, // <java Demo create zipfile file [...]>
84.136 + // create a new zipfile if it doesn't exit
84.137 + // and then add the file(s) into it.
84.138 +
84.139 + attrs2, // <java Demo attrs2 zipfile file [...]>
84.140 + // test different ways to print attrs
84.141 + }
84.142 +
84.143 + public static void main(String[] args) throws Throwable {
84.144 +
84.145 + Action action = Action.valueOf(args[0]);;
84.146 + Map<String, Object> env = env = new HashMap<String, Object>();
84.147 + if (action == Action.create)
84.148 + env.put("createNew", true);
84.149 + if (action == Action.tlist || action == Action.twalk)
84.150 + env.put("buildDirTree", true);
84.151 +
84.152 + FileSystem fs = FileSystems.newFileSystem(
84.153 + URI.create("zip" + Paths.get(args[1]).toUri().toString().substring(4)),
84.154 + env,
84.155 + null);
84.156 + try {
84.157 + FileSystem fs2;
84.158 + Path path, src, dst;
84.159 + boolean isRename = false;
84.160 + switch (action) {
84.161 + case rename:
84.162 + src = fs.getPath(args[2]);
84.163 + dst = fs.getPath(args[3]);
84.164 + src.moveTo(dst);
84.165 + break;
84.166 + case moveout:
84.167 + src = fs.getPath(args[2]);
84.168 + dst = Paths.get(args[3]);
84.169 + src.moveTo(dst);
84.170 + break;
84.171 + case movein:
84.172 + src = Paths.get(args[2]);
84.173 + dst = fs.getPath(args[3]);
84.174 + src.moveTo(dst);
84.175 + break;
84.176 + case copy:
84.177 + src = fs.getPath(args[2]);
84.178 + dst = fs.getPath(args[3]);
84.179 + src.copyTo(dst);
84.180 + break;
84.181 + case copyout:
84.182 + src = fs.getPath(args[2]);
84.183 + dst = Paths.get(args[3]);
84.184 + src.copyTo(dst);
84.185 + break;
84.186 + case copyin:
84.187 + src = Paths.get(args[2]);
84.188 + dst = fs.getPath(args[3]);
84.189 + src.copyTo(dst);
84.190 + break;
84.191 + case zzmove:
84.192 + fs2 = FileSystems.newFileSystem(
84.193 + URI.create("zip" + Paths.get(args[2]).toUri().toString().substring(4)),
84.194 + env,
84.195 + null);
84.196 + //sf1.getPath(args[3]).moveTo(fs2.getPath(args[3]));
84.197 + z2zmove(fs, fs2, args[3]);
84.198 + fs2.close();
84.199 + break;
84.200 + case zzcopy:
84.201 + fs2 = FileSystems.newFileSystem(
84.202 + URI.create("zip" + Paths.get(args[2]).toUri().toString().substring(4)),
84.203 + env,
84.204 + null);
84.205 + //sf1.getPath(args[3]).copyTo(fs2.getPath(args[3]));
84.206 + z2zcopy(fs, fs2, args[3]);
84.207 + fs2.close();
84.208 + break;
84.209 + case attrs:
84.210 + for (int i = 2; i < args.length; i++) {
84.211 + path = fs.getPath(args[i]);
84.212 + System.out.println(
84.213 + Attributes.readBasicFileAttributes(path).toString());
84.214 + }
84.215 + break;
84.216 + case setmtime:
84.217 + DateFormat df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss");
84.218 + Date newDatetime = df.parse(args[2]);
84.219 + for (int i = 3; i < args.length; i++) {
84.220 + path = fs.getPath(args[i]);
84.221 + path.setAttribute("lastModifiedTime",
84.222 + FileTime.fromMillis(newDatetime.getTime()));
84.223 + System.out.println(
84.224 + Attributes.readBasicFileAttributes(path).toString());
84.225 + }
84.226 + break;
84.227 + case attrsspace:
84.228 + path = fs.getPath("/");
84.229 + FileStore fstore = path.getFileStore();
84.230 + //System.out.println(fstore.getFileStoreAttributeView(FileStoreSpaceAttributeView.class)
84.231 + // .readAttributes());
84.232 + // or
84.233 + System.out.printf("filestore[%s]%n", fstore.name());
84.234 + System.out.printf(" totalSpace: %d%n",
84.235 + (Long)fstore.getAttribute("space:totalSpace"));
84.236 + System.out.printf(" usableSpace: %d%n",
84.237 + (Long)fstore.getAttribute("space:usableSpace"));
84.238 + System.out.printf(" unallocSpace: %d%n",
84.239 + (Long)fstore.getAttribute("space:unallocatedSpace"));
84.240 + break;
84.241 + case list:
84.242 + case tlist:
84.243 + if (args.length < 3)
84.244 + list(fs.getPath("/"), false);
84.245 + else
84.246 + list(fs.getPath(args[2]), false);
84.247 + break;
84.248 + case vlist:
84.249 + if (args.length < 3)
84.250 + list(fs.getPath("/"), true);
84.251 + else
84.252 + list(fs.getPath(args[2]), true);
84.253 + break;
84.254 + case twalk:
84.255 + case walk:
84.256 + walk(fs.getPath((args.length > 2)? args[2] : "/"));
84.257 + break;
84.258 + case extract:
84.259 + if (args.length == 2) {
84.260 + extract(fs, "/");
84.261 + } else {
84.262 + for (int i = 2; i < args.length; i++) {
84.263 + extract(fs, args[i]);
84.264 + }
84.265 + }
84.266 + break;
84.267 + case delete:
84.268 + for (int i = 2; i < args.length; i++)
84.269 + fs.getPath(args[i]).delete();
84.270 + break;
84.271 + case create:
84.272 + case add:
84.273 + case update:
84.274 + for (int i = 2; i < args.length; i++) {
84.275 + update(fs, args[i]);
84.276 + }
84.277 + break;
84.278 + case lsdir:
84.279 + path = fs.getPath(args[2]);
84.280 + final String fStr = (args.length > 3)?args[3]:"";
84.281 + DirectoryStream<Path> ds = path.newDirectoryStream(
84.282 + new DirectoryStream.Filter<Path>() {
84.283 + public boolean accept(Path path) {
84.284 + return path.toString().contains(fStr);
84.285 + }
84.286 + });
84.287 + for (Path p : ds)
84.288 + System.out.println(p);
84.289 + break;
84.290 + case mkdir:
84.291 + fs.getPath(args[2]).createDirectory();
84.292 + break;
84.293 + case mkdirs:
84.294 + mkdirs(fs.getPath(args[2]));
84.295 + break;
84.296 + case attrs2:
84.297 + for (int i = 2; i < args.length; i++) {
84.298 + path = fs.getPath(args[i]);
84.299 + System.out.println("-------(1)---------");
84.300 + System.out.println(
84.301 + Attributes.readBasicFileAttributes(path).toString());
84.302 + System.out.println("-------(2)---------");
84.303 + Map<String, ?> map = path.readAttributes("zip:*");
84.304 + for (Map.Entry<String, ?> e : map.entrySet()) {
84.305 + System.out.printf(" %s : %s%n", e.getKey(), e.getValue());
84.306 + }
84.307 + System.out.println("-------(3)---------");
84.308 + map = path.readAttributes("size,lastModifiedTime,isDirectory");
84.309 + for (Map.Entry<String, ?> e : map.entrySet()) {
84.310 + System.out.printf(" %s : %s%n", e.getKey(), e.getValue());
84.311 + }
84.312 + }
84.313 + break;
84.314 + }
84.315 + } catch (Exception x) {
84.316 + x.printStackTrace();
84.317 + } finally {
84.318 + if (fs != null)
84.319 + fs.close();
84.320 + }
84.321 + }
84.322 +
84.323 + private static byte[] getBytes(String name) {
84.324 + return name.getBytes();
84.325 + }
84.326 +
84.327 + private static String getString(byte[] name) {
84.328 + return new String(name);
84.329 + }
84.330 +
84.331 + private static void walk(Path path) throws IOException
84.332 + {
84.333 + Files.walkFileTree(
84.334 + path,
84.335 + new SimpleFileVisitor<Path>() {
84.336 + private int indent = 0;
84.337 + private void indent() {
84.338 + int n = 0;
84.339 + while (n++ < indent)
84.340 + System.out.printf(" ");
84.341 + }
84.342 +
84.343 + @Override
84.344 + public FileVisitResult visitFile(Path file,
84.345 + BasicFileAttributes attrs)
84.346 + {
84.347 + indent();
84.348 + System.out.printf("%s%n", file.getName().toString());
84.349 + return FileVisitResult.CONTINUE;
84.350 + }
84.351 +
84.352 + @Override
84.353 + public FileVisitResult preVisitDirectory(Path dir,
84.354 + BasicFileAttributes attrs)
84.355 + {
84.356 + indent();
84.357 + System.out.printf("[%s]%n", dir.toString());
84.358 + indent += 2;
84.359 + return FileVisitResult.CONTINUE;
84.360 + }
84.361 +
84.362 + @Override
84.363 + public FileVisitResult postVisitDirectory(Path dir,
84.364 + IOException ioe)
84.365 + {
84.366 + indent -= 2;
84.367 + return FileVisitResult.CONTINUE;
84.368 + }
84.369 + });
84.370 + }
84.371 +
84.372 + private static void update(FileSystem fs, String path) throws Throwable{
84.373 + Path src = FileSystems.getDefault().getPath(path);
84.374 + if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) {
84.375 + DirectoryStream<Path> ds = src.newDirectoryStream();
84.376 + for (Path child : ds)
84.377 + update(fs, child.toString());
84.378 + ds.close();
84.379 + } else {
84.380 + Path dst = fs.getPath(path);
84.381 + Path parent = dst.getParent();
84.382 + if (parent != null && parent.notExists())
84.383 + mkdirs(parent);
84.384 + src.copyTo(dst, REPLACE_EXISTING);
84.385 + }
84.386 + }
84.387 +
84.388 + private static void extract(FileSystem fs, String path) throws Throwable{
84.389 + Path src = fs.getPath(path);
84.390 + if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) {
84.391 + DirectoryStream<Path> ds = src.newDirectoryStream();
84.392 + for (Path child : ds)
84.393 + extract(fs, child.toString());
84.394 + ds.close();
84.395 + } else {
84.396 + if (path.startsWith("/"))
84.397 + path = path.substring(1);
84.398 + Path dst = FileSystems.getDefault().getPath(path);
84.399 + Path parent = dst.getParent();
84.400 + if (parent.notExists())
84.401 + mkdirs(parent);
84.402 + src.copyTo(dst, REPLACE_EXISTING);
84.403 + }
84.404 + }
84.405 +
84.406 + // use DirectoryStream
84.407 + private static void z2zcopy(FileSystem src, FileSystem dst, String path)
84.408 + throws IOException
84.409 + {
84.410 + Path srcPath = src.getPath(path);
84.411 + Path dstPath = dst.getPath(path);
84.412 +
84.413 + if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) {
84.414 + if (!dstPath.exists()) {
84.415 + try {
84.416 + mkdirs(dstPath);
84.417 + } catch (FileAlreadyExistsException x) {}
84.418 + }
84.419 + DirectoryStream<Path> ds = srcPath.newDirectoryStream();
84.420 + for (Path child : ds) {
84.421 + z2zcopy(src, dst,
84.422 + path + (path.endsWith("/")?"":"/") + child.getName());
84.423 + }
84.424 + ds.close();
84.425 + } else {
84.426 + //System.out.println("copying..." + path);
84.427 + srcPath.copyTo(dstPath);
84.428 + }
84.429 + }
84.430 +
84.431 + // use TreeWalk to move
84.432 + private static void z2zmove(FileSystem src, FileSystem dst, String path)
84.433 + throws IOException
84.434 + {
84.435 + final Path srcPath = src.getPath(path).toAbsolutePath();
84.436 + final Path dstPath = dst.getPath(path).toAbsolutePath();
84.437 +
84.438 + Files.walkFileTree(srcPath, new SimpleFileVisitor<Path>() {
84.439 +
84.440 + @Override
84.441 + public FileVisitResult visitFile(Path file,
84.442 + BasicFileAttributes attrs)
84.443 + {
84.444 + Path dst = srcPath.relativize(file);
84.445 + dst = dstPath.resolve(dst);
84.446 + try {
84.447 + Path parent = dstPath.getParent();
84.448 + if (parent != null && parent.notExists())
84.449 + mkdirs(parent);
84.450 + file.moveTo(dst);
84.451 + } catch (IOException x) {
84.452 + x.printStackTrace();
84.453 + }
84.454 + return FileVisitResult.CONTINUE;
84.455 + }
84.456 +
84.457 + @Override
84.458 + public FileVisitResult preVisitDirectory(Path dir,
84.459 + BasicFileAttributes attrs)
84.460 + {
84.461 + Path dst = srcPath.relativize(dir);
84.462 + dst = dstPath.resolve(dst);
84.463 + try {
84.464 +
84.465 + if (dst.notExists())
84.466 + mkdirs(dst);
84.467 + } catch (IOException x) {
84.468 + x.printStackTrace();
84.469 + }
84.470 + return FileVisitResult.CONTINUE;
84.471 + }
84.472 +
84.473 + @Override
84.474 + public FileVisitResult postVisitDirectory(Path dir,
84.475 + IOException ioe)
84.476 + throws IOException
84.477 + {
84.478 + try {
84.479 + dir.delete();
84.480 + } catch (IOException x) {
84.481 + //x.printStackTrace();
84.482 + }
84.483 + return FileVisitResult.CONTINUE;
84.484 + }
84.485 + });
84.486 +
84.487 + }
84.488 +
84.489 + private static void mkdirs(Path path) throws IOException {
84.490 + path = path.toAbsolutePath();
84.491 + Path parent = path.getParent();
84.492 + if (parent != null) {
84.493 + if (parent.notExists())
84.494 + mkdirs(parent);
84.495 + }
84.496 + path.createDirectory();
84.497 + }
84.498 +
84.499 + private static void rmdirs(Path path) throws IOException {
84.500 + while (path != null && path.getNameCount() != 0) {
84.501 + path.delete();
84.502 + path = path.getParent();
84.503 + }
84.504 + }
84.505 +
84.506 + private static void list(Path path, boolean verbose ) throws IOException {
84.507 + if (verbose)
84.508 + System.out.println(Attributes.readBasicFileAttributes(path).toString());
84.509 + else
84.510 + System.out.printf(" %s%n", path.toString());
84.511 + if (path.notExists())
84.512 + return;
84.513 + if (Attributes.readBasicFileAttributes(path).isDirectory()) {
84.514 + DirectoryStream<Path> ds = path.newDirectoryStream();
84.515 + for (Path child : ds)
84.516 + list(child, verbose);
84.517 + ds.close();
84.518 + }
84.519 + }
84.520 +
84.521 + // check the content of two paths are equal
84.522 + private static void checkEqual(Path src, Path dst) throws IOException
84.523 + {
84.524 + //System.out.printf("checking <%s> vs <%s>...%n",
84.525 + // src.toString(), dst.toString());
84.526 +
84.527 + //streams
84.528 + InputStream isSrc = src.newInputStream();
84.529 + InputStream isDst = dst.newInputStream();
84.530 + byte[] bufSrc = new byte[8192];
84.531 + byte[] bufDst = new byte[8192];
84.532 +
84.533 + try {
84.534 + int nSrc = 0;
84.535 + while ((nSrc = isSrc.read(bufSrc)) != -1) {
84.536 + int nDst = 0;
84.537 + while (nDst < nSrc) {
84.538 + int n = isDst.read(bufDst, nDst, nSrc - nDst);
84.539 + if (n == -1) {
84.540 + System.out.printf("checking <%s> vs <%s>...%n",
84.541 + src.toString(), dst.toString());
84.542 + throw new RuntimeException("CHECK FAILED!");
84.543 + }
84.544 + nDst += n;
84.545 + }
84.546 + while (--nSrc >= 0) {
84.547 + if (bufSrc[nSrc] != bufDst[nSrc]) {
84.548 + System.out.printf("checking <%s> vs <%s>...%n",
84.549 + src.toString(), dst.toString());
84.550 + throw new RuntimeException("CHECK FAILED!");
84.551 + }
84.552 + nSrc--;
84.553 + }
84.554 + }
84.555 + } finally {
84.556 + isSrc.close();
84.557 + isDst.close();
84.558 + }
84.559 +
84.560 + // channels
84.561 + SeekableByteChannel chSrc = src.newByteChannel();
84.562 + SeekableByteChannel chDst = dst.newByteChannel();
84.563 + if (chSrc.size() != chDst.size()) {
84.564 + System.out.printf("src[%s].size=%d, dst[%s].size=%d%n",
84.565 + chSrc.toString(), chSrc.size(),
84.566 + chDst.toString(), chDst.size());
84.567 + throw new RuntimeException("CHECK FAILED!");
84.568 + }
84.569 + ByteBuffer bbSrc = ByteBuffer.allocate(8192);
84.570 + ByteBuffer bbDst = ByteBuffer.allocate(8192);
84.571 +
84.572 + try {
84.573 + int nSrc = 0;
84.574 + while ((nSrc = chSrc.read(bbSrc)) != -1) {
84.575 + int nDst = chDst.read(bbDst);
84.576 + if (nSrc != nDst) {
84.577 + System.out.printf("checking <%s> vs <%s>...%n",
84.578 + src.toString(), dst.toString());
84.579 + throw new RuntimeException("CHECK FAILED!");
84.580 + }
84.581 + while (--nSrc >= 0) {
84.582 + if (bbSrc.get(nSrc) != bbDst.get(nSrc)) {
84.583 + System.out.printf("checking <%s> vs <%s>...%n",
84.584 + src.toString(), dst.toString());
84.585 + throw new RuntimeException("CHECK FAILED!");
84.586 + }
84.587 + nSrc--;
84.588 + }
84.589 + bbSrc.flip();
84.590 + bbDst.flip();
84.591 + }
84.592 + } catch (IOException x) {
84.593 + x.printStackTrace();
84.594 + } finally {
84.595 + chSrc.close();
84.596 + chDst.close();
84.597 + }
84.598 + }
84.599 +
84.600 + private static void fchCopy(Path src, Path dst) throws IOException
84.601 + {
84.602 + Set<OpenOption> read = new HashSet<>();
84.603 + read.add(READ);
84.604 + Set<OpenOption> openwrite = new HashSet<>();
84.605 + openwrite.add(CREATE_NEW);
84.606 + openwrite.add(WRITE);
84.607 +
84.608 + FileChannel srcFc = src.getFileSystem()
84.609 + .provider()
84.610 + .newFileChannel(src, read);
84.611 + FileChannel dstFc = dst.getFileSystem()
84.612 + .provider()
84.613 + .newFileChannel(dst, openwrite);
84.614 +
84.615 + try {
84.616 + ByteBuffer bb = ByteBuffer.allocate(8192);
84.617 + while (srcFc.read(bb) >= 0) {
84.618 + bb.flip();
84.619 + dstFc.write(bb);
84.620 + bb.clear();
84.621 + }
84.622 + } finally {
84.623 + srcFc.close();
84.624 + dstFc.close();
84.625 + }
84.626 + }
84.627 +
84.628 + private static void chCopy(Path src, Path dst) throws IOException
84.629 + {
84.630 + Set<OpenOption> read = new HashSet<>();
84.631 + read.add(READ);
84.632 + Set<OpenOption> openwrite = new HashSet<>();
84.633 + openwrite.add(CREATE_NEW);
84.634 + openwrite.add(WRITE);
84.635 +
84.636 + SeekableByteChannel srcCh = src.newByteChannel(read);
84.637 + SeekableByteChannel dstCh = dst.newByteChannel(openwrite);
84.638 +
84.639 + try {
84.640 + ByteBuffer bb = ByteBuffer.allocate(8192);
84.641 + while (srcCh.read(bb) >= 0) {
84.642 + bb.flip();
84.643 + dstCh.write(bb);
84.644 + bb.clear();
84.645 + }
84.646 + } finally {
84.647 + srcCh.close();
84.648 + dstCh.close();
84.649 + }
84.650 + }
84.651 +
84.652 + private static void streamCopy(Path src, Path dst) throws IOException
84.653 + {
84.654 + InputStream isSrc = src.newInputStream();
84.655 + OutputStream osDst = dst.newOutputStream();
84.656 + byte[] buf = new byte[8192];
84.657 + try {
84.658 + int n = 0;
84.659 + while ((n = isSrc.read(buf)) != -1) {
84.660 + osDst.write(buf, 0, n);
84.661 + }
84.662 + } finally {
84.663 + isSrc.close();
84.664 + osDst.close();
84.665 + }
84.666 + }
84.667 +}
85.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
85.2 +++ b/src/share/demo/nio/zipfs/META-INF/services/java.nio.file.spi.FileSystemProvider Tue Oct 12 12:51:48 2010 -0700
85.3 @@ -0,0 +1,3 @@
85.4 +com.sun.nio.zipfs.ZipFileSystemProvider
85.5 +com.sun.nio.zipfs.JarFileSystemProvider
85.6 +
86.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
86.2 +++ b/src/share/demo/nio/zipfs/README.txt Tue Oct 12 12:51:48 2010 -0700
86.3 @@ -0,0 +1,29 @@
86.4 +ZipFileSystem is a file system provider that treats the contents of a zip or
86.5 +JAR file as a java.nio.file.FileSystem.
86.6 +
86.7 +To deploy the provider you must copy zipfs.jar into your extensions
86.8 +directory or else add <JDK_HOME>/demo/nio/ZipFileSystem/zipfs.jar
86.9 +to your class path.
86.10 +
86.11 +The factory methods defined by the java.nio.file.FileSystems class can be
86.12 +used to create a FileSystem, eg:
86.13 +
86.14 + // use file type detection
86.15 + Map<String,?> env = Collections.emptyMap();
86.16 + Path jarfile = Path.get("foo.jar");
86.17 + FileSystem fs = FileSystems.newFileSystem(jarfile, env);
86.18 +
86.19 +-or
86.20 +
86.21 + // locate file system by URI
86.22 + Map<String,?> env = Collections.emptyMap();
86.23 + URI uri = URI.create("zip:///mydir/foo.jar");
86.24 + FileSystem fs = FileSystems.newFileSystem(uri, env);
86.25 +
86.26 +Once a FileSystem is created then classes in the java.nio.file package
86.27 +can be used to access files in the zip/JAR file, eg:
86.28 +
86.29 + Path mf = fs.getPath("/META-INF/MANIFEST.MF");
86.30 + InputStream in = mf.newInputStream();
86.31 +
86.32 +
87.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
87.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/JarFileSystemProvider.java Tue Oct 12 12:51:48 2010 -0700
87.3 @@ -0,0 +1,71 @@
87.4 +/*
87.5 + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
87.6 + *
87.7 + * Redistribution and use in source and binary forms, with or without
87.8 + * modification, are permitted provided that the following conditions
87.9 + * are met:
87.10 + *
87.11 + * - Redistributions of source code must retain the above copyright
87.12 + * notice, this list of conditions and the following disclaimer.
87.13 + *
87.14 + * - Redistributions in binary form must reproduce the above copyright
87.15 + * notice, this list of conditions and the following disclaimer in the
87.16 + * documentation and/or other materials provided with the distribution.
87.17 + *
87.18 + * - Neither the name of Sun Microsystems nor the names of its
87.19 + * contributors may be used to endorse or promote products derived
87.20 + * from this software without specific prior written permission.
87.21 + *
87.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
87.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
87.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
87.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
87.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
87.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
87.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
87.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
87.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
87.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
87.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
87.33 + */
87.34 +package com.sun.nio.zipfs;
87.35 +
87.36 +import java.nio.file.*;
87.37 +import java.nio.file.spi.*;
87.38 +import java.nio.file.attribute.*;
87.39 +import java.nio.file.spi.FileSystemProvider;
87.40 +
87.41 +import java.net.URI;
87.42 +import java.io.IOException;
87.43 +import java.net.URISyntaxException;
87.44 +import java.nio.channels.FileChannel;
87.45 +import java.util.HashMap;
87.46 +import java.util.Map;
87.47 +import java.util.Set;
87.48 +
87.49 +public class JarFileSystemProvider extends ZipFileSystemProvider
87.50 +{
87.51 +
87.52 + @Override
87.53 + public String getScheme() {
87.54 + return "jar";
87.55 + }
87.56 +
87.57 + @Override
87.58 + protected Path uriToPath(URI uri) {
87.59 + String scheme = uri.getScheme();
87.60 + if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) {
87.61 + throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'");
87.62 + }
87.63 + try {
87.64 + String uristr = uri.toString();
87.65 + int end = uristr.indexOf("!/");
87.66 + uristr = uristr.substring(4, (end == -1) ? uristr.length() : end);
87.67 + uri = new URI(uristr);
87.68 + return Paths.get(new URI("file", uri.getHost(), uri.getPath(), null))
87.69 + .toAbsolutePath();
87.70 + } catch (URISyntaxException e) {
87.71 + throw new AssertionError(e); //never thrown
87.72 + }
87.73 + }
87.74 +}
88.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
88.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipCoder.java Tue Oct 12 12:51:48 2010 -0700
88.3 @@ -0,0 +1,160 @@
88.4 +/*
88.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
88.6 + *
88.7 + * Redistribution and use in source and binary forms, with or without
88.8 + * modification, are permitted provided that the following conditions
88.9 + * are met:
88.10 + *
88.11 + * - Redistributions of source code must retain the above copyright
88.12 + * notice, this list of conditions and the following disclaimer.
88.13 + *
88.14 + * - Redistributions in binary form must reproduce the above copyright
88.15 + * notice, this list of conditions and the following disclaimer in the
88.16 + * documentation and/or other materials provided with the distribution.
88.17 + *
88.18 + * - Neither the name of Oracle nor the names of its
88.19 + * contributors may be used to endorse or promote products derived
88.20 + * from this software without specific prior written permission.
88.21 + *
88.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
88.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
88.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
88.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
88.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
88.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
88.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
88.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
88.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
88.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88.33 + */
88.34 +
88.35 +package com.sun.nio.zipfs;
88.36 +
88.37 +import java.nio.ByteBuffer;
88.38 +import java.nio.CharBuffer;
88.39 +import java.nio.charset.Charset;
88.40 +import java.nio.charset.CharsetDecoder;
88.41 +import java.nio.charset.CharsetEncoder;
88.42 +import java.nio.charset.CoderResult;
88.43 +import java.nio.charset.CodingErrorAction;
88.44 +import java.util.Arrays;
88.45 +
88.46 +/**
88.47 + * Utility class for zipfile name and comment decoding and encoding
88.48 + *
88.49 + * @author Xueming Shen
88.50 + */
88.51 +
88.52 +final class ZipCoder {
88.53 +
88.54 + String toString(byte[] ba, int length) {
88.55 + CharsetDecoder cd = decoder().reset();
88.56 + int len = (int)(length * cd.maxCharsPerByte());
88.57 + char[] ca = new char[len];
88.58 + if (len == 0)
88.59 + return new String(ca);
88.60 + ByteBuffer bb = ByteBuffer.wrap(ba, 0, length);
88.61 + CharBuffer cb = CharBuffer.wrap(ca);
88.62 + CoderResult cr = cd.decode(bb, cb, true);
88.63 + if (!cr.isUnderflow())
88.64 + throw new IllegalArgumentException(cr.toString());
88.65 + cr = cd.flush(cb);
88.66 + if (!cr.isUnderflow())
88.67 + throw new IllegalArgumentException(cr.toString());
88.68 + return new String(ca, 0, cb.position());
88.69 + }
88.70 +
88.71 + String toString(byte[] ba) {
88.72 + return toString(ba, ba.length);
88.73 + }
88.74 +
88.75 + byte[] getBytes(String s) {
88.76 + CharsetEncoder ce = encoder().reset();
88.77 + char[] ca = s.toCharArray();
88.78 + int len = (int)(ca.length * ce.maxBytesPerChar());
88.79 + byte[] ba = new byte[len];
88.80 + if (len == 0)
88.81 + return ba;
88.82 + ByteBuffer bb = ByteBuffer.wrap(ba);
88.83 + CharBuffer cb = CharBuffer.wrap(ca);
88.84 + CoderResult cr = ce.encode(cb, bb, true);
88.85 + if (!cr.isUnderflow())
88.86 + throw new IllegalArgumentException(cr.toString());
88.87 + cr = ce.flush(bb);
88.88 + if (!cr.isUnderflow())
88.89 + throw new IllegalArgumentException(cr.toString());
88.90 + if (bb.position() == ba.length) // defensive copy?
88.91 + return ba;
88.92 + else
88.93 + return Arrays.copyOf(ba, bb.position());
88.94 + }
88.95 +
88.96 + // assume invoked only if "this" is not utf8
88.97 + byte[] getBytesUTF8(String s) {
88.98 + if (isutf8)
88.99 + return getBytes(s);
88.100 + if (utf8 == null)
88.101 + utf8 = new ZipCoder(Charset.forName("UTF-8"));
88.102 + return utf8.getBytes(s);
88.103 + }
88.104 +
88.105 + String toStringUTF8(byte[] ba, int len) {
88.106 + if (isutf8)
88.107 + return toString(ba, len);
88.108 + if (utf8 == null)
88.109 + utf8 = new ZipCoder(Charset.forName("UTF-8"));
88.110 + return utf8.toString(ba, len);
88.111 + }
88.112 +
88.113 + boolean isUTF8() {
88.114 + return isutf8;
88.115 + }
88.116 +
88.117 + private Charset cs;
88.118 + private boolean isutf8;
88.119 + private ZipCoder utf8;
88.120 +
88.121 + private ZipCoder(Charset cs) {
88.122 + this.cs = cs;
88.123 + this.isutf8 = cs.name().equals("UTF-8");
88.124 + }
88.125 +
88.126 + static ZipCoder get(Charset charset) {
88.127 + return new ZipCoder(charset);
88.128 + }
88.129 +
88.130 + static ZipCoder get(String csn) {
88.131 + try {
88.132 + return new ZipCoder(Charset.forName(csn));
88.133 + } catch (Throwable t) {
88.134 + t.printStackTrace();
88.135 + }
88.136 + return new ZipCoder(Charset.defaultCharset());
88.137 + }
88.138 +
88.139 + private final ThreadLocal<CharsetDecoder> decTL = new ThreadLocal<>();
88.140 + private final ThreadLocal<CharsetEncoder> encTL = new ThreadLocal<>();
88.141 +
88.142 + private CharsetDecoder decoder() {
88.143 + CharsetDecoder dec = decTL.get();
88.144 + if (dec == null) {
88.145 + dec = cs.newDecoder()
88.146 + .onMalformedInput(CodingErrorAction.REPORT)
88.147 + .onUnmappableCharacter(CodingErrorAction.REPORT);
88.148 + decTL.set(dec);
88.149 + }
88.150 + return dec;
88.151 + }
88.152 +
88.153 + private CharsetEncoder encoder() {
88.154 + CharsetEncoder enc = encTL.get();
88.155 + if (enc == null) {
88.156 + enc = cs.newEncoder()
88.157 + .onMalformedInput(CodingErrorAction.REPORT)
88.158 + .onUnmappableCharacter(CodingErrorAction.REPORT);
88.159 + encTL.set(enc);
88.160 + }
88.161 + return enc;
88.162 + }
88.163 +}
89.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
89.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipConstants.java Tue Oct 12 12:51:48 2010 -0700
89.3 @@ -0,0 +1,261 @@
89.4 +/*
89.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
89.6 + *
89.7 + * Redistribution and use in source and binary forms, with or without
89.8 + * modification, are permitted provided that the following conditions
89.9 + * are met:
89.10 + *
89.11 + * - Redistributions of source code must retain the above copyright
89.12 + * notice, this list of conditions and the following disclaimer.
89.13 + *
89.14 + * - Redistributions in binary form must reproduce the above copyright
89.15 + * notice, this list of conditions and the following disclaimer in the
89.16 + * documentation and/or other materials provided with the distribution.
89.17 + *
89.18 + * - Neither the name of Oracle nor the names of its
89.19 + * contributors may be used to endorse or promote products derived
89.20 + * from this software without specific prior written permission.
89.21 + *
89.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
89.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
89.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
89.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
89.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
89.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
89.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
89.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
89.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
89.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89.33 + */
89.34 +
89.35 +package com.sun.nio.zipfs;
89.36 +
89.37 +import java.nio.ByteBuffer;
89.38 +
89.39 +/**
89.40 + *
89.41 + * @author Xueming Shen
89.42 + */
89.43 +
89.44 +class ZipConstants {
89.45 + /*
89.46 + * Compression methods
89.47 + */
89.48 + static final int METHOD_STORED = 0;
89.49 + static final int METHOD_DEFLATED = 8;
89.50 + static final int METHOD_DEFLATED64 = 9;
89.51 + static final int METHOD_BZIP2 = 12;
89.52 + static final int METHOD_LZMA = 14;
89.53 + static final int METHOD_LZ77 = 19;
89.54 +
89.55 + /*
89.56 + * General purpose big flag
89.57 + */
89.58 + static final int FLAG_ENCRYPTED = 0x01;
89.59 + static final int FLAG_DATADESCR = 0x08; // crc, size and csize in dd
89.60 + static final int FLAG_EFS = 0x800; // If this bit is set the filename and
89.61 + // comment fields for this file must be
89.62 + // encoded using UTF-8.
89.63 + /*
89.64 + * Header signatures
89.65 + */
89.66 + static long LOCSIG = 0x04034b50L; // "PK\003\004"
89.67 + static long EXTSIG = 0x08074b50L; // "PK\007\008"
89.68 + static long CENSIG = 0x02014b50L; // "PK\001\002"
89.69 + static long ENDSIG = 0x06054b50L; // "PK\005\006"
89.70 +
89.71 + /*
89.72 + * Header sizes in bytes (including signatures)
89.73 + */
89.74 + static final int LOCHDR = 30; // LOC header size
89.75 + static final int EXTHDR = 16; // EXT header size
89.76 + static final int CENHDR = 46; // CEN header size
89.77 + static final int ENDHDR = 22; // END header size
89.78 +
89.79 + /*
89.80 + * Local file (LOC) header field offsets
89.81 + */
89.82 + static final int LOCVER = 4; // version needed to extract
89.83 + static final int LOCFLG = 6; // general purpose bit flag
89.84 + static final int LOCHOW = 8; // compression method
89.85 + static final int LOCTIM = 10; // modification time
89.86 + static final int LOCCRC = 14; // uncompressed file crc-32 value
89.87 + static final int LOCSIZ = 18; // compressed size
89.88 + static final int LOCLEN = 22; // uncompressed size
89.89 + static final int LOCNAM = 26; // filename length
89.90 + static final int LOCEXT = 28; // extra field length
89.91 +
89.92 + /*
89.93 + * Extra local (EXT) header field offsets
89.94 + */
89.95 + static final int EXTCRC = 4; // uncompressed file crc-32 value
89.96 + static final int EXTSIZ = 8; // compressed size
89.97 + static final int EXTLEN = 12; // uncompressed size
89.98 +
89.99 + /*
89.100 + * Central directory (CEN) header field offsets
89.101 + */
89.102 + static final int CENVEM = 4; // version made by
89.103 + static final int CENVER = 6; // version needed to extract
89.104 + static final int CENFLG = 8; // encrypt, decrypt flags
89.105 + static final int CENHOW = 10; // compression method
89.106 + static final int CENTIM = 12; // modification time
89.107 + static final int CENCRC = 16; // uncompressed file crc-32 value
89.108 + static final int CENSIZ = 20; // compressed size
89.109 + static final int CENLEN = 24; // uncompressed size
89.110 + static final int CENNAM = 28; // filename length
89.111 + static final int CENEXT = 30; // extra field length
89.112 + static final int CENCOM = 32; // comment length
89.113 + static final int CENDSK = 34; // disk number start
89.114 + static final int CENATT = 36; // internal file attributes
89.115 + static final int CENATX = 38; // external file attributes
89.116 + static final int CENOFF = 42; // LOC header offset
89.117 +
89.118 + /*
89.119 + * End of central directory (END) header field offsets
89.120 + */
89.121 + static final int ENDSUB = 8; // number of entries on this disk
89.122 + static final int ENDTOT = 10; // total number of entries
89.123 + static final int ENDSIZ = 12; // central directory size in bytes
89.124 + static final int ENDOFF = 16; // offset of first CEN header
89.125 + static final int ENDCOM = 20; // zip file comment length
89.126 +
89.127 + /*
89.128 + * ZIP64 constants
89.129 + */
89.130 + static final long ZIP64_ENDSIG = 0x06064b50L; // "PK\006\006"
89.131 + static final long ZIP64_LOCSIG = 0x07064b50L; // "PK\006\007"
89.132 + static final int ZIP64_ENDHDR = 56; // ZIP64 end header size
89.133 + static final int ZIP64_LOCHDR = 20; // ZIP64 end loc header size
89.134 + static final int ZIP64_EXTHDR = 24; // EXT header size
89.135 + static final int ZIP64_EXTID = 0x0001; // Extra field Zip64 header ID
89.136 +
89.137 + static final int ZIP64_MINVAL32 = 0xFFFF;
89.138 + static final long ZIP64_MINVAL = 0xFFFFFFFFL;
89.139 +
89.140 + /*
89.141 + * Zip64 End of central directory (END) header field offsets
89.142 + */
89.143 + static final int ZIP64_ENDLEN = 4; // size of zip64 end of central dir
89.144 + static final int ZIP64_ENDVEM = 12; // version made by
89.145 + static final int ZIP64_ENDVER = 14; // version needed to extract
89.146 + static final int ZIP64_ENDNMD = 16; // number of this disk
89.147 + static final int ZIP64_ENDDSK = 20; // disk number of start
89.148 + static final int ZIP64_ENDTOD = 24; // total number of entries on this disk
89.149 + static final int ZIP64_ENDTOT = 32; // total number of entries
89.150 + static final int ZIP64_ENDSIZ = 40; // central directory size in bytes
89.151 + static final int ZIP64_ENDOFF = 48; // offset of first CEN header
89.152 + static final int ZIP64_ENDEXT = 56; // zip64 extensible data sector
89.153 +
89.154 + /*
89.155 + * Zip64 End of central directory locator field offsets
89.156 + */
89.157 + static final int ZIP64_LOCDSK = 4; // disk number start
89.158 + static final int ZIP64_LOCOFF = 8; // offset of zip64 end
89.159 + static final int ZIP64_LOCTOT = 16; // total number of disks
89.160 +
89.161 + /*
89.162 + * Zip64 Extra local (EXT) header field offsets
89.163 + */
89.164 + static final int ZIP64_EXTCRC = 4; // uncompressed file crc-32 value
89.165 + static final int ZIP64_EXTSIZ = 8; // compressed size, 8-byte
89.166 + static final int ZIP64_EXTLEN = 16; // uncompressed size, 8-byte
89.167 +
89.168 + /*
89.169 + * Extra field header ID
89.170 + */
89.171 + static final int EXTID_ZIP64 = 0x0001; // ZIP64
89.172 + static final int EXTID_NTFS = 0x000a; // NTFS
89.173 + static final int EXTID_UNIX = 0x000d; // UNIX
89.174 +
89.175 +
89.176 + /*
89.177 + * fields access methods
89.178 + */
89.179 + ///////////////////////////////////////////////////////
89.180 + static final int CH(byte[] b, int n) {
89.181 + return b[n] & 0xff;
89.182 + }
89.183 +
89.184 + static final int SH(byte[] b, int n) {
89.185 + return (b[n] & 0xff) | ((b[n + 1] & 0xff) << 8);
89.186 + }
89.187 +
89.188 + static final long LG(byte[] b, int n) {
89.189 + return ((SH(b, n)) | (SH(b, n + 2) << 16)) & 0xffffffffL;
89.190 + }
89.191 +
89.192 + static final long LL(byte[] b, int n) {
89.193 + return (LG(b, n)) | (LG(b, n + 4) << 32);
89.194 + }
89.195 +
89.196 + static final long GETSIG(byte[] b) {
89.197 + return LG(b, 0);
89.198 + }
89.199 +
89.200 + // local file (LOC) header fields
89.201 + static final long LOCSIG(byte[] b) { return LG(b, 0); } // signature
89.202 + static final int LOCVER(byte[] b) { return SH(b, 4); } // version needed to extract
89.203 + static final int LOCFLG(byte[] b) { return SH(b, 6); } // general purpose bit flags
89.204 + static final int LOCHOW(byte[] b) { return SH(b, 8); } // compression method
89.205 + static final long LOCTIM(byte[] b) { return LG(b, 10);} // modification time
89.206 + static final long LOCCRC(byte[] b) { return LG(b, 14);} // crc of uncompressed data
89.207 + static final long LOCSIZ(byte[] b) { return LG(b, 18);} // compressed data size
89.208 + static final long LOCLEN(byte[] b) { return LG(b, 22);} // uncompressed data size
89.209 + static final int LOCNAM(byte[] b) { return SH(b, 26);} // filename length
89.210 + static final int LOCEXT(byte[] b) { return SH(b, 28);} // extra field length
89.211 +
89.212 + // extra local (EXT) header fields
89.213 + static final long EXTCRC(byte[] b) { return LG(b, 4);} // crc of uncompressed data
89.214 + static final long EXTSIZ(byte[] b) { return LG(b, 8);} // compressed size
89.215 + static final long EXTLEN(byte[] b) { return LG(b, 12);} // uncompressed size
89.216 +
89.217 + // end of central directory header (END) fields
89.218 + static final int ENDSUB(byte[] b) { return SH(b, 8); } // number of entries on this disk
89.219 + static final int ENDTOT(byte[] b) { return SH(b, 10);} // total number of entries
89.220 + static final long ENDSIZ(byte[] b) { return LG(b, 12);} // central directory size
89.221 + static final long ENDOFF(byte[] b) { return LG(b, 16);} // central directory offset
89.222 + static final int ENDCOM(byte[] b) { return SH(b, 20);} // size of zip file comment
89.223 + static final int ENDCOM(byte[] b, int off) { return SH(b, off + 20);}
89.224 +
89.225 + // zip64 end of central directory recoder fields
89.226 + static final long ZIP64_ENDTOD(byte[] b) { return LL(b, 24);} // total number of entries on disk
89.227 + static final long ZIP64_ENDTOT(byte[] b) { return LL(b, 32);} // total number of entries
89.228 + static final long ZIP64_ENDSIZ(byte[] b) { return LL(b, 40);} // central directory size
89.229 + static final long ZIP64_ENDOFF(byte[] b) { return LL(b, 48);} // central directory offset
89.230 + static final long ZIP64_LOCOFF(byte[] b) { return LL(b, 8);} // zip64 end offset
89.231 +
89.232 + //////////////////////////////////////////
89.233 + static final int CH(ByteBuffer b, int pos) {
89.234 + return b.get(pos) & 0xff;
89.235 + }
89.236 + static final int SH(ByteBuffer b, int pos) {
89.237 + return b.getShort(pos) & 0xffff;
89.238 + }
89.239 + static final long LG(ByteBuffer b, int pos) {
89.240 + return b.getInt(pos) & 0xffffffffL;
89.241 + }
89.242 +
89.243 + // central directory header (END) fields
89.244 + static final long CENSIG(ByteBuffer b, int pos) { return LG(b, pos + 0); }
89.245 + static final int CENVEM(ByteBuffer b, int pos) { return SH(b, pos + 4); }
89.246 + static final int CENVER(ByteBuffer b, int pos) { return SH(b, pos + 6); }
89.247 + static final int CENFLG(ByteBuffer b, int pos) { return SH(b, pos + 8); }
89.248 + static final int CENHOW(ByteBuffer b, int pos) { return SH(b, pos + 10);}
89.249 + static final long CENTIM(ByteBuffer b, int pos) { return LG(b, pos + 12);}
89.250 + static final long CENCRC(ByteBuffer b, int pos) { return LG(b, pos + 16);}
89.251 + static final long CENSIZ(ByteBuffer b, int pos) { return LG(b, pos + 20);}
89.252 + static final long CENLEN(ByteBuffer b, int pos) { return LG(b, pos + 24);}
89.253 + static final int CENNAM(ByteBuffer b, int pos) { return SH(b, pos + 28);}
89.254 + static final int CENEXT(ByteBuffer b, int pos) { return SH(b, pos + 30);}
89.255 + static final int CENCOM(ByteBuffer b, int pos) { return SH(b, pos + 32);}
89.256 + static final int CENDSK(ByteBuffer b, int pos) { return SH(b, pos + 34);}
89.257 + static final int CENATT(ByteBuffer b, int pos) { return SH(b, pos + 36);}
89.258 + static final long CENATX(ByteBuffer b, int pos) { return LG(b, pos + 38);}
89.259 + static final long CENOFF(ByteBuffer b, int pos) { return LG(b, pos + 42);}
89.260 +
89.261 + /* The END header is followed by a variable length comment of size < 64k. */
89.262 + static final long END_MAXLEN = 0xFFFF + ENDHDR;
89.263 + static final int READBLOCKSZ = 128;
89.264 +}
90.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
90.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipDirectoryStream.java Tue Oct 12 12:51:48 2010 -0700
90.3 @@ -0,0 +1,109 @@
90.4 +/*
90.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
90.6 + *
90.7 + * Redistribution and use in source and binary forms, with or without
90.8 + * modification, are permitted provided that the following conditions
90.9 + * are met:
90.10 + *
90.11 + * - Redistributions of source code must retain the above copyright
90.12 + * notice, this list of conditions and the following disclaimer.
90.13 + *
90.14 + * - Redistributions in binary form must reproduce the above copyright
90.15 + * notice, this list of conditions and the following disclaimer in the
90.16 + * documentation and/or other materials provided with the distribution.
90.17 + *
90.18 + * - Neither the name of Oracle nor the names of its
90.19 + * contributors may be used to endorse or promote products derived
90.20 + * from this software without specific prior written permission.
90.21 + *
90.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
90.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
90.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
90.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
90.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
90.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
90.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
90.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
90.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
90.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90.33 + */
90.34 +
90.35 +package com.sun.nio.zipfs;
90.36 +
90.37 +import java.nio.file.DirectoryStream;
90.38 +import java.nio.file.ClosedDirectoryStreamException;
90.39 +import java.nio.file.NotDirectoryException;
90.40 +import java.nio.file.Path;
90.41 +import java.util.Iterator;
90.42 +import java.util.NoSuchElementException;
90.43 +import java.io.IOException;
90.44 +import static com.sun.nio.zipfs.ZipUtils.*;
90.45 +
90.46 +/**
90.47 + *
90.48 + * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
90.49 + */
90.50 +
90.51 +public class ZipDirectoryStream implements DirectoryStream<Path> {
90.52 +
90.53 + private final ZipFileSystem zipfs;
90.54 + private final byte[] path;
90.55 + private final DirectoryStream.Filter<? super Path> filter;
90.56 + private volatile boolean isClosed;
90.57 + private volatile Iterator<Path> itr;
90.58 +
90.59 + ZipDirectoryStream(ZipPath zipPath,
90.60 + DirectoryStream.Filter<? super java.nio.file.Path> filter)
90.61 + throws IOException
90.62 + {
90.63 + this.zipfs = zipPath.getFileSystem();
90.64 + this.path = zipPath.getResolvedPath();
90.65 + this.filter = filter;
90.66 + // sanity check
90.67 + if (!zipfs.isDirectory(path))
90.68 + throw new NotDirectoryException(zipPath.toString());
90.69 + }
90.70 +
90.71 + @Override
90.72 + public synchronized Iterator<Path> iterator() {
90.73 + if (isClosed)
90.74 + throw new ClosedDirectoryStreamException();
90.75 + if (itr != null)
90.76 + throw new IllegalStateException("Iterator has already been returned");
90.77 +
90.78 + try {
90.79 + itr = zipfs.iteratorOf(path, filter);
90.80 + } catch (IOException e) {
90.81 + throw new IllegalStateException(e);
90.82 + }
90.83 + return new Iterator<Path>() {
90.84 + private Path next;
90.85 + @Override
90.86 + public boolean hasNext() {
90.87 + if (isClosed)
90.88 + return false;
90.89 + return itr.hasNext();
90.90 + }
90.91 +
90.92 + @Override
90.93 + public synchronized Path next() {
90.94 + if (isClosed)
90.95 + throw new NoSuchElementException();
90.96 + return itr.next();
90.97 + }
90.98 +
90.99 + @Override
90.100 + public void remove() {
90.101 + throw new UnsupportedOperationException();
90.102 + }
90.103 + };
90.104 + }
90.105 +
90.106 + @Override
90.107 + public synchronized void close() throws IOException {
90.108 + isClosed = true;
90.109 + }
90.110 +
90.111 +
90.112 +}
91.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
91.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributeView.java Tue Oct 12 12:51:48 2010 -0700
91.3 @@ -0,0 +1,185 @@
91.4 +/*
91.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
91.6 + *
91.7 + * Redistribution and use in source and binary forms, with or without
91.8 + * modification, are permitted provided that the following conditions
91.9 + * are met:
91.10 + *
91.11 + * - Redistributions of source code must retain the above copyright
91.12 + * notice, this list of conditions and the following disclaimer.
91.13 + *
91.14 + * - Redistributions in binary form must reproduce the above copyright
91.15 + * notice, this list of conditions and the following disclaimer in the
91.16 + * documentation and/or other materials provided with the distribution.
91.17 + *
91.18 + * - Neither the name of Oracle nor the names of its
91.19 + * contributors may be used to endorse or promote products derived
91.20 + * from this software without specific prior written permission.
91.21 + *
91.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
91.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
91.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
91.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
91.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
91.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
91.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
91.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
91.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
91.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91.33 + */
91.34 +
91.35 +
91.36 +package com.sun.nio.zipfs;
91.37 +
91.38 +import java.nio.file.ReadOnlyFileSystemException;
91.39 +import java.nio.file.attribute.BasicFileAttributeView;
91.40 +import java.nio.file.attribute.FileAttributeView;
91.41 +import java.nio.file.attribute.FileTime;
91.42 +import java.io.IOException;
91.43 +import java.util.LinkedHashMap;
91.44 +
91.45 +/*
91.46 + * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
91.47 + */
91.48 +
91.49 +public class ZipFileAttributeView implements BasicFileAttributeView
91.50 +{
91.51 + private static enum AttrID {
91.52 + size,
91.53 + creationTime,
91.54 + lastAccessTime,
91.55 + lastModifiedTime,
91.56 + isDirectory,
91.57 + isRegularFile,
91.58 + isSymbolicLink,
91.59 + isOther,
91.60 + fileKey,
91.61 + compressedSize,
91.62 + crc,
91.63 + method
91.64 + };
91.65 +
91.66 + private final ZipPath path;
91.67 + private final boolean isZipView;
91.68 +
91.69 + private ZipFileAttributeView(ZipPath path, boolean isZipView) {
91.70 + this.path = path;
91.71 + this.isZipView = isZipView;
91.72 + }
91.73 +
91.74 + static <V extends FileAttributeView> V get(ZipPath path, Class<V> type) {
91.75 + if (type == null)
91.76 + throw new NullPointerException();
91.77 + if (type == BasicFileAttributeView.class)
91.78 + return (V)new ZipFileAttributeView(path, false);
91.79 + if (type == ZipFileAttributeView.class)
91.80 + return (V)new ZipFileAttributeView(path, true);
91.81 + return null;
91.82 + }
91.83 +
91.84 + static ZipFileAttributeView get(ZipPath path, String type) {
91.85 + if (type == null)
91.86 + throw new NullPointerException();
91.87 + if (type.equals("basic"))
91.88 + return new ZipFileAttributeView(path, false);
91.89 + if (type.equals("zip"))
91.90 + return new ZipFileAttributeView(path, true);
91.91 + return null;
91.92 + }
91.93 +
91.94 + @Override
91.95 + public String name() {
91.96 + return isZipView ? "zip" : "basic";
91.97 + }
91.98 +
91.99 + public ZipFileAttributes readAttributes() throws IOException
91.100 + {
91.101 + return path.getAttributes();
91.102 + }
91.103 +
91.104 + @Override
91.105 + public void setTimes(FileTime lastModifiedTime,
91.106 + FileTime lastAccessTime,
91.107 + FileTime createTime)
91.108 + throws IOException
91.109 + {
91.110 + path.setTimes(lastModifiedTime, lastAccessTime, createTime);
91.111 + }
91.112 +
91.113 + void setAttribute(String attribute, Object value)
91.114 + throws IOException
91.115 + {
91.116 + try {
91.117 + if (AttrID.valueOf(attribute) == AttrID.lastModifiedTime)
91.118 + setTimes ((FileTime)value, null, null);
91.119 + return;
91.120 + } catch (IllegalArgumentException x) {}
91.121 + throw new UnsupportedOperationException("'" + attribute +
91.122 + "' is unknown or read-only attribute");
91.123 + }
91.124 +
91.125 + public Object getAttribute(String attribute, boolean domap)
91.126 + throws IOException
91.127 + {
91.128 + ZipFileAttributes zfas = readAttributes();
91.129 + if (!domap) {
91.130 + try {
91.131 + return attribute(AttrID.valueOf(attribute), zfas);
91.132 + } catch (IllegalArgumentException x) {}
91.133 + return null;
91.134 + }
91.135 + LinkedHashMap<String, Object> map = new LinkedHashMap<>();
91.136 + if ("*".equals(attribute)) {
91.137 + for (AttrID id : AttrID.values()) {
91.138 + try {
91.139 + map.put(id.name(), attribute(id, zfas));
91.140 + } catch (IllegalArgumentException x) {}
91.141 + }
91.142 + } else {
91.143 + String[] as = attribute.split(",");
91.144 + for (String a : as) {
91.145 + try {
91.146 + map.put(a, attribute(AttrID.valueOf(a), zfas));
91.147 + } catch (IllegalArgumentException x) {}
91.148 + }
91.149 + }
91.150 + return map;
91.151 + }
91.152 +
91.153 + Object attribute(AttrID id, ZipFileAttributes zfas) {
91.154 + switch (id) {
91.155 + case size:
91.156 + return zfas.size();
91.157 + case creationTime:
91.158 + return zfas.creationTime();
91.159 + case lastAccessTime:
91.160 + return zfas.lastAccessTime();
91.161 + case lastModifiedTime:
91.162 + return zfas.lastModifiedTime();
91.163 + case isDirectory:
91.164 + return zfas.isDirectory();
91.165 + case isRegularFile:
91.166 + return zfas.isRegularFile();
91.167 + case isSymbolicLink:
91.168 + return zfas.isSymbolicLink();
91.169 + case isOther:
91.170 + return zfas.isOther();
91.171 + case fileKey:
91.172 + return zfas.fileKey();
91.173 + case compressedSize:
91.174 + if (isZipView)
91.175 + return zfas.compressedSize();
91.176 + break;
91.177 + case crc:
91.178 + if (isZipView)
91.179 + return zfas.crc();
91.180 + break;
91.181 + case method:
91.182 + if (isZipView)
91.183 + return zfas.method();
91.184 + break;
91.185 + }
91.186 + return null;
91.187 + }
91.188 +}
92.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
92.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributes.java Tue Oct 12 12:51:48 2010 -0700
92.3 @@ -0,0 +1,156 @@
92.4 +/*
92.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
92.6 + *
92.7 + * Redistribution and use in source and binary forms, with or without
92.8 + * modification, are permitted provided that the following conditions
92.9 + * are met:
92.10 + *
92.11 + * - Redistributions of source code must retain the above copyright
92.12 + * notice, this list of conditions and the following disclaimer.
92.13 + *
92.14 + * - Redistributions in binary form must reproduce the above copyright
92.15 + * notice, this list of conditions and the following disclaimer in the
92.16 + * documentation and/or other materials provided with the distribution.
92.17 + *
92.18 + * - Neither the name of Oracle nor the names of its
92.19 + * contributors may be used to endorse or promote products derived
92.20 + * from this software without specific prior written permission.
92.21 + *
92.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
92.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
92.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
92.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
92.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
92.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
92.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
92.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
92.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
92.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92.33 + */
92.34 +
92.35 +
92.36 +package com.sun.nio.zipfs;
92.37 +
92.38 +import java.nio.file.attribute.BasicFileAttributes;
92.39 +import java.nio.file.attribute.FileTime;
92.40 +import java.util.Arrays;
92.41 +import java.util.Formatter;
92.42 +import static com.sun.nio.zipfs.ZipUtils.*;
92.43 +
92.44 +/**
92.45 + *
92.46 + * @author Xueming Shen, Rajendra Gutupalli,Jaya Hangal
92.47 + */
92.48 +
92.49 +public class ZipFileAttributes implements BasicFileAttributes
92.50 +
92.51 +{
92.52 + private final ZipFileSystem.Entry e;
92.53 +
92.54 + ZipFileAttributes(ZipFileSystem.Entry e) {
92.55 + this.e = e;
92.56 + }
92.57 +
92.58 + ///////// basic attributes ///////////
92.59 + @Override
92.60 + public FileTime creationTime() {
92.61 + if (e.ctime != -1)
92.62 + return FileTime.fromMillis(dosToJavaTime(e.ctime));
92.63 + return null;
92.64 + }
92.65 +
92.66 + @Override
92.67 + public boolean isDirectory() {
92.68 + return e.isDir();
92.69 + }
92.70 +
92.71 + @Override
92.72 + public boolean isOther() {
92.73 + return false;
92.74 + }
92.75 +
92.76 + @Override
92.77 + public boolean isRegularFile() {
92.78 + return !e.isDir();
92.79 + }
92.80 +
92.81 + @Override
92.82 + public FileTime lastAccessTime() {
92.83 + if (e.atime != -1)
92.84 + return FileTime.fromMillis(dosToJavaTime(e.atime));
92.85 + return null;
92.86 + }
92.87 +
92.88 + @Override
92.89 + public FileTime lastModifiedTime() {
92.90 + return FileTime.fromMillis(dosToJavaTime(e.mtime));
92.91 + }
92.92 +
92.93 + @Override
92.94 + public long size() {
92.95 + return e.size;
92.96 + }
92.97 +
92.98 + @Override
92.99 + public boolean isSymbolicLink() {
92.100 + return false;
92.101 + }
92.102 +
92.103 + @Override
92.104 + public Object fileKey() {
92.105 + return null;
92.106 + }
92.107 +
92.108 + ///////// zip entry attributes ///////////
92.109 + public byte[] name() {
92.110 + return Arrays.copyOf(e.name, e.name.length);
92.111 + }
92.112 +
92.113 + public long compressedSize() {
92.114 + return e.csize;
92.115 + }
92.116 +
92.117 + public long crc() {
92.118 + return e.crc;
92.119 + }
92.120 +
92.121 + public int method() {
92.122 + return e.method;
92.123 + }
92.124 +
92.125 + public byte[] extra() {
92.126 + if (e.extra != null)
92.127 + return Arrays.copyOf(e.extra, e.extra.length);
92.128 + return null;
92.129 + }
92.130 +
92.131 + public byte[] comment() {
92.132 + if (e.comment != null)
92.133 + return Arrays.copyOf(e.comment, e.comment.length);
92.134 + return null;
92.135 + }
92.136 +
92.137 + public String toString() {
92.138 + StringBuilder sb = new StringBuilder();
92.139 + Formatter fm = new Formatter(sb);
92.140 + fm.format("[/%s]%n", new String(e.name)); // TBD encoding
92.141 + fm.format(" creationTime : %s%n", creationTime());
92.142 + if (lastAccessTime() != null)
92.143 + fm.format(" lastAccessTime : %tc%n", lastAccessTime().toMillis());
92.144 + else
92.145 + fm.format(" lastAccessTime : null%n");
92.146 + fm.format(" lastModifiedTime: %tc%n", lastModifiedTime().toMillis());
92.147 + fm.format(" isRegularFile : %b%n", isRegularFile());
92.148 + fm.format(" isDirectory : %b%n", isDirectory());
92.149 + fm.format(" isSymbolicLink : %b%n", isSymbolicLink());
92.150 + fm.format(" isOther : %b%n", isOther());
92.151 + fm.format(" fileKey : %s%n", fileKey());
92.152 + fm.format(" size : %d%n", size());
92.153 + fm.format(" compressedSize : %d%n", compressedSize());
92.154 + fm.format(" crc : %x%n", crc());
92.155 + fm.format(" method : %d%n", method());
92.156 + fm.close();
92.157 + return sb.toString();
92.158 + }
92.159 +}
93.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
93.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileStore.java Tue Oct 12 12:51:48 2010 -0700
93.3 @@ -0,0 +1,157 @@
93.4 +/*
93.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
93.6 + *
93.7 + * Redistribution and use in source and binary forms, with or without
93.8 + * modification, are permitted provided that the following conditions
93.9 + * are met:
93.10 + *
93.11 + * - Redistributions of source code must retain the above copyright
93.12 + * notice, this list of conditions and the following disclaimer.
93.13 + *
93.14 + * - Redistributions in binary form must reproduce the above copyright
93.15 + * notice, this list of conditions and the following disclaimer in the
93.16 + * documentation and/or other materials provided with the distribution.
93.17 + *
93.18 + * - Neither the name of Oracle nor the names of its
93.19 + * contributors may be used to endorse or promote products derived
93.20 + * from this software without specific prior written permission.
93.21 + *
93.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
93.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
93.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
93.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
93.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
93.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
93.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
93.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
93.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
93.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
93.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
93.33 + */
93.34 +
93.35 +package com.sun.nio.zipfs;
93.36 +
93.37 +import java.io.IOException;
93.38 +import java.nio.file.FileStore;
93.39 +import java.nio.file.FileSystems;
93.40 +import java.nio.file.Path;
93.41 +import java.nio.file.attribute.FileAttributeView;
93.42 +import java.nio.file.attribute.FileStoreAttributeView;
93.43 +import java.nio.file.attribute.FileStoreSpaceAttributeView;
93.44 +import java.nio.file.attribute.FileStoreSpaceAttributes;
93.45 +import java.nio.file.attribute.Attributes;
93.46 +import java.nio.file.attribute.BasicFileAttributeView;
93.47 +import java.util.Formatter;
93.48 +
93.49 +/*
93.50 + *
93.51 + * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
93.52 + */
93.53 +
93.54 +public class ZipFileStore extends FileStore {
93.55 +
93.56 + private final ZipFileSystem zfs;
93.57 +
93.58 + ZipFileStore(ZipPath zpath) {
93.59 + this.zfs = (ZipFileSystem)zpath.getFileSystem();
93.60 + }
93.61 +
93.62 + @Override
93.63 + public String name() {
93.64 + return zfs.toString() + "/";
93.65 + }
93.66 +
93.67 + @Override
93.68 + public String type() {
93.69 + return "zipfs";
93.70 + }
93.71 +
93.72 + @Override
93.73 + public boolean isReadOnly() {
93.74 + return zfs.isReadOnly();
93.75 + }
93.76 +
93.77 + @Override
93.78 + public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) {
93.79 + return (type == BasicFileAttributeView.class ||
93.80 + type == ZipFileAttributeView.class);
93.81 + }
93.82 +
93.83 + @Override
93.84 + public boolean supportsFileAttributeView(String name) {
93.85 + return name.equals("basic") || name.equals("zip");
93.86 + }
93.87 +
93.88 + @Override
93.89 + @SuppressWarnings("unchecked")
93.90 + public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> type) {
93.91 + if (type == null)
93.92 + throw new NullPointerException();
93.93 + if (type == FileStoreSpaceAttributeView.class)
93.94 + return (V) new ZipFileStoreAttributeView(this);
93.95 + return null;
93.96 + }
93.97 +
93.98 + @Override
93.99 + public Object getAttribute(String attribute) throws IOException {
93.100 + if (attribute.equals("space:totalSpace"))
93.101 + return new ZipFileStoreAttributeView(this).readAttributes().totalSpace();
93.102 + if (attribute.equals("space:usableSpace"))
93.103 + return new ZipFileStoreAttributeView(this).readAttributes().usableSpace();
93.104 + if (attribute.equals("space:unallocatedSpace"))
93.105 + return new ZipFileStoreAttributeView(this).readAttributes().unallocatedSpace();
93.106 + throw new UnsupportedOperationException("does not support the given attribute");
93.107 + }
93.108 +
93.109 + private static class ZipFileStoreAttributeView implements FileStoreSpaceAttributeView {
93.110 +
93.111 + private final ZipFileStore fileStore;
93.112 +
93.113 + public ZipFileStoreAttributeView(ZipFileStore fileStore) {
93.114 + this.fileStore = fileStore;
93.115 + }
93.116 +
93.117 + @Override
93.118 + public String name() {
93.119 + return "space";
93.120 + }
93.121 +
93.122 + @Override
93.123 + public FileStoreSpaceAttributes readAttributes() throws IOException {
93.124 + final String file = fileStore.name();
93.125 + Path path = FileSystems.getDefault().getPath(file);
93.126 + final long size = Attributes.readBasicFileAttributes(path).size();
93.127 + final FileStore fstore = path.getFileStore();
93.128 + final FileStoreSpaceAttributes fstoreAttrs =
93.129 + Attributes.readFileStoreSpaceAttributes(fstore);
93.130 + return new FileStoreSpaceAttributes() {
93.131 + public long totalSpace() {
93.132 + return size;
93.133 + }
93.134 +
93.135 + public long usableSpace() {
93.136 + if (!fstore.isReadOnly())
93.137 + return fstoreAttrs.usableSpace();
93.138 + return 0;
93.139 + }
93.140 +
93.141 + public long unallocatedSpace() {
93.142 + if (!fstore.isReadOnly())
93.143 + return fstoreAttrs.unallocatedSpace();
93.144 + return 0;
93.145 + }
93.146 +
93.147 + public String toString() {
93.148 + StringBuilder sb = new StringBuilder();
93.149 + Formatter fm = new Formatter(sb);
93.150 + fm.format("FileStoreSpaceAttributes[%s]%n", file);
93.151 + fm.format(" totalSpace: %d%n", totalSpace());
93.152 + fm.format(" usableSpace: %d%n", usableSpace());
93.153 + fm.format(" unallocSpace: %d%n", unallocatedSpace());
93.154 + fm.close();
93.155 + return sb.toString();
93.156 + }
93.157 + };
93.158 + }
93.159 + }
93.160 +}
94.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
94.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystem.java Tue Oct 12 12:51:48 2010 -0700
94.3 @@ -0,0 +1,2257 @@
94.4 +/*
94.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
94.6 + *
94.7 + * Redistribution and use in source and binary forms, with or without
94.8 + * modification, are permitted provided that the following conditions
94.9 + * are met:
94.10 + *
94.11 + * - Redistributions of source code must retain the above copyright
94.12 + * notice, this list of conditions and the following disclaimer.
94.13 + *
94.14 + * - Redistributions in binary form must reproduce the above copyright
94.15 + * notice, this list of conditions and the following disclaimer in the
94.16 + * documentation and/or other materials provided with the distribution.
94.17 + *
94.18 + * - Neither the name of Oracle nor the names of its
94.19 + * contributors may be used to endorse or promote products derived
94.20 + * from this software without specific prior written permission.
94.21 + *
94.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
94.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
94.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
94.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
94.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
94.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
94.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
94.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
94.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
94.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94.33 + */
94.34 +
94.35 +package com.sun.nio.zipfs;
94.36 +
94.37 +import java.io.ByteArrayInputStream;
94.38 +import java.io.ByteArrayOutputStream;
94.39 +import java.io.EOFException;
94.40 +import java.io.File;
94.41 +import java.io.FileInputStream;
94.42 +import java.io.IOException;
94.43 +import java.io.InputStream;
94.44 +import java.io.OutputStream;
94.45 +import java.nio.ByteBuffer;
94.46 +import java.nio.ByteOrder;
94.47 +import java.nio.MappedByteBuffer;
94.48 +import java.nio.channels.*;
94.49 +import java.nio.file.*;
94.50 +import java.nio.file.attribute.*;
94.51 +import java.nio.file.spi.*;
94.52 +import java.net.URI;
94.53 +import java.util.*;
94.54 +import java.util.regex.Pattern;
94.55 +import java.util.zip.CRC32;
94.56 +import java.util.zip.Inflater;
94.57 +import java.util.zip.Deflater;
94.58 +import java.util.zip.InflaterInputStream;
94.59 +import java.util.zip.DeflaterOutputStream;
94.60 +import java.util.zip.ZipException;
94.61 +import java.util.zip.ZipError;
94.62 +import static java.lang.Boolean.*;
94.63 +import static com.sun.nio.zipfs.ZipConstants.*;
94.64 +import static com.sun.nio.zipfs.ZipUtils.*;
94.65 +import static java.nio.file.StandardOpenOption.*;
94.66 +import static java.nio.file.StandardCopyOption.*;
94.67 +
94.68 +/**
94.69 + * A FileSystem built on a zip file
94.70 + *
94.71 + * @author Xueming Shen
94.72 + */
94.73 +
94.74 +public class ZipFileSystem extends FileSystem {
94.75 +
94.76 + private final ZipFileSystemProvider provider;
94.77 + private final ZipPath defaultdir;
94.78 + private boolean readOnly = false;
94.79 + private final Path zfpath;
94.80 + private final ZipCoder zc;
94.81 +
94.82 + private final Object lock = new Object();
94.83 +
94.84 + // configurable by env map
94.85 + private final String defaultDir; // default dir for the file system
94.86 + private final String nameEncoding; // default encoding for name/comment
94.87 + private final boolean buildDirTree; // build a dir tree for directoryStream ops
94.88 + private final boolean useTempFile; // use a temp file for newOS, default
94.89 + // is to use BAOS for better performance
94.90 + private final boolean createNew; // create a new zip if not exists
94.91 +
94.92 + ZipFileSystem(ZipFileSystemProvider provider,
94.93 + Path zfpath,
94.94 + Map<String, ?> env)
94.95 + throws IOException
94.96 + {
94.97 + // configurable env setup
94.98 + this.buildDirTree = TRUE.equals(env.get("buildDirTree"));
94.99 + this.useTempFile = TRUE.equals(env.get("useTempFile"));
94.100 + this.createNew = TRUE.equals(env.get("createNew"));
94.101 + this.nameEncoding = env.containsKey("nameEncoding") ?
94.102 + (String)env.get("nameEncoding") : "UTF-8";
94.103 + this.defaultDir = env.containsKey("default.dir") ?
94.104 + (String)env.get("default.dir") : "/";
94.105 + if (this.defaultDir.charAt(0) != '/')
94.106 + throw new IllegalArgumentException("default dir should be absolute");
94.107 +
94.108 + this.provider = provider;
94.109 + this.zfpath = zfpath;
94.110 + if (zfpath.notExists()) {
94.111 + if (createNew) {
94.112 + OutputStream os = zfpath.newOutputStream(CREATE_NEW, WRITE);
94.113 + new END().write(os, 0);
94.114 + os.close();
94.115 + } else {
94.116 + throw new FileSystemNotFoundException(zfpath.toString());
94.117 + }
94.118 + }
94.119 + zfpath.checkAccess(AccessMode.READ); // sm and existence check
94.120 + try {
94.121 + zfpath.checkAccess(AccessMode.WRITE);
94.122 + } catch (AccessDeniedException x) {
94.123 + this.readOnly = true;
94.124 + }
94.125 + this.zc = ZipCoder.get(nameEncoding);
94.126 + this.defaultdir = new ZipPath(this, getBytes(defaultDir));
94.127 + initZipFile();
94.128 + }
94.129 +
94.130 + @Override
94.131 + public FileSystemProvider provider() {
94.132 + return provider;
94.133 + }
94.134 +
94.135 + @Override
94.136 + public String getSeparator() {
94.137 + return "/";
94.138 + }
94.139 +
94.140 + @Override
94.141 + public boolean isOpen() {
94.142 + return isOpen;
94.143 + }
94.144 +
94.145 + @Override
94.146 + public boolean isReadOnly() {
94.147 + return readOnly;
94.148 + }
94.149 +
94.150 + private void checkWritable() throws IOException {
94.151 + if (readOnly)
94.152 + throw new ReadOnlyFileSystemException();
94.153 + }
94.154 +
94.155 + @Override
94.156 + public Iterable<Path> getRootDirectories() {
94.157 + ArrayList<Path> pathArr = new ArrayList<>();
94.158 + pathArr.add(new ZipPath(this, new byte[]{'/'}));
94.159 + return pathArr;
94.160 + }
94.161 +
94.162 + ZipPath getDefaultDir() { // package private
94.163 + return defaultdir;
94.164 + }
94.165 +
94.166 + @Override
94.167 + public ZipPath getPath(String path) {
94.168 + if (path.length() == 0)
94.169 + throw new InvalidPathException(path, "path should not be empty");
94.170 + return new ZipPath(this, getBytes(path));
94.171 + }
94.172 +
94.173 + @Override
94.174 + public UserPrincipalLookupService getUserPrincipalLookupService() {
94.175 + throw new UnsupportedOperationException();
94.176 + }
94.177 +
94.178 + @Override
94.179 + public WatchService newWatchService() {
94.180 + throw new UnsupportedOperationException();
94.181 + }
94.182 +
94.183 + FileStore getFileStore(ZipPath path) {
94.184 + return new ZipFileStore(path);
94.185 + }
94.186 +
94.187 + @Override
94.188 + public Iterable<FileStore> getFileStores() {
94.189 + ArrayList<FileStore> list = new ArrayList<FileStore>(1);
94.190 + list.add(new ZipFileStore(new ZipPath(this, new byte[]{'/'})));
94.191 + return list;
94.192 + }
94.193 +
94.194 + private static final Set<String> supportedFileAttributeViews =
94.195 + Collections.unmodifiableSet(
94.196 + new HashSet<String>(Arrays.asList("basic", "zip")));
94.197 +
94.198 + @Override
94.199 + public Set<String> supportedFileAttributeViews() {
94.200 + return supportedFileAttributeViews;
94.201 + }
94.202 +
94.203 + @Override
94.204 + public String toString() {
94.205 + return zfpath.toString();
94.206 + }
94.207 +
94.208 + Path getZipFile() {
94.209 + return zfpath;
94.210 + }
94.211 +
94.212 + private static final String GLOB_SYNTAX = "glob";
94.213 + private static final String REGEX_SYNTAX = "regex";
94.214 +
94.215 + @Override
94.216 + public PathMatcher getPathMatcher(String syntaxAndInput) {
94.217 + int pos = syntaxAndInput.indexOf(':');
94.218 + if (pos <= 0 || pos == syntaxAndInput.length()) {
94.219 + throw new IllegalArgumentException();
94.220 + }
94.221 + String syntax = syntaxAndInput.substring(0, pos);
94.222 + String input = syntaxAndInput.substring(pos + 1);
94.223 + String expr;
94.224 + if (syntax.equals(GLOB_SYNTAX)) {
94.225 + expr = toRegexPattern(input);
94.226 + } else {
94.227 + if (syntax.equals(REGEX_SYNTAX)) {
94.228 + expr = input;
94.229 + } else {
94.230 + throw new UnsupportedOperationException("Syntax '" + syntax +
94.231 + "' not recognized");
94.232 + }
94.233 + }
94.234 + // return matcher
94.235 + final Pattern pattern = Pattern.compile(expr);
94.236 + return new PathMatcher() {
94.237 + @Override
94.238 + public boolean matches(Path path) {
94.239 + return pattern.matcher(path.toString()).matches();
94.240 + }
94.241 + };
94.242 + }
94.243 +
94.244 + @Override
94.245 + public void close() throws IOException {
94.246 + synchronized (lock) {
94.247 + if (!isOpen)
94.248 + return;
94.249 + isOpen = false;
94.250 + if (!streams.isEmpty()) {
94.251 + synchronized(streams) {
94.252 + for (InputStream is: streams)
94.253 + is.close();
94.254 + }
94.255 + }
94.256 + sync();
94.257 + ch.close();
94.258 + }
94.259 + synchronized (inflaters) {
94.260 + for (Inflater inf : inflaters)
94.261 + inf.end();
94.262 + }
94.263 + synchronized (deflaters) {
94.264 + for (Deflater def : deflaters)
94.265 + def.end();
94.266 + }
94.267 + for (Path p: tmppaths) {
94.268 + try {
94.269 + p.deleteIfExists();
94.270 + } catch (IOException x) {
94.271 + x.printStackTrace();
94.272 + }
94.273 + }
94.274 + provider.removeFileSystem(zfpath);
94.275 + }
94.276 +
94.277 + ZipFileAttributes[] getAllAttributes() throws IOException {
94.278 + ensureOpen();
94.279 + int n = inodes.size();
94.280 + ZipFileAttributes[] zes = new ZipFileAttributes[n];
94.281 + Iterator<IndexNode> itr = inodes.values().iterator();
94.282 + int i = 0;
94.283 + while(itr.hasNext()) {
94.284 + zes[i++] = new ZipFileAttributes(Entry.readCEN(cen, itr.next().pos));
94.285 + }
94.286 + return zes;
94.287 + }
94.288 +
94.289 + EntryName[] getEntryNames() throws IOException {
94.290 + ensureOpen();
94.291 + return inodes.keySet().toArray(new EntryName[0]);
94.292 + }
94.293 +
94.294 + ZipFileAttributes getFileAttributes(byte[] path)
94.295 + throws IOException
94.296 + {
94.297 + synchronized (lock) {
94.298 + Entry e = getEntry0(path);
94.299 + if (e == null) {
94.300 + if (path.length == 0) {
94.301 + e = new Entry(new byte[0]); // root
94.302 + } else if (buildDirTree) {
94.303 + IndexNode inode = getDirs().get(new EntryName(path));
94.304 + if (inode == null)
94.305 + return null;
94.306 + e = new Entry(inode.name);
94.307 + } else {
94.308 + return null;
94.309 + }
94.310 + e.method = METHOD_STORED; // STORED for dir
94.311 + BasicFileAttributes bfas = Attributes.readBasicFileAttributes(zfpath);
94.312 + if (bfas.lastModifiedTime() != null)
94.313 + e.mtime = javaToDosTime(bfas.lastModifiedTime().toMillis());
94.314 + if (bfas.lastAccessTime() != null)
94.315 + e.atime = javaToDosTime(bfas.lastAccessTime().toMillis());
94.316 + if (bfas.creationTime() != null)
94.317 + e.ctime = javaToDosTime(bfas.creationTime().toMillis());
94.318 + }
94.319 + return new ZipFileAttributes(e);
94.320 + }
94.321 + }
94.322 +
94.323 + void setTimes(byte[] path, FileTime mtime, FileTime atime, FileTime ctime)
94.324 + throws IOException
94.325 + {
94.326 + checkWritable();
94.327 + synchronized (lock) {
94.328 + Entry e = getEntry0(path); // ensureOpen checked
94.329 + if (e == null)
94.330 + throw new NoSuchFileException(getString(path));
94.331 + if (e.type == Entry.CEN)
94.332 + e.type = Entry.COPY; // copy e
94.333 + if (mtime != null)
94.334 + e.mtime = javaToDosTime(mtime.toMillis());
94.335 + if (atime != null)
94.336 + e.atime = javaToDosTime(atime.toMillis());
94.337 + if (ctime != null)
94.338 + e.ctime = javaToDosTime(ctime.toMillis());
94.339 + update(e);
94.340 + }
94.341 + }
94.342 +
94.343 + boolean exists(byte[] path)
94.344 + throws IOException
94.345 + {
94.346 + return getEntry0(path) != null;
94.347 + }
94.348 +
94.349 + boolean isDirectory(byte[] path)
94.350 + throws IOException
94.351 + {
94.352 + synchronized (lock) {
94.353 + if (buildDirTree) {
94.354 + return getDirs().containsKey(new EntryName(path));
94.355 + }
94.356 + Entry e = getEntry0(path);
94.357 + return (e != null && e.isDir()) || path.length == 0;
94.358 + }
94.359 + }
94.360 +
94.361 + private ZipPath toZipPath(byte[] path) {
94.362 + // make it absolute
94.363 + byte[] p = new byte[path.length + 1];
94.364 + p[0] = '/';
94.365 + System.arraycopy(path, 0, p, 1, path.length);
94.366 + return new ZipPath(this, p);
94.367 + }
94.368 +
94.369 + // returns the list of child paths of "path"
94.370 + Iterator<Path> iteratorOf(byte[] path,
94.371 + DirectoryStream.Filter<? super Path> filter)
94.372 + throws IOException
94.373 + {
94.374 + synchronized (lock) {
94.375 + if (buildDirTree) {
94.376 + IndexNode inode = getDirs().get(new EntryName(path));
94.377 + if (inode == null)
94.378 + throw new NotDirectoryException(getString(path));
94.379 + List<Path> list = new ArrayList<Path>();
94.380 + IndexNode child = inode.child;
94.381 + while (child != null) {
94.382 + ZipPath zp = toZipPath(child.name);
94.383 + if (filter == null || filter.accept(zp))
94.384 + list.add(zp);
94.385 + child = child.sibling;
94.386 + }
94.387 + return list.iterator();
94.388 + }
94.389 +
94.390 + if (!isDirectory(path))
94.391 + throw new NotDirectoryException(getString(path));
94.392 + List<Path> list = new ArrayList<Path>();
94.393 + EntryName[] entries = getEntryNames();
94.394 + path = toDirectoryPath(path);
94.395 + for (EntryName en :entries) {
94.396 + if (!isParentOf(path, en.name)) // is "path" the parent of "name"
94.397 + continue;
94.398 + int off = path.length;
94.399 + while (off < en.name.length) {
94.400 + if (en.name[off] == '/')
94.401 + break;
94.402 + off++;
94.403 + }
94.404 + if (off < (en.name.length - 1))
94.405 + continue;
94.406 + ZipPath zp = toZipPath(en.name);
94.407 + if (filter == null || filter.accept(zp))
94.408 + list.add(zp);
94.409 + }
94.410 + return list.iterator();
94.411 + }
94.412 + }
94.413 +
94.414 + void createDirectory(byte[] dir, FileAttribute<?>... attrs)
94.415 + throws IOException
94.416 + {
94.417 + checkWritable();
94.418 + dir = toDirectoryPath(dir);
94.419 + synchronized (lock) {
94.420 + ensureOpen();
94.421 + // pseudo root dir, or exiting dir
94.422 + if (dir.length == 0 || exists(dir))
94.423 + throw new FileAlreadyExistsException(getString(dir));
94.424 + checkParents(dir);
94.425 +
94.426 + Entry e = new Entry(dir, Entry.NEW);
94.427 + e.method = METHOD_STORED; // STORED for dir
94.428 + update(e);
94.429 + }
94.430 + }
94.431 +
94.432 + void copyFile(boolean deletesrc, byte[]src, byte[] dst, CopyOption... options)
94.433 + throws IOException
94.434 + {
94.435 + checkWritable();
94.436 + if (Arrays.equals(src, dst))
94.437 + return; // do nothing, src and dst are the same
94.438 + synchronized (lock) {
94.439 + Entry eSrc = getEntry0(src); // ensureOpen checked
94.440 + if (eSrc == null)
94.441 + throw new NoSuchFileException(getString(src));
94.442 + if (eSrc.isDir()) { // spec says to create dst dir
94.443 + createDirectory(dst);
94.444 + return;
94.445 + }
94.446 + boolean hasReplace = false;
94.447 + boolean hasCopyAttrs = false;
94.448 + for (CopyOption opt : options) {
94.449 + if (opt == REPLACE_EXISTING)
94.450 + hasReplace = true;
94.451 + else if (opt == COPY_ATTRIBUTES)
94.452 + hasCopyAttrs = true;
94.453 + }
94.454 + Entry eDst = getEntry0(dst);
94.455 + if (eDst != null) {
94.456 + if (!hasReplace)
94.457 + throw new FileAlreadyExistsException(getString(dst));
94.458 + } else {
94.459 + checkParents(dst);
94.460 + }
94.461 + Entry u = new Entry(eSrc, Entry.COPY); // copy eSrc entry
94.462 + u.name = dst; // change name
94.463 + // don't touch the "nlen and elen" here. writeLOC() always
94.464 + // re-calculate from "name" and "extra" for the correct length,
94.465 + // copyLOCEntry however needs the original lengths to skip the
94.466 + // loc header.
94.467 + // u.nlen = dst.length;
94.468 + if (eSrc.type == Entry.NEW || eSrc.type == Entry.FILECH)
94.469 + {
94.470 + u.type = eSrc.type; // make it the same type
94.471 + if (!deletesrc) { // if it's not "rename", just take the data
94.472 + if (eSrc.bytes != null)
94.473 + u.bytes = Arrays.copyOf(eSrc.bytes, eSrc.bytes.length);
94.474 + else if (eSrc.file != null) {
94.475 + u.file = getTempPathForEntry(null);
94.476 + eSrc.file.copyTo(u.file, REPLACE_EXISTING);
94.477 + }
94.478 + }
94.479 + }
94.480 + if (!hasCopyAttrs)
94.481 + u.mtime = u.atime= u.ctime = javaToDosTime(System.currentTimeMillis());
94.482 + update(u);
94.483 + if (deletesrc)
94.484 + updateDelete(eSrc);
94.485 + }
94.486 + }
94.487 +
94.488 + // Returns an output stream for writing the contents into the specified
94.489 + // entry.
94.490 + OutputStream newOutputStream(byte[] path, OpenOption... options)
94.491 + throws IOException
94.492 + {
94.493 + checkWritable();
94.494 + boolean hasCreateNew = false;
94.495 + boolean hasCreate = false;
94.496 + boolean hasAppend = false;
94.497 + for (OpenOption opt: options) {
94.498 + if (opt == READ)
94.499 + throw new IllegalArgumentException("READ not allowed");
94.500 + if (opt == CREATE_NEW)
94.501 + hasCreateNew = true;
94.502 + if (opt == CREATE)
94.503 + hasCreate = true;
94.504 + if (opt == APPEND)
94.505 + hasAppend = true;
94.506 + }
94.507 + synchronized (lock) {
94.508 + Entry e = getEntry0(path);
94.509 + if (e != null) {
94.510 + if (e.isDir() || hasCreateNew)
94.511 + throw new FileAlreadyExistsException(getString(path));
94.512 + if (hasAppend) {
94.513 + InputStream is = getInputStream(e);
94.514 + OutputStream os = getOutputStream(new Entry(e, Entry.NEW));
94.515 + copyStream(is, os);
94.516 + is.close();
94.517 + return os;
94.518 + }
94.519 + return getOutputStream(new Entry(e, Entry.NEW));
94.520 + } else {
94.521 + if (!hasCreate && !hasCreateNew)
94.522 + throw new NoSuchFileException(getString(path));
94.523 + checkParents(path);
94.524 + return getOutputStream(new Entry(path, Entry.NEW));
94.525 + }
94.526 + }
94.527 + }
94.528 +
94.529 + // Returns an input stream for reading the contents of the specified
94.530 + // file entry.
94.531 + InputStream newInputStream(byte[] path) throws IOException {
94.532 + synchronized (lock) {
94.533 + Entry e = getEntry0(path);
94.534 + if (e == null)
94.535 + throw new NoSuchFileException(getString(path));
94.536 + if (e.isDir())
94.537 + throw new FileSystemException(getString(path), "is a directory", null);
94.538 + return getInputStream(e);
94.539 + }
94.540 + }
94.541 +
94.542 + private void checkOptions(Set<? extends OpenOption> options) {
94.543 + // check for options of null type and option is an intance of StandardOpenOption
94.544 + for (OpenOption option : options) {
94.545 + if (option == null)
94.546 + throw new NullPointerException();
94.547 + if (!(option instanceof StandardOpenOption))
94.548 + throw new IllegalArgumentException();
94.549 + }
94.550 + }
94.551 +
94.552 + // Returns a Writable/ReadByteChannel for now. Might consdier to use
94.553 + // newFileChannel() instead, which dump the entry data into a regular
94.554 + // file on the default file system and create a FileChannel on top of
94.555 + // it.
94.556 + SeekableByteChannel newByteChannel(byte[] path,
94.557 + Set<? extends OpenOption> options,
94.558 + FileAttribute<?>... attrs)
94.559 + throws IOException
94.560 + {
94.561 + checkOptions(options);
94.562 + if (options.contains(StandardOpenOption.WRITE) ||
94.563 + options.contains(StandardOpenOption.APPEND)) {
94.564 + checkWritable();
94.565 + final WritableByteChannel wbc = Channels.newChannel(newOutputStream(path,
94.566 + options.toArray(new OpenOption[0])));
94.567 + long leftover = 0;;
94.568 + if (options.contains(StandardOpenOption.APPEND)) {
94.569 + Entry e = getEntry0(path);
94.570 + if (e != null && e.size >= 0)
94.571 + leftover = e.size;
94.572 + }
94.573 + final long offset = leftover;
94.574 + return new SeekableByteChannel() {
94.575 + long written = offset;
94.576 + public boolean isOpen() {
94.577 + return wbc.isOpen();
94.578 + }
94.579 + public long position() throws IOException {
94.580 + return written;
94.581 + }
94.582 + public SeekableByteChannel position(long pos) throws IOException {
94.583 + throw new UnsupportedOperationException();
94.584 + }
94.585 + public int read(ByteBuffer dst) throws IOException {
94.586 + throw new UnsupportedOperationException();
94.587 + }
94.588 + public SeekableByteChannel truncate(long size) throws IOException {
94.589 + throw new UnsupportedOperationException();
94.590 + }
94.591 + public int write(ByteBuffer src) throws IOException {
94.592 + int n = wbc.write(src);
94.593 + written += n;
94.594 + return n;
94.595 + }
94.596 + public long size() throws IOException {
94.597 + return written;
94.598 + }
94.599 + public void close() throws IOException {
94.600 + wbc.close();
94.601 + }
94.602 + };
94.603 + } else {
94.604 + Entry e = getEntry0(path);
94.605 + if (e == null || e.isDir())
94.606 + throw new NoSuchFileException(getString(path));
94.607 + final ReadableByteChannel rbc =
94.608 + Channels.newChannel(getInputStream(e));
94.609 + final long size = e.size;
94.610 + return new SeekableByteChannel() {
94.611 + long read = 0;
94.612 + public boolean isOpen() {
94.613 + return rbc.isOpen();
94.614 + }
94.615 + public long position() throws IOException {
94.616 + return read;
94.617 + }
94.618 + public SeekableByteChannel position(long pos) throws IOException {
94.619 + throw new UnsupportedOperationException();
94.620 + }
94.621 + public int read(ByteBuffer dst) throws IOException {
94.622 + return rbc.read(dst);
94.623 + }
94.624 + public SeekableByteChannel truncate(long size) throws IOException {
94.625 + throw new NonWritableChannelException();
94.626 + }
94.627 + public int write (ByteBuffer src) throws IOException {
94.628 + throw new NonWritableChannelException();
94.629 + }
94.630 + public long size() throws IOException {
94.631 + return size;
94.632 + }
94.633 + public void close() throws IOException {
94.634 + rbc.close();
94.635 + }
94.636 + };
94.637 + }
94.638 + }
94.639 +
94.640 + // Returns a FileChannel of the specified entry.
94.641 + //
94.642 + // This implementation creates a temporary file on the default file system,
94.643 + // copy the entry data into it if the entry exists, and then create a
94.644 + // FileChannel on top of it.
94.645 + FileChannel newFileChannel(byte[] path,
94.646 + Set<? extends OpenOption> options,
94.647 + FileAttribute<?>... attrs)
94.648 + throws IOException
94.649 + {
94.650 + checkOptions(options);
94.651 + final boolean forWrite = (options.contains(StandardOpenOption.WRITE) ||
94.652 + options.contains(StandardOpenOption.APPEND));
94.653 + Entry e = getEntry0(path);
94.654 + if (forWrite) {
94.655 + checkWritable();
94.656 + if (e == null) {
94.657 + if (!options.contains(StandardOpenOption.CREATE_NEW))
94.658 + throw new NoSuchFileException(getString(path));
94.659 + } else {
94.660 + if (options.contains(StandardOpenOption.CREATE_NEW))
94.661 + throw new FileAlreadyExistsException(getString(path));
94.662 + if (e.isDir())
94.663 + throw new FileAlreadyExistsException("directory <"
94.664 + + getString(path) + "> exists");
94.665 + }
94.666 + options.remove(StandardOpenOption.CREATE_NEW); // for tmpfile
94.667 + } else if (e == null || e.isDir()) {
94.668 + throw new NoSuchFileException(getString(path));
94.669 + }
94.670 +
94.671 + final boolean isFCH = (e != null && e.type == Entry.FILECH);
94.672 + final Path tmpfile = isFCH ? e.file : getTempPathForEntry(path);
94.673 + final FileChannel fch = tmpfile.getFileSystem()
94.674 + .provider()
94.675 + .newFileChannel(tmpfile, options, attrs);
94.676 + final Entry u = isFCH ? e : new Entry(path, tmpfile, Entry.FILECH);
94.677 + if (forWrite) {
94.678 + u.flag = FLAG_DATADESCR;
94.679 + u.method = METHOD_DEFLATED;
94.680 + }
94.681 + // is there a better way to hook into the FileChannel's close method?
94.682 + return new FileChannel() {
94.683 + public int write(ByteBuffer src) throws IOException {
94.684 + return fch.write(src);
94.685 + }
94.686 + public long write(ByteBuffer[] srcs, int offset, int length)
94.687 + throws IOException
94.688 + {
94.689 + return fch.write(srcs, offset, length);
94.690 + }
94.691 + public long position() throws IOException {
94.692 + return fch.position();
94.693 + }
94.694 + public FileChannel position(long newPosition)
94.695 + throws IOException
94.696 + {
94.697 + fch.position(newPosition);
94.698 + return this;
94.699 + }
94.700 + public long size() throws IOException {
94.701 + return fch.size();
94.702 + }
94.703 + public FileChannel truncate(long size)
94.704 + throws IOException
94.705 + {
94.706 + fch.truncate(size);
94.707 + return this;
94.708 + }
94.709 + public void force(boolean metaData)
94.710 + throws IOException
94.711 + {
94.712 + fch.force(metaData);
94.713 + }
94.714 + public long transferTo(long position, long count,
94.715 + WritableByteChannel target)
94.716 + throws IOException
94.717 + {
94.718 + return fch.transferTo(position, count, target);
94.719 + }
94.720 + public long transferFrom(ReadableByteChannel src,
94.721 + long position, long count)
94.722 + throws IOException
94.723 + {
94.724 + return fch.transferFrom(src, position, count);
94.725 + }
94.726 + public int read(ByteBuffer dst) throws IOException {
94.727 + return fch.read(dst);
94.728 + }
94.729 + public int read(ByteBuffer dst, long position)
94.730 + throws IOException
94.731 + {
94.732 + return fch.read(dst, position);
94.733 + }
94.734 + public long read(ByteBuffer[] dsts, int offset, int length)
94.735 + throws IOException
94.736 + {
94.737 + return fch.read(dsts, offset, length);
94.738 + }
94.739 + public int write(ByteBuffer src, long position)
94.740 + throws IOException
94.741 + {
94.742 + return fch.write(src, position);
94.743 + }
94.744 + public MappedByteBuffer map(MapMode mode,
94.745 + long position, long size)
94.746 + throws IOException
94.747 + {
94.748 + throw new UnsupportedOperationException();
94.749 + }
94.750 + public FileLock lock(long position, long size, boolean shared)
94.751 + throws IOException
94.752 + {
94.753 + return fch.lock(position, size, shared);
94.754 + }
94.755 + public FileLock tryLock(long position, long size, boolean shared)
94.756 + throws IOException
94.757 + {
94.758 + return fch.tryLock(position, size, shared);
94.759 + }
94.760 + protected void implCloseChannel() throws IOException {
94.761 + fch.close();
94.762 + if (forWrite) {
94.763 + u.mtime = javaToDosTime(System.currentTimeMillis());
94.764 + u.size = Attributes.readBasicFileAttributes(u.file).size();
94.765 + update(u);
94.766 + } else {
94.767 + if (!isFCH) // if this is a new fch for reading
94.768 + removeTempPathForEntry(tmpfile);
94.769 + }
94.770 + }
94.771 + };
94.772 + }
94.773 +
94.774 + // the outstanding input streams that need to be closed
94.775 + private Set<InputStream> streams =
94.776 + Collections.synchronizedSet(new HashSet<InputStream>());
94.777 +
94.778 + // the ex-channel and ex-path that need to close when their outstanding
94.779 + // input streams are all closed by the obtainers.
94.780 + private Set<ExChannelCloser> exChClosers = new HashSet<>();
94.781 +
94.782 + private Set<Path> tmppaths = new HashSet<>();
94.783 + private Path getTempPathForEntry(byte[] path) throws IOException {
94.784 + Path tmpPath = createTempFileInSameDirectoryAs(zfpath);
94.785 + tmppaths.add(tmpPath);
94.786 +
94.787 + if (path != null) {
94.788 + Entry e = getEntry0(path);
94.789 + if (e != null) {
94.790 + InputStream is = newInputStream(path);
94.791 + OutputStream os = tmpPath.newOutputStream(WRITE);
94.792 + try {
94.793 + copyStream(is, os);
94.794 + } finally {
94.795 + is.close();
94.796 + os.close();
94.797 + }
94.798 + }
94.799 + }
94.800 + return tmpPath;
94.801 + }
94.802 +
94.803 + private void removeTempPathForEntry(Path path) throws IOException {
94.804 + path.delete();
94.805 + tmppaths.remove(path);
94.806 + }
94.807 +
94.808 + // check if all parents really exit. ZIP spec does not require
94.809 + // the existence of any "parent directory".
94.810 + private void checkParents(byte[] path) throws IOException {
94.811 + while ((path = getParent(path)) != null) {
94.812 + if (!inodes.containsKey(new EntryName(path)))
94.813 + throw new NoSuchFileException(getString(path));
94.814 + }
94.815 + }
94.816 +
94.817 + private static byte[] getParent(byte[] path) {
94.818 + int off = path.length - 1;
94.819 + if (off > 0 && path[off] == '/') // isDirectory
94.820 + off--;
94.821 + while (off > 0 && path[off] != '/') { off--; }
94.822 + if (off == 0)
94.823 + return null; // top entry
94.824 + return Arrays.copyOf(path, off + 1);
94.825 + }
94.826 +
94.827 + // If "starter" is the parent directory of "path"
94.828 + private static boolean isParentOf(byte[] p, byte[] c) {
94.829 + final int plen = p.length;
94.830 + if (plen == 0) // root dir
94.831 + return true;
94.832 + if (plen >= c.length)
94.833 + return false;
94.834 + int n = 0;
94.835 + while (n < plen) {
94.836 + if (p[n] != c[n])
94.837 + return false;
94.838 + n++;
94.839 + }
94.840 + if (p[n - 1] != '/' && (c[n] != '/' || n == c.length - 1))
94.841 + return false;
94.842 + return true;
94.843 + }
94.844 +
94.845 + ///////////////////////////////////////////////////////////////////
94.846 + private void initZipFile() throws IOException {
94.847 + ch = zfpath.newByteChannel(READ);
94.848 + initCEN();
94.849 + }
94.850 +
94.851 + private volatile boolean isOpen = true;
94.852 + private SeekableByteChannel ch; // channel to the zipfile
94.853 + ByteBuffer cen; // CEN & ENDHDR
94.854 + private END end;
94.855 + private long locpos; // position of first LOC header (usually 0)
94.856 +
94.857 + // name -> pos (in cen), package private for ZipInfo
94.858 + LinkedHashMap<EntryName, IndexNode> inodes;
94.859 +
94.860 + byte[] getBytes(String name) {
94.861 + return zc.getBytes(name);
94.862 + }
94.863 + String getString(byte[] name) {
94.864 + return zc.toString(name);
94.865 + }
94.866 +
94.867 + protected void finalize() throws IOException {
94.868 + close();
94.869 + }
94.870 +
94.871 + private long getDataPos(Entry e) throws IOException {
94.872 + if (e.locoff == -1) {
94.873 + Entry e2 = getEntry0(e.name);
94.874 + if (e2 == null)
94.875 + throw new ZipException("invalid loc for entry <" + e.name + ">");
94.876 + e.locoff = e2.locoff;
94.877 + }
94.878 + byte[] buf = new byte[LOCHDR];
94.879 + if (readFullyAt(buf, 0, buf.length, e.locoff) != buf.length)
94.880 + throw new ZipException("invalid loc for entry <" + e.name + ">");
94.881 + return locpos + e.locoff + LOCHDR + LOCNAM(buf) + LOCEXT(buf);
94.882 + }
94.883 +
94.884 + // Reads len bytes of data from the specified offset into buf.
94.885 + // Returns the total number of bytes read.
94.886 + // Each/every byte read from here (except the cen, which is mapped).
94.887 + private long readFullyAt(byte[] buf, int off, long len, long pos)
94.888 + throws IOException
94.889 + {
94.890 + ByteBuffer bb = ByteBuffer.wrap(buf);
94.891 + bb.position(off);
94.892 + bb.limit((int)(off + len));
94.893 + return readFullyAt(bb, pos);
94.894 + }
94.895 +
94.896 + private long readFullyAt(ByteBuffer bb, long pos)
94.897 + throws IOException
94.898 + {
94.899 + synchronized(ch) {
94.900 + return ch.position(pos).read(bb);
94.901 + }
94.902 + }
94.903 +
94.904 + // Searches for end of central directory (END) header. The contents of
94.905 + // the END header will be read and placed in endbuf. Returns the file
94.906 + // position of the END header, otherwise returns -1 if the END header
94.907 + // was not found or an error occurred.
94.908 + private END findEND() throws IOException
94.909 + {
94.910 + byte[] buf = new byte[READBLOCKSZ];
94.911 + long ziplen = ch.size();
94.912 + long minHDR = (ziplen - END_MAXLEN) > 0 ? ziplen - END_MAXLEN : 0;
94.913 + long minPos = minHDR - (buf.length - ENDHDR);
94.914 +
94.915 + for (long pos = ziplen - buf.length; pos >= minPos; pos -= (buf.length - ENDHDR))
94.916 + {
94.917 + int off = 0;
94.918 + if (pos < 0) {
94.919 + // Pretend there are some NUL bytes before start of file
94.920 + off = (int)-pos;
94.921 + Arrays.fill(buf, 0, off, (byte)0);
94.922 + }
94.923 + int len = buf.length - off;
94.924 + if (readFullyAt(buf, off, len, pos + off) != len)
94.925 + zerror("zip END header not found");
94.926 +
94.927 + // Now scan the block backwards for END header signature
94.928 + for (int i = buf.length - ENDHDR; i >= 0; i--) {
94.929 + if (buf[i+0] == (byte)'P' &&
94.930 + buf[i+1] == (byte)'K' &&
94.931 + buf[i+2] == (byte)'\005' &&
94.932 + buf[i+3] == (byte)'\006' &&
94.933 + (pos + i + ENDHDR + ENDCOM(buf, i) == ziplen)) {
94.934 + // Found END header
94.935 + buf = Arrays.copyOfRange(buf, i, i + ENDHDR);
94.936 + END end = new END();
94.937 + end.endsub = ENDSUB(buf);
94.938 + end.centot = ENDTOT(buf);
94.939 + end.cenlen = ENDSIZ(buf);
94.940 + end.cenoff = ENDOFF(buf);
94.941 + end.comlen = ENDCOM(buf);
94.942 + end.endpos = pos + i;
94.943 + if (end.cenlen == ZIP64_MINVAL ||
94.944 + end.cenoff == ZIP64_MINVAL ||
94.945 + end.centot == ZIP64_MINVAL32)
94.946 + {
94.947 + // need to find the zip64 end;
94.948 + byte[] loc64 = new byte[ZIP64_LOCHDR];
94.949 + if (readFullyAt(loc64, 0, loc64.length, end.endpos - ZIP64_LOCHDR)
94.950 + != loc64.length) {
94.951 + return end;
94.952 + }
94.953 + long end64pos = ZIP64_LOCOFF(loc64);
94.954 + byte[] end64buf = new byte[ZIP64_ENDHDR];
94.955 + if (readFullyAt(end64buf, 0, end64buf.length, end64pos)
94.956 + != end64buf.length) {
94.957 + return end;
94.958 + }
94.959 + // end64 found, re-calcualte everything.
94.960 + end.cenlen = ZIP64_ENDSIZ(end64buf);
94.961 + end.cenoff = ZIP64_ENDOFF(end64buf);
94.962 + end.centot = (int)ZIP64_ENDTOT(end64buf); // assume total < 2g
94.963 + end.endpos = end64pos;
94.964 + }
94.965 + return end;
94.966 + }
94.967 + }
94.968 + }
94.969 + zerror("zip END header not found");
94.970 + return null; //make compiler happy
94.971 + }
94.972 +
94.973 + // Reads zip file central directory. Returns the file position of first
94.974 + // CEN header, otherwise returns -1 if an error occured. If zip->msg != NULL
94.975 + // then the error was a zip format error and zip->msg has the error text.
94.976 + // Always pass in -1 for knownTotal; it's used for a recursive call.
94.977 + private long initCEN() throws IOException {
94.978 + end = findEND();
94.979 + if (end.endpos == 0) {
94.980 + inodes = new LinkedHashMap<EntryName, IndexNode>(10);
94.981 + locpos = 0;
94.982 + return 0; // only END header present
94.983 + }
94.984 + if (end.cenlen > end.endpos)
94.985 + zerror("invalid END header (bad central directory size)");
94.986 + long cenpos = end.endpos - end.cenlen; // position of CEN table
94.987 +
94.988 + // Get position of first local file (LOC) header, taking into
94.989 + // account that there may be a stub prefixed to the zip file.
94.990 + locpos = cenpos - end.cenoff;
94.991 + if (locpos < 0)
94.992 + zerror("invalid END header (bad central directory offset)");
94.993 +
94.994 + // read in the CEN and END
94.995 + cen = ByteBuffer.allocate((int)(end.cenlen + ENDHDR));
94.996 + if (readFullyAt(cen, cenpos) != end.cenlen + ENDHDR) {
94.997 + zerror("read CEN tables failed");
94.998 + }
94.999 + cen.order(ByteOrder.LITTLE_ENDIAN).flip();
94.1000 +
94.1001 + // Iterate through the entries in the central directory
94.1002 + inodes = new LinkedHashMap<EntryName, IndexNode>(end.centot + 1);
94.1003 + int pos = 0;
94.1004 + int limit = cen.remaining() - ENDHDR;
94.1005 + int i = 0;
94.1006 + byte[] bBuf = new byte[1024];
94.1007 + while (pos < limit) {
94.1008 + if (CENSIG(cen, pos) != CENSIG)
94.1009 + zerror("invalid CEN header (bad signature)");
94.1010 + int method = CENHOW(cen, pos);
94.1011 + int nlen = CENNAM(cen, pos);
94.1012 + int elen = CENEXT(cen, pos);
94.1013 + int clen = CENCOM(cen, pos);
94.1014 + if ((CENFLG(cen, pos) & 1) != 0)
94.1015 + zerror("invalid CEN header (encrypted entry)");
94.1016 + if (method != METHOD_STORED && method != METHOD_DEFLATED)
94.1017 + zerror("invalid CEN header (bad compression method: " + method + ")");
94.1018 + if (pos + CENHDR + nlen > limit)
94.1019 + zerror("invalid CEN header (bad header size)");
94.1020 + if (bBuf.length < nlen)
94.1021 + bBuf = new byte[nlen];
94.1022 + cen.position(pos + CENHDR);
94.1023 + byte[] name = new byte[nlen];
94.1024 + cen.get(name);
94.1025 + inodes.put(new EntryName(name), new IndexNode(name, pos));
94.1026 + // skip ext and comment
94.1027 + cen.position(pos += (CENHDR + nlen + elen + clen));
94.1028 + i++;
94.1029 + }
94.1030 + if (cen.remaining() != ENDHDR) {
94.1031 + zerror("invalid CEN header (bad header size)");
94.1032 + }
94.1033 + dirs = null; // clear the dir map
94.1034 + return cenpos;
94.1035 + }
94.1036 +
94.1037 + private void ensureOpen() throws IOException {
94.1038 + if (!isOpen)
94.1039 + throw new ClosedFileSystemException();
94.1040 + }
94.1041 +
94.1042 + // Creates a new empty temporary file in the same directory as the
94.1043 + // specified file. A variant of File.createTempFile.
94.1044 + private static Path createTempFileInSameDirectoryAs(Path path)
94.1045 + throws IOException
94.1046 + {
94.1047 + Path parent = path.toAbsolutePath().getParent();
94.1048 + String dir = (parent == null)? "." : parent.toString();
94.1049 + return File.createTempFile("zipfstmp", null, new File(dir)).toPath();
94.1050 + }
94.1051 +
94.1052 + ////////////////////update & sync //////////////////////////////////////
94.1053 +
94.1054 + private boolean hasUpdate = false;
94.1055 + private void updateDelete(Entry e) {
94.1056 + EntryName en = new EntryName(e.name);
94.1057 + inodes.remove(en);
94.1058 + hasUpdate = true;
94.1059 + }
94.1060 +
94.1061 + private void update(Entry e) {
94.1062 + EntryName en = new EntryName(e.name);
94.1063 + inodes.put(en, e);
94.1064 + hasUpdate = true;
94.1065 + }
94.1066 +
94.1067 + // copy over the whole LOC entry (header if necessary, data and ext) from
94.1068 + // old zip to the new one.
94.1069 + private long copyLOCEntry(Entry e, boolean updateHeader,
94.1070 + OutputStream os,
94.1071 + long written, byte[] buf)
94.1072 + throws IOException
94.1073 + {
94.1074 + long locoff = e.locoff; // where to read
94.1075 + e.locoff = written; // update the e.locoff with new value
94.1076 +
94.1077 + // calculate the size need to write out
94.1078 + long size = 0;
94.1079 + // if there is A ext
94.1080 + if ((e.flag & FLAG_DATADESCR) != 0) {
94.1081 + if (e.size >= ZIP64_MINVAL || e.csize >= ZIP64_MINVAL)
94.1082 + size = 24;
94.1083 + else
94.1084 + size = 16;
94.1085 + }
94.1086 + if (updateHeader) { // if we need update the loc header
94.1087 + locoff += LOCHDR + e.nlen + e.elen; // skip header
94.1088 + size += e.csize;
94.1089 + written = e.writeLOC(os) + size;
94.1090 + } else {
94.1091 + size += LOCHDR + e.nlen + e.elen + e.csize;
94.1092 + written = size;
94.1093 + }
94.1094 + int n;
94.1095 + while (size > 0 &&
94.1096 + (n = (int)readFullyAt(buf, 0, buf.length, locoff)) != -1)
94.1097 + {
94.1098 + if (size < n)
94.1099 + n = (int)size;
94.1100 + os.write(buf, 0, n);
94.1101 + size -= n;
94.1102 + locoff += n;
94.1103 + }
94.1104 + return written;
94.1105 + }
94.1106 +
94.1107 + // sync the zip file system, if there is any udpate
94.1108 + private void sync() throws IOException {
94.1109 + assert Thread.holdsLock(this);
94.1110 +
94.1111 + // check ex-closer
94.1112 + if (!exChClosers.isEmpty()) {
94.1113 + for (ExChannelCloser ecc : exChClosers) {
94.1114 + if (ecc.streams.isEmpty()) {
94.1115 + ecc.ch.close();
94.1116 + ecc.path.delete();
94.1117 + exChClosers.remove(ecc);
94.1118 + }
94.1119 + }
94.1120 + }
94.1121 + if (!hasUpdate)
94.1122 + return;
94.1123 +
94.1124 + Path tmpFile = createTempFileInSameDirectoryAs(zfpath);
94.1125 + OutputStream os = tmpFile.newOutputStream(WRITE);
94.1126 + ArrayList<Entry> elist = new ArrayList<>(inodes.size());
94.1127 + long written = 0;
94.1128 + byte[] buf = new byte[8192];
94.1129 + Entry e = null;
94.1130 +
94.1131 + // write loc
94.1132 + for (IndexNode inode : inodes.values()) {
94.1133 + if (inode instanceof Entry) { // an updated inode
94.1134 + e = (Entry)inode;
94.1135 + try {
94.1136 + if (e.type == Entry.COPY) {
94.1137 + // entry copy: the only thing changed is the "name"
94.1138 + // and "nlen" in LOC header, so we udpate/rewrite the
94.1139 + // LOC in new file and simply copy the rest (data and
94.1140 + // ext) without enflating/deflating from the old zip
94.1141 + // file LOC entry.
94.1142 + written += copyLOCEntry(e, true, os, written, buf);
94.1143 + } else { // NEW or FILECH
94.1144 + e.locoff = written;
94.1145 + written += e.writeLOC(os); // write loc header
94.1146 + if (e.bytes != null) { // in-memory, deflated
94.1147 + os.write(e.bytes); // already
94.1148 + written += e.bytes.length;
94.1149 + } else if (e.file != null) { // tmp file
94.1150 + InputStream is = e.file.newInputStream();
94.1151 + int n;
94.1152 + if (e.type == Entry.NEW) { // deflated already
94.1153 + while ((n = is.read(buf)) != -1) {
94.1154 + os.write(buf, 0, n);
94.1155 + written += n;
94.1156 + }
94.1157 + } else if (e.type == Entry.FILECH) {
94.1158 + // the data are not deflated, use ZEOS
94.1159 + OutputStream os2 = new EntryOutputStream(e, os);
94.1160 + while ((n = is.read(buf)) != -1) {
94.1161 + os2.write(buf, 0, n);
94.1162 + }
94.1163 + os2.close();
94.1164 + written += e.csize;
94.1165 + if ((e.flag & FLAG_DATADESCR) != 0)
94.1166 + written += e.writeEXT(os);
94.1167 + }
94.1168 + is.close();
94.1169 + e.file.delete();
94.1170 + tmppaths.remove(e.file);
94.1171 + } else {
94.1172 + // dir, 0-length data
94.1173 + }
94.1174 + }
94.1175 + elist.add(e);
94.1176 + } catch (IOException x) {
94.1177 + x.printStackTrace(); // skip any in-accurate entry
94.1178 + }
94.1179 + } else { // unchanged inode
94.1180 + e = Entry.readCEN(cen, inode.pos);
94.1181 + try {
94.1182 + written += copyLOCEntry(e, false, os, written, buf);
94.1183 + elist.add(e);
94.1184 + } catch (IOException x) {
94.1185 + x.printStackTrace(); // skip any wrong entry
94.1186 + }
94.1187 + }
94.1188 + }
94.1189 +
94.1190 + // now write back the cen and end table
94.1191 + end.cenoff = written;
94.1192 + for (Entry entry : elist) {
94.1193 + written += entry.writeCEN(os);
94.1194 + }
94.1195 + end.centot = elist.size();
94.1196 + end.cenlen = written - end.cenoff;
94.1197 + end.write(os, written);
94.1198 + os.close();
94.1199 +
94.1200 + if (!streams.isEmpty()) {
94.1201 + // There are outstanding input streams open on existing "ch",
94.1202 + // so, don't close the "cha" and delete the "file for now, let
94.1203 + // the "ex-channel-closer" to handle them
94.1204 + ExChannelCloser ecc = new ExChannelCloser(
94.1205 + createTempFileInSameDirectoryAs(zfpath),
94.1206 + ch,
94.1207 + streams);
94.1208 + zfpath.moveTo(ecc.path, REPLACE_EXISTING);
94.1209 + exChClosers.add(ecc);
94.1210 + streams = Collections.synchronizedSet(new HashSet<InputStream>());
94.1211 + } else {
94.1212 + ch.close();
94.1213 + zfpath.delete();
94.1214 + }
94.1215 + tmpFile.moveTo(zfpath, REPLACE_EXISTING);
94.1216 + hasUpdate = false; // clear
94.1217 +
94.1218 + if (isOpen) {
94.1219 + ch = zfpath.newByteChannel(READ); // re-fresh "ch" and "cen"
94.1220 + initCEN();
94.1221 + }
94.1222 + //System.out.println("->sync() done!");
94.1223 + }
94.1224 +
94.1225 + private Entry getEntry0(byte[] path) throws IOException {
94.1226 + assert Thread.holdsLock(this);
94.1227 +
94.1228 + if (path == null)
94.1229 + throw new NullPointerException("path");
94.1230 + if (path.length == 0)
94.1231 + return null;
94.1232 + EntryName en = new EntryName(path);
94.1233 + IndexNode inode = null;
94.1234 + synchronized (lock) {
94.1235 + ensureOpen();
94.1236 + if ((inode = inodes.get(en)) == null) {
94.1237 + if (path[path.length -1] == '/') // already has a slash
94.1238 + return null;
94.1239 + path = Arrays.copyOf(path, path.length + 1);
94.1240 + path[path.length - 1] = '/';
94.1241 + en.name(path);
94.1242 + if ((inode = inodes.get(en)) == null)
94.1243 + return null;
94.1244 + }
94.1245 + if (inode instanceof Entry)
94.1246 + return (Entry)inode;
94.1247 + return Entry.readCEN(cen, inode.pos);
94.1248 + }
94.1249 + }
94.1250 +
94.1251 + // Test if the "name" a parent directory of any entry (dir empty)
94.1252 + boolean isAncestor(byte[] name) {
94.1253 + for (Map.Entry<EntryName, IndexNode> entry : inodes.entrySet()) {
94.1254 + byte[] ename = entry.getKey().name;
94.1255 + if (isParentOf(name, ename))
94.1256 + return true;
94.1257 + }
94.1258 + return false;
94.1259 + }
94.1260 +
94.1261 + public void deleteFile(byte[] path, boolean failIfNotExists)
94.1262 + throws IOException
94.1263 + {
94.1264 + checkWritable();
94.1265 + synchronized(lock) {
94.1266 + Entry e = getEntry0(path);
94.1267 + if (e == null) {
94.1268 + if (path != null && path.length == 0)
94.1269 + throw new ZipException("root directory </> can't not be delete");
94.1270 + if (failIfNotExists)
94.1271 + throw new NoSuchFileException(getString(path));
94.1272 + } else {
94.1273 + if (e.isDir() && isAncestor(path))
94.1274 + throw new DirectoryNotEmptyException(getString(path));
94.1275 + updateDelete(e);
94.1276 + }
94.1277 + }
94.1278 + }
94.1279 +
94.1280 + private static void copyStream(InputStream is, OutputStream os)
94.1281 + throws IOException
94.1282 + {
94.1283 + byte[] copyBuf = new byte[8192];
94.1284 + int n;
94.1285 + while ((n = is.read(copyBuf)) != -1) {
94.1286 + os.write(copyBuf, 0, n);
94.1287 + }
94.1288 + }
94.1289 +
94.1290 + // Returns an out stream for either
94.1291 + // (1) writing the contents of a new entry, if the entry exits, or
94.1292 + // (2) updating/replacing the contents of the specified existing entry.
94.1293 + private OutputStream getOutputStream(Entry e) throws IOException {
94.1294 +
94.1295 + ensureOpen();
94.1296 + if (e.mtime == -1)
94.1297 + e.mtime = javaToDosTime(System.currentTimeMillis());
94.1298 + if (e.method == -1)
94.1299 + e.method = METHOD_DEFLATED; // TBD: use default method
94.1300 + // store size, compressed size, and crc-32 in LOC header
94.1301 + e.flag = 0;
94.1302 + if (zc.isUTF8())
94.1303 + e.flag |= FLAG_EFS;
94.1304 + OutputStream os;
94.1305 + if (useTempFile) {
94.1306 + e.file = getTempPathForEntry(null);
94.1307 + os = e.file.newOutputStream(WRITE);
94.1308 + } else {
94.1309 + os = new ByteArrayOutputStream((e.size > 0)? (int)e.size : 8192);
94.1310 + }
94.1311 + return new EntryOutputStream(e, os);
94.1312 + }
94.1313 +
94.1314 + private InputStream getInputStream(Entry e)
94.1315 + throws IOException
94.1316 + {
94.1317 + InputStream eis = null;
94.1318 +
94.1319 + if (e.type == Entry.NEW) {
94.1320 + if (e.bytes != null)
94.1321 + eis = new ByteArrayInputStream(e.bytes);
94.1322 + else if (e.file != null)
94.1323 + eis = e.file.newInputStream();
94.1324 + else
94.1325 + throw new ZipException("update entry data is missing");
94.1326 + } else if (e.type == Entry.FILECH) {
94.1327 + // FILECH result is un-compressed.
94.1328 + eis = e.file.newInputStream();
94.1329 + // TBD: wrap to hook close()
94.1330 + // streams.add(eis);
94.1331 + return eis;
94.1332 + } else { // untouced CEN or COPY
94.1333 + eis = new EntryInputStream(e, ch);
94.1334 + }
94.1335 + if (e.method == METHOD_DEFLATED) {
94.1336 + // MORE: Compute good size for inflater stream:
94.1337 + long bufSize = e.size + 2; // Inflater likes a bit of slack
94.1338 + if (bufSize > 65536)
94.1339 + bufSize = 8192;
94.1340 + final long size = e.size;;
94.1341 + eis = new InflaterInputStream(eis, getInflater(), (int)bufSize) {
94.1342 +
94.1343 + private boolean isClosed = false;
94.1344 + public void close() throws IOException {
94.1345 + if (!isClosed) {
94.1346 + releaseInflater(inf);
94.1347 + this.in.close();
94.1348 + isClosed = true;
94.1349 + }
94.1350 + }
94.1351 + // Override fill() method to provide an extra "dummy" byte
94.1352 + // at the end of the input stream. This is required when
94.1353 + // using the "nowrap" Inflater option. (it appears the new
94.1354 + // zlib in 7 does not need it, but keep it for now)
94.1355 + protected void fill() throws IOException {
94.1356 + if (eof) {
94.1357 + throw new EOFException(
94.1358 + "Unexpected end of ZLIB input stream");
94.1359 + }
94.1360 + len = this.in.read(buf, 0, buf.length);
94.1361 + if (len == -1) {
94.1362 + buf[0] = 0;
94.1363 + len = 1;
94.1364 + eof = true;
94.1365 + }
94.1366 + inf.setInput(buf, 0, len);
94.1367 + }
94.1368 + private boolean eof;
94.1369 +
94.1370 + public int available() throws IOException {
94.1371 + if (isClosed)
94.1372 + return 0;
94.1373 + long avail = size - inf.getBytesWritten();
94.1374 + return avail > (long) Integer.MAX_VALUE ?
94.1375 + Integer.MAX_VALUE : (int) avail;
94.1376 + }
94.1377 + };
94.1378 + } else if (e.method != METHOD_STORED) {
94.1379 + throw new ZipException("invalid compression method");
94.1380 + }
94.1381 + streams.add(eis);
94.1382 + return eis;
94.1383 + }
94.1384 +
94.1385 + // Inner class implementing the input stream used to read
94.1386 + // a (possibly compressed) zip file entry.
94.1387 + private class EntryInputStream extends InputStream {
94.1388 + private SeekableByteChannel zfch; // local ref to zipfs's "ch". zipfs.ch might
94.1389 + // point to a new channel after sync()
94.1390 + private long pos; // current position within entry data
94.1391 + protected long rem; // number of remaining bytes within entry
94.1392 + protected long size; // uncompressed size of this entry
94.1393 +
94.1394 + EntryInputStream(Entry e, SeekableByteChannel zfch)
94.1395 + throws IOException
94.1396 + {
94.1397 + this.zfch = zfch;
94.1398 + rem = e.csize;
94.1399 + size = e.size;
94.1400 + pos = getDataPos(e);
94.1401 + }
94.1402 + public int read(byte b[], int off, int len) throws IOException {
94.1403 + ensureOpen();
94.1404 + if (rem == 0) {
94.1405 + return -1;
94.1406 + }
94.1407 + if (len <= 0) {
94.1408 + return 0;
94.1409 + }
94.1410 + if (len > rem) {
94.1411 + len = (int) rem;
94.1412 + }
94.1413 + // readFullyAt()
94.1414 + long n = 0;
94.1415 + ByteBuffer bb = ByteBuffer.wrap(b);
94.1416 + bb.position(off);
94.1417 + bb.limit(off + len);
94.1418 + synchronized(zfch) {
94.1419 + n = zfch.position(pos).read(bb);
94.1420 + }
94.1421 + if (n > 0) {
94.1422 + pos += n;
94.1423 + rem -= n;
94.1424 + }
94.1425 + if (rem == 0) {
94.1426 + close();
94.1427 + }
94.1428 + return (int)n;
94.1429 + }
94.1430 + public int read() throws IOException {
94.1431 + byte[] b = new byte[1];
94.1432 + if (read(b, 0, 1) == 1) {
94.1433 + return b[0] & 0xff;
94.1434 + } else {
94.1435 + return -1;
94.1436 + }
94.1437 + }
94.1438 + public long skip(long n) throws IOException {
94.1439 + ensureOpen();
94.1440 + if (n > rem)
94.1441 + n = rem;
94.1442 + pos += n;
94.1443 + rem -= n;
94.1444 + if (rem == 0) {
94.1445 + close();
94.1446 + }
94.1447 + return n;
94.1448 + }
94.1449 + public int available() {
94.1450 + return rem > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) rem;
94.1451 + }
94.1452 +
94.1453 + public long size() {
94.1454 + return size;
94.1455 + }
94.1456 + public void close() {
94.1457 + rem = 0;
94.1458 + streams.remove(this);
94.1459 + }
94.1460 + }
94.1461 +
94.1462 + class EntryOutputStream extends DeflaterOutputStream
94.1463 + {
94.1464 + private CRC32 crc;
94.1465 + private Entry e;
94.1466 + private long written;
94.1467 +
94.1468 + EntryOutputStream(Entry e, OutputStream os)
94.1469 + throws IOException
94.1470 + {
94.1471 + super(os, getDeflater());
94.1472 + if (e == null)
94.1473 + throw new NullPointerException("Zip entry is null");
94.1474 + this.e = e;
94.1475 + crc = new CRC32();
94.1476 + }
94.1477 +
94.1478 + @Override
94.1479 + public void write(byte b[], int off, int len) throws IOException {
94.1480 + if (e.type != Entry.FILECH) // only from sync
94.1481 + ensureOpen();
94.1482 + if (off < 0 || len < 0 || off > b.length - len) {
94.1483 + throw new IndexOutOfBoundsException();
94.1484 + } else if (len == 0) {
94.1485 + return;
94.1486 + }
94.1487 + switch (e.method) {
94.1488 + case METHOD_DEFLATED:
94.1489 + super.write(b, off, len);
94.1490 + break;
94.1491 + case METHOD_STORED:
94.1492 + written += len;
94.1493 + out.write(b, off, len);
94.1494 + break;
94.1495 + default:
94.1496 + throw new ZipException("invalid compression method");
94.1497 + }
94.1498 + crc.update(b, off, len);
94.1499 + }
94.1500 +
94.1501 + @Override
94.1502 + public void close() throws IOException {
94.1503 + // TBD ensureOpen();
94.1504 + switch (e.method) {
94.1505 + case METHOD_DEFLATED:
94.1506 + finish();
94.1507 + e.size = def.getBytesRead();
94.1508 + e.csize = def.getBytesWritten();
94.1509 + e.crc = crc.getValue();
94.1510 + break;
94.1511 + case METHOD_STORED:
94.1512 + // we already know that both e.size and e.csize are the same
94.1513 + e.size = e.csize = written;
94.1514 + e.crc = crc.getValue();
94.1515 + break;
94.1516 + default:
94.1517 + throw new ZipException("invalid compression method");
94.1518 + }
94.1519 + //crc.reset();
94.1520 + if (out instanceof ByteArrayOutputStream)
94.1521 + e.bytes = ((ByteArrayOutputStream)out).toByteArray();
94.1522 +
94.1523 + if (e.type == Entry.FILECH) {
94.1524 + releaseDeflater(def);
94.1525 + return;
94.1526 + }
94.1527 + super.close();
94.1528 + releaseDeflater(def);
94.1529 + update(e);
94.1530 + }
94.1531 + }
94.1532 +
94.1533 + private static void zerror(String msg) {
94.1534 + throw new ZipError(msg);
94.1535 + }
94.1536 +
94.1537 + // Maxmum number of de/inflater we cache
94.1538 + private final int MAX_FLATER = 20;
94.1539 + // List of available Inflater objects for decompression
94.1540 + private List<Inflater> inflaters = new ArrayList<>();
94.1541 +
94.1542 + // Gets an inflater from the list of available inflaters or allocates
94.1543 + // a new one.
94.1544 + private Inflater getInflater() {
94.1545 + synchronized (inflaters) {
94.1546 + int size = inflaters.size();
94.1547 + if (size > 0) {
94.1548 + Inflater inf = (Inflater)inflaters.remove(size - 1);
94.1549 + return inf;
94.1550 + } else {
94.1551 + return new Inflater(true);
94.1552 + }
94.1553 + }
94.1554 + }
94.1555 +
94.1556 + // Releases the specified inflater to the list of available inflaters.
94.1557 + private void releaseInflater(Inflater inf) {
94.1558 + synchronized (inflaters) {
94.1559 + if (inflaters.size() < MAX_FLATER) {
94.1560 + inf.reset();
94.1561 + inflaters.add(inf);
94.1562 + } else {
94.1563 + inf.end();
94.1564 + }
94.1565 + }
94.1566 + }
94.1567 +
94.1568 + // List of available Deflater objects for compression
94.1569 + private List<Deflater> deflaters = new ArrayList<>();
94.1570 +
94.1571 + // Gets an deflater from the list of available deflaters or allocates
94.1572 + // a new one.
94.1573 + private Deflater getDeflater() {
94.1574 + synchronized (deflaters) {
94.1575 + int size = deflaters.size();
94.1576 + if (size > 0) {
94.1577 + Deflater def = (Deflater)deflaters.remove(size - 1);
94.1578 + return def;
94.1579 + } else {
94.1580 + return new Deflater(Deflater.DEFAULT_COMPRESSION, true);
94.1581 + }
94.1582 + }
94.1583 + }
94.1584 +
94.1585 + // Releases the specified inflater to the list of available inflaters.
94.1586 + private void releaseDeflater(Deflater def) {
94.1587 + synchronized (deflaters) {
94.1588 + if (inflaters.size() < MAX_FLATER) {
94.1589 + def.reset();
94.1590 + deflaters.add(def);
94.1591 + } else {
94.1592 + def.end();
94.1593 + }
94.1594 + }
94.1595 + }
94.1596 +
94.1597 + // End of central directory record
94.1598 + static class END {
94.1599 + int disknum;
94.1600 + int sdisknum;
94.1601 + int endsub; // endsub
94.1602 + int centot; // 4 bytes
94.1603 + long cenlen; // 4 bytes
94.1604 + long cenoff; // 4 bytes
94.1605 + int comlen; // comment length
94.1606 + byte[] comment;
94.1607 +
94.1608 + /* members of Zip64 end of central directory locator */
94.1609 + int diskNum;
94.1610 + long endpos;
94.1611 + int disktot;
94.1612 +
94.1613 + void write(OutputStream os, long offset) throws IOException {
94.1614 + boolean hasZip64 = false;
94.1615 + long xlen = cenlen;
94.1616 + long xoff = cenoff;
94.1617 + if (xlen >= ZIP64_MINVAL) {
94.1618 + xlen = ZIP64_MINVAL;
94.1619 + hasZip64 = true;
94.1620 + }
94.1621 + if (xoff >= ZIP64_MINVAL) {
94.1622 + xoff = ZIP64_MINVAL;
94.1623 + hasZip64 = true;
94.1624 + }
94.1625 + int count = centot;
94.1626 + if (count >= ZIP64_MINVAL32) {
94.1627 + count = ZIP64_MINVAL32;
94.1628 + hasZip64 = true;
94.1629 + }
94.1630 + if (hasZip64) {
94.1631 + long off64 = offset;
94.1632 + //zip64 end of central directory record
94.1633 + writeInt(os, ZIP64_ENDSIG); // zip64 END record signature
94.1634 + writeLong(os, ZIP64_ENDHDR - 12); // size of zip64 end
94.1635 + writeShort(os, 45); // version made by
94.1636 + writeShort(os, 45); // version needed to extract
94.1637 + writeInt(os, 0); // number of this disk
94.1638 + writeInt(os, 0); // central directory start disk
94.1639 + writeLong(os, centot); // number of directory entires on disk
94.1640 + writeLong(os, centot); // number of directory entires
94.1641 + writeLong(os, cenlen); // length of central directory
94.1642 + writeLong(os, cenoff); // offset of central directory
94.1643 +
94.1644 + //zip64 end of central directory locator
94.1645 + writeInt(os, ZIP64_LOCSIG); // zip64 END locator signature
94.1646 + writeInt(os, 0); // zip64 END start disk
94.1647 + writeLong(os, off64); // offset of zip64 END
94.1648 + writeInt(os, 1); // total number of disks (?)
94.1649 + }
94.1650 + writeInt(os, ENDSIG); // END record signature
94.1651 + writeShort(os, 0); // number of this disk
94.1652 + writeShort(os, 0); // central directory start disk
94.1653 + writeShort(os, count); // number of directory entries on disk
94.1654 + writeShort(os, count); // total number of directory entries
94.1655 + writeInt(os, xlen); // length of central directory
94.1656 + writeInt(os, xoff); // offset of central directory
94.1657 + if (comment != null) { // zip file comment
94.1658 + writeShort(os, comment.length);
94.1659 + writeBytes(os, comment);
94.1660 + } else {
94.1661 + writeShort(os, 0);
94.1662 + }
94.1663 + }
94.1664 + }
94.1665 +
94.1666 + // wrapper for the byte[] name
94.1667 + static class EntryName {
94.1668 + byte[] name;
94.1669 + int hashcode; // node is hashable/hashed by its name
94.1670 +
94.1671 + public EntryName (byte[] name) {
94.1672 + name(name);
94.1673 + }
94.1674 +
94.1675 + void name(byte[] name) {
94.1676 + this.name = name;
94.1677 + this.hashcode = Arrays.hashCode(name);
94.1678 + }
94.1679 +
94.1680 + public boolean equals(Object other) {
94.1681 + if (!(other instanceof EntryName))
94.1682 + return false;
94.1683 + return Arrays.equals(name, ((EntryName)other).name);
94.1684 + }
94.1685 +
94.1686 + public int hashCode() {
94.1687 + return hashcode;
94.1688 + }
94.1689 + }
94.1690 +
94.1691 + // can simply use Integer instead, if we don't use it to
94.1692 + // build a internal node tree.
94.1693 + static class IndexNode {
94.1694 + byte[] name;
94.1695 + int pos = -1; // postion in cen table, -1 menas the
94.1696 + // entry does not exists in zip file
94.1697 + IndexNode(byte[] name, int pos) {
94.1698 + this.name = name;
94.1699 + this.pos = pos;
94.1700 + }
94.1701 +
94.1702 + IndexNode() {}
94.1703 +
94.1704 + IndexNode sibling;
94.1705 + IndexNode child; // 1st child
94.1706 + }
94.1707 +
94.1708 + static class Entry extends IndexNode {
94.1709 +
94.1710 + static final int CEN = 1; // entry read from cen
94.1711 + static final int NEW = 2; // updated contents in bytes or file
94.1712 + static final int FILECH = 3; // fch update in "file"
94.1713 + static final int COPY = 4; // copy of a CEN entry
94.1714 +
94.1715 + byte[] bytes; // updated content bytes
94.1716 + Path file; // use tmp file to store bytes;
94.1717 + int type = CEN; // default is the entry read from cen
94.1718 +
94.1719 + // entry attributes
94.1720 + int version;
94.1721 + int flag;
94.1722 + int method = -1; // compression method
94.1723 + long mtime = -1; // last modification time (in DOS time)
94.1724 + long atime = -1; // last access time
94.1725 + long ctime = -1; // create time
94.1726 + long crc = -1; // crc-32 of entry data
94.1727 + long csize = -1; // compressed size of entry data
94.1728 + long size = -1; // uncompressed size of entry data
94.1729 + int nlen;
94.1730 + int elen;
94.1731 + byte[] extra;
94.1732 +
94.1733 + // loc
94.1734 + long startPos;
94.1735 + long endPos; // exclusive
94.1736 +
94.1737 + // cen
94.1738 + int versionMade;
94.1739 + int disk;
94.1740 + int attrs;
94.1741 + long attrsEx;
94.1742 + long locoff;
94.1743 +
94.1744 + int clen;
94.1745 + byte[] comment;
94.1746 +
94.1747 + // ZIP64 flag
94.1748 + boolean hasZip64;
94.1749 +
94.1750 + Entry() {}
94.1751 +
94.1752 + Entry(byte[] name) {
94.1753 + this.name = name;
94.1754 + //this.nlen = name.length;
94.1755 + this.mtime = javaToDosTime(System.currentTimeMillis());
94.1756 + this.crc = 0;
94.1757 + this.size = 0;
94.1758 + this.csize = 0;
94.1759 + this.method = METHOD_DEFLATED;
94.1760 + }
94.1761 +
94.1762 + Entry(byte[] name, int type) {
94.1763 + this(name);
94.1764 + this.type = type;
94.1765 + }
94.1766 +
94.1767 + Entry (byte[] name, Path file, int type) {
94.1768 + this(name, type);
94.1769 + this.file = file;
94.1770 + this.method = METHOD_STORED;
94.1771 + }
94.1772 +
94.1773 + Entry(Entry e) {
94.1774 + this.version = e.version;
94.1775 + this.name = e.name; // copyOf?
94.1776 + this.nlen = e.nlen;
94.1777 + this.ctime = e.ctime;
94.1778 + this.atime = e.atime;
94.1779 + this.mtime = e.mtime;
94.1780 + this.crc = e.crc;
94.1781 + this.size = e.size;
94.1782 + this.csize = e.csize;
94.1783 + this.method = e.method;
94.1784 + this.extra = (e.extra == null)?
94.1785 + null:Arrays.copyOf(e.extra, e.extra.length);
94.1786 + this.elen = e.elen;
94.1787 + this.versionMade = e.versionMade;
94.1788 + this.disk = e.disk;
94.1789 + this.attrs = e.attrs;
94.1790 + this.attrsEx = e.attrsEx;
94.1791 + this.locoff = e.locoff;
94.1792 + this.clen = e.clen;
94.1793 + this.comment = (e.comment == null)?
94.1794 + null:Arrays.copyOf(e.comment, e.comment.length);
94.1795 + this.startPos = e.startPos;
94.1796 + this.endPos = e.endPos;
94.1797 + this.hasZip64 = e.hasZip64;;
94.1798 + }
94.1799 +
94.1800 + Entry (Entry e, int type) {
94.1801 + this(e);
94.1802 + this.type = type;
94.1803 + }
94.1804 +
94.1805 + boolean isDir() {
94.1806 + return name != null &&
94.1807 + (name.length == 0 ||
94.1808 + name[name.length - 1] == '/');
94.1809 + }
94.1810 +
94.1811 + int version() throws ZipException {
94.1812 + if (method == METHOD_DEFLATED)
94.1813 + return 20;
94.1814 + else if (method == METHOD_STORED)
94.1815 + return 10;
94.1816 + throw new ZipException("unsupported compression method");
94.1817 + }
94.1818 +
94.1819 + ///////////////////// CEN //////////////////////
94.1820 + static Entry readCEN(ByteBuffer cen, int pos) throws IOException
94.1821 + {
94.1822 + return new Entry().cen(cen, pos);
94.1823 + }
94.1824 +
94.1825 + private Entry cen(ByteBuffer cen, int pos) throws IOException
94.1826 + {
94.1827 + if (CENSIG(cen, pos) != CENSIG)
94.1828 + zerror("invalid CEN header (bad signature)");
94.1829 + versionMade = CENVEM(cen, pos);
94.1830 + version = CENVER(cen, pos);
94.1831 + flag = CENFLG(cen, pos);
94.1832 + method = CENHOW(cen, pos);
94.1833 + mtime = CENTIM(cen, pos);
94.1834 + crc = CENCRC(cen, pos);
94.1835 + csize = CENSIZ(cen, pos);
94.1836 + size = CENLEN(cen, pos);
94.1837 + nlen = CENNAM(cen, pos);
94.1838 + elen = CENEXT(cen, pos);
94.1839 + clen = CENCOM(cen, pos);
94.1840 + disk = CENDSK(cen, pos);
94.1841 + attrs = CENATT(cen, pos);
94.1842 + attrsEx = CENATX(cen, pos);
94.1843 + locoff = CENOFF(cen, pos);
94.1844 +
94.1845 + cen.position(pos + CENHDR);
94.1846 + name = new byte[nlen];
94.1847 + cen.get(name);
94.1848 +
94.1849 + if (elen > 0) {
94.1850 + extra = new byte[elen];
94.1851 + cen.get(extra);
94.1852 + if (csize == ZIP64_MINVAL || size == ZIP64_MINVAL ||
94.1853 + locoff == ZIP64_MINVAL) {
94.1854 + int off = 0;
94.1855 + while (off + 4 < elen) {
94.1856 + // extra spec: HeaderID+DataSize+Data
94.1857 + int sz = SH(extra, off + 2);
94.1858 + if (SH(extra, off) == EXTID_ZIP64) {
94.1859 + off += 4;
94.1860 + if (size == ZIP64_MINVAL) {
94.1861 + // if invalid zip64 extra fields, just skip
94.1862 + if (sz < 8 || (off + 8) > elen)
94.1863 + break;
94.1864 + size = LL(extra, off);
94.1865 + sz -= 8;
94.1866 + off += 8;
94.1867 + }
94.1868 + if (csize == ZIP64_MINVAL) {
94.1869 + if (sz < 8 || (off + 8) > elen)
94.1870 + break;
94.1871 + csize = LL(extra, off);
94.1872 + sz -= 8;
94.1873 + off += 8;
94.1874 + }
94.1875 + if (locoff == ZIP64_MINVAL) {
94.1876 + if (sz < 8 || (off + 8) > elen)
94.1877 + break;
94.1878 + locoff = LL(extra, off);
94.1879 + sz -= 8;
94.1880 + off += 8;
94.1881 + }
94.1882 + break;
94.1883 + }
94.1884 + off += (sz + 4);
94.1885 + }
94.1886 + }
94.1887 + }
94.1888 + if (clen > 0) {
94.1889 + comment = new byte[clen];
94.1890 + cen.get(comment);
94.1891 + }
94.1892 + return this;
94.1893 + }
94.1894 +
94.1895 + int writeCEN(OutputStream os) throws IOException
94.1896 + {
94.1897 + int written = CENHDR;
94.1898 + int version0 = version();
94.1899 +
94.1900 + long csize0 = csize;
94.1901 + long size0 = size;
94.1902 + long locoff0 = locoff;
94.1903 + int e64len = 0;
94.1904 +
94.1905 + // confirm size/length
94.1906 + nlen = (name != null) ? name.length : 0;
94.1907 + elen = (extra != null) ? extra.length : 0;
94.1908 + clen = (comment != null) ? comment.length : 0;
94.1909 +
94.1910 + boolean hasZip64 = false;
94.1911 + if (csize >= ZIP64_MINVAL) {
94.1912 + csize0 = ZIP64_MINVAL;
94.1913 + e64len += 8; // csize(8)
94.1914 + hasZip64 = true;
94.1915 + }
94.1916 + if (size >= ZIP64_MINVAL) {
94.1917 + size0 = ZIP64_MINVAL; // size(8)
94.1918 + e64len += 8;
94.1919 + hasZip64 = true;
94.1920 + }
94.1921 + if (locoff >= ZIP64_MINVAL) {
94.1922 + locoff0 = ZIP64_MINVAL;
94.1923 + e64len += 8; // offset(8)
94.1924 + hasZip64 = true;
94.1925 + }
94.1926 + writeInt(os, CENSIG); // CEN header signature
94.1927 + if (hasZip64) {
94.1928 + writeShort(os, 45); // ver 4.5 for zip64
94.1929 + writeShort(os, 45);
94.1930 + } else {
94.1931 + writeShort(os, version0); // version made by
94.1932 + writeShort(os, version0); // version needed to extract
94.1933 + }
94.1934 + writeShort(os, flag); // general purpose bit flag
94.1935 + writeShort(os, method); // compression method
94.1936 + writeInt(os, mtime); // last modification time
94.1937 + writeInt(os, crc); // crc-32
94.1938 + writeInt(os, csize0); // compressed size
94.1939 + writeInt(os, size0); // uncompressed size
94.1940 + writeShort(os, name.length);
94.1941 +
94.1942 + if (hasZip64) {
94.1943 + // + headid(2) + datasize(2)
94.1944 + writeShort(os, e64len + 4 + elen);
94.1945 + } else {
94.1946 + writeShort(os, elen);
94.1947 + }
94.1948 + if (comment != null) {
94.1949 + writeShort(os, Math.min(clen, 0xffff));
94.1950 + } else {
94.1951 + writeShort(os, 0);
94.1952 + }
94.1953 + writeShort(os, 0); // starting disk number
94.1954 + writeShort(os, 0); // internal file attributes (unused)
94.1955 + writeInt(os, 0); // external file attributes (unused)
94.1956 + writeInt(os, locoff0); // relative offset of local header
94.1957 + writeBytes(os, name);
94.1958 + if (hasZip64) {
94.1959 + writeShort(os, EXTID_ZIP64);// Zip64 extra
94.1960 + writeShort(os, e64len);
94.1961 + if (size0 == ZIP64_MINVAL)
94.1962 + writeLong(os, size);
94.1963 + if (csize0 == ZIP64_MINVAL)
94.1964 + writeLong(os, csize);
94.1965 + if (locoff0 == ZIP64_MINVAL)
94.1966 + writeLong(os, locoff);
94.1967 + }
94.1968 + if (extra != null) {
94.1969 + writeBytes(os, extra);
94.1970 + }
94.1971 + if (comment != null) {
94.1972 + //TBD: 0, Math.min(commentBytes.length, 0xffff));
94.1973 + writeBytes(os, comment);
94.1974 + }
94.1975 + return CENHDR + nlen + elen + clen + (hasZip64?(e64len + 4):0);
94.1976 + }
94.1977 +
94.1978 + ///////////////////// LOC //////////////////////
94.1979 + static Entry readLOC(ZipFileSystem zf, long pos)
94.1980 + throws IOException
94.1981 + {
94.1982 + return readLOC(zf, pos, new byte[1024]);
94.1983 + }
94.1984 +
94.1985 + static Entry readLOC(ZipFileSystem zf, long pos, byte[] buf)
94.1986 + throws IOException
94.1987 + {
94.1988 + return new Entry().loc(zf, pos, buf);
94.1989 + }
94.1990 +
94.1991 + Entry loc(ZipFileSystem zf, long pos, byte[] buf)
94.1992 + throws IOException
94.1993 + {
94.1994 + assert (buf.length >= LOCHDR);
94.1995 + if (zf.readFullyAt(buf, 0, LOCHDR , pos) != LOCHDR) {
94.1996 + throw new ZipException("loc: reading failed");
94.1997 + }
94.1998 + if (LOCSIG(buf) != LOCSIG) {
94.1999 + throw new ZipException("loc: wrong sig ->"
94.2000 + + Long.toString(LOCSIG(buf), 16));
94.2001 + }
94.2002 + startPos = pos;
94.2003 + version = LOCVER(buf);
94.2004 + flag = LOCFLG(buf);
94.2005 + method = LOCHOW(buf);
94.2006 + mtime = LOCTIM(buf);
94.2007 + crc = LOCCRC(buf);
94.2008 + csize = LOCSIZ(buf);
94.2009 + size = LOCLEN(buf);
94.2010 + nlen = LOCNAM(buf);
94.2011 + elen = LOCEXT(buf);
94.2012 +
94.2013 + name = new byte[nlen];
94.2014 + if (zf.readFullyAt(name, 0, nlen, pos + LOCHDR) != nlen) {
94.2015 + throw new ZipException("loc: name reading failed");
94.2016 + }
94.2017 + if (elen > 0) {
94.2018 + extra = new byte[elen];
94.2019 + if (zf.readFullyAt(extra, 0, elen, pos + LOCHDR + nlen)
94.2020 + != elen) {
94.2021 + throw new ZipException("loc: ext reading failed");
94.2022 + }
94.2023 + }
94.2024 + pos += (LOCHDR + nlen + elen);
94.2025 + if ((flag & FLAG_DATADESCR) != 0) {
94.2026 + // Data Descriptor
94.2027 + Entry e = zf.getEntry0(name); // get the size/csize from cen
94.2028 + if (e == null)
94.2029 + throw new ZipException("loc: name not found in cen");
94.2030 + size = e.size;
94.2031 + csize = e.csize;
94.2032 + pos += (method == METHOD_STORED ? size : csize);
94.2033 + if (size >= ZIP64_MINVAL || csize >= ZIP64_MINVAL)
94.2034 + pos += 24;
94.2035 + else
94.2036 + pos += 16;
94.2037 + } else {
94.2038 + boolean hasZip64 = false;
94.2039 + if (extra != null &&
94.2040 + (size == ZIP64_MINVAL || csize == ZIP64_MINVAL)) {
94.2041 + // zip64 ext: must include both size and csize
94.2042 + int off = 0;
94.2043 + while (off + 20 < elen) { // HeaderID+DataSize+Data
94.2044 + int sz = SH(extra, off + 2);
94.2045 + if (SH(extra, off) == EXTID_ZIP64 && sz == 16) {
94.2046 + size = LL(extra, off + 4);
94.2047 + csize = LL(extra, off + 12);
94.2048 + hasZip64 = true;
94.2049 + break;
94.2050 + }
94.2051 + off += (sz + 4);
94.2052 + }
94.2053 + }
94.2054 + pos += (method == METHOD_STORED ? size : csize);
94.2055 + }
94.2056 + endPos = pos;
94.2057 + return this;
94.2058 + }
94.2059 +
94.2060 + int writeLOC(OutputStream os)
94.2061 + throws IOException
94.2062 + {
94.2063 + writeInt(os, LOCSIG); // LOC header signature
94.2064 +
94.2065 + int version = version();
94.2066 + if ((flag & FLAG_DATADESCR) != 0) {
94.2067 + writeShort(os, version()); // version needed to extract
94.2068 + writeShort(os, flag); // general purpose bit flag
94.2069 + writeShort(os, method); // compression method
94.2070 + writeInt(os, mtime); // last modification time
94.2071 +
94.2072 + // store size, uncompressed size, and crc-32 in data descriptor
94.2073 + // immediately following compressed entry data
94.2074 + writeInt(os, 0);
94.2075 + writeInt(os, 0);
94.2076 + writeInt(os, 0);
94.2077 + } else {
94.2078 + if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) {
94.2079 + hasZip64 = true;
94.2080 + writeShort(os, 45); // ver 4.5 for zip64
94.2081 + } else {
94.2082 + writeShort(os, version()); // version needed to extract
94.2083 + }
94.2084 + writeShort(os, flag); // general purpose bit flag
94.2085 + writeShort(os, method); // compression method
94.2086 + writeInt(os, mtime); // last modification time
94.2087 + writeInt(os, crc); // crc-32
94.2088 + if (hasZip64) {
94.2089 + writeInt(os, ZIP64_MINVAL);
94.2090 + writeInt(os, ZIP64_MINVAL);
94.2091 + //TBD: e.elen += 20; //headid(2) + size(2) + size(8) + csize(8)
94.2092 + } else {
94.2093 + writeInt(os, csize); // compressed size
94.2094 + writeInt(os, size); // uncompressed size
94.2095 + }
94.2096 + }
94.2097 + writeShort(os, name.length);
94.2098 + writeShort(os, elen + (hasZip64 ? 20 : 0));
94.2099 + writeBytes(os, name);
94.2100 + if (hasZip64) {
94.2101 + // TBD: should we update extra directory?
94.2102 + writeShort(os, EXTID_ZIP64);
94.2103 + writeShort(os, 16);
94.2104 + writeLong(os, size);
94.2105 + writeLong(os, csize);
94.2106 + }
94.2107 + if (extra != null) {
94.2108 + writeBytes(os, extra);
94.2109 + }
94.2110 + return LOCHDR + name.length + elen + (hasZip64 ? 20 : 0);
94.2111 + }
94.2112 +
94.2113 + // Data Descriptior
94.2114 + int writeEXT(OutputStream os)
94.2115 + throws IOException
94.2116 + {
94.2117 + writeInt(os, EXTSIG); // EXT header signature
94.2118 + writeInt(os, crc); // crc-32
94.2119 + if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) {
94.2120 + writeLong(os, csize);
94.2121 + writeLong(os, size);
94.2122 + return 24;
94.2123 + } else {
94.2124 + writeInt(os, csize); // compressed size
94.2125 + writeInt(os, size); // uncompressed size
94.2126 + return 16;
94.2127 + }
94.2128 + }
94.2129 +
94.2130 + // read NTFS, UNIX and ZIP64 data from cen.extra
94.2131 + void readExtra() {
94.2132 + if (extra == null)
94.2133 + return;
94.2134 + int elen = extra.length;
94.2135 + int off = 0;
94.2136 + while (off + 4 < elen) {
94.2137 + // extra spec: HeaderID+DataSize+Data
94.2138 + int sz = SH(extra, off + 2);
94.2139 + int tag = SH(extra, off);
94.2140 + off += 4;
94.2141 + int pos = off;
94.2142 + if (pos + sz > elen) // invalid data
94.2143 + break;
94.2144 + switch (tag) {
94.2145 + case EXTID_ZIP64 :
94.2146 + if (size == ZIP64_MINVAL) {
94.2147 + if (pos + 8 > elen) // invalid zip64 extra
94.2148 + break; // fields, just skip
94.2149 + size = LL(extra, pos);
94.2150 + pos += 8;
94.2151 + }
94.2152 + if (csize == ZIP64_MINVAL) {
94.2153 + if (pos + 8 > elen)
94.2154 + break;
94.2155 + csize = LL(extra, pos);
94.2156 + pos += 8;
94.2157 + }
94.2158 + if (locoff == ZIP64_MINVAL) {
94.2159 + if (pos + 8 > elen)
94.2160 + break;
94.2161 + locoff = LL(extra, pos);
94.2162 + pos += 8;
94.2163 + }
94.2164 + break;
94.2165 + case EXTID_NTFS:
94.2166 + pos += 4; // reserved 4 bytes
94.2167 + if (SH(extra, pos) != 0x0001)
94.2168 + break;
94.2169 + if (SH(extra, pos + 2) != 24)
94.2170 + break;
94.2171 + mtime = LL(extra, pos + 4);
94.2172 + atime = LL(extra, pos + 12);
94.2173 + ctime = LL(extra, pos + 20);
94.2174 + break;
94.2175 + case EXTID_UNIX:
94.2176 + atime = LG(extra, pos);
94.2177 + mtime = LG(extra, pos + 4);
94.2178 + break;
94.2179 + default: // unknow
94.2180 + }
94.2181 + off += sz;
94.2182 + }
94.2183 + }
94.2184 + }
94.2185 +
94.2186 + private static class ExChannelCloser {
94.2187 + Path path;
94.2188 + SeekableByteChannel ch;
94.2189 + Set<InputStream> streams;
94.2190 + ExChannelCloser(Path path,
94.2191 + SeekableByteChannel ch,
94.2192 + Set<InputStream> streams)
94.2193 + {
94.2194 + this.path = path;
94.2195 + this.ch = ch;
94.2196 + this.streams = streams;
94.2197 + }
94.2198 + }
94.2199 +
94.2200 + // ZIP directory has two issues:
94.2201 + // (1) ZIP spec does not require the ZIP file to include
94.2202 + // directory entry
94.2203 + // (2) all entries are not stored/organized in a "tree"
94.2204 + // structure.
94.2205 + // A possible solution is to build the node tree ourself as
94.2206 + // implemented below.
94.2207 + private HashMap<EntryName, IndexNode> dirs;
94.2208 + private IndexNode root;
94.2209 + private IndexNode addToDir(EntryName child) {
94.2210 + IndexNode cinode = dirs.get(child);
94.2211 + if (cinode != null)
94.2212 + return cinode;
94.2213 +
94.2214 + byte[] cname = child.name;
94.2215 + byte[] pname = getParent(cname);
94.2216 + IndexNode pinode;
94.2217 +
94.2218 + if (pname != null)
94.2219 + pinode = addToDir(new EntryName(pname));
94.2220 + else
94.2221 + pinode = root;
94.2222 + cinode = inodes.get(child);
94.2223 + if (cname[cname.length -1] != '/') { // not a dir
94.2224 + cinode.sibling = pinode.child;
94.2225 + pinode.child = cinode;
94.2226 + return null;
94.2227 + }
94.2228 + cinode = dirs.get(child);
94.2229 + if (cinode == null) // pseudo directry entry
94.2230 + cinode = new IndexNode(cname, -1);
94.2231 + cinode.sibling = pinode.child;
94.2232 + pinode.child = cinode;
94.2233 +
94.2234 + dirs.put(child, cinode);
94.2235 + return cinode;
94.2236 + }
94.2237 +
94.2238 + private HashMap<EntryName, IndexNode> getDirs()
94.2239 + throws IOException
94.2240 + {
94.2241 + if (hasUpdate)
94.2242 + sync();
94.2243 + if (dirs != null)
94.2244 + return dirs;
94.2245 + dirs = new HashMap<EntryName, IndexNode>();
94.2246 + byte[] empty = new byte[0];
94.2247 + root = new IndexNode(empty, -1);
94.2248 + dirs.put(new EntryName(empty), root);
94.2249 +
94.2250 + EntryName[] names = inodes.keySet().toArray(new EntryName[0]);
94.2251 + int i = names.length;
94.2252 + while (--i >= 0) {
94.2253 + addToDir(names[i]);
94.2254 + }
94.2255 + // for (int i EntryName en : inodes.keySet()) {
94.2256 + // addToDir(en);
94.2257 + // }
94.2258 + return dirs;
94.2259 + }
94.2260 +}
95.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
95.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystemProvider.java Tue Oct 12 12:51:48 2010 -0700
95.3 @@ -0,0 +1,152 @@
95.4 +/*
95.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
95.6 + *
95.7 + * Redistribution and use in source and binary forms, with or without
95.8 + * modification, are permitted provided that the following conditions
95.9 + * are met:
95.10 + *
95.11 + * - Redistributions of source code must retain the above copyright
95.12 + * notice, this list of conditions and the following disclaimer.
95.13 + *
95.14 + * - Redistributions in binary form must reproduce the above copyright
95.15 + * notice, this list of conditions and the following disclaimer in the
95.16 + * documentation and/or other materials provided with the distribution.
95.17 + *
95.18 + * - Neither the name of Oracle nor the names of its
95.19 + * contributors may be used to endorse or promote products derived
95.20 + * from this software without specific prior written permission.
95.21 + *
95.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
95.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
95.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
95.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
95.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
95.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
95.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
95.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
95.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
95.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95.33 + */
95.34 +
95.35 +package com.sun.nio.zipfs;
95.36 +
95.37 +import java.io.IOException;
95.38 +import java.nio.channels.FileChannel;
95.39 +import java.nio.file.FileRef;
95.40 +import java.nio.file.FileSystem;
95.41 +import java.nio.file.FileSystemNotFoundException;
95.42 +import java.nio.file.FileSystemAlreadyExistsException;
95.43 +import java.nio.file.OpenOption;
95.44 +import java.nio.file.Path;
95.45 +import java.nio.file.Paths;
95.46 +import java.nio.file.ProviderMismatchException;
95.47 +import java.nio.file.attribute.FileAttribute;
95.48 +import java.nio.file.spi.FileSystemProvider;
95.49 +import java.net.URI;
95.50 +import java.net.URISyntaxException;
95.51 +import java.util.HashMap;
95.52 +import java.util.Map;
95.53 +import java.util.Set;
95.54 +
95.55 +/*
95.56 + *
95.57 + * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
95.58 + */
95.59 +
95.60 +public class ZipFileSystemProvider extends FileSystemProvider {
95.61 + private final Map<Path, ZipFileSystem> filesystems = new HashMap<>();
95.62 +
95.63 + public ZipFileSystemProvider() {}
95.64 +
95.65 + @Override
95.66 + public String getScheme() {
95.67 + return "zip";
95.68 + }
95.69 +
95.70 + protected Path uriToPath(URI uri) {
95.71 + String scheme = uri.getScheme();
95.72 + if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) {
95.73 + throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'");
95.74 + }
95.75 + try {
95.76 + return Paths.get(new URI("file", uri.getHost(), uri.getPath(), null))
95.77 + .toAbsolutePath();
95.78 + } catch (URISyntaxException e) {
95.79 + throw new AssertionError(e); //never thrown
95.80 + }
95.81 + }
95.82 +
95.83 + @Override
95.84 + public FileSystem newFileSystem(URI uri, Map<String, ?> env)
95.85 + throws IOException
95.86 + {
95.87 + return newFileSystem(uriToPath(uri), env);
95.88 + }
95.89 +
95.90 + @Override
95.91 + public FileSystem newFileSystem(FileRef file, Map<String, ?> env)
95.92 + throws IOException
95.93 + {
95.94 + if (!(file instanceof Path))
95.95 + throw new UnsupportedOperationException();
95.96 + Path path = (Path)file;
95.97 + if (!path.toUri().getScheme().equalsIgnoreCase("file")) {
95.98 + throw new UnsupportedOperationException();
95.99 + }
95.100 + return newFileSystem(path, env);
95.101 + }
95.102 +
95.103 + private FileSystem newFileSystem(Path path, Map<String, ?> env)
95.104 + throws IOException
95.105 + {
95.106 + synchronized(filesystems) {
95.107 + if (filesystems.containsKey(path))
95.108 + throw new FileSystemAlreadyExistsException();
95.109 + ZipFileSystem zipfs = new ZipFileSystem(this, path, env);
95.110 + filesystems.put(path, zipfs);
95.111 + return zipfs;
95.112 + }
95.113 + }
95.114 +
95.115 + @Override
95.116 + public Path getPath(URI uri) {
95.117 + FileSystem fs = getFileSystem(uri);
95.118 + String fragment = uri.getFragment();
95.119 + if (fragment == null) {
95.120 + throw new IllegalArgumentException("URI: "
95.121 + + uri
95.122 + + " does not contain path fragment ex. zip:///c:/foo.zip#/BAR");
95.123 + }
95.124 + return fs.getPath(fragment);
95.125 + }
95.126 +
95.127 + @Override
95.128 + public FileChannel newFileChannel(Path path,
95.129 + Set<? extends OpenOption> options,
95.130 + FileAttribute<?>... attrs)
95.131 + throws IOException
95.132 + {
95.133 + if (path == null)
95.134 + throw new NullPointerException("path is null");
95.135 + if (path instanceof ZipPath)
95.136 + return ((ZipPath)path).newFileChannel(options, attrs);
95.137 + throw new ProviderMismatchException();
95.138 + }
95.139 +
95.140 + @Override
95.141 + public FileSystem getFileSystem(URI uri) {
95.142 + synchronized (filesystems) {
95.143 + ZipFileSystem zipfs = filesystems.get(uriToPath(uri));
95.144 + if (zipfs == null)
95.145 + throw new FileSystemNotFoundException();
95.146 + return zipfs;
95.147 + }
95.148 + }
95.149 +
95.150 + void removeFileSystem(Path zfpath) {
95.151 + synchronized (filesystems) {
95.152 + filesystems.remove(zfpath);
95.153 + }
95.154 + }
95.155 +}
96.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
96.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipInfo.java Tue Oct 12 12:51:48 2010 -0700
96.3 @@ -0,0 +1,132 @@
96.4 +/*
96.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
96.6 + *
96.7 + * Redistribution and use in source and binary forms, with or without
96.8 + * modification, are permitted provided that the following conditions
96.9 + * are met:
96.10 + *
96.11 + * - Redistributions of source code must retain the above copyright
96.12 + * notice, this list of conditions and the following disclaimer.
96.13 + *
96.14 + * - Redistributions in binary form must reproduce the above copyright
96.15 + * notice, this list of conditions and the following disclaimer in the
96.16 + * documentation and/or other materials provided with the distribution.
96.17 + *
96.18 + * - Neither the name of Oracle nor the names of its
96.19 + * contributors may be used to endorse or promote products derived
96.20 + * from this software without specific prior written permission.
96.21 + *
96.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
96.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
96.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
96.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
96.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
96.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
96.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
96.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
96.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
96.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96.33 + */
96.34 +
96.35 +package com.sun.nio.zipfs;
96.36 +
96.37 +import java.io.PrintStream;
96.38 +import java.nio.file.Paths;
96.39 +import java.util.Collections;
96.40 +import java.util.Iterator;
96.41 +import java.util.Map;
96.42 +import com.sun.nio.zipfs.ZipFileSystem.Entry;
96.43 +import static com.sun.nio.zipfs.ZipConstants.*;
96.44 +import static com.sun.nio.zipfs.ZipUtils.*;
96.45 +
96.46 +/**
96.47 + * Print the loc and cen tables of the ZIP file
96.48 + *
96.49 + * @author Xueming Shen
96.50 + */
96.51 +
96.52 +public class ZipInfo {
96.53 +
96.54 + public static void main(String[] args) throws Throwable {
96.55 + if (args.length < 2) {
96.56 + print("Usage: java ZipInfo [cen|loc] zfname");
96.57 + } else {
96.58 + Map<String, ?> env = Collections.emptyMap();
96.59 + ZipFileSystem zfs = (ZipFileSystem)(new ZipFileSystemProvider()
96.60 + .newFileSystem(Paths.get(args[1]), env));
96.61 +
96.62 + long pos = 0;
96.63 +
96.64 + if ("loc".equals(args[0])) {
96.65 + print("[Local File Header]%n");
96.66 + byte[] buf = new byte[1024];
96.67 + for (int i = 0; i < zfs.getEntryNames().length; i++) {
96.68 + Entry loc = Entry.readLOC(zfs, pos, buf);
96.69 + print("--------loc[%x]--------%n", pos);
96.70 + printLOC(loc);
96.71 + pos = loc.endPos;
96.72 + }
96.73 + } if ("cen".equals(args[0])) {
96.74 + int i = 0;
96.75 + Iterator<ZipFileSystem.IndexNode> itr = zfs.inodes.values().iterator();
96.76 + print("[Central Directory Header]%n");
96.77 + while (itr.hasNext()) {
96.78 + Entry cen = Entry.readCEN(zfs.cen, itr.next().pos);
96.79 + print("--------cen[%d]--------%n", i);
96.80 + printCEN(cen);
96.81 + i++;
96.82 + }
96.83 + }
96.84 + zfs.close();
96.85 + }
96.86 + }
96.87 +
96.88 + static void print(String fmt, Object... objs) {
96.89 + System.out.printf(fmt, objs);
96.90 + }
96.91 +
96.92 + static void printLOC(Entry loc) {
96.93 + print(" [%x, %x]%n", loc.startPos, loc.endPos);
96.94 + print(" Signature : %8x%n", LOCSIG);
96.95 + print(" Version : %4x [%d.%d]%n",
96.96 + loc.version, loc. version/10, loc. version%10);
96.97 + print(" Flag : %4x%n", loc.flag);
96.98 + print(" Method : %4x%n", loc. method);
96.99 + print(" LastMTime : %8x [%tc]%n",
96.100 + loc.mtime, dosToJavaTime(loc.mtime));
96.101 + print(" CRC : %8x%n", loc.crc);
96.102 + print(" CSize : %8x%n", loc.csize);
96.103 + print(" Size : %8x%n", loc.size);
96.104 + print(" NameLength : %4x [%s]%n",
96.105 + loc.nlen, new String(loc.name));
96.106 + print(" ExtraLength : %4x%n", loc.elen);
96.107 + if (loc.hasZip64)
96.108 + print(" *ZIP64*%n");
96.109 + }
96.110 +
96.111 + static void printCEN(Entry cen) {
96.112 + print(" Signature : %08x%n", CENSIG);
96.113 + print(" VerMadeby : %4x [%d.%d]%n",
96.114 + cen.versionMade, cen.versionMade/10, cen.versionMade%10);
96.115 + print(" VerExtract : %4x [%d.%d]%n",
96.116 + cen.version, cen.version/10, cen.version%10);
96.117 + print(" Flag : %4x%n", cen.flag);
96.118 + print(" Method : %4x%n", cen.method);
96.119 + print(" LastMTime : %8x [%tc]%n",
96.120 + cen.mtime, dosToJavaTime(cen.mtime));
96.121 + print(" CRC : %8x%n", cen.crc);
96.122 + print(" CSize : %8x%n", cen.csize);
96.123 + print(" Size : %8x%n", cen.size);
96.124 + print(" NameLen : %4x [%s]%n",
96.125 + cen.nlen, new String(cen.name));
96.126 + print(" ExtraLen : %4x%n", cen.elen);
96.127 + print(" CommentLen : %4x%n", cen.clen);
96.128 + print(" DiskStart : %4x%n", cen.disk);
96.129 + print(" Attrs : %4x%n", cen.attrs);
96.130 + print(" AttrsEx : %8x%n", cen.attrsEx);
96.131 + print(" LocOff : %8x%n", cen.locoff);
96.132 + if (cen.hasZip64)
96.133 + print(" *ZIP64*%n");
96.134 + }
96.135 +}
97.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
97.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipPath.java Tue Oct 12 12:51:48 2010 -0700
97.3 @@ -0,0 +1,964 @@
97.4 +/*
97.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
97.6 + *
97.7 + * Redistribution and use in source and binary forms, with or without
97.8 + * modification, are permitted provided that the following conditions
97.9 + * are met:
97.10 + *
97.11 + * - Redistributions of source code must retain the above copyright
97.12 + * notice, this list of conditions and the following disclaimer.
97.13 + *
97.14 + * - Redistributions in binary form must reproduce the above copyright
97.15 + * notice, this list of conditions and the following disclaimer in the
97.16 + * documentation and/or other materials provided with the distribution.
97.17 + *
97.18 + * - Neither the name of Oracle nor the names of its
97.19 + * contributors may be used to endorse or promote products derived
97.20 + * from this software without specific prior written permission.
97.21 + *
97.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
97.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
97.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
97.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
97.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
97.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
97.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
97.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
97.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
97.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97.33 + */
97.34 +
97.35 +package com.sun.nio.zipfs;
97.36 +
97.37 +import java.io.File;
97.38 +import java.io.FilterInputStream;
97.39 +import java.io.IOException;
97.40 +import java.io.InputStream;
97.41 +import java.io.OutputStream;
97.42 +import java.net.URI;
97.43 +import java.nio.ByteBuffer;
97.44 +import java.nio.channels.FileChannel;
97.45 +import java.nio.channels.SeekableByteChannel;
97.46 +import java.nio.file.*;
97.47 +import java.nio.file.DirectoryStream.Filter;
97.48 +import java.nio.file.spi.FileSystemProvider;
97.49 +import java.nio.file.attribute.BasicFileAttributeView;
97.50 +import java.nio.file.attribute.FileAttribute;
97.51 +import java.nio.file.attribute.FileAttributeView;
97.52 +import java.nio.file.attribute.FileTime;
97.53 +import java.util.*;
97.54 +import java.util.regex.Matcher;
97.55 +import java.util.regex.Pattern;
97.56 +import static java.nio.file.StandardOpenOption.*;
97.57 +import static java.nio.file.StandardCopyOption.*;
97.58 +
97.59 +/**
97.60 + *
97.61 + * @author Xueming Shen, Rajendra Gutupalli,Jaya Hangal
97.62 + */
97.63 +
97.64 +public class ZipPath extends Path {
97.65 +
97.66 + private final ZipFileSystem zfs;
97.67 + private final byte[] path;
97.68 + private volatile int[] offsets;
97.69 + private int hashcode = 0; // cached hashcode (created lazily)
97.70 +
97.71 + ZipPath(ZipFileSystem zfs, byte[] path) {
97.72 + this(zfs, path, false);
97.73 + }
97.74 +
97.75 + ZipPath(ZipFileSystem zfs, byte[] path, boolean normalized)
97.76 + {
97.77 + this.zfs = zfs;
97.78 + if (normalized)
97.79 + this.path = path;
97.80 + else
97.81 + this.path = normalize(path);
97.82 + }
97.83 +
97.84 + @Override
97.85 + public ZipPath getRoot() {
97.86 + if (this.isAbsolute())
97.87 + return new ZipPath(zfs, new byte[]{path[0]});
97.88 + else
97.89 + return null;
97.90 + }
97.91 +
97.92 + @Override
97.93 + public Path getName() {
97.94 + initOffsets();
97.95 + int count = offsets.length;
97.96 + if (count == 0)
97.97 + return null; // no elements so no name
97.98 + if (count == 1 && path[0] != '/')
97.99 + return this;
97.100 + int lastOffset = offsets[count-1];
97.101 + int len = path.length - lastOffset;
97.102 + byte[] result = new byte[len];
97.103 + System.arraycopy(path, lastOffset, result, 0, len);
97.104 + return new ZipPath(zfs, result);
97.105 + }
97.106 +
97.107 + @Override
97.108 + public ZipPath getParent() {
97.109 + initOffsets();
97.110 + int count = offsets.length;
97.111 + if (count == 0) // no elements so no parent
97.112 + return null;
97.113 + int len = offsets[count-1] - 1;
97.114 + if (len <= 0) // parent is root only (may be null)
97.115 + return getRoot();
97.116 + byte[] result = new byte[len];
97.117 + System.arraycopy(path, 0, result, 0, len);
97.118 + return new ZipPath(zfs, result);
97.119 + }
97.120 +
97.121 + @Override
97.122 + public int getNameCount() {
97.123 + initOffsets();
97.124 + return offsets.length;
97.125 + }
97.126 +
97.127 + @Override
97.128 + public ZipPath getName(int index) {
97.129 + initOffsets();
97.130 + if (index < 0 || index >= offsets.length)
97.131 + throw new IllegalArgumentException();
97.132 + int begin = offsets[index];
97.133 + int len;
97.134 + if (index == (offsets.length-1))
97.135 + len = path.length - begin;
97.136 + else
97.137 + len = offsets[index+1] - begin - 1;
97.138 + // construct result
97.139 + byte[] result = new byte[len];
97.140 + System.arraycopy(path, begin, result, 0, len);
97.141 + return new ZipPath(zfs, result);
97.142 + }
97.143 +
97.144 + @Override
97.145 + public ZipPath subpath(int beginIndex, int endIndex) {
97.146 + initOffsets();
97.147 + if (beginIndex < 0 ||
97.148 + beginIndex >= offsets.length ||
97.149 + endIndex > offsets.length ||
97.150 + beginIndex >= endIndex)
97.151 + throw new IllegalArgumentException();
97.152 +
97.153 + // starting offset and length
97.154 + int begin = offsets[beginIndex];
97.155 + int len;
97.156 + if (endIndex == offsets.length)
97.157 + len = path.length - begin;
97.158 + else
97.159 + len = offsets[endIndex] - begin - 1;
97.160 + // construct result
97.161 + byte[] result = new byte[len];
97.162 + System.arraycopy(path, begin, result, 0, len);
97.163 + return new ZipPath(zfs, result);
97.164 + }
97.165 +
97.166 + @Override
97.167 + public ZipPath toRealPath(boolean resolveLinks) throws IOException {
97.168 + ZipPath realPath = new ZipPath(zfs, getResolvedPath());
97.169 + realPath.checkAccess();
97.170 + return realPath;
97.171 + }
97.172 +
97.173 + @Override
97.174 + public boolean isHidden() {
97.175 + return false;
97.176 + }
97.177 +
97.178 + @Override
97.179 + public ZipPath toAbsolutePath() {
97.180 + if (isAbsolute()) {
97.181 + return this;
97.182 + } else {
97.183 + //add / bofore the existing path
97.184 + byte[] defaultdir = zfs.getDefaultDir().path;
97.185 + int defaultlen = defaultdir.length;
97.186 + boolean endsWith = (defaultdir[defaultlen - 1] == '/');
97.187 + byte[] t = null;
97.188 + if (endsWith)
97.189 + t = new byte[defaultlen + path.length];
97.190 + else
97.191 + t = new byte[defaultlen + 1 + path.length];
97.192 + System.arraycopy(defaultdir, 0, t, 0, defaultlen);
97.193 + if (!endsWith)
97.194 + t[defaultlen++] = '/';
97.195 + System.arraycopy(path, 0, t, defaultlen, path.length);
97.196 + return new ZipPath(zfs, t, true); // normalized
97.197 + }
97.198 + }
97.199 +
97.200 + @Override
97.201 + public URI toUri() {
97.202 + String zfPath = zfs.toString();
97.203 + if (File.separatorChar == '\\') // replace all separators by '/'
97.204 + zfPath = "/" + zfPath.replace("\\", "/");
97.205 + try {
97.206 + return new URI("zip", "",
97.207 + zfPath,
97.208 + zfs.getString(toAbsolutePath().path));
97.209 + } catch (Exception ex) {
97.210 + throw new AssertionError(ex);
97.211 + }
97.212 + }
97.213 +
97.214 + private boolean equalsNameAt(ZipPath other, int index) {
97.215 + int mbegin = offsets[index];
97.216 + int mlen = 0;
97.217 + if (index == (offsets.length-1))
97.218 + mlen = path.length - mbegin;
97.219 + else
97.220 + mlen = offsets[index + 1] - mbegin - 1;
97.221 + int obegin = other.offsets[index];
97.222 + int olen = 0;
97.223 + if (index == (other.offsets.length - 1))
97.224 + olen = other.path.length - obegin;
97.225 + else
97.226 + olen = other.offsets[index + 1] - obegin - 1;
97.227 + if (mlen != olen)
97.228 + return false;
97.229 + int n = 0;
97.230 + while(n < mlen) {
97.231 + if (path[mbegin + n] != other.path[obegin + n])
97.232 + return false;
97.233 + n++;
97.234 + }
97.235 + return true;
97.236 + }
97.237 +
97.238 + @Override
97.239 + public Path relativize(Path other) {
97.240 + final ZipPath o = checkPath(other);
97.241 + if (o.equals(this))
97.242 + return null;
97.243 + if (/* this.getFileSystem() != o.getFileSystem() || */
97.244 + this.isAbsolute() != o.isAbsolute()) {
97.245 + throw new IllegalArgumentException();
97.246 + }
97.247 + int mc = this.getNameCount();
97.248 + int oc = o.getNameCount();
97.249 + int n = Math.min(mc, oc);
97.250 + int i = 0;
97.251 + while (i < n) {
97.252 + if (!equalsNameAt(o, i))
97.253 + break;
97.254 + i++;
97.255 + }
97.256 + int dotdots = mc - i;
97.257 + int len = dotdots * 3 - 1;
97.258 + if (i < oc)
97.259 + len += (o.path.length - o.offsets[i] + 1);
97.260 + byte[] result = new byte[len];
97.261 +
97.262 + int pos = 0;
97.263 + while (dotdots > 0) {
97.264 + result[pos++] = (byte)'.';
97.265 + result[pos++] = (byte)'.';
97.266 + if (pos < len) // no tailing slash at the end
97.267 + result[pos++] = (byte)'/';
97.268 + dotdots--;
97.269 + }
97.270 + if (i < oc)
97.271 + System.arraycopy(o.path, o.offsets[i],
97.272 + result, pos,
97.273 + o.path.length - o.offsets[i]);
97.274 + return new ZipPath(getFileSystem(), result);
97.275 + }
97.276 +
97.277 + @Override
97.278 + public ZipFileSystem getFileSystem() {
97.279 + return zfs;
97.280 + }
97.281 +
97.282 + @Override
97.283 + public boolean isAbsolute() {
97.284 + return (this.path[0] == '/');
97.285 + }
97.286 +
97.287 + @Override
97.288 + public ZipPath resolve(Path other) {
97.289 + if (other == null)
97.290 + return this;
97.291 + final ZipPath o = checkPath(other);
97.292 + if (o.isAbsolute())
97.293 + return o;
97.294 + byte[] resolved = null;
97.295 + if (this.path[path.length - 1] == '/') {
97.296 + resolved = new byte[path.length + o.path.length];
97.297 + System.arraycopy(path, 0, resolved, 0, path.length);
97.298 + System.arraycopy(o.path, 0, resolved, path.length, o.path.length);
97.299 + } else {
97.300 + resolved = new byte[path.length + 1 + o.path.length];
97.301 + System.arraycopy(path, 0, resolved, 0, path.length);
97.302 + resolved[path.length] = '/';
97.303 + System.arraycopy(o.path, 0, resolved, path.length + 1, o.path.length);
97.304 + }
97.305 + return new ZipPath(zfs, resolved);
97.306 + }
97.307 +
97.308 + @Override
97.309 + public ZipPath resolve(String other) {
97.310 + return resolve(getFileSystem().getPath(other));
97.311 + }
97.312 +
97.313 + @Override
97.314 + public boolean startsWith(Path other) {
97.315 + final ZipPath o = checkPath(other);
97.316 + if (o.isAbsolute() != this.isAbsolute())
97.317 + return false;
97.318 + final int oCount = o.getNameCount();
97.319 + if (getNameCount() < oCount)
97.320 + return false;
97.321 + for (int i = 0; i < oCount; i++) {
97.322 + if (!o.getName(i).equals(getName(i)))
97.323 + return false;
97.324 + }
97.325 + return true;
97.326 + }
97.327 +
97.328 + @Override
97.329 + public boolean endsWith(Path other) {
97.330 + final ZipPath o = checkPath(other);
97.331 + if (o.isAbsolute())
97.332 + return this.isAbsolute() ? this.equals(o) : false;
97.333 + int i = o.getNameCount();
97.334 + int j = this.getNameCount();
97.335 + if (j < i)
97.336 + return false;
97.337 + for (--i, --j; i >= 0; i--, j--) {
97.338 + if (!o.getName(i).equals(this.getName(j)))
97.339 + return false;
97.340 + }
97.341 + return true;
97.342 + }
97.343 +
97.344 + @Override
97.345 + public Path normalize() {
97.346 + byte[] resolved = getResolved();
97.347 + if (resolved == path) // no change
97.348 + return this;
97.349 + if (resolved.length == 0)
97.350 + return null;
97.351 + return new ZipPath(zfs, resolved, true);
97.352 + }
97.353 +
97.354 + private ZipPath checkPath(Path path) {
97.355 + if (path == null)
97.356 + throw new NullPointerException();
97.357 + if (!(path instanceof ZipPath))
97.358 + throw new ProviderMismatchException();
97.359 + return (ZipPath) path;
97.360 + }
97.361 +
97.362 + // create offset list if not already created
97.363 + private void initOffsets() {
97.364 + if (offsets == null) {
97.365 + int count, index;
97.366 + // count names
97.367 + count = 0;
97.368 + index = 0;
97.369 + while (index < path.length) {
97.370 + byte c = path[index++];
97.371 + if (c != '/') {
97.372 + count++;
97.373 + while (index < path.length && path[index] != '/')
97.374 + index++;
97.375 + }
97.376 + }
97.377 + // populate offsets
97.378 + int[] result = new int[count];
97.379 + count = 0;
97.380 + index = 0;
97.381 + while (index < path.length) {
97.382 + byte c = path[index];
97.383 + if (c == '/') {
97.384 + index++;
97.385 + } else {
97.386 + result[count++] = index++;
97.387 + while (index < path.length && path[index] != '/')
97.388 + index++;
97.389 + }
97.390 + }
97.391 + synchronized (this) {
97.392 + if (offsets == null)
97.393 + offsets = result;
97.394 + }
97.395 + }
97.396 + }
97.397 +
97.398 + // resolved path for locating zip entry inside the zip file,
97.399 + // the result path does not contain ./ and .. components
97.400 + private volatile byte[] resolved = null;
97.401 + byte[] getResolvedPath() {
97.402 + byte[] r = resolved;
97.403 + if (r == null) {
97.404 + if (isAbsolute())
97.405 + r = getResolved();
97.406 + else
97.407 + r = toAbsolutePath().getResolvedPath();
97.408 + if (r[0] == '/')
97.409 + r = Arrays.copyOfRange(r, 1, r.length);
97.410 + resolved = r;
97.411 + }
97.412 + return resolved;
97.413 + }
97.414 +
97.415 + // removes redundant slashs, replace "\" to zip separator "/"
97.416 + // and check for invalid characters
97.417 + private byte[] normalize(byte[] path) {
97.418 + if (path.length == 0)
97.419 + return path;
97.420 + byte prevC = 0;
97.421 + for (int i = 0; i < path.length; i++) {
97.422 + byte c = path[i];
97.423 + if (c == '\\')
97.424 + return normalize(path, i);
97.425 + if (c == (byte)'/' && prevC == '/')
97.426 + return normalize(path, i - 1);
97.427 + if (c == '\u0000')
97.428 + throw new InvalidPathException(zfs.getString(path),
97.429 + "Path: nul character not allowed");
97.430 + prevC = c;
97.431 + }
97.432 + return path;
97.433 + }
97.434 +
97.435 + private byte[] normalize(byte[] path, int off) {
97.436 + byte[] to = new byte[path.length];
97.437 + int n = 0;
97.438 + while (n < off) {
97.439 + to[n] = path[n];
97.440 + n++;
97.441 + }
97.442 + int m = n;
97.443 + byte prevC = 0;
97.444 + while (n < path.length) {
97.445 + byte c = path[n++];
97.446 + if (c == (byte)'\\')
97.447 + c = (byte)'/';
97.448 + if (c == (byte)'/' && prevC == (byte)'/')
97.449 + continue;
97.450 + if (c == '\u0000')
97.451 + throw new InvalidPathException(zfs.getString(path),
97.452 + "Path: nul character not allowed");
97.453 + to[m++] = c;
97.454 + prevC = c;
97.455 + }
97.456 + if (m > 1 && to[m - 1] == '/')
97.457 + m--;
97.458 + return (m == to.length)? to : Arrays.copyOf(to, m);
97.459 + }
97.460 +
97.461 + // Remove DotSlash(./) and resolve DotDot (..) components
97.462 + private byte[] getResolved() {
97.463 + if (path.length == 0)
97.464 + return path;
97.465 + for (int i = 0; i < path.length; i++) {
97.466 + byte c = path[i];
97.467 + if (c == (byte)'.')
97.468 + return resolve0();
97.469 + }
97.470 + return path;
97.471 + }
97.472 +
97.473 + // TBD: performance, avoid initOffsets
97.474 + private byte[] resolve0() {
97.475 + byte[] to = new byte[path.length];
97.476 + int nc = getNameCount();
97.477 + int[] lastM = new int[nc];
97.478 + int lastMOff = -1;
97.479 + int m = 0;
97.480 + for (int i = 0; i < nc; i++) {
97.481 + int n = offsets[i];
97.482 + int len = (i == offsets.length - 1)?
97.483 + (path.length - n):(offsets[i + 1] - n - 1);
97.484 + if (len == 1 && path[n] == (byte)'.')
97.485 + continue;
97.486 + if (len == 2 && path[n] == '.' && path[n + 1] == '.') {
97.487 + if (lastMOff >= 0) {
97.488 + m = lastM[lastMOff--]; // retreat
97.489 + continue;
97.490 + }
97.491 + if (path[0] == '/') { // "/../xyz" skip
97.492 + if (m == 0)
97.493 + to[m++] = '/';
97.494 + } else { // "../xyz" -> "../xyz"
97.495 + if (m != 0 && to[m-1] != '/')
97.496 + to[m++] = '/';
97.497 + while (len-- > 0)
97.498 + to[m++] = path[n++];
97.499 + }
97.500 + continue;
97.501 + }
97.502 + if (m == 0 && path[0] == '/' || // absolute path
97.503 + m != 0 && to[m-1] != '/') { // not the first name
97.504 + to[m++] = '/';
97.505 + }
97.506 + lastM[++lastMOff] = m;
97.507 + while (len-- > 0)
97.508 + to[m++] = path[n++];
97.509 + }
97.510 + if (m > 1 && to[m - 1] == '/')
97.511 + m--;
97.512 + return (m == to.length)? to : Arrays.copyOf(to, m);
97.513 + }
97.514 +
97.515 + @Override
97.516 + public String toString() {
97.517 + return zfs.getString(path);
97.518 + }
97.519 +
97.520 + @Override
97.521 + public int hashCode() {
97.522 + int h = hashcode;
97.523 + if (h == 0)
97.524 + hashcode = h = Arrays.hashCode(path);
97.525 + return h;
97.526 + }
97.527 +
97.528 + @Override
97.529 + public boolean equals(Object obj) {
97.530 + return obj != null &&
97.531 + obj instanceof ZipPath &&
97.532 + this.zfs == ((ZipPath)obj).zfs &&
97.533 + compareTo((Path) obj) == 0;
97.534 + }
97.535 +
97.536 + @Override
97.537 + public int compareTo(Path other) {
97.538 + final ZipPath o = checkPath(other);
97.539 + int len1 = this.path.length;
97.540 + int len2 = o.path.length;
97.541 +
97.542 + int n = Math.min(len1, len2);
97.543 + byte v1[] = this.path;
97.544 + byte v2[] = o.path;
97.545 +
97.546 + int k = 0;
97.547 + while (k < n) {
97.548 + int c1 = v1[k] & 0xff;
97.549 + int c2 = v2[k] & 0xff;
97.550 + if (c1 != c2)
97.551 + return c1 - c2;
97.552 + k++;
97.553 + }
97.554 + return len1 - len2;
97.555 + }
97.556 +
97.557 + @Override
97.558 + public Path createSymbolicLink(
97.559 + Path target, FileAttribute<?>... attrs) throws IOException {
97.560 + throw new UnsupportedOperationException("Not supported.");
97.561 + }
97.562 +
97.563 + @Override
97.564 + public Path createLink(
97.565 + Path existing) throws IOException {
97.566 + throw new UnsupportedOperationException("Not supported.");
97.567 + }
97.568 +
97.569 + @Override
97.570 + public Path readSymbolicLink() throws IOException {
97.571 + throw new UnsupportedOperationException("Not supported.");
97.572 + }
97.573 +
97.574 + @Override
97.575 + public Path createDirectory(FileAttribute<?>... attrs)
97.576 + throws IOException
97.577 + {
97.578 + zfs.createDirectory(getResolvedPath(), attrs);
97.579 + return this;
97.580 + }
97.581 +
97.582 + public final Path createFile(FileAttribute<?>... attrs)
97.583 + throws IOException
97.584 + {
97.585 + OutputStream os = newOutputStream(CREATE_NEW, WRITE);
97.586 + try {
97.587 + os.close();
97.588 + } catch (IOException x) {}
97.589 + return this;
97.590 + }
97.591 +
97.592 + @Override
97.593 + public InputStream newInputStream(OpenOption... options)
97.594 + throws IOException {
97.595 + if (options.length > 0) {
97.596 + for (OpenOption opt : options) {
97.597 + if (opt != READ)
97.598 + throw new UnsupportedOperationException("'" + opt + "' not allowed");
97.599 + }
97.600 + }
97.601 + return zfs.newInputStream(getResolvedPath());
97.602 + }
97.603 +
97.604 + private static final DirectoryStream.Filter<Path> acceptAllFilter =
97.605 + new DirectoryStream.Filter<Path>() {
97.606 + @Override public boolean accept(Path entry) { return true; }
97.607 + };
97.608 +
97.609 + @Override
97.610 + public final DirectoryStream<Path> newDirectoryStream() throws IOException {
97.611 + return newDirectoryStream(acceptAllFilter);
97.612 + }
97.613 +
97.614 + @Override
97.615 + public DirectoryStream<Path> newDirectoryStream(Filter<? super Path> filter)
97.616 + throws IOException
97.617 + {
97.618 + return new ZipDirectoryStream(this, filter);
97.619 + }
97.620 +
97.621 + @Override
97.622 + public final DirectoryStream<Path> newDirectoryStream(String glob)
97.623 + throws IOException
97.624 + {
97.625 + // avoid creating a matcher if all entries are required.
97.626 + if (glob.equals("*"))
97.627 + return newDirectoryStream();
97.628 +
97.629 + // create a matcher and return a filter that uses it.
97.630 + final PathMatcher matcher = getFileSystem().getPathMatcher("glob:" + glob);
97.631 + DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
97.632 + @Override
97.633 + public boolean accept(Path entry) {
97.634 + return matcher.matches(entry.getName());
97.635 + }
97.636 + };
97.637 + return newDirectoryStream(filter);
97.638 + }
97.639 +
97.640 + @Override
97.641 + public final void delete() throws IOException {
97.642 + zfs.deleteFile(getResolvedPath(), true);
97.643 + }
97.644 +
97.645 + @Override
97.646 + public final void deleteIfExists() throws IOException {
97.647 + zfs.deleteFile(getResolvedPath(), false);
97.648 + }
97.649 +
97.650 + ZipFileAttributes getAttributes() throws IOException
97.651 + {
97.652 + ZipFileAttributes zfas = zfs.getFileAttributes(getResolvedPath());
97.653 + if (zfas == null)
97.654 + throw new NoSuchFileException(toString());
97.655 + return zfas;
97.656 + }
97.657 +
97.658 + @Override
97.659 + @SuppressWarnings("unchecked")
97.660 + public <V extends FileAttributeView> V getFileAttributeView(Class<V> type,
97.661 + LinkOption... options)
97.662 + {
97.663 + return (V)ZipFileAttributeView.get(this, type);
97.664 + }
97.665 +
97.666 + @Override
97.667 + public void setAttribute(String attribute,
97.668 + Object value,
97.669 + LinkOption... options)
97.670 + throws IOException
97.671 + {
97.672 + String type = null;
97.673 + String attr = null;
97.674 + int colonPos = attribute.indexOf(':');
97.675 + if (colonPos == -1) {
97.676 + type = "basic";
97.677 + attr = attribute;
97.678 + } else {
97.679 + type = attribute.substring(0, colonPos++);
97.680 + attr = attribute.substring(colonPos);
97.681 + }
97.682 + ZipFileAttributeView view = ZipFileAttributeView.get(this, type);
97.683 + if (view == null)
97.684 + throw new UnsupportedOperationException("view <" + view + "> is not supported");
97.685 + view.setAttribute(attr, value);
97.686 + }
97.687 +
97.688 + void setTimes(FileTime mtime, FileTime atime, FileTime ctime)
97.689 + throws IOException
97.690 + {
97.691 + zfs.setTimes(getResolvedPath(), mtime, atime, ctime);
97.692 + }
97.693 +
97.694 + private Object getAttributesImpl(String attribute, boolean domap)
97.695 + throws IOException
97.696 + {
97.697 + String view = null;
97.698 + String attr = null;
97.699 + int colonPos = attribute.indexOf(':');
97.700 + if (colonPos == -1) {
97.701 + view = "basic";
97.702 + attr = attribute;
97.703 + } else {
97.704 + view = attribute.substring(0, colonPos++);
97.705 + attr = attribute.substring(colonPos);
97.706 + }
97.707 + ZipFileAttributeView zfv = ZipFileAttributeView.get(this, view);
97.708 + if (zfv == null) {
97.709 + throw new UnsupportedOperationException("view not supported");
97.710 + }
97.711 + return zfv.getAttribute(attr, domap);
97.712 + }
97.713 +
97.714 + @Override
97.715 + public Object getAttribute(String attribute, LinkOption... options)
97.716 + throws IOException
97.717 + {
97.718 + return getAttributesImpl(attribute, false);
97.719 + }
97.720 +
97.721 + @Override
97.722 + public Map<String,?> readAttributes(String attribute, LinkOption... options)
97.723 + throws IOException
97.724 + {
97.725 + return (Map<String, ?>)getAttributesImpl(attribute, true);
97.726 + }
97.727 +
97.728 + @Override
97.729 + public FileStore getFileStore() throws IOException {
97.730 + // each ZipFileSystem only has one root (as requested for now)
97.731 + if (exists())
97.732 + return zfs.getFileStore(this);
97.733 + throw new NoSuchFileException(zfs.getString(path));
97.734 + }
97.735 +
97.736 + @Override
97.737 + public boolean isSameFile(Path other) throws IOException {
97.738 + if (other == null ||
97.739 + this.getFileSystem() != other.getFileSystem())
97.740 + return false;
97.741 + this.checkAccess();
97.742 + other.checkAccess();
97.743 + return Arrays.equals(this.getResolvedPath(),
97.744 + ((ZipPath)other).getResolvedPath());
97.745 + }
97.746 +
97.747 + public WatchKey register(
97.748 + WatchService watcher,
97.749 + WatchEvent.Kind<?>[] events,
97.750 + WatchEvent.Modifier... modifiers) {
97.751 + if (watcher == null || events == null || modifiers == null) {
97.752 + throw new NullPointerException();
97.753 + }
97.754 + throw new UnsupportedOperationException();
97.755 + }
97.756 +
97.757 + @Override
97.758 + public WatchKey register(WatchService watcher, WatchEvent.Kind<?>... events) {
97.759 + return register(watcher, events, new WatchEvent.Modifier[0]);
97.760 + }
97.761 +
97.762 + @Override
97.763 + public Iterator<Path> iterator() {
97.764 + return new Iterator<Path>() {
97.765 + private int i = 0;
97.766 +
97.767 + @Override
97.768 + public boolean hasNext() {
97.769 + return (i < getNameCount());
97.770 + }
97.771 +
97.772 + @Override
97.773 + public Path next() {
97.774 + if (i < getNameCount()) {
97.775 + Path result = getName(i);
97.776 + i++;
97.777 + return result;
97.778 + } else {
97.779 + throw new NoSuchElementException();
97.780 + }
97.781 + }
97.782 +
97.783 + @Override
97.784 + public void remove() {
97.785 + throw new ReadOnlyFileSystemException();
97.786 + }
97.787 + };
97.788 + }
97.789 +
97.790 + @Override
97.791 + public SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
97.792 + FileAttribute<?>... attrs)
97.793 + throws IOException
97.794 + {
97.795 + return zfs.newByteChannel(getResolvedPath(), options, attrs);
97.796 + }
97.797 +
97.798 +
97.799 + FileChannel newFileChannel(Set<? extends OpenOption> options,
97.800 + FileAttribute<?>... attrs)
97.801 + throws IOException
97.802 + {
97.803 + return zfs.newFileChannel(getResolvedPath(), options, attrs);
97.804 + }
97.805 +
97.806 + @Override
97.807 + public SeekableByteChannel newByteChannel(OpenOption... options)
97.808 + throws IOException {
97.809 + Set<OpenOption> set = new HashSet<OpenOption>(options.length);
97.810 + Collections.addAll(set, options);
97.811 + return newByteChannel(set);
97.812 + }
97.813 +
97.814 + @Override
97.815 + public void checkAccess(AccessMode... modes) throws IOException {
97.816 + boolean w = false;
97.817 + boolean x = false;
97.818 + for (AccessMode mode : modes) {
97.819 + switch (mode) {
97.820 + case READ:
97.821 + break;
97.822 + case WRITE:
97.823 + w = true;
97.824 + break;
97.825 + case EXECUTE:
97.826 + x = true;
97.827 + break;
97.828 + default:
97.829 + throw new UnsupportedOperationException();
97.830 + }
97.831 + }
97.832 + ZipFileAttributes attrs = zfs.getFileAttributes(getResolvedPath());
97.833 + if (attrs == null && (path.length != 1 || path[0] != '/'))
97.834 + throw new NoSuchFileException(toString());
97.835 + if (w) {
97.836 + if (zfs.isReadOnly())
97.837 + throw new AccessDeniedException(toString());
97.838 + }
97.839 + if (x)
97.840 + throw new AccessDeniedException(toString());
97.841 +
97.842 + }
97.843 +
97.844 + @Override
97.845 + public boolean exists() {
97.846 + if (path.length == 1 && path[0] == '/')
97.847 + return true;
97.848 + try {
97.849 + return zfs.exists(getResolvedPath());
97.850 + } catch (IOException x) {}
97.851 + return false;
97.852 + }
97.853 +
97.854 + @Override
97.855 + public boolean notExists() {
97.856 + return !exists();
97.857 + }
97.858 +
97.859 +
97.860 + @Override
97.861 + public OutputStream newOutputStream(OpenOption... options)
97.862 + throws IOException
97.863 + {
97.864 + if (options.length == 0)
97.865 + return zfs.newOutputStream(getResolvedPath(),
97.866 + CREATE_NEW, WRITE);
97.867 + return zfs.newOutputStream(getResolvedPath(), options);
97.868 + }
97.869 +
97.870 + @Override
97.871 + public Path moveTo(Path target, CopyOption... options)
97.872 + throws IOException
97.873 + {
97.874 + if (this.zfs.provider() == target.getFileSystem().provider() &&
97.875 + this.zfs.getZipFile().isSameFile(((ZipPath)target).zfs.getZipFile()))
97.876 + {
97.877 + zfs.copyFile(true,
97.878 + getResolvedPath(),
97.879 + ((ZipPath)target).getResolvedPath(),
97.880 + options);
97.881 + } else {
97.882 + copyToTarget(target, options);
97.883 + delete();
97.884 + }
97.885 + return target;
97.886 + }
97.887 +
97.888 + @Override
97.889 + public Path copyTo(Path target, CopyOption... options)
97.890 + throws IOException
97.891 + {
97.892 + if (this.zfs.provider() == target.getFileSystem().provider() &&
97.893 + this.zfs.getZipFile().isSameFile(((ZipPath)target).zfs.getZipFile()))
97.894 + {
97.895 + zfs.copyFile(false,
97.896 + getResolvedPath(),
97.897 + ((ZipPath)target).getResolvedPath(),
97.898 + options);
97.899 + } else {
97.900 + copyToTarget(target, options);
97.901 + }
97.902 + return target;
97.903 + }
97.904 +
97.905 + private void copyToTarget(Path target, CopyOption... options)
97.906 + throws IOException
97.907 + {
97.908 + boolean replaceExisting = false;
97.909 + boolean copyAttrs = false;
97.910 + for (CopyOption opt : options) {
97.911 + if (opt == REPLACE_EXISTING)
97.912 + replaceExisting = true;
97.913 + else if (opt == COPY_ATTRIBUTES)
97.914 + copyAttrs = false;
97.915 + }
97.916 + // attributes of source file
97.917 + ZipFileAttributes zfas = getAttributes();
97.918 + // check if target exists
97.919 + boolean exists;
97.920 + if (replaceExisting) {
97.921 + try {
97.922 + target.deleteIfExists();
97.923 + exists = false;
97.924 + } catch (DirectoryNotEmptyException x) {
97.925 + exists = true;
97.926 + }
97.927 + } else {
97.928 + exists = target.exists();
97.929 + }
97.930 + if (exists)
97.931 + throw new FileAlreadyExistsException(target.toString());
97.932 +
97.933 + if (zfas.isDirectory()) {
97.934 + // create directory or file
97.935 + target.createDirectory();
97.936 + } else {
97.937 + InputStream is = zfs.newInputStream(getResolvedPath());
97.938 + try {
97.939 + OutputStream os = target.newOutputStream();
97.940 + try {
97.941 + byte[] buf = new byte[8192];
97.942 + int n = 0;
97.943 + while ((n = is.read(buf)) != -1) {
97.944 + os.write(buf, 0, n);
97.945 + }
97.946 + } finally {
97.947 + os.close();
97.948 + }
97.949 + } finally {
97.950 + is.close();
97.951 + }
97.952 + }
97.953 + if (copyAttrs) {
97.954 + BasicFileAttributeView view =
97.955 + target.getFileAttributeView(BasicFileAttributeView.class);
97.956 + try {
97.957 + view.setTimes(zfas.lastModifiedTime(), null, null);
97.958 + } catch (IOException x) {
97.959 + // rollback?
97.960 + try {
97.961 + target.delete();
97.962 + } catch (IOException ignore) { }
97.963 + throw x;
97.964 + }
97.965 + }
97.966 + }
97.967 +}
98.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
98.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipUtils.java Tue Oct 12 12:51:48 2010 -0700
98.3 @@ -0,0 +1,289 @@
98.4 +/*
98.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
98.6 + *
98.7 + * Redistribution and use in source and binary forms, with or without
98.8 + * modification, are permitted provided that the following conditions
98.9 + * are met:
98.10 + *
98.11 + * - Redistributions of source code must retain the above copyright
98.12 + * notice, this list of conditions and the following disclaimer.
98.13 + *
98.14 + * - Redistributions in binary form must reproduce the above copyright
98.15 + * notice, this list of conditions and the following disclaimer in the
98.16 + * documentation and/or other materials provided with the distribution.
98.17 + *
98.18 + * - Neither the name of Oracle nor the names of its
98.19 + * contributors may be used to endorse or promote products derived
98.20 + * from this software without specific prior written permission.
98.21 + *
98.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
98.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
98.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
98.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
98.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
98.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
98.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
98.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
98.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
98.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98.33 + */
98.34 +
98.35 +package com.sun.nio.zipfs;
98.36 +
98.37 +import java.io.IOException;
98.38 +import java.io.OutputStream;
98.39 +import java.util.Arrays;
98.40 +import java.util.Date;
98.41 +import java.util.regex.PatternSyntaxException;
98.42 +
98.43 +/**
98.44 + *
98.45 + * @author Xueming Shen
98.46 + */
98.47 +
98.48 +class ZipUtils {
98.49 +
98.50 + /*
98.51 + * Writes a 16-bit short to the output stream in little-endian byte order.
98.52 + */
98.53 + public static void writeShort(OutputStream os, int v) throws IOException {
98.54 + os.write((v >>> 0) & 0xff);
98.55 + os.write((v >>> 8) & 0xff);
98.56 + }
98.57 +
98.58 + /*
98.59 + * Writes a 32-bit int to the output stream in little-endian byte order.
98.60 + */
98.61 + public static void writeInt(OutputStream os, long v) throws IOException {
98.62 + os.write((int)((v >>> 0) & 0xff));
98.63 + os.write((int)((v >>> 8) & 0xff));
98.64 + os.write((int)((v >>> 16) & 0xff));
98.65 + os.write((int)((v >>> 24) & 0xff));
98.66 + }
98.67 +
98.68 + /*
98.69 + * Writes a 64-bit int to the output stream in little-endian byte order.
98.70 + */
98.71 + public static void writeLong(OutputStream os, long v) throws IOException {
98.72 + os.write((int)((v >>> 0) & 0xff));
98.73 + os.write((int)((v >>> 8) & 0xff));
98.74 + os.write((int)((v >>> 16) & 0xff));
98.75 + os.write((int)((v >>> 24) & 0xff));
98.76 + os.write((int)((v >>> 32) & 0xff));
98.77 + os.write((int)((v >>> 40) & 0xff));
98.78 + os.write((int)((v >>> 48) & 0xff));
98.79 + os.write((int)((v >>> 56) & 0xff));
98.80 + }
98.81 +
98.82 + /*
98.83 + * Writes an array of bytes to the output stream.
98.84 + */
98.85 + public static void writeBytes(OutputStream os, byte[] b)
98.86 + throws IOException
98.87 + {
98.88 + os.write(b, 0, b.length);
98.89 + }
98.90 +
98.91 + /*
98.92 + * Writes an array of bytes to the output stream.
98.93 + */
98.94 + public static void writeBytes(OutputStream os, byte[] b, int off, int len)
98.95 + throws IOException
98.96 + {
98.97 + os.write(b, off, len);
98.98 + }
98.99 +
98.100 + /*
98.101 + * Append a slash at the end, if it does not have one yet
98.102 + */
98.103 + public static byte[] toDirectoryPath(byte[] dir) {
98.104 + if (dir.length != 0 && dir[dir.length - 1] != '/') {
98.105 + dir = Arrays.copyOf(dir, dir.length + 1);
98.106 + dir[dir.length - 1] = '/';
98.107 + }
98.108 + return dir;
98.109 + }
98.110 +
98.111 + /*
98.112 + * Converts DOS time to Java time (number of milliseconds since epoch).
98.113 + */
98.114 + public static long dosToJavaTime(long dtime) {
98.115 + Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80),
98.116 + (int)(((dtime >> 21) & 0x0f) - 1),
98.117 + (int)((dtime >> 16) & 0x1f),
98.118 + (int)((dtime >> 11) & 0x1f),
98.119 + (int)((dtime >> 5) & 0x3f),
98.120 + (int)((dtime << 1) & 0x3e));
98.121 + return d.getTime();
98.122 + }
98.123 +
98.124 + /*
98.125 + * Converts Java time to DOS time.
98.126 + */
98.127 + public static long javaToDosTime(long time) {
98.128 + Date d = new Date(time);
98.129 + int year = d.getYear() + 1900;
98.130 + if (year < 1980) {
98.131 + return (1 << 21) | (1 << 16);
98.132 + }
98.133 + return (year - 1980) << 25 | (d.getMonth() + 1) << 21 |
98.134 + d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 |
98.135 + d.getSeconds() >> 1;
98.136 + }
98.137 +
98.138 + private static final String regexMetaChars = ".^$+{[]|()";
98.139 + private static final String globMetaChars = "\\*?[{";
98.140 + private static boolean isRegexMeta(char c) {
98.141 + return regexMetaChars.indexOf(c) != -1;
98.142 + }
98.143 + private static boolean isGlobMeta(char c) {
98.144 + return globMetaChars.indexOf(c) != -1;
98.145 + }
98.146 + private static char EOL = 0; //TBD
98.147 + private static char next(String glob, int i) {
98.148 + if (i < glob.length()) {
98.149 + return glob.charAt(i);
98.150 + }
98.151 + return EOL;
98.152 + }
98.153 +
98.154 + /*
98.155 + * Creates a regex pattern from the given glob expression.
98.156 + *
98.157 + * @throws PatternSyntaxException
98.158 + */
98.159 + public static String toRegexPattern(String globPattern) {
98.160 + boolean inGroup = false;
98.161 + StringBuilder regex = new StringBuilder("^");
98.162 +
98.163 + int i = 0;
98.164 + while (i < globPattern.length()) {
98.165 + char c = globPattern.charAt(i++);
98.166 + switch (c) {
98.167 + case '\\':
98.168 + // escape special characters
98.169 + if (i == globPattern.length()) {
98.170 + throw new PatternSyntaxException("No character to escape",
98.171 + globPattern, i - 1);
98.172 + }
98.173 + char next = globPattern.charAt(i++);
98.174 + if (isGlobMeta(next) || isRegexMeta(next)) {
98.175 + regex.append('\\');
98.176 + }
98.177 + regex.append(next);
98.178 + break;
98.179 + case '/':
98.180 + regex.append(c);
98.181 + break;
98.182 + case '[':
98.183 + // don't match name separator in class
98.184 + regex.append("[[^/]&&[");
98.185 + if (next(globPattern, i) == '^') {
98.186 + // escape the regex negation char if it appears
98.187 + regex.append("\\^");
98.188 + i++;
98.189 + } else {
98.190 + // negation
98.191 + if (next(globPattern, i) == '!') {
98.192 + regex.append('^');
98.193 + i++;
98.194 + }
98.195 + // hyphen allowed at start
98.196 + if (next(globPattern, i) == '-') {
98.197 + regex.append('-');
98.198 + i++;
98.199 + }
98.200 + }
98.201 + boolean hasRangeStart = false;
98.202 + char last = 0;
98.203 + while (i < globPattern.length()) {
98.204 + c = globPattern.charAt(i++);
98.205 + if (c == ']') {
98.206 + break;
98.207 + }
98.208 + if (c == '/') {
98.209 + throw new PatternSyntaxException("Explicit 'name separator' in class",
98.210 + globPattern, i - 1);
98.211 + }
98.212 + // TBD: how to specify ']' in a class?
98.213 + if (c == '\\' || c == '[' ||
98.214 + c == '&' && next(globPattern, i) == '&') {
98.215 + // escape '\', '[' or "&&" for regex class
98.216 + regex.append('\\');
98.217 + }
98.218 + regex.append(c);
98.219 +
98.220 + if (c == '-') {
98.221 + if (!hasRangeStart) {
98.222 + throw new PatternSyntaxException("Invalid range",
98.223 + globPattern, i - 1);
98.224 + }
98.225 + if ((c = next(globPattern, i++)) == EOL || c == ']') {
98.226 + break;
98.227 + }
98.228 + if (c < last) {
98.229 + throw new PatternSyntaxException("Invalid range",
98.230 + globPattern, i - 3);
98.231 + }
98.232 + regex.append(c);
98.233 + hasRangeStart = false;
98.234 + } else {
98.235 + hasRangeStart = true;
98.236 + last = c;
98.237 + }
98.238 + }
98.239 + if (c != ']') {
98.240 + throw new PatternSyntaxException("Missing ']", globPattern, i - 1);
98.241 + }
98.242 + regex.append("]]");
98.243 + break;
98.244 + case '{':
98.245 + if (inGroup) {
98.246 + throw new PatternSyntaxException("Cannot nest groups",
98.247 + globPattern, i - 1);
98.248 + }
98.249 + regex.append("(?:(?:");
98.250 + inGroup = true;
98.251 + break;
98.252 + case '}':
98.253 + if (inGroup) {
98.254 + regex.append("))");
98.255 + inGroup = false;
98.256 + } else {
98.257 + regex.append('}');
98.258 + }
98.259 + break;
98.260 + case ',':
98.261 + if (inGroup) {
98.262 + regex.append(")|(?:");
98.263 + } else {
98.264 + regex.append(',');
98.265 + }
98.266 + break;
98.267 + case '*':
98.268 + if (next(globPattern, i) == '*') {
98.269 + // crosses directory boundaries
98.270 + regex.append(".*");
98.271 + i++;
98.272 + } else {
98.273 + // within directory boundary
98.274 + regex.append("[^/]*");
98.275 + }
98.276 + break;
98.277 + case '?':
98.278 + regex.append("[^/]");
98.279 + break;
98.280 + default:
98.281 + if (isRegexMeta(c)) {
98.282 + regex.append('\\');
98.283 + }
98.284 + regex.append(c);
98.285 + }
98.286 + }
98.287 + if (inGroup) {
98.288 + throw new PatternSyntaxException("Missing '}", globPattern, i - 1);
98.289 + }
98.290 + return regex.append('$').toString();
98.291 + }
98.292 +}
99.1 --- a/src/share/native/java/lang/System.c Thu Oct 07 15:12:19 2010 -0700
99.2 +++ b/src/share/native/java/lang/System.c Tue Oct 12 12:51:48 2010 -0700
99.3 @@ -97,14 +97,20 @@
99.4 } else ((void) 0)
99.5
99.6 #ifndef VENDOR /* Third party may overwrite this. */
99.7 -#define VENDOR "Sun Microsystems Inc."
99.8 -#define VENDOR_URL "http://java.sun.com/"
99.9 +#define VENDOR "Oracle Corporation"
99.10 +#define VENDOR_URL "http://java.oracle.com/"
99.11 #define VENDOR_URL_BUG "http://java.sun.com/cgi-bin/bugreport.cgi"
99.12 #endif
99.13
99.14 #define JAVA_MAX_SUPPORTED_VERSION 51
99.15 #define JAVA_MAX_SUPPORTED_MINOR_VERSION 0
99.16
99.17 +#ifdef JAVA_SPECIFICATION_VENDOR /* Third party may NOT overwrite this. */
99.18 + #error "ERROR: No override of JAVA_SPECIFICATION_VENDOR is allowed"
99.19 +#else
99.20 + #define JAVA_SPECIFICATION_VENDOR "Oracle Corporation"
99.21 +#endif
99.22 +
99.23 static int fmtdefault; // boolean value
99.24 jobject fillI18nProps(JNIEnv *env, jobject props, char *baseKey,
99.25 char *platformDispVal, char *platformFmtVal,
99.26 @@ -185,7 +191,8 @@
99.27 JDK_MAJOR_VERSION "." JDK_MINOR_VERSION);
99.28 PUTPROP(props, "java.specification.name",
99.29 "Java Platform API Specification");
99.30 - PUTPROP(props, "java.specification.vendor", "Sun Microsystems Inc.");
99.31 + PUTPROP(props, "java.specification.vendor",
99.32 + JAVA_SPECIFICATION_VENDOR);
99.33
99.34 PUTPROP(props, "java.version", RELEASE);
99.35 PUTPROP(props, "java.vendor", VENDOR);
99.36 @@ -239,7 +246,7 @@
99.37 /* Printing properties */
99.38 /* Note: java.awt.printerjob is an implementation private property which
99.39 * just happens to have a java.* name because it is referenced in
99.40 - * a java.awt class. It is the mechanism by which the Sun implementation
99.41 + * a java.awt class. It is the mechanism by which the implementation
99.42 * finds the appropriate class in the JRE for the platform.
99.43 * It is explicitly not designed to be overridden by clients as
99.44 * a way of replacing the implementation class, and in any case
99.45 @@ -267,7 +274,7 @@
99.46 /* Java2D properties */
99.47 /* Note: java.awt.graphicsenv is an implementation private property which
99.48 * just happens to have a java.* name because it is referenced in
99.49 - * a java.awt class. It is the mechanism by which the Sun implementation
99.50 + * a java.awt class. It is the mechanism by which the implementation
99.51 * finds the appropriate class in the JRE for the platform.
99.52 * It is explicitly not designed to be overridden by clients as
99.53 * a way of replacing the implementation class, and in any case
100.1 --- a/src/share/sample/nio/file/Chmod.java Thu Oct 07 15:12:19 2010 -0700
100.2 +++ b/src/share/sample/nio/file/Chmod.java Tue Oct 12 12:51:48 2010 -0700
100.3 @@ -285,18 +285,12 @@
100.4 }
100.5
100.6 @Override
100.7 - public FileVisitResult preVisitDirectory(FileRef dir) {
100.8 + public FileVisitResult preVisitDirectory(FileRef dir, BasicFileAttributes attrs) {
100.9 chmod(dir, changer);
100.10 return CONTINUE;
100.11 }
100.12
100.13 @Override
100.14 - public FileVisitResult preVisitDirectoryFailed(FileRef dir, IOException exc) {
100.15 - System.err.println("WARNING: " + exc);
100.16 - return CONTINUE;
100.17 - }
100.18 -
100.19 - @Override
100.20 public FileVisitResult visitFile(FileRef file, BasicFileAttributes attrs) {
100.21 chmod(file, changer);
100.22 return CONTINUE;
101.1 --- a/src/share/sample/nio/file/Copy.java Thu Oct 07 15:12:19 2010 -0700
101.2 +++ b/src/share/sample/nio/file/Copy.java Tue Oct 12 12:51:48 2010 -0700
101.3 @@ -85,7 +85,7 @@
101.4 }
101.5
101.6 @Override
101.7 - public FileVisitResult preVisitDirectory(Path dir) {
101.8 + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
101.9 // before visiting entries in a directory we copy the directory
101.10 // (okay if directory already exists).
101.11 CopyOption[] options = (preserve) ?
101.12 @@ -104,19 +104,9 @@
101.13 }
101.14
101.15 @Override
101.16 - public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
101.17 - System.err.format("Unable to copy: %s: %s%n", dir, exc);
101.18 - return CONTINUE;
101.19 - }
101.20 -
101.21 - @Override
101.22 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
101.23 - if (attrs.isDirectory()) {
101.24 - System.err.println("cycle detected: " + file);
101.25 - } else {
101.26 - copyFile(file, target.resolve(source.relativize(file)),
101.27 - prompt, preserve);
101.28 - }
101.29 + copyFile(file, target.resolve(source.relativize(file)),
101.30 + prompt, preserve);
101.31 return CONTINUE;
101.32 }
101.33
101.34 @@ -137,7 +127,11 @@
101.35
101.36 @Override
101.37 public FileVisitResult visitFileFailed(Path file, IOException exc) {
101.38 - System.err.format("Unable to copy: %s: %s%n", file, exc);
101.39 + if (exc instanceof FileSystemLoopException) {
101.40 + System.err.println("cycle detected: " + file);
101.41 + } else {
101.42 + System.err.format("Unable to copy: %s: %s%n", file, exc);
101.43 + }
101.44 return CONTINUE;
101.45 }
101.46 }
102.1 --- a/src/share/sample/nio/file/WatchDir.java Thu Oct 07 15:12:19 2010 -0700
102.2 +++ b/src/share/sample/nio/file/WatchDir.java Tue Oct 12 12:51:48 2010 -0700
102.3 @@ -78,12 +78,10 @@
102.4 // register directory and sub-directories
102.5 Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
102.6 @Override
102.7 - public FileVisitResult preVisitDirectory(Path dir) {
102.8 - try {
102.9 - register(dir);
102.10 - } catch (IOException x) {
102.11 - throw new IOError(x);
102.12 - }
102.13 + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
102.14 + throws IOException
102.15 + {
102.16 + register(dir);
102.17 return FileVisitResult.CONTINUE;
102.18 }
102.19 });
103.1 --- a/src/solaris/classes/java/lang/UNIXProcess.java.linux Thu Oct 07 15:12:19 2010 -0700
103.2 +++ b/src/solaris/classes/java/lang/UNIXProcess.java.linux Tue Oct 12 12:51:48 2010 -0700
103.3 @@ -176,7 +176,13 @@
103.4 }});
103.5 }
103.6
103.7 - synchronized void processExited(int exitcode) {
103.8 + void processExited(int exitcode) {
103.9 + synchronized (this) {
103.10 + this.exitcode = exitcode;
103.11 + hasExited = true;
103.12 + notifyAll();
103.13 + }
103.14 +
103.15 if (stdout instanceof ProcessPipeInputStream)
103.16 ((ProcessPipeInputStream) stdout).processExited();
103.17
103.18 @@ -185,10 +191,6 @@
103.19
103.20 if (stdin instanceof ProcessPipeOutputStream)
103.21 ((ProcessPipeOutputStream) stdin).processExited();
103.22 -
103.23 - this.exitcode = exitcode;
103.24 - hasExited = true;
103.25 - notifyAll();
103.26 }
103.27
103.28 public OutputStream getOutputStream() {
104.1 --- a/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java Thu Oct 07 15:12:19 2010 -0700
104.2 +++ b/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java Tue Oct 12 12:51:48 2010 -0700
104.3 @@ -64,7 +64,10 @@
104.4 accessor.setFile(fd, null);
104.5 accessor.setFiles(fd, null, null);
104.6 } else {
104.7 - accessor.setDirectory(fd, directory);
104.8 + // Fix 6987233: add the trailing slash if it's absent
104.9 + accessor.setDirectory(fd, directory +
104.10 + (directory.endsWith(File.separator) ?
104.11 + "" : File.separator));
104.12 accessor.setFile(fd, filenames[0]);
104.13 accessor.setFiles(fd, directory, filenames);
104.14 }
105.1 --- a/src/solaris/classes/sun/awt/X11/XBaseWindow.java Thu Oct 07 15:12:19 2010 -0700
105.2 +++ b/src/solaris/classes/sun/awt/X11/XBaseWindow.java Tue Oct 12 12:51:48 2010 -0700
105.3 @@ -705,12 +705,8 @@
105.4 throw new IllegalStateException("Attempt to resize uncreated window");
105.5 }
105.6 insLog.fine("Setting bounds on " + this + " to (" + x + ", " + y + "), " + width + "x" + height);
105.7 - if (width <= 0) {
105.8 - width = 1;
105.9 - }
105.10 - if (height <= 0) {
105.11 - height = 1;
105.12 - }
105.13 + width = Math.max(MIN_SIZE, width);
105.14 + height = Math.max(MIN_SIZE, height);
105.15 XToolkit.awtLock();
105.16 try {
105.17 XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), getWindow(), x,y,width,height);
106.1 --- a/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java Thu Oct 07 15:12:19 2010 -0700
106.2 +++ b/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java Tue Oct 12 12:51:48 2010 -0700
106.3 @@ -763,12 +763,8 @@
106.4 }
106.5
106.6 private void checkShellRectSize(Rectangle shellRect) {
106.7 - if (shellRect.width < 0) {
106.8 - shellRect.width = 1;
106.9 - }
106.10 - if (shellRect.height < 0) {
106.11 - shellRect.height = 1;
106.12 - }
106.13 + shellRect.width = Math.max(MIN_SIZE, shellRect.width);
106.14 + shellRect.height = Math.max(MIN_SIZE, shellRect.height);
106.15 }
106.16
106.17 private void checkShellRectPos(Rectangle shellRect) {
107.1 --- a/src/solaris/classes/sun/awt/X11/XEmbeddedFrame.java Thu Oct 07 15:12:19 2010 -0700
107.2 +++ b/src/solaris/classes/sun/awt/X11/XEmbeddedFrame.java Tue Oct 12 12:51:48 2010 -0700
107.3 @@ -28,9 +28,12 @@
107.4 import sun.awt.EmbeddedFrame;
107.5 import java.awt.*;
107.6 import java.awt.AWTKeyStroke;
107.7 +import java.util.logging.Logger;
107.8
107.9 public class XEmbeddedFrame extends EmbeddedFrame {
107.10
107.11 + private static final Logger log = Logger.getLogger(XEmbeddedFrame.class.getName());
107.12 +
107.13 long handle;
107.14 public XEmbeddedFrame() {
107.15 }
107.16 @@ -70,6 +73,21 @@
107.17 this(handle, supportsXEmbed, false);
107.18 }
107.19
107.20 + /*
107.21 + * The method shouldn't be called in case of active XEmbed.
107.22 + */
107.23 + public boolean traverseIn(boolean direction) {
107.24 + XEmbeddedFramePeer peer = (XEmbeddedFramePeer)getPeer();
107.25 + if (peer != null) {
107.26 + if (peer.supportsXEmbed() && peer.isXEmbedActive()) {
107.27 + log.fine("The method shouldn't be called when XEmbed is active!");
107.28 + } else {
107.29 + return super.traverseIn(direction);
107.30 + }
107.31 + }
107.32 + return false;
107.33 + }
107.34 +
107.35 protected boolean traverseOut(boolean direction) {
107.36 XEmbeddedFramePeer xefp = (XEmbeddedFramePeer) getPeer();
107.37 if (direction == FORWARD) {
107.38 @@ -81,6 +99,20 @@
107.39 return true;
107.40 }
107.41
107.42 + /*
107.43 + * The method shouldn't be called in case of active XEmbed.
107.44 + */
107.45 + public void synthesizeWindowActivation(boolean doActivate) {
107.46 + XEmbeddedFramePeer peer = (XEmbeddedFramePeer)getPeer();
107.47 + if (peer != null) {
107.48 + if (peer.supportsXEmbed() && peer.isXEmbedActive()) {
107.49 + log.fine("The method shouldn't be called when XEmbed is active!");
107.50 + } else {
107.51 + peer.synthesizeFocusInOut(doActivate);
107.52 + }
107.53 + }
107.54 + }
107.55 +
107.56 public void registerAccelerator(AWTKeyStroke stroke) {
107.57 XEmbeddedFramePeer xefp = (XEmbeddedFramePeer) getPeer();
107.58 if (xefp != null) {
108.1 --- a/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java Thu Oct 07 15:12:19 2010 -0700
108.2 +++ b/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java Tue Oct 12 12:51:48 2010 -0700
108.3 @@ -35,6 +35,8 @@
108.4 import sun.awt.EmbeddedFrame;
108.5 import sun.awt.SunToolkit;
108.6
108.7 +import static sun.awt.X11.XConstants.*;
108.8 +
108.9 public class XEmbeddedFramePeer extends XFramePeer {
108.10
108.11 private static final PlatformLogger xembedLog = PlatformLogger.getLogger("sun.awt.X11.xembed.XEmbeddedFramePeer");
108.12 @@ -305,4 +307,20 @@
108.13 EmbeddedFrame frame = (EmbeddedFrame)target;
108.14 frame.notifyModalBlocked(blocker, blocked);
108.15 }
108.16 +
108.17 + public void synthesizeFocusInOut(boolean doFocus) {
108.18 + XFocusChangeEvent xev = new XFocusChangeEvent();
108.19 +
108.20 + XToolkit.awtLock();
108.21 + try {
108.22 + xev.set_type(doFocus ? FocusIn : FocusOut);
108.23 + xev.set_window(getFocusProxy().getWindow());
108.24 + xev.set_mode(NotifyNormal);
108.25 + XlibWrapper.XSendEvent(XToolkit.getDisplay(), getFocusProxy().getWindow(), false,
108.26 + NoEventMask, xev.pData);
108.27 + } finally {
108.28 + XToolkit.awtUnlock();
108.29 + xev.dispose();
108.30 + }
108.31 + }
108.32 }
109.1 --- a/src/solaris/classes/sun/awt/X11/XToolkit.java Thu Oct 07 15:12:19 2010 -0700
109.2 +++ b/src/solaris/classes/sun/awt/X11/XToolkit.java Tue Oct 12 12:51:48 2010 -0700
109.3 @@ -1482,8 +1482,19 @@
109.4 try {
109.5 if (numberOfButtons == 0) {
109.6 numberOfButtons = getNumberOfButtonsImpl();
109.7 + numberOfButtons = (numberOfButtons > MAX_BUTTONS_SUPPORTED)? MAX_BUTTONS_SUPPORTED : numberOfButtons;
109.8 + //4th and 5th buttons are for wheel and shouldn't be reported as buttons.
109.9 + //If we have more than 3 physical buttons and a wheel, we report N-2 buttons.
109.10 + //If we have 3 physical buttons and a wheel, we report 3 buttons.
109.11 + //If we have 1,2,3 physical buttons, we report it as is i.e. 1,2 or 3 respectively.
109.12 + if (numberOfButtons >=5) {
109.13 + numberOfButtons -= 2;
109.14 + } else if (numberOfButtons == 4 || numberOfButtons ==5){
109.15 + numberOfButtons = 3;
109.16 + }
109.17 }
109.18 - return (numberOfButtons > MAX_BUTTONS_SUPPORTED)? MAX_BUTTONS_SUPPORTED : numberOfButtons;
109.19 + //Assume don't have to re-query the number again and again.
109.20 + return numberOfButtons;
109.21 } finally {
109.22 awtUnlock();
109.23 }
110.1 --- a/src/solaris/classes/sun/nio/fs/LinuxFileStore.java Thu Oct 07 15:12:19 2010 -0700
110.2 +++ b/src/solaris/classes/sun/nio/fs/LinuxFileStore.java Tue Oct 12 12:51:48 2010 -0700
110.3 @@ -156,9 +156,4 @@
110.4 return supportsFileAttributeView(UserDefinedFileAttributeView.class);
110.5 return super.supportsFileAttributeView(name);
110.6 }
110.7 -
110.8 - @Override
110.9 - boolean isLoopback() {
110.10 - return false;
110.11 - }
110.12 }
111.1 --- a/src/solaris/classes/sun/nio/fs/SolarisFileStore.java Thu Oct 07 15:12:19 2010 -0700
111.2 +++ b/src/solaris/classes/sun/nio/fs/SolarisFileStore.java Tue Oct 12 12:51:48 2010 -0700
111.3 @@ -108,9 +108,4 @@
111.4 return supportsFileAttributeView(UserDefinedFileAttributeView.class);
111.5 return super.supportsFileAttributeView(name);
111.6 }
111.7 -
111.8 - @Override
111.9 - boolean isLoopback() {
111.10 - return type().equals("lofs");
111.11 - }
111.12 }
112.1 --- a/src/solaris/classes/sun/nio/fs/UnixFileStore.java Thu Oct 07 15:12:19 2010 -0700
112.2 +++ b/src/solaris/classes/sun/nio/fs/UnixFileStore.java Tue Oct 12 12:51:48 2010 -0700
112.3 @@ -76,12 +76,6 @@
112.4 */
112.5 abstract UnixMountEntry findMountEntry() throws IOException;
112.6
112.7 - /**
112.8 - * Returns true if this file store represents a loopback file system that
112.9 - * will have the same device ID as underlying file system.
112.10 - */
112.11 - abstract boolean isLoopback();
112.12 -
112.13 UnixPath file() {
112.14 return file;
112.15 }
112.16 @@ -169,22 +163,13 @@
112.17 if (!(ob instanceof UnixFileStore))
112.18 return false;
112.19 UnixFileStore other = (UnixFileStore)ob;
112.20 - if (dev != other.dev)
112.21 - return false;
112.22 - // deviceIDs are equal but they may not be equal if one or both of
112.23 - // them is a loopback file system
112.24 - boolean thisIsLoopback = isLoopback();
112.25 - if (thisIsLoopback != other.isLoopback())
112.26 - return false; // one, but not both, are lofs
112.27 - if (!thisIsLoopback)
112.28 - return true; // neither is lofs
112.29 - // both are lofs so compare mount points
112.30 - return Arrays.equals(this.entry.dir(), other.entry.dir());
112.31 + return (this.dev == other.dev) &&
112.32 + Arrays.equals(this.entry.dir(), other.entry.dir());
112.33 }
112.34
112.35 @Override
112.36 public int hashCode() {
112.37 - return (int)(dev ^ (dev >>> 32));
112.38 + return (int)(dev ^ (dev >>> 32)) ^ Arrays.hashCode(entry.dir());
112.39 }
112.40
112.41 @Override
113.1 --- a/src/solaris/native/java/io/io_util_md.c Thu Oct 07 15:12:19 2010 -0700
113.2 +++ b/src/solaris/native/java/io/io_util_md.c Tue Oct 12 12:51:48 2010 -0700
113.3 @@ -83,8 +83,6 @@
113.4 close(devnull);
113.5 }
113.6 } else if (JVM_Close(fd) == -1) {
113.7 - SET_FD(this, fd, fid); // restore fd
113.8 - printf("JVM_Close returned -1\n");
113.9 - JNU_ThrowIOExceptionWithLastError(env, "close failed");
113.10 + JNU_ThrowIOExceptionWithLastError(env, "close failed");
113.11 }
113.12 }
114.1 --- a/src/solaris/native/java/net/Inet6AddressImpl.c Thu Oct 07 15:12:19 2010 -0700
114.2 +++ b/src/solaris/native/java/net/Inet6AddressImpl.c Tue Oct 12 12:51:48 2010 -0700
114.3 @@ -124,7 +124,7 @@
114.4 static int initialized = 0;
114.5
114.6 /*
114.7 - * Find an internet address for a given hostname. Not this this
114.8 + * Find an internet address for a given hostname. Note that this
114.9 * code only works for addresses of type INET. The translation
114.10 * of %d.%d.%d.%d to an address (int) occurs in java now, so the
114.11 * String "host" shouldn't *ever* be a %d.%d.%d.%d string
114.12 @@ -200,7 +200,7 @@
114.13 */
114.14 if (isspace((unsigned char)hostname[0])) {
114.15 JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
114.16 - (char *)hostname);
114.17 + hostname);
114.18 JNU_ReleaseStringPlatformChars(env, host, hostname);
114.19 return NULL;
114.20 }
114.21 @@ -210,8 +210,7 @@
114.22
114.23 if (error) {
114.24 /* report error */
114.25 - JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
114.26 - (char *)hostname);
114.27 + ThrowUnknownHostExceptionWithGaiError(env, hostname, error);
114.28 JNU_ReleaseStringPlatformChars(env, host, hostname);
114.29 return NULL;
114.30 } else {
114.31 @@ -407,7 +406,7 @@
114.32 addr |= ((caddr[1] <<16) & 0xff0000);
114.33 addr |= ((caddr[2] <<8) & 0xff00);
114.34 addr |= (caddr[3] & 0xff);
114.35 - memset((char *) &him4, 0, sizeof(him4));
114.36 + memset((void *) &him4, 0, sizeof(him4));
114.37 him4.sin_addr.s_addr = (uint32_t) htonl(addr);
114.38 him4.sin_family = AF_INET;
114.39 sa = (struct sockaddr *) &him4;
114.40 @@ -417,7 +416,7 @@
114.41 * For IPv6 address construct a sockaddr_in6 structure.
114.42 */
114.43 (*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr);
114.44 - memset((char *) &him6, 0, sizeof(him6));
114.45 + memset((void *) &him6, 0, sizeof(him6));
114.46 memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) );
114.47 him6.sin6_family = AF_INET6;
114.48 sa = (struct sockaddr *) &him6 ;
114.49 @@ -579,8 +578,8 @@
114.50 ifArray, ttl);
114.51 }
114.52
114.53 - memset((char *) caddr, 0, 16);
114.54 - memset((char *) &him6, 0, sizeof(him6));
114.55 + memset((void *) caddr, 0, 16);
114.56 + memset((void *) &him6, 0, sizeof(him6));
114.57 (*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr);
114.58 memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) );
114.59 him6.sin6_family = AF_INET6;
114.60 @@ -600,8 +599,8 @@
114.61 * for it.
114.62 */
114.63 if (!(IS_NULL(ifArray))) {
114.64 - memset((char *) caddr, 0, 16);
114.65 - memset((char *) &inf6, 0, sizeof(inf6));
114.66 + memset((void *) caddr, 0, 16);
114.67 + memset((void *) &inf6, 0, sizeof(inf6));
114.68 (*env)->GetByteArrayRegion(env, ifArray, 0, 16, caddr);
114.69 memcpy((void *)&(inf6.sin6_addr), caddr, sizeof(struct in6_addr) );
114.70 inf6.sin6_family = AF_INET6;
115.1 --- a/src/solaris/native/java/net/net_util_md.c Thu Oct 07 15:12:19 2010 -0700
115.2 +++ b/src/solaris/native/java/net/net_util_md.c Tue Oct 12 12:51:48 2010 -0700
115.3 @@ -61,6 +61,7 @@
115.4
115.5 getaddrinfo_f getaddrinfo_ptr = NULL;
115.6 freeaddrinfo_f freeaddrinfo_ptr = NULL;
115.7 +gai_strerror_f gai_strerror_ptr = NULL;
115.8 getnameinfo_f getnameinfo_ptr = NULL;
115.9
115.10 /*
115.11 @@ -342,11 +343,14 @@
115.12 freeaddrinfo_ptr = (freeaddrinfo_f)
115.13 JVM_FindLibraryEntry(RTLD_DEFAULT, "freeaddrinfo");
115.14
115.15 + gai_strerror_ptr = (gai_strerror_f)
115.16 + JVM_FindLibraryEntry(RTLD_DEFAULT, "gai_strerror");
115.17 +
115.18 getnameinfo_ptr = (getnameinfo_f)
115.19 JVM_FindLibraryEntry(RTLD_DEFAULT, "getnameinfo");
115.20
115.21 if (freeaddrinfo_ptr == NULL || getnameinfo_ptr == NULL) {
115.22 - /* Wee need all 3 of them */
115.23 + /* We need all 3 of them */
115.24 getaddrinfo_ptr = NULL;
115.25 }
115.26
115.27 @@ -355,6 +359,35 @@
115.28 #endif /* AF_INET6 */
115.29 }
115.30
115.31 +void ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
115.32 + const char* hostname,
115.33 + int gai_error)
115.34 +{
115.35 + int size;
115.36 + char *buf;
115.37 + const char *format = "%s: %s";
115.38 + const char *error_string =
115.39 + (gai_strerror_ptr == NULL) ? NULL : (*gai_strerror_ptr)(gai_error);
115.40 + if (error_string == NULL)
115.41 + error_string = "unknown error";
115.42 +
115.43 + size = strlen(format) + strlen(hostname) + strlen(error_string) + 2;
115.44 + buf = (char *) malloc(size);
115.45 + if (buf) {
115.46 + jstring s;
115.47 + sprintf(buf, format, hostname, error_string);
115.48 + s = JNU_NewStringPlatform(env, buf);
115.49 + if (s != NULL) {
115.50 + jobject x = JNU_NewObjectByName(env,
115.51 + "java/net/UnknownHostException",
115.52 + "(Ljava/lang/String;)V", s);
115.53 + if (x != NULL)
115.54 + (*env)->Throw(env, x);
115.55 + }
115.56 + free(buf);
115.57 + }
115.58 +}
115.59 +
115.60 void
115.61 NET_AllocSockaddr(struct sockaddr **him, int *len) {
115.62 #ifdef AF_INET6
115.63 @@ -1173,19 +1206,26 @@
115.64 }
115.65
115.66 /*
115.67 - * SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On Solaris need to
115.68 - * ensure that value is <= max_buf as otherwise we get
115.69 - * an invalid argument.
115.70 + * SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On Solaris we may need to clamp
115.71 + * the value when it exceeds the system limit.
115.72 */
115.73 #ifdef __solaris__
115.74 if (level == SOL_SOCKET) {
115.75 if (opt == SO_SNDBUF || opt == SO_RCVBUF) {
115.76 int sotype, arglen;
115.77 int *bufsize, maxbuf;
115.78 + int ret;
115.79 +
115.80 + /* Attempt with the original size */
115.81 + ret = setsockopt(fd, level, opt, arg, len);
115.82 + if ((ret == 0) || (ret == -1 && errno != ENOBUFS))
115.83 + return ret;
115.84 +
115.85 + /* Exceeded system limit so clamp and retry */
115.86
115.87 if (!init_max_buf) {
115.88 - tcp_max_buf = getParam("/dev/tcp", "tcp_max_buf", 64*1024);
115.89 - udp_max_buf = getParam("/dev/udp", "udp_max_buf", 64*1024);
115.90 + tcp_max_buf = getParam("/dev/tcp", "tcp_max_buf", 1024*1024);
115.91 + udp_max_buf = getParam("/dev/udp", "udp_max_buf", 2048*1024);
115.92 init_max_buf = 1;
115.93 }
115.94
116.1 --- a/src/solaris/native/java/net/net_util_md.h Thu Oct 07 15:12:19 2010 -0700
116.2 +++ b/src/solaris/native/java/net/net_util_md.h Tue Oct 12 12:51:48 2010 -0700
116.3 @@ -84,11 +84,13 @@
116.4
116.5 /* needed from libsocket on Solaris 8 */
116.6
116.7 -typedef int (*getaddrinfo_f)(const char *nodename, const char *servname,
116.8 - const struct addrinfo *hints, struct addrinfo **res);
116.9 +typedef int (*getaddrinfo_f)(const char *nodename, const char *servname,
116.10 + const struct addrinfo *hints, struct addrinfo **res);
116.11
116.12 typedef void (*freeaddrinfo_f)(struct addrinfo *);
116.13
116.14 +typedef const char * (*gai_strerror_f)(int ecode);
116.15 +
116.16 typedef int (*getnameinfo_f)(const struct sockaddr *, size_t,
116.17 char *, size_t, char *, size_t, int);
116.18
116.19 @@ -96,6 +98,10 @@
116.20 extern freeaddrinfo_f freeaddrinfo_ptr;
116.21 extern getnameinfo_f getnameinfo_ptr;
116.22
116.23 +void ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
116.24 + const char* hostname,
116.25 + int gai_error);
116.26 +
116.27 /* do we have address translation support */
116.28
116.29 extern jboolean NET_addrtransAvailable();
117.1 --- a/src/solaris/native/sun/awt/awt_InputMethod.c Thu Oct 07 15:12:19 2010 -0700
117.2 +++ b/src/solaris/native/sun/awt/awt_InputMethod.c Tue Oct 12 12:51:48 2010 -0700
117.3 @@ -1473,6 +1473,10 @@
117.4 static void DestroyXIMCallback(XIM im, XPointer client_data, XPointer call_data) {
117.5 /* mark that XIM server was destroyed */
117.6 X11im = NULL;
117.7 + JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
117.8 + /* free the old pX11IMData and set it to null. this also avoids crashing
117.9 + * the jvm if the XIM server reappears */
117.10 + X11InputMethodData *pX11IMData = getX11InputMethodData(env, currentX11InputMethodInstance);
117.11 }
117.12
117.13 /*
118.1 --- a/src/windows/classes/sun/awt/windows/WComponentPeer.java Thu Oct 07 15:12:19 2010 -0700
118.2 +++ b/src/windows/classes/sun/awt/windows/WComponentPeer.java Tue Oct 12 12:51:48 2010 -0700
118.3 @@ -556,24 +556,26 @@
118.4
118.5 Component target = (Component)getTarget();
118.6 Window window = SunToolkit.getContainingWindow(target);
118.7 - if (window != null && !window.isOpaque()) {
118.8 - // Non-opaque windows do not support heavyweight children.
118.9 - // Redirect all painting to the Window's Graphics instead.
118.10 - // The caller is responsible for calling the
118.11 - // WindowPeer.updateWindow() after painting has finished.
118.12 - int x = 0, y = 0;
118.13 - for (Component c = target; c != window; c = c.getParent()) {
118.14 - x += c.getX();
118.15 - y += c.getY();
118.16 - }
118.17 -
118.18 + if (window != null) {
118.19 Graphics g =
118.20 ((WWindowPeer)window.getPeer()).getTranslucentGraphics();
118.21 + // getTranslucentGraphics() returns non-null value for non-opaque windows only
118.22 + if (g != null) {
118.23 + // Non-opaque windows do not support heavyweight children.
118.24 + // Redirect all painting to the Window's Graphics instead.
118.25 + // The caller is responsible for calling the
118.26 + // WindowPeer.updateWindow() after painting has finished.
118.27 + int x = 0, y = 0;
118.28 + for (Component c = target; c != window; c = c.getParent()) {
118.29 + x += c.getX();
118.30 + y += c.getY();
118.31 + }
118.32
118.33 - g.translate(x, y);
118.34 - g.clipRect(0, 0, target.getWidth(), target.getHeight());
118.35 + g.translate(x, y);
118.36 + g.clipRect(0, 0, target.getWidth(), target.getHeight());
118.37
118.38 - return g;
118.39 + return g;
118.40 + }
118.41 }
118.42
118.43 SurfaceData surfaceData = this.surfaceData;
119.1 --- a/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java Thu Oct 07 15:12:19 2010 -0700
119.2 +++ b/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java Tue Oct 12 12:51:48 2010 -0700
119.3 @@ -191,9 +191,20 @@
119.4 public void activateEmbeddingTopLevel() {
119.5 }
119.6
119.7 - public void synthesizeWindowActivation(boolean doActivate) {
119.8 - ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(doActivate);
119.9 + public void synthesizeWindowActivation(final boolean doActivate) {
119.10 + if (!doActivate || EventQueue.isDispatchThread()) {
119.11 + ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(doActivate);
119.12 + } else {
119.13 + // To avoid focus concurrence b/w IE and EmbeddedFrame
119.14 + // activation is postponed by means of posting it to EDT.
119.15 + EventQueue.invokeLater(new Runnable() {
119.16 + public void run() {
119.17 + ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(true);
119.18 + }
119.19 + });
119.20 + }
119.21 }
119.22 +
119.23 public void registerAccelerator(AWTKeyStroke stroke) {}
119.24 public void unregisterAccelerator(AWTKeyStroke stroke) {}
119.25
120.1 --- a/src/windows/classes/sun/awt/windows/WWindowPeer.java Thu Oct 07 15:12:19 2010 -0700
120.2 +++ b/src/windows/classes/sun/awt/windows/WWindowPeer.java Tue Oct 12 12:51:48 2010 -0700
120.3 @@ -595,16 +595,6 @@
120.4 }
120.5
120.6 @Override
120.7 - public Graphics getGraphics() {
120.8 - synchronized (getStateLock()) {
120.9 - if (!isOpaque) {
120.10 - return getTranslucentGraphics();
120.11 - }
120.12 - }
120.13 - return super.getGraphics();
120.14 - }
120.15 -
120.16 - @Override
120.17 public void setBackground(Color c) {
120.18 super.setBackground(c);
120.19 synchronized (getStateLock()) {
121.1 --- a/src/windows/lib/tzmappings Thu Oct 07 15:12:19 2010 -0700
121.2 +++ b/src/windows/lib/tzmappings Tue Oct 12 12:51:48 2010 -0700
121.3 @@ -1,5 +1,4 @@
121.4 #
121.5 -#
121.6 # This file describes mapping information between Windows and Java
121.7 # time zones.
121.8 # Format: Each line should include a colon separated fields of Windows
121.9 @@ -11,7 +10,7 @@
121.10 # NOTE
121.11 # This table format is not a public interface of any Java
121.12 # platforms. No applications should depend on this file in any form.
121.13 -#
121.14 +#
121.15 # This table has been generated by a program and should not be edited
121.16 # manually.
121.17 #
121.18 @@ -84,8 +83,8 @@
121.19 Ekaterinburg Standard Time:10,11::Asia/Yekaterinburg:
121.20 West Asia:10,11:UZ:Asia/Tashkent:
121.21 West Asia Standard Time:10,11:UZ:Asia/Tashkent:
121.22 -Central Asia:12,13::Asia/Dhaka:
121.23 -Central Asia Standard Time:12,13::Asia/Dhaka:
121.24 +Central Asia:12,13::Asia/Almaty:
121.25 +Central Asia Standard Time:12,13::Asia/Almaty:
121.26 N. Central Asia Standard Time:12,13::Asia/Novosibirsk:
121.27 Bangkok:14,15::Asia/Bangkok:
121.28 Bangkok Standard Time:14,15::Asia/Bangkok:
121.29 @@ -167,22 +166,27 @@
121.30 Greenwich Standard Time:88,89::GMT:
121.31 Argentina Standard Time:900,900::America/Buenos_Aires:
121.32 Azerbaijan Standard Time:901,901:AZ:Asia/Baku:
121.33 -Central Brazilian Standard Time:902,902:BR:America/Manaus:
121.34 -Central Standard Time (Mexico):903,903::America/Mexico_City:
121.35 -Georgian Standard Time:904,904:GE:Asia/Tbilisi:
121.36 -Jordan Standard Time:905,905:JO:Asia/Amman:
121.37 -Mauritius Standard Time:906,906:MU:Indian/Mauritius:
121.38 -Middle East Standard Time:907,907:LB:Asia/Beirut:
121.39 -Montevideo Standard Time:908,908:UY:America/Montevideo:
121.40 -Morocco Standard Time:909,909:MA:Africa/Casablanca:
121.41 -Mountain Standard Time (Mexico):910,910:MX:America/Chihuahua:
121.42 -Namibia Standard Time:911,911:NA:Africa/Windhoek:
121.43 -Pacific Standard Time (Mexico):912,912:MX:America/Tijuana:
121.44 -Pakistan Standard Time:913,913::Asia/Karachi:
121.45 -UTC:914,914::UTC:
121.46 -Venezuela Standard Time:915,915::America/Caracas:
121.47 -Kamchatka Standard Time:916,916:RU:Asia/Kamchatka:
121.48 -Paraguay Standard Time:917,917:PY:America/Asuncion:
121.49 -Western Brazilian Standard Time:918,918:BR:America/Rio_Branco:
121.50 -Ulaanbaatar Standard Time:919,919::Asia/Ulaanbaatar:
121.51 -Armenian Standard Time:920,920:AM:Asia/Yerevan:
121.52 +Bangladesh Standard Time:902,902::Asia/Dhaka:
121.53 +Central Brazilian Standard Time:903,903:BR:America/Manaus:
121.54 +Central Standard Time (Mexico):904,904::America/Mexico_City:
121.55 +Georgian Standard Time:905,905:GE:Asia/Tbilisi:
121.56 +Jordan Standard Time:906,906:JO:Asia/Amman:
121.57 +Kamchatka Standard Time:907,907:RU:Asia/Kamchatka:
121.58 +Mauritius Standard Time:908,908:MU:Indian/Mauritius:
121.59 +Middle East Standard Time:909,909:LB:Asia/Beirut:
121.60 +Montevideo Standard Time:910,910:UY:America/Montevideo:
121.61 +Morocco Standard Time:911,911:MA:Africa/Casablanca:
121.62 +Mountain Standard Time (Mexico):912,912:MX:America/Chihuahua:
121.63 +Namibia Standard Time:913,913:NA:Africa/Windhoek:
121.64 +Pacific Standard Time (Mexico):914,914:MX:America/Tijuana:
121.65 +Pakistan Standard Time:915,915::Asia/Karachi:
121.66 +Paraguay Standard Time:916,916:PY:America/Asuncion:
121.67 +Syria Standard Time:917,917:SY:Asia/Damascus:
121.68 +UTC:918,918::UTC:
121.69 +UTC+12:919,919::GMT+1200:
121.70 +UTC-02:920,920::GMT-0200:
121.71 +UTC-11:921,921::GMT-1100:
121.72 +Ulaanbaatar Standard Time:922,922::Asia/Ulaanbaatar:
121.73 +Venezuela Standard Time:923,923::America/Caracas:
121.74 +Western Brazilian Standard Time:924,924:BR:America/Rio_Branco:
121.75 +Armenian Standard Time:925,925:AM:Asia/Yerevan:
122.1 --- a/src/windows/native/java/io/io_util_md.c Thu Oct 07 15:12:19 2010 -0700
122.2 +++ b/src/windows/native/java/io/io_util_md.c Tue Oct 12 12:51:48 2010 -0700
122.3 @@ -531,7 +531,6 @@
122.4 SET_FD(this, -1, fid);
122.5
122.6 if (CloseHandle(h) == 0) { /* Returns zero on failure */
122.7 - SET_FD(this, fd, fid); // restore fd
122.8 JNU_ThrowIOExceptionWithLastError(env, "close failed");
122.9 }
122.10 return 0;
123.1 --- a/src/windows/native/sun/net/spi/DefaultProxySelector.c Thu Oct 07 15:12:19 2010 -0700
123.2 +++ b/src/windows/native/sun/net/spi/DefaultProxySelector.c Tue Oct 12 12:51:48 2010 -0700
123.3 @@ -250,6 +250,10 @@
123.4 return proxy;
123.5 }
123.6 }
123.7 + } else {
123.8 + /* ProxyEnable == 0 or Query failed */
123.9 + /* close the handle to the registry key */
123.10 + RegCloseKey(hKey);
123.11 }
123.12 }
123.13
124.1 --- a/src/windows/native/sun/windows/awt_Component.cpp Thu Oct 07 15:12:19 2010 -0700
124.2 +++ b/src/windows/native/sun/windows/awt_Component.cpp Tue Oct 12 12:51:48 2010 -0700
124.3 @@ -2329,6 +2329,19 @@
124.4 MSG msg;
124.5 InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
124.6
124.7 + AwtWindow *toplevel = GetContainer();
124.8 + if (toplevel && !toplevel->IsSimpleWindow()) {
124.9 + /*
124.10 + * The frame should be focused by click in case it is
124.11 + * the active window but not the focused window. See 6886678.
124.12 + */
124.13 + if (toplevel->GetHWnd() == ::GetActiveWindow() &&
124.14 + toplevel->GetHWnd() != AwtComponent::GetFocusedWindow())
124.15 + {
124.16 + toplevel->AwtSetActiveWindow();
124.17 + }
124.18 + }
124.19 +
124.20 SendMouseEvent(java_awt_event_MouseEvent_MOUSE_PRESSED, now, x, y,
124.21 GetJavaModifiers(), clickCount, JNI_FALSE,
124.22 GetButton(button), &msg);
125.1 --- a/src/windows/native/sun/windows/awt_Desktop.cpp Thu Oct 07 15:12:19 2010 -0700
125.2 +++ b/src/windows/native/sun/windows/awt_Desktop.cpp Tue Oct 12 12:51:48 2010 -0700
125.3 @@ -59,15 +59,17 @@
125.4 FORMAT_MESSAGE_FROM_SYSTEM |
125.5 FORMAT_MESSAGE_IGNORE_INSERTS,
125.6 NULL,
125.7 - GetLastError(),
125.8 + (int)retval,
125.9 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
125.10 (LPTSTR)&buffer,
125.11 0,
125.12 NULL );
125.13
125.14 - jstring errmsg = JNU_NewStringPlatform(env, buffer, len);
125.15 - LocalFree(buffer);
125.16 - return errmsg;
125.17 + if (buffer) {
125.18 + jstring errmsg = JNU_NewStringPlatform(env, buffer);
125.19 + LocalFree(buffer);
125.20 + return errmsg;
125.21 + }
125.22 }
125.23
125.24 return NULL;
126.1 --- a/src/windows/native/sun/windows/awt_DesktopProperties.cpp Thu Oct 07 15:12:19 2010 -0700
126.2 +++ b/src/windows/native/sun/windows/awt_DesktopProperties.cpp Tue Oct 12 12:51:48 2010 -0700
126.3 @@ -505,7 +505,8 @@
126.4 SetIntegerProperty(TEXT("win.drag.width"), cxdrag);
126.5 SetIntegerProperty(TEXT("win.drag.height"), cydrag);
126.6 SetIntegerProperty(TEXT("DnD.gestureMotionThreshold"), max(cxdrag, cydrag)/2);
126.7 - SetIntegerProperty(TEXT("awt.mouse.numButtons"), GetSystemMetrics(SM_CMOUSEBUTTONS));
126.8 + SetIntegerProperty(TEXT("awt.mouse.numButtons"), AwtToolkit::GetNumberOfButtons());
126.9 +
126.10 SetIntegerProperty(TEXT("awt.multiClickInterval"), GetDoubleClickTime());
126.11
126.12 // BEGIN cross-platform properties
127.1 --- a/src/windows/native/sun/windows/awt_Toolkit.cpp Thu Oct 07 15:12:19 2010 -0700
127.2 +++ b/src/windows/native/sun/windows/awt_Toolkit.cpp Tue Oct 12 12:51:48 2010 -0700
127.3 @@ -133,6 +133,8 @@
127.4
127.5 static LPCTSTR szAwtToolkitClassName = TEXT("SunAwtToolkit");
127.6
127.7 +static const int MOUSE_BUTTONS_WINDOWS_SUPPORTED = 5; //three standard buttons + XBUTTON1 + XBUTTON2.
127.8 +
127.9 UINT AwtToolkit::GetMouseKeyState()
127.10 {
127.11 static BOOL mbSwapped = ::GetSystemMetrics(SM_SWAPBUTTON);
127.12 @@ -2310,5 +2312,9 @@
127.13
127.14 JNIEXPORT jint JNICALL Java_sun_awt_windows_WToolkit_getNumberOfButtonsImpl
127.15 (JNIEnv *, jobject self) {
127.16 - return GetSystemMetrics(SM_CMOUSEBUTTONS);
127.17 + return AwtToolkit::GetNumberOfButtons();
127.18 }
127.19 +
127.20 +UINT AwtToolkit::GetNumberOfButtons() {
127.21 + return MOUSE_BUTTONS_WINDOWS_SUPPORTED;
127.22 +}
128.1 --- a/src/windows/native/sun/windows/awt_Toolkit.h Thu Oct 07 15:12:19 2010 -0700
128.2 +++ b/src/windows/native/sun/windows/awt_Toolkit.h Tue Oct 12 12:51:48 2010 -0700
128.3 @@ -185,6 +185,7 @@
128.4 BOOL IsDynamicLayoutActive();
128.5 BOOL areExtraMouseButtonsEnabled();
128.6 void setExtraMouseButtonsEnabled(BOOL enable);
128.7 + static UINT GetNumberOfButtons();
128.8
128.9 INLINE BOOL localPump() { return m_localPump; }
128.10 INLINE BOOL VerifyComponents() { return FALSE; } // TODO: Use new DebugHelper class to set this flag
129.1 --- a/test/ProblemList.txt Thu Oct 07 15:12:19 2010 -0700
129.2 +++ b/test/ProblemList.txt Tue Oct 12 12:51:48 2010 -0700
129.3 @@ -165,6 +165,12 @@
129.4 # very small tests and could greatly benefit from a samevm test run.
129.5 # So a large batch of beans tests are currently run with othervm mode.
129.6
129.7 +# Filed 6986807
129.8 +java/beans/Introspector/TestTypeResolver.java generic-all
129.9 +
129.10 +# Filed 6986813
129.11 +java/beans/Introspector/memory/Test4508780.java generic-all
129.12 +
129.13 # Linux, some kind of problems with X11 display
129.14 java/beans/PropertyChangeSupport/Test4682386.java generic-all
129.15 java/beans/PropertyChangeSupport/TestSynchronization.java generic-all
129.16 @@ -493,6 +499,9 @@
129.17
129.18 # jdk_security
129.19
129.20 +# Filed 6986868
129.21 +sun/security/tools/jarsigner/crl.sh generic-all
129.22 +
129.23 # Filed 6951285, not sure how often this fails, last was Linux 64bit Fedora 9
129.24 sun/security/krb5/auto/MaxRetries.java generic-all
129.25
129.26 @@ -689,10 +698,22 @@
129.27
129.28 # jdk_tools
129.29
129.30 +# Filed 6952105
129.31 +com/sun/jdi/SuspendThreadTest.java generic-all
129.32 +
129.33 +# Filed 6986875
129.34 +sun/tools/jps/jps-Vvml.sh generic-all
129.35 +
129.36 +# Filed 6979016
129.37 +sun/tools/jconsole/ResourceCheckTest.sh generic-all
129.38 +
129.39 ############################################################################
129.40
129.41 # jdk_util
129.42
129.43 +# Filed 6933803
129.44 +java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java generic-all
129.45 +
129.46 # Fails with assertion error on windows
129.47 # 11 separate stacktraces created... file reuse problem?
129.48 java/util/zip/ZipFile/ReadLongZipFileName.java generic-all
130.1 --- a/test/com/sun/security/sasl/ntlm/NTLMTest.java Thu Oct 07 15:12:19 2010 -0700
130.2 +++ b/test/com/sun/security/sasl/ntlm/NTLMTest.java Tue Oct 12 12:51:48 2010 -0700
130.3 @@ -31,8 +31,6 @@
130.4 import javax.security.auth.callback.*;
130.5 import java.util.*;
130.6
130.7 -import com.sun.security.ntlm.NTLMException;
130.8 -
130.9 public class NTLMTest {
130.10
130.11 private static final String MECH = "NTLM";
130.12 @@ -95,19 +93,13 @@
130.13 checkVersion("LM/NTLM", "LMv2");
130.14 throw new Exception("Should not succeed");
130.15 } catch (SaslException se) {
130.16 - NTLMException ne = (NTLMException)se.getCause();
130.17 - if (ne.errorCode() != NTLMException.AUTH_FAILED) {
130.18 - throw new Exception("Failed false");
130.19 - }
130.20 + // OK
130.21 }
130.22 try {
130.23 checkVersion("LMv2/NTLMv2", "LM");
130.24 throw new Exception("Should not succeed");
130.25 } catch (SaslException se) {
130.26 - NTLMException ne = (NTLMException)se.getCause();
130.27 - if (ne.errorCode() != NTLMException.AUTH_FAILED) {
130.28 - throw new Exception("Failed false");
130.29 - }
130.30 + // OK
130.31 }
130.32
130.33 }
131.1 --- a/test/com/sun/servicetag/JavaServiceTagTest.java Thu Oct 07 15:12:19 2010 -0700
131.2 +++ b/test/com/sun/servicetag/JavaServiceTagTest.java Tue Oct 12 12:51:48 2010 -0700
131.3 @@ -124,8 +124,9 @@
131.4 throw new RuntimeException("Unexpected platform_arch: " +
131.5 st.getPlatformArch());
131.6 }
131.7 + String vendor = System.getProperty("java.vendor");
131.8 if (!st.getProductVendor().
131.9 - equals("Sun Microsystems")) {
131.10 + equals(vendor)) {
131.11 throw new RuntimeException("Unexpected product_vendor: " +
131.12 st.getProductVendor());
131.13 }
132.1 --- a/test/com/sun/servicetag/JavaServiceTagTest1.java Thu Oct 07 15:12:19 2010 -0700
132.2 +++ b/test/com/sun/servicetag/JavaServiceTagTest1.java Tue Oct 12 12:51:48 2010 -0700
132.3 @@ -196,8 +196,10 @@
132.4 throw new RuntimeException("Unexpected platform_arch: " +
132.5 st.getPlatformArch());
132.6 }
132.7 +
132.8 + String vendor = System.getProperty("java.vendor");
132.9 if (!st.getProductVendor().
132.10 - equals("Sun Microsystems")) {
132.11 + equals(vendor)) {
132.12 throw new RuntimeException("Unexpected product_vendor: " +
132.13 st.getProductVendor());
132.14 }
133.1 --- a/test/com/sun/servicetag/Util.java Thu Oct 07 15:12:19 2010 -0700
133.2 +++ b/test/com/sun/servicetag/Util.java Tue Oct 12 12:51:48 2010 -0700
133.3 @@ -162,6 +162,8 @@
133.4 for (ServiceTag st : svcTags) {
133.5 ServiceTag st1 = stMap.get(st.getInstanceURN());
133.6 if (!matches(st, st1)) {
133.7 + System.err.println(st);
133.8 + System.err.println(st1);
133.9 throw new RuntimeException("ServiceTag in the registry " +
133.10 "does not match the one in the map");
133.11 }
134.1 --- a/test/com/sun/servicetag/environ.properties Thu Oct 07 15:12:19 2010 -0700
134.2 +++ b/test/com/sun/servicetag/environ.properties Tue Oct 12 12:51:48 2010 -0700
134.3 @@ -4,6 +4,6 @@
134.4 osVersion=5.10
134.5 osArchitecture=sparc
134.6 systemModel=Sun-Fire-V440
134.7 -systemManufacturer=Sun Microsystems
134.8 -cpuManufacturer=Sun Microsystems
134.9 +systemManufacturer=Oracle Corporation
134.10 +cpuManufacturer=Oracle Corporation
134.11 serialNumber=BEL078932
135.1 --- a/test/com/sun/servicetag/missing-environ-field.xml Thu Oct 07 15:12:19 2010 -0700
135.2 +++ b/test/com/sun/servicetag/missing-environ-field.xml Tue Oct 12 12:51:48 2010 -0700
135.3 @@ -19,7 +19,7 @@
135.4 <product_parent_urn>urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3</product_parent_urn>
135.5 <product_parent>Java Platform Standard Edition 6 (Java SE 6)</product_parent>
135.6 <product_defined_inst_id>id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc</product_defined_inst_id>
135.7 -<product_vendor>Sun Microsystems</product_vendor>
135.8 +<product_vendor>Oracle Corporation</product_vendor>
135.9 <platform_arch>sparc</platform_arch>
135.10 <timestamp>2007-11-12 06:15:11 GMT</timestamp>
135.11 <container>global</container>
135.12 @@ -34,7 +34,7 @@
135.13 <product_parent_urn>urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3</product_parent_urn>
135.14 <product_parent>Java Platform Standard Edition 6 (Java SE 6)</product_parent>
135.15 <product_defined_inst_id>id=1.6.0_05-b01 sparc,dir=/myjdk/solaris-i586</product_defined_inst_id>
135.16 -<product_vendor>Sun Microsystems</product_vendor>
135.17 +<product_vendor>Oracle Corporation</product_vendor>
135.18 <platform_arch>i386</platform_arch>
135.19 <timestamp>2007-11-12 06:15:11 GMT</timestamp>
135.20 <container>global</container>
136.1 --- a/test/com/sun/servicetag/newer-registry-version.xml Thu Oct 07 15:12:19 2010 -0700
136.2 +++ b/test/com/sun/servicetag/newer-registry-version.xml Tue Oct 12 12:51:48 2010 -0700
136.3 @@ -20,7 +20,7 @@
136.4 <product_parent_urn>urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3</product_parent_urn>
136.5 <product_parent>Java Platform Standard Edition 6 (Java SE 6)</product_parent>
136.6 <product_defined_inst_id>id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc</product_defined_inst_id>
136.7 -<product_vendor>Sun Microsystems</product_vendor>
136.8 +<product_vendor>Oracle Corporation</product_vendor>
136.9 <platform_arch>sparc</platform_arch>
136.10 <timestamp>2007-11-13 00:49:01 GMT</timestamp>
136.11 <container>global</container>
137.1 --- a/test/com/sun/servicetag/registration.xml Thu Oct 07 15:12:19 2010 -0700
137.2 +++ b/test/com/sun/servicetag/registration.xml Tue Oct 12 12:51:48 2010 -0700
137.3 @@ -7,8 +7,8 @@
137.4 <osVersion>5.10</osVersion>
137.5 <osArchitecture>sparc</osArchitecture>
137.6 <systemModel>Sun-Fire-V440</systemModel>
137.7 -<systemManufacturer>Sun Microsystems</systemManufacturer>
137.8 -<cpuManufacturer>Sun Microsystems</cpuManufacturer>
137.9 +<systemManufacturer>Oracle Corporation</systemManufacturer>
137.10 +<cpuManufacturer>Oracle Corporation</cpuManufacturer>
137.11 <serialNumber>BEL078932</serialNumber>
137.12 </environment>
137.13 <registry urn="urn:st:9543ffaa-a4f1-4f77-b2d1-f561922d4e4a" version="1.0">
137.14 @@ -20,7 +20,7 @@
137.15 <product_parent_urn>urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3</product_parent_urn>
137.16 <product_parent>Java Platform Standard Edition 6 (Java SE 6)</product_parent>
137.17 <product_defined_inst_id>id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc</product_defined_inst_id>
137.18 -<product_vendor>Sun Microsystems</product_vendor>
137.19 +<product_vendor>Oracle Corporation</product_vendor>
137.20 <platform_arch>sparc</platform_arch>
137.21 <timestamp>2007-11-13 00:49:01 GMT</timestamp>
137.22 <container>global</container>
137.23 @@ -35,7 +35,7 @@
137.24 <product_parent_urn>urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3</product_parent_urn>
137.25 <product_parent>Java Platform Standard Edition 6 (Java SE 6)</product_parent>
137.26 <product_defined_inst_id>id=1.6.0_05-b01 i386,dir=/myjdk/solaris-i586</product_defined_inst_id>
137.27 -<product_vendor>Sun Microsystems</product_vendor>
137.28 +<product_vendor>Oracle Corporation</product_vendor>
137.29 <platform_arch>i386</platform_arch>
137.30 <timestamp>2007-11-13 00:49:01 GMT</timestamp>
137.31 <container>global</container>
137.32 @@ -50,7 +50,7 @@
137.33 <product_parent_urn>urn:uuid:596ffcfa-63d5-11d7-9886-ac816a682f92</product_parent_urn>
137.34 <product_parent>Solaris Operating System</product_parent>
137.35 <product_defined_inst_id/>
137.36 -<product_vendor>Sun Microsystems</product_vendor>
137.37 +<product_vendor>Oracle Corporation</product_vendor>
137.38 <platform_arch>sparc</platform_arch>
137.39 <timestamp>2007-11-13 00:49:01 GMT</timestamp>
137.40 <container>global</container>
138.1 --- a/test/com/sun/servicetag/servicetag1.properties Thu Oct 07 15:12:19 2010 -0700
138.2 +++ b/test/com/sun/servicetag/servicetag1.properties Tue Oct 12 12:51:48 2010 -0700
138.3 @@ -5,7 +5,7 @@
138.4 product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3
138.5 product_parent=Java Platform Standard Edition 6 (Java SE 6)
138.6 product_defined_inst_id=id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc
138.7 -product_vendor=Sun Microsystems
138.8 +product_vendor=Oracle Corporation
138.9 platform_arch=sparc
138.10 timestamp=2007-11-12 05:19:40 GMT
138.11 container=global
139.1 --- a/test/com/sun/servicetag/servicetag2.properties Thu Oct 07 15:12:19 2010 -0700
139.2 +++ b/test/com/sun/servicetag/servicetag2.properties Tue Oct 12 12:51:48 2010 -0700
139.3 @@ -5,7 +5,7 @@
139.4 product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3
139.5 product_parent=Java Platform Standard Edition 6 (Java SE 6)
139.6 product_defined_inst_id=id=1.6.0_05-b01 i386,dir=/myjdk/solaris-i586
139.7 -product_vendor=Sun Microsystems
139.8 +product_vendor=Oracle Corporation
139.9 platform_arch=i386
139.10 timestamp=2007-11-12 06:12:21 GMT
139.11 container=global
140.1 --- a/test/com/sun/servicetag/servicetag3.properties Thu Oct 07 15:12:19 2010 -0700
140.2 +++ b/test/com/sun/servicetag/servicetag3.properties Tue Oct 12 12:51:48 2010 -0700
140.3 @@ -5,7 +5,7 @@
140.4 product_parent_urn=urn:uuid:596ffcfa-63d5-11d7-9886-ac816a682f92
140.5 product_parent=Solaris Operating System
140.6 product_defined_inst_id=
140.7 -product_vendor=Sun Microsystems
140.8 +product_vendor=Oracle Corporation
140.9 platform_arch=sparc
140.10 timestamp=2007-06-20 22:07:11 GMT
140.11 container=global
141.1 --- a/test/com/sun/servicetag/servicetag4.properties Thu Oct 07 15:12:19 2010 -0700
141.2 +++ b/test/com/sun/servicetag/servicetag4.properties Tue Oct 12 12:51:48 2010 -0700
141.3 @@ -5,7 +5,7 @@
141.4 product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3
141.5 product_parent=Java Platform Standard Edition 6 (Java SE 6)
141.6 product_defined_inst_id=id=1.6.0_05-b01 amd64,dir=/myjdk/linux-amd64
141.7 -product_vendor=Sun Microsystems
141.8 +product_vendor=Oracle Corporation
141.9 platform_arch=x64
141.10 timestamp=2007-12-12 05:19:40 GMT
141.11 container=global
142.1 --- a/test/com/sun/servicetag/servicetag5.properties Thu Oct 07 15:12:19 2010 -0700
142.2 +++ b/test/com/sun/servicetag/servicetag5.properties Tue Oct 12 12:51:48 2010 -0700
142.3 @@ -5,7 +5,7 @@
142.4 product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3
142.5 product_parent=Java Platform Standard Edition 6 (Java SE 6)
142.6 product_defined_inst_id=id=1.6.0_06-b06 i386,dir=/w/mchung/bundles/jdk1.6.0_05/jre
142.7 -product_vendor=Sun Microsystems
142.8 +product_vendor=Oracle Corporation
142.9 platform_arch=x86
142.10 timestamp=2007-11-29 17:59:42 GMT
142.11 container=global
143.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
143.2 +++ b/test/demo/zipfs/Basic.java Tue Oct 12 12:51:48 2010 -0700
143.3 @@ -0,0 +1,159 @@
143.4 +/*
143.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
143.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
143.7 + *
143.8 + * This code is free software; you can redistribute it and/or modify it
143.9 + * under the terms of the GNU General Public License version 2 only, as
143.10 + * published by the Free Software Foundation.
143.11 + *
143.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
143.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
143.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
143.15 + * version 2 for more details (a copy is included in the LICENSE file that
143.16 + * accompanied this code).
143.17 + *
143.18 + * You should have received a copy of the GNU General Public License version
143.19 + * 2 along with this work; if not, write to the Free Software Foundation,
143.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
143.21 + *
143.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
143.23 + * or visit www.oracle.com if you need additional information or have any
143.24 + * questions.
143.25 + */
143.26 +
143.27 +import java.nio.file.*;
143.28 +import java.nio.file.attribute.*;
143.29 +import java.nio.file.spi.FileSystemProvider;
143.30 +import java.util.*;
143.31 +import java.net.URI;
143.32 +import java.io.IOException;
143.33 +
143.34 +/**
143.35 + * Basic test for zip provider
143.36 + */
143.37 +
143.38 +public class Basic {
143.39 + public static void main(String[] args) throws Exception {
143.40 + Path zipfile = Paths.get(args[0]);
143.41 +
143.42 + // Test: zip should should be returned in provider list
143.43 + boolean found = false;
143.44 +
143.45 + for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
143.46 + if (provider.getScheme().equalsIgnoreCase("zip")) {
143.47 + found = true;
143.48 + break;
143.49 + }
143.50 + }
143.51 + if (!found)
143.52 + throw new RuntimeException("'zip' provider not installed");
143.53 +
143.54 + // Test: FileSystems#newFileSystem(FileRef)
143.55 + Map<String,?> env = new HashMap<String,Object>();
143.56 + FileSystems.newFileSystem(zipfile, env, null).close();
143.57 +
143.58 + // Test: FileSystems#newFileSystem(URI)
143.59 + URI uri = URI.create("zip" + zipfile.toUri().toString().substring(4));
143.60 + FileSystem fs = FileSystems.newFileSystem(uri, env, null);
143.61 +
143.62 + // Test: exercise toUri method
143.63 + String expected = uri.toString() + "#/foo";
143.64 + String actual = fs.getPath("/foo").toUri().toString();
143.65 + if (!actual.equals(expected)) {
143.66 + throw new RuntimeException("toUri returned '" + actual +
143.67 + "', expected '" + expected + "'");
143.68 + }
143.69 +
143.70 + // Test: exercise directory iterator and retrieval of basic attributes
143.71 + Files.walkFileTree(fs.getPath("/"), new FileTreePrinter());
143.72 +
143.73 + // Test: DirectoryStream
143.74 + found = false;
143.75 + DirectoryStream<Path> stream = fs.getPath("/").newDirectoryStream();
143.76 + try {
143.77 + for (Path entry: stream) {
143.78 + found = entry.toString().equals("/META-INF/");
143.79 + if (found) break;
143.80 + }
143.81 + } finally {
143.82 + stream.close();
143.83 + }
143.84 +
143.85 + if (!found)
143.86 + throw new RuntimeException("Expected file not found");
143.87 +
143.88 + // Test: copy file from zip file to current (scratch) directory
143.89 + Path source = fs.getPath("/META-INF/services/java.nio.file.spi.FileSystemProvider");
143.90 + if (source.exists()) {
143.91 + Path target = Paths.get(source.getName().toString());
143.92 + source.copyTo(target, StandardCopyOption.REPLACE_EXISTING);
143.93 + try {
143.94 + long s1 = Attributes.readBasicFileAttributes(source).size();
143.95 + long s2 = Attributes.readBasicFileAttributes(target).size();
143.96 + if (s2 != s1)
143.97 + throw new RuntimeException("target size != source size");
143.98 + } finally {
143.99 + target.delete();
143.100 + }
143.101 + }
143.102 +
143.103 + // Test: FileStore
143.104 + FileStore store = fs.getPath("/").getFileStore();
143.105 + if (!store.supportsFileAttributeView("basic"))
143.106 + throw new RuntimeException("BasicFileAttributeView should be supported");
143.107 +
143.108 + // Test: ClosedFileSystemException
143.109 + fs.close();
143.110 + if (fs.isOpen())
143.111 + throw new RuntimeException("FileSystem should be closed");
143.112 + try {
143.113 + fs.getPath("/missing").checkAccess(AccessMode.READ);
143.114 + } catch (ClosedFileSystemException x) { }
143.115 + }
143.116 +
143.117 + // FileVisitor that pretty prints a file tree
143.118 + static class FileTreePrinter extends SimpleFileVisitor<Path> {
143.119 + private int indent = 0;
143.120 +
143.121 + private void indent() {
143.122 + StringBuilder sb = new StringBuilder(indent);
143.123 + for (int i=0; i<indent; i++) sb.append(" ");
143.124 + System.out.print(sb);
143.125 + }
143.126 +
143.127 + @Override
143.128 + public FileVisitResult preVisitDirectory(Path dir,
143.129 + BasicFileAttributes attrs)
143.130 + {
143.131 + if (dir.getName() != null) {
143.132 + indent();
143.133 + System.out.println(dir.getName() + "/");
143.134 + indent++;
143.135 + }
143.136 + return FileVisitResult.CONTINUE;
143.137 + }
143.138 +
143.139 + @Override
143.140 + public FileVisitResult visitFile(Path file,
143.141 + BasicFileAttributes attrs)
143.142 + {
143.143 + indent();
143.144 + System.out.print(file.getName());
143.145 + if (attrs.isRegularFile())
143.146 + System.out.format(" (%d)", attrs.size());
143.147 + System.out.println();
143.148 + return FileVisitResult.CONTINUE;
143.149 + }
143.150 +
143.151 + @Override
143.152 + public FileVisitResult postVisitDirectory(Path dir, IOException exc)
143.153 + throws IOException
143.154 + {
143.155 + if (exc != null)
143.156 + super.postVisitDirectory(dir, exc);
143.157 + if (dir.getName() != null)
143.158 + indent--;
143.159 + return FileVisitResult.CONTINUE;
143.160 + }
143.161 + }
143.162 +}
144.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
144.2 +++ b/test/demo/zipfs/PathOps.java Tue Oct 12 12:51:48 2010 -0700
144.3 @@ -0,0 +1,416 @@
144.4 +/*
144.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
144.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
144.7 + *
144.8 + * This code is free software; you can redistribute it and/or modify it
144.9 + * under the terms of the GNU General Public License version 2 only, as
144.10 + * published by the Free Software Foundation.
144.11 + *
144.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
144.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
144.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
144.15 + * version 2 for more details (a copy is included in the LICENSE file that
144.16 + * accompanied this code).
144.17 + *
144.18 + * You should have received a copy of the GNU General Public License version
144.19 + * 2 along with this work; if not, write to the Free Software Foundation,
144.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
144.21 + *
144.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
144.23 + * or visit www.oracle.com if you need additional information or have any
144.24 + * questions.
144.25 + */
144.26 +
144.27 +import java.nio.file.*;
144.28 +import java.net.*;
144.29 +import java.util.*;
144.30 +import java.io.IOException;
144.31 +
144.32 +/**
144.33 + * Tests path operations for zip provider.
144.34 + */
144.35 +
144.36 +public class PathOps {
144.37 +
144.38 + static final java.io.PrintStream out = System.out;
144.39 + static FileSystem fs;
144.40 +
144.41 + private String input;
144.42 + private Path path;
144.43 + private Exception exc;
144.44 +
144.45 + private PathOps(String s) {
144.46 + out.println();
144.47 + input = s;
144.48 + try {
144.49 + path = fs.getPath(s);
144.50 + out.format("%s -> %s", s, path);
144.51 + } catch (Exception x) {
144.52 + exc = x;
144.53 + out.format("%s -> %s", s, x);
144.54 + }
144.55 + out.println();
144.56 + }
144.57 +
144.58 + Path path() {
144.59 + return path;
144.60 + }
144.61 +
144.62 + void fail() {
144.63 + throw new RuntimeException("PathOps failed");
144.64 + }
144.65 +
144.66 + void checkPath() {
144.67 + if (path == null) {
144.68 + throw new InternalError("path is null");
144.69 + }
144.70 + }
144.71 +
144.72 + void check(Object result, String expected) {
144.73 + out.format("\tExpected: %s\n", expected);
144.74 + out.format("\tActual: %s\n", result);
144.75 + if (result == null) {
144.76 + if (expected == null) return;
144.77 + } else {
144.78 + // compare string representations
144.79 + if (expected != null && result.toString().equals(expected.toString()))
144.80 + return;
144.81 + }
144.82 + fail();
144.83 + }
144.84 +
144.85 + void check(Object result, boolean expected) {
144.86 + check(result, Boolean.toString(expected));
144.87 + }
144.88 +
144.89 + PathOps root(String expected) {
144.90 + out.println("check root");
144.91 + checkPath();
144.92 + check(path.getRoot(), expected);
144.93 + return this;
144.94 + }
144.95 +
144.96 + PathOps parent(String expected) {
144.97 + out.println("check parent");
144.98 + checkPath();
144.99 + check(path.getParent(), expected);
144.100 + return this;
144.101 + }
144.102 +
144.103 + PathOps name(String expected) {
144.104 + out.println("check name");
144.105 + checkPath();
144.106 + check(path.getName(), expected);
144.107 + return this;
144.108 + }
144.109 +
144.110 + PathOps element(int index, String expected) {
144.111 + out.format("check element %d\n", index);
144.112 + checkPath();
144.113 + check(path.getName(index), expected);
144.114 + return this;
144.115 + }
144.116 +
144.117 + PathOps subpath(int startIndex, int endIndex, String expected) {
144.118 + out.format("test subpath(%d,%d)\n", startIndex, endIndex);
144.119 + checkPath();
144.120 + check(path.subpath(startIndex, endIndex), expected);
144.121 + return this;
144.122 + }
144.123 +
144.124 + PathOps starts(String prefix) {
144.125 + out.format("test startsWith with %s\n", prefix);
144.126 + checkPath();
144.127 + Path s = fs.getPath(prefix);
144.128 + check(path.startsWith(s), true);
144.129 + return this;
144.130 + }
144.131 +
144.132 + PathOps notStarts(String prefix) {
144.133 + out.format("test not startsWith with %s\n", prefix);
144.134 + checkPath();
144.135 + Path s = fs.getPath(prefix);
144.136 + check(path.startsWith(s), false);
144.137 + return this;
144.138 + }
144.139 +
144.140 + PathOps ends(String suffix) {
144.141 + out.format("test endsWith %s\n", suffix);
144.142 + checkPath();
144.143 + Path s = fs.getPath(suffix);
144.144 + check(path.endsWith(s), true);
144.145 + return this;
144.146 + }
144.147 +
144.148 + PathOps notEnds(String suffix) {
144.149 + out.format("test not endsWith %s\n", suffix);
144.150 + checkPath();
144.151 + Path s = fs.getPath(suffix);
144.152 + check(path.endsWith(s), false);
144.153 + return this;
144.154 + }
144.155 +
144.156 + PathOps absolute() {
144.157 + out.println("check path is absolute");
144.158 + checkPath();
144.159 + check(path.isAbsolute(), true);
144.160 + return this;
144.161 + }
144.162 +
144.163 + PathOps notAbsolute() {
144.164 + out.println("check path is not absolute");
144.165 + checkPath();
144.166 + check(path.isAbsolute(), false);
144.167 + return this;
144.168 + }
144.169 +
144.170 + PathOps resolve(String other, String expected) {
144.171 + out.format("test resolve %s\n", other);
144.172 + checkPath();
144.173 + check(path.resolve(other), expected);
144.174 + return this;
144.175 + }
144.176 +
144.177 + PathOps relativize(String other, String expected) {
144.178 + out.format("test relativize %s\n", other);
144.179 + checkPath();
144.180 + Path that = fs.getPath(other);
144.181 + check(path.relativize(that), expected);
144.182 + return this;
144.183 + }
144.184 +
144.185 + PathOps normalize(String expected) {
144.186 + out.println("check normalized path");
144.187 + checkPath();
144.188 + check(path.normalize(), expected);
144.189 + return this;
144.190 + }
144.191 +
144.192 + PathOps string(String expected) {
144.193 + out.println("check string representation");
144.194 + checkPath();
144.195 + check(path, expected);
144.196 + return this;
144.197 + }
144.198 +
144.199 + PathOps invalid() {
144.200 + if (!(exc instanceof InvalidPathException)) {
144.201 + out.println("InvalidPathException not thrown as expected");
144.202 + fail();
144.203 + }
144.204 + return this;
144.205 + }
144.206 +
144.207 + static PathOps test(String s) {
144.208 + return new PathOps(s);
144.209 + }
144.210 +
144.211 + // -- PathOpss --
144.212 +
144.213 + static void header(String s) {
144.214 + out.println();
144.215 + out.println();
144.216 + out.println("-- " + s + " --");
144.217 + }
144.218 +
144.219 + static void doPathOpTests() {
144.220 + header("Path operations");
144.221 +
144.222 + // all components
144.223 + test("/a/b/c")
144.224 + .root("/")
144.225 + .parent("/a/b")
144.226 + .name("c");
144.227 +
144.228 + // root component only
144.229 + test("/")
144.230 + .root("/")
144.231 + .parent(null)
144.232 + .name(null);
144.233 +
144.234 + // no root component
144.235 + test("a/b")
144.236 + .root(null)
144.237 + .parent("a")
144.238 + .name("b");
144.239 +
144.240 + // name component only
144.241 + test("foo")
144.242 + .root(null)
144.243 + .parent(null)
144.244 + .name("foo");
144.245 +
144.246 + // startsWith
144.247 + test("/")
144.248 + .starts("/")
144.249 + .notStarts("/foo");
144.250 + test("/foo")
144.251 + .starts("/")
144.252 + .starts("/foo")
144.253 + .notStarts("/f");
144.254 + test("/foo/bar")
144.255 + .starts("/")
144.256 + .starts("/foo")
144.257 + .starts("/foo/bar")
144.258 + .notStarts("/f")
144.259 + .notStarts("foo")
144.260 + .notStarts("foo/bar");
144.261 + test("foo")
144.262 + .starts("foo")
144.263 + .notStarts("f");
144.264 + test("foo/bar")
144.265 + .starts("foo")
144.266 + .starts("foo/bar")
144.267 + .notStarts("f")
144.268 + .notStarts("/foo")
144.269 + .notStarts("/foo/bar");
144.270 +
144.271 + // endsWith
144.272 + test("/")
144.273 + .ends("/")
144.274 + .notEnds("foo")
144.275 + .notEnds("/foo");
144.276 + test("/foo")
144.277 + .ends("foo")
144.278 + .ends("/foo")
144.279 + .notEnds("/");
144.280 + test("/foo/bar")
144.281 + .ends("bar")
144.282 + .ends("foo/bar")
144.283 + .ends("/foo/bar")
144.284 + .notEnds("/bar");
144.285 + test("foo")
144.286 + .ends("foo");
144.287 + test("foo/bar")
144.288 + .ends("bar")
144.289 + .ends("foo/bar");
144.290 +
144.291 + // elements
144.292 + test("a/b/c")
144.293 + .element(0,"a")
144.294 + .element(1,"b")
144.295 + .element(2,"c");
144.296 +
144.297 + // isAbsolute
144.298 + test("/")
144.299 + .absolute();
144.300 + test("/tmp")
144.301 + .absolute();
144.302 + test("tmp")
144.303 + .notAbsolute();
144.304 +
144.305 + // resolve
144.306 + test("/tmp")
144.307 + .resolve("foo", "/tmp/foo")
144.308 + .resolve("/foo", "/foo");
144.309 + test("tmp")
144.310 + .resolve("foo", "tmp/foo")
144.311 + .resolve("/foo", "/foo");
144.312 +
144.313 + // relativize
144.314 + test("/a/b/c")
144.315 + .relativize("/a/b/c", null)
144.316 + .relativize("/a/b/c/d/e", "d/e")
144.317 + .relativize("/a/x", "../../x");
144.318 +
144.319 + // normalize
144.320 + test("/")
144.321 + .normalize("/");
144.322 + test("foo")
144.323 + .normalize("foo");
144.324 + test("/foo")
144.325 + .normalize("/foo");
144.326 + test(".")
144.327 + .normalize(null);
144.328 + test("..")
144.329 + .normalize("..");
144.330 + test("/..")
144.331 + .normalize("/");
144.332 + test("/../..")
144.333 + .normalize("/");
144.334 + test("foo/.")
144.335 + .normalize("foo");
144.336 + test("./foo")
144.337 + .normalize("foo");
144.338 + test("foo/..")
144.339 + .normalize(null);
144.340 + test("../foo")
144.341 + .normalize("../foo");
144.342 + test("../../foo")
144.343 + .normalize("../../foo");
144.344 + test("foo/bar/..")
144.345 + .normalize("foo");
144.346 + test("foo/bar/gus/../..")
144.347 + .normalize("foo");
144.348 + test("/foo/bar/gus/../..")
144.349 + .normalize("/foo");
144.350 +
144.351 + // invalid
144.352 + test("foo\u0000bar")
144.353 + .invalid();
144.354 + test("\u0000foo")
144.355 + .invalid();
144.356 + test("bar\u0000")
144.357 + .invalid();
144.358 + test("//foo\u0000bar")
144.359 + .invalid();
144.360 + test("//\u0000foo")
144.361 + .invalid();
144.362 + test("//bar\u0000")
144.363 + .invalid();
144.364 +
144.365 + // normalization
144.366 + test("//foo//bar")
144.367 + .string("/foo/bar")
144.368 + .root("/")
144.369 + .parent("/foo")
144.370 + .name("bar");
144.371 + }
144.372 +
144.373 + static void npes() {
144.374 + header("NullPointerException");
144.375 +
144.376 + Path path = fs.getPath("foo");
144.377 +
144.378 + try {
144.379 + path.resolve((String)null);
144.380 + throw new RuntimeException("NullPointerException not thrown");
144.381 + } catch (NullPointerException npe) {
144.382 + }
144.383 +
144.384 + try {
144.385 + path.relativize(null);
144.386 + throw new RuntimeException("NullPointerException not thrown");
144.387 + } catch (NullPointerException npe) {
144.388 + }
144.389 +
144.390 + try {
144.391 + path.compareTo(null);
144.392 + throw new RuntimeException("NullPointerException not thrown");
144.393 + } catch (NullPointerException npe) {
144.394 + }
144.395 +
144.396 + try {
144.397 + path.startsWith(null);
144.398 + throw new RuntimeException("NullPointerException not thrown");
144.399 + } catch (NullPointerException npe) {
144.400 + }
144.401 +
144.402 + try {
144.403 + path.endsWith(null);
144.404 + throw new RuntimeException("NullPointerException not thrown");
144.405 + } catch (NullPointerException npe) {
144.406 + }
144.407 +
144.408 + }
144.409 +
144.410 + public static void main(String[] args) throws Throwable {
144.411 +
144.412 + Path zipfile = Paths.get(args[0]);
144.413 + Map<String,?> env = new HashMap<String,Object>();
144.414 + fs = FileSystems.newFileSystem(zipfile, env, null);
144.415 + npes();
144.416 + doPathOpTests();
144.417 + fs.close();
144.418 + }
144.419 +}
145.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
145.2 +++ b/test/demo/zipfs/ZipFSTester.java Tue Oct 12 12:51:48 2010 -0700
145.3 @@ -0,0 +1,633 @@
145.4 +/*
145.5 + * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
145.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
145.7 + *
145.8 + * This code is free software; you can redistribute it and/or modify it
145.9 + * under the terms of the GNU General Public License version 2 only, as
145.10 + * published by the Free Software Foundation.
145.11 + *
145.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
145.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
145.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
145.15 + * version 2 for more details (a copy is included in the LICENSE file that
145.16 + * accompanied this code).
145.17 + *
145.18 + * You should have received a copy of the GNU General Public License version
145.19 + * 2 along with this work; if not, write to the Free Software Foundation,
145.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
145.21 + *
145.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
145.23 + * or visit www.oracle.com if you need additional information or have any
145.24 + * questions.
145.25 + */
145.26 +
145.27 +import java.io.*;
145.28 +import java.nio.*;
145.29 +import java.nio.channels.*;
145.30 +import java.nio.file.*;
145.31 +import java.nio.file.attribute.*;
145.32 +import java.net.*;
145.33 +import java.util.*;
145.34 +
145.35 +import static java.nio.file.StandardOpenOption.*;
145.36 +import static java.nio.file.StandardCopyOption.*;
145.37 +
145.38 +/*
145.39 + * Tests various zipfs operations.
145.40 + */
145.41 +
145.42 +public class ZipFSTester {
145.43 +
145.44 + public static void main(String[] args) throws Throwable {
145.45 + FileSystem fs = null;
145.46 + try {
145.47 + fs = newZipFileSystem(Paths.get(args[0]), new HashMap<String, Object>());
145.48 + test(fs);
145.49 + test2(fs); // more tests
145.50 + } finally {
145.51 + if (fs != null)
145.52 + fs.close();
145.53 + }
145.54 + }
145.55 +
145.56 + static void test(FileSystem fs)
145.57 + throws Exception
145.58 + {
145.59 + Random rdm = new Random();
145.60 +
145.61 + // clone a fs and test on it
145.62 + Path tmpfsPath = getTempPath();
145.63 + Map<String, Object> env = new HashMap<String, Object>();
145.64 + env.put("createNew", true);
145.65 + FileSystem fs0 = newZipFileSystem(tmpfsPath, env);
145.66 + z2zcopy(fs, fs0, "/", 0);
145.67 + fs0.close(); // sync to file
145.68 +
145.69 + fs = newZipFileSystem(tmpfsPath, new HashMap<String, Object>());
145.70 +
145.71 + try {
145.72 + // prepare a src
145.73 + Path src = getTempPath();
145.74 + String tmpName = src.toString();
145.75 + OutputStream os = src.newOutputStream();
145.76 + byte[] bits = new byte[12345];
145.77 + rdm.nextBytes(bits);
145.78 + os.write(bits);
145.79 + os.close();
145.80 +
145.81 + // copyin
145.82 + Path dst = getPathWithParents(fs, tmpName);
145.83 + src.copyTo(dst);
145.84 + checkEqual(src, dst);
145.85 +
145.86 + // copy
145.87 + Path dst2 = getPathWithParents(fs, "/xyz" + rdm.nextInt(100) +
145.88 + "/efg" + rdm.nextInt(100) + "/foo.class");
145.89 + dst.copyTo(dst2);
145.90 + //dst.moveTo(dst2);
145.91 + checkEqual(src, dst2);
145.92 +
145.93 + // delete
145.94 + dst.delete();
145.95 + if (dst.exists())
145.96 + throw new RuntimeException("Failed!");
145.97 +
145.98 + // moveout
145.99 + Path dst3 = Paths.get(tmpName + "_Tmp");
145.100 + dst2.moveTo(dst3);
145.101 + checkEqual(src, dst3);
145.102 +
145.103 + // delete
145.104 + if (dst2.exists())
145.105 + throw new RuntimeException("Failed!");
145.106 + dst3.delete();
145.107 + if (dst3.exists())
145.108 + throw new RuntimeException("Failed!");
145.109 +
145.110 + // newInputStream on dir
145.111 + Path parent = dst2.getParent();
145.112 + try {
145.113 + parent.newInputStream();
145.114 + throw new RuntimeException("Failed");
145.115 + } catch (FileSystemException e) {
145.116 + e.printStackTrace(); // expected fse
145.117 + }
145.118 +
145.119 + // rmdirs
145.120 + try {
145.121 + rmdirs(parent);
145.122 + } catch (IOException x) {
145.123 + x.printStackTrace();
145.124 + }
145.125 +
145.126 + // newFileChannel() copy in, out and verify via fch
145.127 + fchCopy(src, dst); // in
145.128 + checkEqual(src, dst);
145.129 + Path tmp = Paths.get(tmpName + "_Tmp");
145.130 + fchCopy(dst, tmp); // out
145.131 + checkEqual(src, tmp);
145.132 + tmp.delete();
145.133 +
145.134 + // test channels
145.135 + channel(fs, dst);
145.136 + dst.delete();
145.137 + src.delete();
145.138 + } finally {
145.139 + if (fs != null)
145.140 + fs.close();
145.141 + if (tmpfsPath.exists())
145.142 + tmpfsPath.delete();
145.143 + }
145.144 + }
145.145 +
145.146 + static void test2(FileSystem fs) throws Exception {
145.147 +
145.148 + Path fs1Path = getTempPath();
145.149 + Path fs2Path = getTempPath();
145.150 + Path fs3Path = getTempPath();
145.151 +
145.152 + if (fs1Path.exists())
145.153 + fs1Path.delete();
145.154 + if (fs2Path.exists())
145.155 + fs2Path.delete();
145.156 + if (fs3Path.exists())
145.157 + fs3Path.delete();
145.158 +
145.159 + // create a new filesystem, copy everything from fs
145.160 + Map<String, Object> env = new HashMap<String, Object>();
145.161 + env.put("createNew", true);
145.162 + FileSystem fs0 = newZipFileSystem(fs1Path, env);
145.163 +
145.164 + final FileSystem fs2 = newZipFileSystem(fs2Path, env);
145.165 + final FileSystem fs3 = newZipFileSystem(fs3Path, env);
145.166 +
145.167 + System.out.println("copy src: fs -> fs0...");
145.168 + z2zcopy(fs, fs0, "/", 0); // copy fs -> fs1
145.169 + fs0.close(); // dump to file
145.170 +
145.171 + System.out.println("open fs0 as fs1");
145.172 + env = new HashMap<String, Object>();
145.173 + final FileSystem fs1 = newZipFileSystem(fs1Path, env);
145.174 +
145.175 + System.out.println("listing...");
145.176 + final ArrayList<String> files = new ArrayList<>();
145.177 + final ArrayList<String> dirs = new ArrayList<>();
145.178 + list(fs1.getPath("/"), files, dirs);
145.179 +
145.180 + Thread t0 = new Thread(new Runnable() {
145.181 + public void run() {
145.182 + List<String> list = new ArrayList<>(dirs);
145.183 + Collections.shuffle(list);
145.184 + for (String path : list) {
145.185 + try {
145.186 + z2zcopy(fs1, fs2, path, 0);
145.187 + } catch (Exception x) {
145.188 + x.printStackTrace();
145.189 + }
145.190 + }
145.191 + }
145.192 +
145.193 + });
145.194 +
145.195 + Thread t1 = new Thread(new Runnable() {
145.196 + public void run() {
145.197 + List<String> list = new ArrayList<>(dirs);
145.198 + Collections.shuffle(list);
145.199 + for (String path : list) {
145.200 + try {
145.201 + z2zcopy(fs1, fs2, path, 1);
145.202 + } catch (Exception x) {
145.203 + x.printStackTrace();
145.204 + }
145.205 + }
145.206 + }
145.207 +
145.208 + });
145.209 +
145.210 + Thread t2 = new Thread(new Runnable() {
145.211 + public void run() {
145.212 + List<String> list = new ArrayList<>(dirs);
145.213 + Collections.shuffle(list);
145.214 + for (String path : list) {
145.215 + try {
145.216 + z2zcopy(fs1, fs2, path, 2);
145.217 + } catch (Exception x) {
145.218 + x.printStackTrace();
145.219 + }
145.220 + }
145.221 + }
145.222 +
145.223 + });
145.224 +
145.225 + Thread t3 = new Thread(new Runnable() {
145.226 + public void run() {
145.227 + List<String> list = new ArrayList<>(files);
145.228 + Collections.shuffle(list);
145.229 + while (!list.isEmpty()) {
145.230 + Iterator<String> itr = list.iterator();
145.231 + while (itr.hasNext()) {
145.232 + String path = itr.next();
145.233 + try {
145.234 + if (fs2.getPath(path).exists()) {
145.235 + z2zmove(fs2, fs3, path);
145.236 + itr.remove();
145.237 + }
145.238 + } catch (FileAlreadyExistsException x){
145.239 + itr.remove();
145.240 + } catch (Exception x) {
145.241 + x.printStackTrace();
145.242 + }
145.243 + }
145.244 + }
145.245 + }
145.246 +
145.247 + });
145.248 +
145.249 + System.out.println("copying/removing...");
145.250 + t0.start(); t1.start(); t2.start(); t3.start();
145.251 + t0.join(); t1.join(); t2.join(); t3.join();
145.252 +
145.253 + System.out.println("closing: fs1, fs2");
145.254 + fs1.close();
145.255 + fs2.close();
145.256 +
145.257 + int failed = 0;
145.258 + System.out.println("checkEqual: fs vs fs3");
145.259 + for (String path : files) {
145.260 + try {
145.261 + checkEqual(fs.getPath(path), fs3.getPath(path));
145.262 + } catch (IOException x) {
145.263 + //x.printStackTrace();
145.264 + failed++;
145.265 + }
145.266 + }
145.267 + System.out.println("closing: fs3");
145.268 + fs3.close();
145.269 +
145.270 + System.out.println("opening: fs3 as fs4");
145.271 + FileSystem fs4 = newZipFileSystem(fs3Path, env);
145.272 +
145.273 +
145.274 + ArrayList<String> files2 = new ArrayList<>();
145.275 + ArrayList<String> dirs2 = new ArrayList<>();
145.276 + list(fs4.getPath("/"), files2, dirs2);
145.277 +
145.278 + System.out.println("checkEqual: fs vs fs4");
145.279 + for (String path : files2) {
145.280 + checkEqual(fs.getPath(path), fs4.getPath(path));
145.281 + }
145.282 + System.out.println("walking: fs4");
145.283 + walk(fs4.getPath("/"));
145.284 + System.out.println("closing: fs4");
145.285 + fs4.close();
145.286 +
145.287 + System.out.printf("failed=%d%n", failed);
145.288 +
145.289 + fs1Path.delete();
145.290 + fs2Path.delete();
145.291 + fs3Path.delete();
145.292 + }
145.293 +
145.294 + private static FileSystem newZipFileSystem(Path path, Map<String, ?> env)
145.295 + throws IOException
145.296 + {
145.297 + return FileSystems.newFileSystem(
145.298 + URI.create("zip" +
145.299 + path.toUri().toString().substring(4)),
145.300 + env,
145.301 + null);
145.302 + }
145.303 +
145.304 + private static Path getTempPath() throws IOException
145.305 + {
145.306 + File tmp = File.createTempFile("testzipfs_", "zip");
145.307 + tmp.delete(); // we need a clean path, no file
145.308 + return tmp.toPath();
145.309 + }
145.310 +
145.311 + private static void list(Path path, List<String> files, List<String> dirs )
145.312 + throws IOException
145.313 + {
145.314 + if (Attributes.readBasicFileAttributes(path).isDirectory()) {
145.315 + DirectoryStream<Path> ds = path.newDirectoryStream();
145.316 + for (Path child : ds)
145.317 + list(child, files, dirs);
145.318 + ds.close();
145.319 + dirs.add(path.toString());
145.320 + } else {
145.321 + files.add(path.toString());
145.322 + }
145.323 + }
145.324 +
145.325 + private static void z2zcopy(FileSystem src, FileSystem dst, String path,
145.326 + int method)
145.327 + throws IOException
145.328 + {
145.329 + Path srcPath = src.getPath(path);
145.330 + Path dstPath = dst.getPath(path);
145.331 +
145.332 + if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) {
145.333 + if (!dstPath.exists()) {
145.334 + try {
145.335 + mkdirs(dstPath);
145.336 + } catch (FileAlreadyExistsException x) {}
145.337 + }
145.338 + DirectoryStream<Path> ds = srcPath.newDirectoryStream();
145.339 + for (Path child : ds) {
145.340 + z2zcopy(src, dst,
145.341 + path + (path.endsWith("/")?"":"/") + child.getName(),
145.342 + method);
145.343 + }
145.344 + ds.close();
145.345 + } else {
145.346 + try {
145.347 + if (dstPath.exists())
145.348 + return;
145.349 + switch (method) {
145.350 + case 0:
145.351 + srcPath.copyTo(dstPath);
145.352 + break;
145.353 + case 1:
145.354 + chCopy(srcPath, dstPath);
145.355 + break;
145.356 + case 2:
145.357 + //fchCopy(srcPath, dstPath);
145.358 + streamCopy(srcPath, dstPath);
145.359 + break;
145.360 + }
145.361 + } catch (FileAlreadyExistsException x) {}
145.362 + }
145.363 + }
145.364 +
145.365 + private static void z2zmove(FileSystem src, FileSystem dst, String path)
145.366 + throws IOException
145.367 + {
145.368 + Path srcPath = src.getPath(path);
145.369 + Path dstPath = dst.getPath(path);
145.370 +
145.371 + if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) {
145.372 + if (!dstPath.exists())
145.373 + mkdirs(dstPath);
145.374 + DirectoryStream<Path> ds = srcPath.newDirectoryStream();
145.375 + for (Path child : ds) {
145.376 + z2zmove(src, dst,
145.377 + path + (path.endsWith("/")?"":"/") + child.getName());
145.378 + }
145.379 + ds.close();
145.380 + } else {
145.381 + //System.out.println("moving..." + path);
145.382 + Path parent = dstPath.getParent();
145.383 + if (parent != null && parent.notExists())
145.384 + mkdirs(parent);
145.385 + srcPath.moveTo(dstPath);
145.386 + }
145.387 + }
145.388 +
145.389 + private static void walk(Path path) throws IOException
145.390 + {
145.391 + Files.walkFileTree(
145.392 + path,
145.393 + new SimpleFileVisitor<Path>() {
145.394 + private int indent = 0;
145.395 + private void indent() {
145.396 + int n = 0;
145.397 + while (n++ < indent)
145.398 + System.out.printf(" ");
145.399 + }
145.400 +
145.401 + @Override
145.402 + public FileVisitResult visitFile(Path file,
145.403 + BasicFileAttributes attrs)
145.404 + {
145.405 + indent();
145.406 + System.out.printf("%s%n", file.getName().toString());
145.407 + return FileVisitResult.CONTINUE;
145.408 + }
145.409 +
145.410 + @Override
145.411 + public FileVisitResult preVisitDirectory(Path dir,
145.412 + BasicFileAttributes attrs)
145.413 + {
145.414 + indent();
145.415 + System.out.printf("[%s]%n", dir.toString());
145.416 + indent += 2;
145.417 + return FileVisitResult.CONTINUE;
145.418 + }
145.419 +
145.420 + @Override
145.421 + public FileVisitResult postVisitDirectory(Path dir,
145.422 + IOException ioe)
145.423 + throws IOException
145.424 + {
145.425 + indent -= 2;
145.426 + return FileVisitResult.CONTINUE;
145.427 + }
145.428 + });
145.429 + }
145.430 +
145.431 + private static void mkdirs(Path path) throws IOException {
145.432 + path = path.toAbsolutePath();
145.433 + Path parent = path.getParent();
145.434 + if (parent != null) {
145.435 + if (parent.notExists())
145.436 + mkdirs(parent);
145.437 + }
145.438 + path.createDirectory();
145.439 + }
145.440 +
145.441 + private static void rmdirs(Path path) throws IOException {
145.442 + while (path != null && path.getNameCount() != 0) {
145.443 + path.delete();
145.444 + path = path.getParent();
145.445 + }
145.446 + }
145.447 +
145.448 + // check the content of two paths are equal
145.449 + private static void checkEqual(Path src, Path dst) throws IOException
145.450 + {
145.451 + //System.out.printf("checking <%s> vs <%s>...%n",
145.452 + // src.toString(), dst.toString());
145.453 +
145.454 + //streams
145.455 + InputStream isSrc = src.newInputStream();
145.456 + InputStream isDst = dst.newInputStream();
145.457 + byte[] bufSrc = new byte[8192];
145.458 + byte[] bufDst = new byte[8192];
145.459 +
145.460 + try {
145.461 + int nSrc = 0;
145.462 + while ((nSrc = isSrc.read(bufSrc)) != -1) {
145.463 + int nDst = 0;
145.464 + while (nDst < nSrc) {
145.465 + int n = isDst.read(bufDst, nDst, nSrc - nDst);
145.466 + if (n == -1) {
145.467 + System.out.printf("checking <%s> vs <%s>...%n",
145.468 + src.toString(), dst.toString());
145.469 + throw new RuntimeException("CHECK FAILED!");
145.470 + }
145.471 + nDst += n;
145.472 + }
145.473 + while (--nSrc >= 0) {
145.474 + if (bufSrc[nSrc] != bufDst[nSrc]) {
145.475 + System.out.printf("checking <%s> vs <%s>...%n",
145.476 + src.toString(), dst.toString());
145.477 + throw new RuntimeException("CHECK FAILED!");
145.478 + }
145.479 + nSrc--;
145.480 + }
145.481 + }
145.482 + } finally {
145.483 + isSrc.close();
145.484 + isDst.close();
145.485 + }
145.486 +
145.487 + // channels
145.488 + SeekableByteChannel chSrc = src.newByteChannel();
145.489 + SeekableByteChannel chDst = dst.newByteChannel();
145.490 + if (chSrc.size() != chDst.size()) {
145.491 + System.out.printf("src[%s].size=%d, dst[%s].size=%d%n",
145.492 + chSrc.toString(), chSrc.size(),
145.493 + chDst.toString(), chDst.size());
145.494 + throw new RuntimeException("CHECK FAILED!");
145.495 + }
145.496 + ByteBuffer bbSrc = ByteBuffer.allocate(8192);
145.497 + ByteBuffer bbDst = ByteBuffer.allocate(8192);
145.498 +
145.499 + try {
145.500 + int nSrc = 0;
145.501 + while ((nSrc = chSrc.read(bbSrc)) != -1) {
145.502 + int nDst = chDst.read(bbDst);
145.503 + if (nSrc != nDst) {
145.504 + System.out.printf("checking <%s> vs <%s>...%n",
145.505 + src.toString(), dst.toString());
145.506 + throw new RuntimeException("CHECK FAILED!");
145.507 + }
145.508 + while (--nSrc >= 0) {
145.509 + if (bbSrc.get(nSrc) != bbDst.get(nSrc)) {
145.510 + System.out.printf("checking <%s> vs <%s>...%n",
145.511 + src.toString(), dst.toString());
145.512 + throw new RuntimeException("CHECK FAILED!");
145.513 + }
145.514 + nSrc--;
145.515 + }
145.516 + bbSrc.flip();
145.517 + bbDst.flip();
145.518 + }
145.519 + } catch (IOException x) {
145.520 + x.printStackTrace();
145.521 + } finally {
145.522 + chSrc.close();
145.523 + chDst.close();
145.524 + }
145.525 + }
145.526 +
145.527 + private static void fchCopy(Path src, Path dst) throws IOException
145.528 + {
145.529 + Set<OpenOption> read = new HashSet<>();
145.530 + read.add(READ);
145.531 + Set<OpenOption> openwrite = new HashSet<>();
145.532 + openwrite.add(CREATE_NEW);
145.533 + openwrite.add(WRITE);
145.534 +
145.535 + FileChannel srcFc = src.getFileSystem()
145.536 + .provider()
145.537 + .newFileChannel(src, read);
145.538 + FileChannel dstFc = dst.getFileSystem()
145.539 + .provider()
145.540 + .newFileChannel(dst, openwrite);
145.541 +
145.542 + try {
145.543 + ByteBuffer bb = ByteBuffer.allocate(8192);
145.544 + while (srcFc.read(bb) >= 0) {
145.545 + bb.flip();
145.546 + dstFc.write(bb);
145.547 + bb.clear();
145.548 + }
145.549 + } finally {
145.550 + srcFc.close();
145.551 + dstFc.close();
145.552 + }
145.553 + }
145.554 +
145.555 + private static void chCopy(Path src, Path dst) throws IOException
145.556 + {
145.557 + Set<OpenOption> read = new HashSet<>();
145.558 + read.add(READ);
145.559 + Set<OpenOption> openwrite = new HashSet<>();
145.560 + openwrite.add(CREATE_NEW);
145.561 + openwrite.add(WRITE);
145.562 +
145.563 + SeekableByteChannel srcCh = src.newByteChannel(read);
145.564 + SeekableByteChannel dstCh = dst.newByteChannel(openwrite);
145.565 +
145.566 + try {
145.567 + ByteBuffer bb = ByteBuffer.allocate(8192);
145.568 + while (srcCh.read(bb) >= 0) {
145.569 + bb.flip();
145.570 + dstCh.write(bb);
145.571 + bb.clear();
145.572 + }
145.573 + } finally {
145.574 + srcCh.close();
145.575 + dstCh.close();
145.576 + }
145.577 + }
145.578 +
145.579 + private static void streamCopy(Path src, Path dst) throws IOException
145.580 + {
145.581 + InputStream isSrc = src.newInputStream();
145.582 + OutputStream osDst = dst.newOutputStream();
145.583 + byte[] buf = new byte[8192];
145.584 + try {
145.585 + int n = 0;
145.586 + while ((n = isSrc.read(buf)) != -1) {
145.587 + osDst.write(buf, 0, n);
145.588 + }
145.589 + } finally {
145.590 + isSrc.close();
145.591 + osDst.close();
145.592 + }
145.593 + }
145.594 +
145.595 + static void channel(FileSystem fs, Path path)
145.596 + throws Exception
145.597 + {
145.598 + System.out.println("test ByteChannel...");
145.599 + SeekableByteChannel sbc = path.newByteChannel();
145.600 + Set<OpenOption> read = new HashSet<>();
145.601 + read.add(READ);
145.602 + System.out.printf(" sbc[0]: pos=%d, size=%d%n", sbc.position(), sbc.size());
145.603 + ByteBuffer bb = ByteBuffer.allocate((int)sbc.size());
145.604 + int n = sbc.read(bb);
145.605 + System.out.printf(" sbc[1]: read=%d, pos=%d, size=%d%n",
145.606 + n, sbc.position(), sbc.size());
145.607 + ByteBuffer bb2 = ByteBuffer.allocate((int)sbc.size());
145.608 + int N = 120;
145.609 + sbc.close();
145.610 +
145.611 + // sbc.position(pos) is not supported in current version
145.612 + // try the FileChannel
145.613 + sbc = fs.provider().newFileChannel(path, read);
145.614 + sbc.position(N);
145.615 + System.out.printf(" sbc[2]: pos=%d, size=%d%n",
145.616 + sbc.position(), sbc.size());
145.617 + bb2.limit(100);
145.618 + n = sbc.read(bb2);
145.619 + System.out.printf(" sbc[3]: read=%d, pos=%d, size=%d%n",
145.620 + n, sbc.position(), sbc.size());
145.621 + System.out.printf(" sbc[4]: bb[%d]=%d, bb1[0]=%d%n",
145.622 + N, bb.get(N) & 0xff, bb2.get(0) & 0xff);
145.623 + sbc.close();
145.624 + }
145.625 +
145.626 + // create parents if does not exist
145.627 + static Path getPathWithParents(FileSystem fs, String name)
145.628 + throws Exception
145.629 + {
145.630 + Path path = fs.getPath(name);
145.631 + Path parent = path.getParent();
145.632 + if (parent != null && parent.notExists())
145.633 + mkdirs(parent);
145.634 + return path;
145.635 + }
145.636 +}
146.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
146.2 +++ b/test/demo/zipfs/basic.sh Tue Oct 12 12:51:48 2010 -0700
146.3 @@ -0,0 +1,73 @@
146.4 +#
146.5 +# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
146.6 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
146.7 +#
146.8 +# This code is free software; you can redistribute it and/or modify it
146.9 +# under the terms of the GNU General Public License version 2 only, as
146.10 +# published by the Free Software Foundation.
146.11 +#
146.12 +# This code is distributed in the hope that it will be useful, but WITHOUT
146.13 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
146.14 +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
146.15 +# version 2 for more details (a copy is included in the LICENSE file that
146.16 +# accompanied this code).
146.17 +#
146.18 +# You should have received a copy of the GNU General Public License version
146.19 +# 2 along with this work; if not, write to the Free Software Foundation,
146.20 +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
146.21 +#
146.22 +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
146.23 +# or visit www.oracle.com if you need additional information or have any
146.24 +# questions.
146.25 +#
146.26 +# @test
146.27 +# @bug 6990846
146.28 +# @summary Test ZipFileSystem demo
146.29 +# @build Basic PathOps ZipFSTester
146.30 +# @run shell basic.sh
146.31 +
146.32 +if [ -z "${TESTJAVA}" ]; then
146.33 + echo "Test must be run with jtreg"
146.34 + exit 0
146.35 +fi
146.36 +
146.37 +ZIPFS="${TESTJAVA}/demo/nio/zipfs/zipfs.jar"
146.38 +if [ ! -r "${ZIPFS}" ]; then
146.39 + echo "${ZIPFS} not found"
146.40 + exit 0
146.41 +fi
146.42 +
146.43 +OS=`uname -s`
146.44 +case "$OS" in
146.45 + Windows_* )
146.46 + CLASSPATH="${TESTCLASSES};${ZIPFS}"
146.47 + ;;
146.48 + * )
146.49 + CLASSPATH="${TESTCLASSES}:${ZIPFS}"
146.50 + ;;
146.51 +esac
146.52 +export CLASSPATH
146.53 +
146.54 +failures=0
146.55 +
146.56 +go() {
146.57 + echo ""
146.58 + ${TESTJAVA}/bin/java $1 $2 $3 2>&1
146.59 + if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
146.60 +}
146.61 +
146.62 +# Run the tests
146.63 +
146.64 +go Basic "${ZIPFS}"
146.65 +go PathOps "${ZIPFS}"
146.66 +go ZipFSTester "${ZIPFS}"
146.67 +
146.68 +#
146.69 +# Results
146.70 +#
146.71 +
146.72 +if [ $failures -gt 0 ];
146.73 +then echo "$failures tests failed";
146.74 +else echo "All tests passed";
146.75 +fi
146.76 +exit $failures
147.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
147.2 +++ b/test/java/awt/Focus/FocusOwnerFrameOnClick/FocusOwnerFrameOnClick.java Tue Oct 12 12:51:48 2010 -0700
147.3 @@ -0,0 +1,125 @@
147.4 +/*
147.5 + * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
147.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
147.7 + *
147.8 + * This code is free software; you can redistribute it and/or modify it
147.9 + * under the terms of the GNU General Public License version 2 only, as
147.10 + * published by the Free Software Foundation. Oracle designates this
147.11 + * particular file as subject to the "Classpath" exception as provided
147.12 + * by Oracle in the LICENSE file that accompanied this code.
147.13 + *
147.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
147.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
147.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
147.17 + * version 2 for more details (a copy is included in the LICENSE file that
147.18 + * accompanied this code).
147.19 + *
147.20 + * You should have received a copy of the GNU General Public License version
147.21 + * 2 along with this work; if not, write to the Free Software Foundation,
147.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
147.23 + *
147.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
147.25 + * or visit www.oracle.com if you need additional information or have any
147.26 + * questions.
147.27 + */
147.28 +
147.29 +/*
147.30 + @test FocusOwnerFrameOnClick.java %W% %E%
147.31 + @bug 6886678
147.32 + @summary Tests that clicking an owner frame switches focus from its owned window.
147.33 + @author Anton Tarasov: area=awt.focus
147.34 + @library ../../regtesthelpers
147.35 + @build Util
147.36 + @run main FocusOwnerFrameOnClick
147.37 +*/
147.38 +
147.39 +import java.awt.*;
147.40 +import java.awt.event.*;
147.41 +import java.applet.Applet;
147.42 +import java.util.concurrent.atomic.AtomicBoolean;
147.43 +import java.lang.reflect.InvocationTargetException;
147.44 +import test.java.awt.regtesthelpers.Util;
147.45 +
147.46 +public class FocusOwnerFrameOnClick extends Applet {
147.47 + Robot robot;
147.48 + Frame frame = new Frame("Frame");
147.49 + Window window = new Window(frame);
147.50 + Button fButton = new Button("fButton");
147.51 + Button wButton = new Button("wButton");
147.52 +
147.53 + AtomicBoolean focused = new AtomicBoolean(false);
147.54 +
147.55 + public static void main(String[] args) {
147.56 + FocusOwnerFrameOnClick app = new FocusOwnerFrameOnClick();
147.57 + app.init();
147.58 + app.start();
147.59 + }
147.60 +
147.61 + public void init() {
147.62 + robot = Util.createRobot();
147.63 +
147.64 + frame.setLayout(new FlowLayout());
147.65 + frame.setSize(200, 200);
147.66 + frame.add(fButton);
147.67 +
147.68 + window.setLocation(300, 0);
147.69 + window.add(wButton);
147.70 + window.pack();
147.71 + }
147.72 +
147.73 + public void start() {
147.74 + frame.setVisible(true);
147.75 + Util.waitForIdle(robot);
147.76 +
147.77 + window.setVisible(true);
147.78 + Util.waitForIdle(robot);
147.79 +
147.80 + if (!wButton.hasFocus()) {
147.81 + if (!Util.trackFocusGained(wButton, new Runnable() {
147.82 + public void run() {
147.83 + Util.clickOnComp(wButton, robot);
147.84 + }
147.85 + }, 2000, false))
147.86 + {
147.87 + throw new TestErrorException("wButton didn't gain focus on showing");
147.88 + }
147.89 + }
147.90 +
147.91 + Runnable clickAction = new Runnable() {
147.92 + public void run() {
147.93 + Point loc = fButton.getLocationOnScreen();
147.94 + Dimension dim = fButton.getSize();
147.95 +
147.96 + robot.mouseMove(loc.x, loc.y + dim.height + 20);
147.97 + robot.delay(50);
147.98 + robot.mousePress(InputEvent.BUTTON1_MASK);
147.99 + robot.delay(50);
147.100 + robot.mouseRelease(InputEvent.BUTTON1_MASK);
147.101 + }
147.102 + };
147.103 +
147.104 + if (!Util.trackWindowGainedFocus(frame, clickAction, 2000, true)) {
147.105 + throw new TestFailedException("The frame wasn't focused on click");
147.106 + }
147.107 +
147.108 + System.out.println("Test passed.");
147.109 + }
147.110 +}
147.111 +
147.112 +/**
147.113 + * Thrown when the behavior being verified is found wrong.
147.114 + */
147.115 +class TestFailedException extends RuntimeException {
147.116 + TestFailedException(String msg) {
147.117 + super("Test failed: " + msg);
147.118 + }
147.119 +}
147.120 +
147.121 +/**
147.122 + * Thrown when an error not related to the behavior being verified is encountered.
147.123 + */
147.124 +class TestErrorException extends RuntimeException {
147.125 + TestErrorException(String msg) {
147.126 + super("Unexpected error: " + msg);
147.127 + }
147.128 +}
148.1 --- a/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java Thu Oct 07 15:12:19 2010 -0700
148.2 +++ b/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java Tue Oct 12 12:51:48 2010 -0700
148.3 @@ -21,16 +21,15 @@
148.4 static final int SHIFT = 1;
148.5 static final int CTRL = 2;
148.6 static final int ALT = 3;
148.7 - static CheckingModifierAdapter adapterTest1;
148.8 - static CheckingModifierAdapter adapterTest2;
148.9 - static CheckingModifierAdapter adapterTest3;
148.10 - static CheckingModifierAdapter adapterTest4;
148.11 + static CheckingModifierAdapterExtra adapterTest1;
148.12 + static CheckingModifierAdapterExtra adapterTest2;
148.13 + static CheckingModifierAdapterExtra adapterTest3;
148.14 + static CheckingModifierAdapterExtra adapterTest4;
148.15
148.16 static boolean debug = true; //dump all errors (debug) or throw first(under jtreg) exception
148.17 static boolean autorun = false; //use robot or manual run
148.18 static int testModifier = NONE;
148.19
148.20 - static int [] mouseButtons;
148.21 static int [] mouseButtonDownMasks;
148.22
148.23 //an arrays representing a modifiersEx of extra mouse buttons while using ALT/CTRL/SHIFT or none of them
148.24 @@ -39,7 +38,6 @@
148.25 static int [] modifiersExStandardCTRL;
148.26 static int [] modifiersExStandardALT;
148.27
148.28 - // final static int [] mouseButtons = new int [] {MouseEvent.BUTTON1_MASK, MouseEvent.BUTTON2_MASK, MouseEvent.BUTTON3_MASK};
148.29 // BUTTON1, 2, 3 press-release.
148.30 final static int modifiersStandard = 0; //InputEvent.BUTTON_DOWN_MASK;
148.31
148.32 @@ -56,7 +54,7 @@
148.33
148.34 if (modifiersEx != curStandardExModifiers[index]){
148.35 // System.out.println(">>>>>>>>>>>>>>> Pressed. modifiersEx "+modifiersEx +" : "+!= curStandardExModifiers");
148.36 - MessageLogger.reportError("Test failed : Pressed. modifiersEx != curStandardExModifiers");
148.37 + MessageLogger.reportError("Test failed : Pressed. modifiersEx != curStandardExModifiers. Got: " + modifiersEx + " , Expected: " + curStandardExModifiers[index]);
148.38 }
148.39
148.40 //check event.paramString() output
148.41 @@ -168,7 +166,7 @@
148.42 }
148.43
148.44 if (modifiersEx != curStandardExModifiers[index]){
148.45 - MessageLogger.reportError("Test failed : Released. modifiersEx != curStandardExModifiers");
148.46 + MessageLogger.reportError("Test failed : Released. modifiersEx != curStandardExModifiers. Got: " + modifiersEx + " , Expected: " + curStandardExModifiers[index]);
148.47 }
148.48
148.49 //check event.paramString() output
148.50 @@ -191,7 +189,7 @@
148.51 }
148.52
148.53 if (modifiersEx != curStandardExModifiers[index]){
148.54 - MessageLogger.reportError("Test failed : Clicked. modifiersEx != curStandardExModifiers");
148.55 + MessageLogger.reportError("Test failed : Clicked. modifiersEx != curStandardExModifiers. Got: " + modifiersEx + " , Expected: " + curStandardExModifiers[index]);
148.56 }
148.57
148.58 //check event.paramString() output
148.59 @@ -275,11 +273,11 @@
148.60 this.addMouseListener(adapterTest1);
148.61 robot.delay(1000);
148.62 robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
148.63 - for (int i = 3; i< mouseButtons.length; i++){
148.64 - System.out.println("testNONE() => " +mouseButtons[i] );
148.65 - robot.mousePress(mouseButtons[i]);
148.66 + for (int i = 3; i< mouseButtonDownMasks.length; i++){
148.67 + System.out.println("testNONE() => " +mouseButtonDownMasks[i] );
148.68 + robot.mousePress(mouseButtonDownMasks[i]);
148.69 robot.delay(100);
148.70 - robot.mouseRelease(mouseButtons[i]);
148.71 + robot.mouseRelease(mouseButtonDownMasks[i]);
148.72 }
148.73 robot.delay(1000);
148.74 this.removeMouseListener(adapterTest1);
148.75 @@ -289,12 +287,12 @@
148.76 this.addMouseListener(adapterTest2);
148.77 robot.delay(1000);
148.78 robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
148.79 - for (int i = 3; i< mouseButtons.length; i++){
148.80 + for (int i = 3; i< mouseButtonDownMasks.length; i++){
148.81 robot.keyPress(KeyEvent.VK_SHIFT);
148.82 - System.out.println("testSHIFT() => " +mouseButtons[i] );
148.83 - robot.mousePress(mouseButtons[i]);
148.84 + System.out.println("testSHIFT() => " +mouseButtonDownMasks[i] );
148.85 + robot.mousePress(mouseButtonDownMasks[i]);
148.86 robot.delay(100);
148.87 - robot.mouseRelease(mouseButtons[i]);
148.88 + robot.mouseRelease(mouseButtonDownMasks[i]);
148.89 robot.keyRelease(KeyEvent.VK_SHIFT);
148.90 }
148.91 robot.delay(1000);
148.92 @@ -305,12 +303,12 @@
148.93 this.addMouseListener(adapterTest3);
148.94 robot.delay(1000);
148.95 robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
148.96 - for (int i = 3; i< mouseButtons.length; i++){
148.97 + for (int i = 3; i< mouseButtonDownMasks.length; i++){
148.98 robot.keyPress(KeyEvent.VK_CONTROL);
148.99 - System.out.println("testCTRL() => " +mouseButtons[i] );
148.100 - robot.mousePress(mouseButtons[i]);
148.101 + System.out.println("testCTRL() => " +mouseButtonDownMasks[i] );
148.102 + robot.mousePress(mouseButtonDownMasks[i]);
148.103 robot.delay(100);
148.104 - robot.mouseRelease(mouseButtons[i]);
148.105 + robot.mouseRelease(mouseButtonDownMasks[i]);
148.106 robot.keyRelease(KeyEvent.VK_CONTROL);
148.107 }
148.108 robot.delay(1000);
148.109 @@ -321,12 +319,12 @@
148.110 this.addMouseListener(adapterTest4);
148.111 robot.delay(1000);
148.112 robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
148.113 - for (int i = 3; i< mouseButtons.length; i++){
148.114 + for (int i = 3; i< mouseButtonDownMasks.length; i++){
148.115 robot.keyPress(KeyEvent.VK_ALT);
148.116 - System.out.println("testALT() => " +mouseButtons[i] );
148.117 - robot.mousePress(mouseButtons[i]);
148.118 + System.out.println("testALT() => " +mouseButtonDownMasks[i] );
148.119 + robot.mousePress(mouseButtonDownMasks[i]);
148.120 robot.delay(100);
148.121 - robot.mouseRelease(mouseButtons[i]);
148.122 + robot.mouseRelease(mouseButtonDownMasks[i]);
148.123 robot.keyRelease(KeyEvent.VK_ALT);
148.124 }
148.125 robot.delay(1000);
148.126 @@ -368,52 +366,52 @@
148.127 }
148.128
148.129 public static void initAdapters(){
148.130 - adapterTest1 = new CheckingModifierAdapter(NONE);
148.131 - adapterTest2 = new CheckingModifierAdapter(SHIFT);
148.132 - adapterTest3 = new CheckingModifierAdapter(CTRL);
148.133 - adapterTest4 = new CheckingModifierAdapter(ALT);
148.134 + adapterTest1 = new CheckingModifierAdapterExtra(NONE);
148.135 + adapterTest2 = new CheckingModifierAdapterExtra(SHIFT);
148.136 + adapterTest3 = new CheckingModifierAdapterExtra(CTRL);
148.137 + adapterTest4 = new CheckingModifierAdapterExtra(ALT);
148.138 }
148.139
148.140 public static void initVars(){
148.141 - int [] tmp = new int [MouseInfo.getNumberOfButtons()];
148.142 - for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
148.143 - tmp[i] = InputEvent.getMaskForButton(i+1);
148.144 - // System.out.println("TEST: "+tmp[i]);
148.145 + //Init the array of the mouse button masks. It will be used for generating mouse events.
148.146 + mouseButtonDownMasks = new int [MouseInfo.getNumberOfButtons()];
148.147 + for (int i = 0; i < mouseButtonDownMasks.length; i++){
148.148 + mouseButtonDownMasks[i] = InputEvent.getMaskForButton(i+1);
148.149 + System.out.println("MouseArray [i] == "+mouseButtonDownMasks[i]);
148.150 }
148.151
148.152 - mouseButtons = Arrays.copyOf(tmp, tmp.length);
148.153 -
148.154 - for (int i = 0; i < mouseButtons.length; i++){
148.155 - System.out.println("MouseArray [i] == "+mouseButtons[i]);
148.156 - }
148.157 -
148.158 - mouseButtonDownMasks = Arrays.copyOf(tmp, tmp.length);
148.159 -
148.160 // So we need to get the number of extra buttons on the mouse: "MouseInfo.getNumberOfButtons() - 3"
148.161 // and multyply on 3 because each button will generate three events : PRESS, RELEASE and CLICK.
148.162 - tmp = new int [(MouseInfo.getNumberOfButtons()-3)*3];
148.163 + int [] tmp = new int [(MouseInfo.getNumberOfButtons()-3)*3];
148.164 +
148.165 + //Fill array of expected results for the case when mouse buttons are only used (no-modifier keys)
148.166 Arrays.fill(tmp, 0);
148.167 -
148.168 for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
148.169 tmp[i] = mouseButtonDownMasks[j];
148.170 }
148.171 modifiersExStandard = Arrays.copyOf(tmp, tmp.length);
148.172
148.173 + //Fill array of expected results for the case when mouse buttons are only used with SHIFT modifier key
148.174 Arrays.fill(tmp, InputEvent.SHIFT_DOWN_MASK);
148.175 - for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){
148.176 - tmp[i] = tmp[j] | mouseButtonDownMasks[j];
148.177 + for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
148.178 + System.out.println("modifiersExStandardSHIFT FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]);
148.179 + tmp[i] = tmp[i] | mouseButtonDownMasks[j];
148.180 }
148.181 modifiersExStandardSHIFT = Arrays.copyOf(tmp, tmp.length);
148.182
148.183 + //Fill array of expected results for the case when mouse buttons are only used with CTRL modifier key
148.184 Arrays.fill(tmp, InputEvent.CTRL_DOWN_MASK);
148.185 - for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){
148.186 - tmp[i] = tmp[j] | mouseButtonDownMasks[j];
148.187 + for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
148.188 + System.out.println("modifiersExStandardCTRL FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]);
148.189 + tmp[i] = tmp[i] | mouseButtonDownMasks[j];
148.190 }
148.191 modifiersExStandardCTRL = Arrays.copyOf(tmp, tmp.length);
148.192
148.193 + //Fill array of expected results for the case when mouse buttons are only used with ALT modifier key
148.194 Arrays.fill(tmp, InputEvent.ALT_DOWN_MASK);
148.195 - for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){
148.196 - tmp[i] = tmp[j] | mouseButtonDownMasks[j];
148.197 + for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
148.198 + System.out.println("modifiersExStandardALT FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]);
148.199 + tmp[i] = tmp[i] | mouseButtonDownMasks[j];
148.200 }
148.201 modifiersExStandardALT = Arrays.copyOf(tmp, tmp.length);
148.202 }
148.203 @@ -436,9 +434,9 @@
148.204 /* A class that invoke appropriate verification
148.205 * routine with current modifier.
148.206 */
148.207 -class CheckingModifierAdapter extends MouseAdapter{
148.208 +class CheckingModifierAdapterExtra extends MouseAdapter{
148.209 int modifier;
148.210 - public CheckingModifierAdapter(int modifier){
148.211 + public CheckingModifierAdapterExtra(int modifier){
148.212 this.modifier = modifier;
148.213 }
148.214
149.1 --- a/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java Thu Oct 07 15:12:19 2010 -0700
149.2 +++ b/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java Tue Oct 12 12:51:48 2010 -0700
149.3 @@ -90,7 +90,7 @@
149.4 int [] buttonMasks = new int[MouseInfo.getNumberOfButtons()]; // = InputEvent.getButtonDownMasks();
149.5 for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
149.6 buttonMasks[i] = InputEvent.getMaskForButton(i+1);
149.7 - System.out.println("TEST: "+buttonMasks[i]);
149.8 + System.out.println("TEST: buttonMasks["+ i +"] = " + buttonMasks[i]);
149.9 }
149.10
149.11 for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
150.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
150.2 +++ b/test/java/awt/image/GetSamplesTest.java Tue Oct 12 12:51:48 2010 -0700
150.3 @@ -0,0 +1,121 @@
150.4 +/*
150.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
150.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
150.7 + *
150.8 + * This code is free software; you can redistribute it and/or modify it
150.9 + * under the terms of the GNU General Public License version 2 only, as
150.10 + * published by the Free Software Foundation.
150.11 + *
150.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
150.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
150.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
150.15 + * version 2 for more details (a copy is included in the LICENSE file that
150.16 + * accompanied this code).
150.17 + *
150.18 + * You should have received a copy of the GNU General Public License version
150.19 + * 2 along with this work; if not, write to the Free Software Foundation,
150.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
150.21 + *
150.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
150.23 + * or visit www.oracle.com if you need additional information or have any
150.24 + * questions.
150.25 + */
150.26 +
150.27 +/*
150.28 + * @test
150.29 + * @bug 6735275
150.30 + * @summary Test verifies that SampleModel.getSamples() throws an appropriate
150.31 + * exception if coordinates are not in bounds.
150.32 + *
150.33 + * @run main GetSamplesTest
150.34 + */
150.35 +
150.36 +import java.awt.image.BandedSampleModel;
150.37 +import java.awt.image.ComponentSampleModel;
150.38 +import java.awt.image.DataBuffer;
150.39 +import java.awt.image.MultiPixelPackedSampleModel;
150.40 +import java.awt.image.PixelInterleavedSampleModel;
150.41 +import java.awt.image.SampleModel;
150.42 +import java.awt.image.SinglePixelPackedSampleModel;
150.43 +import java.util.Vector;
150.44 +
150.45 +public class GetSamplesTest {
150.46 +
150.47 + public static int width = 100;
150.48 + public static int height = 100;
150.49 + public static int dataType = DataBuffer.TYPE_BYTE;
150.50 + public static int numBands = 4;
150.51 +
150.52 + public static void main(String[] args) {
150.53 + Vector<Class<? extends SampleModel>> classes = new Vector<Class<? extends SampleModel>>();
150.54 +
150.55 + classes.add(ComponentSampleModel.class);
150.56 + classes.add(MultiPixelPackedSampleModel.class);
150.57 + classes.add(SinglePixelPackedSampleModel.class);
150.58 + classes.add(BandedSampleModel.class);
150.59 + classes.add(PixelInterleavedSampleModel.class);
150.60 +
150.61 + for (Class<? extends SampleModel> c : classes) {
150.62 + doTest(c);
150.63 + }
150.64 + }
150.65 + private static void doTest(Class<? extends SampleModel> c) {
150.66 + System.out.println("Test for: " + c.getName());
150.67 + SampleModel sm = createSampleModel(c);
150.68 +
150.69 + DataBuffer db = sm.createDataBuffer();
150.70 +
150.71 + int[] iArray = new int[ width * height + numBands];
150.72 + float[] fArray = new float[ width * height + numBands];
150.73 + double[] dArray = new double[ width * height + numBands];
150.74 +
150.75 + boolean iOk = false;
150.76 + boolean fOk = false;
150.77 + boolean dOk = false;
150.78 +
150.79 + try {
150.80 + sm.getSamples(Integer.MAX_VALUE, 0, 1, 1, 0, iArray, db);
150.81 + } catch (ArrayIndexOutOfBoundsException e) {
150.82 + System.out.println(e.getMessage());
150.83 + iOk = true;
150.84 + }
150.85 +
150.86 + try {
150.87 + sm.getSamples(Integer.MAX_VALUE, 0, 1, 1, 0, fArray, db);
150.88 + } catch (ArrayIndexOutOfBoundsException e) {
150.89 + System.out.println(e.getMessage());
150.90 + fOk = true;
150.91 + }
150.92 +
150.93 + try {
150.94 + sm.getSamples(0, Integer.MAX_VALUE, 1, 1, 0, dArray, db);
150.95 + } catch (ArrayIndexOutOfBoundsException e) {
150.96 + System.out.println(e.getMessage());
150.97 + dOk = true;
150.98 + }
150.99 + if (!iOk || !fOk || !dOk) {
150.100 + throw new RuntimeException("Test for " + c.getSimpleName() +
150.101 + " failed: iOk=" + iOk + "; fOk=" + fOk + "; dOk=" + dOk);
150.102 + }
150.103 + }
150.104 +
150.105 + private static SampleModel createSampleModel(Class<? extends SampleModel> cls) {
150.106 + SampleModel res = null;
150.107 +
150.108 + if (cls == ComponentSampleModel.class) {
150.109 + res = new ComponentSampleModel(dataType, width, height, 4, width * 4, new int[] { 0, 1, 2, 3 } );
150.110 + } else if (cls == MultiPixelPackedSampleModel.class) {
150.111 + res = new MultiPixelPackedSampleModel(dataType, width, height, 4);
150.112 + } else if (cls == SinglePixelPackedSampleModel.class) {
150.113 + res = new SinglePixelPackedSampleModel(dataType, width, height,
150.114 + new int[]{ 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff });
150.115 + } else if (cls == BandedSampleModel.class) {
150.116 + res = new BandedSampleModel(dataType, width, height, numBands);
150.117 + } else if (cls == PixelInterleavedSampleModel.class) {
150.118 + res = new PixelInterleavedSampleModel(dataType, width, height, 4, width * 4, new int[] { 0, 1, 2, 3 });
150.119 + } else {
150.120 + throw new RuntimeException("Unknown class " + cls);
150.121 + }
150.122 + return res;
150.123 + }
150.124 +}
151.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
151.2 +++ b/test/java/beans/Introspector/6976577/Test6976577.java Tue Oct 12 12:51:48 2010 -0700
151.3 @@ -0,0 +1,71 @@
151.4 +/*
151.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
151.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
151.7 + *
151.8 + * This code is free software; you can redistribute it and/or modify it
151.9 + * under the terms of the GNU General Public License version 2 only, as
151.10 + * published by the Free Software Foundation.
151.11 + *
151.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
151.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
151.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
151.15 + * version 2 for more details (a copy is included in the LICENSE file that
151.16 + * accompanied this code).
151.17 + *
151.18 + * You should have received a copy of the GNU General Public License version
151.19 + * 2 along with this work; if not, write to the Free Software Foundation,
151.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
151.21 + *
151.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
151.23 + * or visit www.oracle.com if you need additional information or have any
151.24 + * questions.
151.25 + */
151.26 +
151.27 +/*
151.28 + * @test
151.29 + * @bug 6976577
151.30 + * @summary Tests public methods in non-public beans
151.31 + * @author Sergey Malenkov
151.32 + */
151.33 +
151.34 +import test.Accessor;
151.35 +
151.36 +import java.beans.EventSetDescriptor;
151.37 +import java.beans.IndexedPropertyDescriptor;
151.38 +import java.beans.PropertyDescriptor;
151.39 +import java.lang.reflect.Method;
151.40 +
151.41 +public class Test6976577 {
151.42 +
151.43 + public static void main(String[] args) throws Exception {
151.44 + Class<?> bt = Accessor.getBeanType();
151.45 + Class<?> lt = Accessor.getListenerType();
151.46 +
151.47 + // test PropertyDescriptor
151.48 + PropertyDescriptor pd = new PropertyDescriptor("boolean", bt);
151.49 + test(pd.getReadMethod());
151.50 + test(pd.getWriteMethod());
151.51 +
151.52 + // test IndexedPropertyDescriptor
151.53 + IndexedPropertyDescriptor ipd = new IndexedPropertyDescriptor("indexed", bt);
151.54 + test(ipd.getReadMethod());
151.55 + test(ipd.getWriteMethod());
151.56 + test(ipd.getIndexedReadMethod());
151.57 + test(ipd.getIndexedWriteMethod());
151.58 +
151.59 + // test EventSetDescriptor
151.60 + EventSetDescriptor esd = new EventSetDescriptor(bt, "test", lt, "process");
151.61 + test(esd.getAddListenerMethod());
151.62 + test(esd.getRemoveListenerMethod());
151.63 + test(esd.getGetListenerMethod());
151.64 + test(esd.getListenerMethods());
151.65 + }
151.66 +
151.67 + private static void test(Method... methods) {
151.68 + for (Method method : methods) {
151.69 + if (method == null) {
151.70 + throw new Error("public method is not found");
151.71 + }
151.72 + }
151.73 + }
151.74 +}
152.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
152.2 +++ b/test/java/beans/Introspector/6976577/test/Accessor.java Tue Oct 12 12:51:48 2010 -0700
152.3 @@ -0,0 +1,81 @@
152.4 +package test;
152.5 +
152.6 +import java.beans.PropertyChangeListener;
152.7 +import java.beans.PropertyChangeSupport;
152.8 +import java.util.EventListener;
152.9 +import java.util.TooManyListenersException;
152.10 +
152.11 +public class Accessor {
152.12 +
152.13 + public static Class<?> getBeanType() {
152.14 + return Bean.class;
152.15 + }
152.16 +
152.17 + public static Class<?> getListenerType() {
152.18 + return TestListener.class;
152.19 + }
152.20 +}
152.21 +
152.22 +interface TestEvent {
152.23 +}
152.24 +
152.25 +interface TestListener extends EventListener {
152.26 + void process(TestEvent event);
152.27 +}
152.28 +
152.29 +class Bean {
152.30 +
152.31 + private boolean b;
152.32 + private int[] indexed;
152.33 + private TestListener listener;
152.34 + private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
152.35 +
152.36 + public void addPropertyChangeListener(PropertyChangeListener listener) {
152.37 + this.pcs.addPropertyChangeListener(listener);
152.38 + }
152.39 +
152.40 + public void addTestListener(TestListener listener) throws TooManyListenersException {
152.41 + if (listener != null) {
152.42 + if (this.listener != null) {
152.43 + throw new TooManyListenersException();
152.44 + }
152.45 + this.listener = listener;
152.46 + }
152.47 + }
152.48 +
152.49 + public void removeTestListener(TestListener listener) {
152.50 + if (this.listener == listener) {
152.51 + this.listener = null;
152.52 + }
152.53 + }
152.54 +
152.55 + public TestListener[] getTestListeners() {
152.56 + return (this.listener != null)
152.57 + ? new TestListener[] { this.listener }
152.58 + : new TestListener[0];
152.59 + }
152.60 +
152.61 + public boolean isBoolean() {
152.62 + return this.b;
152.63 + }
152.64 +
152.65 + public void setBoolean(boolean b) {
152.66 + this.b = b;
152.67 + }
152.68 +
152.69 + public int[] getIndexed() {
152.70 + return this.indexed;
152.71 + }
152.72 +
152.73 + public void setIndexed(int[] values) {
152.74 + this.indexed = values;
152.75 + }
152.76 +
152.77 + public int getIndexed(int index) {
152.78 + return this.indexed[index];
152.79 + }
152.80 +
152.81 + public void setIndexed(int index, int value) {
152.82 + this.indexed[index] = value;
152.83 + }
152.84 +}
153.1 --- a/test/java/lang/ProcessBuilder/Basic.java Thu Oct 07 15:12:19 2010 -0700
153.2 +++ b/test/java/lang/ProcessBuilder/Basic.java Tue Oct 12 12:51:48 2010 -0700
153.3 @@ -1825,6 +1825,64 @@
153.4 } catch (Throwable t) { unexpected(t); }
153.5
153.6 //----------------------------------------------------------------
153.7 + // Check that subprocesses which create subprocesses of their
153.8 + // own do not cause parent to hang waiting for file
153.9 + // descriptors to be closed.
153.10 + //----------------------------------------------------------------
153.11 + try {
153.12 + if (Unix.is()
153.13 + && new File("/bin/bash").exists()
153.14 + && new File("/bin/sleep").exists()) {
153.15 + final String[] cmd = { "/bin/bash", "-c", "(/bin/sleep 6666)" };
153.16 + final ProcessBuilder pb = new ProcessBuilder(cmd);
153.17 + final Process p = pb.start();
153.18 + final InputStream stdout = p.getInputStream();
153.19 + final InputStream stderr = p.getErrorStream();
153.20 + final OutputStream stdin = p.getOutputStream();
153.21 + final Thread reader = new Thread() {
153.22 + public void run() {
153.23 + try { stdout.read(); }
153.24 + catch (IOException e) {
153.25 + // e.printStackTrace();
153.26 + if (EnglishUnix.is() &&
153.27 + ! (e.getMessage().matches(".*Bad file descriptor.*")))
153.28 + unexpected(e);
153.29 + }
153.30 + catch (Throwable t) { unexpected(t); }}};
153.31 + reader.setDaemon(true);
153.32 + reader.start();
153.33 + Thread.sleep(100);
153.34 + p.destroy();
153.35 + // Subprocess is now dead, but file descriptors remain open.
153.36 + check(p.waitFor() != 0);
153.37 + check(p.exitValue() != 0);
153.38 + stdout.close();
153.39 + stderr.close();
153.40 + stdin.close();
153.41 + //----------------------------------------------------------
153.42 + // There remain unsolved issues with asynchronous close.
153.43 + // Here's a highly non-portable experiment to demonstrate:
153.44 + //----------------------------------------------------------
153.45 + if (Boolean.getBoolean("wakeupJeff!")) {
153.46 + System.out.println("wakeupJeff!");
153.47 + // Initialize signal handler for INTERRUPT_SIGNAL.
153.48 + new FileInputStream("/bin/sleep").getChannel().close();
153.49 + // Send INTERRUPT_SIGNAL to every thread in this java.
153.50 + String[] wakeupJeff = {
153.51 + "/bin/bash", "-c",
153.52 + "/bin/ps --noheaders -Lfp $PPID | " +
153.53 + "/usr/bin/perl -nale 'print $F[3]' | " +
153.54 + // INTERRUPT_SIGNAL == 62 on my machine du jour.
153.55 + "/usr/bin/xargs kill -62"
153.56 + };
153.57 + new ProcessBuilder(wakeupJeff).start().waitFor();
153.58 + // If wakeupJeff worked, reader probably got EBADF.
153.59 + reader.join();
153.60 + }
153.61 + }
153.62 + } catch (Throwable t) { unexpected(t); }
153.63 +
153.64 + //----------------------------------------------------------------
153.65 // Attempt to start process with insufficient permissions fails.
153.66 //----------------------------------------------------------------
153.67 try {
154.1 --- a/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java Thu Oct 07 15:12:19 2010 -0700
154.2 +++ b/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java Tue Oct 12 12:51:48 2010 -0700
154.3 @@ -29,7 +29,9 @@
154.4
154.5 import java.nio.channels.*;
154.6 import java.net.*;
154.7 +import static java.net.StandardSocketOption.*;
154.8 import java.io.IOException;
154.9 +import java.util.Set;
154.10 import java.util.concurrent.ExecutionException;
154.11 import java.util.concurrent.Future;
154.12 import java.util.concurrent.atomic.AtomicReference;
154.13 @@ -39,6 +41,7 @@
154.14 public static void main(String[] args) throws Exception {
154.15 testBind();
154.16 testAccept();
154.17 + testSocketOptions();
154.18 }
154.19
154.20 static void testBind() throws Exception {
154.21 @@ -131,4 +134,39 @@
154.22 }
154.23
154.24 }
154.25 +
154.26 + static void testSocketOptions() throws Exception {
154.27 + System.out.println("-- socket options --");
154.28 + AsynchronousServerSocketChannel ch = AsynchronousServerSocketChannel.open();
154.29 + try {
154.30 + // check supported options
154.31 + Set<SocketOption<?>> options = ch.supportedOptions();
154.32 + if (!options.contains(SO_REUSEADDR))
154.33 + throw new RuntimeException("SO_REUSEADDR should be supported");
154.34 + if (!options.contains(SO_RCVBUF))
154.35 + throw new RuntimeException("SO_RCVBUF should be supported");
154.36 +
154.37 + // allowed to change when not bound
154.38 + ch.setOption(SO_RCVBUF, 256*1024); // can't check
154.39 + int before = ch.getOption(SO_RCVBUF);
154.40 + int after = ch.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
154.41 + if (after < before)
154.42 + throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
154.43 + ch.setOption(SO_REUSEADDR, true);
154.44 + checkOption(ch, SO_REUSEADDR, true);
154.45 + ch.setOption(SO_REUSEADDR, false);
154.46 + checkOption(ch, SO_REUSEADDR, false);
154.47 + } finally {
154.48 + ch.close();
154.49 + }
154.50 + }
154.51 +
154.52 + static void checkOption(AsynchronousServerSocketChannel ch,
154.53 + SocketOption name, Object expectedValue)
154.54 + throws IOException
154.55 + {
154.56 + Object value = ch.getOption(name);
154.57 + if (!value.equals(expectedValue))
154.58 + throw new RuntimeException("value not as expected");
154.59 + }
154.60 }
155.1 --- a/test/java/nio/channels/AsynchronousSocketChannel/Basic.java Thu Oct 07 15:12:19 2010 -0700
155.2 +++ b/test/java/nio/channels/AsynchronousSocketChannel/Basic.java Tue Oct 12 12:51:48 2010 -0700
155.3 @@ -121,8 +121,20 @@
155.4 AsynchronousSocketChannel ch = AsynchronousSocketChannel.open()
155.5 .setOption(SO_RCVBUF, 128*1024)
155.6 .setOption(SO_SNDBUF, 128*1024)
155.7 - .setOption(SO_REUSEADDR, true)
155.8 - .bind(new InetSocketAddress(0));
155.9 + .setOption(SO_REUSEADDR, true);
155.10 +
155.11 + // check SO_SNDBUF/SO_RCVBUF limits
155.12 + int before, after;
155.13 + before = ch.getOption(SO_SNDBUF);
155.14 + after = ch.setOption(SO_SNDBUF, Integer.MAX_VALUE).getOption(SO_SNDBUF);
155.15 + if (after < before)
155.16 + throw new RuntimeException("setOption caused SO_SNDBUF to decrease");
155.17 + before = ch.getOption(SO_RCVBUF);
155.18 + after = ch.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
155.19 + if (after < before)
155.20 + throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
155.21 +
155.22 + ch.bind(new InetSocketAddress(0));
155.23
155.24 // default values
155.25 if ((Boolean)ch.getOption(SO_KEEPALIVE))
156.1 --- a/test/java/nio/channels/DatagramChannel/SocketOptionTests.java Thu Oct 07 15:12:19 2010 -0700
156.2 +++ b/test/java/nio/channels/DatagramChannel/SocketOptionTests.java Tue Oct 12 12:51:48 2010 -0700
156.3 @@ -68,8 +68,17 @@
156.4 checkOption(dc, SO_BROADCAST, true);
156.5 dc.setOption(SO_BROADCAST, false);
156.6 checkOption(dc, SO_BROADCAST, false);
156.7 - dc.setOption(SO_SNDBUF, 16*1024); // can't check
156.8 - dc.setOption(SO_RCVBUF, 16*1024); // can't check
156.9 + dc.setOption(SO_SNDBUF, 128*1024); // can't check
156.10 + dc.setOption(SO_RCVBUF, 128*1024); // can't check
156.11 + int before, after;
156.12 + before = dc.getOption(SO_SNDBUF);
156.13 + after = dc.setOption(SO_SNDBUF, Integer.MAX_VALUE).getOption(SO_SNDBUF);
156.14 + if (after < before)
156.15 + throw new RuntimeException("setOption caused SO_SNDBUF to decrease");
156.16 + before = dc.getOption(SO_RCVBUF);
156.17 + after = dc.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
156.18 + if (after < before)
156.19 + throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
156.20 dc.setOption(SO_REUSEADDR, true);
156.21 checkOption(dc, SO_REUSEADDR, true);
156.22 dc.setOption(SO_REUSEADDR, false);
157.1 --- a/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java Thu Oct 07 15:12:19 2010 -0700
157.2 +++ b/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java Tue Oct 12 12:51:48 2010 -0700
157.3 @@ -56,6 +56,10 @@
157.4
157.5 // allowed to change when not bound
157.6 ssc.setOption(SO_RCVBUF, 256*1024); // can't check
157.7 + int before = ssc.getOption(SO_RCVBUF);
157.8 + int after = ssc.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
157.9 + if (after < before)
157.10 + throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
157.11 ssc.setOption(SO_REUSEADDR, true);
157.12 checkOption(ssc, SO_REUSEADDR, true);
157.13 ssc.setOption(SO_REUSEADDR, false);
158.1 --- a/test/java/nio/channels/SocketChannel/SocketOptionTests.java Thu Oct 07 15:12:19 2010 -0700
158.2 +++ b/test/java/nio/channels/SocketChannel/SocketOptionTests.java Tue Oct 12 12:51:48 2010 -0700
158.3 @@ -70,6 +70,15 @@
158.4 checkOption(sc, SO_KEEPALIVE, false);
158.5 sc.setOption(SO_SNDBUF, 128*1024); // can't check
158.6 sc.setOption(SO_RCVBUF, 256*1024); // can't check
158.7 + int before, after;
158.8 + before = sc.getOption(SO_SNDBUF);
158.9 + after = sc.setOption(SO_SNDBUF, Integer.MAX_VALUE).getOption(SO_SNDBUF);
158.10 + if (after < before)
158.11 + throw new RuntimeException("setOption caused SO_SNDBUF to decrease");
158.12 + before = sc.getOption(SO_RCVBUF);
158.13 + after = sc.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
158.14 + if (after < before)
158.15 + throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
158.16 sc.setOption(SO_REUSEADDR, true);
158.17 checkOption(sc, SO_REUSEADDR, true);
158.18 sc.setOption(SO_REUSEADDR, false);
159.1 --- a/test/java/nio/file/FileStore/Basic.java Thu Oct 07 15:12:19 2010 -0700
159.2 +++ b/test/java/nio/file/FileStore/Basic.java Tue Oct 12 12:51:48 2010 -0700
159.3 @@ -22,7 +22,7 @@
159.4 */
159.5
159.6 /* @test
159.7 - * @bug 4313887 6873621
159.8 + * @bug 4313887 6873621 6979526
159.9 * @summary Unit test for java.nio.file.FileStore
159.10 * @library ..
159.11 */
160.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
160.2 +++ b/test/java/nio/file/Files/MaxDepth.java Tue Oct 12 12:51:48 2010 -0700
160.3 @@ -0,0 +1,67 @@
160.4 +/*
160.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
160.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
160.7 + *
160.8 + * This code is free software; you can redistribute it and/or modify it
160.9 + * under the terms of the GNU General Public License version 2 only, as
160.10 + * published by the Free Software Foundation.
160.11 + *
160.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
160.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
160.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
160.15 + * version 2 for more details (a copy is included in the LICENSE file that
160.16 + * accompanied this code).
160.17 + *
160.18 + * You should have received a copy of the GNU General Public License version
160.19 + * 2 along with this work; if not, write to the Free Software Foundation,
160.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
160.21 + *
160.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
160.23 + * or visit www.oracle.com if you need additional information or have any
160.24 + * questions.
160.25 + */
160.26 +
160.27 +import java.nio.file.*;
160.28 +import java.nio.file.attribute.*;
160.29 +import java.io.IOException;
160.30 +import java.util.*;
160.31 +
160.32 +/**
160.33 + * Unit test for Files.walkFileTree to test maxDepth parameter
160.34 + */
160.35 +
160.36 +public class MaxDepth {
160.37 + public static void main(String[] args) throws Exception {
160.38 + final Path top = Paths.get(args[0]);
160.39 +
160.40 + for (int i=0; i<5; i++) {
160.41 + Set<FileVisitOption> opts = Collections.emptySet();
160.42 + final int maxDepth = i;
160.43 + Files.walkFileTree(top, opts, maxDepth, new SimpleFileVisitor<Path>() {
160.44 + // compute depth based on relative path to top directory
160.45 + private int depth(Path file) {
160.46 + Path rp = file.relativize(top);
160.47 + return (rp == null) ? 0 : rp.getNameCount();
160.48 + }
160.49 +
160.50 + @Override
160.51 + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
160.52 + int d = depth(dir);
160.53 + if (d == maxDepth)
160.54 + throw new RuntimeException("Should not open directories at maxDepth");
160.55 + if (d > maxDepth)
160.56 + throw new RuntimeException("Too deep");
160.57 + return FileVisitResult.CONTINUE;
160.58 + }
160.59 +
160.60 + @Override
160.61 + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
160.62 + int d = depth(file);
160.63 + if (d > maxDepth)
160.64 + throw new RuntimeException("Too deep");
160.65 + return FileVisitResult.CONTINUE;
160.66 + }
160.67 + });
160.68 + }
160.69 + }
160.70 +}
161.1 --- a/test/java/nio/file/Files/Misc.java Thu Oct 07 15:12:19 2010 -0700
161.2 +++ b/test/java/nio/file/Files/Misc.java Tue Oct 12 12:51:48 2010 -0700
161.3 @@ -30,6 +30,7 @@
161.4
161.5 import java.nio.file.*;
161.6 import java.nio.file.attribute.Attributes;
161.7 +import java.nio.file.attribute.BasicFileAttributes;
161.8 import java.io.IOException;
161.9 import java.util.*;
161.10
161.11 @@ -117,25 +118,25 @@
161.12
161.13 SimpleFileVisitor<Path> visitor = new SimpleFileVisitor<Path>() { };
161.14 boolean ranTheGauntlet = false;
161.15 - try { visitor.preVisitDirectory(null);
161.16 + BasicFileAttributes attrs = Attributes.readBasicFileAttributes(Paths.get("."));
161.17 +
161.18 + try { visitor.preVisitDirectory(null, attrs);
161.19 } catch (NullPointerException x0) {
161.20 - try { visitor.preVisitDirectoryFailed(null, new IOException());
161.21 + try { visitor.preVisitDirectory(dir, null);
161.22 } catch (NullPointerException x1) {
161.23 - try { visitor.preVisitDirectoryFailed(dir, null);
161.24 + try { visitor.visitFile(null, attrs);
161.25 } catch (NullPointerException x2) {
161.26 - try { visitor.visitFile(null, Attributes.readBasicFileAttributes(Paths.get(".")));
161.27 + try { visitor.visitFile(dir, null);
161.28 } catch (NullPointerException x3) {
161.29 - try { visitor.visitFile(dir, null);
161.30 + try { visitor.visitFileFailed(null, new IOException());
161.31 } catch (NullPointerException x4) {
161.32 - try { visitor.visitFileFailed(null, new IOException());
161.33 + try { visitor.visitFileFailed(dir, null);
161.34 } catch (NullPointerException x5) {
161.35 - try { visitor.visitFileFailed(dir, null);
161.36 + try { visitor.postVisitDirectory(null, new IOException());
161.37 } catch (NullPointerException x6) {
161.38 - try { visitor.postVisitDirectory(null, new IOException());
161.39 - } catch (NullPointerException x7) {
161.40 // if we get here then all visit* methods threw NPE as expected
161.41 ranTheGauntlet = true;
161.42 - }}}}}}}}
161.43 + }}}}}}}
161.44 if (!ranTheGauntlet)
161.45 throw new RuntimeException("A visit method did not throw NPE");
161.46 }
162.1 --- a/test/java/nio/file/Files/PrintFileTree.java Thu Oct 07 15:12:19 2010 -0700
162.2 +++ b/test/java/nio/file/Files/PrintFileTree.java Tue Oct 12 12:51:48 2010 -0700
162.3 @@ -56,29 +56,34 @@
162.4
162.5 final boolean reportCycles = printCycles;
162.6 Files.walkFileTree(dir, options, Integer.MAX_VALUE, new FileVisitor<FileRef>() {
162.7 - public FileVisitResult preVisitDirectory(FileRef dir) {
162.8 + @Override
162.9 + public FileVisitResult preVisitDirectory(FileRef dir, BasicFileAttributes attrs) {
162.10 System.out.println(dir);
162.11 return FileVisitResult.CONTINUE;
162.12 }
162.13 - public FileVisitResult preVisitDirectoryFailed(FileRef dir, IOException exc) {
162.14 - exc.printStackTrace();
162.15 - return FileVisitResult.CONTINUE;
162.16 - }
162.17 + @Override
162.18 public FileVisitResult visitFile(FileRef file, BasicFileAttributes attrs) {
162.19 if (!attrs.isDirectory() || reportCycles)
162.20 System.out.println(file);
162.21 return FileVisitResult.CONTINUE;
162.22 }
162.23 - public FileVisitResult postVisitDirectory(FileRef dir, IOException exc) {
162.24 - if (exc != null) {
162.25 - exc.printStackTrace();
162.26 - return FileVisitResult.TERMINATE;
162.27 - }
162.28 + @Override
162.29 + public FileVisitResult postVisitDirectory(FileRef dir, IOException exc)
162.30 + throws IOException
162.31 + {
162.32 + if (exc != null)
162.33 + throw exc;
162.34 return FileVisitResult.CONTINUE;
162.35 }
162.36 - public FileVisitResult visitFileFailed(FileRef file, IOException exc) {
162.37 - exc.printStackTrace();
162.38 - return FileVisitResult.TERMINATE;
162.39 + @Override
162.40 + public FileVisitResult visitFileFailed(FileRef file, IOException exc)
162.41 + throws IOException
162.42 + {
162.43 + if (reportCycles && (exc instanceof FileSystemLoopException)) {
162.44 + System.out.println(file);
162.45 + return FileVisitResult.CONTINUE;
162.46 + }
162.47 + throw exc;
162.48 }
162.49 });
162.50 }
163.1 --- a/test/java/nio/file/Files/SkipSiblings.java Thu Oct 07 15:12:19 2010 -0700
163.2 +++ b/test/java/nio/file/Files/SkipSiblings.java Tue Oct 12 12:51:48 2010 -0700
163.3 @@ -54,32 +54,28 @@
163.4 public static void main(String[] args) throws Exception {
163.5 Path dir = Paths.get(args[0]);
163.6
163.7 - Files.walkFileTree(dir, new FileVisitor<Path>() {
163.8 - public FileVisitResult preVisitDirectory(Path dir) {
163.9 + Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
163.10 + @Override
163.11 + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
163.12 check(dir);
163.13 if (skip(dir))
163.14 return FileVisitResult.SKIP_SIBLINGS;
163.15 return FileVisitResult.CONTINUE;
163.16 }
163.17 - public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
163.18 - throw new RuntimeException(exc);
163.19 - }
163.20 -
163.21 + @Override
163.22 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
163.23 check(file);
163.24 if (skip(file))
163.25 return FileVisitResult.SKIP_SIBLINGS;
163.26 return FileVisitResult.CONTINUE;
163.27 }
163.28 + @Override
163.29 public FileVisitResult postVisitDirectory(Path dir, IOException x) {
163.30 if (x != null)
163.31 throw new RuntimeException(x);
163.32 check(dir);
163.33 return FileVisitResult.CONTINUE;
163.34 }
163.35 - public FileVisitResult visitFileFailed(Path file, IOException x) {
163.36 - throw new RuntimeException(x);
163.37 - }
163.38 });
163.39 }
163.40 }
164.1 --- a/test/java/nio/file/Files/TerminateWalk.java Thu Oct 07 15:12:19 2010 -0700
164.2 +++ b/test/java/nio/file/Files/TerminateWalk.java Tue Oct 12 12:51:48 2010 -0700
164.3 @@ -49,22 +49,19 @@
164.4 public static void main(String[] args) throws Exception {
164.5 Path dir = Paths.get(args[0]);
164.6
164.7 - Files.walkFileTree(dir, new FileVisitor<Path>() {
164.8 - public FileVisitResult preVisitDirectory(Path dir) {
164.9 + Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
164.10 + @Override
164.11 + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
164.12 return maybeTerminate();
164.13 }
164.14 - public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
164.15 - return maybeTerminate();
164.16 - }
164.17 + @Override
164.18 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
164.19 return maybeTerminate();
164.20 }
164.21 + @Override
164.22 public FileVisitResult postVisitDirectory(Path dir, IOException x) {
164.23 return maybeTerminate();
164.24 }
164.25 - public FileVisitResult visitFileFailed(Path file, IOException x) {
164.26 - return maybeTerminate();
164.27 - }
164.28 });
164.29 }
164.30 }
165.1 --- a/test/java/nio/file/Files/WalkWithSecurity.java Thu Oct 07 15:12:19 2010 -0700
165.2 +++ b/test/java/nio/file/Files/WalkWithSecurity.java Tue Oct 12 12:51:48 2010 -0700
165.3 @@ -116,7 +116,7 @@
165.4 }
165.5
165.6 @Override
165.7 - public FileVisitResult preVisitDirectory(Path dir) {
165.8 + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
165.9 System.out.println(dir);
165.10 count++;
165.11 return FileVisitResult.CONTINUE;
166.1 --- a/test/java/nio/file/Files/walk_file_tree.sh Thu Oct 07 15:12:19 2010 -0700
166.2 +++ b/test/java/nio/file/Files/walk_file_tree.sh Tue Oct 12 12:51:48 2010 -0700
166.3 @@ -22,9 +22,9 @@
166.4 #
166.5
166.6 # @test
166.7 -# @bug 4313887
166.8 +# @bug 4313887 6907737
166.9 # @summary Unit test for walkFileTree method
166.10 -# @build CreateFileTree PrintFileTree SkipSiblings TerminateWalk
166.11 +# @build CreateFileTree PrintFileTree SkipSiblings TerminateWalk MaxDepth
166.12 # @run shell walk_file_tree.sh
166.13
166.14 # if TESTJAVA isn't set then we assume an interactive run.
166.15 @@ -84,6 +84,10 @@
166.16 $JAVA TerminateWalk "$ROOT"
166.17 if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
166.18
166.19 +# test maxDepth
166.20 +$JAVA MaxDepth "$ROOT"
166.21 +if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
166.22 +
166.23 # clean-up
166.24 rm -r "$ROOT"
166.25
167.1 --- a/test/java/nio/file/TestUtil.java Thu Oct 07 15:12:19 2010 -0700
167.2 +++ b/test/java/nio/file/TestUtil.java Tue Oct 12 12:51:48 2010 -0700
167.3 @@ -44,15 +44,10 @@
167.4 return createTemporaryDirectory(System.getProperty("java.io.tmpdir"));
167.5 }
167.6
167.7 - static void removeAll(Path dir) {
167.8 + static void removeAll(Path dir) throws IOException {
167.9 Files.walkFileTree(dir, new FileVisitor<Path>() {
167.10 @Override
167.11 - public FileVisitResult preVisitDirectory(Path dir) {
167.12 - return FileVisitResult.CONTINUE;
167.13 - }
167.14 - @Override
167.15 - public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
167.16 - System.err.format("Error occured accessing directory %s\n", dir, exc);
167.17 + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
167.18 return FileVisitResult.CONTINUE;
167.19 }
167.20 @Override
168.1 --- a/test/java/util/Collection/BiggernYours.java Thu Oct 07 15:12:19 2010 -0700
168.2 +++ b/test/java/util/Collection/BiggernYours.java Tue Oct 12 12:51:48 2010 -0700
168.3 @@ -174,6 +174,11 @@
168.4 public int size() {return randomize(super.size());}});
168.5
168.6 testCollections(
168.7 + new ConcurrentLinkedDeque(),
168.8 + new ConcurrentLinkedDeque() {
168.9 + public int size() {return randomize(super.size());}});
168.10 +
168.11 + testCollections(
168.12 new ConcurrentLinkedQueue(),
168.13 new ConcurrentLinkedQueue() {
168.14 public int size() {return randomize(super.size());}});
169.1 --- a/test/java/util/Collection/IteratorAtEnd.java Thu Oct 07 15:12:19 2010 -0700
169.2 +++ b/test/java/util/Collection/IteratorAtEnd.java Tue Oct 12 12:51:48 2010 -0700
169.3 @@ -48,6 +48,7 @@
169.4 testCollection(new PriorityQueue());
169.5 testCollection(new LinkedBlockingQueue());
169.6 testCollection(new ArrayBlockingQueue(100));
169.7 + testCollection(new ConcurrentLinkedDeque());
169.8 testCollection(new ConcurrentLinkedQueue());
169.9 testCollection(new LinkedTransferQueue());
169.10
170.1 --- a/test/java/util/Collection/MOAT.java Thu Oct 07 15:12:19 2010 -0700
170.2 +++ b/test/java/util/Collection/MOAT.java Tue Oct 12 12:51:48 2010 -0700
170.3 @@ -75,6 +75,7 @@
170.4 testCollection(new ArrayBlockingQueue<Integer>(20));
170.5 testCollection(new LinkedBlockingQueue<Integer>(20));
170.6 testCollection(new LinkedBlockingDeque<Integer>(20));
170.7 + testCollection(new ConcurrentLinkedDeque<Integer>());
170.8 testCollection(new ConcurrentLinkedQueue<Integer>());
170.9 testCollection(new LinkedTransferQueue<Integer>());
170.10 testCollection(new ConcurrentSkipListSet<Integer>());
170.11 @@ -431,8 +432,9 @@
170.12 q.poll();
170.13 equal(q.size(), 4);
170.14 checkFunctionalInvariants(q);
170.15 - if ((q instanceof LinkedBlockingQueue) ||
170.16 - (q instanceof LinkedBlockingDeque) ||
170.17 + if ((q instanceof LinkedBlockingQueue) ||
170.18 + (q instanceof LinkedBlockingDeque) ||
170.19 + (q instanceof ConcurrentLinkedDeque) ||
170.20 (q instanceof ConcurrentLinkedQueue)) {
170.21 testQueueIteratorRemove(q);
170.22 }
171.1 --- a/test/java/util/Collections/RacingCollections.java Thu Oct 07 15:12:19 2010 -0700
171.2 +++ b/test/java/util/Collections/RacingCollections.java Tue Oct 12 12:51:48 2010 -0700
171.3 @@ -235,6 +235,7 @@
171.4 new ArrayList<Queue<Integer>>(newConcurrentDeques());
171.5 list.add(new LinkedBlockingQueue<Integer>(10));
171.6 list.add(new LinkedTransferQueue<Integer>());
171.7 + list.add(new ConcurrentLinkedQueue<Integer>());
171.8 return list;
171.9 }
171.10
171.11 @@ -248,6 +249,7 @@
171.12 private static List<Deque<Integer>> newConcurrentDeques() {
171.13 List<Deque<Integer>> list = new ArrayList<Deque<Integer>>();
171.14 list.add(new LinkedBlockingDeque<Integer>(10));
171.15 + list.add(new ConcurrentLinkedDeque<Integer>());
171.16 return list;
171.17 }
171.18
172.1 --- a/test/java/util/Deque/ChorusLine.java Thu Oct 07 15:12:19 2010 -0700
172.2 +++ b/test/java/util/Deque/ChorusLine.java Tue Oct 12 12:51:48 2010 -0700
172.3 @@ -129,6 +129,7 @@
172.4 deqs.add(new ArrayDeque<Integer>());
172.5 deqs.add(new LinkedList<Integer>());
172.6 deqs.add(new LinkedBlockingDeque<Integer>());
172.7 + deqs.add(new ConcurrentLinkedDeque<Integer>());
172.8
172.9 equal(deqs);
172.10
173.1 --- a/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java Thu Oct 07 15:12:19 2010 -0700
173.2 +++ b/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java Tue Oct 12 12:51:48 2010 -0700
173.3 @@ -55,6 +55,7 @@
173.4
173.5 Collection<Queue<Integer>> concurrentQueues() {
173.6 List<Queue<Integer>> queues = new ArrayList<Queue<Integer>>();
173.7 + queues.add(new ConcurrentLinkedDeque<Integer>());
173.8 queues.add(new ConcurrentLinkedQueue<Integer>());
173.9 queues.add(new ArrayBlockingQueue<Integer>(items, false));
173.10 //queues.add(new ArrayBlockingQueue<Integer>(count, true));
173.11 @@ -105,7 +106,7 @@
173.12 final Queue<Integer> queue;
173.13 final CyclicBarrier barrier;
173.14 int items;
173.15 - Stage (Queue<Integer> q, CyclicBarrier b, int items) {
173.16 + Stage(Queue<Integer> q, CyclicBarrier b, int items) {
173.17 queue = q;
173.18 barrier = b;
173.19 this.items = items;
174.1 --- a/test/java/util/concurrent/ConcurrentQueues/GCRetention.java Thu Oct 07 15:12:19 2010 -0700
174.2 +++ b/test/java/util/concurrent/ConcurrentQueues/GCRetention.java Tue Oct 12 12:51:48 2010 -0700
174.3 @@ -40,6 +40,7 @@
174.4
174.5 import java.util.concurrent.ArrayBlockingQueue;
174.6 import java.util.concurrent.ConcurrentHashMap;
174.7 +import java.util.concurrent.ConcurrentLinkedDeque;
174.8 import java.util.concurrent.ConcurrentLinkedQueue;
174.9 import java.util.concurrent.LinkedBlockingDeque;
174.10 import java.util.concurrent.LinkedBlockingQueue;
174.11 @@ -62,6 +63,7 @@
174.12
174.13 Collection<Queue<Boolean>> queues() {
174.14 List<Queue<Boolean>> queues = new ArrayList<Queue<Boolean>>();
174.15 + queues.add(new ConcurrentLinkedDeque<Boolean>());
174.16 queues.add(new ConcurrentLinkedQueue<Boolean>());
174.17 queues.add(new ArrayBlockingQueue<Boolean>(count, false));
174.18 queues.add(new ArrayBlockingQueue<Boolean>(count, true));
175.1 --- a/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java Thu Oct 07 15:12:19 2010 -0700
175.2 +++ b/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java Tue Oct 12 12:51:48 2010 -0700
175.3 @@ -48,6 +48,7 @@
175.4 test(new LinkedBlockingQueue(20));
175.5 test(new LinkedBlockingDeque());
175.6 test(new LinkedBlockingDeque(20));
175.7 + test(new ConcurrentLinkedDeque());
175.8 test(new ConcurrentLinkedQueue());
175.9 test(new LinkedTransferQueue());
175.10 // Other concurrent queues (e.g. ArrayBlockingQueue) do not
176.1 --- a/test/java/util/concurrent/ConcurrentQueues/OfferRemoveLoops.java Thu Oct 07 15:12:19 2010 -0700
176.2 +++ b/test/java/util/concurrent/ConcurrentQueues/OfferRemoveLoops.java Tue Oct 12 12:51:48 2010 -0700
176.3 @@ -55,6 +55,7 @@
176.4 testQueue(new LinkedBlockingDeque());
176.5 testQueue(new ArrayBlockingQueue(10));
176.6 testQueue(new PriorityBlockingQueue(10));
176.7 + testQueue(new ConcurrentLinkedDeque());
176.8 testQueue(new ConcurrentLinkedQueue());
176.9 testQueue(new LinkedTransferQueue());
176.10 }
177.1 --- a/test/java/util/concurrent/ConcurrentQueues/RemovePollRace.java Thu Oct 07 15:12:19 2010 -0700
177.2 +++ b/test/java/util/concurrent/ConcurrentQueues/RemovePollRace.java Tue Oct 12 12:51:48 2010 -0700
177.3 @@ -41,6 +41,7 @@
177.4
177.5 import java.util.concurrent.ArrayBlockingQueue;
177.6 import java.util.concurrent.ConcurrentHashMap;
177.7 +import java.util.concurrent.ConcurrentLinkedDeque;
177.8 import java.util.concurrent.ConcurrentLinkedQueue;
177.9 import java.util.concurrent.CountDownLatch;
177.10 import java.util.concurrent.LinkedBlockingDeque;
177.11 @@ -62,6 +63,7 @@
177.12
177.13 Collection<Queue<Boolean>> concurrentQueues() {
177.14 List<Queue<Boolean>> queues = new ArrayList<Queue<Boolean>>();
177.15 + queues.add(new ConcurrentLinkedDeque<Boolean>());
177.16 queues.add(new ConcurrentLinkedQueue<Boolean>());
177.17 queues.add(new ArrayBlockingQueue<Boolean>(count, false));
177.18 queues.add(new ArrayBlockingQueue<Boolean>(count, true));
178.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
178.2 +++ b/test/javax/swing/JComboBox/6632953/bug6632953.java Tue Oct 12 12:51:48 2010 -0700
178.3 @@ -0,0 +1,44 @@
178.4 +/*
178.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
178.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
178.7 + *
178.8 + * This code is free software; you can redistribute it and/or modify it
178.9 + * under the terms of the GNU General Public License version 2 only, as
178.10 + * published by the Free Software Foundation.
178.11 + *
178.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
178.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
178.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
178.15 + * version 2 for more details (a copy is included in the LICENSE file that
178.16 + * accompanied this code).
178.17 + *
178.18 + * You should have received a copy of the GNU General Public License version
178.19 + * 2 along with this work; if not, write to the Free Software Foundation,
178.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
178.21 + *
178.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
178.23 + * or visit www.oracle.com if you need additional information or have any
178.24 + * questions.
178.25 + */
178.26 +
178.27 +/* @test
178.28 + * @bug 6632953
178.29 + * @summary MetalComboBoxUI.getBaseline(JComponent, int, int) throws IAE for valid width/height
178.30 + * @author Alexander Potochkin
178.31 + */
178.32 +
178.33 +import javax.swing.JComboBox;
178.34 +import javax.swing.plaf.metal.MetalComboBoxUI;
178.35 +
178.36 +public class bug6632953 {
178.37 +
178.38 + public static void main(String... args) throws Exception {
178.39 + MetalComboBoxUI ui = new MetalComboBoxUI();
178.40 + ui.installUI(new JComboBox());
178.41 + ui.getBaseline(new JComboBox(), 0, 0);
178.42 + ui.getBaseline(new JComboBox(), 1, 1);
178.43 + ui.getBaseline(new JComboBox(), 2, 2);
178.44 + ui.getBaseline(new JComboBox(), 3, 3);
178.45 + ui.getBaseline(new JComboBox(), 4, 4);
178.46 + }
178.47 +}
179.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
179.2 +++ b/test/javax/swing/JScrollBar/6542335/bug6542335.java Tue Oct 12 12:51:48 2010 -0700
179.3 @@ -0,0 +1,92 @@
179.4 +/*
179.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
179.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
179.7 + *
179.8 + * This code is free software; you can redistribute it and/or modify it
179.9 + * under the terms of the GNU General Public License version 2 only, as
179.10 + * published by the Free Software Foundation.
179.11 + *
179.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
179.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
179.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
179.15 + * version 2 for more details (a copy is included in the LICENSE file that
179.16 + * accompanied this code).
179.17 + *
179.18 + * You should have received a copy of the GNU General Public License version
179.19 + * 2 along with this work; if not, write to the Free Software Foundation,
179.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
179.21 + *
179.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
179.23 + * or visit www.oracle.com if you need additional information or have any
179.24 + * questions.
179.25 + */
179.26 +
179.27 +/* @test
179.28 + @bug 6542335
179.29 + @summary different behavior on knob of scroll bar between 1.4.2 and 5.0
179.30 + @author Alexander Potochkin
179.31 + @run main bug6542335
179.32 +*/
179.33 +
179.34 +import sun.awt.SunToolkit;
179.35 +
179.36 +import javax.swing.*;
179.37 +import javax.swing.plaf.basic.BasicScrollBarUI;
179.38 +import java.awt.*;
179.39 +import java.awt.event.InputEvent;
179.40 +
179.41 +public class bug6542335 {
179.42 + private static JScrollBar sb;
179.43 + private static MyScrollBarUI ui;
179.44 +
179.45 + public static void main(String[] args) throws Exception {
179.46 + Robot robot = new Robot();
179.47 + robot.setAutoDelay(10);
179.48 +
179.49 + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
179.50 +
179.51 + SwingUtilities.invokeAndWait(new Runnable() {
179.52 + public void run() {
179.53 + final JFrame frame = new JFrame("bug6542335");
179.54 + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
179.55 +
179.56 + sb = new JScrollBar(0, 0, 1, 0, 1);
179.57 +
179.58 + ui = new MyScrollBarUI();
179.59 + sb.setUI(ui);
179.60 +
179.61 + sb.setPreferredSize(new Dimension(200, 17));
179.62 + DefaultBoundedRangeModel rangeModel = new DefaultBoundedRangeModel();
179.63 + rangeModel.setMaximum(100);
179.64 + rangeModel.setMinimum(0);
179.65 + rangeModel.setExtent(50);
179.66 + rangeModel.setValue(50);
179.67 +
179.68 + sb.setModel(rangeModel);
179.69 + frame.add(sb);
179.70 +
179.71 + frame.setSize(200, 100);
179.72 + frame.setVisible(true);
179.73 + }
179.74 + });
179.75 +
179.76 + Rectangle thumbBounds = new Rectangle(ui.getThumbBounds());
179.77 +
179.78 + toolkit.realSync();
179.79 + Point l = sb.getLocationOnScreen();
179.80 + robot.mouseMove(l.x + (int) (0.75 * sb.getWidth()), l.y + sb.getHeight()/2);
179.81 + robot.mousePress(InputEvent.BUTTON1_MASK);
179.82 + robot.mouseRelease(InputEvent.BUTTON1_MASK);
179.83 + toolkit.realSync();
179.84 +
179.85 + if (!thumbBounds.equals(ui.getThumbBounds())) {
179.86 + throw new RuntimeException("Test failed");
179.87 + }
179.88 + }
179.89 +
179.90 + static class MyScrollBarUI extends BasicScrollBarUI {
179.91 + public Rectangle getThumbBounds() {
179.92 + return super.getThumbBounds();
179.93 + }
179.94 + }
179.95 +}
180.1 --- a/test/javax/swing/JTable/Test6888156.java Thu Oct 07 15:12:19 2010 -0700
180.2 +++ b/test/javax/swing/JTable/Test6888156.java Tue Oct 12 12:51:48 2010 -0700
180.3 @@ -1,5 +1,5 @@
180.4 /*
180.5 - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
180.6 + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
180.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
180.8 *
180.9 * This code is free software; you can redistribute it and/or modify it
180.10 @@ -71,14 +71,14 @@
180.11 table = new JTable(model);
180.12 }
180.13
180.14 - public void test(final LookAndFeel laf) throws Exception {
180.15 + public void test(final String laf) throws Exception {
180.16 SwingUtilities.invokeAndWait(new Runnable() {
180.17 @Override public void run() {
180.18 try {
180.19 + System.out.println(laf);
180.20 UIManager.setLookAndFeel(laf);
180.21 - } catch (UnsupportedLookAndFeelException e) {
180.22 - System.err.println(laf.getDescription() +
180.23 - " is unsupported; continuing");
180.24 + } catch (Exception e) {
180.25 + System.err.println(laf + " is unsupported; continuing");
180.26 return;
180.27 }
180.28 SwingUtilities.updateComponentTreeUI(table);
180.29 @@ -92,8 +92,10 @@
180.30
180.31 public static void main(String[] args) throws Exception {
180.32 Test6888156 t = new Test6888156();
180.33 - t.test(new javax.swing.plaf.nimbus.NimbusLookAndFeel());
180.34 - t.test(new com.sun.java.swing.plaf.gtk.GTKLookAndFeel());
180.35 + t.test("javax.swing.plaf.nimbus.NimbusLookAndFeel");
180.36 + t.test("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
180.37 + for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
180.38 + t.test(laf.getClassName());
180.39 + }
180.40 }
180.41 }
180.42 -
181.1 --- a/test/javax/swing/JTextArea/6940863/bug6940863.java Thu Oct 07 15:12:19 2010 -0700
181.2 +++ b/test/javax/swing/JTextArea/6940863/bug6940863.java Tue Oct 12 12:51:48 2010 -0700
181.3 @@ -56,6 +56,7 @@
181.4 public static void main(String[] args) throws Exception {
181.5 if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) {
181.6 System.out.println("The test is suitable only for Windows OS. Skipped");
181.7 + return;
181.8 }
181.9
181.10 UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
182.1 --- a/test/sun/net/www/http/ChunkedInputStream/ChunkedCharEncoding.sh Thu Oct 07 15:12:19 2010 -0700
182.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
182.3 @@ -1,62 +0,0 @@
182.4 -#
182.5 -# Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
182.6 -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
182.7 -#
182.8 -# This code is free software; you can redistribute it and/or modify it
182.9 -# under the terms of the GNU General Public License version 2 only, as
182.10 -# published by the Free Software Foundation.
182.11 -#
182.12 -# This code is distributed in the hope that it will be useful, but WITHOUT
182.13 -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
182.14 -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
182.15 -# version 2 for more details (a copy is included in the LICENSE file that
182.16 -# accompanied this code).
182.17 -#
182.18 -# You should have received a copy of the GNU General Public License version
182.19 -# 2 along with this work; if not, write to the Free Software Foundation,
182.20 -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
182.21 -#
182.22 -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
182.23 -# or visit www.oracle.com if you need additional information or have any
182.24 -# questions.
182.25 -#
182.26 -
182.27 - # @test
182.28 - # @bug 6502503
182.29 - # @run shell/timeout=140 ChunkedCharEncoding.sh
182.30 - # @summary Http URL connection don't work when default encoding is Cp037: HTTP Transfer-Encoding:chunked
182.31 -
182.32 -OS=`uname -s`
182.33 -case "$OS" in
182.34 - SunOS | Linux )
182.35 - PS=":"
182.36 - FS="/"
182.37 - ;;
182.38 - CYGWIN* )
182.39 - PS=";"
182.40 - FS="/"
182.41 - ;;
182.42 - Windows* )
182.43 - PS=";"
182.44 - FS="\\"
182.45 - ;;
182.46 - * )
182.47 - echo "Unrecognized system!"
182.48 - exit 1;
182.49 - ;;
182.50 -esac
182.51 -
182.52 -# compile
182.53 -${TESTJAVA}${FS}bin${FS}javac -d . ${TESTSRC}${FS}TestAvailable.java
182.54 -
182.55 -# run with CP037 encoding specified.
182.56 -${TESTJAVA}${FS}bin${FS}java -Dfile.encoding=Cp037 TestAvailable 2>&1
182.57 -
182.58 -result=$?
182.59 -if [ "$result" -ne "0" ]; then
182.60 - exit 1
182.61 -fi
182.62 -
182.63 -# no failures, exit.
182.64 -exit 0
182.65 -
183.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
183.2 +++ b/test/sun/net/www/http/HttpClient/StreamingRetry.java Tue Oct 12 12:51:48 2010 -0700
183.3 @@ -0,0 +1,89 @@
183.4 +/*
183.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
183.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
183.7 + *
183.8 + * This code is free software; you can redistribute it and/or modify it
183.9 + * under the terms of the GNU General Public License version 2 only, as
183.10 + * published by the Free Software Foundation.
183.11 + *
183.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
183.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
183.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
183.15 + * version 2 for more details (a copy is included in the LICENSE file that
183.16 + * accompanied this code).
183.17 + *
183.18 + * You should have received a copy of the GNU General Public License version
183.19 + * 2 along with this work; if not, write to the Free Software Foundation,
183.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
183.21 + *
183.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
183.23 + * or visit www.oracle.com if you need additional information or have any
183.24 + * questions.
183.25 + */
183.26 +
183.27 +/*
183.28 + * @test
183.29 + * @bug 6672144
183.30 + * @summary HttpURLConnection.getInputStream sends POST request after failed chunked send
183.31 + */
183.32 +
183.33 +import java.net.HttpURLConnection;
183.34 +import java.net.ServerSocket;
183.35 +import java.net.URL;
183.36 +import java.io.IOException;
183.37 +import java.io.InputStream;
183.38 +import java.io.OutputStream;
183.39 +
183.40 +public class StreamingRetry implements Runnable {
183.41 + static final int ACCEPT_TIMEOUT = 20 * 1000; // 20 seconds
183.42 + ServerSocket ss;
183.43 +
183.44 + public static void main(String[] args) throws IOException {
183.45 + (new StreamingRetry()).instanceMain();
183.46 + }
183.47 +
183.48 + void instanceMain() throws IOException {
183.49 + test();
183.50 + if (failed > 0) throw new RuntimeException("Some tests failed");
183.51 + }
183.52 +
183.53 + void test() throws IOException {
183.54 + ss = new ServerSocket(0);
183.55 + ss.setSoTimeout(ACCEPT_TIMEOUT);
183.56 + int port = ss.getLocalPort();
183.57 +
183.58 + (new Thread(this)).start();
183.59 +
183.60 + try {
183.61 + URL url = new URL("http://localhost:" + port + "/");
183.62 + HttpURLConnection uc = (HttpURLConnection) url.openConnection();
183.63 + uc.setDoOutput(true);
183.64 + uc.setChunkedStreamingMode(4096);
183.65 + OutputStream os = uc.getOutputStream();
183.66 + os.write("Hello there".getBytes());
183.67 +
183.68 + InputStream is = uc.getInputStream();
183.69 + is.close();
183.70 + } catch (IOException expected) {
183.71 + //expected.printStackTrace();
183.72 + } finally {
183.73 + ss.close();
183.74 + }
183.75 + }
183.76 +
183.77 + // Server
183.78 + public void run() {
183.79 + try {
183.80 + (ss.accept()).close();
183.81 + (ss.accept()).close();
183.82 + ss.close();
183.83 + fail("The server shouldn't accept a second connection");
183.84 + } catch (IOException e) {
183.85 + //OK, the clien will close the server socket if successfull
183.86 + }
183.87 + }
183.88 +
183.89 + volatile int failed = 0;
183.90 + void fail() {failed++; Thread.dumpStack();}
183.91 + void fail(String msg) {System.err.println(msg); fail();}
183.92 +}
184.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
184.2 +++ b/test/sun/net/www/protocol/http/6550798/TestCache.java Tue Oct 12 12:51:48 2010 -0700
184.3 @@ -0,0 +1,133 @@
184.4 +/*
184.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
184.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
184.7 + *
184.8 + * This code is free software; you can redistribute it and/or modify it
184.9 + * under the terms of the GNU General Public License version 2 only, as
184.10 + * published by the Free Software Foundation.
184.11 + *
184.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
184.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
184.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
184.15 + * version 2 for more details (a copy is included in the LICENSE file that
184.16 + * accompanied this code).
184.17 + *
184.18 + * You should have received a copy of the GNU General Public License version
184.19 + * 2 along with this work; if not, write to the Free Software Foundation,
184.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
184.21 + *
184.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
184.23 + * or visit www.oracle.com if you need additional information or have any
184.24 + * questions.
184.25 + */
184.26 +
184.27 +import java.net.*;
184.28 +import java.io.*;
184.29 +import java.io.IOException;
184.30 +import java.io.InputStream;
184.31 +import java.io.OutputStream;
184.32 +import java.io.FileInputStream;
184.33 +import java.io.FileOutputStream;
184.34 +import java.io.BufferedInputStream;
184.35 +import java.io.ByteArrayInputStream;
184.36 +import java.io.PrintStream;
184.37 +import java.io.InputStream;
184.38 +import java.io.File;
184.39 +import java.net.CacheRequest;
184.40 +import java.net.CacheResponse;
184.41 +import java.net.ResponseCache;
184.42 +import java.net.URI;
184.43 +import java.net.URL;
184.44 +import java.net.URLConnection;
184.45 +import java.util.ArrayList;
184.46 +import java.util.HashMap;
184.47 +import java.util.Map;
184.48 +import java.util.List;
184.49 +import java.util.Iterator;
184.50 +import java.util.StringTokenizer;
184.51 +import java.util.jar.JarInputStream;
184.52 +import java.util.jar.JarFile;
184.53 +import java.security.AccessController;
184.54 +import java.security.PrivilegedAction;
184.55 +import java.security.PrivilegedExceptionAction;
184.56 +import java.security.PrivilegedActionException;
184.57 +import java.security.Principal;
184.58 +import java.security.cert.Certificate;
184.59 +import javax.net.ssl.SSLPeerUnverifiedException;
184.60 +
184.61 +public class TestCache extends java.net.ResponseCache {
184.62 + private boolean inCacheHandler = false;
184.63 + private boolean _downloading = false;
184.64 +
184.65 + public static volatile boolean fail = false;
184.66 +
184.67 + public static void reset() {
184.68 + // Set system wide cache handler
184.69 + System.out.println("install deploy cache handler");
184.70 + ResponseCache.setDefault(new TestCache());
184.71 + }
184.72 +
184.73 + public synchronized CacheResponse get(final URI uri, String rqstMethod,
184.74 + Map requestHeaders) throws IOException {
184.75 + System.out.println("get: " + uri);
184.76 + Thread.currentThread().dumpStack();
184.77 + return null;
184.78 + }
184.79 +
184.80 + public synchronized CacheRequest put(URI uri, URLConnection conn)
184.81 + throws IOException {
184.82 + System.out.println("put: " + uri);
184.83 + Thread.currentThread().dumpStack();
184.84 + URL url = uri.toURL();
184.85 + return new DeployCacheRequest(url, conn);
184.86 +
184.87 + }
184.88 +}
184.89 +
184.90 +class DeployByteArrayOutputStream extends java.io.ByteArrayOutputStream {
184.91 +
184.92 + private URL _url;
184.93 + private URLConnection _conn;
184.94 +
184.95 + DeployByteArrayOutputStream(URL url, URLConnection conn) {
184.96 + _url = url;
184.97 + _conn = conn;
184.98 + }
184.99 +
184.100 +
184.101 + public void close() throws IOException {
184.102 +
184.103 + System.out.println("contentLength: " + _conn.getContentLength());
184.104 + System.out.println("byte array size: " + size());
184.105 + if ( _conn.getContentLength() == size()) {
184.106 + System.out.println("correct content length");
184.107 + } else {
184.108 + System.out.println("wrong content length");
184.109 + System.out.println("TEST FAILED");
184.110 + TestCache.fail = true;
184.111 + }
184.112 + super.close();
184.113 + }
184.114 +}
184.115 +
184.116 +class DeployCacheRequest extends java.net.CacheRequest {
184.117 +
184.118 + private URL _url;
184.119 + private URLConnection _conn;
184.120 + private boolean _downloading = false;
184.121 +
184.122 + DeployCacheRequest(URL url, URLConnection conn) {
184.123 + System.out.println("DeployCacheRequest ctor for: " + url);
184.124 + _url = url;
184.125 + _conn = conn;
184.126 + }
184.127 +
184.128 + public void abort() {
184.129 + System.out.println("abort called");
184.130 + }
184.131 +
184.132 + public OutputStream getBody() throws IOException {
184.133 + System.out.println("getBody called");
184.134 + return new DeployByteArrayOutputStream(_url, _conn);
184.135 + }
184.136 +}
185.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
185.2 +++ b/test/sun/net/www/protocol/http/6550798/test.java Tue Oct 12 12:51:48 2010 -0700
185.3 @@ -0,0 +1,90 @@
185.4 +/*
185.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
185.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
185.7 + *
185.8 + * This code is free software; you can redistribute it and/or modify it
185.9 + * under the terms of the GNU General Public License version 2 only, as
185.10 + * published by the Free Software Foundation.
185.11 + *
185.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
185.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
185.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
185.15 + * version 2 for more details (a copy is included in the LICENSE file that
185.16 + * accompanied this code).
185.17 + *
185.18 + * You should have received a copy of the GNU General Public License version
185.19 + * 2 along with this work; if not, write to the Free Software Foundation,
185.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
185.21 + *
185.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
185.23 + * or visit www.oracle.com if you need additional information or have any
185.24 + * questions.
185.25 + */
185.26 +
185.27 +/**
185.28 + * @test
185.29 + * @bug 6550798
185.30 + * @summary Using InputStream.skip with ResponseCache will cause partial data to be cached
185.31 + * @run main/othervm test
185.32 + */
185.33 +
185.34 +import java.net.*;
185.35 +import com.sun.net.httpserver.*;
185.36 +import java.io.*;
185.37 +
185.38 +public class test {
185.39 +
185.40 + final static int LEN = 16 * 1024;
185.41 +
185.42 + public static void main(String[] args) throws Exception {
185.43 +
185.44 + TestCache.reset();
185.45 + HttpServer s = HttpServer.create (new InetSocketAddress(0), 10);
185.46 + s.createContext ("/", new HttpHandler () {
185.47 + public void handle (HttpExchange e) {
185.48 + try {
185.49 + byte[] buf = new byte [LEN];
185.50 + OutputStream o = e.getResponseBody();
185.51 + e.sendResponseHeaders(200, LEN);
185.52 + o.write (buf);
185.53 + e.close();
185.54 + } catch (IOException ex) {
185.55 + ex.printStackTrace();
185.56 + TestCache.fail = true;
185.57 + }
185.58 + }
185.59 + });
185.60 + s.start();
185.61 +
185.62 + System.out.println("http request with cache hander");
185.63 + URL u = new URL("http://127.0.0.1:"+s.getAddress().getPort()+"/f");
185.64 + URLConnection conn = u.openConnection();
185.65 +
185.66 + InputStream is = null;
185.67 + try {
185.68 + // this calls into TestCache.get
185.69 + byte[] buf = new byte[8192];
185.70 + is = new BufferedInputStream(conn.getInputStream());
185.71 +
185.72 + is.skip(1000);
185.73 +
185.74 + while (is.read(buf) != -1) {
185.75 + }
185.76 + } finally {
185.77 + if (is != null) {
185.78 + // this calls into TestCache.put
185.79 + // TestCache.put will check if the resource
185.80 + // should be cached
185.81 + is.close();
185.82 + }
185.83 + s.stop(0);
185.84 + }
185.85 +
185.86 + if (TestCache.fail) {
185.87 + System.out.println ("TEST FAILED");
185.88 + throw new RuntimeException ();
185.89 + } else {
185.90 + System.out.println ("TEST OK");
185.91 + }
185.92 + }
185.93 +}
186.1 --- a/test/sun/security/tools/jarsigner/crl.sh Thu Oct 07 15:12:19 2010 -0700
186.2 +++ b/test/sun/security/tools/jarsigner/crl.sh Tue Oct 12 12:51:48 2010 -0700
186.3 @@ -63,7 +63,15 @@
186.4 $KT -alias b -dname CN=b -keyalg rsa -genkey -validity 300
186.5 $KT -alias b -gencrl -id 5:1 -id 6:2 -file crl3
186.6
186.7 -$TESTJAVA${FS}bin${FS}jrunscript -e 'println(new File("crl1").toURI())' > uri
186.8 +cat > ToURI.java <<EOF
186.9 +class ToURI {
186.10 + public static void main(String[] args) throws Exception {
186.11 + System.out.println(new java.io.File("crl1").toURI());
186.12 + }
186.13 +}
186.14 +EOF
186.15 +$TESTJAVA${FS}bin${FS}javac ToURI.java
186.16 +$TESTJAVA${FS}bin${FS}java ToURI > uri
186.17 $KT -alias c -dname CN=c -keyalg rsa -genkey -validity 300 \
186.18 -ext crl=uri:`cat uri`
186.19