1.1 --- a/.hgtags Tue Oct 12 13:34:59 2010 -0400
1.2 +++ b/.hgtags Mon Oct 18 11:25:28 2010 -0400
1.3 @@ -88,3 +88,4 @@
1.4 fb63a2688db807a73e2a3de7d9bab298f1bff0e8 jdk7-b111
1.5 b53f226b1d91473ac54184afa827be07b87e0319 jdk7-b112
1.6 61d3b9fbb26bdef56cfa41b9af5bc312a22cbeb8 jdk7-b113
1.7 +e250cef36ea05e627e7e6f7d75e5e19f529e2ba3 jdk7-b114
2.1 --- a/make/Makefile Tue Oct 12 13:34:59 2010 -0400
2.2 +++ b/make/Makefile Mon Oct 18 11:25:28 2010 -0400
2.3 @@ -75,7 +75,6 @@
2.4 import_fastdebug -- copy in the fastdebug components \n\
2.5 import_debug -- copy in the debug components \n\
2.6 modules -- build the jdk and jre module images (experimental) \n\
2.7 -sccs_get -- make sure all SCCS files are up-to-date (need SCCS) \n\
2.8 create_links -- create softlinks in Solaris 32bit build to 64bit dirs \n\
2.9 "
2.10
2.11 @@ -278,21 +277,6 @@
2.12 $(OUTPUTDIR) $(TEMPDIR):
2.13 $(MKDIR) -p $@
2.14
2.15 -# cleanup everything. If the workspace is not being built by the control
2.16 -# workspace, and if it is a Teamware workspace, then see if there are
2.17 -# any files which are not under SCCS control.
2.18 -clean clobber::
2.19 -ifndef EXTERNALSANITYCONTROL
2.20 - @if [ -d $(TOPDIR)/Codemgr_wsdata ]; then \
2.21 - $(ECHO) '\nPerforming workspace scan for remnant files.\n' \
2.22 - ' Any files listed below are not under SCCS control in the workspace\n' \
2.23 - ' and you should review them and possibly remove them manually:' ; \
2.24 - $(FIND) $(TOPDIR)/make $(TOPDIR)/src -type f | \
2.25 - $(SED) 's+SCCS/[ps]\.++' | $(SORT) | $(UNIQ) -c | $(NAWK) '$$1<2 {print $$2;}' ; \
2.26 - $(ECHO) 'End of workspace scan.' ; \
2.27 - fi
2.28 -endif
2.29 -
2.30 # this should be the last rule in this file:
2.31 all::
2.32 @if [ -r $(WARNING_FILE) ]; then \
2.33 @@ -341,16 +325,70 @@
2.34 include $(BUILDDIR)/common/internal/BinaryPlugs.gmk
2.35
2.36 #
2.37 -# Get top level sccs_get rule
2.38 +# Test rule
2.39 #
2.40 -include $(BUILDDIR)/common/Rules-SCCS.gmk
2.41
2.42 +.NOTPARALLEL: test_run
2.43 +
2.44 +test:
2.45 + $(MAKE) test_run
2.46 +
2.47 +test_run: test_clean test_start test_summary
2.48 +
2.49 +test_start:
2.50 + @$(ECHO) "Tests started at `$(DATE)`"
2.51 +
2.52 +test_clean:
2.53 + $(RM) $(OUTPUTDIR)/test_failures.txt $(OUTPUTDIR)/test_log.txt
2.54 +
2.55 +test_summary: $(OUTPUTDIR)/test_failures.txt
2.56 + @$(ECHO) "#################################################"
2.57 + @$(ECHO) "Tests completed at `$(DATE)`"
2.58 + @( $(EGREP) '^TEST STATS:' $(OUTPUTDIR)/test_log.txt \
2.59 + || $(ECHO) "No TEST STATS seen in log" )
2.60 + @$(ECHO) "For complete details see: $(OUTPUTDIR)/test_log.txt"
2.61 + @$(ECHO) "#################################################"
2.62 + @if [ -s $< ] ; then \
2.63 + $(ECHO) "ERROR: Test failure count: `$(CAT) $< | $(WC) -l`"; \
2.64 + $(CAT) $<; \
2.65 + exit 1; \
2.66 + else \
2.67 + $(ECHO) "Success! No failures detected"; \
2.68 + fi
2.69 +
2.70 +# Get failure list from log
2.71 +$(OUTPUTDIR)/test_failures.txt: $(OUTPUTDIR)/test_log.txt
2.72 + @$(RM) $@
2.73 + @( $(EGREP) '^FAILED:' $< || $(ECHO) "" ) | $(NAWK) 'length>0' > $@
2.74 +
2.75 +# Get log file of all tests run
2.76 +JDK_TO_TEST := $(shell \
2.77 + if [ -d "$(ABS_OUTPUTDIR)/j2sdk-image" ] ; then \
2.78 + $(ECHO) "$(ABS_OUTPUTDIR)/j2sdk-image"; \
2.79 + elif [ -d "$(ABS_OUTPUTDIR)/bin" ] ; then \
2.80 + $(ECHO) "$(ABS_OUTPUTDIR)"; \
2.81 + elif [ "$(PRODUCT_HOME)" != "" -a -d "$(PRODUCT_HOME)/bin" ] ; then \
2.82 + $(ECHO) "$(PRODUCT_HOME)"; \
2.83 + fi \
2.84 +)
2.85 +
2.86 +TEST_TARGETS=jdk_all
2.87 +$(OUTPUTDIR)/test_log.txt:
2.88 + $(RM) $@
2.89 + ( $(CD) ../test && \
2.90 + $(MAKE) NO_STOPPING=- PRODUCT_HOME=$(JDK_TO_TEST) $(TEST_TARGETS) \
2.91 + ) | tee $@
2.92 +
2.93 +#
2.94 # JPRT rules
2.95 +#
2.96 +
2.97 include jprt.gmk
2.98
2.99 #
2.100 # Phonies to avoid accidents.
2.101 #
2.102 .PHONY: all build clean clobber optimized debug fastdebug create_links \
2.103 - import import_product import_fastdebug import_debug
2.104 + import import_product import_fastdebug import_debug \
2.105 + test test_run test_start test_clean test_summary
2.106
3.1 --- a/make/common/Cscope.gmk Tue Oct 12 13:34:59 2010 -0400
3.2 +++ b/make/common/Cscope.gmk Mon Oct 18 11:25:28 2010 -0400
3.3 @@ -76,7 +76,7 @@
3.4 # What files should we include? A simple rule might be just those files under
3.5 # SCM control, however this would miss files we create like the opcodes and
3.6 # CClassHeaders. The following attempts to find everything that is *useful*.
3.7 -# (.del files are created by sccsrm, demo directories contain many .java files
3.8 +# (demo directories contain many .java files
3.9 # that probably aren't useful for development, and the pkgarchive may contain
3.10 # duplicates of files within the source hierarchy). The ordering of the .raw
3.11 # file is an attempt to make cscope display the most relevant files first.
4.1 --- a/make/common/Defs.gmk Tue Oct 12 13:34:59 2010 -0400
4.2 +++ b/make/common/Defs.gmk Mon Oct 18 11:25:28 2010 -0400
4.3 @@ -334,7 +334,7 @@
4.4 DOCSDIRSUFFIX =
4.5
4.6 # The MESSAGE, WARNING and ERROR files are used to store sanityck and
4.7 -# SCCS check messages, warnings and errors.
4.8 +# warnings and errors.
4.9 ifndef ERROR_FILE
4.10 ERROR_FILE = $(OUTPUTDIR)/sanityCheckErrors.txt
4.11 endif
4.12 @@ -634,38 +634,6 @@
4.13
4.14 VERSION_DEFINES = -DRELEASE='"$(RELEASE)"'
4.15
4.16 -# Note: As a rule, GNU Make rules should not appear in any of the
4.17 -# Defs*.gmk files. These were added for Kestrel-Solaris and do address
4.18 -# a TeamWare bug. They should be moved elsewhere for Merlin.
4.19 -#
4.20 -# Override gnumake built-in rules which do sccs get operations badly.
4.21 -# (They put the checked out code in the current directory, not in the
4.22 -# directory of the original file.)
4.23 -# Since this is a symptom of a teamware failure, complain and die on the spot.
4.24 -
4.25 -# This message immediately goes to stdout and the build terminates.
4.26 -define SCCS-trouble
4.27 -$(error \
4.28 -"ERROR: File $@ referenced while building in $(CURRENT_DIRECTORY) \
4.29 - is out of date with respect to its SCCS file $<. \
4.30 - This can happen from an unresolved Teamware conflict, a file movement, or \
4.31 - a failure in which SCCS files are updated but the 'sccs get' was not done. \
4.32 - You should double check for other out of date files in your workspace. \
4.33 - Or run: cd $(TOPDIR) && $(MAKE) sccs_get")
4.34 -endef
4.35 -
4.36 -%:: s.%
4.37 - @$(SCCS-trouble)
4.38 -%:: SCCS/s.%
4.39 - @$(SCCS-trouble)
4.40 - @$(ECHO) " is out of date with respect to its SCCS file." >> $(WARNING_FILE)
4.41 - @$(ECHO) " This file may be from an unresolved Teamware conflict." >> $(WARNING_FILE)
4.42 - @$(ECHO) " This is also a symptom of a Teamware bringover/putback failure" >> $(WARNING_FILE)
4.43 - @$(ECHO) " in which SCCS files are updated but not checked out." >> $(WARNING_FILE)
4.44 - @$(ECHO) " Check for other out of date files in your workspace." >> $(WARNING_FILE)
4.45 - @$(ECHO) "" >> $(WARNING_FILE)
4.46 - @#exit 666
4.47 -
4.48 ifdef INSANE
4.49 export INSANE
4.50 endif
5.1 --- a/make/common/Rules-SCCS.gmk Tue Oct 12 13:34:59 2010 -0400
5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
5.3 @@ -1,70 +0,0 @@
5.4 -#
5.5 -# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
5.6 -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5.7 -#
5.8 -# This code is free software; you can redistribute it and/or modify it
5.9 -# under the terms of the GNU General Public License version 2 only, as
5.10 -# published by the Free Software Foundation. Oracle designates this
5.11 -# particular file as subject to the "Classpath" exception as provided
5.12 -# by Oracle in the LICENSE file that accompanied this code.
5.13 -#
5.14 -# This code is distributed in the hope that it will be useful, but WITHOUT
5.15 -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5.16 -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5.17 -# version 2 for more details (a copy is included in the LICENSE file that
5.18 -# accompanied this code).
5.19 -#
5.20 -# You should have received a copy of the GNU General Public License version
5.21 -# 2 along with this work; if not, write to the Free Software Foundation,
5.22 -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
5.23 -#
5.24 -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
5.25 -# or visit www.oracle.com if you need additional information or have any
5.26 -# questions.
5.27 -#
5.28 -
5.29 -#
5.30 -# Only get these rules if SCCS is available
5.31 -#
5.32 -
5.33 -ifdef SCCS
5.34 -
5.35 -# SCCS command to extract out latest source
5.36 -SCCS_GET=$(SCCS) get -s
5.37 -
5.38 -#
5.39 -# Make sure all files in workspace are fresh
5.40 -#
5.41 -TEMP_ALL_FILES=$(JDK_TOPDIR)/temp_filelist
5.42 -$(TEMP_ALL_FILES): $(JDK_TOPDIR)/Codemgr_wsdata/nametable
5.43 - $(prep-target)
5.44 - @$(CUT) -d' ' -f1 $< \
5.45 - | $(GREP) -v '^VERSION' \
5.46 - | $(GREP) -v '^deleted_files' \
5.47 - | $(GREP) -v '^Codemgr_wsdata' > $@
5.48 -
5.49 -sccs_get: $(TEMP_ALL_FILES)
5.50 - @$(PRINTF) "Workspace has %d files\n" `$(CAT) $< | $(WC) -l`
5.51 - @count=0; \
5.52 - for i in `$(CAT) $<` ; do \
5.53 - f=$(JDK_TOPDIR)/$$i; \
5.54 - count=`$(EXPR) $$count '+' 1`; \
5.55 - if [ `$(EXPR) $$count '%' 100` = 0 ] ; then \
5.56 - $(PRINTF) "\rChecked $$count files"; \
5.57 - fi; \
5.58 - if [ ! -f $$f ] ; then \
5.59 - $(PRINTF) "\r$(SCCS_GET) $$f\n"; \
5.60 - (cd `$(DIRNAME) $$f` && $(SCCS_GET) `$(BASENAME) $$f`); \
5.61 - elif /usr/bin/test $$f -ot `$(DIRNAME) $$f`/SCCS/s.`$(BASENAME) $$f` ; then \
5.62 - $(PRINTF) "\r$(SCCS_GET) $$f\n"; \
5.63 - (cd `$(DIRNAME) $$f` && $(SCCS_GET) `$(BASENAME) $$f`); \
5.64 - fi; \
5.65 - done; \
5.66 - $(PRINTF) "\rChecked $$count files\n"
5.67 -
5.68 -#
5.69 -# Phonies to avoid accidents.
5.70 -#
5.71 -.PHONY: sccs_get
5.72 -
5.73 -endif
6.1 --- a/make/common/shared/Defs-utils.gmk Tue Oct 12 13:34:59 2010 -0400
6.2 +++ b/make/common/shared/Defs-utils.gmk Mon Oct 18 11:25:28 2010 -0400
6.3 @@ -33,7 +33,7 @@
6.4 # UTILS_COMMAND_PATH
6.5 # /usr/bin/
6.6 # UTILS_USR_BIN_PATH
6.7 -# /usr/ccs/bin/ (sccs, m4, lex, yacc, as, ar, strip, mcs)
6.8 +# /usr/ccs/bin/ (m4, lex, yacc, as, ar, strip, mcs)
6.9 # UTILS_CCS_BIN_PATH
6.10 # Dev Tools: zip, unzip, etc that we may have special versions of
6.11 # UTILS_DEVTOOL_PATH
6.12 @@ -117,7 +117,6 @@
6.13 RMDIR = $(UTILS_COMMAND_PATH)rmdir
6.14 RPM = $(UTILS_COMMAND_PATH)rpm
6.15 RPMBUILD = $(UTILS_COMMAND_PATH)rpmbuild
6.16 -SCCS = $(UTILS_CCS_BIN_PATH)sccs
6.17 SED = $(UTILS_COMMAND_PATH)sed
6.18 SH = $(UTILS_COMMAND_PATH)sh
6.19 SHOWREV = $(UTILS_USR_BIN_PATH)showrev
6.20 @@ -183,7 +182,7 @@
6.21 NAWK = $(USRBIN_PATH)gawk
6.22 # Intrinsic unix command, with backslash-escaped character interpretation
6.23 ECHO = /bin/echo -e
6.24 - # These are really in UTILS_USR_BIN_PATH on Linux (only sccs is not)
6.25 + # These are really in UTILS_USR_BIN_PATH on Linux
6.26 AR = $(UTILS_USR_BIN_PATH)ar
6.27 AS = $(UTILS_USR_BIN_PATH)as
6.28 LD = $(UTILS_USR_BIN_PATH)ld
7.1 --- a/make/common/shared/Defs.gmk Tue Oct 12 13:34:59 2010 -0400
7.2 +++ b/make/common/shared/Defs.gmk Mon Oct 18 11:25:28 2010 -0400
7.3 @@ -219,7 +219,7 @@
7.4 PRODUCT_NAME = Java(TM)
7.5 PRODUCT_SUFFIX = SE Runtime Environment
7.6 JDK_RC_PLATFORM_NAME = Platform SE
7.7 - COMPANY_NAME = Oracle
7.8 + COMPANY_NAME = Oracle Corporation
7.9 endif
7.10
7.11 RUNTIME_NAME = $(PRODUCT_NAME) $(PRODUCT_SUFFIX)
8.1 --- a/make/java/java/FILES_java.gmk Tue Oct 12 13:34:59 2010 -0400
8.2 +++ b/make/java/java/FILES_java.gmk Mon Oct 18 11:25:28 2010 -0400
8.3 @@ -284,6 +284,7 @@
8.4 java/util/concurrent/CancellationException.java \
8.5 java/util/concurrent/CompletionService.java \
8.6 java/util/concurrent/ConcurrentHashMap.java \
8.7 + java/util/concurrent/ConcurrentLinkedDeque.java \
8.8 java/util/concurrent/ConcurrentLinkedQueue.java \
8.9 java/util/concurrent/ConcurrentMap.java \
8.10 java/util/concurrent/ConcurrentNavigableMap.java \
9.1 --- a/make/jprt.properties Tue Oct 12 13:34:59 2010 -0400
9.2 +++ b/make/jprt.properties Mon Oct 18 11:25:28 2010 -0400
9.3 @@ -25,43 +25,265 @@
9.4
9.5 # Properties for jprt
9.6
9.7 -# Use whatever release that the submitted job requests
9.8 +# At submit time, the release supplied will be in jprt.submit.release
9.9 +# and will be one of the official release names defined in jprt.
9.10 +# jprt supports property value expansion using ${property.name} syntax.
9.11 +
9.12 +# This tells jprt what default release we want to build
9.13 jprt.tools.default.release=${jprt.submit.release}
9.14
9.15 # The different build flavors we want, we override here so we just get these 2
9.16 jprt.build.flavors=product,fastdebug
9.17
9.18 -# Standard test target for everybody
9.19 -jprt.test.targets=*-*-*-jvm98
9.20 +# Define the Windows we want (temporary)
9.21 +jprt.my.windows.i586.jdk7b107=windows_i586_5.0
9.22 +jprt.my.windows.i586.jdk7temp=windows_i586_5.0
9.23 +jprt.my.windows.i586.jdk7=windows_i586_5.1
9.24 +jprt.my.windows.i586=${jprt.my.windows.i586.${jprt.tools.default.release}}
9.25
9.26 -# Test targets in test/Makefile (some longer running tests only test c2)
9.27 -jprt.make.rule.test.targets= \
9.28 - *-product-*-jdk_beans1, \
9.29 - *-product-*-jdk_beans2, \
9.30 - *-product-*-jdk_beans3, \
9.31 - *-product-*-jdk_io, \
9.32 - *-product-*-jdk_lang, \
9.33 - *-product-*-jdk_management1, \
9.34 - *-product-*-jdk_management2, \
9.35 - *-product-*-jdk_math, \
9.36 - *-product-*-jdk_misc, \
9.37 - *-product-*-jdk_net, \
9.38 - *-product-*-jdk_nio1, \
9.39 - *-product-*-jdk_nio2, \
9.40 - *-product-*-jdk_nio3, \
9.41 - *-product-*-jdk_security1, \
9.42 - *-product-*-jdk_security2, \
9.43 - *-product-*-jdk_security3, \
9.44 - *-product-*-jdk_text, \
9.45 - *-product-*-jdk_tools1, \
9.46 - *-product-*-jdk_tools2, \
9.47 - *-product-*-jdk_util
9.48 +# Standard list of jprt build targets for this source tree
9.49 +jprt.build.targets= \
9.50 + solaris_sparc_5.10-{product|fastdebug}, \
9.51 + solaris_sparcv9_5.10-{product|fastdebug}, \
9.52 + solaris_i586_5.10-{product|fastdebug}, \
9.53 + solaris_x64_5.10-{product|fastdebug}, \
9.54 + linux_i586_2.6-{product|fastdebug}, \
9.55 + linux_x64_2.6-{product|fastdebug}, \
9.56 + ${jprt.my.windows.i586}-{product|fastdebug}, \
9.57 + windows_x64_5.2-{product|fastdebug}
9.58
9.59 -# Some of these are crashing Xvfb or windows manager, need dedicated DISPLAY per test batch
9.60 -jprt2.make.rule.test.targets= \
9.61 - *-product-*-jdk_awt, \
9.62 - *-product-*-jdk_rmi, \
9.63 - *-product-*-jdk_swing, \
9.64 +# Standard vm test target
9.65 +jprt.test.targets= \
9.66 + solaris_sparc_5.10-product-c1-jvm98, \
9.67 + solaris_sparcv9_5.10-product-c2-jvm98, \
9.68 + solaris_i586_5.10-product-c1-jvm98, \
9.69 + solaris_x64_5.10-product-c2-jvm98, \
9.70 + linux_i586_2.6-product-{c1|c2}-jvm98, \
9.71 + linux_x64_2.6-product-c2-jvm98, \
9.72 + ${jprt.my.windows.i586}-product-c1-jvm98, \
9.73 + windows_x64_5.2-product-c2-jvm98
9.74 +
9.75 +# User can select the test set with jprt submit "-testset name" option
9.76 +jprt.my.test.set=${jprt.test.set}
9.77 +
9.78 +# Default jdk test targets in test/Makefile (no fastdebug & limited c2)
9.79 +jprt.make.rule.default.test.targets= \
9.80 + \
9.81 + solaris_sparc_5.10-product-c1-jdk_beans1, \
9.82 + solaris_sparcv9_5.10-product-c2-jdk_beans1, \
9.83 + solaris_i586_5.10-product-c1-jdk_beans1, \
9.84 + solaris_x64_5.10-product-c2-jdk_beans1, \
9.85 + linux_i586_2.6-product-{c1|c2}-jdk_beans1, \
9.86 + linux_x64_2.6-product-c2-jdk_beans1, \
9.87 + ${jprt.my.windows.i586}-product-c1-jdk_beans1, \
9.88 + windows_x64_5.2-product-c2-jdk_beans1, \
9.89 + \
9.90 + solaris_sparc_5.10-product-c1-jdk_io, \
9.91 + solaris_sparcv9_5.10-product-c2-jdk_io, \
9.92 + solaris_i586_5.10-product-c1-jdk_io, \
9.93 + solaris_x64_5.10-product-c2-jdk_io, \
9.94 + linux_i586_2.6-product-{c1|c2}-jdk_io, \
9.95 + linux_x64_2.6-product-c2-jdk_io, \
9.96 + ${jprt.my.windows.i586}-product-c1-jdk_io, \
9.97 + windows_x64_5.2-product-c2-jdk_io, \
9.98 + \
9.99 + solaris_sparc_5.10-product-c1-jdk_lang, \
9.100 + solaris_sparcv9_5.10-product-c2-jdk_lang, \
9.101 + solaris_i586_5.10-product-c1-jdk_lang, \
9.102 + solaris_x64_5.10-product-c2-jdk_lang, \
9.103 + linux_i586_2.6-product-{c1|c2}-jdk_lang, \
9.104 + linux_x64_2.6-product-c2-jdk_lang, \
9.105 + ${jprt.my.windows.i586}-product-c1-jdk_lang, \
9.106 + windows_x64_5.2-product-c2-jdk_lang, \
9.107 + \
9.108 + solaris_sparc_5.10-product-c1-jdk_math, \
9.109 + solaris_sparcv9_5.10-product-c2-jdk_math, \
9.110 + solaris_i586_5.10-product-c1-jdk_math, \
9.111 + solaris_x64_5.10-product-c2-jdk_math, \
9.112 + linux_i586_2.6-product-{c1|c2}-jdk_math, \
9.113 + linux_x64_2.6-product-c2-jdk_math, \
9.114 + ${jprt.my.windows.i586}-product-c1-jdk_math, \
9.115 + windows_x64_5.2-product-c2-jdk_math, \
9.116 + \
9.117 + solaris_sparc_5.10-product-c1-jdk_misc, \
9.118 + solaris_sparcv9_5.10-product-c2-jdk_misc, \
9.119 + solaris_i586_5.10-product-c1-jdk_misc, \
9.120 + solaris_x64_5.10-product-c2-jdk_misc, \
9.121 + linux_i586_2.6-product-{c1|c2}-jdk_misc, \
9.122 + linux_x64_2.6-product-c2-jdk_misc, \
9.123 + ${jprt.my.windows.i586}-product-c1-jdk_misc, \
9.124 + windows_x64_5.2-product-c2-jdk_misc, \
9.125 + \
9.126 + solaris_sparc_5.10-product-c1-jdk_net, \
9.127 + solaris_sparcv9_5.10-product-c2-jdk_net, \
9.128 + solaris_i586_5.10-product-c1-jdk_net, \
9.129 + solaris_x64_5.10-product-c2-jdk_net, \
9.130 + linux_i586_2.6-product-{c1|c2}-jdk_net, \
9.131 + linux_x64_2.6-product-c2-jdk_net, \
9.132 + ${jprt.my.windows.i586}-product-c1-jdk_net, \
9.133 + windows_x64_5.2-product-c2-jdk_net, \
9.134 + \
9.135 + solaris_sparc_5.10-product-c1-jdk_nio1, \
9.136 + solaris_sparcv9_5.10-product-c2-jdk_nio1, \
9.137 + solaris_i586_5.10-product-c1-jdk_nio1, \
9.138 + solaris_x64_5.10-product-c2-jdk_nio1, \
9.139 + linux_i586_2.6-product-{c1|c2}-jdk_nio1, \
9.140 + linux_x64_2.6-product-c2-jdk_nio1, \
9.141 + ${jprt.my.windows.i586}-product-c1-jdk_nio1, \
9.142 + windows_x64_5.2-product-c2-jdk_nio1, \
9.143 + \
9.144 + solaris_sparc_5.10-product-c1-jdk_nio2, \
9.145 + solaris_sparcv9_5.10-product-c2-jdk_nio2, \
9.146 + solaris_i586_5.10-product-c1-jdk_nio2, \
9.147 + solaris_x64_5.10-product-c2-jdk_nio2, \
9.148 + linux_i586_2.6-product-{c1|c2}-jdk_nio2, \
9.149 + linux_x64_2.6-product-c2-jdk_nio2, \
9.150 + ${jprt.my.windows.i586}-product-c1-jdk_nio2, \
9.151 + windows_x64_5.2-product-c2-jdk_nio2, \
9.152 + \
9.153 + solaris_sparc_5.10-product-c1-jdk_nio3, \
9.154 + solaris_sparcv9_5.10-product-c2-jdk_nio3, \
9.155 + solaris_i586_5.10-product-c1-jdk_nio3, \
9.156 + solaris_x64_5.10-product-c2-jdk_nio3, \
9.157 + linux_i586_2.6-product-{c1|c2}-jdk_nio3, \
9.158 + linux_x64_2.6-product-c2-jdk_nio3, \
9.159 + ${jprt.my.windows.i586}-product-c1-jdk_nio3, \
9.160 + windows_x64_5.2-product-c2-jdk_nio3, \
9.161 + \
9.162 + solaris_sparc_5.10-product-c1-jdk_security1, \
9.163 + solaris_sparcv9_5.10-product-c2-jdk_security1, \
9.164 + solaris_i586_5.10-product-c1-jdk_security1, \
9.165 + solaris_x64_5.10-product-c2-jdk_security1, \
9.166 + linux_i586_2.6-product-{c1|c2}-jdk_security1, \
9.167 + linux_x64_2.6-product-c2-jdk_security1, \
9.168 + ${jprt.my.windows.i586}-product-c1-jdk_security1, \
9.169 + windows_x64_5.2-product-c2-jdk_security1, \
9.170 + \
9.171 + solaris_sparc_5.10-product-c1-jdk_text, \
9.172 + solaris_sparcv9_5.10-product-c2-jdk_text, \
9.173 + solaris_i586_5.10-product-c1-jdk_text, \
9.174 + solaris_x64_5.10-product-c2-jdk_text, \
9.175 + linux_i586_2.6-product-{c1|c2}-jdk_text, \
9.176 + linux_x64_2.6-product-c2-jdk_text, \
9.177 + ${jprt.my.windows.i586}-product-c1-jdk_text, \
9.178 + windows_x64_5.2-product-c2-jdk_text, \
9.179 + \
9.180 + solaris_sparc_5.10-product-c1-jdk_tools1, \
9.181 + solaris_sparcv9_5.10-product-c2-jdk_tools1, \
9.182 + solaris_i586_5.10-product-c1-jdk_tools1, \
9.183 + solaris_x64_5.10-product-c2-jdk_tools1, \
9.184 + linux_i586_2.6-product-{c1|c2}-jdk_tools1, \
9.185 + linux_x64_2.6-product-c2-jdk_tools1, \
9.186 + ${jprt.my.windows.i586}-product-c1-jdk_tools1, \
9.187 + windows_x64_5.2-product-c2-jdk_tools1, \
9.188 + \
9.189 + solaris_sparc_5.10-product-c1-jdk_util, \
9.190 + solaris_sparcv9_5.10-product-c2-jdk_util, \
9.191 + solaris_i586_5.10-product-c1-jdk_util, \
9.192 + solaris_x64_5.10-product-c2-jdk_util, \
9.193 + linux_i586_2.6-product-{c1|c2}-jdk_util, \
9.194 + linux_x64_2.6-product-c2-jdk_util, \
9.195 + ${jprt.my.windows.i586}-product-c1-jdk_util, \
9.196 + windows_x64_5.2-product-c2-jdk_util
9.197 +
9.198 +# All jdk test targets in test/Makefile (still no fastdebug & limited c2)
9.199 +jprt.make.rule.all.test.targets= \
9.200 + \
9.201 + ${jprt.make.rule.default.test.targets}, \
9.202 + \
9.203 + solaris_sparc_5.10-product-c1-jdk_awt, \
9.204 + solaris_sparcv9_5.10-product-c2-jdk_awt, \
9.205 + solaris_i586_5.10-product-c1-jdk_awt, \
9.206 + solaris_x64_5.10-product-c2-jdk_awt, \
9.207 + linux_i586_2.6-product-{c1|c2}-jdk_awt, \
9.208 + linux_x64_2.6-product-c2-jdk_awt, \
9.209 + ${jprt.my.windows.i586}-product-c1-jdk_awt, \
9.210 + windows_x64_5.2-product-c2-jdk_awt, \
9.211 + \
9.212 + solaris_sparc_5.10-product-c1-jdk_beans2, \
9.213 + solaris_sparcv9_5.10-product-c2-jdk_beans2, \
9.214 + solaris_i586_5.10-product-c1-jdk_beans2, \
9.215 + solaris_x64_5.10-product-c2-jdk_beans2, \
9.216 + linux_i586_2.6-product-{c1|c2}-jdk_beans2, \
9.217 + linux_x64_2.6-product-c2-jdk_beans2, \
9.218 + ${jprt.my.windows.i586}-product-c1-jdk_beans2, \
9.219 + windows_x64_5.2-product-c2-jdk_beans2, \
9.220 + \
9.221 + solaris_sparc_5.10-product-c1-jdk_beans3, \
9.222 + solaris_sparcv9_5.10-product-c2-jdk_beans3, \
9.223 + solaris_i586_5.10-product-c1-jdk_beans3, \
9.224 + solaris_x64_5.10-product-c2-jdk_beans3, \
9.225 + linux_i586_2.6-product-{c1|c2}-jdk_beans3, \
9.226 + linux_x64_2.6-product-c2-jdk_beans3, \
9.227 + ${jprt.my.windows.i586}-product-c1-jdk_beans3, \
9.228 + windows_x64_5.2-product-c2-jdk_beans3, \
9.229 + \
9.230 + solaris_sparc_5.10-product-c1-jdk_management1, \
9.231 + solaris_sparcv9_5.10-product-c2-jdk_management1, \
9.232 + solaris_i586_5.10-product-c1-jdk_management1, \
9.233 + solaris_x64_5.10-product-c2-jdk_management1, \
9.234 + linux_i586_2.6-product-{c1|c2}-jdk_management1, \
9.235 + linux_x64_2.6-product-c2-jdk_management1, \
9.236 + ${jprt.my.windows.i586}-product-c1-jdk_management1, \
9.237 + windows_x64_5.2-product-c2-jdk_management1, \
9.238 + \
9.239 + solaris_sparc_5.10-product-c1-jdk_management2, \
9.240 + solaris_sparcv9_5.10-product-c2-jdk_management2, \
9.241 + solaris_i586_5.10-product-c1-jdk_management2, \
9.242 + solaris_x64_5.10-product-c2-jdk_management2, \
9.243 + linux_i586_2.6-product-{c1|c2}-jdk_management2, \
9.244 + linux_x64_2.6-product-c2-jdk_management2, \
9.245 + ${jprt.my.windows.i586}-product-c1-jdk_management2, \
9.246 + windows_x64_5.2-product-c2-jdk_management2, \
9.247 + \
9.248 + solaris_sparc_5.10-product-c1-jdk_rmi, \
9.249 + solaris_sparcv9_5.10-product-c2-jdk_rmi, \
9.250 + solaris_i586_5.10-product-c1-jdk_rmi, \
9.251 + solaris_x64_5.10-product-c2-jdk_rmi, \
9.252 + linux_i586_2.6-product-{c1|c2}-jdk_rmi, \
9.253 + linux_x64_2.6-product-c2-jdk_rmi, \
9.254 + ${jprt.my.windows.i586}-product-c1-jdk_rmi, \
9.255 + windows_x64_5.2-product-c2-jdk_rmi, \
9.256 + \
9.257 + solaris_sparc_5.10-product-c1-jdk_security2, \
9.258 + solaris_sparcv9_5.10-product-c2-jdk_security2, \
9.259 + solaris_i586_5.10-product-c1-jdk_security2, \
9.260 + solaris_x64_5.10-product-c2-jdk_security2, \
9.261 + linux_i586_2.6-product-{c1|c2}-jdk_security2, \
9.262 + linux_x64_2.6-product-c2-jdk_security2, \
9.263 + ${jprt.my.windows.i586}-product-c1-jdk_security2, \
9.264 + windows_x64_5.2-product-c2-jdk_security2, \
9.265 + \
9.266 + solaris_sparc_5.10-product-c1-jdk_security3, \
9.267 + solaris_sparcv9_5.10-product-c2-jdk_security3, \
9.268 + solaris_i586_5.10-product-c1-jdk_security3, \
9.269 + solaris_x64_5.10-product-c2-jdk_security3, \
9.270 + linux_i586_2.6-product-{c1|c2}-jdk_security3, \
9.271 + linux_x64_2.6-product-c2-jdk_security3, \
9.272 + ${jprt.my.windows.i586}-product-c1-jdk_security3, \
9.273 + windows_x64_5.2-product-c2-jdk_security3, \
9.274 + \
9.275 + solaris_sparc_5.10-product-c1-jdk_swing, \
9.276 + solaris_sparcv9_5.10-product-c2-jdk_swing, \
9.277 + solaris_i586_5.10-product-c1-jdk_swing, \
9.278 + solaris_x64_5.10-product-c2-jdk_swing, \
9.279 + linux_i586_2.6-product-{c1|c2}-jdk_swing, \
9.280 + linux_x64_2.6-product-c2-jdk_swing, \
9.281 + ${jprt.my.windows.i586}-product-c1-jdk_swing, \
9.282 + windows_x64_5.2-product-c2-jdk_swing, \
9.283 + \
9.284 + solaris_sparc_5.10-product-c1-jdk_tools2, \
9.285 + solaris_sparcv9_5.10-product-c2-jdk_tools2, \
9.286 + solaris_i586_5.10-product-c1-jdk_tools2, \
9.287 + solaris_x64_5.10-product-c2-jdk_tools2, \
9.288 + linux_i586_2.6-product-{c1|c2}-jdk_tools2, \
9.289 + linux_x64_2.6-product-c2-jdk_tools2, \
9.290 + ${jprt.my.windows.i586}-product-c1-jdk_tools2, \
9.291 + windows_x64_5.2-product-c2-jdk_tools2
9.292 +
9.293 +# Select list to use (allow for testset to be empty too)
9.294 +jprt.make.rule..test.targets=${jprt.make.rule.default.test.targets}
9.295 +jprt.make.rule.test.targets=${jprt.make.rule.${jprt.my.test.set}.test.targets}
9.296
9.297 # Directories to be excluded from the source bundles
9.298 jprt.bundle.exclude.src.dirs=build dist webrev
10.1 --- a/make/mkdemo/Makefile Tue Oct 12 13:34:59 2010 -0400
10.2 +++ b/make/mkdemo/Makefile Mon Oct 18 11:25:28 2010 -0400
10.3 @@ -31,7 +31,7 @@
10.4 PRODUCT = demos
10.5 include $(BUILDDIR)/common/Defs.gmk
10.6
10.7 -SUBDIRS = jni
10.8 +SUBDIRS = jni nio
10.9 SUBDIRS_desktop = applets jfc
10.10 SUBDIRS_management = management
10.11 SUBDIRS_misc = scripting
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/make/mkdemo/nio/Makefile Mon Oct 18 11:25:28 2010 -0400
11.3 @@ -0,0 +1,39 @@
11.4 +#
11.5 +# Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
11.6 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
11.7 +#
11.8 +# This code is free software; you can redistribute it and/or modify it
11.9 +# under the terms of the GNU General Public License version 2 only, as
11.10 +# published by the Free Software Foundation. Oracle designates this
11.11 +# particular file as subject to the "Classpath" exception as provided
11.12 +# by Oracle in the LICENSE file that accompanied this code.
11.13 +#
11.14 +# This code is distributed in the hope that it will be useful, but WITHOUT
11.15 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11.16 +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11.17 +# version 2 for more details (a copy is included in the LICENSE file that
11.18 +# accompanied this code).
11.19 +#
11.20 +# You should have received a copy of the GNU General Public License version
11.21 +# 2 along with this work; if not, write to the Free Software Foundation,
11.22 +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
11.23 +#
11.24 +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
11.25 +# or visit www.oracle.com if you need additional information or have any
11.26 +# questions.
11.27 +#
11.28 +
11.29 +#
11.30 +# Makefile for building the jfc demos
11.31 +#
11.32 +
11.33 +BUILDDIR = ../..
11.34 +PRODUCT = demos
11.35 +include $(BUILDDIR)/common/Defs.gmk
11.36 +
11.37 +SUBDIRS = zipfs
11.38 +include $(BUILDDIR)/common/Subdirs.gmk
11.39 +
11.40 +all build clean clobber::
11.41 + $(SUBDIRS-loop)
11.42 +
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/make/mkdemo/nio/zipfs/Makefile Mon Oct 18 11:25:28 2010 -0400
12.3 @@ -0,0 +1,44 @@
12.4 +#
12.5 +# Copyright (c) 1997, 2002, Oracle and/or its affiliates. All rights reserved.
12.6 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
12.7 +#
12.8 +# This code is free software; you can redistribute it and/or modify it
12.9 +# under the terms of the GNU General Public License version 2 only, as
12.10 +# published by the Free Software Foundation. Oracle designates this
12.11 +# particular file as subject to the "Classpath" exception as provided
12.12 +# by Oracle in the LICENSE file that accompanied this code.
12.13 +#
12.14 +# This code is distributed in the hope that it will be useful, but WITHOUT
12.15 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12.16 +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12.17 +# version 2 for more details (a copy is included in the LICENSE file that
12.18 +# accompanied this code).
12.19 +#
12.20 +# You should have received a copy of the GNU General Public License version
12.21 +# 2 along with this work; if not, write to the Free Software Foundation,
12.22 +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
12.23 +#
12.24 +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
12.25 +# or visit www.oracle.com if you need additional information or have any
12.26 +# questions.
12.27 +#
12.28 +
12.29 +#
12.30 +# Makefile to build the ZipFileSystem demo.
12.31 +#
12.32 +
12.33 +BUILDDIR = ../../..
12.34 +PRODUCT = demo/zipfs
12.35 +DEMONAME = zipfs
12.36 +include $(BUILDDIR)/common/Defs.gmk
12.37 +
12.38 +DEMO_ROOT = $(SHARE_SRC)/demo/nio/$(DEMONAME)
12.39 +DEMO_TOPFILES = ./README.txt
12.40 +DEMO_SRCDIR = $(DEMO_ROOT)
12.41 +DEMO_DESTDIR = $(DEMODIR)/nio/$(DEMONAME)
12.42 +
12.43 +#
12.44 +# Demo jar building rules.
12.45 +#
12.46 +include $(BUILDDIR)/common/Demo.gmk
12.47 +
13.1 --- a/make/sun/cmm/lcms/Makefile Tue Oct 12 13:34:59 2010 -0400
13.2 +++ b/make/sun/cmm/lcms/Makefile Mon Oct 18 11:25:28 2010 -0400
13.3 @@ -80,7 +80,12 @@
13.4 vpath %.c $(SHARE_SRC)/native/sun/java2d
13.5
13.6 ifeq ($(PLATFORM), windows)
13.7 -OTHER_CFLAGS += -DCMS_IS_WINDOWS_ -Dsqrtf=sqrt
13.8 +OTHER_CFLAGS += -DCMS_IS_WINDOWS_
13.9 +
13.10 +ifeq ($(COMPILER_VERSION), VS2003)
13.11 +OTHER_CFLAGS += -Dsqrtf=sqrt
13.12 +endif
13.13 +
13.14 OTHER_LDLIBS = $(OBJDIR)/../../../sun.awt/awt/$(OBJDIRNAME)/awt.lib
13.15 OTHER_INCLUDES += -I$(SHARE_SRC)/native/sun/java2d \
13.16 -I$(SHARE_SRC)/native/sun/awt/debug
14.1 --- a/src/share/classes/com/sun/rowset/CachedRowSetImpl.java Tue Oct 12 13:34:59 2010 -0400
14.2 +++ b/src/share/classes/com/sun/rowset/CachedRowSetImpl.java Mon Oct 18 11:25:28 2010 -0400
14.3 @@ -525,7 +525,7 @@
14.4
14.5 iMatchColumns = new Vector(10);
14.6 for(int i = 0; i < 10 ; i++) {
14.7 - iMatchColumns.add(i,new Integer(-1));
14.8 + iMatchColumns.add(i,Integer.valueOf(-1));
14.9 }
14.10
14.11 strMatchColumns = new Vector(10);
14.12 @@ -889,7 +889,12 @@
14.13 success = false;
14.14 } else {
14.15 tWriter = (TransactionalWriter)rowSetWriter;
14.16 - ((CachedRowSetWriter)tWriter).commit(this, updateOnInsert);
14.17 + if (tWriter instanceof CachedRowSetWriter) {
14.18 + ((CachedRowSetWriter)tWriter).commit(this, updateOnInsert);
14.19 + } else {
14.20 + tWriter.commit();
14.21 + }
14.22 +
14.23 success = true;
14.24 }
14.25 }
14.26 @@ -1294,7 +1299,7 @@
14.27 tMap = new TreeMap();
14.28
14.29 for (int i = 0; i<numRows; i++) {
14.30 - tMap.put(new Integer(i), rvh.get(i));
14.31 + tMap.put(Integer.valueOf(i), rvh.get(i));
14.32 }
14.33
14.34 return (tMap.values());
14.35 @@ -1806,7 +1811,7 @@
14.36 return (byte)0;
14.37 }
14.38 try {
14.39 - return ((new Byte(value.toString())).byteValue());
14.40 + return ((Byte.valueOf(value.toString())).byteValue());
14.41 } catch (NumberFormatException ex) {
14.42 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.bytefail").toString(),
14.43 new Object[] {value.toString().trim(), columnIndex}));
14.44 @@ -1850,7 +1855,7 @@
14.45 }
14.46
14.47 try {
14.48 - return ((new Short(value.toString().trim())).shortValue());
14.49 + return ((Short.valueOf(value.toString().trim())).shortValue());
14.50 } catch (NumberFormatException ex) {
14.51 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.shortfail").toString(),
14.52 new Object[] {value.toString().trim(), columnIndex}));
14.53 @@ -1893,7 +1898,7 @@
14.54 }
14.55
14.56 try {
14.57 - return ((new Integer(value.toString().trim())).intValue());
14.58 + return ((Integer.valueOf(value.toString().trim())).intValue());
14.59 } catch (NumberFormatException ex) {
14.60 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.intfail").toString(),
14.61 new Object[] {value.toString().trim(), columnIndex}));
14.62 @@ -1936,7 +1941,7 @@
14.63 return (long)0;
14.64 }
14.65 try {
14.66 - return ((new Long(value.toString().trim())).longValue());
14.67 + return ((Long.valueOf(value.toString().trim())).longValue());
14.68 } catch (NumberFormatException ex) {
14.69 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.longfail").toString(),
14.70 new Object[] {value.toString().trim(), columnIndex}));
14.71 @@ -4014,18 +4019,18 @@
14.72 try {
14.73 switch (trgType) {
14.74 case java.sql.Types.BIT:
14.75 - Integer i = new Integer(srcObj.toString().trim());
14.76 - return i.equals(new Integer((int)0)) ?
14.77 - new Boolean(false) :
14.78 - new Boolean(true);
14.79 + Integer i = Integer.valueOf(srcObj.toString().trim());
14.80 + return i.equals(Integer.valueOf((int)0)) ?
14.81 + Boolean.valueOf(false) :
14.82 + Boolean.valueOf(true);
14.83 case java.sql.Types.TINYINT:
14.84 - return new Byte(srcObj.toString().trim());
14.85 + return Byte.valueOf(srcObj.toString().trim());
14.86 case java.sql.Types.SMALLINT:
14.87 - return new Short(srcObj.toString().trim());
14.88 + return Short.valueOf(srcObj.toString().trim());
14.89 case java.sql.Types.INTEGER:
14.90 - return new Integer(srcObj.toString().trim());
14.91 + return Integer.valueOf(srcObj.toString().trim());
14.92 case java.sql.Types.BIGINT:
14.93 - return new Long(srcObj.toString().trim());
14.94 + return Long.valueOf(srcObj.toString().trim());
14.95 case java.sql.Types.NUMERIC:
14.96 case java.sql.Types.DECIMAL:
14.97 return new BigDecimal(srcObj.toString().trim());
14.98 @@ -4037,7 +4042,7 @@
14.99 case java.sql.Types.CHAR:
14.100 case java.sql.Types.VARCHAR:
14.101 case java.sql.Types.LONGVARCHAR:
14.102 - return new String(srcObj.toString());
14.103 + return srcObj.toString();
14.104 default:
14.105 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()+ trgType);
14.106 }
14.107 @@ -4134,7 +4139,7 @@
14.108 case java.sql.Types.CHAR:
14.109 case java.sql.Types.VARCHAR:
14.110 case java.sql.Types.LONGVARCHAR:
14.111 - return new String(srcObj.toString());
14.112 + return srcObj.toString();
14.113 default:
14.114 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());
14.115 }
14.116 @@ -4181,12 +4186,12 @@
14.117 try {
14.118 switch (trgType) {
14.119 case java.sql.Types.BIT:
14.120 - Integer i = new Integer(srcObj.toString().trim());
14.121 - return i.equals(new Integer((int)0)) ?
14.122 - new Boolean(false) :
14.123 - new Boolean(true);
14.124 + Integer i = Integer.valueOf(srcObj.toString().trim());
14.125 + return i.equals(Integer.valueOf((int)0)) ?
14.126 + Boolean.valueOf(false) :
14.127 + Boolean.valueOf(true);
14.128 case java.sql.Types.BOOLEAN:
14.129 - return new Boolean(srcObj.toString().trim());
14.130 + return Boolean.valueOf(srcObj.toString().trim());
14.131 default:
14.132 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()+ trgType);
14.133 }
14.134 @@ -4260,7 +4265,7 @@
14.135 checkIndex(columnIndex);
14.136 // make sure the cursor is on a valid row
14.137 checkCursor();
14.138 - Object obj = convertBoolean(new Boolean(x),
14.139 + Object obj = convertBoolean(Boolean.valueOf(x),
14.140 java.sql.Types.BIT,
14.141 RowSetMD.getColumnType(columnIndex));
14.142
14.143 @@ -4296,7 +4301,7 @@
14.144 // make sure the cursor is on a valid row
14.145 checkCursor();
14.146
14.147 - Object obj = convertNumeric(new Byte(x),
14.148 + Object obj = convertNumeric(Byte.valueOf(x),
14.149 java.sql.Types.TINYINT,
14.150 RowSetMD.getColumnType(columnIndex));
14.151
14.152 @@ -4332,7 +4337,7 @@
14.153 // make sure the cursor is on a valid row
14.154 checkCursor();
14.155
14.156 - Object obj = convertNumeric(new Short(x),
14.157 + Object obj = convertNumeric(Short.valueOf(x),
14.158 java.sql.Types.SMALLINT,
14.159 RowSetMD.getColumnType(columnIndex));
14.160
14.161 @@ -4367,7 +4372,7 @@
14.162 checkIndex(columnIndex);
14.163 // make sure the cursor is on a valid row
14.164 checkCursor();
14.165 - Object obj = convertNumeric(new Integer(x),
14.166 + Object obj = convertNumeric(Integer.valueOf(x),
14.167 java.sql.Types.INTEGER,
14.168 RowSetMD.getColumnType(columnIndex));
14.169
14.170 @@ -4403,7 +4408,7 @@
14.171 // make sure the cursor is on a valid row
14.172 checkCursor();
14.173
14.174 - Object obj = convertNumeric(new Long(x),
14.175 + Object obj = convertNumeric(Long.valueOf(x),
14.176 java.sql.Types.BIGINT,
14.177 RowSetMD.getColumnType(columnIndex));
14.178
14.179 @@ -6429,7 +6434,7 @@
14.180 if (tabName == null)
14.181 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.tablename").toString());
14.182 else
14.183 - tableName = new String(tabName);
14.184 + tableName = tabName;
14.185 }
14.186
14.187 /**
14.188 @@ -6940,7 +6945,7 @@
14.189 }
14.190
14.191 for( int i = 0;i < columnIdxes.length ;i++) {
14.192 - iMatchColumns.set(i,new Integer(-1));
14.193 + iMatchColumns.set(i,Integer.valueOf(-1));
14.194 }
14.195 }
14.196
14.197 @@ -7049,7 +7054,7 @@
14.198 }
14.199 }
14.200 for(int i = 0 ;i < columnIdxes.length; i++) {
14.201 - iMatchColumns.add(i,new Integer(columnIdxes[i]));
14.202 + iMatchColumns.add(i,Integer.valueOf(columnIdxes[i]));
14.203 }
14.204 }
14.205
14.206 @@ -7104,7 +7109,7 @@
14.207 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols1").toString());
14.208 } else {
14.209 // set iMatchColumn
14.210 - iMatchColumns.set(0, new Integer(columnIdx));
14.211 + iMatchColumns.set(0, Integer.valueOf(columnIdx));
14.212 //strMatchColumn = null;
14.213 }
14.214 }
14.215 @@ -7126,7 +7131,7 @@
14.216 */
14.217 public void setMatchColumn(String columnName) throws SQLException {
14.218 // validate, if col is ok to be set
14.219 - if(columnName.equals(null) || ((columnName = columnName.trim()) == "" )) {
14.220 + if(columnName == null || (columnName= columnName.trim()).equals("") ) {
14.221 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols2").toString());
14.222 } else {
14.223 // set strMatchColumn
14.224 @@ -7151,13 +7156,13 @@
14.225 */
14.226 public void unsetMatchColumn(int columnIdx) throws SQLException {
14.227 // check if we are unsetting the SAME column
14.228 - if(! iMatchColumns.get(0).equals(new Integer(columnIdx) ) ) {
14.229 + if(! iMatchColumns.get(0).equals(Integer.valueOf(columnIdx) ) ) {
14.230 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch").toString());
14.231 } else if(strMatchColumns.get(0) != null) {
14.232 throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch1").toString());
14.233 } else {
14.234 // that is, we are unsetting it.
14.235 - iMatchColumns.set(0, new Integer(-1));
14.236 + iMatchColumns.set(0, Integer.valueOf(-1));
14.237 }
14.238 }
14.239
15.1 --- a/src/share/classes/com/sun/rowset/FilteredRowSetImpl.java Tue Oct 12 13:34:59 2010 -0400
15.2 +++ b/src/share/classes/com/sun/rowset/FilteredRowSetImpl.java Mon Oct 18 11:25:28 2010 -0400
15.3 @@ -499,7 +499,7 @@
15.4
15.5 if(onInsertRow) {
15.6 if(p != null) {
15.7 - bool = p.evaluate(new Integer(x),columnIndex);
15.8 + bool = p.evaluate(Integer.valueOf(x),columnIndex);
15.9
15.10 if(!bool) {
15.11 throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
15.12 @@ -566,7 +566,7 @@
15.13
15.14 if(onInsertRow) {
15.15 if(p != null) {
15.16 - bool = p.evaluate(new Boolean(x) , columnIndex);
15.17 + bool = p.evaluate(Boolean.valueOf(x) , columnIndex);
15.18
15.19 if(!bool) {
15.20 throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
15.21 @@ -634,7 +634,7 @@
15.22
15.23 if(onInsertRow) {
15.24 if(p != null) {
15.25 - bool = p.evaluate(new Byte(x),columnIndex);
15.26 + bool = p.evaluate(Byte.valueOf(x),columnIndex);
15.27
15.28 if(!bool) {
15.29 throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
15.30 @@ -703,7 +703,7 @@
15.31
15.32 if(onInsertRow) {
15.33 if(p != null) {
15.34 - bool = p.evaluate(new Short(x), columnIndex);
15.35 + bool = p.evaluate(Short.valueOf(x), columnIndex);
15.36
15.37 if(!bool) {
15.38 throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
15.39 @@ -771,7 +771,7 @@
15.40
15.41 if(onInsertRow) {
15.42 if(p != null) {
15.43 - bool = p.evaluate(new Long(x), columnIndex);
15.44 + bool = p.evaluate(Long.valueOf(x), columnIndex);
15.45
15.46 if(!bool) {
15.47 throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
15.48 @@ -1106,12 +1106,12 @@
15.49 public void updateBytes(int columnIndex , byte []x) throws SQLException {
15.50
15.51 boolean bool;
15.52 - String val = new String();
15.53 + String val = "";
15.54
15.55 Byte [] obj_arr = new Byte[x.length];
15.56
15.57 for(int i = 0; i < x.length; i++) {
15.58 - obj_arr[i] = new Byte(x[i]);
15.59 + obj_arr[i] = Byte.valueOf(x[i]);
15.60 val = val.concat(obj_arr[i].toString());
15.61 }
15.62
16.1 --- a/src/share/classes/com/sun/rowset/JdbcRowSetImpl.java Tue Oct 12 13:34:59 2010 -0400
16.2 +++ b/src/share/classes/com/sun/rowset/JdbcRowSetImpl.java Mon Oct 18 11:25:28 2010 -0400
16.3 @@ -215,7 +215,7 @@
16.4
16.5 iMatchColumns = new Vector(10);
16.6 for(int i = 0; i < 10 ; i++) {
16.7 - iMatchColumns.add(i,new Integer(-1));
16.8 + iMatchColumns.add(i,Integer.valueOf(-1));
16.9 }
16.10
16.11 strMatchColumns = new Vector(10);
16.12 @@ -288,7 +288,7 @@
16.13
16.14 iMatchColumns = new Vector(10);
16.15 for(int i = 0; i < 10 ; i++) {
16.16 - iMatchColumns.add(i,new Integer(-1));
16.17 + iMatchColumns.add(i,Integer.valueOf(-1));
16.18 }
16.19
16.20 strMatchColumns = new Vector(10);
16.21 @@ -375,7 +375,7 @@
16.22
16.23 iMatchColumns = new Vector(10);
16.24 for(int i = 0; i < 10 ; i++) {
16.25 - iMatchColumns.add(i,new Integer(-1));
16.26 + iMatchColumns.add(i,Integer.valueOf(-1));
16.27 }
16.28
16.29 strMatchColumns = new Vector(10);
16.30 @@ -465,7 +465,7 @@
16.31
16.32 iMatchColumns = new Vector(10);
16.33 for(int i = 0; i < 10 ; i++) {
16.34 - iMatchColumns.add(i,new Integer(-1));
16.35 + iMatchColumns.add(i,Integer.valueOf(-1));
16.36 }
16.37
16.38 strMatchColumns = new Vector(10);
16.39 @@ -3754,7 +3754,7 @@
16.40 }
16.41
16.42 for( int i = 0;i < columnIdxes.length ;i++) {
16.43 - iMatchColumns.set(i,new Integer(-1));
16.44 + iMatchColumns.set(i,Integer.valueOf(-1));
16.45 }
16.46 }
16.47
16.48 @@ -3863,7 +3863,7 @@
16.49 }
16.50 }
16.51 for(int i = 0 ;i < columnIdxes.length; i++) {
16.52 - iMatchColumns.add(i,new Integer(columnIdxes[i]));
16.53 + iMatchColumns.add(i,Integer.valueOf(columnIdxes[i]));
16.54 }
16.55 }
16.56
16.57 @@ -3918,7 +3918,7 @@
16.58 throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.matchcols1").toString());
16.59 } else {
16.60 // set iMatchColumn
16.61 - iMatchColumns.set(0, new Integer(columnIdx));
16.62 + iMatchColumns.set(0, Integer.valueOf(columnIdx));
16.63 //strMatchColumn = null;
16.64 }
16.65 }
16.66 @@ -3940,7 +3940,7 @@
16.67 */
16.68 public void setMatchColumn(String columnName) throws SQLException {
16.69 // validate, if col is ok to be set
16.70 - if(columnName.equals(null) || ((columnName = columnName.trim()) == "" )) {
16.71 + if(columnName == null || (columnName= columnName.trim()).equals("")) {
16.72 throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.matchcols2").toString());
16.73 } else {
16.74 // set strMatchColumn
16.75 @@ -3965,13 +3965,13 @@
16.76 */
16.77 public void unsetMatchColumn(int columnIdx) throws SQLException {
16.78 // check if we are unsetting the SAME column
16.79 - if(! iMatchColumns.get(0).equals(new Integer(columnIdx) ) ) {
16.80 + if(! iMatchColumns.get(0).equals(Integer.valueOf(columnIdx) ) ) {
16.81 throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.unsetmatch").toString());
16.82 } else if(strMatchColumns.get(0) != null) {
16.83 throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.usecolname").toString());
16.84 } else {
16.85 // that is, we are unsetting it.
16.86 - iMatchColumns.set(0, new Integer(-1));
16.87 + iMatchColumns.set(0, Integer.valueOf(-1));
16.88 }
16.89 }
16.90
17.1 --- a/src/share/classes/com/sun/rowset/JoinRowSetImpl.java Tue Oct 12 13:34:59 2010 -0400
17.2 +++ b/src/share/classes/com/sun/rowset/JoinRowSetImpl.java Mon Oct 18 11:25:28 2010 -0400
17.3 @@ -33,6 +33,8 @@
17.4 import java.util.*;
17.5
17.6 import javax.sql.rowset.*;
17.7 +import javax.sql.rowset.spi.SyncProvider;
17.8 +import javax.sql.rowset.spi.SyncProviderException;
17.9
17.10 /**
17.11 * The standard implementation of the <code>JoinRowSet</code>
17.12 @@ -550,7 +552,7 @@
17.13 // This 'if' will be removed after all joins are implemented.
17.14 throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.notsupported").toString());
17.15 } else {
17.16 - Integer Intgr = new Integer(JoinRowSet.INNER_JOIN);
17.17 + Integer Intgr = Integer.valueOf(JoinRowSet.INNER_JOIN);
17.18 vecJoinType.add(Intgr);
17.19 }
17.20 } else {
17.21 @@ -874,8 +876,8 @@
17.22
17.23 String strWhereClause = "Select ";
17.24 String whereClause;
17.25 - String tabName= null;
17.26 - String strTabName = null;
17.27 + String tabName= "";
17.28 + String strTabName = "";
17.29 int sz,cols;
17.30 int j;
17.31 CachedRowSetImpl crs;
17.32 @@ -889,8 +891,6 @@
17.33 // tableNameX.(rowsetX.getMatchColumnName()) ==
17.34 // tableNameZ.(rowsetZ.getMatchColumnName()));
17.35
17.36 - tabName = new String();
17.37 - strTabName = new String();
17.38 sz = vecRowSetsInJOIN.size();
17.39 for(int i=0;i<sz; i++) {
17.40 crs = (CachedRowSetImpl)vecRowSetsInJOIN.get(i);
17.41 @@ -4311,6 +4311,27 @@
17.42 return crsInternal.createCopySchema();
17.43 }
17.44
17.45 + /**
17.46 + * {@inheritDoc}
17.47 + */
17.48 + public void setSyncProvider(String providerStr) throws SQLException {
17.49 + crsInternal.setSyncProvider(providerStr);
17.50 + }
17.51 +
17.52 + /**
17.53 + * {@inheritDoc}
17.54 + */
17.55 + public void acceptChanges() throws SyncProviderException {
17.56 + crsInternal.acceptChanges();
17.57 + }
17.58 +
17.59 + /**
17.60 + * {@inheritDoc}
17.61 + */
17.62 + public SyncProvider getSyncProvider() throws SQLException {
17.63 + return crsInternal.getSyncProvider();
17.64 + }
17.65 +
17.66 /**
17.67 * This method re populates the resBundle
17.68 * during the deserialization process
18.1 --- a/src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java Tue Oct 12 13:34:59 2010 -0400
18.2 +++ b/src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java Mon Oct 18 11:25:28 2010 -0400
18.3 @@ -338,11 +338,11 @@
18.4 if (crs.rowDeleted()) {
18.5 // The row has been deleted.
18.6 if (conflict = (deleteOriginalRow(crs, this.crsResolve)) == true) {
18.7 - status.add(rows, new Integer(SyncResolver.DELETE_ROW_CONFLICT));
18.8 + status.add(rows, Integer.valueOf(SyncResolver.DELETE_ROW_CONFLICT));
18.9 } else {
18.10 // delete happened without any occurrence of conflicts
18.11 // so update status accordingly
18.12 - status.add(rows, new Integer(SyncResolver.NO_ROW_CONFLICT));
18.13 + status.add(rows, Integer.valueOf(SyncResolver.NO_ROW_CONFLICT));
18.14 }
18.15
18.16 } else if (crs.rowInserted()) {
18.17 @@ -350,20 +350,20 @@
18.18
18.19 pstmtIns = con.prepareStatement(insertCmd);
18.20 if ( (conflict = insertNewRow(crs, pstmtIns, this.crsResolve)) == true) {
18.21 - status.add(rows, new Integer(SyncResolver.INSERT_ROW_CONFLICT));
18.22 + status.add(rows, Integer.valueOf(SyncResolver.INSERT_ROW_CONFLICT));
18.23 } else {
18.24 // insert happened without any occurrence of conflicts
18.25 // so update status accordingly
18.26 - status.add(rows, new Integer(SyncResolver.NO_ROW_CONFLICT));
18.27 + status.add(rows, Integer.valueOf(SyncResolver.NO_ROW_CONFLICT));
18.28 }
18.29 } else if (crs.rowUpdated()) {
18.30 // The row has been updated.
18.31 if ( conflict = (updateOriginalRow(crs)) == true) {
18.32 - status.add(rows, new Integer(SyncResolver.UPDATE_ROW_CONFLICT));
18.33 + status.add(rows, Integer.valueOf(SyncResolver.UPDATE_ROW_CONFLICT));
18.34 } else {
18.35 // update happened without any occurrence of conflicts
18.36 // so update status accordingly
18.37 - status.add(rows, new Integer(SyncResolver.NO_ROW_CONFLICT));
18.38 + status.add(rows, Integer.valueOf(SyncResolver.NO_ROW_CONFLICT));
18.39 }
18.40
18.41 } else {
18.42 @@ -375,7 +375,7 @@
18.43 * that is fine.
18.44 **/
18.45 int icolCount = crs.getMetaData().getColumnCount();
18.46 - status.add(rows, new Integer(SyncResolver.NO_ROW_CONFLICT));
18.47 + status.add(rows, Integer.valueOf(SyncResolver.NO_ROW_CONFLICT));
18.48
18.49 this.crsResolve.moveToInsertRow();
18.50 for(int cols=0;cols<iColCount;cols++) {
18.51 @@ -398,7 +398,7 @@
18.52 boolean boolConf = false;
18.53 for (int j=1;j<status.size();j++){
18.54 // ignore status for index = 0 which is set to null
18.55 - if(! ((status.get(j)).equals(new Integer(SyncResolver.NO_ROW_CONFLICT)))) {
18.56 + if(! ((status.get(j)).equals(Integer.valueOf(SyncResolver.NO_ROW_CONFLICT)))) {
18.57 // there is at least one conflict which needs to be resolved
18.58 boolConf = true;
18.59 break;
18.60 @@ -541,7 +541,7 @@
18.61 // how many fields need to be updated
18.62 int colsNotChanged = 0;
18.63 Vector cols = new Vector();
18.64 - String updateExec = new String(updateCmd);
18.65 + String updateExec = updateCmd;
18.66 Object orig;
18.67 Object curr;
18.68 Object rsval;
18.69 @@ -652,7 +652,7 @@
18.70 updateExec += ", ";
18.71 }
18.72 updateExec += crs.getMetaData().getColumnName(i);
18.73 - cols.add(new Integer(i));
18.74 + cols.add(Integer.valueOf(i));
18.75 updateExec += " = ? ";
18.76 first = false;
18.77
18.78 @@ -698,7 +698,7 @@
18.79 updateExec += ", ";
18.80 }
18.81 updateExec += crs.getMetaData().getColumnName(i);
18.82 - cols.add(new Integer(i));
18.83 + cols.add(Integer.valueOf(i));
18.84 updateExec += " = ? ";
18.85 flag = false;
18.86 } else {
18.87 @@ -1184,7 +1184,7 @@
18.88 // trim all the leading and trailing whitespaces,
18.89 // white spaces can never be catalog, schema or a table name.
18.90
18.91 - String cmd = new String();
18.92 + String cmd = "";
18.93
18.94 catalog = catalog.trim();
18.95 schema = schema.trim();
19.1 --- a/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java Tue Oct 12 13:34:59 2010 -0400
19.2 +++ b/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java Mon Oct 18 11:25:28 2010 -0400
19.3 @@ -248,7 +248,7 @@
19.4 String strProvider = strProviderInstance.substring(0, (caller.getSyncProvider()).toString().indexOf("@"));
19.5
19.6 propString("sync-provider-name", strProvider);
19.7 - propString("sync-provider-vendor", "Sun Microsystems Inc.");
19.8 + propString("sync-provider-vendor", "Oracle Corporation");
19.9 propString("sync-provider-version", "1.0");
19.10 propInteger("sync-provider-grade", caller.getSyncProvider().getProviderGrade());
19.11 propInteger("data-source-lock", caller.getSyncProvider().getDataSourceLock());
19.12 @@ -387,7 +387,7 @@
19.13 if (caller.wasNull())
19.14 writeNull();
19.15 else
19.16 - writeInteger(caller.getInt(idx));
19.17 + writeInteger(i);
19.18 break;
19.19 case java.sql.Types.BIGINT:
19.20 long l = caller.getLong(idx);
19.21 @@ -574,7 +574,7 @@
19.22 }
19.23
19.24 private void writeBoolean(boolean b) throws java.io.IOException {
19.25 - writer.write(new Boolean(b).toString());
19.26 + writer.write(Boolean.valueOf(b).toString());
19.27 }
19.28
19.29 private void writeFloat(float f) throws java.io.IOException {
19.30 @@ -641,7 +641,7 @@
19.31 return null;
19.32 }
19.33 char []charStr = s.toCharArray();
19.34 - String specialStr = new String();
19.35 + String specialStr = "";
19.36
19.37 for(int i = 0; i < charStr.length; i++) {
19.38 if(charStr[i] == '&') {
20.1 --- a/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java Tue Oct 12 13:34:59 2010 -0400
20.2 +++ b/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java Mon Oct 18 11:25:28 2010 -0400
20.3 @@ -441,9 +441,9 @@
20.4 updates = new Vector();
20.5
20.6 // start out with the empty string
20.7 - columnValue = new String("");
20.8 - propertyValue = new String("");
20.9 - metaDataValue = new String("");
20.10 + columnValue = "";
20.11 + propertyValue = "";
20.12 + metaDataValue = "";
20.13
20.14 nullVal = false;
20.15 idx = 0;
20.16 @@ -481,21 +481,21 @@
20.17 items = properties.length;
20.18
20.19 for (i=0;i<items;i++) {
20.20 - propMap.put(properties[i], new Integer(i));
20.21 + propMap.put(properties[i], Integer.valueOf(i));
20.22 }
20.23
20.24 colDefMap = new HashMap();
20.25 items = colDef.length;
20.26
20.27 for (i=0;i<items;i++) {
20.28 - colDefMap.put(colDef[i], new Integer(i));
20.29 + colDefMap.put(colDef[i], Integer.valueOf(i));
20.30 }
20.31
20.32 dataMap = new HashMap();
20.33 items = data.length;
20.34
20.35 for (i=0;i<items;i++) {
20.36 - dataMap.put(data[i], new Integer(i));
20.37 + dataMap.put(data[i], Integer.valueOf(i));
20.38 }
20.39
20.40 //Initialize connection map here
20.41 @@ -686,7 +686,7 @@
20.42 }
20.43
20.44 // propertyValue need to be reset to an empty string
20.45 - propertyValue = new String("");
20.46 + propertyValue = "";
20.47 setTag(-1);
20.48 break;
20.49 case METADATA:
20.50 @@ -710,7 +710,7 @@
20.51
20.52 }
20.53 // metaDataValue needs to be reset to an empty string
20.54 - metaDataValue = new String("");
20.55 + metaDataValue = "";
20.56 }
20.57 setTag(-1);
20.58 break;
20.59 @@ -736,7 +736,7 @@
20.60 insertValue(tempStr);
20.61 }
20.62 // columnValue now need to be reset to the empty string
20.63 - columnValue = new String("");
20.64 + columnValue = "";
20.65 } catch (SQLException ex) {
20.66 throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errinsert").toString(), ex.getMessage()));
20.67 }
20.68 @@ -981,7 +981,7 @@
20.69
20.70 private boolean getBooleanValue(String s) {
20.71
20.72 - return new Boolean(s).booleanValue();
20.73 + return Boolean.valueOf(s).booleanValue();
20.74 }
20.75
20.76 private java.math.BigDecimal getBigDecimalValue(String s) {
20.77 @@ -1316,7 +1316,7 @@
20.78 **/
20.79
20.80 tempUpdate = tempUpdate.concat(new String(ch,start,len));
20.81 - upd[0] = new Integer(idx);
20.82 + upd[0] = Integer.valueOf(idx);
20.83 upd[1] = tempUpdate;
20.84 //updates.add(upd);
20.85
21.1 --- a/src/share/classes/com/sun/rowset/providers/RIOptimisticProvider.java Tue Oct 12 13:34:59 2010 -0400
21.2 +++ b/src/share/classes/com/sun/rowset/providers/RIOptimisticProvider.java Mon Oct 18 11:25:28 2010 -0400
21.3 @@ -93,14 +93,14 @@
21.4 private CachedRowSetWriter writer;
21.5
21.6 /**
21.7 - * The unique provider indentifier.
21.8 + * The unique provider identifier.
21.9 */
21.10 private String providerID = "com.sun.rowset.providers.RIOptimisticProvider";
21.11
21.12 /**
21.13 * The vendor name of this SyncProvider implementation
21.14 */
21.15 - private String vendorName = "Sun Microsystems Inc.";
21.16 + private String vendorName = "Oracle Corporation";
21.17
21.18 /**
21.19 * The version number of this SyncProvider implementation
21.20 @@ -236,8 +236,8 @@
21.21 }
21.22
21.23 /**
21.24 - * Returns the vendor name of the Reference Implemntation Optimistic
21.25 - * Syncchronication Provider
21.26 + * Returns the vendor name of the Reference Implementation Optimistic
21.27 + * Synchronization Provider
21.28 *
21.29 * @return the <code>String</code> detailing the vendor name of this
21.30 * SyncProvider
22.1 --- a/src/share/classes/com/sun/rowset/providers/RIXMLProvider.java Tue Oct 12 13:34:59 2010 -0400
22.2 +++ b/src/share/classes/com/sun/rowset/providers/RIXMLProvider.java Mon Oct 18 11:25:28 2010 -0400
22.3 @@ -1,5 +1,5 @@
22.4 /*
22.5 - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
22.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
22.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
22.8 *
22.9 * This code is free software; you can redistribute it and/or modify it
22.10 @@ -85,7 +85,7 @@
22.11 /**
22.12 * The vendor name of this SyncProvider implementation.
22.13 */
22.14 - private String vendorName = "Sun Microsystems Inc.";
22.15 + private String vendorName = "Oracle Corporation";
22.16
22.17 /**
22.18 * The version number of this SyncProvider implementation.
23.1 --- a/src/share/classes/com/sun/servicetag/Installer.java Tue Oct 12 13:34:59 2010 -0400
23.2 +++ b/src/share/classes/com/sun/servicetag/Installer.java Mon Oct 18 11:25:28 2010 -0400
23.3 @@ -43,7 +43,8 @@
23.4 "servicetag.dir.path";
23.5 private static String SVCTAG_ENABLE_REGISTRATION =
23.6 "servicetag.registration.enabled";
23.7 - private final static String SUN_VENDOR = "Sun Microsystems";
23.8 + private final static String ORACLE = "Oracle";
23.9 + private final static String SUN = "Sun Microsystems";
23.10 private final static String REGISTRATION_XML = "registration.xml";
23.11 private final static String SERVICE_TAG_FILE = "servicetag";
23.12 private final static String REGISTRATION_HTML_NAME = "register";
23.13 @@ -84,9 +85,10 @@
23.14
23.15 // Implementation of ServiceTag.getJavaServiceTag(String) method
23.16 static ServiceTag getJavaServiceTag(String source) throws IOException {
23.17 - if (!System.getProperty("java.vendor").startsWith(SUN_VENDOR)) {
23.18 + String vendor = System.getProperty("java.vendor", "");
23.19 + if (!vendor.startsWith(SUN) && !vendor.startsWith(ORACLE)) {
23.20 // Products bundling this implementation may run on
23.21 - // Mac OS which is not a Sun JDK
23.22 + // Mac OS which is not a Sun/Oracle JDK
23.23 return null;
23.24 }
23.25 boolean cleanup = false;
23.26 @@ -365,7 +367,7 @@
23.27 props.getProperty("servicetag.parent.name"),
23.28 props.getProperty("servicetag.parent.urn"),
23.29 getProductDefinedId(),
23.30 - SUN_VENDOR,
23.31 + System.getProperty("java.vendor"),
23.32 System.getProperty("os.arch"),
23.33 getZoneName(),
23.34 svcTagSource);
24.1 --- a/src/share/classes/com/sun/servicetag/RegistrationData.java Tue Oct 12 13:34:59 2010 -0400
24.2 +++ b/src/share/classes/com/sun/servicetag/RegistrationData.java Mon Oct 18 11:25:28 2010 -0400
24.3 @@ -80,12 +80,12 @@
24.4 * <tr>
24.5 * <td><tt>systemManufacturer</tt></td>
24.6 * <td>System manufacturer</td>
24.7 - * <td> e.g. Sun Microsystems</td>
24.8 + * <td> e.g. Oracle Corporation</td>
24.9 * </tr>
24.10 * <tr>
24.11 * <td><tt>cpuManufacturer</tt></td>
24.12 * <td>CPU manufacturer</td>
24.13 - * <td> e.g. Sun Microsystems</td>
24.14 + * <td> e.g. Oracle Corporation</td>
24.15 * </tr>
24.16 * <tr>
24.17 * <td><tt>serialNumber</tt></td>
25.1 --- a/src/share/classes/com/sun/servicetag/Registry.java Tue Oct 12 13:34:59 2010 -0400
25.2 +++ b/src/share/classes/com/sun/servicetag/Registry.java Mon Oct 18 11:25:28 2010 -0400
25.3 @@ -90,7 +90,7 @@
25.4 stclient = getWindowsStClientFile();
25.5 } else {
25.6 if (isVerbose()) {
25.7 - System.out.println("Running on non-Sun JDK");
25.8 + System.out.println("Running on unsupported platform");
25.9 }
25.10 }
25.11 initialized = true;
26.1 --- a/src/share/classes/com/sun/servicetag/SolarisSystemEnvironment.java Tue Oct 12 13:34:59 2010 -0400
26.2 +++ b/src/share/classes/com/sun/servicetag/SolarisSystemEnvironment.java Mon Oct 18 11:25:28 2010 -0400
26.3 @@ -44,6 +44,7 @@
26.4 * Solaris implementation of the SystemEnvironment class.
26.5 */
26.6 class SolarisSystemEnvironment extends SystemEnvironment {
26.7 + private static final String ORACLE = "Oracle Corporation";
26.8 SolarisSystemEnvironment() {
26.9 setHostId(getCommandOutput("/usr/bin/hostid"));
26.10 setSystemModel(getCommandOutput("/usr/bin/uname", "-i"));
26.11 @@ -59,7 +60,7 @@
26.12 private String getSolarisCpuManufacturer() {
26.13 // not fully accurate, this could be another manufacturer (fujitsu for example)
26.14 if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) {
26.15 - return "Sun Microsystems, Inc";
26.16 + return ORACLE;
26.17 }
26.18
26.19 // if we're here, then we'll try smbios (type 4)
26.20 @@ -73,7 +74,7 @@
26.21 private String getSolarisSystemManufacturer() {
26.22 // not fully accurate, this could be another manufacturer (fujitsu for example)
26.23 if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) {
26.24 - return "Sun Microsystems, Inc";
26.25 + return ORACLE;
26.26 }
26.27
26.28 // if we're here, then we'll try smbios (type 1)
26.29 @@ -117,7 +118,7 @@
26.30 // ID SIZE TYPE
26.31 // 1 150 SMB_TYPE_SYSTEM (system information)
26.32 //
26.33 - // Manufacturer: Sun Microsystems
26.34 + // Manufacturer: Oracle Corporation
26.35 // Product: Sun Fire X4600
26.36 // Version: To Be Filled By O.E.M.
26.37 // Serial Number: 00:14:4F:45:0C:2A
27.1 --- a/src/share/classes/java/awt/Dialog.java Tue Oct 12 13:34:59 2010 -0400
27.2 +++ b/src/share/classes/java/awt/Dialog.java Mon Oct 18 11:25:28 2010 -0400
27.3 @@ -1068,7 +1068,7 @@
27.4 modalityPushed();
27.5 try {
27.6 EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
27.7 - secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 5000);
27.8 + secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 0);
27.9 if (!secondaryLoop.enter()) {
27.10 secondaryLoop = null;
27.11 }
28.1 --- a/src/share/classes/java/awt/KeyboardFocusManager.java Tue Oct 12 13:34:59 2010 -0400
28.2 +++ b/src/share/classes/java/awt/KeyboardFocusManager.java Mon Oct 18 11:25:28 2010 -0400
28.3 @@ -142,6 +142,9 @@
28.4 public void removeLastFocusRequest(Component heavyweight) {
28.5 KeyboardFocusManager.removeLastFocusRequest(heavyweight);
28.6 }
28.7 + public void setMostRecentFocusOwner(Window window, Component component) {
28.8 + KeyboardFocusManager.setMostRecentFocusOwner(window, component);
28.9 + }
28.10 }
28.11 );
28.12 }
29.1 --- a/src/share/classes/java/awt/event/ActionEvent.java Tue Oct 12 13:34:59 2010 -0400
29.2 +++ b/src/share/classes/java/awt/event/ActionEvent.java Mon Oct 18 11:25:28 2010 -0400
29.3 @@ -51,7 +51,7 @@
29.4 * in the range from {@code ACTION_FIRST} to {@code ACTION_LAST}.
29.5 *
29.6 * @see ActionListener
29.7 - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/eventmodel.html">Tutorial: Java 1.1 Event Model</a>
29.8 + * @see <a href="http://java.sun.com/docs/books/tutorial/uiswing/events/actionlistener.html">Tutorial: How to Write an Action Listener</a>
29.9 *
29.10 * @author Carl Quinn
29.11 * @since 1.1
30.1 --- a/src/share/classes/java/awt/image/SampleModel.java Tue Oct 12 13:34:59 2010 -0400
30.2 +++ b/src/share/classes/java/awt/image/SampleModel.java Mon Oct 18 11:25:28 2010 -0400
30.3 @@ -937,14 +937,22 @@
30.4 int iArray[], DataBuffer data) {
30.5 int pixels[];
30.6 int Offset=0;
30.7 + int x1 = x + w;
30.8 + int y1 = y + h;
30.9 +
30.10 + if (x < 0 || x1 < x || x1 > width ||
30.11 + y < 0 || y1 < y || y1 > height)
30.12 + {
30.13 + throw new ArrayIndexOutOfBoundsException("Invalid coordinates.");
30.14 + }
30.15
30.16 if (iArray != null)
30.17 pixels = iArray;
30.18 else
30.19 pixels = new int[w * h];
30.20
30.21 - for(int i=y; i<(h+y); i++) {
30.22 - for (int j=x; j<(w+x); j++) {
30.23 + for(int i=y; i<y1; i++) {
30.24 + for (int j=x; j<x1; j++) {
30.25 pixels[Offset++] = getSample(j, i, b, data);
30.26 }
30.27 }
30.28 @@ -978,14 +986,22 @@
30.29 DataBuffer data) {
30.30 float pixels[];
30.31 int Offset=0;
30.32 + int x1 = x + w;
30.33 + int y1 = y + h;
30.34 +
30.35 + if (x < 0 || x1 < x || x1 > width ||
30.36 + y < 0 || y1 < y || y1 > height)
30.37 + {
30.38 + throw new ArrayIndexOutOfBoundsException("Invalid coordinates");
30.39 + }
30.40
30.41 if (fArray != null)
30.42 pixels = fArray;
30.43 else
30.44 pixels = new float[w * h];
30.45
30.46 - for (int i=y; i<(h+y); i++) {
30.47 - for (int j=x; j<(w+x); j++) {
30.48 + for (int i=y; i<y1; i++) {
30.49 + for (int j=x; j<x1; j++) {
30.50 pixels[Offset++] = getSampleFloat(j, i, b, data);
30.51 }
30.52 }
30.53 @@ -1019,14 +1035,22 @@
30.54 DataBuffer data) {
30.55 double pixels[];
30.56 int Offset=0;
30.57 + int x1 = x + w;
30.58 + int y1 = y + h;
30.59 +
30.60 + if (x < 0 || x1 < x || x1 > width ||
30.61 + y < 0 || y1 < y || y1 > height)
30.62 + {
30.63 + throw new ArrayIndexOutOfBoundsException("Invalid coordinates");
30.64 + }
30.65
30.66 if (dArray != null)
30.67 pixels = dArray;
30.68 else
30.69 pixels = new double[w * h];
30.70
30.71 - for (int i=y; i<(y+h); i++) {
30.72 - for (int j=x; j<(x+w); j++) {
30.73 + for (int i=y; i<y1; i++) {
30.74 + for (int j=x; j<x1; j++) {
30.75 pixels[Offset++] = getSampleDouble(j, i, b, data);
30.76 }
30.77 }
31.1 --- a/src/share/classes/java/beans/EventSetDescriptor.java Tue Oct 12 13:34:59 2010 -0400
31.2 +++ b/src/share/classes/java/beans/EventSetDescriptor.java Mon Oct 18 11:25:28 2010 -0400
31.3 @@ -176,8 +176,9 @@
31.4 setRemoveListenerMethod(getMethod(sourceClass, removeListenerMethodName, 1));
31.5
31.6 // Be more forgiving of not finding the getListener method.
31.7 - if (getListenerMethodName != null) {
31.8 - setGetListenerMethod(Introspector.findInstanceMethod(sourceClass, getListenerMethodName));
31.9 + Method method = Introspector.findMethod(sourceClass, getListenerMethodName, 0);
31.10 + if (method != null) {
31.11 + setGetListenerMethod(method);
31.12 }
31.13 }
31.14
32.1 --- a/src/share/classes/java/beans/IndexedPropertyDescriptor.java Tue Oct 12 13:34:59 2010 -0400
32.2 +++ b/src/share/classes/java/beans/IndexedPropertyDescriptor.java Mon Oct 18 11:25:28 2010 -0400
32.3 @@ -189,11 +189,13 @@
32.4 indexedReadMethodName = Introspector.GET_PREFIX + getBaseName();
32.5 }
32.6 }
32.7 - indexedReadMethod = Introspector.findInstanceMethod(cls, indexedReadMethodName, int.class);
32.8 +
32.9 + Class[] args = { int.class };
32.10 + indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args);
32.11 if (indexedReadMethod == null) {
32.12 // no "is" method, so look for a "get" method.
32.13 indexedReadMethodName = Introspector.GET_PREFIX + getBaseName();
32.14 - indexedReadMethod = Introspector.findInstanceMethod(cls, indexedReadMethodName, int.class);
32.15 + indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args);
32.16 }
32.17 setIndexedReadMethod0(indexedReadMethod);
32.18 }
32.19 @@ -265,7 +267,9 @@
32.20 if (indexedWriteMethodName == null) {
32.21 indexedWriteMethodName = Introspector.SET_PREFIX + getBaseName();
32.22 }
32.23 - indexedWriteMethod = Introspector.findInstanceMethod(cls, indexedWriteMethodName, int.class, type);
32.24 +
32.25 + Class[] args = (type == null) ? null : new Class[] { int.class, type };
32.26 + indexedWriteMethod = Introspector.findMethod(cls, indexedWriteMethodName, 2, args);
32.27 if (indexedWriteMethod != null) {
32.28 if (!indexedWriteMethod.getReturnType().equals(void.class)) {
32.29 indexedWriteMethod = null;
33.1 --- a/src/share/classes/java/beans/Introspector.java Tue Oct 12 13:34:59 2010 -0400
33.2 +++ b/src/share/classes/java/beans/Introspector.java Mon Oct 18 11:25:28 2010 -0400
33.3 @@ -28,7 +28,6 @@
33.4 import com.sun.beans.WeakCache;
33.5 import com.sun.beans.finder.BeanInfoFinder;
33.6 import com.sun.beans.finder.ClassFinder;
33.7 -import com.sun.beans.finder.MethodFinder;
33.8
33.9 import java.lang.ref.Reference;
33.10 import java.lang.ref.SoftReference;
33.11 @@ -843,8 +842,8 @@
33.12 Method read = result.getReadMethod();
33.13
33.14 if (read == null && write != null) {
33.15 - read = findInstanceMethod(result.getClass0(),
33.16 - GET_PREFIX + NameGenerator.capitalize(result.getName()));
33.17 + read = findMethod(result.getClass0(),
33.18 + GET_PREFIX + NameGenerator.capitalize(result.getName()), 0);
33.19 if (read != null) {
33.20 try {
33.21 result.setReadMethod(read);
33.22 @@ -854,9 +853,9 @@
33.23 }
33.24 }
33.25 if (write == null && read != null) {
33.26 - write = findInstanceMethod(result.getClass0(),
33.27 - SET_PREFIX + NameGenerator.capitalize(result.getName()),
33.28 - FeatureDescriptor.getReturnType(result.getClass0(), read));
33.29 + write = findMethod(result.getClass0(),
33.30 + SET_PREFIX + NameGenerator.capitalize(result.getName()), 1,
33.31 + new Class[] { FeatureDescriptor.getReturnType(result.getClass0(), read) });
33.32 if (write != null) {
33.33 try {
33.34 result.setWriteMethod(write);
33.35 @@ -1280,27 +1279,90 @@
33.36 // Package private support methods.
33.37 //======================================================================
33.38
33.39 - static Method findMethod(Class<?> type, String name, int args) {
33.40 - for (Method method : type.getMethods()) {
33.41 - if (method.getName().equals(name) && (args == method.getParameterTypes().length)) {
33.42 - try {
33.43 - return MethodFinder.findAccessibleMethod(method);
33.44 + /**
33.45 + * Internal support for finding a target methodName with a given
33.46 + * parameter list on a given class.
33.47 + */
33.48 + private static Method internalFindMethod(Class start, String methodName,
33.49 + int argCount, Class args[]) {
33.50 + // For overriden methods we need to find the most derived version.
33.51 + // So we start with the given class and walk up the superclass chain.
33.52 +
33.53 + Method method = null;
33.54 +
33.55 + for (Class cl = start; cl != null; cl = cl.getSuperclass()) {
33.56 + Method methods[] = getPublicDeclaredMethods(cl);
33.57 + for (int i = 0; i < methods.length; i++) {
33.58 + method = methods[i];
33.59 + if (method == null) {
33.60 + continue;
33.61 }
33.62 - catch (NoSuchMethodException exception) {
33.63 - // continue search for a method with the specified count of parameters
33.64 +
33.65 + // make sure method signature matches.
33.66 + Class params[] = FeatureDescriptor.getParameterTypes(start, method);
33.67 + if (method.getName().equals(methodName) &&
33.68 + params.length == argCount) {
33.69 + if (args != null) {
33.70 + boolean different = false;
33.71 + if (argCount > 0) {
33.72 + for (int j = 0; j < argCount; j++) {
33.73 + if (params[j] != args[j]) {
33.74 + different = true;
33.75 + continue;
33.76 + }
33.77 + }
33.78 + if (different) {
33.79 + continue;
33.80 + }
33.81 + }
33.82 + }
33.83 + return method;
33.84 }
33.85 }
33.86 }
33.87 - return null;
33.88 + method = null;
33.89 +
33.90 + // Now check any inherited interfaces. This is necessary both when
33.91 + // the argument class is itself an interface, and when the argument
33.92 + // class is an abstract class.
33.93 + Class ifcs[] = start.getInterfaces();
33.94 + for (int i = 0 ; i < ifcs.length; i++) {
33.95 + // Note: The original implementation had both methods calling
33.96 + // the 3 arg method. This is preserved but perhaps it should
33.97 + // pass the args array instead of null.
33.98 + method = internalFindMethod(ifcs[i], methodName, argCount, null);
33.99 + if (method != null) {
33.100 + break;
33.101 + }
33.102 + }
33.103 + return method;
33.104 }
33.105
33.106 - static Method findInstanceMethod(Class<?> type, String name, Class<?>... args) {
33.107 - try {
33.108 - return MethodFinder.findInstanceMethod(type, name, args);
33.109 - }
33.110 - catch (NoSuchMethodException exception) {
33.111 + /**
33.112 + * Find a target methodName on a given class.
33.113 + */
33.114 + static Method findMethod(Class cls, String methodName, int argCount) {
33.115 + return findMethod(cls, methodName, argCount, null);
33.116 + }
33.117 +
33.118 + /**
33.119 + * Find a target methodName with specific parameter list on a given class.
33.120 + * <p>
33.121 + * Used in the contructors of the EventSetDescriptor,
33.122 + * PropertyDescriptor and the IndexedPropertyDescriptor.
33.123 + * <p>
33.124 + * @param cls The Class object on which to retrieve the method.
33.125 + * @param methodName Name of the method.
33.126 + * @param argCount Number of arguments for the desired method.
33.127 + * @param args Array of argument types for the method.
33.128 + * @return the method or null if not found
33.129 + */
33.130 + static Method findMethod(Class cls, String methodName, int argCount,
33.131 + Class args[]) {
33.132 + if (methodName == null) {
33.133 return null;
33.134 }
33.135 + return internalFindMethod(cls, methodName, argCount, args);
33.136 }
33.137
33.138 /**
34.1 --- a/src/share/classes/java/beans/MethodDescriptor.java Tue Oct 12 13:34:59 2010 -0400
34.2 +++ b/src/share/classes/java/beans/MethodDescriptor.java Mon Oct 18 11:25:28 2010 -0400
34.3 @@ -90,13 +90,13 @@
34.4 // Find methods for up to 2 params. We are guessing here.
34.5 // This block should never execute unless the classloader
34.6 // that loaded the argument classes disappears.
34.7 - method = Introspector.findMethod(cls, name, i);
34.8 + method = Introspector.findMethod(cls, name, i, null);
34.9 if (method != null) {
34.10 break;
34.11 }
34.12 }
34.13 } else {
34.14 - method = Statement.getMethod(cls, name, params);
34.15 + method = Introspector.findMethod(cls, name, params.length, params);
34.16 }
34.17 setMethod(method);
34.18 }
35.1 --- a/src/share/classes/java/beans/PropertyDescriptor.java Tue Oct 12 13:34:59 2010 -0400
35.2 +++ b/src/share/classes/java/beans/PropertyDescriptor.java Mon Oct 18 11:25:28 2010 -0400
35.3 @@ -112,7 +112,8 @@
35.4 // If this class or one of its base classes allow PropertyChangeListener,
35.5 // then we assume that any properties we discover are "bound".
35.6 // See Introspector.getTargetPropertyInfo() method.
35.7 - this.bound = null != Introspector.findInstanceMethod(beanClass, "addPropertyChangeListener", PropertyChangeListener.class);
35.8 + Class[] args = { PropertyChangeListener.class };
35.9 + this.bound = null != Introspector.findMethod(beanClass, "addPropertyChangeListener", args.length, args);
35.10 }
35.11
35.12 /**
35.13 @@ -223,10 +224,10 @@
35.14 // property type is. For booleans, there can be "is" and "get"
35.15 // methods. If an "is" method exists, this is the official
35.16 // reader method so look for this one first.
35.17 - readMethod = Introspector.findInstanceMethod(cls, readMethodName);
35.18 + readMethod = Introspector.findMethod(cls, readMethodName, 0);
35.19 if (readMethod == null) {
35.20 readMethodName = Introspector.GET_PREFIX + getBaseName();
35.21 - readMethod = Introspector.findInstanceMethod(cls, readMethodName);
35.22 + readMethod = Introspector.findMethod(cls, readMethodName, 0);
35.23 }
35.24 try {
35.25 setReadMethod(readMethod);
35.26 @@ -291,7 +292,8 @@
35.27 writeMethodName = Introspector.SET_PREFIX + getBaseName();
35.28 }
35.29
35.30 - writeMethod = Introspector.findInstanceMethod(cls, writeMethodName, type);
35.31 + Class[] args = (type == null) ? null : new Class[] { type };
35.32 + writeMethod = Introspector.findMethod(cls, writeMethodName, 1, args);
35.33 if (writeMethod != null) {
35.34 if (!writeMethod.getReturnType().equals(void.class)) {
35.35 writeMethod = null;
36.1 --- a/src/share/classes/java/lang/System.java Tue Oct 12 13:34:59 2010 -0400
36.2 +++ b/src/share/classes/java/lang/System.java Mon Oct 18 11:25:28 2010 -0400
36.3 @@ -1101,22 +1101,12 @@
36.4 lineSeparator = props.getProperty("line.separator");
36.5 sun.misc.Version.init();
36.6
36.7 - // Workaround until DownloadManager initialization is revisited.
36.8 - // Make JavaLangAccess available early enough for internal
36.9 - // Shutdown hooks to be registered
36.10 - setJavaLangAccess();
36.11 -
36.12 // Gets and removes system properties that configure the Integer
36.13 // cache used to support the object identity semantics of autoboxing.
36.14 // At this time, the size of the cache may be controlled by the
36.15 // vm option -XX:AutoBoxCacheMax=<size>.
36.16 Integer.getAndRemoveCacheProperties();
36.17
36.18 - // Load the zip library now in order to keep java.util.zip.ZipFile
36.19 - // from trying to use itself to load this library later.
36.20 - loadLibrary("zip");
36.21 -
36.22 -
36.23 FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
36.24 FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
36.25 FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
36.26 @@ -1124,6 +1114,10 @@
36.27 setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
36.28 setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true));
36.29
36.30 + // Load the zip library now in order to keep java.util.zip.ZipFile
36.31 + // from trying to use itself to load this library later.
36.32 + loadLibrary("zip");
36.33 +
36.34 // Setup Java signal handlers for HUP, TERM, and INT (where available).
36.35 Terminator.setup();
36.36
36.37 @@ -1153,6 +1147,9 @@
36.38 // way as other threads; we must do it ourselves here.
36.39 Thread current = Thread.currentThread();
36.40 current.getThreadGroup().add(current);
36.41 +
36.42 + // register shared secrets
36.43 + setJavaLangAccess();
36.44 }
36.45
36.46 private static void setJavaLangAccess() {
37.1 --- a/src/share/classes/java/net/InetAddress.java Tue Oct 12 13:34:59 2010 -0400
37.2 +++ b/src/share/classes/java/net/InetAddress.java Mon Oct 18 11:25:28 2010 -0400
37.3 @@ -677,19 +677,20 @@
37.4
37.5 static InetAddressImpl impl;
37.6
37.7 - private static HashMap lookupTable = new HashMap();
37.8 + private static HashMap<String, InetAddress[]> lookupTable
37.9 + = new HashMap<String, InetAddress[]>();
37.10
37.11 /**
37.12 * Represents a cache entry
37.13 */
37.14 static final class CacheEntry {
37.15
37.16 - CacheEntry(Object address, long expiration) {
37.17 - this.address = address;
37.18 + CacheEntry(InetAddress[] addresses, long expiration) {
37.19 + this.addresses = addresses;
37.20 this.expiration = expiration;
37.21 }
37.22
37.23 - Object address;
37.24 + InetAddress[] addresses;
37.25 long expiration;
37.26 }
37.27
37.28 @@ -698,7 +699,7 @@
37.29 * at creation time.
37.30 */
37.31 static final class Cache {
37.32 - private LinkedHashMap cache;
37.33 + private LinkedHashMap<String, CacheEntry> cache;
37.34 private Type type;
37.35
37.36 enum Type {Positive, Negative};
37.37 @@ -708,7 +709,7 @@
37.38 */
37.39 public Cache(Type type) {
37.40 this.type = type;
37.41 - cache = new LinkedHashMap();
37.42 + cache = new LinkedHashMap<String, CacheEntry>();
37.43 }
37.44
37.45 private int getPolicy() {
37.46 @@ -724,7 +725,7 @@
37.47 * entry then for this host then the entry will be
37.48 * replaced.
37.49 */
37.50 - public Cache put(String host, Object address) {
37.51 + public Cache put(String host, InetAddress[] addresses) {
37.52 int policy = getPolicy();
37.53 if (policy == InetAddressCachePolicy.NEVER) {
37.54 return this;
37.55 @@ -736,12 +737,10 @@
37.56
37.57 // As we iterate in insertion order we can
37.58 // terminate when a non-expired entry is found.
37.59 - LinkedList expired = new LinkedList();
37.60 - Iterator i = cache.keySet().iterator();
37.61 + LinkedList<String> expired = new LinkedList<String>();
37.62 long now = System.currentTimeMillis();
37.63 - while (i.hasNext()) {
37.64 - String key = (String)i.next();
37.65 - CacheEntry entry = (CacheEntry)cache.get(key);
37.66 + for (String key : cache.keySet()) {
37.67 + CacheEntry entry = cache.get(key);
37.68
37.69 if (entry.expiration >= 0 && entry.expiration < now) {
37.70 expired.add(key);
37.71 @@ -750,9 +749,8 @@
37.72 }
37.73 }
37.74
37.75 - i = expired.iterator();
37.76 - while (i.hasNext()) {
37.77 - cache.remove(i.next());
37.78 + for (String key : expired) {
37.79 + cache.remove(key);
37.80 }
37.81 }
37.82
37.83 @@ -766,7 +764,7 @@
37.84 } else {
37.85 expiration = System.currentTimeMillis() + (policy * 1000);
37.86 }
37.87 - CacheEntry entry = new CacheEntry(address, expiration);
37.88 + CacheEntry entry = new CacheEntry(addresses, expiration);
37.89 cache.put(host, entry);
37.90 return this;
37.91 }
37.92 @@ -780,7 +778,7 @@
37.93 if (policy == InetAddressCachePolicy.NEVER) {
37.94 return null;
37.95 }
37.96 - CacheEntry entry = (CacheEntry)cache.get(host);
37.97 + CacheEntry entry = cache.get(host);
37.98
37.99 // check if entry has expired
37.100 if (entry != null && policy != InetAddressCachePolicy.FOREVER) {
37.101 @@ -814,42 +812,41 @@
37.102 }
37.103
37.104 /*
37.105 - * Cache the given hostname and address.
37.106 + * Cache the given hostname and addresses.
37.107 */
37.108 - private static void cacheAddress(String hostname, Object address,
37.109 - boolean success) {
37.110 + private static void cacheAddresses(String hostname,
37.111 + InetAddress[] addresses,
37.112 + boolean success) {
37.113 hostname = hostname.toLowerCase();
37.114 synchronized (addressCache) {
37.115 cacheInitIfNeeded();
37.116 if (success) {
37.117 - addressCache.put(hostname, address);
37.118 + addressCache.put(hostname, addresses);
37.119 } else {
37.120 - negativeCache.put(hostname, address);
37.121 + negativeCache.put(hostname, addresses);
37.122 }
37.123 }
37.124 }
37.125
37.126 /*
37.127 * Lookup hostname in cache (positive & negative cache). If
37.128 - * found return address, null if not found.
37.129 + * found return addresses, null if not found.
37.130 */
37.131 - private static Object getCachedAddress(String hostname) {
37.132 + private static InetAddress[] getCachedAddresses(String hostname) {
37.133 hostname = hostname.toLowerCase();
37.134
37.135 // search both positive & negative caches
37.136
37.137 synchronized (addressCache) {
37.138 - CacheEntry entry;
37.139 -
37.140 cacheInitIfNeeded();
37.141
37.142 - entry = addressCache.get(hostname);
37.143 + CacheEntry entry = addressCache.get(hostname);
37.144 if (entry == null) {
37.145 entry = negativeCache.get(hostname);
37.146 }
37.147
37.148 if (entry != null) {
37.149 - return entry.address;
37.150 + return entry.addresses;
37.151 }
37.152 }
37.153
37.154 @@ -911,7 +908,7 @@
37.155
37.156 static {
37.157 // create the impl
37.158 - impl = (new InetAddressImplFactory()).create();
37.159 + impl = InetAddressImplFactory.create();
37.160
37.161 // get name service if provided and requested
37.162 String provider = null;;
37.163 @@ -931,7 +928,7 @@
37.164 }
37.165
37.166 // if not designate any name services provider,
37.167 - // creat a default one
37.168 + // create a default one
37.169 if (nameServices.size() == 0) {
37.170 NameService ns = createNSProvider("default");
37.171 nameServices.add(ns);
37.172 @@ -939,7 +936,7 @@
37.173 }
37.174
37.175 /**
37.176 - * Create an InetAddress based on the provided host name and IP address
37.177 + * Creates an InetAddress based on the provided host name and IP address.
37.178 * No name service is checked for the validity of the address.
37.179 *
37.180 * <p> The host name can either be a machine name, such as
37.181 @@ -1067,13 +1064,13 @@
37.182
37.183 boolean ipv6Expected = false;
37.184 if (host.charAt(0) == '[') {
37.185 - // This is supposed to be an IPv6 litteral
37.186 + // This is supposed to be an IPv6 literal
37.187 if (host.length() > 2 && host.charAt(host.length()-1) == ']') {
37.188 host = host.substring(1, host.length() -1);
37.189 ipv6Expected = true;
37.190 } else {
37.191 // This was supposed to be a IPv6 address, but it's not!
37.192 - throw new UnknownHostException(host);
37.193 + throw new UnknownHostException(host + ": invalid IPv6 address");
37.194 }
37.195 }
37.196
37.197 @@ -1180,8 +1177,6 @@
37.198 throws UnknownHostException {
37.199 /* If it gets here it is presumed to be a hostname */
37.200 /* Cache.get can return: null, unknownAddress, or InetAddress[] */
37.201 - Object obj = null;
37.202 - Object objcopy = null;
37.203
37.204 /* make sure the connection to the host is allowed, before we
37.205 * give out a hostname
37.206 @@ -1193,26 +1188,23 @@
37.207 }
37.208 }
37.209
37.210 - obj = getCachedAddress(host);
37.211 + InetAddress[] addresses = getCachedAddresses(host);
37.212
37.213 /* If no entry in cache, then do the host lookup */
37.214 - if (obj == null) {
37.215 - obj = getAddressFromNameService(host);
37.216 + if (addresses == null) {
37.217 + addresses = getAddressesFromNameService(host);
37.218 }
37.219
37.220 - if (obj == unknown_array)
37.221 + if (addresses == unknown_array)
37.222 throw new UnknownHostException(host);
37.223
37.224 - /* Make a copy of the InetAddress array */
37.225 - objcopy = ((InetAddress [])obj).clone();
37.226 -
37.227 - return (InetAddress [])objcopy;
37.228 + return addresses.clone();
37.229 }
37.230
37.231 - private static Object getAddressFromNameService(String host)
37.232 + private static InetAddress[] getAddressesFromNameService(String host)
37.233 throws UnknownHostException
37.234 {
37.235 - Object obj = null;
37.236 + InetAddress[] addresses = null;
37.237 boolean success = false;
37.238 UnknownHostException ex = null;
37.239
37.240 @@ -1226,16 +1218,16 @@
37.241 // would be blocked until the host is removed
37.242 // from the lookupTable. Then this thread
37.243 // should try to look up the addressCache.
37.244 - // i) if it found the address in the
37.245 + // i) if it found the addresses in the
37.246 // addressCache, checkLookupTable() would
37.247 - // return the address.
37.248 - // ii) if it didn't find the address in the
37.249 + // return the addresses.
37.250 + // ii) if it didn't find the addresses in the
37.251 // addressCache for any reason,
37.252 // it should add the host in the
37.253 // lookupTable and return null so the
37.254 // following code would do a lookup itself.
37.255 - if ((obj = checkLookupTable(host)) == null) {
37.256 - // This is the first thread which looks up the address
37.257 + if ((addresses = checkLookupTable(host)) == null) {
37.258 + // This is the first thread which looks up the addresses
37.259 // this host or the cache entry for this host has been
37.260 // expired so this thread should do the lookup.
37.261 for (NameService nameService : nameServices) {
37.262 @@ -1246,26 +1238,26 @@
37.263 * allocating space when the lookup fails.
37.264 */
37.265
37.266 - obj = nameService.lookupAllHostAddr(host);
37.267 + addresses = nameService.lookupAllHostAddr(host);
37.268 success = true;
37.269 break;
37.270 } catch (UnknownHostException uhe) {
37.271 if (host.equalsIgnoreCase("localhost")) {
37.272 InetAddress[] local = new InetAddress[] { impl.loopbackAddress() };
37.273 - obj = local;
37.274 + addresses = local;
37.275 success = true;
37.276 break;
37.277 }
37.278 else {
37.279 - obj = unknown_array;
37.280 + addresses = unknown_array;
37.281 success = false;
37.282 ex = uhe;
37.283 }
37.284 }
37.285 }
37.286
37.287 - // Cache the address.
37.288 - cacheAddress(host, obj, success);
37.289 + // Cache the addresses.
37.290 + cacheAddresses(host, addresses, success);
37.291 // Delete the host from the lookupTable, and
37.292 // notify all threads waiting for the monitor
37.293 // for lookupTable.
37.294 @@ -1274,13 +1266,13 @@
37.295 throw ex;
37.296 }
37.297
37.298 - return obj;
37.299 + return addresses;
37.300 }
37.301
37.302
37.303 - private static Object checkLookupTable(String host) {
37.304 - // make sure obj is null.
37.305 - Object obj = null;
37.306 + private static InetAddress[] checkLookupTable(String host) {
37.307 + // make sure addresses is null.
37.308 + InetAddress[] addresses = null;
37.309
37.310 synchronized (lookupTable) {
37.311 // If the host isn't in the lookupTable, add it in the
37.312 @@ -1288,11 +1280,11 @@
37.313 // the lookup.
37.314 if (lookupTable.containsKey(host) == false) {
37.315 lookupTable.put(host, null);
37.316 - return obj;
37.317 + return addresses;
37.318 }
37.319
37.320 // If the host is in the lookupTable, it means that another
37.321 - // thread is trying to look up the address of this host.
37.322 + // thread is trying to look up the addresses of this host.
37.323 // This thread should wait.
37.324 while (lookupTable.containsKey(host)) {
37.325 try {
37.326 @@ -1302,18 +1294,18 @@
37.327 }
37.328 }
37.329
37.330 - // The other thread has finished looking up the address of
37.331 - // the host. This thread should retry to get the address
37.332 - // from the addressCache. If it doesn't get the address from
37.333 - // the cache, it will try to look up the address itself.
37.334 - obj = getCachedAddress(host);
37.335 - if (obj == null) {
37.336 + // The other thread has finished looking up the addresses of
37.337 + // the host. This thread should retry to get the addresses
37.338 + // from the addressCache. If it doesn't get the addresses from
37.339 + // the cache, it will try to look up the addresses itself.
37.340 + addresses = getCachedAddresses(host);
37.341 + if (addresses == null) {
37.342 synchronized (lookupTable) {
37.343 lookupTable.put(host, null);
37.344 }
37.345 }
37.346
37.347 - return obj;
37.348 + return addresses;
37.349 }
37.350
37.351 private static void updateLookupTable(String host) {
37.352 @@ -1396,15 +1388,20 @@
37.353 cachedLocalHost = null;
37.354 }
37.355
37.356 - // we are calling getAddressFromNameService directly
37.357 + // we are calling getAddressesFromNameService directly
37.358 // to avoid getting localHost from cache
37.359 if (ret == null) {
37.360 InetAddress[] localAddrs;
37.361 try {
37.362 localAddrs =
37.363 - (InetAddress[]) InetAddress.getAddressFromNameService(local);
37.364 + InetAddress.getAddressesFromNameService(local);
37.365 } catch (UnknownHostException uhe) {
37.366 - throw new UnknownHostException(local + ": " + uhe.getMessage());
37.367 + // Rethrow with a more informative error message.
37.368 + UnknownHostException uhe2 =
37.369 + new UnknownHostException(local + ": " +
37.370 + uhe.getMessage());
37.371 + uhe2.initCause(uhe);
37.372 + throw uhe2;
37.373 }
37.374 cachedLocalHost = localAddrs[0];
37.375 cacheTime = now;
37.376 @@ -1434,8 +1431,8 @@
37.377 /*
37.378 * Load and instantiate an underlying impl class
37.379 */
37.380 - static Object loadImpl(String implName) {
37.381 - Object impl;
37.382 + static InetAddressImpl loadImpl(String implName) {
37.383 + Object impl = null;
37.384
37.385 /*
37.386 * Property "impl.prefix" will be prepended to the classname
37.387 @@ -1446,7 +1443,6 @@
37.388 */
37.389 String prefix = AccessController.doPrivileged(
37.390 new GetPropertyAction("impl.prefix", ""));
37.391 - impl = null;
37.392 try {
37.393 impl = Class.forName("java.net." + prefix + implName).newInstance();
37.394 } catch (ClassNotFoundException e) {
37.395 @@ -1471,7 +1467,7 @@
37.396 }
37.397 }
37.398
37.399 - return impl;
37.400 + return (InetAddressImpl) impl;
37.401 }
37.402
37.403 private void readObjectNoData (ObjectInputStream s) throws
37.404 @@ -1498,13 +1494,8 @@
37.405 class InetAddressImplFactory {
37.406
37.407 static InetAddressImpl create() {
37.408 - Object o;
37.409 - if (isIPv6Supported()) {
37.410 - o = InetAddress.loadImpl("Inet6AddressImpl");
37.411 - } else {
37.412 - o = InetAddress.loadImpl("Inet4AddressImpl");
37.413 - }
37.414 - return (InetAddressImpl)o;
37.415 + return InetAddress.loadImpl(isIPv6Supported() ?
37.416 + "Inet6AddressImpl" : "Inet4AddressImpl");
37.417 }
37.418
37.419 static native boolean isIPv6Supported();
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
38.2 +++ b/src/share/classes/java/nio/file/FileSystemLoopException.java Mon Oct 18 11:25:28 2010 -0400
38.3 @@ -0,0 +1,50 @@
38.4 +/*
38.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
38.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
38.7 + *
38.8 + * This code is free software; you can redistribute it and/or modify it
38.9 + * under the terms of the GNU General Public License version 2 only, as
38.10 + * published by the Free Software Foundation. Oracle designates this
38.11 + * particular file as subject to the "Classpath" exception as provided
38.12 + * by Oracle in the LICENSE file that accompanied this code.
38.13 + *
38.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
38.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
38.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
38.17 + * version 2 for more details (a copy is included in the LICENSE file that
38.18 + * accompanied this code).
38.19 + *
38.20 + * You should have received a copy of the GNU General Public License version
38.21 + * 2 along with this work; if not, write to the Free Software Foundation,
38.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
38.23 + *
38.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
38.25 + * or visit www.oracle.com if you need additional information or have any
38.26 + * questions.
38.27 + */
38.28 +
38.29 +package java.nio.file;
38.30 +
38.31 +/**
38.32 + * Checked exception thrown when a file system loop, or cycle, is encountered.
38.33 + *
38.34 + * @since 1.7
38.35 + * @see Files#walkFileTree
38.36 + */
38.37 +
38.38 +public class FileSystemLoopException
38.39 + extends FileSystemException
38.40 +{
38.41 + private static final long serialVersionUID = 4843039591949217617L;
38.42 +
38.43 + /**
38.44 + * Constructs an instance of this class.
38.45 + *
38.46 + * @param file
38.47 + * a string identifying the file causing the cycle or {@code null} if
38.48 + * not known
38.49 + */
38.50 + public FileSystemLoopException(String file) {
38.51 + super(file);
38.52 + }
38.53 +}
39.1 --- a/src/share/classes/java/nio/file/FileTreeWalker.java Tue Oct 12 13:34:59 2010 -0400
39.2 +++ b/src/share/classes/java/nio/file/FileTreeWalker.java Mon Oct 18 11:25:28 2010 -0400
39.3 @@ -38,7 +38,6 @@
39.4
39.5 class FileTreeWalker {
39.6 private final boolean followLinks;
39.7 - private final boolean detectCycles;
39.8 private final LinkOption[] linkOptions;
39.9 private final FileVisitor<? super Path> visitor;
39.10 private final int maxDepth;
39.11 @@ -48,17 +47,15 @@
39.12 int maxDepth)
39.13 {
39.14 boolean fl = false;
39.15 - boolean dc = false;
39.16 for (FileVisitOption option: options) {
39.17 + // will throw NPE if options contains null
39.18 switch (option) {
39.19 - case FOLLOW_LINKS : fl = true; break;
39.20 - case DETECT_CYCLES : dc = true; break;
39.21 + case FOLLOW_LINKS : fl = true; break;
39.22 default:
39.23 throw new AssertionError("Should not get here");
39.24 }
39.25 }
39.26 this.followLinks = fl;
39.27 - this.detectCycles = fl | dc;
39.28 this.linkOptions = (fl) ? new LinkOption[0] :
39.29 new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
39.30 this.visitor = visitor;
39.31 @@ -68,13 +65,11 @@
39.32 /**
39.33 * Walk file tree starting at the given file
39.34 */
39.35 - void walk(Path start) {
39.36 + void walk(Path start) throws IOException {
39.37 FileVisitResult result = walk(start,
39.38 0,
39.39 new ArrayList<AncestorDirectory>());
39.40 - if (result == null) {
39.41 - throw new NullPointerException("Visitor returned 'null'");
39.42 - }
39.43 + Objects.nonNull(result, "FileVisitor returned null");
39.44 }
39.45
39.46 /**
39.47 @@ -88,11 +83,8 @@
39.48 private FileVisitResult walk(Path file,
39.49 int depth,
39.50 List<AncestorDirectory> ancestors)
39.51 + throws IOException
39.52 {
39.53 - // depth check
39.54 - if (depth > maxDepth)
39.55 - return FileVisitResult.CONTINUE;
39.56 -
39.57 // if attributes are cached then use them if possible
39.58 BasicFileAttributes attrs = null;
39.59 if ((depth > 0) &&
39.60 @@ -137,13 +129,13 @@
39.61 return visitor.visitFileFailed(file, exc);
39.62 }
39.63
39.64 - // file is not a directory so invoke visitFile method
39.65 - if (!attrs.isDirectory()) {
39.66 + // at maximum depth or file is not a directory
39.67 + if (depth >= maxDepth || !attrs.isDirectory()) {
39.68 return visitor.visitFile(file, attrs);
39.69 }
39.70
39.71 - // check for cycles
39.72 - if (detectCycles) {
39.73 + // check for cycles when following links
39.74 + if (followLinks) {
39.75 Object key = attrs.fileKey();
39.76
39.77 // if this directory and ancestor has a file key then we compare
39.78 @@ -153,19 +145,23 @@
39.79 if (key != null && ancestorKey != null) {
39.80 if (key.equals(ancestorKey)) {
39.81 // cycle detected
39.82 - return visitor.visitFile(file, attrs);
39.83 + return visitor.visitFileFailed(file,
39.84 + new FileSystemLoopException(file.toString()));
39.85 }
39.86 } else {
39.87 + boolean isSameFile = false;
39.88 try {
39.89 - if (file.isSameFile(ancestor.file())) {
39.90 - // cycle detected
39.91 - return visitor.visitFile(file, attrs);
39.92 - }
39.93 + isSameFile = file.isSameFile(ancestor.file());
39.94 } catch (IOException x) {
39.95 // ignore
39.96 } catch (SecurityException x) {
39.97 // ignore
39.98 }
39.99 + if (isSameFile) {
39.100 + // cycle detected
39.101 + return visitor.visitFileFailed(file,
39.102 + new FileSystemLoopException(file.toString()));
39.103 + }
39.104 }
39.105 }
39.106
39.107 @@ -181,7 +177,7 @@
39.108 try {
39.109 stream = file.newDirectoryStream();
39.110 } catch (IOException x) {
39.111 - return visitor.preVisitDirectoryFailed(file, x);
39.112 + return visitor.visitFileFailed(file, x);
39.113 } catch (SecurityException x) {
39.114 // ignore, as per spec
39.115 return FileVisitResult.CONTINUE;
39.116 @@ -192,20 +188,14 @@
39.117
39.118 // invoke preVisitDirectory and then visit each entry
39.119 try {
39.120 - result = visitor.preVisitDirectory(file);
39.121 + result = visitor.preVisitDirectory(file, attrs);
39.122 if (result != FileVisitResult.CONTINUE) {
39.123 return result;
39.124 }
39.125
39.126 - // if an I/O occurs during iteration then a CME is thrown. We
39.127 - // need to distinguish this from a CME thrown by the visitor.
39.128 - boolean inAction = false;
39.129 -
39.130 try {
39.131 for (Path entry: stream) {
39.132 - inAction = true;
39.133 result = walk(entry, depth+1, ancestors);
39.134 - inAction = false;
39.135
39.136 // returning null will cause NPE to be thrown
39.137 if (result == null || result == FileVisitResult.TERMINATE)
39.138 @@ -215,17 +205,9 @@
39.139 if (result == FileVisitResult.SKIP_SIBLINGS)
39.140 break;
39.141 }
39.142 - } catch (ConcurrentModificationException x) {
39.143 - // if CME thrown because the iteration failed then remember
39.144 - // the IOException so that it is notified to postVisitDirectory
39.145 - if (!inAction) {
39.146 - // iteration failed
39.147 - Throwable t = x.getCause();
39.148 - if (t instanceof IOException)
39.149 - ioe = (IOException)t;
39.150 - }
39.151 - if (ioe == null)
39.152 - throw x;
39.153 + } catch (DirectoryIteratorException e) {
39.154 + // IOException will be notified to postVisitDirectory
39.155 + ioe = e.getCause();
39.156 }
39.157 } finally {
39.158 try {
39.159 @@ -238,7 +220,7 @@
39.160
39.161 } finally {
39.162 // remove key from trail if doing cycle detection
39.163 - if (detectCycles) {
39.164 + if (followLinks) {
39.165 ancestors.remove(ancestors.size()-1);
39.166 }
39.167 }
40.1 --- a/src/share/classes/java/nio/file/FileVisitOption.java Tue Oct 12 13:34:59 2010 -0400
40.2 +++ b/src/share/classes/java/nio/file/FileVisitOption.java Mon Oct 18 11:25:28 2010 -0400
40.3 @@ -37,9 +37,5 @@
40.4 /**
40.5 * Follow symbolic links.
40.6 */
40.7 - FOLLOW_LINKS,
40.8 - /**
40.9 - * Detect cycles in the file tree.
40.10 - */
40.11 - DETECT_CYCLES;
40.12 + FOLLOW_LINKS;
40.13 }
41.1 --- a/src/share/classes/java/nio/file/FileVisitor.java Tue Oct 12 13:34:59 2010 -0400
41.2 +++ b/src/share/classes/java/nio/file/FileVisitor.java Mon Oct 18 11:25:28 2010 -0400
41.3 @@ -40,33 +40,28 @@
41.4 * Path start = ...
41.5 * Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
41.6 * @Override
41.7 - * public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
41.8 - * try {
41.9 - * file.delete();
41.10 - * } catch (IOException exc) {
41.11 - * // failed to delete, do error handling here
41.12 - * }
41.13 + * public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
41.14 + * throws IOException
41.15 + * {
41.16 + * file.delete();
41.17 * return FileVisitResult.CONTINUE;
41.18 * }
41.19 * @Override
41.20 - * public FileVisitResult postVisitDirectory(Path dir, IOException e) {
41.21 - * if (e == null) {
41.22 - * try {
41.23 - * dir.delete();
41.24 - * } catch (IOException exc) {
41.25 - * // failed to delete, do error handling here
41.26 - * }
41.27 - * } else {
41.28 + * public FileVisitResult postVisitDirectory(Path dir, IOException e)
41.29 + * throws IOException
41.30 + * {
41.31 + * if (e != null) {
41.32 * // directory iteration failed
41.33 + * throw e;
41.34 * }
41.35 + * dir.delete();
41.36 * return FileVisitResult.CONTINUE;
41.37 * }
41.38 * });
41.39 * </pre>
41.40 - * <p> Furthermore, suppose we want to copy a file tree rooted at a source
41.41 - * directory to a target location. In that case, symbolic links should be
41.42 - * followed and the target directory should be created before the entries in
41.43 - * the directory are copied.
41.44 + * <p> Furthermore, suppose we want to copy a file tree to a target location.
41.45 + * In that case, symbolic links should be followed and the target directory
41.46 + * should be created before the entries in the directory are copied.
41.47 * <pre>
41.48 * final Path source = ...
41.49 * final Path target = ...
41.50 @@ -74,25 +69,21 @@
41.51 * Files.walkFileTree(source, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
41.52 * new SimpleFileVisitor<Path>() {
41.53 * @Override
41.54 - * public FileVisitResult preVisitDirectory(Path dir) {
41.55 + * public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
41.56 + * throws IOException
41.57 + * {
41.58 * try {
41.59 * dir.copyTo(target.resolve(source.relativize(dir)));
41.60 * } catch (FileAlreadyExistsException e) {
41.61 * // ignore
41.62 - * } catch (IOException e) {
41.63 - * // copy failed, do error handling here
41.64 - * // skip rest of directory and descendants
41.65 - * return SKIP_SUBTREE;
41.66 * }
41.67 * return CONTINUE;
41.68 * }
41.69 * @Override
41.70 - * public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
41.71 - * try {
41.72 - * file.copyTo(target.resolve(source.relativize(file)));
41.73 - * } catch (IOException e) {
41.74 - * // copy failed, do error handling here
41.75 - * }
41.76 + * public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
41.77 + * throws IOException
41.78 + * {
41.79 + * file.copyTo(target.resolve(source.relativize(file)));
41.80 * return CONTINUE;
41.81 * }
41.82 * });
41.83 @@ -114,22 +105,16 @@
41.84 *
41.85 * @param dir
41.86 * a reference to the directory
41.87 + * @param attrs
41.88 + * the directory's basic attributes
41.89 *
41.90 * @return the visit result
41.91 + *
41.92 + * @throws IOException
41.93 + * if an I/O error occurs
41.94 */
41.95 - FileVisitResult preVisitDirectory(T dir);
41.96 -
41.97 - /**
41.98 - * Invoked for a directory that could not be opened.
41.99 - *
41.100 - * @param dir
41.101 - * a reference to the directory
41.102 - * @param exc
41.103 - * the I/O exception thrown from the attempt to open the directory
41.104 - *
41.105 - * @return the visit result
41.106 - */
41.107 - FileVisitResult preVisitDirectoryFailed(T dir, IOException exc);
41.108 + FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
41.109 + throws IOException;
41.110
41.111 /**
41.112 * Invoked for a file in a directory.
41.113 @@ -140,21 +125,30 @@
41.114 * the file's basic attributes
41.115 *
41.116 * @return the visit result
41.117 + *
41.118 + * @throws IOException
41.119 + * if an I/O error occurs
41.120 */
41.121 - FileVisitResult visitFile(T file, BasicFileAttributes attrs);
41.122 + FileVisitResult visitFile(T file, BasicFileAttributes attrs)
41.123 + throws IOException;
41.124
41.125 /**
41.126 - * Invoked for a file when its basic file attributes could not be read.
41.127 + * Invoked for a file that could not be visited. This method is invoked
41.128 + * if the file's attributes could not be read, the file is a directory
41.129 + * that could not be opened, and other reasons.
41.130 *
41.131 * @param file
41.132 * a reference to the file
41.133 * @param exc
41.134 - * the I/O exception thrown from the attempt to read the file
41.135 - * attributes
41.136 + * the I/O exception that prevented the file from being visited
41.137 *
41.138 * @return the visit result
41.139 + *
41.140 + * @throws IOException
41.141 + * if an I/O error occurs
41.142 */
41.143 - FileVisitResult visitFileFailed(T file, IOException exc);
41.144 + FileVisitResult visitFileFailed(T file, IOException exc)
41.145 + throws IOException;
41.146
41.147 /**
41.148 * Invoked for a directory after entries in the directory, and all of their
41.149 @@ -171,6 +165,10 @@
41.150 * of the directory to complete prematurely
41.151 *
41.152 * @return the visit result
41.153 + *
41.154 + * @throws IOException
41.155 + * if an I/O error occurs
41.156 */
41.157 - FileVisitResult postVisitDirectory(T dir, IOException exc);
41.158 + FileVisitResult postVisitDirectory(T dir, IOException exc)
41.159 + throws IOException;
41.160 }
42.1 --- a/src/share/classes/java/nio/file/Files.java Tue Oct 12 13:34:59 2010 -0400
42.2 +++ b/src/share/classes/java/nio/file/Files.java Mon Oct 18 11:25:28 2010 -0400
42.3 @@ -135,9 +135,9 @@
42.4 * FileVisitor} invoked for each file encountered. File tree traversal
42.5 * completes when all accessible files in the tree have been visited, or a
42.6 * visit method returns a result of {@link FileVisitResult#TERMINATE
42.7 - * TERMINATE}. Where a visit method terminates due an uncaught error or
42.8 - * runtime exception then the traversal is terminated and the error or
42.9 - * exception is propagated to the caller of this method.
42.10 + * TERMINATE}. Where a visit method terminates due an {@code IOException},
42.11 + * an uncaught error, or runtime exception, then the traversal is terminated
42.12 + * and the error or exception is propagated to the caller of this method.
42.13 *
42.14 * <p> For each file encountered this method attempts to gets its {@link
42.15 * java.nio.file.attribute.BasicFileAttributes}. If the file is not a
42.16 @@ -146,12 +146,10 @@
42.17 * due to an I/O exception, then the {@link FileVisitor#visitFileFailed
42.18 * visitFileFailed} method is invoked with the I/O exception.
42.19 *
42.20 - * <p> Where the file is a directory, this method attempts to open it by
42.21 - * invoking its {@link Path#newDirectoryStream newDirectoryStream} method.
42.22 - * Where the directory could not be opened, due to an {@code IOException},
42.23 - * then the {@link FileVisitor#preVisitDirectoryFailed preVisitDirectoryFailed}
42.24 - * method is invoked with the I/O exception, after which, the file tree walk
42.25 - * continues, by default, at the next <em>sibling</em> of the directory.
42.26 + * <p> Where the file is a directory, and the directory could not be opened,
42.27 + * then the {@code visitFileFailed} method is invoked with the I/O exception,
42.28 + * after which, the file tree walk continues, by default, at the next
42.29 + * <em>sibling</em> of the directory.
42.30 *
42.31 * <p> Where the directory is opened successfully, then the entries in the
42.32 * directory, and their <em>descendants</em> are visited. When all entries
42.33 @@ -171,26 +169,25 @@
42.34 * method is invoked as specified above).
42.35 *
42.36 * <p> If the {@code options} parameter contains the {@link
42.37 - * FileVisitOption#DETECT_CYCLES DETECT_CYCLES} or {@link
42.38 - * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} options then this method keeps
42.39 + * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then this method keeps
42.40 * track of directories visited so that cycles can be detected. A cycle
42.41 * arises when there is an entry in a directory that is an ancestor of the
42.42 * directory. Cycle detection is done by recording the {@link
42.43 * java.nio.file.attribute.BasicFileAttributes#fileKey file-key} of directories,
42.44 * or if file keys are not available, by invoking the {@link Path#isSameFile
42.45 * isSameFile} method to test if a directory is the same file as an
42.46 - * ancestor. When a cycle is detected the {@link FileVisitor#visitFile
42.47 - * visitFile} is invoked with the attributes of the directory. The {@link
42.48 - * java.nio.file.attribute.BasicFileAttributes#isDirectory isDirectory}
42.49 - * method may be used to test if the file is a directory and that a cycle is
42.50 - * detected. The {@code preVisitDirectory} and {@code postVisitDirectory}
42.51 - * methods are not invoked.
42.52 + * ancestor. When a cycle is detected it is treated as an I/O error, and the
42.53 + * {@link FileVisitor#visitFileFailed visitFileFailed} method is invoked with
42.54 + * an instance of {@link FileSystemLoopException}.
42.55 *
42.56 * <p> The {@code maxDepth} parameter is the maximum number of levels of
42.57 * directories to visit. A value of {@code 0} means that only the starting
42.58 * file is visited, unless denied by the security manager. A value of
42.59 * {@link Integer#MAX_VALUE MAX_VALUE} may be used to indicate that all
42.60 - * levels should be visited.
42.61 + * levels should be visited. The {@code visitFile} method is invoked for all
42.62 + * files, including directories, encountered at {@code maxDepth}, unless the
42.63 + * basic file attributes cannot be read, in which case the {@code
42.64 + * visitFileFailed} method is invoked.
42.65 *
42.66 * <p> If a visitor returns a result of {@code null} then {@code
42.67 * NullPointerException} is thrown.
42.68 @@ -215,11 +212,14 @@
42.69 * In the case of the default provider, the {@link
42.70 * SecurityManager#checkRead(String) checkRead} method is invoked
42.71 * to check read access to the directory.
42.72 + * @throws IOException
42.73 + * If an I/O error is thrown by a visitor method
42.74 */
42.75 public static void walkFileTree(Path start,
42.76 Set<FileVisitOption> options,
42.77 int maxDepth,
42.78 FileVisitor<? super Path> visitor)
42.79 + throws IOException
42.80 {
42.81 if (maxDepth < 0)
42.82 throw new IllegalArgumentException("'maxDepth' is negative");
42.83 @@ -245,8 +245,12 @@
42.84 * In the case of the default provider, the {@link
42.85 * SecurityManager#checkRead(String) checkRead} method is invoked
42.86 * to check read access to the directory.
42.87 + * @throws IOException
42.88 + * If an I/O error is thrown by a visitor method
42.89 */
42.90 - public static void walkFileTree(Path start, FileVisitor<? super Path> visitor) {
42.91 + public static void walkFileTree(Path start, FileVisitor<? super Path> visitor)
42.92 + throws IOException
42.93 + {
42.94 walkFileTree(start,
42.95 EnumSet.noneOf(FileVisitOption.class),
42.96 Integer.MAX_VALUE,
43.1 --- a/src/share/classes/java/nio/file/SimpleFileVisitor.java Tue Oct 12 13:34:59 2010 -0400
43.2 +++ b/src/share/classes/java/nio/file/SimpleFileVisitor.java Mon Oct 18 11:25:28 2010 -0400
43.3 @@ -27,7 +27,7 @@
43.4
43.5 import java.nio.file.attribute.BasicFileAttributes;
43.6 import java.io.IOException;
43.7 -import java.io.IOError;
43.8 +import java.util.Objects;
43.9
43.10 /**
43.11 * A simple visitor of files with default behavior to visit all files and to
43.12 @@ -48,70 +48,47 @@
43.13 }
43.14
43.15 /**
43.16 - * Throws NullPointerException if obj is null.
43.17 - */
43.18 - private static void checkNotNull(Object obj) {
43.19 - if (obj == null)
43.20 - throw new NullPointerException();
43.21 - }
43.22 -
43.23 - /**
43.24 * Invoked for a directory before entries in the directory are visited.
43.25 *
43.26 * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
43.27 * CONTINUE}.
43.28 */
43.29 @Override
43.30 - public FileVisitResult preVisitDirectory(T dir) {
43.31 - checkNotNull(dir);
43.32 + public FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
43.33 + throws IOException
43.34 + {
43.35 + Objects.nonNull(dir);
43.36 + Objects.nonNull(attrs);
43.37 return FileVisitResult.CONTINUE;
43.38 }
43.39
43.40 /**
43.41 - * Invoked for a directory that could not be opened.
43.42 - *
43.43 - * <p> Unless overridden, this method throws {@link IOError} with the I/O
43.44 - * exception as cause.
43.45 - *
43.46 - * @throws IOError
43.47 - * with the I/O exception thrown when the attempt to open the
43.48 - * directory failed
43.49 - */
43.50 - @Override
43.51 - public FileVisitResult preVisitDirectoryFailed(T dir, IOException exc) {
43.52 - checkNotNull(dir);
43.53 - checkNotNull(exc);
43.54 - throw new IOError(exc);
43.55 - }
43.56 -
43.57 - /**
43.58 * Invoked for a file in a directory.
43.59 *
43.60 * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
43.61 * CONTINUE}.
43.62 */
43.63 @Override
43.64 - public FileVisitResult visitFile(T file, BasicFileAttributes attrs) {
43.65 - checkNotNull(file);
43.66 - checkNotNull(attrs);
43.67 + public FileVisitResult visitFile(T file, BasicFileAttributes attrs)
43.68 + throws IOException
43.69 + {
43.70 + Objects.nonNull(file);
43.71 + Objects.nonNull(attrs);
43.72 return FileVisitResult.CONTINUE;
43.73 }
43.74
43.75 /**
43.76 - * Invoked for a file when its basic file attributes could not be read.
43.77 + * Invoked for a file that could not be visited.
43.78 *
43.79 - * <p> Unless overridden, this method throws {@link IOError} with the I/O
43.80 - * exception as cause.
43.81 - *
43.82 - * @throws IOError
43.83 - * with the I/O exception thrown when the attempt to read the file
43.84 - * attributes failed
43.85 + * <p> Unless overridden, this method re-throws the I/O exception that prevented
43.86 + * the file from being visited.
43.87 */
43.88 @Override
43.89 - public FileVisitResult visitFileFailed(T file, IOException exc) {
43.90 - checkNotNull(file);
43.91 - checkNotNull(exc);
43.92 - throw new IOError(exc);
43.93 + public FileVisitResult visitFileFailed(T file, IOException exc)
43.94 + throws IOException
43.95 + {
43.96 + Objects.nonNull(file);
43.97 + throw exc;
43.98 }
43.99
43.100 /**
43.101 @@ -120,18 +97,16 @@
43.102 *
43.103 * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
43.104 * CONTINUE} if the directory iteration completes without an I/O exception;
43.105 - * otherwise this method throws {@link IOError} with the I/O exception as
43.106 - * cause.
43.107 - *
43.108 - * @throws IOError
43.109 - * with the I/O exception thrown when iteration of the directory
43.110 - * completed prematurely due to an I/O error
43.111 + * otherwise this method re-throws the I/O exception that caused the iteration
43.112 + * of the directory to terminate prematurely.
43.113 */
43.114 @Override
43.115 - public FileVisitResult postVisitDirectory(T dir, IOException exc) {
43.116 - checkNotNull(dir);
43.117 + public FileVisitResult postVisitDirectory(T dir, IOException exc)
43.118 + throws IOException
43.119 + {
43.120 + Objects.nonNull(dir);
43.121 if (exc != null)
43.122 - throw new IOError(exc);
43.123 + throw exc;
43.124 return FileVisitResult.CONTINUE;
43.125 }
43.126 }
44.1 --- a/src/share/classes/java/sql/DatabaseMetaData.java Tue Oct 12 13:34:59 2010 -0400
44.2 +++ b/src/share/classes/java/sql/DatabaseMetaData.java Mon Oct 18 11:25:28 2010 -0400
44.3 @@ -3643,7 +3643,7 @@
44.4
44.5 /**
44.6 * Retrieves whether a generated key will always be returned if the column
44.7 - * name(s) or indexe(s) specified for the auto generated key column(s)
44.8 + * name(s) or index(es) specified for the auto generated key column(s)
44.9 * are valid and the statement succeeds. The key that is returned may or
44.10 * may not be based on the column(s) for the auto generated key.
44.11 * Consult your JDBC driver documentation for additional details.
45.1 --- a/src/share/classes/java/sql/Statement.java Tue Oct 12 13:34:59 2010 -0400
45.2 +++ b/src/share/classes/java/sql/Statement.java Mon Oct 18 11:25:28 2010 -0400
45.3 @@ -1051,9 +1051,9 @@
45.4
45.5 /**
45.6 * Returns a value indicating whether this {@code Statement} will be
45.7 - * closed when all dependent objects such as resultsets are closed.
45.8 + * closed when all its dependent result sets are closed.
45.9 * @return {@code true} if the {@code Statement} will be closed when all
45.10 - * of its dependent objects are closed; {@code false} otherwise
45.11 + * of its dependent result sets are closed; {@code false} otherwise
45.12 * @throws SQLException if this method is called on a closed
45.13 * {@code Statement}
45.14 * @since 1.7
46.1 --- a/src/share/classes/java/util/Locale.java Tue Oct 12 13:34:59 2010 -0400
46.2 +++ b/src/share/classes/java/util/Locale.java Mon Oct 18 11:25:28 2010 -0400
46.3 @@ -569,6 +569,9 @@
46.4 * @exception NullPointerException thrown if any argument is null.
46.5 */
46.6 public Locale(String language, String country, String variant) {
46.7 + if (language== null || country == null || variant == null) {
46.8 + throw new NullPointerException();
46.9 + }
46.10 _baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), "", country, variant);
46.11 _extensions = getCompatibilityExtensions(language, "", country, variant);
46.12 }
47.1 --- a/src/share/classes/java/util/ResourceBundle.java Tue Oct 12 13:34:59 2010 -0400
47.2 +++ b/src/share/classes/java/util/ResourceBundle.java Mon Oct 18 11:25:28 2010 -0400
47.3 @@ -293,16 +293,6 @@
47.4 = new ConcurrentHashMap<CacheKey, BundleReference>(INITIAL_CACHE_SIZE);
47.5
47.6 /**
47.7 - * This ConcurrentMap is used to keep multiple threads from loading the
47.8 - * same bundle concurrently. The table entries are <CacheKey, Thread>
47.9 - * where CacheKey is the key for the bundle that is under construction
47.10 - * and Thread is the thread that is constructing the bundle.
47.11 - * This list is manipulated in findBundleInCache and putBundleInCache.
47.12 - */
47.13 - private static final ConcurrentMap<CacheKey, Thread> underConstruction
47.14 - = new ConcurrentHashMap<CacheKey, Thread>();
47.15 -
47.16 - /**
47.17 * Queue for reference objects referring to class loaders or bundles.
47.18 */
47.19 private static final ReferenceQueue referenceQueue = new ReferenceQueue();
47.20 @@ -1381,7 +1371,7 @@
47.21 boolean expiredBundle = false;
47.22
47.23 // First, look up the cache to see if it's in the cache, without
47.24 - // declaring beginLoading.
47.25 + // attempting to load bundle.
47.26 cacheKey.setLocale(targetLocale);
47.27 ResourceBundle bundle = findBundleInCache(cacheKey, control);
47.28 if (isValidBundle(bundle)) {
47.29 @@ -1408,56 +1398,25 @@
47.30 CacheKey constKey = (CacheKey) cacheKey.clone();
47.31
47.32 try {
47.33 - // Try declaring loading. If beginLoading() returns true,
47.34 - // then we can proceed. Otherwise, we need to take a look
47.35 - // at the cache again to see if someone else has loaded
47.36 - // the bundle and put it in the cache while we've been
47.37 - // waiting for other loading work to complete.
47.38 - while (!beginLoading(constKey)) {
47.39 - bundle = findBundleInCache(cacheKey, control);
47.40 - if (bundle == null) {
47.41 - continue;
47.42 + bundle = loadBundle(cacheKey, formats, control, expiredBundle);
47.43 + if (bundle != null) {
47.44 + if (bundle.parent == null) {
47.45 + bundle.setParent(parent);
47.46 }
47.47 - if (bundle == NONEXISTENT_BUNDLE) {
47.48 - // If the bundle is NONEXISTENT_BUNDLE, the bundle doesn't exist.
47.49 - return parent;
47.50 - }
47.51 - expiredBundle = bundle.expired;
47.52 - if (!expiredBundle) {
47.53 - if (bundle.parent == parent) {
47.54 - return bundle;
47.55 - }
47.56 - BundleReference bundleRef = cacheList.get(cacheKey);
47.57 - if (bundleRef != null && bundleRef.get() == bundle) {
47.58 - cacheList.remove(cacheKey, bundleRef);
47.59 - }
47.60 - }
47.61 + bundle.locale = targetLocale;
47.62 + bundle = putBundleInCache(cacheKey, bundle, control);
47.63 + return bundle;
47.64 }
47.65
47.66 - try {
47.67 - bundle = loadBundle(cacheKey, formats, control, expiredBundle);
47.68 - if (bundle != null) {
47.69 - if (bundle.parent == null) {
47.70 - bundle.setParent(parent);
47.71 - }
47.72 - bundle.locale = targetLocale;
47.73 - bundle = putBundleInCache(cacheKey, bundle, control);
47.74 - return bundle;
47.75 - }
47.76 -
47.77 - // Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle
47.78 - // instance for the locale.
47.79 - putBundleInCache(cacheKey, NONEXISTENT_BUNDLE, control);
47.80 - } finally {
47.81 - endLoading(constKey);
47.82 - }
47.83 + // Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle
47.84 + // instance for the locale.
47.85 + putBundleInCache(cacheKey, NONEXISTENT_BUNDLE, control);
47.86 } finally {
47.87 if (constKey.getCause() instanceof InterruptedException) {
47.88 Thread.currentThread().interrupt();
47.89 }
47.90 }
47.91 }
47.92 - assert underConstruction.get(cacheKey) != Thread.currentThread();
47.93 return parent;
47.94 }
47.95
47.96 @@ -1465,7 +1424,6 @@
47.97 List<String> formats,
47.98 Control control,
47.99 boolean reload) {
47.100 - assert underConstruction.get(cacheKey) == Thread.currentThread();
47.101
47.102 // Here we actually load the bundle in the order of formats
47.103 // specified by the getFormats() value.
47.104 @@ -1498,7 +1456,6 @@
47.105 break;
47.106 }
47.107 }
47.108 - assert underConstruction.get(cacheKey) == Thread.currentThread();
47.109
47.110 return bundle;
47.111 }
47.112 @@ -1530,57 +1487,6 @@
47.113 }
47.114
47.115 /**
47.116 - * Declares the beginning of actual resource bundle loading. This method
47.117 - * returns true if the declaration is successful and the current thread has
47.118 - * been put in underConstruction. If someone else has already begun
47.119 - * loading, this method waits until that loading work is complete and
47.120 - * returns false.
47.121 - */
47.122 - private static final boolean beginLoading(CacheKey constKey) {
47.123 - Thread me = Thread.currentThread();
47.124 - Thread worker;
47.125 - // We need to declare by putting the current Thread (me) to
47.126 - // underConstruction that we are working on loading the specified
47.127 - // resource bundle. If we are already working the loading, it means
47.128 - // that the resource loading requires a recursive call. In that case,
47.129 - // we have to proceed. (4300693)
47.130 - if (((worker = underConstruction.putIfAbsent(constKey, me)) == null)
47.131 - || worker == me) {
47.132 - return true;
47.133 - }
47.134 -
47.135 - // If someone else is working on the loading, wait until
47.136 - // the Thread finishes the bundle loading.
47.137 - synchronized (worker) {
47.138 - while (underConstruction.get(constKey) == worker) {
47.139 - try {
47.140 - worker.wait();
47.141 - } catch (InterruptedException e) {
47.142 - // record the interruption
47.143 - constKey.setCause(e);
47.144 - }
47.145 - }
47.146 - }
47.147 - return false;
47.148 - }
47.149 -
47.150 - /**
47.151 - * Declares the end of the bundle loading. This method calls notifyAll
47.152 - * for those who are waiting for this completion.
47.153 - */
47.154 - private static final void endLoading(CacheKey constKey) {
47.155 - // Remove this Thread from the underConstruction map and wake up
47.156 - // those who have been waiting for me to complete this bundle
47.157 - // loading.
47.158 - Thread me = Thread.currentThread();
47.159 - assert (underConstruction.get(constKey) == me);
47.160 - underConstruction.remove(constKey);
47.161 - synchronized (me) {
47.162 - me.notifyAll();
47.163 - }
47.164 - }
47.165 -
47.166 - /**
47.167 * Throw a MissingResourceException with proper message
47.168 */
47.169 private static final void throwMissingResourceException(String baseName,
48.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
48.2 +++ b/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java Mon Oct 18 11:25:28 2010 -0400
48.3 @@ -0,0 +1,1445 @@
48.4 +/*
48.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
48.6 + *
48.7 + * This code is free software; you can redistribute it and/or modify it
48.8 + * under the terms of the GNU General Public License version 2 only, as
48.9 + * published by the Free Software Foundation. Oracle designates this
48.10 + * particular file as subject to the "Classpath" exception as provided
48.11 + * by Oracle in the LICENSE file that accompanied this code.
48.12 + *
48.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
48.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
48.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
48.16 + * version 2 for more details (a copy is included in the LICENSE file that
48.17 + * accompanied this code).
48.18 + *
48.19 + * You should have received a copy of the GNU General Public License version
48.20 + * 2 along with this work; if not, write to the Free Software Foundation,
48.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
48.22 + *
48.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
48.24 + * or visit www.oracle.com if you need additional information or have any
48.25 + * questions.
48.26 + */
48.27 +
48.28 +/*
48.29 + * This file is available under and governed by the GNU General Public
48.30 + * License version 2 only, as published by the Free Software Foundation.
48.31 + * However, the following notice accompanied the original version of this
48.32 + * file:
48.33 + *
48.34 + * Written by Doug Lea and Martin Buchholz with assistance from members of
48.35 + * JCP JSR-166 Expert Group and released to the public domain, as explained
48.36 + * at http://creativecommons.org/licenses/publicdomain
48.37 + */
48.38 +
48.39 +package java.util.concurrent;
48.40 +
48.41 +import java.util.AbstractCollection;
48.42 +import java.util.ArrayList;
48.43 +import java.util.Collection;
48.44 +import java.util.ConcurrentModificationException;
48.45 +import java.util.Deque;
48.46 +import java.util.Iterator;
48.47 +import java.util.NoSuchElementException;
48.48 +import java.util.Queue;
48.49 +
48.50 +/**
48.51 + * An unbounded concurrent {@linkplain Deque deque} based on linked nodes.
48.52 + * Concurrent insertion, removal, and access operations execute safely
48.53 + * across multiple threads.
48.54 + * A {@code ConcurrentLinkedDeque} is an appropriate choice when
48.55 + * many threads will share access to a common collection.
48.56 + * Like most other concurrent collection implementations, this class
48.57 + * does not permit the use of {@code null} elements.
48.58 + *
48.59 + * <p>Iterators are <i>weakly consistent</i>, returning elements
48.60 + * reflecting the state of the deque at some point at or since the
48.61 + * creation of the iterator. They do <em>not</em> throw {@link
48.62 + * java.util.ConcurrentModificationException
48.63 + * ConcurrentModificationException}, and may proceed concurrently with
48.64 + * other operations.
48.65 + *
48.66 + * <p>Beware that, unlike in most collections, the {@code size}
48.67 + * method is <em>NOT</em> a constant-time operation. Because of the
48.68 + * asynchronous nature of these deques, determining the current number
48.69 + * of elements requires a traversal of the elements.
48.70 + *
48.71 + * <p>This class and its iterator implement all of the <em>optional</em>
48.72 + * methods of the {@link Deque} and {@link Iterator} interfaces.
48.73 + *
48.74 + * <p>Memory consistency effects: As with other concurrent collections,
48.75 + * actions in a thread prior to placing an object into a
48.76 + * {@code ConcurrentLinkedDeque}
48.77 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
48.78 + * actions subsequent to the access or removal of that element from
48.79 + * the {@code ConcurrentLinkedDeque} in another thread.
48.80 + *
48.81 + * <p>This class is a member of the
48.82 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
48.83 + * Java Collections Framework</a>.
48.84 + *
48.85 + * @since 1.7
48.86 + * @author Doug Lea
48.87 + * @author Martin Buchholz
48.88 + * @param <E> the type of elements held in this collection
48.89 + */
48.90 +
48.91 +public class ConcurrentLinkedDeque<E>
48.92 + extends AbstractCollection<E>
48.93 + implements Deque<E>, java.io.Serializable {
48.94 +
48.95 + /*
48.96 + * This is an implementation of a concurrent lock-free deque
48.97 + * supporting interior removes but not interior insertions, as
48.98 + * required to support the entire Deque interface.
48.99 + *
48.100 + * We extend the techniques developed for ConcurrentLinkedQueue and
48.101 + * LinkedTransferQueue (see the internal docs for those classes).
48.102 + * Understanding the ConcurrentLinkedQueue implementation is a
48.103 + * prerequisite for understanding the implementation of this class.
48.104 + *
48.105 + * The data structure is a symmetrical doubly-linked "GC-robust"
48.106 + * linked list of nodes. We minimize the number of volatile writes
48.107 + * using two techniques: advancing multiple hops with a single CAS
48.108 + * and mixing volatile and non-volatile writes of the same memory
48.109 + * locations.
48.110 + *
48.111 + * A node contains the expected E ("item") and links to predecessor
48.112 + * ("prev") and successor ("next") nodes:
48.113 + *
48.114 + * class Node<E> { volatile Node<E> prev, next; volatile E item; }
48.115 + *
48.116 + * A node p is considered "live" if it contains a non-null item
48.117 + * (p.item != null). When an item is CASed to null, the item is
48.118 + * atomically logically deleted from the collection.
48.119 + *
48.120 + * At any time, there is precisely one "first" node with a null
48.121 + * prev reference that terminates any chain of prev references
48.122 + * starting at a live node. Similarly there is precisely one
48.123 + * "last" node terminating any chain of next references starting at
48.124 + * a live node. The "first" and "last" nodes may or may not be live.
48.125 + * The "first" and "last" nodes are always mutually reachable.
48.126 + *
48.127 + * A new element is added atomically by CASing the null prev or
48.128 + * next reference in the first or last node to a fresh node
48.129 + * containing the element. The element's node atomically becomes
48.130 + * "live" at that point.
48.131 + *
48.132 + * A node is considered "active" if it is a live node, or the
48.133 + * first or last node. Active nodes cannot be unlinked.
48.134 + *
48.135 + * A "self-link" is a next or prev reference that is the same node:
48.136 + * p.prev == p or p.next == p
48.137 + * Self-links are used in the node unlinking process. Active nodes
48.138 + * never have self-links.
48.139 + *
48.140 + * A node p is active if and only if:
48.141 + *
48.142 + * p.item != null ||
48.143 + * (p.prev == null && p.next != p) ||
48.144 + * (p.next == null && p.prev != p)
48.145 + *
48.146 + * The deque object has two node references, "head" and "tail".
48.147 + * The head and tail are only approximations to the first and last
48.148 + * nodes of the deque. The first node can always be found by
48.149 + * following prev pointers from head; likewise for tail. However,
48.150 + * it is permissible for head and tail to be referring to deleted
48.151 + * nodes that have been unlinked and so may not be reachable from
48.152 + * any live node.
48.153 + *
48.154 + * There are 3 stages of node deletion;
48.155 + * "logical deletion", "unlinking", and "gc-unlinking".
48.156 + *
48.157 + * 1. "logical deletion" by CASing item to null atomically removes
48.158 + * the element from the collection, and makes the containing node
48.159 + * eligible for unlinking.
48.160 + *
48.161 + * 2. "unlinking" makes a deleted node unreachable from active
48.162 + * nodes, and thus eventually reclaimable by GC. Unlinked nodes
48.163 + * may remain reachable indefinitely from an iterator.
48.164 + *
48.165 + * Physical node unlinking is merely an optimization (albeit a
48.166 + * critical one), and so can be performed at our convenience. At
48.167 + * any time, the set of live nodes maintained by prev and next
48.168 + * links are identical, that is, the live nodes found via next
48.169 + * links from the first node is equal to the elements found via
48.170 + * prev links from the last node. However, this is not true for
48.171 + * nodes that have already been logically deleted - such nodes may
48.172 + * be reachable in one direction only.
48.173 + *
48.174 + * 3. "gc-unlinking" takes unlinking further by making active
48.175 + * nodes unreachable from deleted nodes, making it easier for the
48.176 + * GC to reclaim future deleted nodes. This step makes the data
48.177 + * structure "gc-robust", as first described in detail by Boehm
48.178 + * (http://portal.acm.org/citation.cfm?doid=503272.503282).
48.179 + *
48.180 + * GC-unlinked nodes may remain reachable indefinitely from an
48.181 + * iterator, but unlike unlinked nodes, are never reachable from
48.182 + * head or tail.
48.183 + *
48.184 + * Making the data structure GC-robust will eliminate the risk of
48.185 + * unbounded memory retention with conservative GCs and is likely
48.186 + * to improve performance with generational GCs.
48.187 + *
48.188 + * When a node is dequeued at either end, e.g. via poll(), we would
48.189 + * like to break any references from the node to active nodes. We
48.190 + * develop further the use of self-links that was very effective in
48.191 + * other concurrent collection classes. The idea is to replace
48.192 + * prev and next pointers with special values that are interpreted
48.193 + * to mean off-the-list-at-one-end. These are approximations, but
48.194 + * good enough to preserve the properties we want in our
48.195 + * traversals, e.g. we guarantee that a traversal will never visit
48.196 + * the same element twice, but we don't guarantee whether a
48.197 + * traversal that runs out of elements will be able to see more
48.198 + * elements later after enqueues at that end. Doing gc-unlinking
48.199 + * safely is particularly tricky, since any node can be in use
48.200 + * indefinitely (for example by an iterator). We must ensure that
48.201 + * the nodes pointed at by head/tail never get gc-unlinked, since
48.202 + * head/tail are needed to get "back on track" by other nodes that
48.203 + * are gc-unlinked. gc-unlinking accounts for much of the
48.204 + * implementation complexity.
48.205 + *
48.206 + * Since neither unlinking nor gc-unlinking are necessary for
48.207 + * correctness, there are many implementation choices regarding
48.208 + * frequency (eagerness) of these operations. Since volatile
48.209 + * reads are likely to be much cheaper than CASes, saving CASes by
48.210 + * unlinking multiple adjacent nodes at a time may be a win.
48.211 + * gc-unlinking can be performed rarely and still be effective,
48.212 + * since it is most important that long chains of deleted nodes
48.213 + * are occasionally broken.
48.214 + *
48.215 + * The actual representation we use is that p.next == p means to
48.216 + * goto the first node (which in turn is reached by following prev
48.217 + * pointers from head), and p.next == null && p.prev == p means
48.218 + * that the iteration is at an end and that p is a (final static)
48.219 + * dummy node, NEXT_TERMINATOR, and not the last active node.
48.220 + * Finishing the iteration when encountering such a TERMINATOR is
48.221 + * good enough for read-only traversals, so such traversals can use
48.222 + * p.next == null as the termination condition. When we need to
48.223 + * find the last (active) node, for enqueueing a new node, we need
48.224 + * to check whether we have reached a TERMINATOR node; if so,
48.225 + * restart traversal from tail.
48.226 + *
48.227 + * The implementation is completely directionally symmetrical,
48.228 + * except that most public methods that iterate through the list
48.229 + * follow next pointers ("forward" direction).
48.230 + *
48.231 + * We believe (without full proof) that all single-element deque
48.232 + * operations (e.g., addFirst, peekLast, pollLast) are linearizable
48.233 + * (see Herlihy and Shavit's book). However, some combinations of
48.234 + * operations are known not to be linearizable. In particular,
48.235 + * when an addFirst(A) is racing with pollFirst() removing B, it is
48.236 + * possible for an observer iterating over the elements to observe
48.237 + * A B C and subsequently observe A C, even though no interior
48.238 + * removes are ever performed. Nevertheless, iterators behave
48.239 + * reasonably, providing the "weakly consistent" guarantees.
48.240 + *
48.241 + * Empirically, microbenchmarks suggest that this class adds about
48.242 + * 40% overhead relative to ConcurrentLinkedQueue, which feels as
48.243 + * good as we can hope for.
48.244 + */
48.245 +
48.246 + private static final long serialVersionUID = 876323262645176354L;
48.247 +
48.248 + /**
48.249 + * A node from which the first node on list (that is, the unique node p
48.250 + * with p.prev == null && p.next != p) can be reached in O(1) time.
48.251 + * Invariants:
48.252 + * - the first node is always O(1) reachable from head via prev links
48.253 + * - all live nodes are reachable from the first node via succ()
48.254 + * - head != null
48.255 + * - (tmp = head).next != tmp || tmp != head
48.256 + * - head is never gc-unlinked (but may be unlinked)
48.257 + * Non-invariants:
48.258 + * - head.item may or may not be null
48.259 + * - head may not be reachable from the first or last node, or from tail
48.260 + */
48.261 + private transient volatile Node<E> head;
48.262 +
48.263 + /**
48.264 + * A node from which the last node on list (that is, the unique node p
48.265 + * with p.next == null && p.prev != p) can be reached in O(1) time.
48.266 + * Invariants:
48.267 + * - the last node is always O(1) reachable from tail via next links
48.268 + * - all live nodes are reachable from the last node via pred()
48.269 + * - tail != null
48.270 + * - tail is never gc-unlinked (but may be unlinked)
48.271 + * Non-invariants:
48.272 + * - tail.item may or may not be null
48.273 + * - tail may not be reachable from the first or last node, or from head
48.274 + */
48.275 + private transient volatile Node<E> tail;
48.276 +
48.277 + private final static Node<Object> PREV_TERMINATOR, NEXT_TERMINATOR;
48.278 +
48.279 + static {
48.280 + PREV_TERMINATOR = new Node<Object>(null);
48.281 + PREV_TERMINATOR.next = PREV_TERMINATOR;
48.282 + NEXT_TERMINATOR = new Node<Object>(null);
48.283 + NEXT_TERMINATOR.prev = NEXT_TERMINATOR;
48.284 + }
48.285 +
48.286 + @SuppressWarnings("unchecked")
48.287 + Node<E> prevTerminator() {
48.288 + return (Node<E>) PREV_TERMINATOR;
48.289 + }
48.290 +
48.291 + @SuppressWarnings("unchecked")
48.292 + Node<E> nextTerminator() {
48.293 + return (Node<E>) NEXT_TERMINATOR;
48.294 + }
48.295 +
48.296 + static final class Node<E> {
48.297 + volatile Node<E> prev;
48.298 + volatile E item;
48.299 + volatile Node<E> next;
48.300 +
48.301 + /**
48.302 + * Constructs a new node. Uses relaxed write because item can
48.303 + * only be seen after publication via casNext or casPrev.
48.304 + */
48.305 + Node(E item) {
48.306 + UNSAFE.putObject(this, itemOffset, item);
48.307 + }
48.308 +
48.309 + boolean casItem(E cmp, E val) {
48.310 + return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
48.311 + }
48.312 +
48.313 + void lazySetNext(Node<E> val) {
48.314 + UNSAFE.putOrderedObject(this, nextOffset, val);
48.315 + }
48.316 +
48.317 + boolean casNext(Node<E> cmp, Node<E> val) {
48.318 + return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
48.319 + }
48.320 +
48.321 + void lazySetPrev(Node<E> val) {
48.322 + UNSAFE.putOrderedObject(this, prevOffset, val);
48.323 + }
48.324 +
48.325 + boolean casPrev(Node<E> cmp, Node<E> val) {
48.326 + return UNSAFE.compareAndSwapObject(this, prevOffset, cmp, val);
48.327 + }
48.328 +
48.329 + // Unsafe mechanics
48.330 +
48.331 + private static final sun.misc.Unsafe UNSAFE =
48.332 + sun.misc.Unsafe.getUnsafe();
48.333 + private static final long prevOffset =
48.334 + objectFieldOffset(UNSAFE, "prev", Node.class);
48.335 + private static final long itemOffset =
48.336 + objectFieldOffset(UNSAFE, "item", Node.class);
48.337 + private static final long nextOffset =
48.338 + objectFieldOffset(UNSAFE, "next", Node.class);
48.339 + }
48.340 +
48.341 + /**
48.342 + * Links e as first element.
48.343 + */
48.344 + private void linkFirst(E e) {
48.345 + checkNotNull(e);
48.346 + final Node<E> newNode = new Node<E>(e);
48.347 +
48.348 + restartFromHead:
48.349 + for (;;)
48.350 + for (Node<E> h = head, p = h, q;;) {
48.351 + if ((q = p.prev) != null &&
48.352 + (q = (p = q).prev) != null)
48.353 + // Check for head updates every other hop.
48.354 + // If p == q, we are sure to follow head instead.
48.355 + p = (h != (h = head)) ? h : q;
48.356 + else if (p.next == p) // PREV_TERMINATOR
48.357 + continue restartFromHead;
48.358 + else {
48.359 + // p is first node
48.360 + newNode.lazySetNext(p); // CAS piggyback
48.361 + if (p.casPrev(null, newNode)) {
48.362 + // Successful CAS is the linearization point
48.363 + // for e to become an element of this deque,
48.364 + // and for newNode to become "live".
48.365 + if (p != h) // hop two nodes at a time
48.366 + casHead(h, newNode); // Failure is OK.
48.367 + return;
48.368 + }
48.369 + // Lost CAS race to another thread; re-read prev
48.370 + }
48.371 + }
48.372 + }
48.373 +
48.374 + /**
48.375 + * Links e as last element.
48.376 + */
48.377 + private void linkLast(E e) {
48.378 + checkNotNull(e);
48.379 + final Node<E> newNode = new Node<E>(e);
48.380 +
48.381 + restartFromTail:
48.382 + for (;;)
48.383 + for (Node<E> t = tail, p = t, q;;) {
48.384 + if ((q = p.next) != null &&
48.385 + (q = (p = q).next) != null)
48.386 + // Check for tail updates every other hop.
48.387 + // If p == q, we are sure to follow tail instead.
48.388 + p = (t != (t = tail)) ? t : q;
48.389 + else if (p.prev == p) // NEXT_TERMINATOR
48.390 + continue restartFromTail;
48.391 + else {
48.392 + // p is last node
48.393 + newNode.lazySetPrev(p); // CAS piggyback
48.394 + if (p.casNext(null, newNode)) {
48.395 + // Successful CAS is the linearization point
48.396 + // for e to become an element of this deque,
48.397 + // and for newNode to become "live".
48.398 + if (p != t) // hop two nodes at a time
48.399 + casTail(t, newNode); // Failure is OK.
48.400 + return;
48.401 + }
48.402 + // Lost CAS race to another thread; re-read next
48.403 + }
48.404 + }
48.405 + }
48.406 +
48.407 + private final static int HOPS = 2;
48.408 +
48.409 + /**
48.410 + * Unlinks non-null node x.
48.411 + */
48.412 + void unlink(Node<E> x) {
48.413 + // assert x != null;
48.414 + // assert x.item == null;
48.415 + // assert x != PREV_TERMINATOR;
48.416 + // assert x != NEXT_TERMINATOR;
48.417 +
48.418 + final Node<E> prev = x.prev;
48.419 + final Node<E> next = x.next;
48.420 + if (prev == null) {
48.421 + unlinkFirst(x, next);
48.422 + } else if (next == null) {
48.423 + unlinkLast(x, prev);
48.424 + } else {
48.425 + // Unlink interior node.
48.426 + //
48.427 + // This is the common case, since a series of polls at the
48.428 + // same end will be "interior" removes, except perhaps for
48.429 + // the first one, since end nodes cannot be unlinked.
48.430 + //
48.431 + // At any time, all active nodes are mutually reachable by
48.432 + // following a sequence of either next or prev pointers.
48.433 + //
48.434 + // Our strategy is to find the unique active predecessor
48.435 + // and successor of x. Try to fix up their links so that
48.436 + // they point to each other, leaving x unreachable from
48.437 + // active nodes. If successful, and if x has no live
48.438 + // predecessor/successor, we additionally try to gc-unlink,
48.439 + // leaving active nodes unreachable from x, by rechecking
48.440 + // that the status of predecessor and successor are
48.441 + // unchanged and ensuring that x is not reachable from
48.442 + // tail/head, before setting x's prev/next links to their
48.443 + // logical approximate replacements, self/TERMINATOR.
48.444 + Node<E> activePred, activeSucc;
48.445 + boolean isFirst, isLast;
48.446 + int hops = 1;
48.447 +
48.448 + // Find active predecessor
48.449 + for (Node<E> p = prev; ; ++hops) {
48.450 + if (p.item != null) {
48.451 + activePred = p;
48.452 + isFirst = false;
48.453 + break;
48.454 + }
48.455 + Node<E> q = p.prev;
48.456 + if (q == null) {
48.457 + if (p.next == p)
48.458 + return;
48.459 + activePred = p;
48.460 + isFirst = true;
48.461 + break;
48.462 + }
48.463 + else if (p == q)
48.464 + return;
48.465 + else
48.466 + p = q;
48.467 + }
48.468 +
48.469 + // Find active successor
48.470 + for (Node<E> p = next; ; ++hops) {
48.471 + if (p.item != null) {
48.472 + activeSucc = p;
48.473 + isLast = false;
48.474 + break;
48.475 + }
48.476 + Node<E> q = p.next;
48.477 + if (q == null) {
48.478 + if (p.prev == p)
48.479 + return;
48.480 + activeSucc = p;
48.481 + isLast = true;
48.482 + break;
48.483 + }
48.484 + else if (p == q)
48.485 + return;
48.486 + else
48.487 + p = q;
48.488 + }
48.489 +
48.490 + // TODO: better HOP heuristics
48.491 + if (hops < HOPS
48.492 + // always squeeze out interior deleted nodes
48.493 + && (isFirst | isLast))
48.494 + return;
48.495 +
48.496 + // Squeeze out deleted nodes between activePred and
48.497 + // activeSucc, including x.
48.498 + skipDeletedSuccessors(activePred);
48.499 + skipDeletedPredecessors(activeSucc);
48.500 +
48.501 + // Try to gc-unlink, if possible
48.502 + if ((isFirst | isLast) &&
48.503 +
48.504 + // Recheck expected state of predecessor and successor
48.505 + (activePred.next == activeSucc) &&
48.506 + (activeSucc.prev == activePred) &&
48.507 + (isFirst ? activePred.prev == null : activePred.item != null) &&
48.508 + (isLast ? activeSucc.next == null : activeSucc.item != null)) {
48.509 +
48.510 + updateHead(); // Ensure x is not reachable from head
48.511 + updateTail(); // Ensure x is not reachable from tail
48.512 +
48.513 + // Finally, actually gc-unlink
48.514 + x.lazySetPrev(isFirst ? prevTerminator() : x);
48.515 + x.lazySetNext(isLast ? nextTerminator() : x);
48.516 + }
48.517 + }
48.518 + }
48.519 +
48.520 + /**
48.521 + * Unlinks non-null first node.
48.522 + */
48.523 + private void unlinkFirst(Node<E> first, Node<E> next) {
48.524 + // assert first != null;
48.525 + // assert next != null;
48.526 + // assert first.item == null;
48.527 + for (Node<E> o = null, p = next, q;;) {
48.528 + if (p.item != null || (q = p.next) == null) {
48.529 + if (o != null && p.prev != p && first.casNext(next, p)) {
48.530 + skipDeletedPredecessors(p);
48.531 + if (first.prev == null &&
48.532 + (p.next == null || p.item != null) &&
48.533 + p.prev == first) {
48.534 +
48.535 + updateHead(); // Ensure o is not reachable from head
48.536 + updateTail(); // Ensure o is not reachable from tail
48.537 +
48.538 + // Finally, actually gc-unlink
48.539 + o.lazySetNext(o);
48.540 + o.lazySetPrev(prevTerminator());
48.541 + }
48.542 + }
48.543 + return;
48.544 + }
48.545 + else if (p == q)
48.546 + return;
48.547 + else {
48.548 + o = p;
48.549 + p = q;
48.550 + }
48.551 + }
48.552 + }
48.553 +
48.554 + /**
48.555 + * Unlinks non-null last node.
48.556 + */
48.557 + private void unlinkLast(Node<E> last, Node<E> prev) {
48.558 + // assert last != null;
48.559 + // assert prev != null;
48.560 + // assert last.item == null;
48.561 + for (Node<E> o = null, p = prev, q;;) {
48.562 + if (p.item != null || (q = p.prev) == null) {
48.563 + if (o != null && p.next != p && last.casPrev(prev, p)) {
48.564 + skipDeletedSuccessors(p);
48.565 + if (last.next == null &&
48.566 + (p.prev == null || p.item != null) &&
48.567 + p.next == last) {
48.568 +
48.569 + updateHead(); // Ensure o is not reachable from head
48.570 + updateTail(); // Ensure o is not reachable from tail
48.571 +
48.572 + // Finally, actually gc-unlink
48.573 + o.lazySetPrev(o);
48.574 + o.lazySetNext(nextTerminator());
48.575 + }
48.576 + }
48.577 + return;
48.578 + }
48.579 + else if (p == q)
48.580 + return;
48.581 + else {
48.582 + o = p;
48.583 + p = q;
48.584 + }
48.585 + }
48.586 + }
48.587 +
48.588 + /**
48.589 + * Guarantees that any node which was unlinked before a call to
48.590 + * this method will be unreachable from head after it returns.
48.591 + * Does not guarantee to eliminate slack, only that head will
48.592 + * point to a node that was active while this method was running.
48.593 + */
48.594 + private final void updateHead() {
48.595 + // Either head already points to an active node, or we keep
48.596 + // trying to cas it to the first node until it does.
48.597 + Node<E> h, p, q;
48.598 + restartFromHead:
48.599 + while ((h = head).item == null && (p = h.prev) != null) {
48.600 + for (;;) {
48.601 + if ((q = p.prev) == null ||
48.602 + (q = (p = q).prev) == null) {
48.603 + // It is possible that p is PREV_TERMINATOR,
48.604 + // but if so, the CAS is guaranteed to fail.
48.605 + if (casHead(h, p))
48.606 + return;
48.607 + else
48.608 + continue restartFromHead;
48.609 + }
48.610 + else if (h != head)
48.611 + continue restartFromHead;
48.612 + else
48.613 + p = q;
48.614 + }
48.615 + }
48.616 + }
48.617 +
48.618 + /**
48.619 + * Guarantees that any node which was unlinked before a call to
48.620 + * this method will be unreachable from tail after it returns.
48.621 + * Does not guarantee to eliminate slack, only that tail will
48.622 + * point to a node that was active while this method was running.
48.623 + */
48.624 + private final void updateTail() {
48.625 + // Either tail already points to an active node, or we keep
48.626 + // trying to cas it to the last node until it does.
48.627 + Node<E> t, p, q;
48.628 + restartFromTail:
48.629 + while ((t = tail).item == null && (p = t.next) != null) {
48.630 + for (;;) {
48.631 + if ((q = p.next) == null ||
48.632 + (q = (p = q).next) == null) {
48.633 + // It is possible that p is NEXT_TERMINATOR,
48.634 + // but if so, the CAS is guaranteed to fail.
48.635 + if (casTail(t, p))
48.636 + return;
48.637 + else
48.638 + continue restartFromTail;
48.639 + }
48.640 + else if (t != tail)
48.641 + continue restartFromTail;
48.642 + else
48.643 + p = q;
48.644 + }
48.645 + }
48.646 + }
48.647 +
48.648 + private void skipDeletedPredecessors(Node<E> x) {
48.649 + whileActive:
48.650 + do {
48.651 + Node<E> prev = x.prev;
48.652 + // assert prev != null;
48.653 + // assert x != NEXT_TERMINATOR;
48.654 + // assert x != PREV_TERMINATOR;
48.655 + Node<E> p = prev;
48.656 + findActive:
48.657 + for (;;) {
48.658 + if (p.item != null)
48.659 + break findActive;
48.660 + Node<E> q = p.prev;
48.661 + if (q == null) {
48.662 + if (p.next == p)
48.663 + continue whileActive;
48.664 + break findActive;
48.665 + }
48.666 + else if (p == q)
48.667 + continue whileActive;
48.668 + else
48.669 + p = q;
48.670 + }
48.671 +
48.672 + // found active CAS target
48.673 + if (prev == p || x.casPrev(prev, p))
48.674 + return;
48.675 +
48.676 + } while (x.item != null || x.next == null);
48.677 + }
48.678 +
48.679 + private void skipDeletedSuccessors(Node<E> x) {
48.680 + whileActive:
48.681 + do {
48.682 + Node<E> next = x.next;
48.683 + // assert next != null;
48.684 + // assert x != NEXT_TERMINATOR;
48.685 + // assert x != PREV_TERMINATOR;
48.686 + Node<E> p = next;
48.687 + findActive:
48.688 + for (;;) {
48.689 + if (p.item != null)
48.690 + break findActive;
48.691 + Node<E> q = p.next;
48.692 + if (q == null) {
48.693 + if (p.prev == p)
48.694 + continue whileActive;
48.695 + break findActive;
48.696 + }
48.697 + else if (p == q)
48.698 + continue whileActive;
48.699 + else
48.700 + p = q;
48.701 + }
48.702 +
48.703 + // found active CAS target
48.704 + if (next == p || x.casNext(next, p))
48.705 + return;
48.706 +
48.707 + } while (x.item != null || x.prev == null);
48.708 + }
48.709 +
48.710 + /**
48.711 + * Returns the successor of p, or the first node if p.next has been
48.712 + * linked to self, which will only be true if traversing with a
48.713 + * stale pointer that is now off the list.
48.714 + */
48.715 + final Node<E> succ(Node<E> p) {
48.716 + // TODO: should we skip deleted nodes here?
48.717 + Node<E> q = p.next;
48.718 + return (p == q) ? first() : q;
48.719 + }
48.720 +
48.721 + /**
48.722 + * Returns the predecessor of p, or the last node if p.prev has been
48.723 + * linked to self, which will only be true if traversing with a
48.724 + * stale pointer that is now off the list.
48.725 + */
48.726 + final Node<E> pred(Node<E> p) {
48.727 + Node<E> q = p.prev;
48.728 + return (p == q) ? last() : q;
48.729 + }
48.730 +
48.731 + /**
48.732 + * Returns the first node, the unique node p for which:
48.733 + * p.prev == null && p.next != p
48.734 + * The returned node may or may not be logically deleted.
48.735 + * Guarantees that head is set to the returned node.
48.736 + */
48.737 + Node<E> first() {
48.738 + restartFromHead:
48.739 + for (;;)
48.740 + for (Node<E> h = head, p = h, q;;) {
48.741 + if ((q = p.prev) != null &&
48.742 + (q = (p = q).prev) != null)
48.743 + // Check for head updates every other hop.
48.744 + // If p == q, we are sure to follow head instead.
48.745 + p = (h != (h = head)) ? h : q;
48.746 + else if (p == h
48.747 + // It is possible that p is PREV_TERMINATOR,
48.748 + // but if so, the CAS is guaranteed to fail.
48.749 + || casHead(h, p))
48.750 + return p;
48.751 + else
48.752 + continue restartFromHead;
48.753 + }
48.754 + }
48.755 +
48.756 + /**
48.757 + * Returns the last node, the unique node p for which:
48.758 + * p.next == null && p.prev != p
48.759 + * The returned node may or may not be logically deleted.
48.760 + * Guarantees that tail is set to the returned node.
48.761 + */
48.762 + Node<E> last() {
48.763 + restartFromTail:
48.764 + for (;;)
48.765 + for (Node<E> t = tail, p = t, q;;) {
48.766 + if ((q = p.next) != null &&
48.767 + (q = (p = q).next) != null)
48.768 + // Check for tail updates every other hop.
48.769 + // If p == q, we are sure to follow tail instead.
48.770 + p = (t != (t = tail)) ? t : q;
48.771 + else if (p == t
48.772 + // It is possible that p is NEXT_TERMINATOR,
48.773 + // but if so, the CAS is guaranteed to fail.
48.774 + || casTail(t, p))
48.775 + return p;
48.776 + else
48.777 + continue restartFromTail;
48.778 + }
48.779 + }
48.780 +
48.781 + // Minor convenience utilities
48.782 +
48.783 + /**
48.784 + * Throws NullPointerException if argument is null.
48.785 + *
48.786 + * @param v the element
48.787 + */
48.788 + private static void checkNotNull(Object v) {
48.789 + if (v == null)
48.790 + throw new NullPointerException();
48.791 + }
48.792 +
48.793 + /**
48.794 + * Returns element unless it is null, in which case throws
48.795 + * NoSuchElementException.
48.796 + *
48.797 + * @param v the element
48.798 + * @return the element
48.799 + */
48.800 + private E screenNullResult(E v) {
48.801 + if (v == null)
48.802 + throw new NoSuchElementException();
48.803 + return v;
48.804 + }
48.805 +
48.806 + /**
48.807 + * Creates an array list and fills it with elements of this list.
48.808 + * Used by toArray.
48.809 + *
48.810 + * @return the arrayList
48.811 + */
48.812 + private ArrayList<E> toArrayList() {
48.813 + ArrayList<E> list = new ArrayList<E>();
48.814 + for (Node<E> p = first(); p != null; p = succ(p)) {
48.815 + E item = p.item;
48.816 + if (item != null)
48.817 + list.add(item);
48.818 + }
48.819 + return list;
48.820 + }
48.821 +
48.822 + /**
48.823 + * Constructs an empty deque.
48.824 + */
48.825 + public ConcurrentLinkedDeque() {
48.826 + head = tail = new Node<E>(null);
48.827 + }
48.828 +
48.829 + /**
48.830 + * Constructs a deque initially containing the elements of
48.831 + * the given collection, added in traversal order of the
48.832 + * collection's iterator.
48.833 + *
48.834 + * @param c the collection of elements to initially contain
48.835 + * @throws NullPointerException if the specified collection or any
48.836 + * of its elements are null
48.837 + */
48.838 + public ConcurrentLinkedDeque(Collection<? extends E> c) {
48.839 + // Copy c into a private chain of Nodes
48.840 + Node<E> h = null, t = null;
48.841 + for (E e : c) {
48.842 + checkNotNull(e);
48.843 + Node<E> newNode = new Node<E>(e);
48.844 + if (h == null)
48.845 + h = t = newNode;
48.846 + else {
48.847 + t.lazySetNext(newNode);
48.848 + newNode.lazySetPrev(t);
48.849 + t = newNode;
48.850 + }
48.851 + }
48.852 + initHeadTail(h, t);
48.853 + }
48.854 +
48.855 + /**
48.856 + * Initializes head and tail, ensuring invariants hold.
48.857 + */
48.858 + private void initHeadTail(Node<E> h, Node<E> t) {
48.859 + if (h == t) {
48.860 + if (h == null)
48.861 + h = t = new Node<E>(null);
48.862 + else {
48.863 + // Avoid edge case of a single Node with non-null item.
48.864 + Node<E> newNode = new Node<E>(null);
48.865 + t.lazySetNext(newNode);
48.866 + newNode.lazySetPrev(t);
48.867 + t = newNode;
48.868 + }
48.869 + }
48.870 + head = h;
48.871 + tail = t;
48.872 + }
48.873 +
48.874 + /**
48.875 + * Inserts the specified element at the front of this deque.
48.876 + *
48.877 + * @throws NullPointerException {@inheritDoc}
48.878 + */
48.879 + public void addFirst(E e) {
48.880 + linkFirst(e);
48.881 + }
48.882 +
48.883 + /**
48.884 + * Inserts the specified element at the end of this deque.
48.885 + *
48.886 + * <p>This method is equivalent to {@link #add}.
48.887 + *
48.888 + * @throws NullPointerException {@inheritDoc}
48.889 + */
48.890 + public void addLast(E e) {
48.891 + linkLast(e);
48.892 + }
48.893 +
48.894 + /**
48.895 + * Inserts the specified element at the front of this deque.
48.896 + *
48.897 + * @return {@code true} always
48.898 + * @throws NullPointerException {@inheritDoc}
48.899 + */
48.900 + public boolean offerFirst(E e) {
48.901 + linkFirst(e);
48.902 + return true;
48.903 + }
48.904 +
48.905 + /**
48.906 + * Inserts the specified element at the end of this deque.
48.907 + *
48.908 + * <p>This method is equivalent to {@link #add}.
48.909 + *
48.910 + * @return {@code true} always
48.911 + * @throws NullPointerException {@inheritDoc}
48.912 + */
48.913 + public boolean offerLast(E e) {
48.914 + linkLast(e);
48.915 + return true;
48.916 + }
48.917 +
48.918 + public E peekFirst() {
48.919 + for (Node<E> p = first(); p != null; p = succ(p)) {
48.920 + E item = p.item;
48.921 + if (item != null)
48.922 + return item;
48.923 + }
48.924 + return null;
48.925 + }
48.926 +
48.927 + public E peekLast() {
48.928 + for (Node<E> p = last(); p != null; p = pred(p)) {
48.929 + E item = p.item;
48.930 + if (item != null)
48.931 + return item;
48.932 + }
48.933 + return null;
48.934 + }
48.935 +
48.936 + /**
48.937 + * @throws NoSuchElementException {@inheritDoc}
48.938 + */
48.939 + public E getFirst() {
48.940 + return screenNullResult(peekFirst());
48.941 + }
48.942 +
48.943 + /**
48.944 + * @throws NoSuchElementException {@inheritDoc}
48.945 + */
48.946 + public E getLast() {
48.947 + return screenNullResult(peekLast());
48.948 + }
48.949 +
48.950 + public E pollFirst() {
48.951 + for (Node<E> p = first(); p != null; p = succ(p)) {
48.952 + E item = p.item;
48.953 + if (item != null && p.casItem(item, null)) {
48.954 + unlink(p);
48.955 + return item;
48.956 + }
48.957 + }
48.958 + return null;
48.959 + }
48.960 +
48.961 + public E pollLast() {
48.962 + for (Node<E> p = last(); p != null; p = pred(p)) {
48.963 + E item = p.item;
48.964 + if (item != null && p.casItem(item, null)) {
48.965 + unlink(p);
48.966 + return item;
48.967 + }
48.968 + }
48.969 + return null;
48.970 + }
48.971 +
48.972 + /**
48.973 + * @throws NoSuchElementException {@inheritDoc}
48.974 + */
48.975 + public E removeFirst() {
48.976 + return screenNullResult(pollFirst());
48.977 + }
48.978 +
48.979 + /**
48.980 + * @throws NoSuchElementException {@inheritDoc}
48.981 + */
48.982 + public E removeLast() {
48.983 + return screenNullResult(pollLast());
48.984 + }
48.985 +
48.986 + // *** Queue and stack methods ***
48.987 +
48.988 + /**
48.989 + * Inserts the specified element at the tail of this deque.
48.990 + *
48.991 + * @return {@code true} (as specified by {@link Queue#offer})
48.992 + * @throws NullPointerException if the specified element is null
48.993 + */
48.994 + public boolean offer(E e) {
48.995 + return offerLast(e);
48.996 + }
48.997 +
48.998 + /**
48.999 + * Inserts the specified element at the tail of this deque.
48.1000 + *
48.1001 + * @return {@code true} (as specified by {@link Collection#add})
48.1002 + * @throws NullPointerException if the specified element is null
48.1003 + */
48.1004 + public boolean add(E e) {
48.1005 + return offerLast(e);
48.1006 + }
48.1007 +
48.1008 + public E poll() { return pollFirst(); }
48.1009 + public E remove() { return removeFirst(); }
48.1010 + public E peek() { return peekFirst(); }
48.1011 + public E element() { return getFirst(); }
48.1012 + public void push(E e) { addFirst(e); }
48.1013 + public E pop() { return removeFirst(); }
48.1014 +
48.1015 + /**
48.1016 + * Removes the first element {@code e} such that
48.1017 + * {@code o.equals(e)}, if such an element exists in this deque.
48.1018 + * If the deque does not contain the element, it is unchanged.
48.1019 + *
48.1020 + * @param o element to be removed from this deque, if present
48.1021 + * @return {@code true} if the deque contained the specified element
48.1022 + * @throws NullPointerException if the specified element is {@code null}
48.1023 + */
48.1024 + public boolean removeFirstOccurrence(Object o) {
48.1025 + checkNotNull(o);
48.1026 + for (Node<E> p = first(); p != null; p = succ(p)) {
48.1027 + E item = p.item;
48.1028 + if (item != null && o.equals(item) && p.casItem(item, null)) {
48.1029 + unlink(p);
48.1030 + return true;
48.1031 + }
48.1032 + }
48.1033 + return false;
48.1034 + }
48.1035 +
48.1036 + /**
48.1037 + * Removes the last element {@code e} such that
48.1038 + * {@code o.equals(e)}, if such an element exists in this deque.
48.1039 + * If the deque does not contain the element, it is unchanged.
48.1040 + *
48.1041 + * @param o element to be removed from this deque, if present
48.1042 + * @return {@code true} if the deque contained the specified element
48.1043 + * @throws NullPointerException if the specified element is {@code null}
48.1044 + */
48.1045 + public boolean removeLastOccurrence(Object o) {
48.1046 + checkNotNull(o);
48.1047 + for (Node<E> p = last(); p != null; p = pred(p)) {
48.1048 + E item = p.item;
48.1049 + if (item != null && o.equals(item) && p.casItem(item, null)) {
48.1050 + unlink(p);
48.1051 + return true;
48.1052 + }
48.1053 + }
48.1054 + return false;
48.1055 + }
48.1056 +
48.1057 + /**
48.1058 + * Returns {@code true} if this deque contains at least one
48.1059 + * element {@code e} such that {@code o.equals(e)}.
48.1060 + *
48.1061 + * @param o element whose presence in this deque is to be tested
48.1062 + * @return {@code true} if this deque contains the specified element
48.1063 + */
48.1064 + public boolean contains(Object o) {
48.1065 + if (o == null) return false;
48.1066 + for (Node<E> p = first(); p != null; p = succ(p)) {
48.1067 + E item = p.item;
48.1068 + if (item != null && o.equals(item))
48.1069 + return true;
48.1070 + }
48.1071 + return false;
48.1072 + }
48.1073 +
48.1074 + /**
48.1075 + * Returns {@code true} if this collection contains no elements.
48.1076 + *
48.1077 + * @return {@code true} if this collection contains no elements
48.1078 + */
48.1079 + public boolean isEmpty() {
48.1080 + return peekFirst() == null;
48.1081 + }
48.1082 +
48.1083 + /**
48.1084 + * Returns the number of elements in this deque. If this deque
48.1085 + * contains more than {@code Integer.MAX_VALUE} elements, it
48.1086 + * returns {@code Integer.MAX_VALUE}.
48.1087 + *
48.1088 + * <p>Beware that, unlike in most collections, this method is
48.1089 + * <em>NOT</em> a constant-time operation. Because of the
48.1090 + * asynchronous nature of these deques, determining the current
48.1091 + * number of elements requires traversing them all to count them.
48.1092 + * Additionally, it is possible for the size to change during
48.1093 + * execution of this method, in which case the returned result
48.1094 + * will be inaccurate. Thus, this method is typically not very
48.1095 + * useful in concurrent applications.
48.1096 + *
48.1097 + * @return the number of elements in this deque
48.1098 + */
48.1099 + public int size() {
48.1100 + int count = 0;
48.1101 + for (Node<E> p = first(); p != null; p = succ(p))
48.1102 + if (p.item != null)
48.1103 + // Collection.size() spec says to max out
48.1104 + if (++count == Integer.MAX_VALUE)
48.1105 + break;
48.1106 + return count;
48.1107 + }
48.1108 +
48.1109 + /**
48.1110 + * Removes the first element {@code e} such that
48.1111 + * {@code o.equals(e)}, if such an element exists in this deque.
48.1112 + * If the deque does not contain the element, it is unchanged.
48.1113 + *
48.1114 + * @param o element to be removed from this deque, if present
48.1115 + * @return {@code true} if the deque contained the specified element
48.1116 + * @throws NullPointerException if the specified element is {@code null}
48.1117 + */
48.1118 + public boolean remove(Object o) {
48.1119 + return removeFirstOccurrence(o);
48.1120 + }
48.1121 +
48.1122 + /**
48.1123 + * Appends all of the elements in the specified collection to the end of
48.1124 + * this deque, in the order that they are returned by the specified
48.1125 + * collection's iterator. Attempts to {@code addAll} of a deque to
48.1126 + * itself result in {@code IllegalArgumentException}.
48.1127 + *
48.1128 + * @param c the elements to be inserted into this deque
48.1129 + * @return {@code true} if this deque changed as a result of the call
48.1130 + * @throws NullPointerException if the specified collection or any
48.1131 + * of its elements are null
48.1132 + * @throws IllegalArgumentException if the collection is this deque
48.1133 + */
48.1134 + public boolean addAll(Collection<? extends E> c) {
48.1135 + if (c == this)
48.1136 + // As historically specified in AbstractQueue#addAll
48.1137 + throw new IllegalArgumentException();
48.1138 +
48.1139 + // Copy c into a private chain of Nodes
48.1140 + Node<E> beginningOfTheEnd = null, last = null;
48.1141 + for (E e : c) {
48.1142 + checkNotNull(e);
48.1143 + Node<E> newNode = new Node<E>(e);
48.1144 + if (beginningOfTheEnd == null)
48.1145 + beginningOfTheEnd = last = newNode;
48.1146 + else {
48.1147 + last.lazySetNext(newNode);
48.1148 + newNode.lazySetPrev(last);
48.1149 + last = newNode;
48.1150 + }
48.1151 + }
48.1152 + if (beginningOfTheEnd == null)
48.1153 + return false;
48.1154 +
48.1155 + // Atomically append the chain at the tail of this collection
48.1156 + restartFromTail:
48.1157 + for (;;)
48.1158 + for (Node<E> t = tail, p = t, q;;) {
48.1159 + if ((q = p.next) != null &&
48.1160 + (q = (p = q).next) != null)
48.1161 + // Check for tail updates every other hop.
48.1162 + // If p == q, we are sure to follow tail instead.
48.1163 + p = (t != (t = tail)) ? t : q;
48.1164 + else if (p.prev == p) // NEXT_TERMINATOR
48.1165 + continue restartFromTail;
48.1166 + else {
48.1167 + // p is last node
48.1168 + beginningOfTheEnd.lazySetPrev(p); // CAS piggyback
48.1169 + if (p.casNext(null, beginningOfTheEnd)) {
48.1170 + // Successful CAS is the linearization point
48.1171 + // for all elements to be added to this queue.
48.1172 + if (!casTail(t, last)) {
48.1173 + // Try a little harder to update tail,
48.1174 + // since we may be adding many elements.
48.1175 + t = tail;
48.1176 + if (last.next == null)
48.1177 + casTail(t, last);
48.1178 + }
48.1179 + return true;
48.1180 + }
48.1181 + // Lost CAS race to another thread; re-read next
48.1182 + }
48.1183 + }
48.1184 + }
48.1185 +
48.1186 + /**
48.1187 + * Removes all of the elements from this deque.
48.1188 + */
48.1189 + public void clear() {
48.1190 + while (pollFirst() != null)
48.1191 + ;
48.1192 + }
48.1193 +
48.1194 + /**
48.1195 + * Returns an array containing all of the elements in this deque, in
48.1196 + * proper sequence (from first to last element).
48.1197 + *
48.1198 + * <p>The returned array will be "safe" in that no references to it are
48.1199 + * maintained by this deque. (In other words, this method must allocate
48.1200 + * a new array). The caller is thus free to modify the returned array.
48.1201 + *
48.1202 + * <p>This method acts as bridge between array-based and collection-based
48.1203 + * APIs.
48.1204 + *
48.1205 + * @return an array containing all of the elements in this deque
48.1206 + */
48.1207 + public Object[] toArray() {
48.1208 + return toArrayList().toArray();
48.1209 + }
48.1210 +
48.1211 + /**
48.1212 + * Returns an array containing all of the elements in this deque,
48.1213 + * in proper sequence (from first to last element); the runtime
48.1214 + * type of the returned array is that of the specified array. If
48.1215 + * the deque fits in the specified array, it is returned therein.
48.1216 + * Otherwise, a new array is allocated with the runtime type of
48.1217 + * the specified array and the size of this deque.
48.1218 + *
48.1219 + * <p>If this deque fits in the specified array with room to spare
48.1220 + * (i.e., the array has more elements than this deque), the element in
48.1221 + * the array immediately following the end of the deque is set to
48.1222 + * {@code null}.
48.1223 + *
48.1224 + * <p>Like the {@link #toArray()} method, this method acts as
48.1225 + * bridge between array-based and collection-based APIs. Further,
48.1226 + * this method allows precise control over the runtime type of the
48.1227 + * output array, and may, under certain circumstances, be used to
48.1228 + * save allocation costs.
48.1229 + *
48.1230 + * <p>Suppose {@code x} is a deque known to contain only strings.
48.1231 + * The following code can be used to dump the deque into a newly
48.1232 + * allocated array of {@code String}:
48.1233 + *
48.1234 + * <pre>
48.1235 + * String[] y = x.toArray(new String[0]);</pre>
48.1236 + *
48.1237 + * Note that {@code toArray(new Object[0])} is identical in function to
48.1238 + * {@code toArray()}.
48.1239 + *
48.1240 + * @param a the array into which the elements of the deque are to
48.1241 + * be stored, if it is big enough; otherwise, a new array of the
48.1242 + * same runtime type is allocated for this purpose
48.1243 + * @return an array containing all of the elements in this deque
48.1244 + * @throws ArrayStoreException if the runtime type of the specified array
48.1245 + * is not a supertype of the runtime type of every element in
48.1246 + * this deque
48.1247 + * @throws NullPointerException if the specified array is null
48.1248 + */
48.1249 + public <T> T[] toArray(T[] a) {
48.1250 + return toArrayList().toArray(a);
48.1251 + }
48.1252 +
48.1253 + /**
48.1254 + * Returns an iterator over the elements in this deque in proper sequence.
48.1255 + * The elements will be returned in order from first (head) to last (tail).
48.1256 + *
48.1257 + * <p>The returned {@code Iterator} is a "weakly consistent" iterator that
48.1258 + * will never throw {@link java.util.ConcurrentModificationException
48.1259 + * ConcurrentModificationException},
48.1260 + * and guarantees to traverse elements as they existed upon
48.1261 + * construction of the iterator, and may (but is not guaranteed to)
48.1262 + * reflect any modifications subsequent to construction.
48.1263 + *
48.1264 + * @return an iterator over the elements in this deque in proper sequence
48.1265 + */
48.1266 + public Iterator<E> iterator() {
48.1267 + return new Itr();
48.1268 + }
48.1269 +
48.1270 + /**
48.1271 + * Returns an iterator over the elements in this deque in reverse
48.1272 + * sequential order. The elements will be returned in order from
48.1273 + * last (tail) to first (head).
48.1274 + *
48.1275 + * <p>The returned {@code Iterator} is a "weakly consistent" iterator that
48.1276 + * will never throw {@link java.util.ConcurrentModificationException
48.1277 + * ConcurrentModificationException},
48.1278 + * and guarantees to traverse elements as they existed upon
48.1279 + * construction of the iterator, and may (but is not guaranteed to)
48.1280 + * reflect any modifications subsequent to construction.
48.1281 + *
48.1282 + * @return an iterator over the elements in this deque in reverse order
48.1283 + */
48.1284 + public Iterator<E> descendingIterator() {
48.1285 + return new DescendingItr();
48.1286 + }
48.1287 +
48.1288 + private abstract class AbstractItr implements Iterator<E> {
48.1289 + /**
48.1290 + * Next node to return item for.
48.1291 + */
48.1292 + private Node<E> nextNode;
48.1293 +
48.1294 + /**
48.1295 + * nextItem holds on to item fields because once we claim
48.1296 + * that an element exists in hasNext(), we must return it in
48.1297 + * the following next() call even if it was in the process of
48.1298 + * being removed when hasNext() was called.
48.1299 + */
48.1300 + private E nextItem;
48.1301 +
48.1302 + /**
48.1303 + * Node returned by most recent call to next. Needed by remove.
48.1304 + * Reset to null if this element is deleted by a call to remove.
48.1305 + */
48.1306 + private Node<E> lastRet;
48.1307 +
48.1308 + abstract Node<E> startNode();
48.1309 + abstract Node<E> nextNode(Node<E> p);
48.1310 +
48.1311 + AbstractItr() {
48.1312 + advance();
48.1313 + }
48.1314 +
48.1315 + /**
48.1316 + * Sets nextNode and nextItem to next valid node, or to null
48.1317 + * if no such.
48.1318 + */
48.1319 + private void advance() {
48.1320 + lastRet = nextNode;
48.1321 +
48.1322 + Node<E> p = (nextNode == null) ? startNode() : nextNode(nextNode);
48.1323 + for (;; p = nextNode(p)) {
48.1324 + if (p == null) {
48.1325 + // p might be active end or TERMINATOR node; both are OK
48.1326 + nextNode = null;
48.1327 + nextItem = null;
48.1328 + break;
48.1329 + }
48.1330 + E item = p.item;
48.1331 + if (item != null) {
48.1332 + nextNode = p;
48.1333 + nextItem = item;
48.1334 + break;
48.1335 + }
48.1336 + }
48.1337 + }
48.1338 +
48.1339 + public boolean hasNext() {
48.1340 + return nextItem != null;
48.1341 + }
48.1342 +
48.1343 + public E next() {
48.1344 + E item = nextItem;
48.1345 + if (item == null) throw new NoSuchElementException();
48.1346 + advance();
48.1347 + return item;
48.1348 + }
48.1349 +
48.1350 + public void remove() {
48.1351 + Node<E> l = lastRet;
48.1352 + if (l == null) throw new IllegalStateException();
48.1353 + l.item = null;
48.1354 + unlink(l);
48.1355 + lastRet = null;
48.1356 + }
48.1357 + }
48.1358 +
48.1359 + /** Forward iterator */
48.1360 + private class Itr extends AbstractItr {
48.1361 + Node<E> startNode() { return first(); }
48.1362 + Node<E> nextNode(Node<E> p) { return succ(p); }
48.1363 + }
48.1364 +
48.1365 + /** Descending iterator */
48.1366 + private class DescendingItr extends AbstractItr {
48.1367 + Node<E> startNode() { return last(); }
48.1368 + Node<E> nextNode(Node<E> p) { return pred(p); }
48.1369 + }
48.1370 +
48.1371 + /**
48.1372 + * Saves the state to a stream (that is, serializes it).
48.1373 + *
48.1374 + * @serialData All of the elements (each an {@code E}) in
48.1375 + * the proper order, followed by a null
48.1376 + * @param s the stream
48.1377 + */
48.1378 + private void writeObject(java.io.ObjectOutputStream s)
48.1379 + throws java.io.IOException {
48.1380 +
48.1381 + // Write out any hidden stuff
48.1382 + s.defaultWriteObject();
48.1383 +
48.1384 + // Write out all elements in the proper order.
48.1385 + for (Node<E> p = first(); p != null; p = succ(p)) {
48.1386 + E item = p.item;
48.1387 + if (item != null)
48.1388 + s.writeObject(item);
48.1389 + }
48.1390 +
48.1391 + // Use trailing null as sentinel
48.1392 + s.writeObject(null);
48.1393 + }
48.1394 +
48.1395 + /**
48.1396 + * Reconstitutes the instance from a stream (that is, deserializes it).
48.1397 + * @param s the stream
48.1398 + */
48.1399 + private void readObject(java.io.ObjectInputStream s)
48.1400 + throws java.io.IOException, ClassNotFoundException {
48.1401 + s.defaultReadObject();
48.1402 +
48.1403 + // Read in elements until trailing null sentinel found
48.1404 + Node<E> h = null, t = null;
48.1405 + Object item;
48.1406 + while ((item = s.readObject()) != null) {
48.1407 + @SuppressWarnings("unchecked")
48.1408 + Node<E> newNode = new Node<E>((E) item);
48.1409 + if (h == null)
48.1410 + h = t = newNode;
48.1411 + else {
48.1412 + t.lazySetNext(newNode);
48.1413 + newNode.lazySetPrev(t);
48.1414 + t = newNode;
48.1415 + }
48.1416 + }
48.1417 + initHeadTail(h, t);
48.1418 + }
48.1419 +
48.1420 + // Unsafe mechanics
48.1421 +
48.1422 + private static final sun.misc.Unsafe UNSAFE =
48.1423 + sun.misc.Unsafe.getUnsafe();
48.1424 + private static final long headOffset =
48.1425 + objectFieldOffset(UNSAFE, "head", ConcurrentLinkedDeque.class);
48.1426 + private static final long tailOffset =
48.1427 + objectFieldOffset(UNSAFE, "tail", ConcurrentLinkedDeque.class);
48.1428 +
48.1429 + private boolean casHead(Node<E> cmp, Node<E> val) {
48.1430 + return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
48.1431 + }
48.1432 +
48.1433 + private boolean casTail(Node<E> cmp, Node<E> val) {
48.1434 + return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val);
48.1435 + }
48.1436 +
48.1437 + static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
48.1438 + String field, Class<?> klazz) {
48.1439 + try {
48.1440 + return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
48.1441 + } catch (NoSuchFieldException e) {
48.1442 + // Convert Exception to corresponding Error
48.1443 + NoSuchFieldError error = new NoSuchFieldError(field);
48.1444 + error.initCause(e);
48.1445 + throw error;
48.1446 + }
48.1447 + }
48.1448 +}
49.1 --- a/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java Tue Oct 12 13:34:59 2010 -0400
49.2 +++ b/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java Mon Oct 18 11:25:28 2010 -0400
49.3 @@ -28,9 +28,9 @@
49.4 * However, the following notice accompanied the original version of this
49.5 * file:
49.6 *
49.7 - * Written by Doug Lea with assistance from members of JCP JSR-166
49.8 - * Expert Group and released to the public domain, as explained at
49.9 - * http://creativecommons.org/licenses/publicdomain
49.10 + * Written by Doug Lea and Martin Buchholz with assistance from members of
49.11 + * JCP JSR-166 Expert Group and released to the public domain, as explained
49.12 + * at http://creativecommons.org/licenses/publicdomain
49.13 */
49.14
49.15 package java.util.concurrent;
49.16 @@ -53,7 +53,8 @@
49.17 * operations obtain elements at the head of the queue.
49.18 * A {@code ConcurrentLinkedQueue} is an appropriate choice when
49.19 * many threads will share access to a common collection.
49.20 - * This queue does not permit {@code null} elements.
49.21 + * Like most other concurrent collection implementations, this class
49.22 + * does not permit the use of {@code null} elements.
49.23 *
49.24 * <p>This implementation employs an efficient "wait-free"
49.25 * algorithm based on one described in <a
49.26 @@ -61,14 +62,20 @@
49.27 * Fast, and Practical Non-Blocking and Blocking Concurrent Queue
49.28 * Algorithms</a> by Maged M. Michael and Michael L. Scott.
49.29 *
49.30 + * <p>Iterators are <i>weakly consistent</i>, returning elements
49.31 + * reflecting the state of the queue at some point at or since the
49.32 + * creation of the iterator. They do <em>not</em> throw {@link
49.33 + * ConcurrentModificationException}, and may proceed concurrently with
49.34 + * other operations. Elements contained in the queue since the creation
49.35 + * of the iterator will be returned exactly once.
49.36 + *
49.37 * <p>Beware that, unlike in most collections, the {@code size} method
49.38 * is <em>NOT</em> a constant-time operation. Because of the
49.39 * asynchronous nature of these queues, determining the current number
49.40 * of elements requires a traversal of the elements.
49.41 *
49.42 - * <p>This class and its iterator implement all of the
49.43 - * <em>optional</em> methods of the {@link Collection} and {@link
49.44 - * Iterator} interfaces.
49.45 + * <p>This class and its iterator implement all of the <em>optional</em>
49.46 + * methods of the {@link Queue} and {@link Iterator} interfaces.
49.47 *
49.48 * <p>Memory consistency effects: As with other concurrent
49.49 * collections, actions in a thread prior to placing an object into a
49.50 @@ -132,9 +139,10 @@
49.51 *
49.52 * Both head and tail are permitted to lag. In fact, failing to
49.53 * update them every time one could is a significant optimization
49.54 - * (fewer CASes). This is controlled by local "hops" variables
49.55 - * that only trigger helping-CASes after experiencing multiple
49.56 - * lags.
49.57 + * (fewer CASes). As with LinkedTransferQueue (see the internal
49.58 + * documentation for that class), we use a slack threshold of two;
49.59 + * that is, we update head/tail when the current pointer appears
49.60 + * to be two or more steps away from the first/last node.
49.61 *
49.62 * Since head and tail are updated concurrently and independently,
49.63 * it is possible for tail to lag behind head (why not)?
49.64 @@ -148,8 +156,8 @@
49.65 * this is merely an optimization.
49.66 *
49.67 * When constructing a Node (before enqueuing it) we avoid paying
49.68 - * for a volatile write to item by using lazySet instead of a
49.69 - * normal write. This allows the cost of enqueue to be
49.70 + * for a volatile write to item by using Unsafe.putObject instead
49.71 + * of a normal write. This allows the cost of enqueue to be
49.72 * "one-and-a-half" CASes.
49.73 *
49.74 * Both head and tail may or may not point to a Node with a
49.75 @@ -161,38 +169,25 @@
49.76 */
49.77
49.78 private static class Node<E> {
49.79 - private volatile E item;
49.80 - private volatile Node<E> next;
49.81 + volatile E item;
49.82 + volatile Node<E> next;
49.83
49.84 + /**
49.85 + * Constructs a new node. Uses relaxed write because item can
49.86 + * only be seen after publication via casNext.
49.87 + */
49.88 Node(E item) {
49.89 - // Piggyback on imminent casNext()
49.90 - lazySetItem(item);
49.91 - }
49.92 -
49.93 - E getItem() {
49.94 - return item;
49.95 + UNSAFE.putObject(this, itemOffset, item);
49.96 }
49.97
49.98 boolean casItem(E cmp, E val) {
49.99 return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
49.100 }
49.101
49.102 - void setItem(E val) {
49.103 - item = val;
49.104 - }
49.105 -
49.106 - void lazySetItem(E val) {
49.107 - UNSAFE.putOrderedObject(this, itemOffset, val);
49.108 - }
49.109 -
49.110 void lazySetNext(Node<E> val) {
49.111 UNSAFE.putOrderedObject(this, nextOffset, val);
49.112 }
49.113
49.114 - Node<E> getNext() {
49.115 - return next;
49.116 - }
49.117 -
49.118 boolean casNext(Node<E> cmp, Node<E> val) {
49.119 return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
49.120 }
49.121 @@ -219,7 +214,7 @@
49.122 * - it is permitted for tail to lag behind head, that is, for tail
49.123 * to not be reachable from head!
49.124 */
49.125 - private transient volatile Node<E> head = new Node<E>(null);
49.126 + private transient volatile Node<E> head;
49.127
49.128 /**
49.129 * A node from which the last node on list (that is, the unique
49.130 @@ -233,25 +228,41 @@
49.131 * to not be reachable from head!
49.132 * - tail.next may or may not be self-pointing to tail.
49.133 */
49.134 - private transient volatile Node<E> tail = head;
49.135 + private transient volatile Node<E> tail;
49.136
49.137
49.138 /**
49.139 * Creates a {@code ConcurrentLinkedQueue} that is initially empty.
49.140 */
49.141 - public ConcurrentLinkedQueue() {}
49.142 + public ConcurrentLinkedQueue() {
49.143 + head = tail = new Node<E>(null);
49.144 + }
49.145
49.146 /**
49.147 * Creates a {@code ConcurrentLinkedQueue}
49.148 * initially containing the elements of the given collection,
49.149 * added in traversal order of the collection's iterator.
49.150 + *
49.151 * @param c the collection of elements to initially contain
49.152 * @throws NullPointerException if the specified collection or any
49.153 * of its elements are null
49.154 */
49.155 public ConcurrentLinkedQueue(Collection<? extends E> c) {
49.156 - for (E e : c)
49.157 - add(e);
49.158 + Node<E> h = null, t = null;
49.159 + for (E e : c) {
49.160 + checkNotNull(e);
49.161 + Node<E> newNode = new Node<E>(e);
49.162 + if (h == null)
49.163 + h = t = newNode;
49.164 + else {
49.165 + t.lazySetNext(newNode);
49.166 + t = newNode;
49.167 + }
49.168 + }
49.169 + if (h == null)
49.170 + h = t = new Node<E>(null);
49.171 + head = h;
49.172 + tail = t;
49.173 }
49.174
49.175 // Have to override just to update the javadoc
49.176 @@ -267,13 +278,6 @@
49.177 }
49.178
49.179 /**
49.180 - * We don't bother to update head or tail pointers if fewer than
49.181 - * HOPS links from "true" location. We assume that volatile
49.182 - * writes are significantly more expensive than volatile reads.
49.183 - */
49.184 - private static final int HOPS = 1;
49.185 -
49.186 - /**
49.187 * Try to CAS head to p. If successful, repoint old head to itself
49.188 * as sentinel for succ(), below.
49.189 */
49.190 @@ -288,7 +292,7 @@
49.191 * stale pointer that is now off the list.
49.192 */
49.193 final Node<E> succ(Node<E> p) {
49.194 - Node<E> next = p.getNext();
49.195 + Node<E> next = p.next;
49.196 return (p == next) ? head : next;
49.197 }
49.198
49.199 @@ -299,68 +303,75 @@
49.200 * @throws NullPointerException if the specified element is null
49.201 */
49.202 public boolean offer(E e) {
49.203 - if (e == null) throw new NullPointerException();
49.204 - Node<E> n = new Node<E>(e);
49.205 - retry:
49.206 + checkNotNull(e);
49.207 + final Node<E> newNode = new Node<E>(e);
49.208 +
49.209 + for (Node<E> t = tail, p = t;;) {
49.210 + Node<E> q = p.next;
49.211 + if (q == null) {
49.212 + // p is last node
49.213 + if (p.casNext(null, newNode)) {
49.214 + // Successful CAS is the linearization point
49.215 + // for e to become an element of this queue,
49.216 + // and for newNode to become "live".
49.217 + if (p != t) // hop two nodes at a time
49.218 + casTail(t, newNode); // Failure is OK.
49.219 + return true;
49.220 + }
49.221 + // Lost CAS race to another thread; re-read next
49.222 + }
49.223 + else if (p == q)
49.224 + // We have fallen off list. If tail is unchanged, it
49.225 + // will also be off-list, in which case we need to
49.226 + // jump to head, from which all live nodes are always
49.227 + // reachable. Else the new tail is a better bet.
49.228 + p = (t != (t = tail)) ? t : head;
49.229 + else
49.230 + // Check for tail updates after two hops.
49.231 + p = (p != t && t != (t = tail)) ? t : q;
49.232 + }
49.233 + }
49.234 +
49.235 + public E poll() {
49.236 + restartFromHead:
49.237 for (;;) {
49.238 - Node<E> t = tail;
49.239 - Node<E> p = t;
49.240 - for (int hops = 0; ; hops++) {
49.241 - Node<E> next = succ(p);
49.242 - if (next != null) {
49.243 - if (hops > HOPS && t != tail)
49.244 - continue retry;
49.245 - p = next;
49.246 - } else if (p.casNext(null, n)) {
49.247 - if (hops >= HOPS)
49.248 - casTail(t, n); // Failure is OK.
49.249 - return true;
49.250 - } else {
49.251 - p = succ(p);
49.252 + for (Node<E> h = head, p = h, q;;) {
49.253 + E item = p.item;
49.254 +
49.255 + if (item != null && p.casItem(item, null)) {
49.256 + // Successful CAS is the linearization point
49.257 + // for item to be removed from this queue.
49.258 + if (p != h) // hop two nodes at a time
49.259 + updateHead(h, ((q = p.next) != null) ? q : p);
49.260 + return item;
49.261 }
49.262 + else if ((q = p.next) == null) {
49.263 + updateHead(h, p);
49.264 + return null;
49.265 + }
49.266 + else if (p == q)
49.267 + continue restartFromHead;
49.268 + else
49.269 + p = q;
49.270 }
49.271 }
49.272 }
49.273
49.274 - public E poll() {
49.275 - Node<E> h = head;
49.276 - Node<E> p = h;
49.277 - for (int hops = 0; ; hops++) {
49.278 - E item = p.getItem();
49.279 -
49.280 - if (item != null && p.casItem(item, null)) {
49.281 - if (hops >= HOPS) {
49.282 - Node<E> q = p.getNext();
49.283 - updateHead(h, (q != null) ? q : p);
49.284 + public E peek() {
49.285 + restartFromHead:
49.286 + for (;;) {
49.287 + for (Node<E> h = head, p = h, q;;) {
49.288 + E item = p.item;
49.289 + if (item != null || (q = p.next) == null) {
49.290 + updateHead(h, p);
49.291 + return item;
49.292 }
49.293 - return item;
49.294 + else if (p == q)
49.295 + continue restartFromHead;
49.296 + else
49.297 + p = q;
49.298 }
49.299 - Node<E> next = succ(p);
49.300 - if (next == null) {
49.301 - updateHead(h, p);
49.302 - break;
49.303 - }
49.304 - p = next;
49.305 }
49.306 - return null;
49.307 - }
49.308 -
49.309 - public E peek() {
49.310 - Node<E> h = head;
49.311 - Node<E> p = h;
49.312 - E item;
49.313 - for (;;) {
49.314 - item = p.getItem();
49.315 - if (item != null)
49.316 - break;
49.317 - Node<E> next = succ(p);
49.318 - if (next == null) {
49.319 - break;
49.320 - }
49.321 - p = next;
49.322 - }
49.323 - updateHead(h, p);
49.324 - return item;
49.325 }
49.326
49.327 /**
49.328 @@ -372,24 +383,20 @@
49.329 * of losing a race to a concurrent poll().
49.330 */
49.331 Node<E> first() {
49.332 - Node<E> h = head;
49.333 - Node<E> p = h;
49.334 - Node<E> result;
49.335 + restartFromHead:
49.336 for (;;) {
49.337 - E item = p.getItem();
49.338 - if (item != null) {
49.339 - result = p;
49.340 - break;
49.341 + for (Node<E> h = head, p = h, q;;) {
49.342 + boolean hasItem = (p.item != null);
49.343 + if (hasItem || (q = p.next) == null) {
49.344 + updateHead(h, p);
49.345 + return hasItem ? p : null;
49.346 + }
49.347 + else if (p == q)
49.348 + continue restartFromHead;
49.349 + else
49.350 + p = q;
49.351 }
49.352 - Node<E> next = succ(p);
49.353 - if (next == null) {
49.354 - result = null;
49.355 - break;
49.356 - }
49.357 - p = next;
49.358 }
49.359 - updateHead(h, p);
49.360 - return result;
49.361 }
49.362
49.363 /**
49.364 @@ -410,18 +417,20 @@
49.365 * <em>NOT</em> a constant-time operation. Because of the
49.366 * asynchronous nature of these queues, determining the current
49.367 * number of elements requires an O(n) traversal.
49.368 + * Additionally, if elements are added or removed during execution
49.369 + * of this method, the returned result may be inaccurate. Thus,
49.370 + * this method is typically not very useful in concurrent
49.371 + * applications.
49.372 *
49.373 * @return the number of elements in this queue
49.374 */
49.375 public int size() {
49.376 int count = 0;
49.377 - for (Node<E> p = first(); p != null; p = succ(p)) {
49.378 - if (p.getItem() != null) {
49.379 - // Collections.size() spec says to max out
49.380 + for (Node<E> p = first(); p != null; p = succ(p))
49.381 + if (p.item != null)
49.382 + // Collection.size() spec says to max out
49.383 if (++count == Integer.MAX_VALUE)
49.384 break;
49.385 - }
49.386 - }
49.387 return count;
49.388 }
49.389
49.390 @@ -436,9 +445,8 @@
49.391 public boolean contains(Object o) {
49.392 if (o == null) return false;
49.393 for (Node<E> p = first(); p != null; p = succ(p)) {
49.394 - E item = p.getItem();
49.395 - if (item != null &&
49.396 - o.equals(item))
49.397 + E item = p.item;
49.398 + if (item != null && o.equals(item))
49.399 return true;
49.400 }
49.401 return false;
49.402 @@ -459,7 +467,7 @@
49.403 if (o == null) return false;
49.404 Node<E> pred = null;
49.405 for (Node<E> p = first(); p != null; p = succ(p)) {
49.406 - E item = p.getItem();
49.407 + E item = p.item;
49.408 if (item != null &&
49.409 o.equals(item) &&
49.410 p.casItem(item, null)) {
49.411 @@ -474,6 +482,69 @@
49.412 }
49.413
49.414 /**
49.415 + * Appends all of the elements in the specified collection to the end of
49.416 + * this queue, in the order that they are returned by the specified
49.417 + * collection's iterator. Attempts to {@code addAll} of a queue to
49.418 + * itself result in {@code IllegalArgumentException}.
49.419 + *
49.420 + * @param c the elements to be inserted into this queue
49.421 + * @return {@code true} if this queue changed as a result of the call
49.422 + * @throws NullPointerException if the specified collection or any
49.423 + * of its elements are null
49.424 + * @throws IllegalArgumentException if the collection is this queue
49.425 + */
49.426 + public boolean addAll(Collection<? extends E> c) {
49.427 + if (c == this)
49.428 + // As historically specified in AbstractQueue#addAll
49.429 + throw new IllegalArgumentException();
49.430 +
49.431 + // Copy c into a private chain of Nodes
49.432 + Node<E> beginningOfTheEnd = null, last = null;
49.433 + for (E e : c) {
49.434 + checkNotNull(e);
49.435 + Node<E> newNode = new Node<E>(e);
49.436 + if (beginningOfTheEnd == null)
49.437 + beginningOfTheEnd = last = newNode;
49.438 + else {
49.439 + last.lazySetNext(newNode);
49.440 + last = newNode;
49.441 + }
49.442 + }
49.443 + if (beginningOfTheEnd == null)
49.444 + return false;
49.445 +
49.446 + // Atomically append the chain at the tail of this collection
49.447 + for (Node<E> t = tail, p = t;;) {
49.448 + Node<E> q = p.next;
49.449 + if (q == null) {
49.450 + // p is last node
49.451 + if (p.casNext(null, beginningOfTheEnd)) {
49.452 + // Successful CAS is the linearization point
49.453 + // for all elements to be added to this queue.
49.454 + if (!casTail(t, last)) {
49.455 + // Try a little harder to update tail,
49.456 + // since we may be adding many elements.
49.457 + t = tail;
49.458 + if (last.next == null)
49.459 + casTail(t, last);
49.460 + }
49.461 + return true;
49.462 + }
49.463 + // Lost CAS race to another thread; re-read next
49.464 + }
49.465 + else if (p == q)
49.466 + // We have fallen off list. If tail is unchanged, it
49.467 + // will also be off-list, in which case we need to
49.468 + // jump to head, from which all live nodes are always
49.469 + // reachable. Else the new tail is a better bet.
49.470 + p = (t != (t = tail)) ? t : head;
49.471 + else
49.472 + // Check for tail updates after two hops.
49.473 + p = (p != t && t != (t = tail)) ? t : q;
49.474 + }
49.475 + }
49.476 +
49.477 + /**
49.478 * Returns an array containing all of the elements in this queue, in
49.479 * proper sequence.
49.480 *
49.481 @@ -490,7 +561,7 @@
49.482 // Use ArrayList to deal with resizing.
49.483 ArrayList<E> al = new ArrayList<E>();
49.484 for (Node<E> p = first(); p != null; p = succ(p)) {
49.485 - E item = p.getItem();
49.486 + E item = p.item;
49.487 if (item != null)
49.488 al.add(item);
49.489 }
49.490 @@ -539,7 +610,7 @@
49.491 int k = 0;
49.492 Node<E> p;
49.493 for (p = first(); p != null && k < a.length; p = succ(p)) {
49.494 - E item = p.getItem();
49.495 + E item = p.item;
49.496 if (item != null)
49.497 a[k++] = (T)item;
49.498 }
49.499 @@ -552,7 +623,7 @@
49.500 // If won't fit, use ArrayList version
49.501 ArrayList<E> al = new ArrayList<E>();
49.502 for (Node<E> q = first(); q != null; q = succ(q)) {
49.503 - E item = q.getItem();
49.504 + E item = q.item;
49.505 if (item != null)
49.506 al.add(item);
49.507 }
49.508 @@ -561,7 +632,9 @@
49.509
49.510 /**
49.511 * Returns an iterator over the elements in this queue in proper sequence.
49.512 - * The returned iterator is a "weakly consistent" iterator that
49.513 + * The elements will be returned in order from first (head) to last (tail).
49.514 + *
49.515 + * <p>The returned {@code Iterator} is a "weakly consistent" iterator that
49.516 * will never throw {@link java.util.ConcurrentModificationException
49.517 * ConcurrentModificationException},
49.518 * and guarantees to traverse elements as they existed upon
49.519 @@ -620,7 +693,7 @@
49.520 nextItem = null;
49.521 return x;
49.522 }
49.523 - E item = p.getItem();
49.524 + E item = p.item;
49.525 if (item != null) {
49.526 nextNode = p;
49.527 nextItem = item;
49.528 @@ -648,13 +721,13 @@
49.529 Node<E> l = lastRet;
49.530 if (l == null) throw new IllegalStateException();
49.531 // rely on a future traversal to relink.
49.532 - l.setItem(null);
49.533 + l.item = null;
49.534 lastRet = null;
49.535 }
49.536 }
49.537
49.538 /**
49.539 - * Save the state to a stream (that is, serialize it).
49.540 + * Saves the state to a stream (that is, serializes it).
49.541 *
49.542 * @serialData All of the elements (each an {@code E}) in
49.543 * the proper order, followed by a null
49.544 @@ -668,7 +741,7 @@
49.545
49.546 // Write out all elements in the proper order.
49.547 for (Node<E> p = first(); p != null; p = succ(p)) {
49.548 - Object item = p.getItem();
49.549 + Object item = p.item;
49.550 if (item != null)
49.551 s.writeObject(item);
49.552 }
49.553 @@ -678,25 +751,40 @@
49.554 }
49.555
49.556 /**
49.557 - * Reconstitute the Queue instance from a stream (that is,
49.558 - * deserialize it).
49.559 + * Reconstitutes the instance from a stream (that is, deserializes it).
49.560 * @param s the stream
49.561 */
49.562 private void readObject(java.io.ObjectInputStream s)
49.563 throws java.io.IOException, ClassNotFoundException {
49.564 - // Read in capacity, and any hidden stuff
49.565 s.defaultReadObject();
49.566 - head = new Node<E>(null);
49.567 - tail = head;
49.568 - // Read in all elements and place in queue
49.569 - for (;;) {
49.570 +
49.571 + // Read in elements until trailing null sentinel found
49.572 + Node<E> h = null, t = null;
49.573 + Object item;
49.574 + while ((item = s.readObject()) != null) {
49.575 @SuppressWarnings("unchecked")
49.576 - E item = (E)s.readObject();
49.577 - if (item == null)
49.578 - break;
49.579 - else
49.580 - offer(item);
49.581 + Node<E> newNode = new Node<E>((E) item);
49.582 + if (h == null)
49.583 + h = t = newNode;
49.584 + else {
49.585 + t.lazySetNext(newNode);
49.586 + t = newNode;
49.587 + }
49.588 }
49.589 + if (h == null)
49.590 + h = t = new Node<E>(null);
49.591 + head = h;
49.592 + tail = t;
49.593 + }
49.594 +
49.595 + /**
49.596 + * Throws NullPointerException if argument is null.
49.597 + *
49.598 + * @param v the element
49.599 + */
49.600 + private static void checkNotNull(Object v) {
49.601 + if (v == null)
49.602 + throw new NullPointerException();
49.603 }
49.604
49.605 // Unsafe mechanics
49.606 @@ -715,10 +803,6 @@
49.607 return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
49.608 }
49.609
49.610 - private void lazySetHead(Node<E> val) {
49.611 - UNSAFE.putOrderedObject(this, headOffset, val);
49.612 - }
49.613 -
49.614 static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
49.615 String field, Class<?> klazz) {
49.616 try {
50.1 --- a/src/share/classes/java/util/concurrent/ForkJoinPool.java Tue Oct 12 13:34:59 2010 -0400
50.2 +++ b/src/share/classes/java/util/concurrent/ForkJoinPool.java Mon Oct 18 11:25:28 2010 -0400
50.3 @@ -42,7 +42,6 @@
50.4 import java.util.List;
50.5 import java.util.concurrent.AbstractExecutorService;
50.6 import java.util.concurrent.Callable;
50.7 -import java.util.concurrent.CountDownLatch;
50.8 import java.util.concurrent.ExecutorService;
50.9 import java.util.concurrent.Future;
50.10 import java.util.concurrent.RejectedExecutionException;
50.11 @@ -823,15 +822,13 @@
50.12 (workerCounts & RUNNING_COUNT_MASK) <= 1);
50.13 long startTime = untimed? 0 : System.nanoTime();
50.14 Thread.interrupted(); // clear/ignore interrupt
50.15 - if (eventCount != ec || w.runState != 0 ||
50.16 - runState >= TERMINATING) // recheck after clear
50.17 - break;
50.18 + if (eventCount != ec || w.isTerminating())
50.19 + break; // recheck after clear
50.20 if (untimed)
50.21 LockSupport.park(w);
50.22 else {
50.23 LockSupport.parkNanos(w, SHRINK_RATE_NANOS);
50.24 - if (eventCount != ec || w.runState != 0 ||
50.25 - runState >= TERMINATING)
50.26 + if (eventCount != ec || w.isTerminating())
50.27 break;
50.28 if (System.nanoTime() - startTime >= SHRINK_RATE_NANOS)
50.29 tryShutdownUnusedWorker(ec);
50.30 @@ -899,16 +896,23 @@
50.31 UNSAFE.compareAndSwapInt(this, workerCountsOffset, wc,
50.32 wc + (ONE_RUNNING|ONE_TOTAL))) {
50.33 ForkJoinWorkerThread w = null;
50.34 + Throwable fail = null;
50.35 try {
50.36 w = factory.newThread(this);
50.37 - } finally { // adjust on null or exceptional factory return
50.38 - if (w == null) {
50.39 - decrementWorkerCounts(ONE_RUNNING, ONE_TOTAL);
50.40 - tryTerminate(false); // handle failure during shutdown
50.41 - }
50.42 + } catch (Throwable ex) {
50.43 + fail = ex;
50.44 }
50.45 - if (w == null)
50.46 + if (w == null) { // null or exceptional factory return
50.47 + decrementWorkerCounts(ONE_RUNNING, ONE_TOTAL);
50.48 + tryTerminate(false); // handle failure during shutdown
50.49 + // If originating from an external caller,
50.50 + // propagate exception, else ignore
50.51 + if (fail != null && runState < TERMINATING &&
50.52 + !(Thread.currentThread() instanceof
50.53 + ForkJoinWorkerThread))
50.54 + UNSAFE.throwException(fail);
50.55 break;
50.56 + }
50.57 w.start(recordWorker(w), ueh);
50.58 if ((workerCounts >>> TOTAL_COUNT_SHIFT) >= pc) {
50.59 int c; // advance event count
50.60 @@ -997,8 +1001,12 @@
50.61 boolean active = w.active;
50.62 boolean inactivate = false;
50.63 int pc = parallelism;
50.64 - int rs;
50.65 - while (w.runState == 0 && (rs = runState) < TERMINATING) {
50.66 + while (w.runState == 0) {
50.67 + int rs = runState;
50.68 + if (rs >= TERMINATING) { // propagate shutdown
50.69 + w.shutdown();
50.70 + break;
50.71 + }
50.72 if ((inactivate || (active && (rs & ACTIVE_COUNT_MASK) >= pc)) &&
50.73 UNSAFE.compareAndSwapInt(this, runStateOffset, rs, rs - 1))
50.74 inactivate = active = w.active = false;
50.75 @@ -1126,6 +1134,7 @@
50.76 return true;
50.77 }
50.78
50.79 +
50.80 /**
50.81 * Actions on transition to TERMINATING
50.82 *
50.83 @@ -1149,7 +1158,7 @@
50.84 if (passes > 0 && !w.isTerminated()) {
50.85 w.cancelTasks();
50.86 LockSupport.unpark(w);
50.87 - if (passes > 1) {
50.88 + if (passes > 1 && !w.isInterrupted()) {
50.89 try {
50.90 w.interrupt();
50.91 } catch (SecurityException ignore) {
50.92 @@ -1726,6 +1735,13 @@
50.93 }
50.94
50.95 /**
50.96 + * Returns true if terminating or terminated. Used by ForkJoinWorkerThread.
50.97 + */
50.98 + final boolean isAtLeastTerminating() {
50.99 + return runState >= TERMINATING;
50.100 + }
50.101 +
50.102 + /**
50.103 * Returns {@code true} if this pool has been shut down.
50.104 *
50.105 * @return {@code true} if this pool has been shut down
51.1 --- a/src/share/classes/java/util/concurrent/ForkJoinTask.java Tue Oct 12 13:34:59 2010 -0400
51.2 +++ b/src/share/classes/java/util/concurrent/ForkJoinTask.java Mon Oct 18 11:25:28 2010 -0400
51.3 @@ -55,10 +55,10 @@
51.4 * start other subtasks. As indicated by the name of this class,
51.5 * many programs using {@code ForkJoinTask} employ only methods
51.6 * {@link #fork} and {@link #join}, or derivatives such as {@link
51.7 - * #invokeAll}. However, this class also provides a number of other
51.8 - * methods that can come into play in advanced usages, as well as
51.9 - * extension mechanics that allow support of new forms of fork/join
51.10 - * processing.
51.11 + * #invokeAll(ForkJoinTask...) invokeAll}. However, this class also
51.12 + * provides a number of other methods that can come into play in
51.13 + * advanced usages, as well as extension mechanics that allow
51.14 + * support of new forms of fork/join processing.
51.15 *
51.16 * <p>A {@code ForkJoinTask} is a lightweight form of {@link Future}.
51.17 * The efficiency of {@code ForkJoinTask}s stems from a set of
51.18 @@ -250,7 +250,7 @@
51.19 int s; // the odd construction reduces lock bias effects
51.20 while ((s = status) >= 0) {
51.21 try {
51.22 - synchronized(this) {
51.23 + synchronized (this) {
51.24 if (UNSAFE.compareAndSwapInt(this, statusOffset, s,SIGNAL))
51.25 wait();
51.26 }
51.27 @@ -270,7 +270,7 @@
51.28 int s;
51.29 if ((s = status) >= 0) {
51.30 try {
51.31 - synchronized(this) {
51.32 + synchronized (this) {
51.33 if (UNSAFE.compareAndSwapInt(this, statusOffset, s,SIGNAL))
51.34 wait(millis, 0);
51.35 }
51.36 @@ -288,7 +288,7 @@
51.37 private void externalAwaitDone() {
51.38 int s;
51.39 while ((s = status) >= 0) {
51.40 - synchronized(this) {
51.41 + synchronized (this) {
51.42 if (UNSAFE.compareAndSwapInt(this, statusOffset, s, SIGNAL)){
51.43 boolean interrupted = false;
51.44 while (status >= 0) {
51.45 @@ -669,11 +669,34 @@
51.46 setCompletion(NORMAL);
51.47 }
51.48
51.49 + /**
51.50 + * Waits if necessary for the computation to complete, and then
51.51 + * retrieves its result.
51.52 + *
51.53 + * @return the computed result
51.54 + * @throws CancellationException if the computation was cancelled
51.55 + * @throws ExecutionException if the computation threw an
51.56 + * exception
51.57 + * @throws InterruptedException if the current thread is not a
51.58 + * member of a ForkJoinPool and was interrupted while waiting
51.59 + */
51.60 public final V get() throws InterruptedException, ExecutionException {
51.61 - quietlyJoin();
51.62 - if (Thread.interrupted())
51.63 - throw new InterruptedException();
51.64 - int s = status;
51.65 + int s;
51.66 + if (Thread.currentThread() instanceof ForkJoinWorkerThread) {
51.67 + quietlyJoin();
51.68 + s = status;
51.69 + }
51.70 + else {
51.71 + while ((s = status) >= 0) {
51.72 + synchronized (this) { // interruptible form of awaitDone
51.73 + if (UNSAFE.compareAndSwapInt(this, statusOffset,
51.74 + s, SIGNAL)) {
51.75 + while (status >= 0)
51.76 + wait();
51.77 + }
51.78 + }
51.79 + }
51.80 + }
51.81 if (s < NORMAL) {
51.82 Throwable ex;
51.83 if (s == CANCELLED)
51.84 @@ -684,6 +707,20 @@
51.85 return getRawResult();
51.86 }
51.87
51.88 + /**
51.89 + * Waits if necessary for at most the given time for the computation
51.90 + * to complete, and then retrieves its result, if available.
51.91 + *
51.92 + * @param timeout the maximum time to wait
51.93 + * @param unit the time unit of the timeout argument
51.94 + * @return the computed result
51.95 + * @throws CancellationException if the computation was cancelled
51.96 + * @throws ExecutionException if the computation threw an
51.97 + * exception
51.98 + * @throws InterruptedException if the current thread is not a
51.99 + * member of a ForkJoinPool and was interrupted while waiting
51.100 + * @throws TimeoutException if the wait timed out
51.101 + */
51.102 public final V get(long timeout, TimeUnit unit)
51.103 throws InterruptedException, ExecutionException, TimeoutException {
51.104 Thread t = Thread.currentThread();
51.105 @@ -725,7 +762,7 @@
51.106 long ms = nt / 1000000;
51.107 int ns = (int) (nt % 1000000);
51.108 try {
51.109 - synchronized(this) {
51.110 + synchronized (this) {
51.111 if (status >= 0)
51.112 wait(ms, ns);
51.113 }
52.1 --- a/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java Tue Oct 12 13:34:59 2010 -0400
52.2 +++ b/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java Mon Oct 18 11:25:28 2010 -0400
52.3 @@ -778,11 +778,20 @@
52.4
52.5 // status check methods used mainly by ForkJoinPool
52.6 final boolean isRunning() { return runState == 0; }
52.7 - final boolean isTerminating() { return (runState & TERMINATING) != 0; }
52.8 final boolean isTerminated() { return (runState & TERMINATED) != 0; }
52.9 final boolean isSuspended() { return (runState & SUSPENDED) != 0; }
52.10 final boolean isTrimmed() { return (runState & TRIMMED) != 0; }
52.11
52.12 + final boolean isTerminating() {
52.13 + if ((runState & TERMINATING) != 0)
52.14 + return true;
52.15 + if (pool.isAtLeastTerminating()) { // propagate pool state
52.16 + shutdown();
52.17 + return true;
52.18 + }
52.19 + return false;
52.20 + }
52.21 +
52.22 /**
52.23 * Sets state to TERMINATING. Does NOT unpark or interrupt
52.24 * to wake up if currently blocked. Callers must do so if desired.
53.1 --- a/src/share/classes/java/util/concurrent/RecursiveAction.java Tue Oct 12 13:34:59 2010 -0400
53.2 +++ b/src/share/classes/java/util/concurrent/RecursiveAction.java Mon Oct 18 11:25:28 2010 -0400
53.3 @@ -138,7 +138,7 @@
53.4 * if (right.tryUnfork()) // directly calculate if not stolen
53.5 * sum += right.atLeaf(right.lo, right.hi);
53.6 * else {
53.7 - * right.helpJoin();
53.8 + * right.join();
53.9 * sum += right.result;
53.10 * }
53.11 * right = right.next;
54.1 --- a/src/share/classes/java/util/logging/LogManager.java Tue Oct 12 13:34:59 2010 -0400
54.2 +++ b/src/share/classes/java/util/logging/LogManager.java Mon Oct 18 11:25:28 2010 -0400
54.3 @@ -690,6 +690,11 @@
54.4 * Note that since untrusted code may create loggers with
54.5 * arbitrary names this method should not be relied on to
54.6 * find Loggers for security sensitive logging.
54.7 + * It is also important to note that the Logger associated with the
54.8 + * String {@code name} may be garbage collected at any time if there
54.9 + * is no strong reference to the Logger. The caller of this method
54.10 + * must check the return value for null in order to properly handle
54.11 + * the case where the Logger has been garbage collected.
54.12 * <p>
54.13 * @param name name of the logger
54.14 * @return matching logger or null if none is found
54.15 @@ -713,6 +718,14 @@
54.16 * <p>
54.17 * Note: Loggers may be added dynamically as new classes are loaded.
54.18 * This method only reports on the loggers that are currently registered.
54.19 + * It is also important to note that this method only returns the name
54.20 + * of a Logger, not a strong reference to the Logger itself.
54.21 + * The returned String does nothing to prevent the Logger from being
54.22 + * garbage collected. In particular, if the returned name is passed
54.23 + * to {@code LogManager.getLogger()}, then the caller must check the
54.24 + * return value from {@code LogManager.getLogger()} for null to properly
54.25 + * handle the case where the Logger has been garbage collected in the
54.26 + * time since its name was returned by this method.
54.27 * <p>
54.28 * @return enumeration of logger name strings
54.29 */
55.1 --- a/src/share/classes/java/util/logging/Logger.java Tue Oct 12 13:34:59 2010 -0400
55.2 +++ b/src/share/classes/java/util/logging/Logger.java Mon Oct 18 11:25:28 2010 -0400
55.3 @@ -42,7 +42,10 @@
55.4 * <p>
55.5 * Logger objects may be obtained by calls on one of the getLogger
55.6 * factory methods. These will either create a new Logger or
55.7 - * return a suitable existing Logger.
55.8 + * return a suitable existing Logger. It is important to note that
55.9 + * the Logger returned by one of the {@code getLogger} factory methods
55.10 + * may be garbage collected at any time if a strong reference to the
55.11 + * Logger is not kept.
55.12 * <p>
55.13 * Logging messages will be forwarded to registered Handler
55.14 * objects, which can forward the messages to a variety of
55.15 @@ -210,7 +213,9 @@
55.16 * who are making serious use of the logging package (for example
55.17 * in products) should create and use their own Logger objects,
55.18 * with appropriate names, so that logging can be controlled on a
55.19 - * suitable per-Logger granularity.
55.20 + * suitable per-Logger granularity. Developers also need to keep a
55.21 + * strong reference to their Logger objects to prevent them from
55.22 + * being garbage collected.
55.23 * <p>
55.24 * @deprecated Initialization of this field is prone to deadlocks.
55.25 * The field must be initialized by the Logger class initialization
55.26 @@ -287,6 +292,15 @@
55.27 * based on the LogManager configuration and it will configured
55.28 * to also send logging output to its parent's Handlers. It will
55.29 * be registered in the LogManager global namespace.
55.30 + * <p>
55.31 + * Note: The LogManager may only retain a weak reference to the newly
55.32 + * created Logger. It is important to understand that a previously
55.33 + * created Logger with the given name may be garbage collected at any
55.34 + * time if there is no strong reference to the Logger. In particular,
55.35 + * this means that two back-to-back calls like
55.36 + * {@code getLogger("MyLogger").log(...)} may use different Logger
55.37 + * objects named "MyLogger" if there is no strong reference to the
55.38 + * Logger named "MyLogger" elsewhere in the program.
55.39 *
55.40 * @param name A name for the logger. This should
55.41 * be a dot-separated name and should normally
55.42 @@ -311,6 +325,15 @@
55.43 * output to its parent's Handlers. It will be registered in
55.44 * the LogManager global namespace.
55.45 * <p>
55.46 + * Note: The LogManager may only retain a weak reference to the newly
55.47 + * created Logger. It is important to understand that a previously
55.48 + * created Logger with the given name may be garbage collected at any
55.49 + * time if there is no strong reference to the Logger. In particular,
55.50 + * this means that two back-to-back calls like
55.51 + * {@code getLogger("MyLogger", ...).log(...)} may use different Logger
55.52 + * objects named "MyLogger" if there is no strong reference to the
55.53 + * Logger named "MyLogger" elsewhere in the program.
55.54 + * <p>
55.55 * If the named Logger already exists and does not yet have a
55.56 * localization resource bundle then the given resource bundle
55.57 * name is used. If the named Logger already exists and has
56.1 --- a/src/share/classes/javax/sql/rowset/BaseRowSet.java Tue Oct 12 13:34:59 2010 -0400
56.2 +++ b/src/share/classes/javax/sql/rowset/BaseRowSet.java Mon Oct 18 11:25:28 2010 -0400
56.3 @@ -1,5 +1,5 @@
56.4 /*
56.5 - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
56.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
56.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
56.8 *
56.9 * This code is free software; you can redistribute it and/or modify it
56.10 @@ -734,7 +734,7 @@
56.11 throw new SQLException("Set initParams() before setCommand");
56.12 }
56.13 params.clear();
56.14 - command = new String(cmd);
56.15 + command = cmd;
56.16 }
56.17
56.18 }
56.19 @@ -797,7 +797,7 @@
56.20 throw new SQLException("Invalid url string detected. " +
56.21 "Cannot be of length less than 1");
56.22 } else {
56.23 - URL = new String(url);
56.24 + URL = url;
56.25 }
56.26
56.27 dataSource = null;
56.28 @@ -854,7 +854,7 @@
56.29 } else if (name.equals("")) {
56.30 throw new SQLException("DataSource name cannot be empty string");
56.31 } else {
56.32 - dataSource = new String(name);
56.33 + dataSource = name;
56.34 }
56.35
56.36 URL = null;
56.37 @@ -889,7 +889,7 @@
56.38 {
56.39 username = null;
56.40 } else {
56.41 - username = new String(name);
56.42 + username = name;
56.43 }
56.44 }
56.45
56.46 @@ -924,7 +924,7 @@
56.47 {
56.48 password = null;
56.49 } else {
56.50 - password = new String(pass);
56.51 + password = pass;
56.52 }
56.53 }
56.54
56.55 @@ -1563,13 +1563,13 @@
56.56
56.57 nullVal = new Object[2];
56.58 nullVal[0] = null;
56.59 - nullVal[1] = new Integer(sqlType);
56.60 + nullVal[1] = Integer.valueOf(sqlType);
56.61
56.62 if (params == null){
56.63 throw new SQLException("Set initParams() before setNull");
56.64 }
56.65
56.66 - params.put(new Integer(parameterIndex - 1), nullVal);
56.67 + params.put(Integer.valueOf(parameterIndex - 1), nullVal);
56.68 }
56.69
56.70 /**
56.71 @@ -1644,14 +1644,14 @@
56.72
56.73 nullVal = new Object[3];
56.74 nullVal[0] = null;
56.75 - nullVal[1] = new Integer(sqlType);
56.76 - nullVal[2] = new String(typeName);
56.77 + nullVal[1] = Integer.valueOf(sqlType);
56.78 + nullVal[2] = typeName;
56.79
56.80 if(params == null){
56.81 throw new SQLException("Set initParams() before setNull");
56.82 }
56.83
56.84 - params.put(new Integer(parameterIndex - 1), nullVal);
56.85 + params.put(Integer.valueOf(parameterIndex - 1), nullVal);
56.86 }
56.87
56.88
56.89 @@ -1686,7 +1686,7 @@
56.90 throw new SQLException("Set initParams() before setNull");
56.91 }
56.92
56.93 - params.put(new Integer(parameterIndex - 1), new Boolean(x));
56.94 + params.put(Integer.valueOf(parameterIndex - 1), Boolean.valueOf(x));
56.95 }
56.96
56.97 /**
56.98 @@ -1720,7 +1720,7 @@
56.99 throw new SQLException("Set initParams() before setByte");
56.100 }
56.101
56.102 - params.put(new Integer(parameterIndex - 1), new Byte(x));
56.103 + params.put(Integer.valueOf(parameterIndex - 1), Byte.valueOf(x));
56.104 }
56.105
56.106 /**
56.107 @@ -1754,7 +1754,7 @@
56.108 throw new SQLException("Set initParams() before setShort");
56.109 }
56.110
56.111 - params.put(new Integer(parameterIndex - 1), new Short(x));
56.112 + params.put(Integer.valueOf(parameterIndex - 1), Short.valueOf(x));
56.113 }
56.114
56.115 /**
56.116 @@ -1786,7 +1786,7 @@
56.117 if(params == null){
56.118 throw new SQLException("Set initParams() before setInt");
56.119 }
56.120 - params.put(new Integer(parameterIndex - 1), new Integer(x));
56.121 + params.put(Integer.valueOf(parameterIndex - 1), Integer.valueOf(x));
56.122 }
56.123
56.124 /**
56.125 @@ -1818,7 +1818,7 @@
56.126 if(params == null){
56.127 throw new SQLException("Set initParams() before setLong");
56.128 }
56.129 - params.put(new Integer(parameterIndex - 1), new Long(x));
56.130 + params.put(Integer.valueOf(parameterIndex - 1), Long.valueOf(x));
56.131 }
56.132
56.133 /**
56.134 @@ -1850,7 +1850,7 @@
56.135 if(params == null){
56.136 throw new SQLException("Set initParams() before setFloat");
56.137 }
56.138 - params.put(new Integer(parameterIndex - 1), new Float(x));
56.139 + params.put(Integer.valueOf(parameterIndex - 1), new Float(x));
56.140 }
56.141
56.142 /**
56.143 @@ -1882,7 +1882,7 @@
56.144 if(params == null){
56.145 throw new SQLException("Set initParams() before setDouble");
56.146 }
56.147 - params.put(new Integer(parameterIndex - 1), new Double(x));
56.148 + params.put(Integer.valueOf(parameterIndex - 1), new Double(x));
56.149 }
56.150
56.151 /**
56.152 @@ -1914,7 +1914,7 @@
56.153 if(params == null){
56.154 throw new SQLException("Set initParams() before setBigDecimal");
56.155 }
56.156 - params.put(new Integer(parameterIndex - 1), x);
56.157 + params.put(Integer.valueOf(parameterIndex - 1), x);
56.158 }
56.159
56.160 /**
56.161 @@ -1948,7 +1948,7 @@
56.162 if(params == null){
56.163 throw new SQLException("Set initParams() before setString");
56.164 }
56.165 - params.put(new Integer(parameterIndex - 1), x);
56.166 + params.put(Integer.valueOf(parameterIndex - 1), x);
56.167 }
56.168
56.169 /**
56.170 @@ -1982,7 +1982,7 @@
56.171 if(params == null){
56.172 throw new SQLException("Set initParams() before setBytes");
56.173 }
56.174 - params.put(new Integer(parameterIndex - 1), x);
56.175 + params.put(Integer.valueOf(parameterIndex - 1), x);
56.176 }
56.177
56.178 /**
56.179 @@ -2024,7 +2024,7 @@
56.180 if(params == null){
56.181 throw new SQLException("Set initParams() before setDate");
56.182 }
56.183 - params.put(new Integer(parameterIndex - 1), x);
56.184 + params.put(Integer.valueOf(parameterIndex - 1), x);
56.185 }
56.186
56.187 /**
56.188 @@ -2069,7 +2069,7 @@
56.189 throw new SQLException("Set initParams() before setTime");
56.190 }
56.191
56.192 - params.put(new Integer(parameterIndex - 1), x);
56.193 + params.put(Integer.valueOf(parameterIndex - 1), x);
56.194 }
56.195
56.196 /**
56.197 @@ -2112,7 +2112,7 @@
56.198 throw new SQLException("Set initParams() before setTimestamp");
56.199 }
56.200
56.201 - params.put(new Integer(parameterIndex - 1), x);
56.202 + params.put(Integer.valueOf(parameterIndex - 1), x);
56.203 }
56.204
56.205 /**
56.206 @@ -2185,14 +2185,14 @@
56.207
56.208 asciiStream = new Object[3];
56.209 asciiStream[0] = x;
56.210 - asciiStream[1] = new Integer(length);
56.211 - asciiStream[2] = new Integer(ASCII_STREAM_PARAM);
56.212 + asciiStream[1] = Integer.valueOf(length);
56.213 + asciiStream[2] = Integer.valueOf(ASCII_STREAM_PARAM);
56.214
56.215 if(params == null){
56.216 throw new SQLException("Set initParams() before setAsciiStream");
56.217 }
56.218
56.219 - params.put(new Integer(parameterIndex - 1), asciiStream);
56.220 + params.put(Integer.valueOf(parameterIndex - 1), asciiStream);
56.221 }
56.222
56.223 /**
56.224 @@ -2290,13 +2290,13 @@
56.225
56.226 binaryStream = new Object[3];
56.227 binaryStream[0] = x;
56.228 - binaryStream[1] = new Integer(length);
56.229 - binaryStream[2] = new Integer(BINARY_STREAM_PARAM);
56.230 + binaryStream[1] = Integer.valueOf(length);
56.231 + binaryStream[2] = Integer.valueOf(BINARY_STREAM_PARAM);
56.232 if(params == null){
56.233 throw new SQLException("Set initParams() before setBinaryStream");
56.234 }
56.235
56.236 - params.put(new Integer(parameterIndex - 1), binaryStream);
56.237 + params.put(Integer.valueOf(parameterIndex - 1), binaryStream);
56.238 }
56.239
56.240
56.241 @@ -2396,12 +2396,12 @@
56.242
56.243 unicodeStream = new Object[3];
56.244 unicodeStream[0] = x;
56.245 - unicodeStream[1] = new Integer(length);
56.246 - unicodeStream[2] = new Integer(UNICODE_STREAM_PARAM);
56.247 + unicodeStream[1] = Integer.valueOf(length);
56.248 + unicodeStream[2] = Integer.valueOf(UNICODE_STREAM_PARAM);
56.249 if(params == null){
56.250 throw new SQLException("Set initParams() before setUnicodeStream");
56.251 }
56.252 - params.put(new Integer(parameterIndex - 1), unicodeStream);
56.253 + params.put(Integer.valueOf(parameterIndex - 1), unicodeStream);
56.254 }
56.255
56.256 /**
56.257 @@ -2475,11 +2475,11 @@
56.258
56.259 charStream = new Object[2];
56.260 charStream[0] = reader;
56.261 - charStream[1] = new Integer(length);
56.262 + charStream[1] = Integer.valueOf(length);
56.263 if(params == null){
56.264 throw new SQLException("Set initParams() before setCharacterStream");
56.265 }
56.266 - params.put(new Integer(parameterIndex - 1), charStream);
56.267 + params.put(Integer.valueOf(parameterIndex - 1), charStream);
56.268 }
56.269
56.270 /**
56.271 @@ -2591,12 +2591,12 @@
56.272
56.273 obj = new Object[3];
56.274 obj[0] = x;
56.275 - obj[1] = new Integer(targetSqlType);
56.276 - obj[2] = new Integer(scale);
56.277 + obj[1] = Integer.valueOf(targetSqlType);
56.278 + obj[2] = Integer.valueOf(scale);
56.279 if(params == null){
56.280 throw new SQLException("Set initParams() before setObject");
56.281 }
56.282 - params.put(new Integer(parameterIndex - 1), obj);
56.283 + params.put(Integer.valueOf(parameterIndex - 1), obj);
56.284 }
56.285
56.286 /**
56.287 @@ -2654,11 +2654,11 @@
56.288
56.289 obj = new Object[2];
56.290 obj[0] = x;
56.291 - obj[1] = new Integer(targetSqlType);
56.292 + obj[1] = Integer.valueOf(targetSqlType);
56.293 if (params == null){
56.294 throw new SQLException("Set initParams() before setObject");
56.295 }
56.296 - params.put(new Integer(parameterIndex - 1), obj);
56.297 + params.put(Integer.valueOf(parameterIndex - 1), obj);
56.298 }
56.299
56.300 /**
56.301 @@ -2726,7 +2726,7 @@
56.302 if (params == null) {
56.303 throw new SQLException("Set initParams() before setObject");
56.304 }
56.305 - params.put(new Integer(parameterIndex - 1), x);
56.306 + params.put(Integer.valueOf(parameterIndex - 1), x);
56.307 }
56.308
56.309 /**
56.310 @@ -2773,7 +2773,7 @@
56.311 if (params == null) {
56.312 throw new SQLException("Set initParams() before setRef");
56.313 }
56.314 - params.put(new Integer(parameterIndex - 1), new SerialRef(ref));
56.315 + params.put(Integer.valueOf(parameterIndex - 1), new SerialRef(ref));
56.316 }
56.317
56.318 /**
56.319 @@ -2817,7 +2817,7 @@
56.320 if(params == null){
56.321 throw new SQLException("Set initParams() before setBlob");
56.322 }
56.323 - params.put(new Integer(parameterIndex - 1), new SerialBlob(x));
56.324 + params.put(Integer.valueOf(parameterIndex - 1), new SerialBlob(x));
56.325 }
56.326
56.327 /**
56.328 @@ -2862,7 +2862,7 @@
56.329 if(params == null){
56.330 throw new SQLException("Set initParams() before setClob");
56.331 }
56.332 - params.put(new Integer(parameterIndex - 1), new SerialClob(x));
56.333 + params.put(Integer.valueOf(parameterIndex - 1), new SerialClob(x));
56.334 }
56.335
56.336 /**
56.337 @@ -2910,7 +2910,7 @@
56.338 if (params == null){
56.339 throw new SQLException("Set initParams() before setArray");
56.340 }
56.341 - params.put(new Integer(parameterIndex - 1), new SerialArray(array));
56.342 + params.put(Integer.valueOf(parameterIndex - 1), new SerialArray(array));
56.343 }
56.344
56.345 /**
56.346 @@ -2975,7 +2975,7 @@
56.347 if(params == null){
56.348 throw new SQLException("Set initParams() before setDate");
56.349 }
56.350 - params.put(new Integer(parameterIndex - 1), date);
56.351 + params.put(Integer.valueOf(parameterIndex - 1), date);
56.352 }
56.353
56.354 /**
56.355 @@ -3041,7 +3041,7 @@
56.356 if(params == null){
56.357 throw new SQLException("Set initParams() before setTime");
56.358 }
56.359 - params.put(new Integer(parameterIndex - 1), time);
56.360 + params.put(Integer.valueOf(parameterIndex - 1), time);
56.361 }
56.362
56.363 /**
56.364 @@ -3107,7 +3107,7 @@
56.365 if(params == null){
56.366 throw new SQLException("Set initParams() before setTimestamp");
56.367 }
56.368 - params.put(new Integer(parameterIndex - 1), timestamp);
56.369 + params.put(Integer.valueOf(parameterIndex - 1), timestamp);
56.370 }
56.371
56.372 /**
56.373 @@ -3181,7 +3181,7 @@
56.374
56.375 Object[] paramsArray = new Object[params.size()];
56.376 for (int i = 0; i < params.size(); i++) {
56.377 - paramsArray[i] = params.get(new Integer(i));
56.378 + paramsArray[i] = params.get(Integer.valueOf(i));
56.379 if (paramsArray[i] == null) {
56.380 throw new SQLException("missing parameter: " + (i + 1));
56.381 } //end if
57.1 --- a/src/share/classes/javax/sql/rowset/CachedRowSet.java Tue Oct 12 13:34:59 2010 -0400
57.2 +++ b/src/share/classes/javax/sql/rowset/CachedRowSet.java Mon Oct 18 11:25:28 2010 -0400
57.3 @@ -39,7 +39,7 @@
57.4 * <code>CachedRowSet</code> must implement.
57.5 * <P>
57.6 * The reference implementation of the <code>CachedRowSet</code> interface provided
57.7 - * by Sun Microsystems is a standard implementation. Developers may use this implementation
57.8 + * by Oracle Corporation is a standard implementation. Developers may use this implementation
57.9 * just as it is, they may extend it, or they may choose to write their own implementations
57.10 * of this interface.
57.11 * <P>
57.12 @@ -1623,4 +1623,3 @@
57.13 public boolean previousPage() throws SQLException;
57.14
57.15 }
57.16 -
58.1 --- a/src/share/classes/javax/sql/rowset/RowSetMetaDataImpl.java Tue Oct 12 13:34:59 2010 -0400
58.2 +++ b/src/share/classes/javax/sql/rowset/RowSetMetaDataImpl.java Mon Oct 18 11:25:28 2010 -0400
58.3 @@ -1,5 +1,5 @@
58.4 /*
58.5 - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
58.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
58.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
58.8 *
58.9 * This code is free software; you can redistribute it and/or modify it
58.10 @@ -306,9 +306,9 @@
58.11 public void setColumnLabel(int columnIndex, String label) throws SQLException {
58.12 checkColRange(columnIndex);
58.13 if (label != null) {
58.14 - colInfo[columnIndex].columnLabel = new String(label);
58.15 + colInfo[columnIndex].columnLabel = label;
58.16 } else {
58.17 - colInfo[columnIndex].columnLabel = new String("");
58.18 + colInfo[columnIndex].columnLabel = "";
58.19 }
58.20 }
58.21
58.22 @@ -326,9 +326,9 @@
58.23 public void setColumnName(int columnIndex, String columnName) throws SQLException {
58.24 checkColRange(columnIndex);
58.25 if (columnName != null) {
58.26 - colInfo[columnIndex].columnName = new String(columnName);
58.27 + colInfo[columnIndex].columnName = columnName;
58.28 } else {
58.29 - colInfo[columnIndex].columnName = new String("");
58.30 + colInfo[columnIndex].columnName = "";
58.31 }
58.32 }
58.33
58.34 @@ -348,9 +348,9 @@
58.35 public void setSchemaName(int columnIndex, String schemaName) throws SQLException {
58.36 checkColRange(columnIndex);
58.37 if (schemaName != null ) {
58.38 - colInfo[columnIndex].schemaName = new String(schemaName);
58.39 + colInfo[columnIndex].schemaName = schemaName;
58.40 } else {
58.41 - colInfo[columnIndex].schemaName = new String("");
58.42 + colInfo[columnIndex].schemaName = "";
58.43 }
58.44 }
58.45
58.46 @@ -411,9 +411,9 @@
58.47 public void setTableName(int columnIndex, String tableName) throws SQLException {
58.48 checkColRange(columnIndex);
58.49 if (tableName != null) {
58.50 - colInfo[columnIndex].tableName = new String(tableName);
58.51 + colInfo[columnIndex].tableName = tableName;
58.52 } else {
58.53 - colInfo[columnIndex].tableName = new String("");
58.54 + colInfo[columnIndex].tableName = "";
58.55 }
58.56 }
58.57
58.58 @@ -432,9 +432,9 @@
58.59 public void setCatalogName(int columnIndex, String catalogName) throws SQLException {
58.60 checkColRange(columnIndex);
58.61 if (catalogName != null)
58.62 - colInfo[columnIndex].catName = new String(catalogName);
58.63 + colInfo[columnIndex].catName = catalogName;
58.64 else
58.65 - colInfo[columnIndex].catName = new String("");
58.66 + colInfo[columnIndex].catName = "";
58.67 }
58.68
58.69 /**
58.70 @@ -474,9 +474,9 @@
58.71 throws SQLException {
58.72 checkColRange(columnIndex);
58.73 if (typeName != null) {
58.74 - colInfo[columnIndex].colTypeName = new String(typeName);
58.75 + colInfo[columnIndex].colTypeName = typeName;
58.76 } else {
58.77 - colInfo[columnIndex].colTypeName = new String("");
58.78 + colInfo[columnIndex].colTypeName = "";
58.79 }
58.80 }
58.81
58.82 @@ -827,7 +827,7 @@
58.83 * or the given column number is out of bounds
58.84 */
58.85 public String getColumnClassName(int columnIndex) throws SQLException {
58.86 - String className = (new String()).getClass().getName();
58.87 + String className = String.class.getName();
58.88
58.89 int sqlType = getColumnType(columnIndex);
58.90
58.91 @@ -835,65 +835,62 @@
58.92
58.93 case Types.NUMERIC:
58.94 case Types.DECIMAL:
58.95 - className = (new java.math.BigDecimal(0)).getClass().getName ();
58.96 + className = java.math.BigDecimal.class.getName();
58.97 break;
58.98
58.99 case Types.BIT:
58.100 - className = (new Boolean(false)).getClass().getName ();
58.101 + className = java.lang.Boolean.class.getName();
58.102 break;
58.103
58.104 case Types.TINYINT:
58.105 - className = (new Byte("0")).getClass().getName ();
58.106 + className = java.lang.Byte.class.getName();
58.107 break;
58.108
58.109 case Types.SMALLINT:
58.110 - className = (new Short("0")).getClass().getName ();
58.111 + className = java.lang.Short.class.getName();
58.112 break;
58.113
58.114 case Types.INTEGER:
58.115 - className = (new Integer(0)).getClass().getName ();
58.116 + className = java.lang.Integer.class.getName();
58.117 break;
58.118
58.119 case Types.BIGINT:
58.120 - className = (new Long(0)).getClass().getName ();
58.121 + className = java.lang.Long.class.getName();
58.122 break;
58.123
58.124 case Types.REAL:
58.125 - className = (new Float(0)).getClass().getName ();
58.126 + className = java.lang.Float.class.getName();
58.127 break;
58.128
58.129 case Types.FLOAT:
58.130 case Types.DOUBLE:
58.131 - className = (new Double(0)).getClass().getName();
58.132 + className = java.lang.Double.class.getName();
58.133 break;
58.134
58.135 case Types.BINARY:
58.136 case Types.VARBINARY:
58.137 case Types.LONGVARBINARY:
58.138 - byte[] b = {};
58.139 - className = (b.getClass()).getName();
58.140 + className = "byte[]";
58.141 break;
58.142
58.143 case Types.DATE:
58.144 - className = (new java.sql.Date(123456)).getClass().getName ();
58.145 + className = java.sql.Date.class.getName();
58.146 break;
58.147
58.148 case Types.TIME:
58.149 - className = (new java.sql.Time(123456)).getClass().getName ();
58.150 + className = java.sql.Time.class.getName();
58.151 break;
58.152
58.153 case Types.TIMESTAMP:
58.154 - className = (new java.sql.Timestamp(123456)).getClass().getName ();
58.155 + className = java.sql.Timestamp.class.getName();
58.156 break;
58.157
58.158 case Types.BLOB:
58.159 - byte[] blob = {};
58.160 - className = (blob.getClass()).getName();
58.161 + className = java.sql.Blob.class.getName();
58.162 break;
58.163
58.164 case Types.CLOB:
58.165 - char[] c = {};
58.166 - className = (c.getClass()).getName();
58.167 + className = java.sql.Clob.class.getName();
58.168 break;
58.169 }
58.170
59.1 --- a/src/share/classes/javax/sql/rowset/RowSetProvider.java Tue Oct 12 13:34:59 2010 -0400
59.2 +++ b/src/share/classes/javax/sql/rowset/RowSetProvider.java Mon Oct 18 11:25:28 2010 -0400
59.3 @@ -29,7 +29,6 @@
59.4 import java.security.PrivilegedAction;
59.5 import java.sql.SQLException;
59.6 import java.util.ServiceLoader;
59.7 -import javax.sql.rowset.RowSetFactory;
59.8
59.9 /**
59.10 * A factory API that enables applications to obtain a
59.11 @@ -82,15 +81,15 @@
59.12 * the <code>RowSetFactory</code> implementation class to load:</p>
59.13 * <ul>
59.14 * <li>
59.15 - * The System property {@code javax.sql.rowset.RowsetFactory}. For example:
59.16 + * The System property {@code javax.sql.rowset.RowSetFactory}. For example:
59.17 * <ul>
59.18 * <li>
59.19 - * -Djavax.sql.rowset.RowsetFactory=com.sun.rowset.RowSetFactoryImpl
59.20 + * -Djavax.sql.rowset.RowSetFactory=com.sun.rowset.RowSetFactoryImpl
59.21 * </li>
59.22 * </ul>
59.23 * <li>
59.24 - * The ServiceLocator API. The ServiceLocator API will look
59.25 - * for a classname in the file
59.26 + * The {@link ServiceLoader} API. The {@code ServiceLoader} API will look
59.27 + * for a class name in the file
59.28 * {@code META-INF/services/javax.sql.rowset.RowSetFactory}
59.29 * in jars available to the runtime. For example, to have the the RowSetFactory
59.30 * implementation {@code com.sun.rowset.RowSetFactoryImpl } loaded, the
59.31 @@ -271,7 +270,7 @@
59.32 /**
59.33 * Returns the requested System Property. If a {@code SecurityException}
59.34 * occurs, just return NULL
59.35 - * @param propName - System property to retreive
59.36 + * @param propName - System property to retrieve
59.37 * @return The System property value or NULL if the property does not exist
59.38 * or a {@code SecurityException} occurs.
59.39 */
60.1 --- a/src/share/classes/javax/sql/rowset/WebRowSet.java Tue Oct 12 13:34:59 2010 -0400
60.2 +++ b/src/share/classes/javax/sql/rowset/WebRowSet.java Mon Oct 18 11:25:28 2010 -0400
60.3 @@ -1,5 +1,5 @@
60.4 /*
60.5 - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
60.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
60.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
60.8 *
60.9 * This code is free software; you can redistribute it and/or modify it
60.10 @@ -115,7 +115,7 @@
60.11 * <<font color=red>url</font>>jdbc:thin:oracle<<font color=red>/url</font>>
60.12 * <<font color=red>sync-provider</font>>
60.13 * <<font color=red>sync-provider-name</font>>.com.rowset.provider.RIOptimisticProvider<<font color=red>/sync-provider-name</font>>
60.14 - * <<font color=red>sync-provider-vendor</font>>Sun Microsystems<<font color=red>/sync-provider-vendor</font>>
60.15 + * <<font color=red>sync-provider-vendor</font>>Oracle Corporation<<font color=red>/sync-provider-vendor</font>>
60.16 * <<font color=red>sync-provider-version</font>>1.0<<font color=red>/sync-provider-name</font>>
60.17 * <<font color=red>sync-provider-grade</font>>LOW<<font color=red>/sync-provider-grade</font>>
60.18 * <<font color=red>data-source-lock</font>>NONE<<font color=red>/data-source-lock</font>>
60.19 @@ -489,7 +489,7 @@
60.20 * tags and their valid values for a <code>WebRowSet</code> implementation.
60.21 */
60.22 public static String PUBLIC_XML_SCHEMA =
60.23 - "--//Sun Microsystems, Inc.//XSD Schema//EN";
60.24 + "--//Oracle Corporation//XSD Schema//EN";
60.25
60.26 /**
60.27 * The URL for the XML Schema definition file that defines the XML tags and
61.1 --- a/src/share/classes/javax/sql/rowset/rowset.properties Tue Oct 12 13:34:59 2010 -0400
61.2 +++ b/src/share/classes/javax/sql/rowset/rowset.properties Mon Oct 18 11:25:28 2010 -0400
61.3 @@ -3,10 +3,10 @@
61.4
61.5 # Optimistic synchonriztaion provider
61.6 rowset.provider.classname.0=com.sun.rowset.providers.RIOptimisticProvider
61.7 -rowset.provider.vendor.0=Sun Microsystems Inc
61.8 +rowset.provider.vendor.0=Oracle Corporation
61.9 rowset.provider.version.0=1.0
61.10
61.11 # XML Provider using standard XML schema
61.12 rowset.provider.classname.1=com.sun.rowset.providers.RIXMLProvider
61.13 -rowset.provider.vendor.1=Sun Microsystems Inc.
61.14 +rowset.provider.vendor.1=Oracle Corporation
61.15 rowset.provider.version.1=1.0
62.1 --- a/src/share/classes/javax/sql/rowset/serial/SQLOutputImpl.java Tue Oct 12 13:34:59 2010 -0400
62.2 +++ b/src/share/classes/javax/sql/rowset/serial/SQLOutputImpl.java Mon Oct 18 11:25:28 2010 -0400
62.3 @@ -1,5 +1,5 @@
62.4 /*
62.5 - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
62.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
62.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
62.8 *
62.9 * This code is free software; you can redistribute it and/or modify it
62.10 @@ -137,7 +137,7 @@
62.11 * values of a UDT to the database.
62.12 */
62.13 public void writeBoolean(boolean x) throws SQLException {
62.14 - attribs.add(new Boolean(x));
62.15 + attribs.add(Boolean.valueOf(x));
62.16 }
62.17
62.18 /**
62.19 @@ -151,7 +151,7 @@
62.20 * values of a UDT to the database.
62.21 */
62.22 public void writeByte(byte x) throws SQLException {
62.23 - attribs.add(new Byte(x));
62.24 + attribs.add(Byte.valueOf(x));
62.25 }
62.26
62.27 /**
62.28 @@ -165,7 +165,7 @@
62.29 * values of a UDT to the database.
62.30 */
62.31 public void writeShort(short x) throws SQLException {
62.32 - attribs.add(new Short(x));
62.33 + attribs.add(Short.valueOf(x));
62.34 }
62.35
62.36 /**
62.37 @@ -179,7 +179,7 @@
62.38 * values of a UDT to the database.
62.39 */
62.40 public void writeInt(int x) throws SQLException {
62.41 - attribs.add(new Integer(x));
62.42 + attribs.add(Integer.valueOf(x));
62.43 }
62.44
62.45 /**
62.46 @@ -193,7 +193,7 @@
62.47 * values of a UDT to the database.
62.48 */
62.49 public void writeLong(long x) throws SQLException {
62.50 - attribs.add(new Long(x));
62.51 + attribs.add(Long.valueOf(x));
62.52 }
62.53
62.54 /**
63.1 --- a/src/share/classes/javax/sql/rowset/serial/SerialRef.java Tue Oct 12 13:34:59 2010 -0400
63.2 +++ b/src/share/classes/javax/sql/rowset/serial/SerialRef.java Mon Oct 18 11:25:28 2010 -0400
63.3 @@ -1,5 +1,5 @@
63.4 /*
63.5 - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
63.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
63.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
63.8 *
63.9 * This code is free software; you can redistribute it and/or modify it
63.10 @@ -77,7 +77,7 @@
63.11 throw new SQLException("Cannot instantiate a SerialRef object " +
63.12 "that returns a null base type name");
63.13 } else {
63.14 - baseTypeName = new String(ref.getBaseTypeName());
63.15 + baseTypeName = ref.getBaseTypeName();
63.16 }
63.17 }
63.18
63.19 @@ -110,7 +110,7 @@
63.20 throws SerialException
63.21 {
63.22 map = new Hashtable(map);
63.23 - if (!object.equals(null)) {
63.24 + if (object != null) {
63.25 return map.get(object);
63.26 } else {
63.27 throw new SerialException("The object is not set");
64.1 --- a/src/share/classes/javax/sql/rowset/serial/SerialStruct.java Tue Oct 12 13:34:59 2010 -0400
64.2 +++ b/src/share/classes/javax/sql/rowset/serial/SerialStruct.java Mon Oct 18 11:25:28 2010 -0400
64.3 @@ -1,5 +1,5 @@
64.4 /*
64.5 - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
64.6 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
64.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
64.8 *
64.9 * This code is free software; you can redistribute it and/or modify it
64.10 @@ -94,7 +94,7 @@
64.11 try {
64.12
64.13 // get the type name
64.14 - SQLTypeName = new String(in.getSQLTypeName());
64.15 + SQLTypeName = in.getSQLTypeName();
64.16 System.out.println("SQLTypeName: " + SQLTypeName);
64.17
64.18 // get the attributes of the struct
64.19 @@ -137,7 +137,7 @@
64.20 try {
64.21
64.22 //set the type name
64.23 - SQLTypeName = new String(in.getSQLTypeName());
64.24 + SQLTypeName = in.getSQLTypeName();
64.25
64.26 Vector tmp = new Vector();
64.27 in.writeSQL(new SQLOutputImpl(tmp, map));
64.28 @@ -247,7 +247,7 @@
64.29 }
64.30
64.31 /**
64.32 - * The identifier that assists in the serialization of this
64.33 + * The identifier that assists in the serialization of this
64.34 * <code>SerialStruct</code> object.
64.35 */
64.36 static final long serialVersionUID = -8322445504027483372L;
65.1 --- a/src/share/classes/javax/sql/rowset/spi/SyncFactory.java Tue Oct 12 13:34:59 2010 -0400
65.2 +++ b/src/share/classes/javax/sql/rowset/spi/SyncFactory.java Mon Oct 18 11:25:28 2010 -0400
65.3 @@ -125,12 +125,12 @@
65.4 *
65.5 * # Optimistic synchronization provider
65.6 * rowset.provider.classname.0=com.sun.rowset.providers.RIOptimisticProvider
65.7 - * rowset.provider.vendor.0=Sun Microsystems Inc
65.8 + * rowset.provider.vendor.0=Oracle Corporation
65.9 * rowset.provider.version.0=1.0
65.10 *
65.11 * # XML Provider using standard XML schema
65.12 * rowset.provider.classname.1=com.sun.rowset.providers.RIXMLProvider
65.13 - * rowset.provider.vendor.1=Sun Microsystems Inc.
65.14 + * rowset.provider.vendor.1=Oracle Corporation
65.15 * rowset.provider.version.1=1.0
65.16 * </PRE>
65.17 * The <code>SyncFactory</code> checks this file and registers the
65.18 @@ -369,7 +369,7 @@
65.19 try {
65.20
65.21 // check if user is supplying his Synchronisation Provider
65.22 - // Implementation if not use Sun's implementation.
65.23 + // Implementation if not using Oracle's implementation.
65.24 // properties.load(new FileInputStream(ROWSET_PROPERTIES));
65.25
65.26 // The rowset.properties needs to be in jdk/jre/lib when
66.1 --- a/src/share/classes/javax/sql/rowset/spi/SyncProvider.java Tue Oct 12 13:34:59 2010 -0400
66.2 +++ b/src/share/classes/javax/sql/rowset/spi/SyncProvider.java Mon Oct 18 11:25:28 2010 -0400
66.3 @@ -91,8 +91,8 @@
66.4 * </pre>
66.5 * <p>
66.6 * A vendor can register a <code>SyncProvider</code> implementation class name
66.7 - * with Sun Microsystems, Inc. by sending email to jdbc@sun.com.
66.8 - * Sun will maintain a database listing the
66.9 + * with Oracle Corporation by sending email to jdbc@sun.com.
66.10 + * Oracle will maintain a database listing the
66.11 * available <code>SyncProvider</code> implementations for use with compliant
66.12 * <code>RowSet</code> implementations. This database will be similar to the
66.13 * one already maintained to list available JDBC drivers.
67.1 --- a/src/share/classes/javax/sql/rowset/spi/package.html Tue Oct 12 13:34:59 2010 -0400
67.2 +++ b/src/share/classes/javax/sql/rowset/spi/package.html Mon Oct 18 11:25:28 2010 -0400
67.3 @@ -8,7 +8,7 @@
67.4 <meta name="GENERATOR"
67.5 content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
67.6 <!--
67.7 -Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
67.8 +Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
67.9 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
67.10
67.11 This code is free software; you can redistribute it and/or modify it
67.12 @@ -199,7 +199,7 @@
67.13 Vendors may develop a <tt>SyncProvider</tt> implementation with any one of the possible
67.14 levels of synchronization, thus giving <code>RowSet</code> objects a choice of
67.15 synchronization mechanisms. A vendor can make its implementation available by
67.16 -registering the fully qualified class name with Sun Microsystems at
67.17 +registering the fully qualified class name with Oracle Corporation at
67.18 <code>jdbc@sun.com</code>. This process is discussed in further detail below.
67.19 <P>
67.20
68.1 --- a/src/share/classes/javax/swing/GroupLayout.java Tue Oct 12 13:34:59 2010 -0400
68.2 +++ b/src/share/classes/javax/swing/GroupLayout.java Mon Oct 18 11:25:28 2010 -0400
68.3 @@ -1464,8 +1464,8 @@
68.4 * <= {@code pref} <= {@code max}.
68.5 * <p>
68.6 * Similarly any methods that take a {@code Component} throw a
68.7 - * {@code NullPointerException} if passed {@code null} and any methods
68.8 - * that take a {@code Group} throw an {@code IllegalArgumentException} if
68.9 + * {@code IllegalArgumentException} if passed {@code null} and any methods
68.10 + * that take a {@code Group} throw an {@code NullPointerException} if
68.11 * passed {@code null}.
68.12 *
68.13 * @see #createSequentialGroup
69.1 --- a/src/share/classes/javax/swing/JComponent.java Tue Oct 12 13:34:59 2010 -0400
69.2 +++ b/src/share/classes/javax/swing/JComponent.java Mon Oct 18 11:25:28 2010 -0400
69.3 @@ -4787,6 +4787,17 @@
69.4 * @see RepaintManager#addDirtyRegion
69.5 */
69.6 public void repaint(long tm, int x, int y, int width, int height) {
69.7 + Container p = this;
69.8 + while ((p = p.getParent()) instanceof JComponent) {
69.9 + JComponent jp = (JComponent) p;
69.10 + if (jp.isPaintingOrigin()) {
69.11 + Rectangle rectangle = SwingUtilities.convertRectangle(
69.12 + this, new Rectangle(x, y, width, height), jp);
69.13 + jp.repaint(tm,
69.14 + rectangle.x, rectangle.y, rectangle.width, rectangle.height);
69.15 + return;
69.16 + }
69.17 + }
69.18 RepaintManager.currentManager(this).addDirtyRegion(this, x, y, width, height);
69.19 }
69.20
70.1 --- a/src/share/classes/javax/swing/JDesktopPane.java Tue Oct 12 13:34:59 2010 -0400
70.2 +++ b/src/share/classes/javax/swing/JDesktopPane.java Mon Oct 18 11:25:28 2010 -0400
70.3 @@ -215,7 +215,8 @@
70.4
70.5 /**
70.6 * Sets the <code>DesktopManger</code> that will handle
70.7 - * desktop-specific UI actions.
70.8 + * desktop-specific UI actions. This may be overridden by
70.9 + * {@code LookAndFeel}.
70.10 *
70.11 * @param d the <code>DesktopManager</code> to use
70.12 *
71.1 --- a/src/share/classes/javax/swing/JLayer.java Tue Oct 12 13:34:59 2010 -0400
71.2 +++ b/src/share/classes/javax/swing/JLayer.java Mon Oct 18 11:25:28 2010 -0400
71.3 @@ -25,17 +25,17 @@
71.4
71.5 package javax.swing;
71.6
71.7 +import sun.awt.AWTAccessor;
71.8 +
71.9 import javax.swing.plaf.LayerUI;
71.10 +import javax.swing.border.Border;
71.11 import java.awt.*;
71.12 import java.awt.event.*;
71.13 import java.beans.PropertyChangeEvent;
71.14 import java.beans.PropertyChangeListener;
71.15 import java.io.IOException;
71.16 import java.io.ObjectInputStream;
71.17 -import java.io.Serializable;
71.18 -import java.lang.ref.WeakReference;
71.19 import java.util.ArrayList;
71.20 -import java.util.Iterator;
71.21 import java.security.AccessController;
71.22 import java.security.PrivilegedAction;
71.23
71.24 @@ -156,8 +156,6 @@
71.25 private LayerUI<? super V> layerUI;
71.26 private JPanel glassPane;
71.27 private boolean isPainting;
71.28 - private static final DefaultLayerLayout sharedLayoutInstance =
71.29 - new DefaultLayerLayout();
71.30 private long eventMask;
71.31
71.32 private static final LayerEventController eventController =
71.33 @@ -165,7 +163,7 @@
71.34
71.35 /**
71.36 * Creates a new {@code JLayer} object with a {@code null} view component
71.37 - * and {@code null} {@link javax.swing.plaf.LayerUI}.
71.38 + * and default {@link javax.swing.plaf.LayerUI}.
71.39 *
71.40 * @see #setView
71.41 * @see #setUI
71.42 @@ -176,14 +174,14 @@
71.43
71.44 /**
71.45 * Creates a new {@code JLayer} object
71.46 - * with {@code null} {@link javax.swing.plaf.LayerUI}.
71.47 + * with default {@link javax.swing.plaf.LayerUI}.
71.48 *
71.49 * @param view the component to be decorated by this {@code JLayer}
71.50 *
71.51 * @see #setUI
71.52 */
71.53 public JLayer(V view) {
71.54 - this(view, null);
71.55 + this(view, new LayerUI<V>());
71.56 }
71.57
71.58 /**
71.59 @@ -195,7 +193,6 @@
71.60 * to be used by this {@code JLayer}
71.61 */
71.62 public JLayer(V view, LayerUI<V> ui) {
71.63 - setLayout(sharedLayoutInstance);
71.64 setGlassPane(createGlassPane());
71.65 setView(view);
71.66 setUI(ui);
71.67 @@ -279,10 +276,15 @@
71.68 */
71.69 public void setGlassPane(JPanel glassPane) {
71.70 Component oldGlassPane = getGlassPane();
71.71 + boolean isGlassPaneVisible = false;
71.72 if (oldGlassPane != null) {
71.73 + isGlassPaneVisible = oldGlassPane.isVisible();
71.74 super.remove(oldGlassPane);
71.75 }
71.76 if (glassPane != null) {
71.77 + AWTAccessor.getComponentAccessor().setMixingCutoutShape(glassPane,
71.78 + new Rectangle());
71.79 + glassPane.setVisible(isGlassPaneVisible);
71.80 super.addImpl(glassPane, null, 0);
71.81 }
71.82 this.glassPane = glassPane;
71.83 @@ -303,6 +305,40 @@
71.84 }
71.85
71.86 /**
71.87 + * Sets the layout manager for this container. This method is
71.88 + * overridden to prevent the layout manager from being set.
71.89 + * <p/>Note: If {@code mgr} is non-{@code null}, this
71.90 + * method will throw an exception as layout managers are not supported on
71.91 + * a {@code JLayer}.
71.92 + *
71.93 + * @param mgr the specified layout manager
71.94 + * @exception IllegalArgumentException this method is not supported
71.95 + */
71.96 + public void setLayout(LayoutManager mgr) {
71.97 + if (mgr != null) {
71.98 + throw new IllegalArgumentException("JLayer.setLayout() not supported");
71.99 + }
71.100 + }
71.101 +
71.102 + /**
71.103 + * A non-{@code null] border, or non-zero insets, isn't supported, to prevent the geometry
71.104 + * of this component from becoming complex enough to inhibit
71.105 + * subclassing of {@code LayerUI} class. To create a {@code JLayer} with a border,
71.106 + * add it to a {@code JPanel} that has a border.
71.107 + * <p/>Note: If {@code border} is non-{@code null}, this
71.108 + * method will throw an exception as borders are not supported on
71.109 + * a {@code JLayer}.
71.110 + *
71.111 + * @param border the {@code Border} to set
71.112 + * @exception IllegalArgumentException this method is not supported
71.113 + */
71.114 + public void setBorder(Border border) {
71.115 + if (border != null) {
71.116 + throw new IllegalArgumentException("JLayer.setBorder() not supported");
71.117 + }
71.118 + }
71.119 +
71.120 + /**
71.121 * This method is not supported by {@code JLayer}
71.122 * and always throws {@code UnsupportedOperationException}
71.123 *
71.124 @@ -341,6 +377,32 @@
71.125 }
71.126
71.127 /**
71.128 + * Always returns {@code true} to cause painting to originate from {@code JLayer},
71.129 + * or one of its ancestors.
71.130 + *
71.131 + * @return true
71.132 + * @see JComponent#isPaintingOrigin()
71.133 + */
71.134 + boolean isPaintingOrigin() {
71.135 + return true;
71.136 + }
71.137 +
71.138 + /**
71.139 + * Delegates repainting to {@link javax.swing.plaf.LayerUI#repaint} method.
71.140 + *
71.141 + * @param tm this parameter is not used
71.142 + * @param x the x value of the dirty region
71.143 + * @param y the y value of the dirty region
71.144 + * @param width the width of the dirty region
71.145 + * @param height the height of the dirty region
71.146 + */
71.147 + public void repaint(long tm, int x, int y, int width, int height) {
71.148 + if (getUI() != null) {
71.149 + getUI().repaint(tm, x, y, width, height, this);
71.150 + }
71.151 + }
71.152 +
71.153 + /**
71.154 * Delegates all painting to the {@link javax.swing.plaf.LayerUI} object.
71.155 *
71.156 * @param g the {@code Graphics} to render to
71.157 @@ -364,14 +426,18 @@
71.158 }
71.159
71.160 /**
71.161 - * To enable the correct painting of the {@code glassPane} and view component,
71.162 - * the {@code JLayer} overrides the default implementation of
71.163 - * this method to return {@code false} when the {@code glassPane} is visible.
71.164 + * The {@code JLayer} overrides the default implementation of
71.165 + * this method (in {@code JComponent}) to return {@code false}.
71.166 + * This ensures
71.167 + * that the drawing machinery will call the {@code JLayer}'s
71.168 + * {@code paint}
71.169 + * implementation rather than messaging the {@code JLayer}'s
71.170 + * children directly.
71.171 *
71.172 - * @return false if {@code JLayer}'s {@code glassPane} is visible
71.173 + * @return false
71.174 */
71.175 public boolean isOptimizedDrawingEnabled() {
71.176 - return glassPane == null || !glassPane.isVisible();
71.177 + return false;
71.178 }
71.179
71.180 /**
71.181 @@ -461,17 +527,16 @@
71.182 /**
71.183 * Returns the preferred size of the viewport for a view component.
71.184 * <p/>
71.185 - * If the ui delegate of this layer is not {@code null}, this method delegates its
71.186 - * implementation to the {@code LayerUI.getPreferredScrollableViewportSize(JLayer)}
71.187 + * If the view component of this layer implements {@link Scrollable}, this method delegates its
71.188 + * implementation to the view component.
71.189 *
71.190 * @return the preferred size of the viewport for a view component
71.191 *
71.192 * @see Scrollable
71.193 - * @see LayerUI#getPreferredScrollableViewportSize(JLayer)
71.194 */
71.195 public Dimension getPreferredScrollableViewportSize() {
71.196 - if (getUI() != null) {
71.197 - return getUI().getPreferredScrollableViewportSize(this);
71.198 + if (getView() instanceof Scrollable) {
71.199 + return ((Scrollable)getView()).getPreferredScrollableViewportSize();
71.200 }
71.201 return getPreferredSize();
71.202 }
71.203 @@ -481,18 +546,17 @@
71.204 * that display logical rows or columns in order to completely expose
71.205 * one block of rows or columns, depending on the value of orientation.
71.206 * <p/>
71.207 - * If the ui delegate of this layer is not {@code null}, this method delegates its
71.208 - * implementation to the {@code LayerUI.getScrollableBlockIncrement(JLayer,Rectangle,int,int)}
71.209 + * If the view component of this layer implements {@link Scrollable}, this method delegates its
71.210 + * implementation to the view component.
71.211 *
71.212 * @return the "block" increment for scrolling in the specified direction
71.213 *
71.214 * @see Scrollable
71.215 - * @see LayerUI#getScrollableBlockIncrement(JLayer, Rectangle, int, int)
71.216 */
71.217 public int getScrollableBlockIncrement(Rectangle visibleRect,
71.218 int orientation, int direction) {
71.219 - if (getUI() != null) {
71.220 - return getUI().getScrollableBlockIncrement(this, visibleRect,
71.221 + if (getView() instanceof Scrollable) {
71.222 + return ((Scrollable)getView()).getScrollableBlockIncrement(visibleRect,
71.223 orientation, direction);
71.224 }
71.225 return (orientation == SwingConstants.VERTICAL) ? visibleRect.height :
71.226 @@ -504,17 +568,16 @@
71.227 * determine the height of the layer, unless the preferred height
71.228 * of the layer is smaller than the height of the viewport.
71.229 * <p/>
71.230 - * If the ui delegate of this layer is not null, this method delegates its
71.231 - * implementation to the {@code LayerUI.getScrollableTracksViewportHeight(JLayer)}
71.232 + * If the view component of this layer implements {@link Scrollable}, this method delegates its
71.233 + * implementation to the view component.
71.234 *
71.235 * @return whether the layer should track the height of the viewport
71.236 *
71.237 * @see Scrollable
71.238 - * @see LayerUI#getScrollableTracksViewportHeight(JLayer)
71.239 */
71.240 public boolean getScrollableTracksViewportHeight() {
71.241 - if (getUI() != null) {
71.242 - return getUI().getScrollableTracksViewportHeight(this);
71.243 + if (getView() instanceof Scrollable) {
71.244 + return ((Scrollable)getView()).getScrollableTracksViewportHeight();
71.245 }
71.246 return false;
71.247 }
71.248 @@ -524,17 +587,16 @@
71.249 * determine the width of the layer, unless the preferred width
71.250 * of the layer is smaller than the width of the viewport.
71.251 * <p/>
71.252 - * If the ui delegate of this layer is not null, this method delegates its
71.253 - * implementation to the {@code LayerUI.getScrollableTracksViewportWidth(JLayer)}
71.254 + * If the view component of this layer implements {@link Scrollable}, this method delegates its
71.255 + * implementation to the view component.
71.256 *
71.257 * @return whether the layer should track the width of the viewport
71.258 *
71.259 * @see Scrollable
71.260 - * @see LayerUI#getScrollableTracksViewportWidth(JLayer)
71.261 */
71.262 public boolean getScrollableTracksViewportWidth() {
71.263 - if (getUI() != null) {
71.264 - return getUI().getScrollableTracksViewportWidth(this);
71.265 + if (getView() instanceof Scrollable) {
71.266 + return ((Scrollable)getView()).getScrollableTracksViewportWidth();
71.267 }
71.268 return false;
71.269 }
71.270 @@ -549,20 +611,19 @@
71.271 * Scrolling containers, like {@code JScrollPane}, will use this method
71.272 * each time the user requests a unit scroll.
71.273 * <p/>
71.274 - * If the ui delegate of this layer is not {@code null}, this method delegates its
71.275 - * implementation to the {@code LayerUI.getScrollableUnitIncrement(JLayer,Rectangle,int,int)}
71.276 + * If the view component of this layer implements {@link Scrollable}, this method delegates its
71.277 + * implementation to the view component.
71.278 *
71.279 * @return The "unit" increment for scrolling in the specified direction.
71.280 * This value should always be positive.
71.281 *
71.282 * @see Scrollable
71.283 - * @see LayerUI#getScrollableUnitIncrement(JLayer, Rectangle, int, int)
71.284 */
71.285 public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation,
71.286 int direction) {
71.287 - if (getUI() != null) {
71.288 - return getUI().getScrollableUnitIncrement(
71.289 - this, visibleRect, orientation, direction);
71.290 + if (getView() instanceof Scrollable) {
71.291 + return ((Scrollable) getView()).getScrollableUnitIncrement(
71.292 + visibleRect, orientation, direction);
71.293 }
71.294 return 1;
71.295 }
71.296 @@ -595,6 +656,16 @@
71.297 }
71.298
71.299 /**
71.300 + * Delegates its functionality to the {@link javax.swing.plaf.LayerUI#doLayout(JLayer)} method,
71.301 + * if {@code LayerUI} is set.
71.302 + */
71.303 + public void doLayout() {
71.304 + if (getUI() != null) {
71.305 + getUI().doLayout(this);
71.306 + }
71.307 + }
71.308 +
71.309 + /**
71.310 * static AWTEventListener to be shared with all AbstractLayerUIs
71.311 */
71.312 private static class LayerEventController implements AWTEventListener {
71.313 @@ -625,8 +696,8 @@
71.314 JLayer l = (JLayer) component;
71.315 LayerUI ui = l.getUI();
71.316 if (ui != null &&
71.317 - isEventEnabled(l.getLayerEventMask(),
71.318 - event.getID())) {
71.319 + isEventEnabled(l.getLayerEventMask(), event.getID()) &&
71.320 + (!(event instanceof InputEvent) || !((InputEvent)event).isConsumed())) {
71.321 ui.eventDispatched(event, l);
71.322 }
71.323 }
71.324 @@ -758,82 +829,4 @@
71.325 return super.contains(x, y);
71.326 }
71.327 }
71.328 -
71.329 - /**
71.330 - * The default layout manager for the {@link javax.swing.JLayer}.<br/>
71.331 - * It places the glassPane on top of the view component
71.332 - * and makes it the same size as {@code JLayer},
71.333 - * it also makes the view component the same size but minus layer's insets<br/>
71.334 - */
71.335 - private static class DefaultLayerLayout implements LayoutManager, Serializable {
71.336 - /**
71.337 - * {@inheritDoc}
71.338 - */
71.339 - public void layoutContainer(Container parent) {
71.340 - JLayer layer = (JLayer) parent;
71.341 - Component view = layer.getView();
71.342 - Component glassPane = layer.getGlassPane();
71.343 - if (view != null) {
71.344 - Insets insets = layer.getInsets();
71.345 - view.setLocation(insets.left, insets.top);
71.346 - view.setSize(layer.getWidth() - insets.left - insets.right,
71.347 - layer.getHeight() - insets.top - insets.bottom);
71.348 - }
71.349 - if (glassPane != null) {
71.350 - glassPane.setLocation(0, 0);
71.351 - glassPane.setSize(layer.getWidth(), layer.getHeight());
71.352 - }
71.353 - }
71.354 -
71.355 - /**
71.356 - * {@inheritDoc}
71.357 - */
71.358 - public Dimension minimumLayoutSize(Container parent) {
71.359 - JLayer layer = (JLayer) parent;
71.360 - Insets insets = layer.getInsets();
71.361 - Dimension ret = new Dimension(insets.left + insets.right,
71.362 - insets.top + insets.bottom);
71.363 - Component view = layer.getView();
71.364 - if (view != null) {
71.365 - Dimension size = view.getMinimumSize();
71.366 - ret.width += size.width;
71.367 - ret.height += size.height;
71.368 - }
71.369 - if (ret.width == 0 || ret.height == 0) {
71.370 - ret.width = ret.height = 4;
71.371 - }
71.372 - return ret;
71.373 - }
71.374 -
71.375 - /**
71.376 - * {@inheritDoc}
71.377 - */
71.378 - public Dimension preferredLayoutSize(Container parent) {
71.379 - JLayer layer = (JLayer) parent;
71.380 - Insets insets = layer.getInsets();
71.381 - Dimension ret = new Dimension(insets.left + insets.right,
71.382 - insets.top + insets.bottom);
71.383 - Component view = layer.getView();
71.384 - if (view != null) {
71.385 - Dimension size = view.getPreferredSize();
71.386 - if (size.width > 0 && size.height > 0) {
71.387 - ret.width += size.width;
71.388 - ret.height += size.height;
71.389 - }
71.390 - }
71.391 - return ret;
71.392 - }
71.393 -
71.394 - /**
71.395 - * {@inheritDoc}
71.396 - */
71.397 - public void addLayoutComponent(String name, Component comp) {
71.398 - }
71.399 -
71.400 - /**
71.401 - * {@inheritDoc}
71.402 - */
71.403 - public void removeLayoutComponent(Component comp) {
71.404 - }
71.405 - }
71.406 }
72.1 --- a/src/share/classes/javax/swing/JTable.java Tue Oct 12 13:34:59 2010 -0400
72.2 +++ b/src/share/classes/javax/swing/JTable.java Mon Oct 18 11:25:28 2010 -0400
72.3 @@ -4574,9 +4574,8 @@
72.4 * @see TableColumnModelListener
72.5 */
72.6 public void columnMoved(TableColumnModelEvent e) {
72.7 - // If I'm currently editing, then I should stop editing
72.8 - if (isEditing()) {
72.9 - removeEditor();
72.10 + if (isEditing() && !getCellEditor().stopCellEditing()) {
72.11 + getCellEditor().cancelCellEditing();
72.12 }
72.13 repaint();
72.14 }
72.15 @@ -4593,8 +4592,8 @@
72.16 * @see TableColumnModelListener
72.17 */
72.18 public void columnMarginChanged(ChangeEvent e) {
72.19 - if (isEditing()) {
72.20 - removeEditor();
72.21 + if (isEditing() && !getCellEditor().stopCellEditing()) {
72.22 + getCellEditor().cancelCellEditing();
72.23 }
72.24 TableColumn resizingColumn = getResizingColumn();
72.25 // Need to do this here, before the parent's
73.1 --- a/src/share/classes/javax/swing/ToolTipManager.java Tue Oct 12 13:34:59 2010 -0400
73.2 +++ b/src/share/classes/javax/swing/ToolTipManager.java Mon Oct 18 11:25:28 2010 -0400
73.3 @@ -459,7 +459,7 @@
73.4 if (insideComponent == null) {
73.5 // Drag exit
73.6 }
73.7 - if (window != null && event.getSource() == window) {
73.8 + if (window != null && event.getSource() == window && insideComponent != null) {
73.9 // if we get an exit and have a heavy window
73.10 // we need to check if it if overlapping the inside component
73.11 Container insideComponentWindow = insideComponent.getTopLevelAncestor();
74.1 --- a/src/share/classes/javax/swing/plaf/LayerUI.java Tue Oct 12 13:34:59 2010 -0400
74.2 +++ b/src/share/classes/javax/swing/plaf/LayerUI.java Mon Oct 18 11:25:28 2010 -0400
74.3 @@ -600,104 +600,6 @@
74.4 }
74.5
74.6 /**
74.7 - * Returns the preferred size of the viewport for a view component.
74.8 - *
74.9 - * @param l the {@code JLayer} component where this UI delegate is being installed
74.10 - * @return the preferred size of the viewport for a view component
74.11 - * @see Scrollable#getPreferredScrollableViewportSize()
74.12 - */
74.13 - public Dimension getPreferredScrollableViewportSize(JLayer<? extends V> l) {
74.14 - if (l.getView() instanceof Scrollable) {
74.15 - return ((Scrollable)l.getView()).getPreferredScrollableViewportSize();
74.16 - }
74.17 - return l.getPreferredSize();
74.18 - }
74.19 -
74.20 - /**
74.21 - * Returns a scroll increment, which is required for components
74.22 - * that display logical rows or columns in order to completely expose
74.23 - * one block of rows or columns, depending on the value of orientation.
74.24 - *
74.25 - * @param l the {@code JLayer} component where this UI delegate is being installed
74.26 - * @param visibleRect The view area visible within the viewport
74.27 - * @param orientation Either SwingConstants.VERTICAL or SwingConstants.HORIZONTAL.
74.28 - * @param direction Less than zero to scroll up/left, greater than zero for down/right.
74.29 - * @return the "block" increment for scrolling in the specified direction
74.30 - * @see Scrollable#getScrollableBlockIncrement(Rectangle, int, int)
74.31 - */
74.32 - public int getScrollableBlockIncrement(JLayer<? extends V> l,
74.33 - Rectangle visibleRect,
74.34 - int orientation, int direction) {
74.35 - if (l.getView() instanceof Scrollable) {
74.36 - return ((Scrollable)l.getView()).getScrollableBlockIncrement(
74.37 - visibleRect,orientation, direction);
74.38 - }
74.39 - return (orientation == SwingConstants.VERTICAL) ? visibleRect.height :
74.40 - visibleRect.width;
74.41 - }
74.42 -
74.43 - /**
74.44 - * Returns {@code false} to indicate that the height of the viewport does not
74.45 - * determine the height of the layer, unless the preferred height
74.46 - * of the layer is smaller than the height of the viewport.
74.47 - *
74.48 - * @param l the {@code JLayer} component where this UI delegate is being installed
74.49 - * @return whether the layer should track the height of the viewport
74.50 - * @see Scrollable#getScrollableTracksViewportHeight()
74.51 - */
74.52 - public boolean getScrollableTracksViewportHeight(JLayer<? extends V> l) {
74.53 - if (l.getView() instanceof Scrollable) {
74.54 - return ((Scrollable)l.getView()).getScrollableTracksViewportHeight();
74.55 - }
74.56 - return false;
74.57 - }
74.58 -
74.59 - /**
74.60 - * Returns {@code false} to indicate that the width of the viewport does not
74.61 - * determine the width of the layer, unless the preferred width
74.62 - * of the layer is smaller than the width of the viewport.
74.63 - *
74.64 - * @param l the {@code JLayer} component where this UI delegate is being installed
74.65 - * @return whether the layer should track the width of the viewport
74.66 - * @see Scrollable
74.67 - * @see LayerUI#getScrollableTracksViewportWidth(JLayer)
74.68 - */
74.69 - public boolean getScrollableTracksViewportWidth(JLayer<? extends V> l) {
74.70 - if (l.getView() instanceof Scrollable) {
74.71 - return ((Scrollable)l.getView()).getScrollableTracksViewportWidth();
74.72 - }
74.73 - return false;
74.74 - }
74.75 -
74.76 - /**
74.77 - * Returns a scroll increment, which is required for components
74.78 - * that display logical rows or columns in order to completely expose
74.79 - * one new row or column, depending on the value of orientation.
74.80 - * Ideally, components should handle a partially exposed row or column
74.81 - * by returning the distance required to completely expose the item.
74.82 - * <p>
74.83 - * Scrolling containers, like JScrollPane, will use this method
74.84 - * each time the user requests a unit scroll.
74.85 - *
74.86 - * @param l the {@code JLayer} component where this UI delegate is being installed
74.87 - * @param visibleRect The view area visible within the viewport
74.88 - * @param orientation Either SwingConstants.VERTICAL or SwingConstants.HORIZONTAL.
74.89 - * @param direction Less than zero to scroll up/left, greater than zero for down/right.
74.90 - * @return The "unit" increment for scrolling in the specified direction.
74.91 - * This value should always be positive.
74.92 - * @see Scrollable#getScrollableUnitIncrement(Rectangle, int, int)
74.93 - */
74.94 - public int getScrollableUnitIncrement(JLayer<? extends V> l,
74.95 - Rectangle visibleRect,
74.96 - int orientation, int direction) {
74.97 - if (l.getView() instanceof Scrollable) {
74.98 - return ((Scrollable)l.getView()).getScrollableUnitIncrement(
74.99 - visibleRect, orientation, direction);
74.100 - }
74.101 - return 1;
74.102 - }
74.103 -
74.104 - /**
74.105 * If the {@code JLayer}'s view component is not {@code null},
74.106 * this calls the view's {@code getBaseline()} method.
74.107 * Otherwise, the default implementation is called.
74.108 @@ -718,7 +620,7 @@
74.109
74.110 /**
74.111 * If the {@code JLayer}'s view component is not {@code null},
74.112 - * this calls the view's {@code getBaselineResizeBehavior()} method.
74.113 + * this returns the result of the view's {@code getBaselineResizeBehavior()} method.
74.114 * Otherwise, the default implementation is called.
74.115 *
74.116 * @param c {@code JLayer} to return baseline resize behavior for
74.117 @@ -732,4 +634,90 @@
74.118 }
74.119 return super.getBaselineResizeBehavior(c);
74.120 }
74.121 +
74.122 + /**
74.123 + * Causes the passed instance of {@code JLayer} to lay out its components.
74.124 + *
74.125 + * @param l the {@code JLayer} component where this UI delegate is being installed
74.126 + */
74.127 + public void doLayout(JLayer<? extends V> l) {
74.128 + Component view = l.getView();
74.129 + if (view != null) {
74.130 + view.setBounds(0, 0, l.getWidth(), l.getHeight());
74.131 + }
74.132 + Component glassPane = l.getGlassPane();
74.133 + if (glassPane != null) {
74.134 + glassPane.setBounds(0, 0, l.getWidth(), l.getHeight());
74.135 + }
74.136 + }
74.137 +
74.138 + /**
74.139 + * If the {@code JLayer}'s view component is not {@code null},
74.140 + * this returns the result of the view's {@code getPreferredSize()} method.
74.141 + * Otherwise, the default implementation is used.
74.142 + *
74.143 + * @param c {@code JLayer} to return preferred size for
74.144 + * @return preferred size for the passed {@code JLayer}
74.145 + */
74.146 + public Dimension getPreferredSize(JComponent c) {
74.147 + JLayer l = (JLayer) c;
74.148 + Component view = l.getView();
74.149 + if (view != null) {
74.150 + return view.getPreferredSize();
74.151 + }
74.152 + return super.getPreferredSize(c);
74.153 + }
74.154 +
74.155 + /**
74.156 + * If the {@code JLayer}'s view component is not {@code null},
74.157 + * this returns the result of the view's {@code getMinimalSize()} method.
74.158 + * Otherwise, the default implementation is used.
74.159 + *
74.160 + * @param c {@code JLayer} to return preferred size for
74.161 + * @return minimal size for the passed {@code JLayer}
74.162 + */
74.163 + public Dimension getMinimumSize(JComponent c) {
74.164 + JLayer l = (JLayer) c;
74.165 + Component view = l.getView();
74.166 + if (view != null) {
74.167 + return view.getMinimumSize();
74.168 + }
74.169 + return super.getMinimumSize(c);
74.170 + }
74.171 +
74.172 + /**
74.173 + * If the {@code JLayer}'s view component is not {@code null},
74.174 + * this returns the result of the view's {@code getMaximumSize()} method.
74.175 + * Otherwise, the default implementation is used.
74.176 + *
74.177 + * @param c {@code JLayer} to return preferred size for
74.178 + * @return maximun size for the passed {@code JLayer}
74.179 + */
74.180 + public Dimension getMaximumSize(JComponent c) {
74.181 + JLayer l = (JLayer) c;
74.182 + Component view = l.getView();
74.183 + if (view != null) {
74.184 + return view.getMaximumSize();
74.185 + }
74.186 + return super.getMaximumSize(c);
74.187 + }
74.188 +
74.189 + /**
74.190 + * Adds the specified region to the dirty region list if the component
74.191 + * is showing. The component will be repainted after all of the
74.192 + * currently pending events have been dispatched.
74.193 + * <p/>
74.194 + * This method is to be overridden when the dirty region needs to be changed.
74.195 + *
74.196 + * @param tm this parameter is not used
74.197 + * @param x the x value of the dirty region
74.198 + * @param y the y value of the dirty region
74.199 + * @param width the width of the dirty region
74.200 + * @param height the height of the dirty region
74.201 + * @see java.awt.Component#isShowing
74.202 + * @see RepaintManager#addDirtyRegion
74.203 + */
74.204 + public void repaint(long tm, int x, int y, int width, int height, JLayer<? extends V> l) {
74.205 + RepaintManager.currentManager(l).addDirtyRegion(l, x, y, width, height);
74.206 + }
74.207 }
75.1 --- a/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java Tue Oct 12 13:34:59 2010 -0400
75.2 +++ b/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java Mon Oct 18 11:25:28 2010 -0400
75.3 @@ -1603,6 +1603,7 @@
75.4 BoundedRangeModel newModel = (BoundedRangeModel)e.getNewValue();
75.5 oldModel.removeChangeListener(modelListener);
75.6 newModel.addChangeListener(modelListener);
75.7 + scrollBarValue = scrollbar.getValue();
75.8 scrollbar.repaint();
75.9 scrollbar.revalidate();
75.10 } else if ("orientation" == propertyName) {
76.1 --- a/src/share/classes/javax/swing/plaf/metal/MetalComboBoxUI.java Tue Oct 12 13:34:59 2010 -0400
76.2 +++ b/src/share/classes/javax/swing/plaf/metal/MetalComboBoxUI.java Mon Oct 18 11:25:28 2010 -0400
76.3 @@ -144,7 +144,7 @@
76.4 */
76.5 public int getBaseline(JComponent c, int width, int height) {
76.6 int baseline;
76.7 - if (MetalLookAndFeel.usingOcean()) {
76.8 + if (MetalLookAndFeel.usingOcean() && height >= 4) {
76.9 height -= 4;
76.10 baseline = super.getBaseline(c, width, height);
76.11 if (baseline >= 0) {
77.1 --- a/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java Tue Oct 12 13:34:59 2010 -0400
77.2 +++ b/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java Mon Oct 18 11:25:28 2010 -0400
77.3 @@ -115,6 +115,9 @@
77.4 return new SynthTabbedPaneUI();
77.5 }
77.6
77.7 + private SynthTabbedPaneUI() {
77.8 + }
77.9 +
77.10 private boolean scrollableTabLayoutEnabled() {
77.11 return (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT);
77.12 }
78.1 --- a/src/share/classes/sun/awt/AWTAccessor.java Tue Oct 12 13:34:59 2010 -0400
78.2 +++ b/src/share/classes/sun/awt/AWTAccessor.java Mon Oct 18 11:25:28 2010 -0400
78.3 @@ -344,6 +344,11 @@
78.4 * Removes the last focus request for the heavyweight from the queue.
78.5 */
78.6 void removeLastFocusRequest(Component heavyweight);
78.7 +
78.8 + /*
78.9 + * Sets the most recent focus owner in the window.
78.10 + */
78.11 + void setMostRecentFocusOwner(Window window, Component component);
78.12 }
78.13
78.14 /*
79.1 --- a/src/share/classes/sun/awt/EmbeddedFrame.java Tue Oct 12 13:34:59 2010 -0400
79.2 +++ b/src/share/classes/sun/awt/EmbeddedFrame.java Mon Oct 18 11:25:28 2010 -0400
79.3 @@ -70,7 +70,10 @@
79.4 // JDK 1.1 compatibility
79.5 private static final long serialVersionUID = 2967042741780317130L;
79.6
79.7 - // Use these in traverseOut method to determine directions
79.8 + /*
79.9 + * The constants define focus traversal directions.
79.10 + * Use them in {@code traverseIn}, {@code traverseOut} methods.
79.11 + */
79.12 protected static final boolean FORWARD = true;
79.13 protected static final boolean BACKWARD = false;
79.14
79.15 @@ -284,6 +287,41 @@
79.16 }
79.17
79.18 /**
79.19 + * This method is called by the embedder when we should receive focus as element
79.20 + * of the traversal chain. The method requests focus on:
79.21 + * 1. the first Component of this EmbeddedFrame if user moves focus forward
79.22 + * in the focus traversal cycle.
79.23 + * 2. the last Component of this EmbeddedFrame if user moves focus backward
79.24 + * in the focus traversal cycle.
79.25 + *
79.26 + * The direction parameter specifies which of the two mentioned cases is
79.27 + * happening. Use FORWARD and BACKWARD constants defined in the EmbeddedFrame class
79.28 + * to avoid confusing boolean values.
79.29 + *
79.30 + * A concrete implementation of this method is defined in the platform-dependent
79.31 + * subclasses.
79.32 + *
79.33 + * @param direction FORWARD or BACKWARD
79.34 + * @return true, if the EmbeddedFrame wants to get focus, false otherwise.
79.35 + */
79.36 + public boolean traverseIn(boolean direction) {
79.37 + Component comp = null;
79.38 +
79.39 + if (direction == FORWARD) {
79.40 + comp = getFocusTraversalPolicy().getFirstComponent(this);
79.41 + } else {
79.42 + comp = getFocusTraversalPolicy().getLastComponent(this);
79.43 + }
79.44 + if (comp != null) {
79.45 + // comp.requestFocus(); - Leads to a hung.
79.46 +
79.47 + AWTAccessor.getKeyboardFocusManagerAccessor().setMostRecentFocusOwner(this, comp);
79.48 + synthesizeWindowActivation(true);
79.49 + }
79.50 + return (null != comp);
79.51 + }
79.52 +
79.53 + /**
79.54 * This method is called from dispatchKeyEvent in the following two cases:
79.55 * 1. The focus is on the first Component of this EmbeddedFrame and we are
79.56 * about to transfer the focus backward.
80.1 --- a/src/share/classes/sun/net/www/http/HttpClient.java Tue Oct 12 13:34:59 2010 -0400
80.2 +++ b/src/share/classes/sun/net/www/http/HttpClient.java Mon Oct 18 11:25:28 2010 -0400
80.3 @@ -55,6 +55,9 @@
80.4 // Http data we send with the headers
80.5 PosterOutputStream poster = null;
80.6
80.7 + // true if we are in streaming mode (fixed length or chunked)
80.8 + boolean streaming;
80.9 +
80.10 // if we've had one io error
80.11 boolean failedOnce = false;
80.12
80.13 @@ -275,6 +278,10 @@
80.14 ret.cachedHttpClient = true;
80.15 assert ret.inCache;
80.16 ret.inCache = false;
80.17 + PlatformLogger logger = HttpURLConnection.getHttpLogger();
80.18 + if (logger.isLoggable(PlatformLogger.FINEST)) {
80.19 + logger.finest("KeepAlive stream retrieved from the cache, " + ret);
80.20 + }
80.21 }
80.22 } else {
80.23 // We cannot return this connection to the cache as it's
80.24 @@ -545,6 +552,13 @@
80.25 serverOutput.flush();
80.26 }
80.27
80.28 + public void writeRequests(MessageHeader head,
80.29 + PosterOutputStream pos,
80.30 + boolean streaming) throws IOException {
80.31 + this.streaming = streaming;
80.32 + writeRequests(head, pos);
80.33 + }
80.34 +
80.35 /** Parse the first line of the HTTP request. It usually looks
80.36 something like: "HTTP/1.0 <number> comment\r\n". */
80.37
80.38 @@ -577,11 +591,11 @@
80.39 closeServer();
80.40 cachedHttpClient = false;
80.41 if (!failedOnce && requests != null) {
80.42 - if (httpuc.getRequestMethod().equals("POST") && !retryPostProp) {
80.43 + failedOnce = true;
80.44 + if (httpuc.getRequestMethod().equals("POST") && (!retryPostProp || streaming)) {
80.45 // do not retry the request
80.46 } else {
80.47 // try once more
80.48 - failedOnce = true;
80.49 openServer();
80.50 if (needsTunneling()) {
80.51 httpuc.doTunneling();
80.52 @@ -684,10 +698,10 @@
80.53 }
80.54 } else if (nread != 8) {
80.55 if (!failedOnce && requests != null) {
80.56 - if (httpuc.getRequestMethod().equals("POST") && !retryPostProp) {
80.57 + failedOnce = true;
80.58 + if (httpuc.getRequestMethod().equals("POST") && (!retryPostProp || streaming)) {
80.59 // do not retry the request
80.60 } else {
80.61 - failedOnce = true;
80.62 closeServer();
80.63 cachedHttpClient = false;
80.64 openServer();
81.1 --- a/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Tue Oct 12 13:34:59 2010 -0400
81.2 +++ b/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Mon Oct 18 11:25:28 2010 -0400
81.3 @@ -494,7 +494,7 @@
81.4 if (logger.isLoggable(PlatformLogger.FINE)) {
81.5 logger.fine(requests.toString());
81.6 }
81.7 - http.writeRequests(requests, poster);
81.8 + http.writeRequests(requests, poster, streaming());
81.9 if (ps.checkError()) {
81.10 String proxyHost = http.getProxyHostUsed();
81.11 int proxyPort = http.getProxyPortUsed();
81.12 @@ -2825,6 +2825,38 @@
81.13 }
81.14 }
81.15
81.16 + /* skip() calls read() in order to ensure that entire response gets
81.17 + * cached. same implementation as InputStream.skip */
81.18 +
81.19 + private byte[] skipBuffer;
81.20 + private static final int SKIP_BUFFER_SIZE = 8096;
81.21 +
81.22 + @Override
81.23 + public long skip (long n) throws IOException {
81.24 +
81.25 + long remaining = n;
81.26 + int nr;
81.27 + if (skipBuffer == null)
81.28 + skipBuffer = new byte[SKIP_BUFFER_SIZE];
81.29 +
81.30 + byte[] localSkipBuffer = skipBuffer;
81.31 +
81.32 + if (n <= 0) {
81.33 + return 0;
81.34 + }
81.35 +
81.36 + while (remaining > 0) {
81.37 + nr = read(localSkipBuffer, 0,
81.38 + (int) Math.min(SKIP_BUFFER_SIZE, remaining));
81.39 + if (nr < 0) {
81.40 + break;
81.41 + }
81.42 + remaining -= nr;
81.43 + }
81.44 +
81.45 + return n - remaining;
81.46 + }
81.47 +
81.48 @Override
81.49 public void close () throws IOException {
81.50 try {
82.1 --- a/src/share/classes/sun/security/tools/KeyTool.java Tue Oct 12 13:34:59 2010 -0400
82.2 +++ b/src/share/classes/sun/security/tools/KeyTool.java Mon Oct 18 11:25:28 2010 -0400
82.3 @@ -281,7 +281,7 @@
82.4 RFC("rfc", null, "output in RFC style"),
82.5 SIGALG("sigalg", "<sigalg>", "signature algorithm name"),
82.6 SRCALIAS("srcalias", "<srcalias>", "source alias"),
82.7 - SRCKEYPASS("srckeypass", "<arg>", "source keystore password"),
82.8 + SRCKEYPASS("srckeypass", "<arg>", "source key password"),
82.9 SRCKEYSTORE("srckeystore", "<srckeystore>", "source keystore name"),
82.10 SRCPROTECTED("srcprotected", null, "source keystore password protected"),
82.11 SRCPROVIDERNAME("srcprovidername", "<srcprovidername>", "source keystore provider name"),
83.1 --- a/src/share/classes/sun/security/util/Resources.java Tue Oct 12 13:34:59 2010 -0400
83.2 +++ b/src/share/classes/sun/security/util/Resources.java Mon Oct 18 11:25:28 2010 -0400
83.3 @@ -116,11 +116,9 @@
83.4 {"X.509 extension",
83.5 "X.509 extension"}, //-ext
83.6 {"output file name",
83.7 - "output file name"}, //-file
83.8 + "output file name"}, //-file and -outfile
83.9 {"input file name",
83.10 - "input file name"}, //-file
83.11 - {"input file name",
83.12 - "input file name"}, //-infile
83.13 + "input file name"}, //-file and -infile
83.14 {"key algorithm name",
83.15 "key algorithm name"}, //-keyalg
83.16 {"key password",
83.17 @@ -133,8 +131,6 @@
83.18 "new password"}, //-new
83.19 {"do not prompt",
83.20 "do not prompt"}, //-noprompt
83.21 - {"output file name",
83.22 - "output file name"}, //-outfile
83.23 {"password through protected mechanism",
83.24 "password through protected mechanism"}, //-protected
83.25 {"provider argument",
83.26 @@ -151,8 +147,8 @@
83.27 "signature algorithm name"}, //-sigalg
83.28 {"source alias",
83.29 "source alias"}, //-srcalias
83.30 - {"source keystore password",
83.31 - "source keystore password"}, //-srckeypass
83.32 + {"source key password",
83.33 + "source key password"}, //-srckeypass
83.34 {"source keystore name",
83.35 "source keystore name"}, //-srckeystore
83.36 {"source keystore password protected",
83.37 @@ -276,8 +272,6 @@
83.38 "Alias <{0}> has no certificate"},
83.39 {"Key pair not generated, alias <alias> already exists",
83.40 "Key pair not generated, alias <{0}> already exists"},
83.41 - {"Cannot derive signature algorithm",
83.42 - "Cannot derive signature algorithm"},
83.43 {"Generating keysize bit keyAlgName key pair and self-signed certificate (sigAlgName) with a validity of validality days\n\tfor: x500Name",
83.44 "Generating {0} bit {1} key pair and self-signed certificate ({2}) with a validity of {3} days\n\tfor: {4}"},
83.45 {"Enter key password for <alias>", "Enter key password for <{0}>"},
83.46 @@ -321,8 +315,6 @@
83.47 {"Failed to parse input", "Failed to parse input"},
83.48 {"Empty input", "Empty input"},
83.49 {"Not X.509 certificate", "Not X.509 certificate"},
83.50 - {"Cannot derive signature algorithm",
83.51 - "Cannot derive signature algorithm"},
83.52 {"alias has no public key", "{0} has no public key"},
83.53 {"alias has no X.509 certificate", "{0} has no X.509 certificate"},
83.54 {"New certificate (self-signed):", "New certificate (self-signed):"},
83.55 @@ -552,7 +544,6 @@
83.56 {"package name", "package name"},
83.57 {"policy type", "policy type"},
83.58 {"property name", "property name"},
83.59 - {"provider name", "provider name"},
83.60 {"Principal List", "Principal List"},
83.61 {"Permission List", "Permission List"},
83.62 {"Code Base", "Code Base"},
84.1 --- a/src/share/classes/sun/util/locale/BaseLocale.java Tue Oct 12 13:34:59 2010 -0400
84.2 +++ b/src/share/classes/sun/util/locale/BaseLocale.java Mon Oct 18 11:25:28 2010 -0400
84.3 @@ -64,12 +64,14 @@
84.4
84.5 public static BaseLocale getInstance(String language, String script, String region, String variant) {
84.6 // JDK uses deprecated ISO639.1 language codes for he, yi and id
84.7 - if (AsciiUtil.caseIgnoreMatch(language, "he")) {
84.8 - language = "iw";
84.9 - } else if (AsciiUtil.caseIgnoreMatch(language, "yi")) {
84.10 - language = "ji";
84.11 - } else if (AsciiUtil.caseIgnoreMatch(language, "id")) {
84.12 - language = "in";
84.13 + if (language != null) {
84.14 + if (AsciiUtil.caseIgnoreMatch(language, "he")) {
84.15 + language = "iw";
84.16 + } else if (AsciiUtil.caseIgnoreMatch(language, "yi")) {
84.17 + language = "ji";
84.18 + } else if (AsciiUtil.caseIgnoreMatch(language, "id")) {
84.19 + language = "in";
84.20 + }
84.21 }
84.22
84.23 Key key = new Key(language, script, region, variant);
85.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
85.2 +++ b/src/share/demo/nio/zipfs/Demo.java Mon Oct 18 11:25:28 2010 -0400
85.3 @@ -0,0 +1,664 @@
85.4 +/*
85.5 + * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
85.6 + *
85.7 + * Redistribution and use in source and binary forms, with or without
85.8 + * modification, are permitted provided that the following conditions
85.9 + * are met:
85.10 + *
85.11 + * - Redistributions of source code must retain the above copyright
85.12 + * notice, this list of conditions and the following disclaimer.
85.13 + *
85.14 + * - Redistributions in binary form must reproduce the above copyright
85.15 + * notice, this list of conditions and the following disclaimer in the
85.16 + * documentation and/or other materials provided with the distribution.
85.17 + *
85.18 + * - Neither the name of Oracle nor the names of its
85.19 + * contributors may be used to endorse or promote products derived
85.20 + * from this software without specific prior written permission.
85.21 + *
85.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
85.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
85.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
85.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
85.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
85.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
85.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
85.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
85.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
85.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
85.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
85.33 + */
85.34 +
85.35 +import java.io.*;
85.36 +import java.nio.*;
85.37 +import java.nio.channels.*;
85.38 +import java.nio.file.*;
85.39 +import java.nio.file.attribute.*;
85.40 +import java.net.*;
85.41 +import java.text.DateFormat;
85.42 +import java.text.SimpleDateFormat;
85.43 +import java.util.*;
85.44 +
85.45 +import static java.nio.file.StandardOpenOption.*;
85.46 +import static java.nio.file.StandardCopyOption.*;
85.47 +
85.48 +/*
85.49 + * ZipFileSystem usage demo
85.50 + *
85.51 + * java [-cp .../zipfs.jar:./] Demo action ZipfileName [...]
85.52 + *
85.53 + * To deploy the provider, either copy the zipfs.jar into JDK/JRE
85.54 + * extensions directory or add
85.55 + * <JDK_HOME>/demo/nio/ZipFileSystem/zipfs.jar
85.56 + * into your class path as showed above.
85.57 + *
85.58 + * @author Xueming Shen
85.59 + */
85.60 +
85.61 +public class Demo {
85.62 +
85.63 + static enum Action {
85.64 + rename, // <java Demo rename zipfile src dst>
85.65 + // rename entry src to dst inside zipfile
85.66 +
85.67 + movein, // <java Demo movein zipfile src dst>
85.68 + // move an external src file into zipfile
85.69 + // as entry dst
85.70 +
85.71 + moveout, // <java Demo moveout zipfile src dst>
85.72 + // move a zipfile entry src out to dst
85.73 +
85.74 + copy, // <java Demo copy zipfile src dst>
85.75 + // copy entry src to dst inside zipfile
85.76 +
85.77 + copyin, // <java Demo copyin zipfile src dst>
85.78 + // copy an external src file into zipfile
85.79 + // as entry dst
85.80 +
85.81 + copyout, // <java Demo copyout zipfile src dst>
85.82 + // copy zipfile entry src" out to file dst
85.83 +
85.84 + zzmove, // <java Demo zzmove zfsrc zfdst path>
85.85 + // move entry path/dir from zfsrc to zfdst
85.86 +
85.87 + zzcopy, // <java Demo zzcopy zfsrc zfdst path>
85.88 + // copy path from zipfile zfsrc to zipfile
85.89 + // zfdst
85.90 +
85.91 + attrs, // <java Demo attrs zipfile path>
85.92 + // printout the attributes of entry path
85.93 +
85.94 + attrsspace, // <java Demo attrsspace zipfile path>
85.95 + // printout the storespace attrs of entry path
85.96 +
85.97 + setmtime, // <java Demo setmtime zipfile "MM/dd/yy-HH:mm:ss" path...>
85.98 + // set the lastModifiedTime of entry path
85.99 +
85.100 + lsdir, // <java Demo lsdir zipfile dir>
85.101 + // list dir's direct child files/dirs
85.102 +
85.103 + mkdir, // <java Demo mkdir zipfile dir>
85.104 +
85.105 + mkdirs, // <java Demo mkdirs zipfile dir>
85.106 +
85.107 + rmdirs, // <java Demo rmdirs zipfile dir>
85.108 +
85.109 + list, // <java Demo list zipfile [dir]>
85.110 + // recursively list all entries of dir
85.111 + // via DirectoryStream
85.112 +
85.113 + tlist, // <java Demo tlist zipfile [dir]>
85.114 + // list with buildDirTree=true
85.115 +
85.116 + vlist, // <java Demo vlist zipfile [dir]>
85.117 + // recursively verbose list all entries of
85.118 + // dir via DirectoryStream
85.119 +
85.120 + walk, // <java Demo walk zipfile [dir]>
85.121 + // recursively walk all entries of dir
85.122 + // via Files.walkFileTree
85.123 +
85.124 + twalk, // <java Demo twalk zipfile [dir]>
85.125 + // walk with buildDirTree=true
85.126 +
85.127 + extract, // <java Demo extract zipfile file [...]>
85.128 +
85.129 + update, // <java Demo extract zipfile file [...]>
85.130 +
85.131 + delete, // <java Demo delete zipfile file [...]>
85.132 +
85.133 + add, // <java Demo add zipfile file [...]>
85.134 +
85.135 + create, // <java Demo create zipfile file [...]>
85.136 + // create a new zipfile if it doesn't exit
85.137 + // and then add the file(s) into it.
85.138 +
85.139 + attrs2, // <java Demo attrs2 zipfile file [...]>
85.140 + // test different ways to print attrs
85.141 + }
85.142 +
85.143 + public static void main(String[] args) throws Throwable {
85.144 +
85.145 + Action action = Action.valueOf(args[0]);;
85.146 + Map<String, Object> env = env = new HashMap<String, Object>();
85.147 + if (action == Action.create)
85.148 + env.put("createNew", true);
85.149 + if (action == Action.tlist || action == Action.twalk)
85.150 + env.put("buildDirTree", true);
85.151 +
85.152 + FileSystem fs = FileSystems.newFileSystem(
85.153 + URI.create("zip" + Paths.get(args[1]).toUri().toString().substring(4)),
85.154 + env,
85.155 + null);
85.156 + try {
85.157 + FileSystem fs2;
85.158 + Path path, src, dst;
85.159 + boolean isRename = false;
85.160 + switch (action) {
85.161 + case rename:
85.162 + src = fs.getPath(args[2]);
85.163 + dst = fs.getPath(args[3]);
85.164 + src.moveTo(dst);
85.165 + break;
85.166 + case moveout:
85.167 + src = fs.getPath(args[2]);
85.168 + dst = Paths.get(args[3]);
85.169 + src.moveTo(dst);
85.170 + break;
85.171 + case movein:
85.172 + src = Paths.get(args[2]);
85.173 + dst = fs.getPath(args[3]);
85.174 + src.moveTo(dst);
85.175 + break;
85.176 + case copy:
85.177 + src = fs.getPath(args[2]);
85.178 + dst = fs.getPath(args[3]);
85.179 + src.copyTo(dst);
85.180 + break;
85.181 + case copyout:
85.182 + src = fs.getPath(args[2]);
85.183 + dst = Paths.get(args[3]);
85.184 + src.copyTo(dst);
85.185 + break;
85.186 + case copyin:
85.187 + src = Paths.get(args[2]);
85.188 + dst = fs.getPath(args[3]);
85.189 + src.copyTo(dst);
85.190 + break;
85.191 + case zzmove:
85.192 + fs2 = FileSystems.newFileSystem(
85.193 + URI.create("zip" + Paths.get(args[2]).toUri().toString().substring(4)),
85.194 + env,
85.195 + null);
85.196 + //sf1.getPath(args[3]).moveTo(fs2.getPath(args[3]));
85.197 + z2zmove(fs, fs2, args[3]);
85.198 + fs2.close();
85.199 + break;
85.200 + case zzcopy:
85.201 + fs2 = FileSystems.newFileSystem(
85.202 + URI.create("zip" + Paths.get(args[2]).toUri().toString().substring(4)),
85.203 + env,
85.204 + null);
85.205 + //sf1.getPath(args[3]).copyTo(fs2.getPath(args[3]));
85.206 + z2zcopy(fs, fs2, args[3]);
85.207 + fs2.close();
85.208 + break;
85.209 + case attrs:
85.210 + for (int i = 2; i < args.length; i++) {
85.211 + path = fs.getPath(args[i]);
85.212 + System.out.println(
85.213 + Attributes.readBasicFileAttributes(path).toString());
85.214 + }
85.215 + break;
85.216 + case setmtime:
85.217 + DateFormat df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss");
85.218 + Date newDatetime = df.parse(args[2]);
85.219 + for (int i = 3; i < args.length; i++) {
85.220 + path = fs.getPath(args[i]);
85.221 + path.setAttribute("lastModifiedTime",
85.222 + FileTime.fromMillis(newDatetime.getTime()));
85.223 + System.out.println(
85.224 + Attributes.readBasicFileAttributes(path).toString());
85.225 + }
85.226 + break;
85.227 + case attrsspace:
85.228 + path = fs.getPath("/");
85.229 + FileStore fstore = path.getFileStore();
85.230 + //System.out.println(fstore.getFileStoreAttributeView(FileStoreSpaceAttributeView.class)
85.231 + // .readAttributes());
85.232 + // or
85.233 + System.out.printf("filestore[%s]%n", fstore.name());
85.234 + System.out.printf(" totalSpace: %d%n",
85.235 + (Long)fstore.getAttribute("space:totalSpace"));
85.236 + System.out.printf(" usableSpace: %d%n",
85.237 + (Long)fstore.getAttribute("space:usableSpace"));
85.238 + System.out.printf(" unallocSpace: %d%n",
85.239 + (Long)fstore.getAttribute("space:unallocatedSpace"));
85.240 + break;
85.241 + case list:
85.242 + case tlist:
85.243 + if (args.length < 3)
85.244 + list(fs.getPath("/"), false);
85.245 + else
85.246 + list(fs.getPath(args[2]), false);
85.247 + break;
85.248 + case vlist:
85.249 + if (args.length < 3)
85.250 + list(fs.getPath("/"), true);
85.251 + else
85.252 + list(fs.getPath(args[2]), true);
85.253 + break;
85.254 + case twalk:
85.255 + case walk:
85.256 + walk(fs.getPath((args.length > 2)? args[2] : "/"));
85.257 + break;
85.258 + case extract:
85.259 + if (args.length == 2) {
85.260 + extract(fs, "/");
85.261 + } else {
85.262 + for (int i = 2; i < args.length; i++) {
85.263 + extract(fs, args[i]);
85.264 + }
85.265 + }
85.266 + break;
85.267 + case delete:
85.268 + for (int i = 2; i < args.length; i++)
85.269 + fs.getPath(args[i]).delete();
85.270 + break;
85.271 + case create:
85.272 + case add:
85.273 + case update:
85.274 + for (int i = 2; i < args.length; i++) {
85.275 + update(fs, args[i]);
85.276 + }
85.277 + break;
85.278 + case lsdir:
85.279 + path = fs.getPath(args[2]);
85.280 + final String fStr = (args.length > 3)?args[3]:"";
85.281 + DirectoryStream<Path> ds = path.newDirectoryStream(
85.282 + new DirectoryStream.Filter<Path>() {
85.283 + public boolean accept(Path path) {
85.284 + return path.toString().contains(fStr);
85.285 + }
85.286 + });
85.287 + for (Path p : ds)
85.288 + System.out.println(p);
85.289 + break;
85.290 + case mkdir:
85.291 + fs.getPath(args[2]).createDirectory();
85.292 + break;
85.293 + case mkdirs:
85.294 + mkdirs(fs.getPath(args[2]));
85.295 + break;
85.296 + case attrs2:
85.297 + for (int i = 2; i < args.length; i++) {
85.298 + path = fs.getPath(args[i]);
85.299 + System.out.println("-------(1)---------");
85.300 + System.out.println(
85.301 + Attributes.readBasicFileAttributes(path).toString());
85.302 + System.out.println("-------(2)---------");
85.303 + Map<String, ?> map = path.readAttributes("zip:*");
85.304 + for (Map.Entry<String, ?> e : map.entrySet()) {
85.305 + System.out.printf(" %s : %s%n", e.getKey(), e.getValue());
85.306 + }
85.307 + System.out.println("-------(3)---------");
85.308 + map = path.readAttributes("size,lastModifiedTime,isDirectory");
85.309 + for (Map.Entry<String, ?> e : map.entrySet()) {
85.310 + System.out.printf(" %s : %s%n", e.getKey(), e.getValue());
85.311 + }
85.312 + }
85.313 + break;
85.314 + }
85.315 + } catch (Exception x) {
85.316 + x.printStackTrace();
85.317 + } finally {
85.318 + if (fs != null)
85.319 + fs.close();
85.320 + }
85.321 + }
85.322 +
85.323 + private static byte[] getBytes(String name) {
85.324 + return name.getBytes();
85.325 + }
85.326 +
85.327 + private static String getString(byte[] name) {
85.328 + return new String(name);
85.329 + }
85.330 +
85.331 + private static void walk(Path path) throws IOException
85.332 + {
85.333 + Files.walkFileTree(
85.334 + path,
85.335 + new SimpleFileVisitor<Path>() {
85.336 + private int indent = 0;
85.337 + private void indent() {
85.338 + int n = 0;
85.339 + while (n++ < indent)
85.340 + System.out.printf(" ");
85.341 + }
85.342 +
85.343 + @Override
85.344 + public FileVisitResult visitFile(Path file,
85.345 + BasicFileAttributes attrs)
85.346 + {
85.347 + indent();
85.348 + System.out.printf("%s%n", file.getName().toString());
85.349 + return FileVisitResult.CONTINUE;
85.350 + }
85.351 +
85.352 + @Override
85.353 + public FileVisitResult preVisitDirectory(Path dir,
85.354 + BasicFileAttributes attrs)
85.355 + {
85.356 + indent();
85.357 + System.out.printf("[%s]%n", dir.toString());
85.358 + indent += 2;
85.359 + return FileVisitResult.CONTINUE;
85.360 + }
85.361 +
85.362 + @Override
85.363 + public FileVisitResult postVisitDirectory(Path dir,
85.364 + IOException ioe)
85.365 + {
85.366 + indent -= 2;
85.367 + return FileVisitResult.CONTINUE;
85.368 + }
85.369 + });
85.370 + }
85.371 +
85.372 + private static void update(FileSystem fs, String path) throws Throwable{
85.373 + Path src = FileSystems.getDefault().getPath(path);
85.374 + if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) {
85.375 + DirectoryStream<Path> ds = src.newDirectoryStream();
85.376 + for (Path child : ds)
85.377 + update(fs, child.toString());
85.378 + ds.close();
85.379 + } else {
85.380 + Path dst = fs.getPath(path);
85.381 + Path parent = dst.getParent();
85.382 + if (parent != null && parent.notExists())
85.383 + mkdirs(parent);
85.384 + src.copyTo(dst, REPLACE_EXISTING);
85.385 + }
85.386 + }
85.387 +
85.388 + private static void extract(FileSystem fs, String path) throws Throwable{
85.389 + Path src = fs.getPath(path);
85.390 + if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) {
85.391 + DirectoryStream<Path> ds = src.newDirectoryStream();
85.392 + for (Path child : ds)
85.393 + extract(fs, child.toString());
85.394 + ds.close();
85.395 + } else {
85.396 + if (path.startsWith("/"))
85.397 + path = path.substring(1);
85.398 + Path dst = FileSystems.getDefault().getPath(path);
85.399 + Path parent = dst.getParent();
85.400 + if (parent.notExists())
85.401 + mkdirs(parent);
85.402 + src.copyTo(dst, REPLACE_EXISTING);
85.403 + }
85.404 + }
85.405 +
85.406 + // use DirectoryStream
85.407 + private static void z2zcopy(FileSystem src, FileSystem dst, String path)
85.408 + throws IOException
85.409 + {
85.410 + Path srcPath = src.getPath(path);
85.411 + Path dstPath = dst.getPath(path);
85.412 +
85.413 + if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) {
85.414 + if (!dstPath.exists()) {
85.415 + try {
85.416 + mkdirs(dstPath);
85.417 + } catch (FileAlreadyExistsException x) {}
85.418 + }
85.419 + DirectoryStream<Path> ds = srcPath.newDirectoryStream();
85.420 + for (Path child : ds) {
85.421 + z2zcopy(src, dst,
85.422 + path + (path.endsWith("/")?"":"/") + child.getName());
85.423 + }
85.424 + ds.close();
85.425 + } else {
85.426 + //System.out.println("copying..." + path);
85.427 + srcPath.copyTo(dstPath);
85.428 + }
85.429 + }
85.430 +
85.431 + // use TreeWalk to move
85.432 + private static void z2zmove(FileSystem src, FileSystem dst, String path)
85.433 + throws IOException
85.434 + {
85.435 + final Path srcPath = src.getPath(path).toAbsolutePath();
85.436 + final Path dstPath = dst.getPath(path).toAbsolutePath();
85.437 +
85.438 + Files.walkFileTree(srcPath, new SimpleFileVisitor<Path>() {
85.439 +
85.440 + @Override
85.441 + public FileVisitResult visitFile(Path file,
85.442 + BasicFileAttributes attrs)
85.443 + {
85.444 + Path dst = srcPath.relativize(file);
85.445 + dst = dstPath.resolve(dst);
85.446 + try {
85.447 + Path parent = dstPath.getParent();
85.448 + if (parent != null && parent.notExists())
85.449 + mkdirs(parent);
85.450 + file.moveTo(dst);
85.451 + } catch (IOException x) {
85.452 + x.printStackTrace();
85.453 + }
85.454 + return FileVisitResult.CONTINUE;
85.455 + }
85.456 +
85.457 + @Override
85.458 + public FileVisitResult preVisitDirectory(Path dir,
85.459 + BasicFileAttributes attrs)
85.460 + {
85.461 + Path dst = srcPath.relativize(dir);
85.462 + dst = dstPath.resolve(dst);
85.463 + try {
85.464 +
85.465 + if (dst.notExists())
85.466 + mkdirs(dst);
85.467 + } catch (IOException x) {
85.468 + x.printStackTrace();
85.469 + }
85.470 + return FileVisitResult.CONTINUE;
85.471 + }
85.472 +
85.473 + @Override
85.474 + public FileVisitResult postVisitDirectory(Path dir,
85.475 + IOException ioe)
85.476 + throws IOException
85.477 + {
85.478 + try {
85.479 + dir.delete();
85.480 + } catch (IOException x) {
85.481 + //x.printStackTrace();
85.482 + }
85.483 + return FileVisitResult.CONTINUE;
85.484 + }
85.485 + });
85.486 +
85.487 + }
85.488 +
85.489 + private static void mkdirs(Path path) throws IOException {
85.490 + path = path.toAbsolutePath();
85.491 + Path parent = path.getParent();
85.492 + if (parent != null) {
85.493 + if (parent.notExists())
85.494 + mkdirs(parent);
85.495 + }
85.496 + path.createDirectory();
85.497 + }
85.498 +
85.499 + private static void rmdirs(Path path) throws IOException {
85.500 + while (path != null && path.getNameCount() != 0) {
85.501 + path.delete();
85.502 + path = path.getParent();
85.503 + }
85.504 + }
85.505 +
85.506 + private static void list(Path path, boolean verbose ) throws IOException {
85.507 + if (verbose)
85.508 + System.out.println(Attributes.readBasicFileAttributes(path).toString());
85.509 + else
85.510 + System.out.printf(" %s%n", path.toString());
85.511 + if (path.notExists())
85.512 + return;
85.513 + if (Attributes.readBasicFileAttributes(path).isDirectory()) {
85.514 + DirectoryStream<Path> ds = path.newDirectoryStream();
85.515 + for (Path child : ds)
85.516 + list(child, verbose);
85.517 + ds.close();
85.518 + }
85.519 + }
85.520 +
85.521 + // check the content of two paths are equal
85.522 + private static void checkEqual(Path src, Path dst) throws IOException
85.523 + {
85.524 + //System.out.printf("checking <%s> vs <%s>...%n",
85.525 + // src.toString(), dst.toString());
85.526 +
85.527 + //streams
85.528 + InputStream isSrc = src.newInputStream();
85.529 + InputStream isDst = dst.newInputStream();
85.530 + byte[] bufSrc = new byte[8192];
85.531 + byte[] bufDst = new byte[8192];
85.532 +
85.533 + try {
85.534 + int nSrc = 0;
85.535 + while ((nSrc = isSrc.read(bufSrc)) != -1) {
85.536 + int nDst = 0;
85.537 + while (nDst < nSrc) {
85.538 + int n = isDst.read(bufDst, nDst, nSrc - nDst);
85.539 + if (n == -1) {
85.540 + System.out.printf("checking <%s> vs <%s>...%n",
85.541 + src.toString(), dst.toString());
85.542 + throw new RuntimeException("CHECK FAILED!");
85.543 + }
85.544 + nDst += n;
85.545 + }
85.546 + while (--nSrc >= 0) {
85.547 + if (bufSrc[nSrc] != bufDst[nSrc]) {
85.548 + System.out.printf("checking <%s> vs <%s>...%n",
85.549 + src.toString(), dst.toString());
85.550 + throw new RuntimeException("CHECK FAILED!");
85.551 + }
85.552 + nSrc--;
85.553 + }
85.554 + }
85.555 + } finally {
85.556 + isSrc.close();
85.557 + isDst.close();
85.558 + }
85.559 +
85.560 + // channels
85.561 + SeekableByteChannel chSrc = src.newByteChannel();
85.562 + SeekableByteChannel chDst = dst.newByteChannel();
85.563 + if (chSrc.size() != chDst.size()) {
85.564 + System.out.printf("src[%s].size=%d, dst[%s].size=%d%n",
85.565 + chSrc.toString(), chSrc.size(),
85.566 + chDst.toString(), chDst.size());
85.567 + throw new RuntimeException("CHECK FAILED!");
85.568 + }
85.569 + ByteBuffer bbSrc = ByteBuffer.allocate(8192);
85.570 + ByteBuffer bbDst = ByteBuffer.allocate(8192);
85.571 +
85.572 + try {
85.573 + int nSrc = 0;
85.574 + while ((nSrc = chSrc.read(bbSrc)) != -1) {
85.575 + int nDst = chDst.read(bbDst);
85.576 + if (nSrc != nDst) {
85.577 + System.out.printf("checking <%s> vs <%s>...%n",
85.578 + src.toString(), dst.toString());
85.579 + throw new RuntimeException("CHECK FAILED!");
85.580 + }
85.581 + while (--nSrc >= 0) {
85.582 + if (bbSrc.get(nSrc) != bbDst.get(nSrc)) {
85.583 + System.out.printf("checking <%s> vs <%s>...%n",
85.584 + src.toString(), dst.toString());
85.585 + throw new RuntimeException("CHECK FAILED!");
85.586 + }
85.587 + nSrc--;
85.588 + }
85.589 + bbSrc.flip();
85.590 + bbDst.flip();
85.591 + }
85.592 + } catch (IOException x) {
85.593 + x.printStackTrace();
85.594 + } finally {
85.595 + chSrc.close();
85.596 + chDst.close();
85.597 + }
85.598 + }
85.599 +
85.600 + private static void fchCopy(Path src, Path dst) throws IOException
85.601 + {
85.602 + Set<OpenOption> read = new HashSet<>();
85.603 + read.add(READ);
85.604 + Set<OpenOption> openwrite = new HashSet<>();
85.605 + openwrite.add(CREATE_NEW);
85.606 + openwrite.add(WRITE);
85.607 +
85.608 + FileChannel srcFc = src.getFileSystem()
85.609 + .provider()
85.610 + .newFileChannel(src, read);
85.611 + FileChannel dstFc = dst.getFileSystem()
85.612 + .provider()
85.613 + .newFileChannel(dst, openwrite);
85.614 +
85.615 + try {
85.616 + ByteBuffer bb = ByteBuffer.allocate(8192);
85.617 + while (srcFc.read(bb) >= 0) {
85.618 + bb.flip();
85.619 + dstFc.write(bb);
85.620 + bb.clear();
85.621 + }
85.622 + } finally {
85.623 + srcFc.close();
85.624 + dstFc.close();
85.625 + }
85.626 + }
85.627 +
85.628 + private static void chCopy(Path src, Path dst) throws IOException
85.629 + {
85.630 + Set<OpenOption> read = new HashSet<>();
85.631 + read.add(READ);
85.632 + Set<OpenOption> openwrite = new HashSet<>();
85.633 + openwrite.add(CREATE_NEW);
85.634 + openwrite.add(WRITE);
85.635 +
85.636 + SeekableByteChannel srcCh = src.newByteChannel(read);
85.637 + SeekableByteChannel dstCh = dst.newByteChannel(openwrite);
85.638 +
85.639 + try {
85.640 + ByteBuffer bb = ByteBuffer.allocate(8192);
85.641 + while (srcCh.read(bb) >= 0) {
85.642 + bb.flip();
85.643 + dstCh.write(bb);
85.644 + bb.clear();
85.645 + }
85.646 + } finally {
85.647 + srcCh.close();
85.648 + dstCh.close();
85.649 + }
85.650 + }
85.651 +
85.652 + private static void streamCopy(Path src, Path dst) throws IOException
85.653 + {
85.654 + InputStream isSrc = src.newInputStream();
85.655 + OutputStream osDst = dst.newOutputStream();
85.656 + byte[] buf = new byte[8192];
85.657 + try {
85.658 + int n = 0;
85.659 + while ((n = isSrc.read(buf)) != -1) {
85.660 + osDst.write(buf, 0, n);
85.661 + }
85.662 + } finally {
85.663 + isSrc.close();
85.664 + osDst.close();
85.665 + }
85.666 + }
85.667 +}
86.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
86.2 +++ b/src/share/demo/nio/zipfs/META-INF/services/java.nio.file.spi.FileSystemProvider Mon Oct 18 11:25:28 2010 -0400
86.3 @@ -0,0 +1,3 @@
86.4 +com.sun.nio.zipfs.ZipFileSystemProvider
86.5 +com.sun.nio.zipfs.JarFileSystemProvider
86.6 +
87.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
87.2 +++ b/src/share/demo/nio/zipfs/README.txt Mon Oct 18 11:25:28 2010 -0400
87.3 @@ -0,0 +1,29 @@
87.4 +ZipFileSystem is a file system provider that treats the contents of a zip or
87.5 +JAR file as a java.nio.file.FileSystem.
87.6 +
87.7 +To deploy the provider you must copy zipfs.jar into your extensions
87.8 +directory or else add <JDK_HOME>/demo/nio/ZipFileSystem/zipfs.jar
87.9 +to your class path.
87.10 +
87.11 +The factory methods defined by the java.nio.file.FileSystems class can be
87.12 +used to create a FileSystem, eg:
87.13 +
87.14 + // use file type detection
87.15 + Map<String,?> env = Collections.emptyMap();
87.16 + Path jarfile = Path.get("foo.jar");
87.17 + FileSystem fs = FileSystems.newFileSystem(jarfile, env);
87.18 +
87.19 +-or
87.20 +
87.21 + // locate file system by URI
87.22 + Map<String,?> env = Collections.emptyMap();
87.23 + URI uri = URI.create("zip:///mydir/foo.jar");
87.24 + FileSystem fs = FileSystems.newFileSystem(uri, env);
87.25 +
87.26 +Once a FileSystem is created then classes in the java.nio.file package
87.27 +can be used to access files in the zip/JAR file, eg:
87.28 +
87.29 + Path mf = fs.getPath("/META-INF/MANIFEST.MF");
87.30 + InputStream in = mf.newInputStream();
87.31 +
87.32 +
88.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
88.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/JarFileSystemProvider.java Mon Oct 18 11:25:28 2010 -0400
88.3 @@ -0,0 +1,71 @@
88.4 +/*
88.5 + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
88.6 + *
88.7 + * Redistribution and use in source and binary forms, with or without
88.8 + * modification, are permitted provided that the following conditions
88.9 + * are met:
88.10 + *
88.11 + * - Redistributions of source code must retain the above copyright
88.12 + * notice, this list of conditions and the following disclaimer.
88.13 + *
88.14 + * - Redistributions in binary form must reproduce the above copyright
88.15 + * notice, this list of conditions and the following disclaimer in the
88.16 + * documentation and/or other materials provided with the distribution.
88.17 + *
88.18 + * - Neither the name of Sun Microsystems nor the names of its
88.19 + * contributors may be used to endorse or promote products derived
88.20 + * from this software without specific prior written permission.
88.21 + *
88.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
88.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
88.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
88.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
88.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
88.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
88.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
88.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
88.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
88.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88.33 + */
88.34 +package com.sun.nio.zipfs;
88.35 +
88.36 +import java.nio.file.*;
88.37 +import java.nio.file.spi.*;
88.38 +import java.nio.file.attribute.*;
88.39 +import java.nio.file.spi.FileSystemProvider;
88.40 +
88.41 +import java.net.URI;
88.42 +import java.io.IOException;
88.43 +import java.net.URISyntaxException;
88.44 +import java.nio.channels.FileChannel;
88.45 +import java.util.HashMap;
88.46 +import java.util.Map;
88.47 +import java.util.Set;
88.48 +
88.49 +public class JarFileSystemProvider extends ZipFileSystemProvider
88.50 +{
88.51 +
88.52 + @Override
88.53 + public String getScheme() {
88.54 + return "jar";
88.55 + }
88.56 +
88.57 + @Override
88.58 + protected Path uriToPath(URI uri) {
88.59 + String scheme = uri.getScheme();
88.60 + if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) {
88.61 + throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'");
88.62 + }
88.63 + try {
88.64 + String uristr = uri.toString();
88.65 + int end = uristr.indexOf("!/");
88.66 + uristr = uristr.substring(4, (end == -1) ? uristr.length() : end);
88.67 + uri = new URI(uristr);
88.68 + return Paths.get(new URI("file", uri.getHost(), uri.getPath(), null))
88.69 + .toAbsolutePath();
88.70 + } catch (URISyntaxException e) {
88.71 + throw new AssertionError(e); //never thrown
88.72 + }
88.73 + }
88.74 +}
89.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
89.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipCoder.java Mon Oct 18 11:25:28 2010 -0400
89.3 @@ -0,0 +1,160 @@
89.4 +/*
89.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
89.6 + *
89.7 + * Redistribution and use in source and binary forms, with or without
89.8 + * modification, are permitted provided that the following conditions
89.9 + * are met:
89.10 + *
89.11 + * - Redistributions of source code must retain the above copyright
89.12 + * notice, this list of conditions and the following disclaimer.
89.13 + *
89.14 + * - Redistributions in binary form must reproduce the above copyright
89.15 + * notice, this list of conditions and the following disclaimer in the
89.16 + * documentation and/or other materials provided with the distribution.
89.17 + *
89.18 + * - Neither the name of Oracle nor the names of its
89.19 + * contributors may be used to endorse or promote products derived
89.20 + * from this software without specific prior written permission.
89.21 + *
89.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
89.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
89.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
89.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
89.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
89.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
89.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
89.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
89.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
89.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89.33 + */
89.34 +
89.35 +package com.sun.nio.zipfs;
89.36 +
89.37 +import java.nio.ByteBuffer;
89.38 +import java.nio.CharBuffer;
89.39 +import java.nio.charset.Charset;
89.40 +import java.nio.charset.CharsetDecoder;
89.41 +import java.nio.charset.CharsetEncoder;
89.42 +import java.nio.charset.CoderResult;
89.43 +import java.nio.charset.CodingErrorAction;
89.44 +import java.util.Arrays;
89.45 +
89.46 +/**
89.47 + * Utility class for zipfile name and comment decoding and encoding
89.48 + *
89.49 + * @author Xueming Shen
89.50 + */
89.51 +
89.52 +final class ZipCoder {
89.53 +
89.54 + String toString(byte[] ba, int length) {
89.55 + CharsetDecoder cd = decoder().reset();
89.56 + int len = (int)(length * cd.maxCharsPerByte());
89.57 + char[] ca = new char[len];
89.58 + if (len == 0)
89.59 + return new String(ca);
89.60 + ByteBuffer bb = ByteBuffer.wrap(ba, 0, length);
89.61 + CharBuffer cb = CharBuffer.wrap(ca);
89.62 + CoderResult cr = cd.decode(bb, cb, true);
89.63 + if (!cr.isUnderflow())
89.64 + throw new IllegalArgumentException(cr.toString());
89.65 + cr = cd.flush(cb);
89.66 + if (!cr.isUnderflow())
89.67 + throw new IllegalArgumentException(cr.toString());
89.68 + return new String(ca, 0, cb.position());
89.69 + }
89.70 +
89.71 + String toString(byte[] ba) {
89.72 + return toString(ba, ba.length);
89.73 + }
89.74 +
89.75 + byte[] getBytes(String s) {
89.76 + CharsetEncoder ce = encoder().reset();
89.77 + char[] ca = s.toCharArray();
89.78 + int len = (int)(ca.length * ce.maxBytesPerChar());
89.79 + byte[] ba = new byte[len];
89.80 + if (len == 0)
89.81 + return ba;
89.82 + ByteBuffer bb = ByteBuffer.wrap(ba);
89.83 + CharBuffer cb = CharBuffer.wrap(ca);
89.84 + CoderResult cr = ce.encode(cb, bb, true);
89.85 + if (!cr.isUnderflow())
89.86 + throw new IllegalArgumentException(cr.toString());
89.87 + cr = ce.flush(bb);
89.88 + if (!cr.isUnderflow())
89.89 + throw new IllegalArgumentException(cr.toString());
89.90 + if (bb.position() == ba.length) // defensive copy?
89.91 + return ba;
89.92 + else
89.93 + return Arrays.copyOf(ba, bb.position());
89.94 + }
89.95 +
89.96 + // assume invoked only if "this" is not utf8
89.97 + byte[] getBytesUTF8(String s) {
89.98 + if (isutf8)
89.99 + return getBytes(s);
89.100 + if (utf8 == null)
89.101 + utf8 = new ZipCoder(Charset.forName("UTF-8"));
89.102 + return utf8.getBytes(s);
89.103 + }
89.104 +
89.105 + String toStringUTF8(byte[] ba, int len) {
89.106 + if (isutf8)
89.107 + return toString(ba, len);
89.108 + if (utf8 == null)
89.109 + utf8 = new ZipCoder(Charset.forName("UTF-8"));
89.110 + return utf8.toString(ba, len);
89.111 + }
89.112 +
89.113 + boolean isUTF8() {
89.114 + return isutf8;
89.115 + }
89.116 +
89.117 + private Charset cs;
89.118 + private boolean isutf8;
89.119 + private ZipCoder utf8;
89.120 +
89.121 + private ZipCoder(Charset cs) {
89.122 + this.cs = cs;
89.123 + this.isutf8 = cs.name().equals("UTF-8");
89.124 + }
89.125 +
89.126 + static ZipCoder get(Charset charset) {
89.127 + return new ZipCoder(charset);
89.128 + }
89.129 +
89.130 + static ZipCoder get(String csn) {
89.131 + try {
89.132 + return new ZipCoder(Charset.forName(csn));
89.133 + } catch (Throwable t) {
89.134 + t.printStackTrace();
89.135 + }
89.136 + return new ZipCoder(Charset.defaultCharset());
89.137 + }
89.138 +
89.139 + private final ThreadLocal<CharsetDecoder> decTL = new ThreadLocal<>();
89.140 + private final ThreadLocal<CharsetEncoder> encTL = new ThreadLocal<>();
89.141 +
89.142 + private CharsetDecoder decoder() {
89.143 + CharsetDecoder dec = decTL.get();
89.144 + if (dec == null) {
89.145 + dec = cs.newDecoder()
89.146 + .onMalformedInput(CodingErrorAction.REPORT)
89.147 + .onUnmappableCharacter(CodingErrorAction.REPORT);
89.148 + decTL.set(dec);
89.149 + }
89.150 + return dec;
89.151 + }
89.152 +
89.153 + private CharsetEncoder encoder() {
89.154 + CharsetEncoder enc = encTL.get();
89.155 + if (enc == null) {
89.156 + enc = cs.newEncoder()
89.157 + .onMalformedInput(CodingErrorAction.REPORT)
89.158 + .onUnmappableCharacter(CodingErrorAction.REPORT);
89.159 + encTL.set(enc);
89.160 + }
89.161 + return enc;
89.162 + }
89.163 +}
90.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
90.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipConstants.java Mon Oct 18 11:25:28 2010 -0400
90.3 @@ -0,0 +1,261 @@
90.4 +/*
90.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
90.6 + *
90.7 + * Redistribution and use in source and binary forms, with or without
90.8 + * modification, are permitted provided that the following conditions
90.9 + * are met:
90.10 + *
90.11 + * - Redistributions of source code must retain the above copyright
90.12 + * notice, this list of conditions and the following disclaimer.
90.13 + *
90.14 + * - Redistributions in binary form must reproduce the above copyright
90.15 + * notice, this list of conditions and the following disclaimer in the
90.16 + * documentation and/or other materials provided with the distribution.
90.17 + *
90.18 + * - Neither the name of Oracle nor the names of its
90.19 + * contributors may be used to endorse or promote products derived
90.20 + * from this software without specific prior written permission.
90.21 + *
90.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
90.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
90.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
90.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
90.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
90.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
90.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
90.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
90.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
90.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90.33 + */
90.34 +
90.35 +package com.sun.nio.zipfs;
90.36 +
90.37 +import java.nio.ByteBuffer;
90.38 +
90.39 +/**
90.40 + *
90.41 + * @author Xueming Shen
90.42 + */
90.43 +
90.44 +class ZipConstants {
90.45 + /*
90.46 + * Compression methods
90.47 + */
90.48 + static final int METHOD_STORED = 0;
90.49 + static final int METHOD_DEFLATED = 8;
90.50 + static final int METHOD_DEFLATED64 = 9;
90.51 + static final int METHOD_BZIP2 = 12;
90.52 + static final int METHOD_LZMA = 14;
90.53 + static final int METHOD_LZ77 = 19;
90.54 +
90.55 + /*
90.56 + * General purpose big flag
90.57 + */
90.58 + static final int FLAG_ENCRYPTED = 0x01;
90.59 + static final int FLAG_DATADESCR = 0x08; // crc, size and csize in dd
90.60 + static final int FLAG_EFS = 0x800; // If this bit is set the filename and
90.61 + // comment fields for this file must be
90.62 + // encoded using UTF-8.
90.63 + /*
90.64 + * Header signatures
90.65 + */
90.66 + static long LOCSIG = 0x04034b50L; // "PK\003\004"
90.67 + static long EXTSIG = 0x08074b50L; // "PK\007\008"
90.68 + static long CENSIG = 0x02014b50L; // "PK\001\002"
90.69 + static long ENDSIG = 0x06054b50L; // "PK\005\006"
90.70 +
90.71 + /*
90.72 + * Header sizes in bytes (including signatures)
90.73 + */
90.74 + static final int LOCHDR = 30; // LOC header size
90.75 + static final int EXTHDR = 16; // EXT header size
90.76 + static final int CENHDR = 46; // CEN header size
90.77 + static final int ENDHDR = 22; // END header size
90.78 +
90.79 + /*
90.80 + * Local file (LOC) header field offsets
90.81 + */
90.82 + static final int LOCVER = 4; // version needed to extract
90.83 + static final int LOCFLG = 6; // general purpose bit flag
90.84 + static final int LOCHOW = 8; // compression method
90.85 + static final int LOCTIM = 10; // modification time
90.86 + static final int LOCCRC = 14; // uncompressed file crc-32 value
90.87 + static final int LOCSIZ = 18; // compressed size
90.88 + static final int LOCLEN = 22; // uncompressed size
90.89 + static final int LOCNAM = 26; // filename length
90.90 + static final int LOCEXT = 28; // extra field length
90.91 +
90.92 + /*
90.93 + * Extra local (EXT) header field offsets
90.94 + */
90.95 + static final int EXTCRC = 4; // uncompressed file crc-32 value
90.96 + static final int EXTSIZ = 8; // compressed size
90.97 + static final int EXTLEN = 12; // uncompressed size
90.98 +
90.99 + /*
90.100 + * Central directory (CEN) header field offsets
90.101 + */
90.102 + static final int CENVEM = 4; // version made by
90.103 + static final int CENVER = 6; // version needed to extract
90.104 + static final int CENFLG = 8; // encrypt, decrypt flags
90.105 + static final int CENHOW = 10; // compression method
90.106 + static final int CENTIM = 12; // modification time
90.107 + static final int CENCRC = 16; // uncompressed file crc-32 value
90.108 + static final int CENSIZ = 20; // compressed size
90.109 + static final int CENLEN = 24; // uncompressed size
90.110 + static final int CENNAM = 28; // filename length
90.111 + static final int CENEXT = 30; // extra field length
90.112 + static final int CENCOM = 32; // comment length
90.113 + static final int CENDSK = 34; // disk number start
90.114 + static final int CENATT = 36; // internal file attributes
90.115 + static final int CENATX = 38; // external file attributes
90.116 + static final int CENOFF = 42; // LOC header offset
90.117 +
90.118 + /*
90.119 + * End of central directory (END) header field offsets
90.120 + */
90.121 + static final int ENDSUB = 8; // number of entries on this disk
90.122 + static final int ENDTOT = 10; // total number of entries
90.123 + static final int ENDSIZ = 12; // central directory size in bytes
90.124 + static final int ENDOFF = 16; // offset of first CEN header
90.125 + static final int ENDCOM = 20; // zip file comment length
90.126 +
90.127 + /*
90.128 + * ZIP64 constants
90.129 + */
90.130 + static final long ZIP64_ENDSIG = 0x06064b50L; // "PK\006\006"
90.131 + static final long ZIP64_LOCSIG = 0x07064b50L; // "PK\006\007"
90.132 + static final int ZIP64_ENDHDR = 56; // ZIP64 end header size
90.133 + static final int ZIP64_LOCHDR = 20; // ZIP64 end loc header size
90.134 + static final int ZIP64_EXTHDR = 24; // EXT header size
90.135 + static final int ZIP64_EXTID = 0x0001; // Extra field Zip64 header ID
90.136 +
90.137 + static final int ZIP64_MINVAL32 = 0xFFFF;
90.138 + static final long ZIP64_MINVAL = 0xFFFFFFFFL;
90.139 +
90.140 + /*
90.141 + * Zip64 End of central directory (END) header field offsets
90.142 + */
90.143 + static final int ZIP64_ENDLEN = 4; // size of zip64 end of central dir
90.144 + static final int ZIP64_ENDVEM = 12; // version made by
90.145 + static final int ZIP64_ENDVER = 14; // version needed to extract
90.146 + static final int ZIP64_ENDNMD = 16; // number of this disk
90.147 + static final int ZIP64_ENDDSK = 20; // disk number of start
90.148 + static final int ZIP64_ENDTOD = 24; // total number of entries on this disk
90.149 + static final int ZIP64_ENDTOT = 32; // total number of entries
90.150 + static final int ZIP64_ENDSIZ = 40; // central directory size in bytes
90.151 + static final int ZIP64_ENDOFF = 48; // offset of first CEN header
90.152 + static final int ZIP64_ENDEXT = 56; // zip64 extensible data sector
90.153 +
90.154 + /*
90.155 + * Zip64 End of central directory locator field offsets
90.156 + */
90.157 + static final int ZIP64_LOCDSK = 4; // disk number start
90.158 + static final int ZIP64_LOCOFF = 8; // offset of zip64 end
90.159 + static final int ZIP64_LOCTOT = 16; // total number of disks
90.160 +
90.161 + /*
90.162 + * Zip64 Extra local (EXT) header field offsets
90.163 + */
90.164 + static final int ZIP64_EXTCRC = 4; // uncompressed file crc-32 value
90.165 + static final int ZIP64_EXTSIZ = 8; // compressed size, 8-byte
90.166 + static final int ZIP64_EXTLEN = 16; // uncompressed size, 8-byte
90.167 +
90.168 + /*
90.169 + * Extra field header ID
90.170 + */
90.171 + static final int EXTID_ZIP64 = 0x0001; // ZIP64
90.172 + static final int EXTID_NTFS = 0x000a; // NTFS
90.173 + static final int EXTID_UNIX = 0x000d; // UNIX
90.174 +
90.175 +
90.176 + /*
90.177 + * fields access methods
90.178 + */
90.179 + ///////////////////////////////////////////////////////
90.180 + static final int CH(byte[] b, int n) {
90.181 + return b[n] & 0xff;
90.182 + }
90.183 +
90.184 + static final int SH(byte[] b, int n) {
90.185 + return (b[n] & 0xff) | ((b[n + 1] & 0xff) << 8);
90.186 + }
90.187 +
90.188 + static final long LG(byte[] b, int n) {
90.189 + return ((SH(b, n)) | (SH(b, n + 2) << 16)) & 0xffffffffL;
90.190 + }
90.191 +
90.192 + static final long LL(byte[] b, int n) {
90.193 + return (LG(b, n)) | (LG(b, n + 4) << 32);
90.194 + }
90.195 +
90.196 + static final long GETSIG(byte[] b) {
90.197 + return LG(b, 0);
90.198 + }
90.199 +
90.200 + // local file (LOC) header fields
90.201 + static final long LOCSIG(byte[] b) { return LG(b, 0); } // signature
90.202 + static final int LOCVER(byte[] b) { return SH(b, 4); } // version needed to extract
90.203 + static final int LOCFLG(byte[] b) { return SH(b, 6); } // general purpose bit flags
90.204 + static final int LOCHOW(byte[] b) { return SH(b, 8); } // compression method
90.205 + static final long LOCTIM(byte[] b) { return LG(b, 10);} // modification time
90.206 + static final long LOCCRC(byte[] b) { return LG(b, 14);} // crc of uncompressed data
90.207 + static final long LOCSIZ(byte[] b) { return LG(b, 18);} // compressed data size
90.208 + static final long LOCLEN(byte[] b) { return LG(b, 22);} // uncompressed data size
90.209 + static final int LOCNAM(byte[] b) { return SH(b, 26);} // filename length
90.210 + static final int LOCEXT(byte[] b) { return SH(b, 28);} // extra field length
90.211 +
90.212 + // extra local (EXT) header fields
90.213 + static final long EXTCRC(byte[] b) { return LG(b, 4);} // crc of uncompressed data
90.214 + static final long EXTSIZ(byte[] b) { return LG(b, 8);} // compressed size
90.215 + static final long EXTLEN(byte[] b) { return LG(b, 12);} // uncompressed size
90.216 +
90.217 + // end of central directory header (END) fields
90.218 + static final int ENDSUB(byte[] b) { return SH(b, 8); } // number of entries on this disk
90.219 + static final int ENDTOT(byte[] b) { return SH(b, 10);} // total number of entries
90.220 + static final long ENDSIZ(byte[] b) { return LG(b, 12);} // central directory size
90.221 + static final long ENDOFF(byte[] b) { return LG(b, 16);} // central directory offset
90.222 + static final int ENDCOM(byte[] b) { return SH(b, 20);} // size of zip file comment
90.223 + static final int ENDCOM(byte[] b, int off) { return SH(b, off + 20);}
90.224 +
90.225 + // zip64 end of central directory recoder fields
90.226 + static final long ZIP64_ENDTOD(byte[] b) { return LL(b, 24);} // total number of entries on disk
90.227 + static final long ZIP64_ENDTOT(byte[] b) { return LL(b, 32);} // total number of entries
90.228 + static final long ZIP64_ENDSIZ(byte[] b) { return LL(b, 40);} // central directory size
90.229 + static final long ZIP64_ENDOFF(byte[] b) { return LL(b, 48);} // central directory offset
90.230 + static final long ZIP64_LOCOFF(byte[] b) { return LL(b, 8);} // zip64 end offset
90.231 +
90.232 + //////////////////////////////////////////
90.233 + static final int CH(ByteBuffer b, int pos) {
90.234 + return b.get(pos) & 0xff;
90.235 + }
90.236 + static final int SH(ByteBuffer b, int pos) {
90.237 + return b.getShort(pos) & 0xffff;
90.238 + }
90.239 + static final long LG(ByteBuffer b, int pos) {
90.240 + return b.getInt(pos) & 0xffffffffL;
90.241 + }
90.242 +
90.243 + // central directory header (END) fields
90.244 + static final long CENSIG(ByteBuffer b, int pos) { return LG(b, pos + 0); }
90.245 + static final int CENVEM(ByteBuffer b, int pos) { return SH(b, pos + 4); }
90.246 + static final int CENVER(ByteBuffer b, int pos) { return SH(b, pos + 6); }
90.247 + static final int CENFLG(ByteBuffer b, int pos) { return SH(b, pos + 8); }
90.248 + static final int CENHOW(ByteBuffer b, int pos) { return SH(b, pos + 10);}
90.249 + static final long CENTIM(ByteBuffer b, int pos) { return LG(b, pos + 12);}
90.250 + static final long CENCRC(ByteBuffer b, int pos) { return LG(b, pos + 16);}
90.251 + static final long CENSIZ(ByteBuffer b, int pos) { return LG(b, pos + 20);}
90.252 + static final long CENLEN(ByteBuffer b, int pos) { return LG(b, pos + 24);}
90.253 + static final int CENNAM(ByteBuffer b, int pos) { return SH(b, pos + 28);}
90.254 + static final int CENEXT(ByteBuffer b, int pos) { return SH(b, pos + 30);}
90.255 + static final int CENCOM(ByteBuffer b, int pos) { return SH(b, pos + 32);}
90.256 + static final int CENDSK(ByteBuffer b, int pos) { return SH(b, pos + 34);}
90.257 + static final int CENATT(ByteBuffer b, int pos) { return SH(b, pos + 36);}
90.258 + static final long CENATX(ByteBuffer b, int pos) { return LG(b, pos + 38);}
90.259 + static final long CENOFF(ByteBuffer b, int pos) { return LG(b, pos + 42);}
90.260 +
90.261 + /* The END header is followed by a variable length comment of size < 64k. */
90.262 + static final long END_MAXLEN = 0xFFFF + ENDHDR;
90.263 + static final int READBLOCKSZ = 128;
90.264 +}
91.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
91.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipDirectoryStream.java Mon Oct 18 11:25:28 2010 -0400
91.3 @@ -0,0 +1,109 @@
91.4 +/*
91.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
91.6 + *
91.7 + * Redistribution and use in source and binary forms, with or without
91.8 + * modification, are permitted provided that the following conditions
91.9 + * are met:
91.10 + *
91.11 + * - Redistributions of source code must retain the above copyright
91.12 + * notice, this list of conditions and the following disclaimer.
91.13 + *
91.14 + * - Redistributions in binary form must reproduce the above copyright
91.15 + * notice, this list of conditions and the following disclaimer in the
91.16 + * documentation and/or other materials provided with the distribution.
91.17 + *
91.18 + * - Neither the name of Oracle nor the names of its
91.19 + * contributors may be used to endorse or promote products derived
91.20 + * from this software without specific prior written permission.
91.21 + *
91.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
91.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
91.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
91.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
91.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
91.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
91.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
91.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
91.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
91.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91.33 + */
91.34 +
91.35 +package com.sun.nio.zipfs;
91.36 +
91.37 +import java.nio.file.DirectoryStream;
91.38 +import java.nio.file.ClosedDirectoryStreamException;
91.39 +import java.nio.file.NotDirectoryException;
91.40 +import java.nio.file.Path;
91.41 +import java.util.Iterator;
91.42 +import java.util.NoSuchElementException;
91.43 +import java.io.IOException;
91.44 +import static com.sun.nio.zipfs.ZipUtils.*;
91.45 +
91.46 +/**
91.47 + *
91.48 + * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
91.49 + */
91.50 +
91.51 +public class ZipDirectoryStream implements DirectoryStream<Path> {
91.52 +
91.53 + private final ZipFileSystem zipfs;
91.54 + private final byte[] path;
91.55 + private final DirectoryStream.Filter<? super Path> filter;
91.56 + private volatile boolean isClosed;
91.57 + private volatile Iterator<Path> itr;
91.58 +
91.59 + ZipDirectoryStream(ZipPath zipPath,
91.60 + DirectoryStream.Filter<? super java.nio.file.Path> filter)
91.61 + throws IOException
91.62 + {
91.63 + this.zipfs = zipPath.getFileSystem();
91.64 + this.path = zipPath.getResolvedPath();
91.65 + this.filter = filter;
91.66 + // sanity check
91.67 + if (!zipfs.isDirectory(path))
91.68 + throw new NotDirectoryException(zipPath.toString());
91.69 + }
91.70 +
91.71 + @Override
91.72 + public synchronized Iterator<Path> iterator() {
91.73 + if (isClosed)
91.74 + throw new ClosedDirectoryStreamException();
91.75 + if (itr != null)
91.76 + throw new IllegalStateException("Iterator has already been returned");
91.77 +
91.78 + try {
91.79 + itr = zipfs.iteratorOf(path, filter);
91.80 + } catch (IOException e) {
91.81 + throw new IllegalStateException(e);
91.82 + }
91.83 + return new Iterator<Path>() {
91.84 + private Path next;
91.85 + @Override
91.86 + public boolean hasNext() {
91.87 + if (isClosed)
91.88 + return false;
91.89 + return itr.hasNext();
91.90 + }
91.91 +
91.92 + @Override
91.93 + public synchronized Path next() {
91.94 + if (isClosed)
91.95 + throw new NoSuchElementException();
91.96 + return itr.next();
91.97 + }
91.98 +
91.99 + @Override
91.100 + public void remove() {
91.101 + throw new UnsupportedOperationException();
91.102 + }
91.103 + };
91.104 + }
91.105 +
91.106 + @Override
91.107 + public synchronized void close() throws IOException {
91.108 + isClosed = true;
91.109 + }
91.110 +
91.111 +
91.112 +}
92.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
92.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributeView.java Mon Oct 18 11:25:28 2010 -0400
92.3 @@ -0,0 +1,185 @@
92.4 +/*
92.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
92.6 + *
92.7 + * Redistribution and use in source and binary forms, with or without
92.8 + * modification, are permitted provided that the following conditions
92.9 + * are met:
92.10 + *
92.11 + * - Redistributions of source code must retain the above copyright
92.12 + * notice, this list of conditions and the following disclaimer.
92.13 + *
92.14 + * - Redistributions in binary form must reproduce the above copyright
92.15 + * notice, this list of conditions and the following disclaimer in the
92.16 + * documentation and/or other materials provided with the distribution.
92.17 + *
92.18 + * - Neither the name of Oracle nor the names of its
92.19 + * contributors may be used to endorse or promote products derived
92.20 + * from this software without specific prior written permission.
92.21 + *
92.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
92.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
92.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
92.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
92.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
92.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
92.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
92.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
92.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
92.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92.33 + */
92.34 +
92.35 +
92.36 +package com.sun.nio.zipfs;
92.37 +
92.38 +import java.nio.file.ReadOnlyFileSystemException;
92.39 +import java.nio.file.attribute.BasicFileAttributeView;
92.40 +import java.nio.file.attribute.FileAttributeView;
92.41 +import java.nio.file.attribute.FileTime;
92.42 +import java.io.IOException;
92.43 +import java.util.LinkedHashMap;
92.44 +
92.45 +/*
92.46 + * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
92.47 + */
92.48 +
92.49 +public class ZipFileAttributeView implements BasicFileAttributeView
92.50 +{
92.51 + private static enum AttrID {
92.52 + size,
92.53 + creationTime,
92.54 + lastAccessTime,
92.55 + lastModifiedTime,
92.56 + isDirectory,
92.57 + isRegularFile,
92.58 + isSymbolicLink,
92.59 + isOther,
92.60 + fileKey,
92.61 + compressedSize,
92.62 + crc,
92.63 + method
92.64 + };
92.65 +
92.66 + private final ZipPath path;
92.67 + private final boolean isZipView;
92.68 +
92.69 + private ZipFileAttributeView(ZipPath path, boolean isZipView) {
92.70 + this.path = path;
92.71 + this.isZipView = isZipView;
92.72 + }
92.73 +
92.74 + static <V extends FileAttributeView> V get(ZipPath path, Class<V> type) {
92.75 + if (type == null)
92.76 + throw new NullPointerException();
92.77 + if (type == BasicFileAttributeView.class)
92.78 + return (V)new ZipFileAttributeView(path, false);
92.79 + if (type == ZipFileAttributeView.class)
92.80 + return (V)new ZipFileAttributeView(path, true);
92.81 + return null;
92.82 + }
92.83 +
92.84 + static ZipFileAttributeView get(ZipPath path, String type) {
92.85 + if (type == null)
92.86 + throw new NullPointerException();
92.87 + if (type.equals("basic"))
92.88 + return new ZipFileAttributeView(path, false);
92.89 + if (type.equals("zip"))
92.90 + return new ZipFileAttributeView(path, true);
92.91 + return null;
92.92 + }
92.93 +
92.94 + @Override
92.95 + public String name() {
92.96 + return isZipView ? "zip" : "basic";
92.97 + }
92.98 +
92.99 + public ZipFileAttributes readAttributes() throws IOException
92.100 + {
92.101 + return path.getAttributes();
92.102 + }
92.103 +
92.104 + @Override
92.105 + public void setTimes(FileTime lastModifiedTime,
92.106 + FileTime lastAccessTime,
92.107 + FileTime createTime)
92.108 + throws IOException
92.109 + {
92.110 + path.setTimes(lastModifiedTime, lastAccessTime, createTime);
92.111 + }
92.112 +
92.113 + void setAttribute(String attribute, Object value)
92.114 + throws IOException
92.115 + {
92.116 + try {
92.117 + if (AttrID.valueOf(attribute) == AttrID.lastModifiedTime)
92.118 + setTimes ((FileTime)value, null, null);
92.119 + return;
92.120 + } catch (IllegalArgumentException x) {}
92.121 + throw new UnsupportedOperationException("'" + attribute +
92.122 + "' is unknown or read-only attribute");
92.123 + }
92.124 +
92.125 + public Object getAttribute(String attribute, boolean domap)
92.126 + throws IOException
92.127 + {
92.128 + ZipFileAttributes zfas = readAttributes();
92.129 + if (!domap) {
92.130 + try {
92.131 + return attribute(AttrID.valueOf(attribute), zfas);
92.132 + } catch (IllegalArgumentException x) {}
92.133 + return null;
92.134 + }
92.135 + LinkedHashMap<String, Object> map = new LinkedHashMap<>();
92.136 + if ("*".equals(attribute)) {
92.137 + for (AttrID id : AttrID.values()) {
92.138 + try {
92.139 + map.put(id.name(), attribute(id, zfas));
92.140 + } catch (IllegalArgumentException x) {}
92.141 + }
92.142 + } else {
92.143 + String[] as = attribute.split(",");
92.144 + for (String a : as) {
92.145 + try {
92.146 + map.put(a, attribute(AttrID.valueOf(a), zfas));
92.147 + } catch (IllegalArgumentException x) {}
92.148 + }
92.149 + }
92.150 + return map;
92.151 + }
92.152 +
92.153 + Object attribute(AttrID id, ZipFileAttributes zfas) {
92.154 + switch (id) {
92.155 + case size:
92.156 + return zfas.size();
92.157 + case creationTime:
92.158 + return zfas.creationTime();
92.159 + case lastAccessTime:
92.160 + return zfas.lastAccessTime();
92.161 + case lastModifiedTime:
92.162 + return zfas.lastModifiedTime();
92.163 + case isDirectory:
92.164 + return zfas.isDirectory();
92.165 + case isRegularFile:
92.166 + return zfas.isRegularFile();
92.167 + case isSymbolicLink:
92.168 + return zfas.isSymbolicLink();
92.169 + case isOther:
92.170 + return zfas.isOther();
92.171 + case fileKey:
92.172 + return zfas.fileKey();
92.173 + case compressedSize:
92.174 + if (isZipView)
92.175 + return zfas.compressedSize();
92.176 + break;
92.177 + case crc:
92.178 + if (isZipView)
92.179 + return zfas.crc();
92.180 + break;
92.181 + case method:
92.182 + if (isZipView)
92.183 + return zfas.method();
92.184 + break;
92.185 + }
92.186 + return null;
92.187 + }
92.188 +}
93.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
93.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributes.java Mon Oct 18 11:25:28 2010 -0400
93.3 @@ -0,0 +1,156 @@
93.4 +/*
93.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
93.6 + *
93.7 + * Redistribution and use in source and binary forms, with or without
93.8 + * modification, are permitted provided that the following conditions
93.9 + * are met:
93.10 + *
93.11 + * - Redistributions of source code must retain the above copyright
93.12 + * notice, this list of conditions and the following disclaimer.
93.13 + *
93.14 + * - Redistributions in binary form must reproduce the above copyright
93.15 + * notice, this list of conditions and the following disclaimer in the
93.16 + * documentation and/or other materials provided with the distribution.
93.17 + *
93.18 + * - Neither the name of Oracle nor the names of its
93.19 + * contributors may be used to endorse or promote products derived
93.20 + * from this software without specific prior written permission.
93.21 + *
93.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
93.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
93.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
93.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
93.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
93.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
93.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
93.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
93.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
93.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
93.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
93.33 + */
93.34 +
93.35 +
93.36 +package com.sun.nio.zipfs;
93.37 +
93.38 +import java.nio.file.attribute.BasicFileAttributes;
93.39 +import java.nio.file.attribute.FileTime;
93.40 +import java.util.Arrays;
93.41 +import java.util.Formatter;
93.42 +import static com.sun.nio.zipfs.ZipUtils.*;
93.43 +
93.44 +/**
93.45 + *
93.46 + * @author Xueming Shen, Rajendra Gutupalli,Jaya Hangal
93.47 + */
93.48 +
93.49 +public class ZipFileAttributes implements BasicFileAttributes
93.50 +
93.51 +{
93.52 + private final ZipFileSystem.Entry e;
93.53 +
93.54 + ZipFileAttributes(ZipFileSystem.Entry e) {
93.55 + this.e = e;
93.56 + }
93.57 +
93.58 + ///////// basic attributes ///////////
93.59 + @Override
93.60 + public FileTime creationTime() {
93.61 + if (e.ctime != -1)
93.62 + return FileTime.fromMillis(dosToJavaTime(e.ctime));
93.63 + return null;
93.64 + }
93.65 +
93.66 + @Override
93.67 + public boolean isDirectory() {
93.68 + return e.isDir();
93.69 + }
93.70 +
93.71 + @Override
93.72 + public boolean isOther() {
93.73 + return false;
93.74 + }
93.75 +
93.76 + @Override
93.77 + public boolean isRegularFile() {
93.78 + return !e.isDir();
93.79 + }
93.80 +
93.81 + @Override
93.82 + public FileTime lastAccessTime() {
93.83 + if (e.atime != -1)
93.84 + return FileTime.fromMillis(dosToJavaTime(e.atime));
93.85 + return null;
93.86 + }
93.87 +
93.88 + @Override
93.89 + public FileTime lastModifiedTime() {
93.90 + return FileTime.fromMillis(dosToJavaTime(e.mtime));
93.91 + }
93.92 +
93.93 + @Override
93.94 + public long size() {
93.95 + return e.size;
93.96 + }
93.97 +
93.98 + @Override
93.99 + public boolean isSymbolicLink() {
93.100 + return false;
93.101 + }
93.102 +
93.103 + @Override
93.104 + public Object fileKey() {
93.105 + return null;
93.106 + }
93.107 +
93.108 + ///////// zip entry attributes ///////////
93.109 + public byte[] name() {
93.110 + return Arrays.copyOf(e.name, e.name.length);
93.111 + }
93.112 +
93.113 + public long compressedSize() {
93.114 + return e.csize;
93.115 + }
93.116 +
93.117 + public long crc() {
93.118 + return e.crc;
93.119 + }
93.120 +
93.121 + public int method() {
93.122 + return e.method;
93.123 + }
93.124 +
93.125 + public byte[] extra() {
93.126 + if (e.extra != null)
93.127 + return Arrays.copyOf(e.extra, e.extra.length);
93.128 + return null;
93.129 + }
93.130 +
93.131 + public byte[] comment() {
93.132 + if (e.comment != null)
93.133 + return Arrays.copyOf(e.comment, e.comment.length);
93.134 + return null;
93.135 + }
93.136 +
93.137 + public String toString() {
93.138 + StringBuilder sb = new StringBuilder();
93.139 + Formatter fm = new Formatter(sb);
93.140 + fm.format("[/%s]%n", new String(e.name)); // TBD encoding
93.141 + fm.format(" creationTime : %s%n", creationTime());
93.142 + if (lastAccessTime() != null)
93.143 + fm.format(" lastAccessTime : %tc%n", lastAccessTime().toMillis());
93.144 + else
93.145 + fm.format(" lastAccessTime : null%n");
93.146 + fm.format(" lastModifiedTime: %tc%n", lastModifiedTime().toMillis());
93.147 + fm.format(" isRegularFile : %b%n", isRegularFile());
93.148 + fm.format(" isDirectory : %b%n", isDirectory());
93.149 + fm.format(" isSymbolicLink : %b%n", isSymbolicLink());
93.150 + fm.format(" isOther : %b%n", isOther());
93.151 + fm.format(" fileKey : %s%n", fileKey());
93.152 + fm.format(" size : %d%n", size());
93.153 + fm.format(" compressedSize : %d%n", compressedSize());
93.154 + fm.format(" crc : %x%n", crc());
93.155 + fm.format(" method : %d%n", method());
93.156 + fm.close();
93.157 + return sb.toString();
93.158 + }
93.159 +}
94.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
94.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileStore.java Mon Oct 18 11:25:28 2010 -0400
94.3 @@ -0,0 +1,157 @@
94.4 +/*
94.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
94.6 + *
94.7 + * Redistribution and use in source and binary forms, with or without
94.8 + * modification, are permitted provided that the following conditions
94.9 + * are met:
94.10 + *
94.11 + * - Redistributions of source code must retain the above copyright
94.12 + * notice, this list of conditions and the following disclaimer.
94.13 + *
94.14 + * - Redistributions in binary form must reproduce the above copyright
94.15 + * notice, this list of conditions and the following disclaimer in the
94.16 + * documentation and/or other materials provided with the distribution.
94.17 + *
94.18 + * - Neither the name of Oracle nor the names of its
94.19 + * contributors may be used to endorse or promote products derived
94.20 + * from this software without specific prior written permission.
94.21 + *
94.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
94.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
94.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
94.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
94.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
94.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
94.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
94.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
94.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
94.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94.33 + */
94.34 +
94.35 +package com.sun.nio.zipfs;
94.36 +
94.37 +import java.io.IOException;
94.38 +import java.nio.file.FileStore;
94.39 +import java.nio.file.FileSystems;
94.40 +import java.nio.file.Path;
94.41 +import java.nio.file.attribute.FileAttributeView;
94.42 +import java.nio.file.attribute.FileStoreAttributeView;
94.43 +import java.nio.file.attribute.FileStoreSpaceAttributeView;
94.44 +import java.nio.file.attribute.FileStoreSpaceAttributes;
94.45 +import java.nio.file.attribute.Attributes;
94.46 +import java.nio.file.attribute.BasicFileAttributeView;
94.47 +import java.util.Formatter;
94.48 +
94.49 +/*
94.50 + *
94.51 + * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
94.52 + */
94.53 +
94.54 +public class ZipFileStore extends FileStore {
94.55 +
94.56 + private final ZipFileSystem zfs;
94.57 +
94.58 + ZipFileStore(ZipPath zpath) {
94.59 + this.zfs = (ZipFileSystem)zpath.getFileSystem();
94.60 + }
94.61 +
94.62 + @Override
94.63 + public String name() {
94.64 + return zfs.toString() + "/";
94.65 + }
94.66 +
94.67 + @Override
94.68 + public String type() {
94.69 + return "zipfs";
94.70 + }
94.71 +
94.72 + @Override
94.73 + public boolean isReadOnly() {
94.74 + return zfs.isReadOnly();
94.75 + }
94.76 +
94.77 + @Override
94.78 + public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) {
94.79 + return (type == BasicFileAttributeView.class ||
94.80 + type == ZipFileAttributeView.class);
94.81 + }
94.82 +
94.83 + @Override
94.84 + public boolean supportsFileAttributeView(String name) {
94.85 + return name.equals("basic") || name.equals("zip");
94.86 + }
94.87 +
94.88 + @Override
94.89 + @SuppressWarnings("unchecked")
94.90 + public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> type) {
94.91 + if (type == null)
94.92 + throw new NullPointerException();
94.93 + if (type == FileStoreSpaceAttributeView.class)
94.94 + return (V) new ZipFileStoreAttributeView(this);
94.95 + return null;
94.96 + }
94.97 +
94.98 + @Override
94.99 + public Object getAttribute(String attribute) throws IOException {
94.100 + if (attribute.equals("space:totalSpace"))
94.101 + return new ZipFileStoreAttributeView(this).readAttributes().totalSpace();
94.102 + if (attribute.equals("space:usableSpace"))
94.103 + return new ZipFileStoreAttributeView(this).readAttributes().usableSpace();
94.104 + if (attribute.equals("space:unallocatedSpace"))
94.105 + return new ZipFileStoreAttributeView(this).readAttributes().unallocatedSpace();
94.106 + throw new UnsupportedOperationException("does not support the given attribute");
94.107 + }
94.108 +
94.109 + private static class ZipFileStoreAttributeView implements FileStoreSpaceAttributeView {
94.110 +
94.111 + private final ZipFileStore fileStore;
94.112 +
94.113 + public ZipFileStoreAttributeView(ZipFileStore fileStore) {
94.114 + this.fileStore = fileStore;
94.115 + }
94.116 +
94.117 + @Override
94.118 + public String name() {
94.119 + return "space";
94.120 + }
94.121 +
94.122 + @Override
94.123 + public FileStoreSpaceAttributes readAttributes() throws IOException {
94.124 + final String file = fileStore.name();
94.125 + Path path = FileSystems.getDefault().getPath(file);
94.126 + final long size = Attributes.readBasicFileAttributes(path).size();
94.127 + final FileStore fstore = path.getFileStore();
94.128 + final FileStoreSpaceAttributes fstoreAttrs =
94.129 + Attributes.readFileStoreSpaceAttributes(fstore);
94.130 + return new FileStoreSpaceAttributes() {
94.131 + public long totalSpace() {
94.132 + return size;
94.133 + }
94.134 +
94.135 + public long usableSpace() {
94.136 + if (!fstore.isReadOnly())
94.137 + return fstoreAttrs.usableSpace();
94.138 + return 0;
94.139 + }
94.140 +
94.141 + public long unallocatedSpace() {
94.142 + if (!fstore.isReadOnly())
94.143 + return fstoreAttrs.unallocatedSpace();
94.144 + return 0;
94.145 + }
94.146 +
94.147 + public String toString() {
94.148 + StringBuilder sb = new StringBuilder();
94.149 + Formatter fm = new Formatter(sb);
94.150 + fm.format("FileStoreSpaceAttributes[%s]%n", file);
94.151 + fm.format(" totalSpace: %d%n", totalSpace());
94.152 + fm.format(" usableSpace: %d%n", usableSpace());
94.153 + fm.format(" unallocSpace: %d%n", unallocatedSpace());
94.154 + fm.close();
94.155 + return sb.toString();
94.156 + }
94.157 + };
94.158 + }
94.159 + }
94.160 +}
95.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
95.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystem.java Mon Oct 18 11:25:28 2010 -0400
95.3 @@ -0,0 +1,2257 @@
95.4 +/*
95.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
95.6 + *
95.7 + * Redistribution and use in source and binary forms, with or without
95.8 + * modification, are permitted provided that the following conditions
95.9 + * are met:
95.10 + *
95.11 + * - Redistributions of source code must retain the above copyright
95.12 + * notice, this list of conditions and the following disclaimer.
95.13 + *
95.14 + * - Redistributions in binary form must reproduce the above copyright
95.15 + * notice, this list of conditions and the following disclaimer in the
95.16 + * documentation and/or other materials provided with the distribution.
95.17 + *
95.18 + * - Neither the name of Oracle nor the names of its
95.19 + * contributors may be used to endorse or promote products derived
95.20 + * from this software without specific prior written permission.
95.21 + *
95.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
95.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
95.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
95.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
95.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
95.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
95.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
95.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
95.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
95.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95.33 + */
95.34 +
95.35 +package com.sun.nio.zipfs;
95.36 +
95.37 +import java.io.ByteArrayInputStream;
95.38 +import java.io.ByteArrayOutputStream;
95.39 +import java.io.EOFException;
95.40 +import java.io.File;
95.41 +import java.io.FileInputStream;
95.42 +import java.io.IOException;
95.43 +import java.io.InputStream;
95.44 +import java.io.OutputStream;
95.45 +import java.nio.ByteBuffer;
95.46 +import java.nio.ByteOrder;
95.47 +import java.nio.MappedByteBuffer;
95.48 +import java.nio.channels.*;
95.49 +import java.nio.file.*;
95.50 +import java.nio.file.attribute.*;
95.51 +import java.nio.file.spi.*;
95.52 +import java.net.URI;
95.53 +import java.util.*;
95.54 +import java.util.regex.Pattern;
95.55 +import java.util.zip.CRC32;
95.56 +import java.util.zip.Inflater;
95.57 +import java.util.zip.Deflater;
95.58 +import java.util.zip.InflaterInputStream;
95.59 +import java.util.zip.DeflaterOutputStream;
95.60 +import java.util.zip.ZipException;
95.61 +import java.util.zip.ZipError;
95.62 +import static java.lang.Boolean.*;
95.63 +import static com.sun.nio.zipfs.ZipConstants.*;
95.64 +import static com.sun.nio.zipfs.ZipUtils.*;
95.65 +import static java.nio.file.StandardOpenOption.*;
95.66 +import static java.nio.file.StandardCopyOption.*;
95.67 +
95.68 +/**
95.69 + * A FileSystem built on a zip file
95.70 + *
95.71 + * @author Xueming Shen
95.72 + */
95.73 +
95.74 +public class ZipFileSystem extends FileSystem {
95.75 +
95.76 + private final ZipFileSystemProvider provider;
95.77 + private final ZipPath defaultdir;
95.78 + private boolean readOnly = false;
95.79 + private final Path zfpath;
95.80 + private final ZipCoder zc;
95.81 +
95.82 + private final Object lock = new Object();
95.83 +
95.84 + // configurable by env map
95.85 + private final String defaultDir; // default dir for the file system
95.86 + private final String nameEncoding; // default encoding for name/comment
95.87 + private final boolean buildDirTree; // build a dir tree for directoryStream ops
95.88 + private final boolean useTempFile; // use a temp file for newOS, default
95.89 + // is to use BAOS for better performance
95.90 + private final boolean createNew; // create a new zip if not exists
95.91 +
95.92 + ZipFileSystem(ZipFileSystemProvider provider,
95.93 + Path zfpath,
95.94 + Map<String, ?> env)
95.95 + throws IOException
95.96 + {
95.97 + // configurable env setup
95.98 + this.buildDirTree = TRUE.equals(env.get("buildDirTree"));
95.99 + this.useTempFile = TRUE.equals(env.get("useTempFile"));
95.100 + this.createNew = TRUE.equals(env.get("createNew"));
95.101 + this.nameEncoding = env.containsKey("nameEncoding") ?
95.102 + (String)env.get("nameEncoding") : "UTF-8";
95.103 + this.defaultDir = env.containsKey("default.dir") ?
95.104 + (String)env.get("default.dir") : "/";
95.105 + if (this.defaultDir.charAt(0) != '/')
95.106 + throw new IllegalArgumentException("default dir should be absolute");
95.107 +
95.108 + this.provider = provider;
95.109 + this.zfpath = zfpath;
95.110 + if (zfpath.notExists()) {
95.111 + if (createNew) {
95.112 + OutputStream os = zfpath.newOutputStream(CREATE_NEW, WRITE);
95.113 + new END().write(os, 0);
95.114 + os.close();
95.115 + } else {
95.116 + throw new FileSystemNotFoundException(zfpath.toString());
95.117 + }
95.118 + }
95.119 + zfpath.checkAccess(AccessMode.READ); // sm and existence check
95.120 + try {
95.121 + zfpath.checkAccess(AccessMode.WRITE);
95.122 + } catch (AccessDeniedException x) {
95.123 + this.readOnly = true;
95.124 + }
95.125 + this.zc = ZipCoder.get(nameEncoding);
95.126 + this.defaultdir = new ZipPath(this, getBytes(defaultDir));
95.127 + initZipFile();
95.128 + }
95.129 +
95.130 + @Override
95.131 + public FileSystemProvider provider() {
95.132 + return provider;
95.133 + }
95.134 +
95.135 + @Override
95.136 + public String getSeparator() {
95.137 + return "/";
95.138 + }
95.139 +
95.140 + @Override
95.141 + public boolean isOpen() {
95.142 + return isOpen;
95.143 + }
95.144 +
95.145 + @Override
95.146 + public boolean isReadOnly() {
95.147 + return readOnly;
95.148 + }
95.149 +
95.150 + private void checkWritable() throws IOException {
95.151 + if (readOnly)
95.152 + throw new ReadOnlyFileSystemException();
95.153 + }
95.154 +
95.155 + @Override
95.156 + public Iterable<Path> getRootDirectories() {
95.157 + ArrayList<Path> pathArr = new ArrayList<>();
95.158 + pathArr.add(new ZipPath(this, new byte[]{'/'}));
95.159 + return pathArr;
95.160 + }
95.161 +
95.162 + ZipPath getDefaultDir() { // package private
95.163 + return defaultdir;
95.164 + }
95.165 +
95.166 + @Override
95.167 + public ZipPath getPath(String path) {
95.168 + if (path.length() == 0)
95.169 + throw new InvalidPathException(path, "path should not be empty");
95.170 + return new ZipPath(this, getBytes(path));
95.171 + }
95.172 +
95.173 + @Override
95.174 + public UserPrincipalLookupService getUserPrincipalLookupService() {
95.175 + throw new UnsupportedOperationException();
95.176 + }
95.177 +
95.178 + @Override
95.179 + public WatchService newWatchService() {
95.180 + throw new UnsupportedOperationException();
95.181 + }
95.182 +
95.183 + FileStore getFileStore(ZipPath path) {
95.184 + return new ZipFileStore(path);
95.185 + }
95.186 +
95.187 + @Override
95.188 + public Iterable<FileStore> getFileStores() {
95.189 + ArrayList<FileStore> list = new ArrayList<FileStore>(1);
95.190 + list.add(new ZipFileStore(new ZipPath(this, new byte[]{'/'})));
95.191 + return list;
95.192 + }
95.193 +
95.194 + private static final Set<String> supportedFileAttributeViews =
95.195 + Collections.unmodifiableSet(
95.196 + new HashSet<String>(Arrays.asList("basic", "zip")));
95.197 +
95.198 + @Override
95.199 + public Set<String> supportedFileAttributeViews() {
95.200 + return supportedFileAttributeViews;
95.201 + }
95.202 +
95.203 + @Override
95.204 + public String toString() {
95.205 + return zfpath.toString();
95.206 + }
95.207 +
95.208 + Path getZipFile() {
95.209 + return zfpath;
95.210 + }
95.211 +
95.212 + private static final String GLOB_SYNTAX = "glob";
95.213 + private static final String REGEX_SYNTAX = "regex";
95.214 +
95.215 + @Override
95.216 + public PathMatcher getPathMatcher(String syntaxAndInput) {
95.217 + int pos = syntaxAndInput.indexOf(':');
95.218 + if (pos <= 0 || pos == syntaxAndInput.length()) {
95.219 + throw new IllegalArgumentException();
95.220 + }
95.221 + String syntax = syntaxAndInput.substring(0, pos);
95.222 + String input = syntaxAndInput.substring(pos + 1);
95.223 + String expr;
95.224 + if (syntax.equals(GLOB_SYNTAX)) {
95.225 + expr = toRegexPattern(input);
95.226 + } else {
95.227 + if (syntax.equals(REGEX_SYNTAX)) {
95.228 + expr = input;
95.229 + } else {
95.230 + throw new UnsupportedOperationException("Syntax '" + syntax +
95.231 + "' not recognized");
95.232 + }
95.233 + }
95.234 + // return matcher
95.235 + final Pattern pattern = Pattern.compile(expr);
95.236 + return new PathMatcher() {
95.237 + @Override
95.238 + public boolean matches(Path path) {
95.239 + return pattern.matcher(path.toString()).matches();
95.240 + }
95.241 + };
95.242 + }
95.243 +
95.244 + @Override
95.245 + public void close() throws IOException {
95.246 + synchronized (lock) {
95.247 + if (!isOpen)
95.248 + return;
95.249 + isOpen = false;
95.250 + if (!streams.isEmpty()) {
95.251 + synchronized(streams) {
95.252 + for (InputStream is: streams)
95.253 + is.close();
95.254 + }
95.255 + }
95.256 + sync();
95.257 + ch.close();
95.258 + }
95.259 + synchronized (inflaters) {
95.260 + for (Inflater inf : inflaters)
95.261 + inf.end();
95.262 + }
95.263 + synchronized (deflaters) {
95.264 + for (Deflater def : deflaters)
95.265 + def.end();
95.266 + }
95.267 + for (Path p: tmppaths) {
95.268 + try {
95.269 + p.deleteIfExists();
95.270 + } catch (IOException x) {
95.271 + x.printStackTrace();
95.272 + }
95.273 + }
95.274 + provider.removeFileSystem(zfpath);
95.275 + }
95.276 +
95.277 + ZipFileAttributes[] getAllAttributes() throws IOException {
95.278 + ensureOpen();
95.279 + int n = inodes.size();
95.280 + ZipFileAttributes[] zes = new ZipFileAttributes[n];
95.281 + Iterator<IndexNode> itr = inodes.values().iterator();
95.282 + int i = 0;
95.283 + while(itr.hasNext()) {
95.284 + zes[i++] = new ZipFileAttributes(Entry.readCEN(cen, itr.next().pos));
95.285 + }
95.286 + return zes;
95.287 + }
95.288 +
95.289 + EntryName[] getEntryNames() throws IOException {
95.290 + ensureOpen();
95.291 + return inodes.keySet().toArray(new EntryName[0]);
95.292 + }
95.293 +
95.294 + ZipFileAttributes getFileAttributes(byte[] path)
95.295 + throws IOException
95.296 + {
95.297 + synchronized (lock) {
95.298 + Entry e = getEntry0(path);
95.299 + if (e == null) {
95.300 + if (path.length == 0) {
95.301 + e = new Entry(new byte[0]); // root
95.302 + } else if (buildDirTree) {
95.303 + IndexNode inode = getDirs().get(new EntryName(path));
95.304 + if (inode == null)
95.305 + return null;
95.306 + e = new Entry(inode.name);
95.307 + } else {
95.308 + return null;
95.309 + }
95.310 + e.method = METHOD_STORED; // STORED for dir
95.311 + BasicFileAttributes bfas = Attributes.readBasicFileAttributes(zfpath);
95.312 + if (bfas.lastModifiedTime() != null)
95.313 + e.mtime = javaToDosTime(bfas.lastModifiedTime().toMillis());
95.314 + if (bfas.lastAccessTime() != null)
95.315 + e.atime = javaToDosTime(bfas.lastAccessTime().toMillis());
95.316 + if (bfas.creationTime() != null)
95.317 + e.ctime = javaToDosTime(bfas.creationTime().toMillis());
95.318 + }
95.319 + return new ZipFileAttributes(e);
95.320 + }
95.321 + }
95.322 +
95.323 + void setTimes(byte[] path, FileTime mtime, FileTime atime, FileTime ctime)
95.324 + throws IOException
95.325 + {
95.326 + checkWritable();
95.327 + synchronized (lock) {
95.328 + Entry e = getEntry0(path); // ensureOpen checked
95.329 + if (e == null)
95.330 + throw new NoSuchFileException(getString(path));
95.331 + if (e.type == Entry.CEN)
95.332 + e.type = Entry.COPY; // copy e
95.333 + if (mtime != null)
95.334 + e.mtime = javaToDosTime(mtime.toMillis());
95.335 + if (atime != null)
95.336 + e.atime = javaToDosTime(atime.toMillis());
95.337 + if (ctime != null)
95.338 + e.ctime = javaToDosTime(ctime.toMillis());
95.339 + update(e);
95.340 + }
95.341 + }
95.342 +
95.343 + boolean exists(byte[] path)
95.344 + throws IOException
95.345 + {
95.346 + return getEntry0(path) != null;
95.347 + }
95.348 +
95.349 + boolean isDirectory(byte[] path)
95.350 + throws IOException
95.351 + {
95.352 + synchronized (lock) {
95.353 + if (buildDirTree) {
95.354 + return getDirs().containsKey(new EntryName(path));
95.355 + }
95.356 + Entry e = getEntry0(path);
95.357 + return (e != null && e.isDir()) || path.length == 0;
95.358 + }
95.359 + }
95.360 +
95.361 + private ZipPath toZipPath(byte[] path) {
95.362 + // make it absolute
95.363 + byte[] p = new byte[path.length + 1];
95.364 + p[0] = '/';
95.365 + System.arraycopy(path, 0, p, 1, path.length);
95.366 + return new ZipPath(this, p);
95.367 + }
95.368 +
95.369 + // returns the list of child paths of "path"
95.370 + Iterator<Path> iteratorOf(byte[] path,
95.371 + DirectoryStream.Filter<? super Path> filter)
95.372 + throws IOException
95.373 + {
95.374 + synchronized (lock) {
95.375 + if (buildDirTree) {
95.376 + IndexNode inode = getDirs().get(new EntryName(path));
95.377 + if (inode == null)
95.378 + throw new NotDirectoryException(getString(path));
95.379 + List<Path> list = new ArrayList<Path>();
95.380 + IndexNode child = inode.child;
95.381 + while (child != null) {
95.382 + ZipPath zp = toZipPath(child.name);
95.383 + if (filter == null || filter.accept(zp))
95.384 + list.add(zp);
95.385 + child = child.sibling;
95.386 + }
95.387 + return list.iterator();
95.388 + }
95.389 +
95.390 + if (!isDirectory(path))
95.391 + throw new NotDirectoryException(getString(path));
95.392 + List<Path> list = new ArrayList<Path>();
95.393 + EntryName[] entries = getEntryNames();
95.394 + path = toDirectoryPath(path);
95.395 + for (EntryName en :entries) {
95.396 + if (!isParentOf(path, en.name)) // is "path" the parent of "name"
95.397 + continue;
95.398 + int off = path.length;
95.399 + while (off < en.name.length) {
95.400 + if (en.name[off] == '/')
95.401 + break;
95.402 + off++;
95.403 + }
95.404 + if (off < (en.name.length - 1))
95.405 + continue;
95.406 + ZipPath zp = toZipPath(en.name);
95.407 + if (filter == null || filter.accept(zp))
95.408 + list.add(zp);
95.409 + }
95.410 + return list.iterator();
95.411 + }
95.412 + }
95.413 +
95.414 + void createDirectory(byte[] dir, FileAttribute<?>... attrs)
95.415 + throws IOException
95.416 + {
95.417 + checkWritable();
95.418 + dir = toDirectoryPath(dir);
95.419 + synchronized (lock) {
95.420 + ensureOpen();
95.421 + // pseudo root dir, or exiting dir
95.422 + if (dir.length == 0 || exists(dir))
95.423 + throw new FileAlreadyExistsException(getString(dir));
95.424 + checkParents(dir);
95.425 +
95.426 + Entry e = new Entry(dir, Entry.NEW);
95.427 + e.method = METHOD_STORED; // STORED for dir
95.428 + update(e);
95.429 + }
95.430 + }
95.431 +
95.432 + void copyFile(boolean deletesrc, byte[]src, byte[] dst, CopyOption... options)
95.433 + throws IOException
95.434 + {
95.435 + checkWritable();
95.436 + if (Arrays.equals(src, dst))
95.437 + return; // do nothing, src and dst are the same
95.438 + synchronized (lock) {
95.439 + Entry eSrc = getEntry0(src); // ensureOpen checked
95.440 + if (eSrc == null)
95.441 + throw new NoSuchFileException(getString(src));
95.442 + if (eSrc.isDir()) { // spec says to create dst dir
95.443 + createDirectory(dst);
95.444 + return;
95.445 + }
95.446 + boolean hasReplace = false;
95.447 + boolean hasCopyAttrs = false;
95.448 + for (CopyOption opt : options) {
95.449 + if (opt == REPLACE_EXISTING)
95.450 + hasReplace = true;
95.451 + else if (opt == COPY_ATTRIBUTES)
95.452 + hasCopyAttrs = true;
95.453 + }
95.454 + Entry eDst = getEntry0(dst);
95.455 + if (eDst != null) {
95.456 + if (!hasReplace)
95.457 + throw new FileAlreadyExistsException(getString(dst));
95.458 + } else {
95.459 + checkParents(dst);
95.460 + }
95.461 + Entry u = new Entry(eSrc, Entry.COPY); // copy eSrc entry
95.462 + u.name = dst; // change name
95.463 + // don't touch the "nlen and elen" here. writeLOC() always
95.464 + // re-calculate from "name" and "extra" for the correct length,
95.465 + // copyLOCEntry however needs the original lengths to skip the
95.466 + // loc header.
95.467 + // u.nlen = dst.length;
95.468 + if (eSrc.type == Entry.NEW || eSrc.type == Entry.FILECH)
95.469 + {
95.470 + u.type = eSrc.type; // make it the same type
95.471 + if (!deletesrc) { // if it's not "rename", just take the data
95.472 + if (eSrc.bytes != null)
95.473 + u.bytes = Arrays.copyOf(eSrc.bytes, eSrc.bytes.length);
95.474 + else if (eSrc.file != null) {
95.475 + u.file = getTempPathForEntry(null);
95.476 + eSrc.file.copyTo(u.file, REPLACE_EXISTING);
95.477 + }
95.478 + }
95.479 + }
95.480 + if (!hasCopyAttrs)
95.481 + u.mtime = u.atime= u.ctime = javaToDosTime(System.currentTimeMillis());
95.482 + update(u);
95.483 + if (deletesrc)
95.484 + updateDelete(eSrc);
95.485 + }
95.486 + }
95.487 +
95.488 + // Returns an output stream for writing the contents into the specified
95.489 + // entry.
95.490 + OutputStream newOutputStream(byte[] path, OpenOption... options)
95.491 + throws IOException
95.492 + {
95.493 + checkWritable();
95.494 + boolean hasCreateNew = false;
95.495 + boolean hasCreate = false;
95.496 + boolean hasAppend = false;
95.497 + for (OpenOption opt: options) {
95.498 + if (opt == READ)
95.499 + throw new IllegalArgumentException("READ not allowed");
95.500 + if (opt == CREATE_NEW)
95.501 + hasCreateNew = true;
95.502 + if (opt == CREATE)
95.503 + hasCreate = true;
95.504 + if (opt == APPEND)
95.505 + hasAppend = true;
95.506 + }
95.507 + synchronized (lock) {
95.508 + Entry e = getEntry0(path);
95.509 + if (e != null) {
95.510 + if (e.isDir() || hasCreateNew)
95.511 + throw new FileAlreadyExistsException(getString(path));
95.512 + if (hasAppend) {
95.513 + InputStream is = getInputStream(e);
95.514 + OutputStream os = getOutputStream(new Entry(e, Entry.NEW));
95.515 + copyStream(is, os);
95.516 + is.close();
95.517 + return os;
95.518 + }
95.519 + return getOutputStream(new Entry(e, Entry.NEW));
95.520 + } else {
95.521 + if (!hasCreate && !hasCreateNew)
95.522 + throw new NoSuchFileException(getString(path));
95.523 + checkParents(path);
95.524 + return getOutputStream(new Entry(path, Entry.NEW));
95.525 + }
95.526 + }
95.527 + }
95.528 +
95.529 + // Returns an input stream for reading the contents of the specified
95.530 + // file entry.
95.531 + InputStream newInputStream(byte[] path) throws IOException {
95.532 + synchronized (lock) {
95.533 + Entry e = getEntry0(path);
95.534 + if (e == null)
95.535 + throw new NoSuchFileException(getString(path));
95.536 + if (e.isDir())
95.537 + throw new FileSystemException(getString(path), "is a directory", null);
95.538 + return getInputStream(e);
95.539 + }
95.540 + }
95.541 +
95.542 + private void checkOptions(Set<? extends OpenOption> options) {
95.543 + // check for options of null type and option is an intance of StandardOpenOption
95.544 + for (OpenOption option : options) {
95.545 + if (option == null)
95.546 + throw new NullPointerException();
95.547 + if (!(option instanceof StandardOpenOption))
95.548 + throw new IllegalArgumentException();
95.549 + }
95.550 + }
95.551 +
95.552 + // Returns a Writable/ReadByteChannel for now. Might consdier to use
95.553 + // newFileChannel() instead, which dump the entry data into a regular
95.554 + // file on the default file system and create a FileChannel on top of
95.555 + // it.
95.556 + SeekableByteChannel newByteChannel(byte[] path,
95.557 + Set<? extends OpenOption> options,
95.558 + FileAttribute<?>... attrs)
95.559 + throws IOException
95.560 + {
95.561 + checkOptions(options);
95.562 + if (options.contains(StandardOpenOption.WRITE) ||
95.563 + options.contains(StandardOpenOption.APPEND)) {
95.564 + checkWritable();
95.565 + final WritableByteChannel wbc = Channels.newChannel(newOutputStream(path,
95.566 + options.toArray(new OpenOption[0])));
95.567 + long leftover = 0;;
95.568 + if (options.contains(StandardOpenOption.APPEND)) {
95.569 + Entry e = getEntry0(path);
95.570 + if (e != null && e.size >= 0)
95.571 + leftover = e.size;
95.572 + }
95.573 + final long offset = leftover;
95.574 + return new SeekableByteChannel() {
95.575 + long written = offset;
95.576 + public boolean isOpen() {
95.577 + return wbc.isOpen();
95.578 + }
95.579 + public long position() throws IOException {
95.580 + return written;
95.581 + }
95.582 + public SeekableByteChannel position(long pos) throws IOException {
95.583 + throw new UnsupportedOperationException();
95.584 + }
95.585 + public int read(ByteBuffer dst) throws IOException {
95.586 + throw new UnsupportedOperationException();
95.587 + }
95.588 + public SeekableByteChannel truncate(long size) throws IOException {
95.589 + throw new UnsupportedOperationException();
95.590 + }
95.591 + public int write(ByteBuffer src) throws IOException {
95.592 + int n = wbc.write(src);
95.593 + written += n;
95.594 + return n;
95.595 + }
95.596 + public long size() throws IOException {
95.597 + return written;
95.598 + }
95.599 + public void close() throws IOException {
95.600 + wbc.close();
95.601 + }
95.602 + };
95.603 + } else {
95.604 + Entry e = getEntry0(path);
95.605 + if (e == null || e.isDir())
95.606 + throw new NoSuchFileException(getString(path));
95.607 + final ReadableByteChannel rbc =
95.608 + Channels.newChannel(getInputStream(e));
95.609 + final long size = e.size;
95.610 + return new SeekableByteChannel() {
95.611 + long read = 0;
95.612 + public boolean isOpen() {
95.613 + return rbc.isOpen();
95.614 + }
95.615 + public long position() throws IOException {
95.616 + return read;
95.617 + }
95.618 + public SeekableByteChannel position(long pos) throws IOException {
95.619 + throw new UnsupportedOperationException();
95.620 + }
95.621 + public int read(ByteBuffer dst) throws IOException {
95.622 + return rbc.read(dst);
95.623 + }
95.624 + public SeekableByteChannel truncate(long size) throws IOException {
95.625 + throw new NonWritableChannelException();
95.626 + }
95.627 + public int write (ByteBuffer src) throws IOException {
95.628 + throw new NonWritableChannelException();
95.629 + }
95.630 + public long size() throws IOException {
95.631 + return size;
95.632 + }
95.633 + public void close() throws IOException {
95.634 + rbc.close();
95.635 + }
95.636 + };
95.637 + }
95.638 + }
95.639 +
95.640 + // Returns a FileChannel of the specified entry.
95.641 + //
95.642 + // This implementation creates a temporary file on the default file system,
95.643 + // copy the entry data into it if the entry exists, and then create a
95.644 + // FileChannel on top of it.
95.645 + FileChannel newFileChannel(byte[] path,
95.646 + Set<? extends OpenOption> options,
95.647 + FileAttribute<?>... attrs)
95.648 + throws IOException
95.649 + {
95.650 + checkOptions(options);
95.651 + final boolean forWrite = (options.contains(StandardOpenOption.WRITE) ||
95.652 + options.contains(StandardOpenOption.APPEND));
95.653 + Entry e = getEntry0(path);
95.654 + if (forWrite) {
95.655 + checkWritable();
95.656 + if (e == null) {
95.657 + if (!options.contains(StandardOpenOption.CREATE_NEW))
95.658 + throw new NoSuchFileException(getString(path));
95.659 + } else {
95.660 + if (options.contains(StandardOpenOption.CREATE_NEW))
95.661 + throw new FileAlreadyExistsException(getString(path));
95.662 + if (e.isDir())
95.663 + throw new FileAlreadyExistsException("directory <"
95.664 + + getString(path) + "> exists");
95.665 + }
95.666 + options.remove(StandardOpenOption.CREATE_NEW); // for tmpfile
95.667 + } else if (e == null || e.isDir()) {
95.668 + throw new NoSuchFileException(getString(path));
95.669 + }
95.670 +
95.671 + final boolean isFCH = (e != null && e.type == Entry.FILECH);
95.672 + final Path tmpfile = isFCH ? e.file : getTempPathForEntry(path);
95.673 + final FileChannel fch = tmpfile.getFileSystem()
95.674 + .provider()
95.675 + .newFileChannel(tmpfile, options, attrs);
95.676 + final Entry u = isFCH ? e : new Entry(path, tmpfile, Entry.FILECH);
95.677 + if (forWrite) {
95.678 + u.flag = FLAG_DATADESCR;
95.679 + u.method = METHOD_DEFLATED;
95.680 + }
95.681 + // is there a better way to hook into the FileChannel's close method?
95.682 + return new FileChannel() {
95.683 + public int write(ByteBuffer src) throws IOException {
95.684 + return fch.write(src);
95.685 + }
95.686 + public long write(ByteBuffer[] srcs, int offset, int length)
95.687 + throws IOException
95.688 + {
95.689 + return fch.write(srcs, offset, length);
95.690 + }
95.691 + public long position() throws IOException {
95.692 + return fch.position();
95.693 + }
95.694 + public FileChannel position(long newPosition)
95.695 + throws IOException
95.696 + {
95.697 + fch.position(newPosition);
95.698 + return this;
95.699 + }
95.700 + public long size() throws IOException {
95.701 + return fch.size();
95.702 + }
95.703 + public FileChannel truncate(long size)
95.704 + throws IOException
95.705 + {
95.706 + fch.truncate(size);
95.707 + return this;
95.708 + }
95.709 + public void force(boolean metaData)
95.710 + throws IOException
95.711 + {
95.712 + fch.force(metaData);
95.713 + }
95.714 + public long transferTo(long position, long count,
95.715 + WritableByteChannel target)
95.716 + throws IOException
95.717 + {
95.718 + return fch.transferTo(position, count, target);
95.719 + }
95.720 + public long transferFrom(ReadableByteChannel src,
95.721 + long position, long count)
95.722 + throws IOException
95.723 + {
95.724 + return fch.transferFrom(src, position, count);
95.725 + }
95.726 + public int read(ByteBuffer dst) throws IOException {
95.727 + return fch.read(dst);
95.728 + }
95.729 + public int read(ByteBuffer dst, long position)
95.730 + throws IOException
95.731 + {
95.732 + return fch.read(dst, position);
95.733 + }
95.734 + public long read(ByteBuffer[] dsts, int offset, int length)
95.735 + throws IOException
95.736 + {
95.737 + return fch.read(dsts, offset, length);
95.738 + }
95.739 + public int write(ByteBuffer src, long position)
95.740 + throws IOException
95.741 + {
95.742 + return fch.write(src, position);
95.743 + }
95.744 + public MappedByteBuffer map(MapMode mode,
95.745 + long position, long size)
95.746 + throws IOException
95.747 + {
95.748 + throw new UnsupportedOperationException();
95.749 + }
95.750 + public FileLock lock(long position, long size, boolean shared)
95.751 + throws IOException
95.752 + {
95.753 + return fch.lock(position, size, shared);
95.754 + }
95.755 + public FileLock tryLock(long position, long size, boolean shared)
95.756 + throws IOException
95.757 + {
95.758 + return fch.tryLock(position, size, shared);
95.759 + }
95.760 + protected void implCloseChannel() throws IOException {
95.761 + fch.close();
95.762 + if (forWrite) {
95.763 + u.mtime = javaToDosTime(System.currentTimeMillis());
95.764 + u.size = Attributes.readBasicFileAttributes(u.file).size();
95.765 + update(u);
95.766 + } else {
95.767 + if (!isFCH) // if this is a new fch for reading
95.768 + removeTempPathForEntry(tmpfile);
95.769 + }
95.770 + }
95.771 + };
95.772 + }
95.773 +
95.774 + // the outstanding input streams that need to be closed
95.775 + private Set<InputStream> streams =
95.776 + Collections.synchronizedSet(new HashSet<InputStream>());
95.777 +
95.778 + // the ex-channel and ex-path that need to close when their outstanding
95.779 + // input streams are all closed by the obtainers.
95.780 + private Set<ExChannelCloser> exChClosers = new HashSet<>();
95.781 +
95.782 + private Set<Path> tmppaths = new HashSet<>();
95.783 + private Path getTempPathForEntry(byte[] path) throws IOException {
95.784 + Path tmpPath = createTempFileInSameDirectoryAs(zfpath);
95.785 + tmppaths.add(tmpPath);
95.786 +
95.787 + if (path != null) {
95.788 + Entry e = getEntry0(path);
95.789 + if (e != null) {
95.790 + InputStream is = newInputStream(path);
95.791 + OutputStream os = tmpPath.newOutputStream(WRITE);
95.792 + try {
95.793 + copyStream(is, os);
95.794 + } finally {
95.795 + is.close();
95.796 + os.close();
95.797 + }
95.798 + }
95.799 + }
95.800 + return tmpPath;
95.801 + }
95.802 +
95.803 + private void removeTempPathForEntry(Path path) throws IOException {
95.804 + path.delete();
95.805 + tmppaths.remove(path);
95.806 + }
95.807 +
95.808 + // check if all parents really exit. ZIP spec does not require
95.809 + // the existence of any "parent directory".
95.810 + private void checkParents(byte[] path) throws IOException {
95.811 + while ((path = getParent(path)) != null) {
95.812 + if (!inodes.containsKey(new EntryName(path)))
95.813 + throw new NoSuchFileException(getString(path));
95.814 + }
95.815 + }
95.816 +
95.817 + private static byte[] getParent(byte[] path) {
95.818 + int off = path.length - 1;
95.819 + if (off > 0 && path[off] == '/') // isDirectory
95.820 + off--;
95.821 + while (off > 0 && path[off] != '/') { off--; }
95.822 + if (off == 0)
95.823 + return null; // top entry
95.824 + return Arrays.copyOf(path, off + 1);
95.825 + }
95.826 +
95.827 + // If "starter" is the parent directory of "path"
95.828 + private static boolean isParentOf(byte[] p, byte[] c) {
95.829 + final int plen = p.length;
95.830 + if (plen == 0) // root dir
95.831 + return true;
95.832 + if (plen >= c.length)
95.833 + return false;
95.834 + int n = 0;
95.835 + while (n < plen) {
95.836 + if (p[n] != c[n])
95.837 + return false;
95.838 + n++;
95.839 + }
95.840 + if (p[n - 1] != '/' && (c[n] != '/' || n == c.length - 1))
95.841 + return false;
95.842 + return true;
95.843 + }
95.844 +
95.845 + ///////////////////////////////////////////////////////////////////
95.846 + private void initZipFile() throws IOException {
95.847 + ch = zfpath.newByteChannel(READ);
95.848 + initCEN();
95.849 + }
95.850 +
95.851 + private volatile boolean isOpen = true;
95.852 + private SeekableByteChannel ch; // channel to the zipfile
95.853 + ByteBuffer cen; // CEN & ENDHDR
95.854 + private END end;
95.855 + private long locpos; // position of first LOC header (usually 0)
95.856 +
95.857 + // name -> pos (in cen), package private for ZipInfo
95.858 + LinkedHashMap<EntryName, IndexNode> inodes;
95.859 +
95.860 + byte[] getBytes(String name) {
95.861 + return zc.getBytes(name);
95.862 + }
95.863 + String getString(byte[] name) {
95.864 + return zc.toString(name);
95.865 + }
95.866 +
95.867 + protected void finalize() throws IOException {
95.868 + close();
95.869 + }
95.870 +
95.871 + private long getDataPos(Entry e) throws IOException {
95.872 + if (e.locoff == -1) {
95.873 + Entry e2 = getEntry0(e.name);
95.874 + if (e2 == null)
95.875 + throw new ZipException("invalid loc for entry <" + e.name + ">");
95.876 + e.locoff = e2.locoff;
95.877 + }
95.878 + byte[] buf = new byte[LOCHDR];
95.879 + if (readFullyAt(buf, 0, buf.length, e.locoff) != buf.length)
95.880 + throw new ZipException("invalid loc for entry <" + e.name + ">");
95.881 + return locpos + e.locoff + LOCHDR + LOCNAM(buf) + LOCEXT(buf);
95.882 + }
95.883 +
95.884 + // Reads len bytes of data from the specified offset into buf.
95.885 + // Returns the total number of bytes read.
95.886 + // Each/every byte read from here (except the cen, which is mapped).
95.887 + private long readFullyAt(byte[] buf, int off, long len, long pos)
95.888 + throws IOException
95.889 + {
95.890 + ByteBuffer bb = ByteBuffer.wrap(buf);
95.891 + bb.position(off);
95.892 + bb.limit((int)(off + len));
95.893 + return readFullyAt(bb, pos);
95.894 + }
95.895 +
95.896 + private long readFullyAt(ByteBuffer bb, long pos)
95.897 + throws IOException
95.898 + {
95.899 + synchronized(ch) {
95.900 + return ch.position(pos).read(bb);
95.901 + }
95.902 + }
95.903 +
95.904 + // Searches for end of central directory (END) header. The contents of
95.905 + // the END header will be read and placed in endbuf. Returns the file
95.906 + // position of the END header, otherwise returns -1 if the END header
95.907 + // was not found or an error occurred.
95.908 + private END findEND() throws IOException
95.909 + {
95.910 + byte[] buf = new byte[READBLOCKSZ];
95.911 + long ziplen = ch.size();
95.912 + long minHDR = (ziplen - END_MAXLEN) > 0 ? ziplen - END_MAXLEN : 0;
95.913 + long minPos = minHDR - (buf.length - ENDHDR);
95.914 +
95.915 + for (long pos = ziplen - buf.length; pos >= minPos; pos -= (buf.length - ENDHDR))
95.916 + {
95.917 + int off = 0;
95.918 + if (pos < 0) {
95.919 + // Pretend there are some NUL bytes before start of file
95.920 + off = (int)-pos;
95.921 + Arrays.fill(buf, 0, off, (byte)0);
95.922 + }
95.923 + int len = buf.length - off;
95.924 + if (readFullyAt(buf, off, len, pos + off) != len)
95.925 + zerror("zip END header not found");
95.926 +
95.927 + // Now scan the block backwards for END header signature
95.928 + for (int i = buf.length - ENDHDR; i >= 0; i--) {
95.929 + if (buf[i+0] == (byte)'P' &&
95.930 + buf[i+1] == (byte)'K' &&
95.931 + buf[i+2] == (byte)'\005' &&
95.932 + buf[i+3] == (byte)'\006' &&
95.933 + (pos + i + ENDHDR + ENDCOM(buf, i) == ziplen)) {
95.934 + // Found END header
95.935 + buf = Arrays.copyOfRange(buf, i, i + ENDHDR);
95.936 + END end = new END();
95.937 + end.endsub = ENDSUB(buf);
95.938 + end.centot = ENDTOT(buf);
95.939 + end.cenlen = ENDSIZ(buf);
95.940 + end.cenoff = ENDOFF(buf);
95.941 + end.comlen = ENDCOM(buf);
95.942 + end.endpos = pos + i;
95.943 + if (end.cenlen == ZIP64_MINVAL ||
95.944 + end.cenoff == ZIP64_MINVAL ||
95.945 + end.centot == ZIP64_MINVAL32)
95.946 + {
95.947 + // need to find the zip64 end;
95.948 + byte[] loc64 = new byte[ZIP64_LOCHDR];
95.949 + if (readFullyAt(loc64, 0, loc64.length, end.endpos - ZIP64_LOCHDR)
95.950 + != loc64.length) {
95.951 + return end;
95.952 + }
95.953 + long end64pos = ZIP64_LOCOFF(loc64);
95.954 + byte[] end64buf = new byte[ZIP64_ENDHDR];
95.955 + if (readFullyAt(end64buf, 0, end64buf.length, end64pos)
95.956 + != end64buf.length) {
95.957 + return end;
95.958 + }
95.959 + // end64 found, re-calcualte everything.
95.960 + end.cenlen = ZIP64_ENDSIZ(end64buf);
95.961 + end.cenoff = ZIP64_ENDOFF(end64buf);
95.962 + end.centot = (int)ZIP64_ENDTOT(end64buf); // assume total < 2g
95.963 + end.endpos = end64pos;
95.964 + }
95.965 + return end;
95.966 + }
95.967 + }
95.968 + }
95.969 + zerror("zip END header not found");
95.970 + return null; //make compiler happy
95.971 + }
95.972 +
95.973 + // Reads zip file central directory. Returns the file position of first
95.974 + // CEN header, otherwise returns -1 if an error occured. If zip->msg != NULL
95.975 + // then the error was a zip format error and zip->msg has the error text.
95.976 + // Always pass in -1 for knownTotal; it's used for a recursive call.
95.977 + private long initCEN() throws IOException {
95.978 + end = findEND();
95.979 + if (end.endpos == 0) {
95.980 + inodes = new LinkedHashMap<EntryName, IndexNode>(10);
95.981 + locpos = 0;
95.982 + return 0; // only END header present
95.983 + }
95.984 + if (end.cenlen > end.endpos)
95.985 + zerror("invalid END header (bad central directory size)");
95.986 + long cenpos = end.endpos - end.cenlen; // position of CEN table
95.987 +
95.988 + // Get position of first local file (LOC) header, taking into
95.989 + // account that there may be a stub prefixed to the zip file.
95.990 + locpos = cenpos - end.cenoff;
95.991 + if (locpos < 0)
95.992 + zerror("invalid END header (bad central directory offset)");
95.993 +
95.994 + // read in the CEN and END
95.995 + cen = ByteBuffer.allocate((int)(end.cenlen + ENDHDR));
95.996 + if (readFullyAt(cen, cenpos) != end.cenlen + ENDHDR) {
95.997 + zerror("read CEN tables failed");
95.998 + }
95.999 + cen.order(ByteOrder.LITTLE_ENDIAN).flip();
95.1000 +
95.1001 + // Iterate through the entries in the central directory
95.1002 + inodes = new LinkedHashMap<EntryName, IndexNode>(end.centot + 1);
95.1003 + int pos = 0;
95.1004 + int limit = cen.remaining() - ENDHDR;
95.1005 + int i = 0;
95.1006 + byte[] bBuf = new byte[1024];
95.1007 + while (pos < limit) {
95.1008 + if (CENSIG(cen, pos) != CENSIG)
95.1009 + zerror("invalid CEN header (bad signature)");
95.1010 + int method = CENHOW(cen, pos);
95.1011 + int nlen = CENNAM(cen, pos);
95.1012 + int elen = CENEXT(cen, pos);
95.1013 + int clen = CENCOM(cen, pos);
95.1014 + if ((CENFLG(cen, pos) & 1) != 0)
95.1015 + zerror("invalid CEN header (encrypted entry)");
95.1016 + if (method != METHOD_STORED && method != METHOD_DEFLATED)
95.1017 + zerror("invalid CEN header (bad compression method: " + method + ")");
95.1018 + if (pos + CENHDR + nlen > limit)
95.1019 + zerror("invalid CEN header (bad header size)");
95.1020 + if (bBuf.length < nlen)
95.1021 + bBuf = new byte[nlen];
95.1022 + cen.position(pos + CENHDR);
95.1023 + byte[] name = new byte[nlen];
95.1024 + cen.get(name);
95.1025 + inodes.put(new EntryName(name), new IndexNode(name, pos));
95.1026 + // skip ext and comment
95.1027 + cen.position(pos += (CENHDR + nlen + elen + clen));
95.1028 + i++;
95.1029 + }
95.1030 + if (cen.remaining() != ENDHDR) {
95.1031 + zerror("invalid CEN header (bad header size)");
95.1032 + }
95.1033 + dirs = null; // clear the dir map
95.1034 + return cenpos;
95.1035 + }
95.1036 +
95.1037 + private void ensureOpen() throws IOException {
95.1038 + if (!isOpen)
95.1039 + throw new ClosedFileSystemException();
95.1040 + }
95.1041 +
95.1042 + // Creates a new empty temporary file in the same directory as the
95.1043 + // specified file. A variant of File.createTempFile.
95.1044 + private static Path createTempFileInSameDirectoryAs(Path path)
95.1045 + throws IOException
95.1046 + {
95.1047 + Path parent = path.toAbsolutePath().getParent();
95.1048 + String dir = (parent == null)? "." : parent.toString();
95.1049 + return File.createTempFile("zipfstmp", null, new File(dir)).toPath();
95.1050 + }
95.1051 +
95.1052 + ////////////////////update & sync //////////////////////////////////////
95.1053 +
95.1054 + private boolean hasUpdate = false;
95.1055 + private void updateDelete(Entry e) {
95.1056 + EntryName en = new EntryName(e.name);
95.1057 + inodes.remove(en);
95.1058 + hasUpdate = true;
95.1059 + }
95.1060 +
95.1061 + private void update(Entry e) {
95.1062 + EntryName en = new EntryName(e.name);
95.1063 + inodes.put(en, e);
95.1064 + hasUpdate = true;
95.1065 + }
95.1066 +
95.1067 + // copy over the whole LOC entry (header if necessary, data and ext) from
95.1068 + // old zip to the new one.
95.1069 + private long copyLOCEntry(Entry e, boolean updateHeader,
95.1070 + OutputStream os,
95.1071 + long written, byte[] buf)
95.1072 + throws IOException
95.1073 + {
95.1074 + long locoff = e.locoff; // where to read
95.1075 + e.locoff = written; // update the e.locoff with new value
95.1076 +
95.1077 + // calculate the size need to write out
95.1078 + long size = 0;
95.1079 + // if there is A ext
95.1080 + if ((e.flag & FLAG_DATADESCR) != 0) {
95.1081 + if (e.size >= ZIP64_MINVAL || e.csize >= ZIP64_MINVAL)
95.1082 + size = 24;
95.1083 + else
95.1084 + size = 16;
95.1085 + }
95.1086 + if (updateHeader) { // if we need update the loc header
95.1087 + locoff += LOCHDR + e.nlen + e.elen; // skip header
95.1088 + size += e.csize;
95.1089 + written = e.writeLOC(os) + size;
95.1090 + } else {
95.1091 + size += LOCHDR + e.nlen + e.elen + e.csize;
95.1092 + written = size;
95.1093 + }
95.1094 + int n;
95.1095 + while (size > 0 &&
95.1096 + (n = (int)readFullyAt(buf, 0, buf.length, locoff)) != -1)
95.1097 + {
95.1098 + if (size < n)
95.1099 + n = (int)size;
95.1100 + os.write(buf, 0, n);
95.1101 + size -= n;
95.1102 + locoff += n;
95.1103 + }
95.1104 + return written;
95.1105 + }
95.1106 +
95.1107 + // sync the zip file system, if there is any udpate
95.1108 + private void sync() throws IOException {
95.1109 + assert Thread.holdsLock(this);
95.1110 +
95.1111 + // check ex-closer
95.1112 + if (!exChClosers.isEmpty()) {
95.1113 + for (ExChannelCloser ecc : exChClosers) {
95.1114 + if (ecc.streams.isEmpty()) {
95.1115 + ecc.ch.close();
95.1116 + ecc.path.delete();
95.1117 + exChClosers.remove(ecc);
95.1118 + }
95.1119 + }
95.1120 + }
95.1121 + if (!hasUpdate)
95.1122 + return;
95.1123 +
95.1124 + Path tmpFile = createTempFileInSameDirectoryAs(zfpath);
95.1125 + OutputStream os = tmpFile.newOutputStream(WRITE);
95.1126 + ArrayList<Entry> elist = new ArrayList<>(inodes.size());
95.1127 + long written = 0;
95.1128 + byte[] buf = new byte[8192];
95.1129 + Entry e = null;
95.1130 +
95.1131 + // write loc
95.1132 + for (IndexNode inode : inodes.values()) {
95.1133 + if (inode instanceof Entry) { // an updated inode
95.1134 + e = (Entry)inode;
95.1135 + try {
95.1136 + if (e.type == Entry.COPY) {
95.1137 + // entry copy: the only thing changed is the "name"
95.1138 + // and "nlen" in LOC header, so we udpate/rewrite the
95.1139 + // LOC in new file and simply copy the rest (data and
95.1140 + // ext) without enflating/deflating from the old zip
95.1141 + // file LOC entry.
95.1142 + written += copyLOCEntry(e, true, os, written, buf);
95.1143 + } else { // NEW or FILECH
95.1144 + e.locoff = written;
95.1145 + written += e.writeLOC(os); // write loc header
95.1146 + if (e.bytes != null) { // in-memory, deflated
95.1147 + os.write(e.bytes); // already
95.1148 + written += e.bytes.length;
95.1149 + } else if (e.file != null) { // tmp file
95.1150 + InputStream is = e.file.newInputStream();
95.1151 + int n;
95.1152 + if (e.type == Entry.NEW) { // deflated already
95.1153 + while ((n = is.read(buf)) != -1) {
95.1154 + os.write(buf, 0, n);
95.1155 + written += n;
95.1156 + }
95.1157 + } else if (e.type == Entry.FILECH) {
95.1158 + // the data are not deflated, use ZEOS
95.1159 + OutputStream os2 = new EntryOutputStream(e, os);
95.1160 + while ((n = is.read(buf)) != -1) {
95.1161 + os2.write(buf, 0, n);
95.1162 + }
95.1163 + os2.close();
95.1164 + written += e.csize;
95.1165 + if ((e.flag & FLAG_DATADESCR) != 0)
95.1166 + written += e.writeEXT(os);
95.1167 + }
95.1168 + is.close();
95.1169 + e.file.delete();
95.1170 + tmppaths.remove(e.file);
95.1171 + } else {
95.1172 + // dir, 0-length data
95.1173 + }
95.1174 + }
95.1175 + elist.add(e);
95.1176 + } catch (IOException x) {
95.1177 + x.printStackTrace(); // skip any in-accurate entry
95.1178 + }
95.1179 + } else { // unchanged inode
95.1180 + e = Entry.readCEN(cen, inode.pos);
95.1181 + try {
95.1182 + written += copyLOCEntry(e, false, os, written, buf);
95.1183 + elist.add(e);
95.1184 + } catch (IOException x) {
95.1185 + x.printStackTrace(); // skip any wrong entry
95.1186 + }
95.1187 + }
95.1188 + }
95.1189 +
95.1190 + // now write back the cen and end table
95.1191 + end.cenoff = written;
95.1192 + for (Entry entry : elist) {
95.1193 + written += entry.writeCEN(os);
95.1194 + }
95.1195 + end.centot = elist.size();
95.1196 + end.cenlen = written - end.cenoff;
95.1197 + end.write(os, written);
95.1198 + os.close();
95.1199 +
95.1200 + if (!streams.isEmpty()) {
95.1201 + // There are outstanding input streams open on existing "ch",
95.1202 + // so, don't close the "cha" and delete the "file for now, let
95.1203 + // the "ex-channel-closer" to handle them
95.1204 + ExChannelCloser ecc = new ExChannelCloser(
95.1205 + createTempFileInSameDirectoryAs(zfpath),
95.1206 + ch,
95.1207 + streams);
95.1208 + zfpath.moveTo(ecc.path, REPLACE_EXISTING);
95.1209 + exChClosers.add(ecc);
95.1210 + streams = Collections.synchronizedSet(new HashSet<InputStream>());
95.1211 + } else {
95.1212 + ch.close();
95.1213 + zfpath.delete();
95.1214 + }
95.1215 + tmpFile.moveTo(zfpath, REPLACE_EXISTING);
95.1216 + hasUpdate = false; // clear
95.1217 +
95.1218 + if (isOpen) {
95.1219 + ch = zfpath.newByteChannel(READ); // re-fresh "ch" and "cen"
95.1220 + initCEN();
95.1221 + }
95.1222 + //System.out.println("->sync() done!");
95.1223 + }
95.1224 +
95.1225 + private Entry getEntry0(byte[] path) throws IOException {
95.1226 + assert Thread.holdsLock(this);
95.1227 +
95.1228 + if (path == null)
95.1229 + throw new NullPointerException("path");
95.1230 + if (path.length == 0)
95.1231 + return null;
95.1232 + EntryName en = new EntryName(path);
95.1233 + IndexNode inode = null;
95.1234 + synchronized (lock) {
95.1235 + ensureOpen();
95.1236 + if ((inode = inodes.get(en)) == null) {
95.1237 + if (path[path.length -1] == '/') // already has a slash
95.1238 + return null;
95.1239 + path = Arrays.copyOf(path, path.length + 1);
95.1240 + path[path.length - 1] = '/';
95.1241 + en.name(path);
95.1242 + if ((inode = inodes.get(en)) == null)
95.1243 + return null;
95.1244 + }
95.1245 + if (inode instanceof Entry)
95.1246 + return (Entry)inode;
95.1247 + return Entry.readCEN(cen, inode.pos);
95.1248 + }
95.1249 + }
95.1250 +
95.1251 + // Test if the "name" a parent directory of any entry (dir empty)
95.1252 + boolean isAncestor(byte[] name) {
95.1253 + for (Map.Entry<EntryName, IndexNode> entry : inodes.entrySet()) {
95.1254 + byte[] ename = entry.getKey().name;
95.1255 + if (isParentOf(name, ename))
95.1256 + return true;
95.1257 + }
95.1258 + return false;
95.1259 + }
95.1260 +
95.1261 + public void deleteFile(byte[] path, boolean failIfNotExists)
95.1262 + throws IOException
95.1263 + {
95.1264 + checkWritable();
95.1265 + synchronized(lock) {
95.1266 + Entry e = getEntry0(path);
95.1267 + if (e == null) {
95.1268 + if (path != null && path.length == 0)
95.1269 + throw new ZipException("root directory </> can't not be delete");
95.1270 + if (failIfNotExists)
95.1271 + throw new NoSuchFileException(getString(path));
95.1272 + } else {
95.1273 + if (e.isDir() && isAncestor(path))
95.1274 + throw new DirectoryNotEmptyException(getString(path));
95.1275 + updateDelete(e);
95.1276 + }
95.1277 + }
95.1278 + }
95.1279 +
95.1280 + private static void copyStream(InputStream is, OutputStream os)
95.1281 + throws IOException
95.1282 + {
95.1283 + byte[] copyBuf = new byte[8192];
95.1284 + int n;
95.1285 + while ((n = is.read(copyBuf)) != -1) {
95.1286 + os.write(copyBuf, 0, n);
95.1287 + }
95.1288 + }
95.1289 +
95.1290 + // Returns an out stream for either
95.1291 + // (1) writing the contents of a new entry, if the entry exits, or
95.1292 + // (2) updating/replacing the contents of the specified existing entry.
95.1293 + private OutputStream getOutputStream(Entry e) throws IOException {
95.1294 +
95.1295 + ensureOpen();
95.1296 + if (e.mtime == -1)
95.1297 + e.mtime = javaToDosTime(System.currentTimeMillis());
95.1298 + if (e.method == -1)
95.1299 + e.method = METHOD_DEFLATED; // TBD: use default method
95.1300 + // store size, compressed size, and crc-32 in LOC header
95.1301 + e.flag = 0;
95.1302 + if (zc.isUTF8())
95.1303 + e.flag |= FLAG_EFS;
95.1304 + OutputStream os;
95.1305 + if (useTempFile) {
95.1306 + e.file = getTempPathForEntry(null);
95.1307 + os = e.file.newOutputStream(WRITE);
95.1308 + } else {
95.1309 + os = new ByteArrayOutputStream((e.size > 0)? (int)e.size : 8192);
95.1310 + }
95.1311 + return new EntryOutputStream(e, os);
95.1312 + }
95.1313 +
95.1314 + private InputStream getInputStream(Entry e)
95.1315 + throws IOException
95.1316 + {
95.1317 + InputStream eis = null;
95.1318 +
95.1319 + if (e.type == Entry.NEW) {
95.1320 + if (e.bytes != null)
95.1321 + eis = new ByteArrayInputStream(e.bytes);
95.1322 + else if (e.file != null)
95.1323 + eis = e.file.newInputStream();
95.1324 + else
95.1325 + throw new ZipException("update entry data is missing");
95.1326 + } else if (e.type == Entry.FILECH) {
95.1327 + // FILECH result is un-compressed.
95.1328 + eis = e.file.newInputStream();
95.1329 + // TBD: wrap to hook close()
95.1330 + // streams.add(eis);
95.1331 + return eis;
95.1332 + } else { // untouced CEN or COPY
95.1333 + eis = new EntryInputStream(e, ch);
95.1334 + }
95.1335 + if (e.method == METHOD_DEFLATED) {
95.1336 + // MORE: Compute good size for inflater stream:
95.1337 + long bufSize = e.size + 2; // Inflater likes a bit of slack
95.1338 + if (bufSize > 65536)
95.1339 + bufSize = 8192;
95.1340 + final long size = e.size;;
95.1341 + eis = new InflaterInputStream(eis, getInflater(), (int)bufSize) {
95.1342 +
95.1343 + private boolean isClosed = false;
95.1344 + public void close() throws IOException {
95.1345 + if (!isClosed) {
95.1346 + releaseInflater(inf);
95.1347 + this.in.close();
95.1348 + isClosed = true;
95.1349 + }
95.1350 + }
95.1351 + // Override fill() method to provide an extra "dummy" byte
95.1352 + // at the end of the input stream. This is required when
95.1353 + // using the "nowrap" Inflater option. (it appears the new
95.1354 + // zlib in 7 does not need it, but keep it for now)
95.1355 + protected void fill() throws IOException {
95.1356 + if (eof) {
95.1357 + throw new EOFException(
95.1358 + "Unexpected end of ZLIB input stream");
95.1359 + }
95.1360 + len = this.in.read(buf, 0, buf.length);
95.1361 + if (len == -1) {
95.1362 + buf[0] = 0;
95.1363 + len = 1;
95.1364 + eof = true;
95.1365 + }
95.1366 + inf.setInput(buf, 0, len);
95.1367 + }
95.1368 + private boolean eof;
95.1369 +
95.1370 + public int available() throws IOException {
95.1371 + if (isClosed)
95.1372 + return 0;
95.1373 + long avail = size - inf.getBytesWritten();
95.1374 + return avail > (long) Integer.MAX_VALUE ?
95.1375 + Integer.MAX_VALUE : (int) avail;
95.1376 + }
95.1377 + };
95.1378 + } else if (e.method != METHOD_STORED) {
95.1379 + throw new ZipException("invalid compression method");
95.1380 + }
95.1381 + streams.add(eis);
95.1382 + return eis;
95.1383 + }
95.1384 +
95.1385 + // Inner class implementing the input stream used to read
95.1386 + // a (possibly compressed) zip file entry.
95.1387 + private class EntryInputStream extends InputStream {
95.1388 + private SeekableByteChannel zfch; // local ref to zipfs's "ch". zipfs.ch might
95.1389 + // point to a new channel after sync()
95.1390 + private long pos; // current position within entry data
95.1391 + protected long rem; // number of remaining bytes within entry
95.1392 + protected long size; // uncompressed size of this entry
95.1393 +
95.1394 + EntryInputStream(Entry e, SeekableByteChannel zfch)
95.1395 + throws IOException
95.1396 + {
95.1397 + this.zfch = zfch;
95.1398 + rem = e.csize;
95.1399 + size = e.size;
95.1400 + pos = getDataPos(e);
95.1401 + }
95.1402 + public int read(byte b[], int off, int len) throws IOException {
95.1403 + ensureOpen();
95.1404 + if (rem == 0) {
95.1405 + return -1;
95.1406 + }
95.1407 + if (len <= 0) {
95.1408 + return 0;
95.1409 + }
95.1410 + if (len > rem) {
95.1411 + len = (int) rem;
95.1412 + }
95.1413 + // readFullyAt()
95.1414 + long n = 0;
95.1415 + ByteBuffer bb = ByteBuffer.wrap(b);
95.1416 + bb.position(off);
95.1417 + bb.limit(off + len);
95.1418 + synchronized(zfch) {
95.1419 + n = zfch.position(pos).read(bb);
95.1420 + }
95.1421 + if (n > 0) {
95.1422 + pos += n;
95.1423 + rem -= n;
95.1424 + }
95.1425 + if (rem == 0) {
95.1426 + close();
95.1427 + }
95.1428 + return (int)n;
95.1429 + }
95.1430 + public int read() throws IOException {
95.1431 + byte[] b = new byte[1];
95.1432 + if (read(b, 0, 1) == 1) {
95.1433 + return b[0] & 0xff;
95.1434 + } else {
95.1435 + return -1;
95.1436 + }
95.1437 + }
95.1438 + public long skip(long n) throws IOException {
95.1439 + ensureOpen();
95.1440 + if (n > rem)
95.1441 + n = rem;
95.1442 + pos += n;
95.1443 + rem -= n;
95.1444 + if (rem == 0) {
95.1445 + close();
95.1446 + }
95.1447 + return n;
95.1448 + }
95.1449 + public int available() {
95.1450 + return rem > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) rem;
95.1451 + }
95.1452 +
95.1453 + public long size() {
95.1454 + return size;
95.1455 + }
95.1456 + public void close() {
95.1457 + rem = 0;
95.1458 + streams.remove(this);
95.1459 + }
95.1460 + }
95.1461 +
95.1462 + class EntryOutputStream extends DeflaterOutputStream
95.1463 + {
95.1464 + private CRC32 crc;
95.1465 + private Entry e;
95.1466 + private long written;
95.1467 +
95.1468 + EntryOutputStream(Entry e, OutputStream os)
95.1469 + throws IOException
95.1470 + {
95.1471 + super(os, getDeflater());
95.1472 + if (e == null)
95.1473 + throw new NullPointerException("Zip entry is null");
95.1474 + this.e = e;
95.1475 + crc = new CRC32();
95.1476 + }
95.1477 +
95.1478 + @Override
95.1479 + public void write(byte b[], int off, int len) throws IOException {
95.1480 + if (e.type != Entry.FILECH) // only from sync
95.1481 + ensureOpen();
95.1482 + if (off < 0 || len < 0 || off > b.length - len) {
95.1483 + throw new IndexOutOfBoundsException();
95.1484 + } else if (len == 0) {
95.1485 + return;
95.1486 + }
95.1487 + switch (e.method) {
95.1488 + case METHOD_DEFLATED:
95.1489 + super.write(b, off, len);
95.1490 + break;
95.1491 + case METHOD_STORED:
95.1492 + written += len;
95.1493 + out.write(b, off, len);
95.1494 + break;
95.1495 + default:
95.1496 + throw new ZipException("invalid compression method");
95.1497 + }
95.1498 + crc.update(b, off, len);
95.1499 + }
95.1500 +
95.1501 + @Override
95.1502 + public void close() throws IOException {
95.1503 + // TBD ensureOpen();
95.1504 + switch (e.method) {
95.1505 + case METHOD_DEFLATED:
95.1506 + finish();
95.1507 + e.size = def.getBytesRead();
95.1508 + e.csize = def.getBytesWritten();
95.1509 + e.crc = crc.getValue();
95.1510 + break;
95.1511 + case METHOD_STORED:
95.1512 + // we already know that both e.size and e.csize are the same
95.1513 + e.size = e.csize = written;
95.1514 + e.crc = crc.getValue();
95.1515 + break;
95.1516 + default:
95.1517 + throw new ZipException("invalid compression method");
95.1518 + }
95.1519 + //crc.reset();
95.1520 + if (out instanceof ByteArrayOutputStream)
95.1521 + e.bytes = ((ByteArrayOutputStream)out).toByteArray();
95.1522 +
95.1523 + if (e.type == Entry.FILECH) {
95.1524 + releaseDeflater(def);
95.1525 + return;
95.1526 + }
95.1527 + super.close();
95.1528 + releaseDeflater(def);
95.1529 + update(e);
95.1530 + }
95.1531 + }
95.1532 +
95.1533 + private static void zerror(String msg) {
95.1534 + throw new ZipError(msg);
95.1535 + }
95.1536 +
95.1537 + // Maxmum number of de/inflater we cache
95.1538 + private final int MAX_FLATER = 20;
95.1539 + // List of available Inflater objects for decompression
95.1540 + private List<Inflater> inflaters = new ArrayList<>();
95.1541 +
95.1542 + // Gets an inflater from the list of available inflaters or allocates
95.1543 + // a new one.
95.1544 + private Inflater getInflater() {
95.1545 + synchronized (inflaters) {
95.1546 + int size = inflaters.size();
95.1547 + if (size > 0) {
95.1548 + Inflater inf = (Inflater)inflaters.remove(size - 1);
95.1549 + return inf;
95.1550 + } else {
95.1551 + return new Inflater(true);
95.1552 + }
95.1553 + }
95.1554 + }
95.1555 +
95.1556 + // Releases the specified inflater to the list of available inflaters.
95.1557 + private void releaseInflater(Inflater inf) {
95.1558 + synchronized (inflaters) {
95.1559 + if (inflaters.size() < MAX_FLATER) {
95.1560 + inf.reset();
95.1561 + inflaters.add(inf);
95.1562 + } else {
95.1563 + inf.end();
95.1564 + }
95.1565 + }
95.1566 + }
95.1567 +
95.1568 + // List of available Deflater objects for compression
95.1569 + private List<Deflater> deflaters = new ArrayList<>();
95.1570 +
95.1571 + // Gets an deflater from the list of available deflaters or allocates
95.1572 + // a new one.
95.1573 + private Deflater getDeflater() {
95.1574 + synchronized (deflaters) {
95.1575 + int size = deflaters.size();
95.1576 + if (size > 0) {
95.1577 + Deflater def = (Deflater)deflaters.remove(size - 1);
95.1578 + return def;
95.1579 + } else {
95.1580 + return new Deflater(Deflater.DEFAULT_COMPRESSION, true);
95.1581 + }
95.1582 + }
95.1583 + }
95.1584 +
95.1585 + // Releases the specified inflater to the list of available inflaters.
95.1586 + private void releaseDeflater(Deflater def) {
95.1587 + synchronized (deflaters) {
95.1588 + if (inflaters.size() < MAX_FLATER) {
95.1589 + def.reset();
95.1590 + deflaters.add(def);
95.1591 + } else {
95.1592 + def.end();
95.1593 + }
95.1594 + }
95.1595 + }
95.1596 +
95.1597 + // End of central directory record
95.1598 + static class END {
95.1599 + int disknum;
95.1600 + int sdisknum;
95.1601 + int endsub; // endsub
95.1602 + int centot; // 4 bytes
95.1603 + long cenlen; // 4 bytes
95.1604 + long cenoff; // 4 bytes
95.1605 + int comlen; // comment length
95.1606 + byte[] comment;
95.1607 +
95.1608 + /* members of Zip64 end of central directory locator */
95.1609 + int diskNum;
95.1610 + long endpos;
95.1611 + int disktot;
95.1612 +
95.1613 + void write(OutputStream os, long offset) throws IOException {
95.1614 + boolean hasZip64 = false;
95.1615 + long xlen = cenlen;
95.1616 + long xoff = cenoff;
95.1617 + if (xlen >= ZIP64_MINVAL) {
95.1618 + xlen = ZIP64_MINVAL;
95.1619 + hasZip64 = true;
95.1620 + }
95.1621 + if (xoff >= ZIP64_MINVAL) {
95.1622 + xoff = ZIP64_MINVAL;
95.1623 + hasZip64 = true;
95.1624 + }
95.1625 + int count = centot;
95.1626 + if (count >= ZIP64_MINVAL32) {
95.1627 + count = ZIP64_MINVAL32;
95.1628 + hasZip64 = true;
95.1629 + }
95.1630 + if (hasZip64) {
95.1631 + long off64 = offset;
95.1632 + //zip64 end of central directory record
95.1633 + writeInt(os, ZIP64_ENDSIG); // zip64 END record signature
95.1634 + writeLong(os, ZIP64_ENDHDR - 12); // size of zip64 end
95.1635 + writeShort(os, 45); // version made by
95.1636 + writeShort(os, 45); // version needed to extract
95.1637 + writeInt(os, 0); // number of this disk
95.1638 + writeInt(os, 0); // central directory start disk
95.1639 + writeLong(os, centot); // number of directory entires on disk
95.1640 + writeLong(os, centot); // number of directory entires
95.1641 + writeLong(os, cenlen); // length of central directory
95.1642 + writeLong(os, cenoff); // offset of central directory
95.1643 +
95.1644 + //zip64 end of central directory locator
95.1645 + writeInt(os, ZIP64_LOCSIG); // zip64 END locator signature
95.1646 + writeInt(os, 0); // zip64 END start disk
95.1647 + writeLong(os, off64); // offset of zip64 END
95.1648 + writeInt(os, 1); // total number of disks (?)
95.1649 + }
95.1650 + writeInt(os, ENDSIG); // END record signature
95.1651 + writeShort(os, 0); // number of this disk
95.1652 + writeShort(os, 0); // central directory start disk
95.1653 + writeShort(os, count); // number of directory entries on disk
95.1654 + writeShort(os, count); // total number of directory entries
95.1655 + writeInt(os, xlen); // length of central directory
95.1656 + writeInt(os, xoff); // offset of central directory
95.1657 + if (comment != null) { // zip file comment
95.1658 + writeShort(os, comment.length);
95.1659 + writeBytes(os, comment);
95.1660 + } else {
95.1661 + writeShort(os, 0);
95.1662 + }
95.1663 + }
95.1664 + }
95.1665 +
95.1666 + // wrapper for the byte[] name
95.1667 + static class EntryName {
95.1668 + byte[] name;
95.1669 + int hashcode; // node is hashable/hashed by its name
95.1670 +
95.1671 + public EntryName (byte[] name) {
95.1672 + name(name);
95.1673 + }
95.1674 +
95.1675 + void name(byte[] name) {
95.1676 + this.name = name;
95.1677 + this.hashcode = Arrays.hashCode(name);
95.1678 + }
95.1679 +
95.1680 + public boolean equals(Object other) {
95.1681 + if (!(other instanceof EntryName))
95.1682 + return false;
95.1683 + return Arrays.equals(name, ((EntryName)other).name);
95.1684 + }
95.1685 +
95.1686 + public int hashCode() {
95.1687 + return hashcode;
95.1688 + }
95.1689 + }
95.1690 +
95.1691 + // can simply use Integer instead, if we don't use it to
95.1692 + // build a internal node tree.
95.1693 + static class IndexNode {
95.1694 + byte[] name;
95.1695 + int pos = -1; // postion in cen table, -1 menas the
95.1696 + // entry does not exists in zip file
95.1697 + IndexNode(byte[] name, int pos) {
95.1698 + this.name = name;
95.1699 + this.pos = pos;
95.1700 + }
95.1701 +
95.1702 + IndexNode() {}
95.1703 +
95.1704 + IndexNode sibling;
95.1705 + IndexNode child; // 1st child
95.1706 + }
95.1707 +
95.1708 + static class Entry extends IndexNode {
95.1709 +
95.1710 + static final int CEN = 1; // entry read from cen
95.1711 + static final int NEW = 2; // updated contents in bytes or file
95.1712 + static final int FILECH = 3; // fch update in "file"
95.1713 + static final int COPY = 4; // copy of a CEN entry
95.1714 +
95.1715 + byte[] bytes; // updated content bytes
95.1716 + Path file; // use tmp file to store bytes;
95.1717 + int type = CEN; // default is the entry read from cen
95.1718 +
95.1719 + // entry attributes
95.1720 + int version;
95.1721 + int flag;
95.1722 + int method = -1; // compression method
95.1723 + long mtime = -1; // last modification time (in DOS time)
95.1724 + long atime = -1; // last access time
95.1725 + long ctime = -1; // create time
95.1726 + long crc = -1; // crc-32 of entry data
95.1727 + long csize = -1; // compressed size of entry data
95.1728 + long size = -1; // uncompressed size of entry data
95.1729 + int nlen;
95.1730 + int elen;
95.1731 + byte[] extra;
95.1732 +
95.1733 + // loc
95.1734 + long startPos;
95.1735 + long endPos; // exclusive
95.1736 +
95.1737 + // cen
95.1738 + int versionMade;
95.1739 + int disk;
95.1740 + int attrs;
95.1741 + long attrsEx;
95.1742 + long locoff;
95.1743 +
95.1744 + int clen;
95.1745 + byte[] comment;
95.1746 +
95.1747 + // ZIP64 flag
95.1748 + boolean hasZip64;
95.1749 +
95.1750 + Entry() {}
95.1751 +
95.1752 + Entry(byte[] name) {
95.1753 + this.name = name;
95.1754 + //this.nlen = name.length;
95.1755 + this.mtime = javaToDosTime(System.currentTimeMillis());
95.1756 + this.crc = 0;
95.1757 + this.size = 0;
95.1758 + this.csize = 0;
95.1759 + this.method = METHOD_DEFLATED;
95.1760 + }
95.1761 +
95.1762 + Entry(byte[] name, int type) {
95.1763 + this(name);
95.1764 + this.type = type;
95.1765 + }
95.1766 +
95.1767 + Entry (byte[] name, Path file, int type) {
95.1768 + this(name, type);
95.1769 + this.file = file;
95.1770 + this.method = METHOD_STORED;
95.1771 + }
95.1772 +
95.1773 + Entry(Entry e) {
95.1774 + this.version = e.version;
95.1775 + this.name = e.name; // copyOf?
95.1776 + this.nlen = e.nlen;
95.1777 + this.ctime = e.ctime;
95.1778 + this.atime = e.atime;
95.1779 + this.mtime = e.mtime;
95.1780 + this.crc = e.crc;
95.1781 + this.size = e.size;
95.1782 + this.csize = e.csize;
95.1783 + this.method = e.method;
95.1784 + this.extra = (e.extra == null)?
95.1785 + null:Arrays.copyOf(e.extra, e.extra.length);
95.1786 + this.elen = e.elen;
95.1787 + this.versionMade = e.versionMade;
95.1788 + this.disk = e.disk;
95.1789 + this.attrs = e.attrs;
95.1790 + this.attrsEx = e.attrsEx;
95.1791 + this.locoff = e.locoff;
95.1792 + this.clen = e.clen;
95.1793 + this.comment = (e.comment == null)?
95.1794 + null:Arrays.copyOf(e.comment, e.comment.length);
95.1795 + this.startPos = e.startPos;
95.1796 + this.endPos = e.endPos;
95.1797 + this.hasZip64 = e.hasZip64;;
95.1798 + }
95.1799 +
95.1800 + Entry (Entry e, int type) {
95.1801 + this(e);
95.1802 + this.type = type;
95.1803 + }
95.1804 +
95.1805 + boolean isDir() {
95.1806 + return name != null &&
95.1807 + (name.length == 0 ||
95.1808 + name[name.length - 1] == '/');
95.1809 + }
95.1810 +
95.1811 + int version() throws ZipException {
95.1812 + if (method == METHOD_DEFLATED)
95.1813 + return 20;
95.1814 + else if (method == METHOD_STORED)
95.1815 + return 10;
95.1816 + throw new ZipException("unsupported compression method");
95.1817 + }
95.1818 +
95.1819 + ///////////////////// CEN //////////////////////
95.1820 + static Entry readCEN(ByteBuffer cen, int pos) throws IOException
95.1821 + {
95.1822 + return new Entry().cen(cen, pos);
95.1823 + }
95.1824 +
95.1825 + private Entry cen(ByteBuffer cen, int pos) throws IOException
95.1826 + {
95.1827 + if (CENSIG(cen, pos) != CENSIG)
95.1828 + zerror("invalid CEN header (bad signature)");
95.1829 + versionMade = CENVEM(cen, pos);
95.1830 + version = CENVER(cen, pos);
95.1831 + flag = CENFLG(cen, pos);
95.1832 + method = CENHOW(cen, pos);
95.1833 + mtime = CENTIM(cen, pos);
95.1834 + crc = CENCRC(cen, pos);
95.1835 + csize = CENSIZ(cen, pos);
95.1836 + size = CENLEN(cen, pos);
95.1837 + nlen = CENNAM(cen, pos);
95.1838 + elen = CENEXT(cen, pos);
95.1839 + clen = CENCOM(cen, pos);
95.1840 + disk = CENDSK(cen, pos);
95.1841 + attrs = CENATT(cen, pos);
95.1842 + attrsEx = CENATX(cen, pos);
95.1843 + locoff = CENOFF(cen, pos);
95.1844 +
95.1845 + cen.position(pos + CENHDR);
95.1846 + name = new byte[nlen];
95.1847 + cen.get(name);
95.1848 +
95.1849 + if (elen > 0) {
95.1850 + extra = new byte[elen];
95.1851 + cen.get(extra);
95.1852 + if (csize == ZIP64_MINVAL || size == ZIP64_MINVAL ||
95.1853 + locoff == ZIP64_MINVAL) {
95.1854 + int off = 0;
95.1855 + while (off + 4 < elen) {
95.1856 + // extra spec: HeaderID+DataSize+Data
95.1857 + int sz = SH(extra, off + 2);
95.1858 + if (SH(extra, off) == EXTID_ZIP64) {
95.1859 + off += 4;
95.1860 + if (size == ZIP64_MINVAL) {
95.1861 + // if invalid zip64 extra fields, just skip
95.1862 + if (sz < 8 || (off + 8) > elen)
95.1863 + break;
95.1864 + size = LL(extra, off);
95.1865 + sz -= 8;
95.1866 + off += 8;
95.1867 + }
95.1868 + if (csize == ZIP64_MINVAL) {
95.1869 + if (sz < 8 || (off + 8) > elen)
95.1870 + break;
95.1871 + csize = LL(extra, off);
95.1872 + sz -= 8;
95.1873 + off += 8;
95.1874 + }
95.1875 + if (locoff == ZIP64_MINVAL) {
95.1876 + if (sz < 8 || (off + 8) > elen)
95.1877 + break;
95.1878 + locoff = LL(extra, off);
95.1879 + sz -= 8;
95.1880 + off += 8;
95.1881 + }
95.1882 + break;
95.1883 + }
95.1884 + off += (sz + 4);
95.1885 + }
95.1886 + }
95.1887 + }
95.1888 + if (clen > 0) {
95.1889 + comment = new byte[clen];
95.1890 + cen.get(comment);
95.1891 + }
95.1892 + return this;
95.1893 + }
95.1894 +
95.1895 + int writeCEN(OutputStream os) throws IOException
95.1896 + {
95.1897 + int written = CENHDR;
95.1898 + int version0 = version();
95.1899 +
95.1900 + long csize0 = csize;
95.1901 + long size0 = size;
95.1902 + long locoff0 = locoff;
95.1903 + int e64len = 0;
95.1904 +
95.1905 + // confirm size/length
95.1906 + nlen = (name != null) ? name.length : 0;
95.1907 + elen = (extra != null) ? extra.length : 0;
95.1908 + clen = (comment != null) ? comment.length : 0;
95.1909 +
95.1910 + boolean hasZip64 = false;
95.1911 + if (csize >= ZIP64_MINVAL) {
95.1912 + csize0 = ZIP64_MINVAL;
95.1913 + e64len += 8; // csize(8)
95.1914 + hasZip64 = true;
95.1915 + }
95.1916 + if (size >= ZIP64_MINVAL) {
95.1917 + size0 = ZIP64_MINVAL; // size(8)
95.1918 + e64len += 8;
95.1919 + hasZip64 = true;
95.1920 + }
95.1921 + if (locoff >= ZIP64_MINVAL) {
95.1922 + locoff0 = ZIP64_MINVAL;
95.1923 + e64len += 8; // offset(8)
95.1924 + hasZip64 = true;
95.1925 + }
95.1926 + writeInt(os, CENSIG); // CEN header signature
95.1927 + if (hasZip64) {
95.1928 + writeShort(os, 45); // ver 4.5 for zip64
95.1929 + writeShort(os, 45);
95.1930 + } else {
95.1931 + writeShort(os, version0); // version made by
95.1932 + writeShort(os, version0); // version needed to extract
95.1933 + }
95.1934 + writeShort(os, flag); // general purpose bit flag
95.1935 + writeShort(os, method); // compression method
95.1936 + writeInt(os, mtime); // last modification time
95.1937 + writeInt(os, crc); // crc-32
95.1938 + writeInt(os, csize0); // compressed size
95.1939 + writeInt(os, size0); // uncompressed size
95.1940 + writeShort(os, name.length);
95.1941 +
95.1942 + if (hasZip64) {
95.1943 + // + headid(2) + datasize(2)
95.1944 + writeShort(os, e64len + 4 + elen);
95.1945 + } else {
95.1946 + writeShort(os, elen);
95.1947 + }
95.1948 + if (comment != null) {
95.1949 + writeShort(os, Math.min(clen, 0xffff));
95.1950 + } else {
95.1951 + writeShort(os, 0);
95.1952 + }
95.1953 + writeShort(os, 0); // starting disk number
95.1954 + writeShort(os, 0); // internal file attributes (unused)
95.1955 + writeInt(os, 0); // external file attributes (unused)
95.1956 + writeInt(os, locoff0); // relative offset of local header
95.1957 + writeBytes(os, name);
95.1958 + if (hasZip64) {
95.1959 + writeShort(os, EXTID_ZIP64);// Zip64 extra
95.1960 + writeShort(os, e64len);
95.1961 + if (size0 == ZIP64_MINVAL)
95.1962 + writeLong(os, size);
95.1963 + if (csize0 == ZIP64_MINVAL)
95.1964 + writeLong(os, csize);
95.1965 + if (locoff0 == ZIP64_MINVAL)
95.1966 + writeLong(os, locoff);
95.1967 + }
95.1968 + if (extra != null) {
95.1969 + writeBytes(os, extra);
95.1970 + }
95.1971 + if (comment != null) {
95.1972 + //TBD: 0, Math.min(commentBytes.length, 0xffff));
95.1973 + writeBytes(os, comment);
95.1974 + }
95.1975 + return CENHDR + nlen + elen + clen + (hasZip64?(e64len + 4):0);
95.1976 + }
95.1977 +
95.1978 + ///////////////////// LOC //////////////////////
95.1979 + static Entry readLOC(ZipFileSystem zf, long pos)
95.1980 + throws IOException
95.1981 + {
95.1982 + return readLOC(zf, pos, new byte[1024]);
95.1983 + }
95.1984 +
95.1985 + static Entry readLOC(ZipFileSystem zf, long pos, byte[] buf)
95.1986 + throws IOException
95.1987 + {
95.1988 + return new Entry().loc(zf, pos, buf);
95.1989 + }
95.1990 +
95.1991 + Entry loc(ZipFileSystem zf, long pos, byte[] buf)
95.1992 + throws IOException
95.1993 + {
95.1994 + assert (buf.length >= LOCHDR);
95.1995 + if (zf.readFullyAt(buf, 0, LOCHDR , pos) != LOCHDR) {
95.1996 + throw new ZipException("loc: reading failed");
95.1997 + }
95.1998 + if (LOCSIG(buf) != LOCSIG) {
95.1999 + throw new ZipException("loc: wrong sig ->"
95.2000 + + Long.toString(LOCSIG(buf), 16));
95.2001 + }
95.2002 + startPos = pos;
95.2003 + version = LOCVER(buf);
95.2004 + flag = LOCFLG(buf);
95.2005 + method = LOCHOW(buf);
95.2006 + mtime = LOCTIM(buf);
95.2007 + crc = LOCCRC(buf);
95.2008 + csize = LOCSIZ(buf);
95.2009 + size = LOCLEN(buf);
95.2010 + nlen = LOCNAM(buf);
95.2011 + elen = LOCEXT(buf);
95.2012 +
95.2013 + name = new byte[nlen];
95.2014 + if (zf.readFullyAt(name, 0, nlen, pos + LOCHDR) != nlen) {
95.2015 + throw new ZipException("loc: name reading failed");
95.2016 + }
95.2017 + if (elen > 0) {
95.2018 + extra = new byte[elen];
95.2019 + if (zf.readFullyAt(extra, 0, elen, pos + LOCHDR + nlen)
95.2020 + != elen) {
95.2021 + throw new ZipException("loc: ext reading failed");
95.2022 + }
95.2023 + }
95.2024 + pos += (LOCHDR + nlen + elen);
95.2025 + if ((flag & FLAG_DATADESCR) != 0) {
95.2026 + // Data Descriptor
95.2027 + Entry e = zf.getEntry0(name); // get the size/csize from cen
95.2028 + if (e == null)
95.2029 + throw new ZipException("loc: name not found in cen");
95.2030 + size = e.size;
95.2031 + csize = e.csize;
95.2032 + pos += (method == METHOD_STORED ? size : csize);
95.2033 + if (size >= ZIP64_MINVAL || csize >= ZIP64_MINVAL)
95.2034 + pos += 24;
95.2035 + else
95.2036 + pos += 16;
95.2037 + } else {
95.2038 + boolean hasZip64 = false;
95.2039 + if (extra != null &&
95.2040 + (size == ZIP64_MINVAL || csize == ZIP64_MINVAL)) {
95.2041 + // zip64 ext: must include both size and csize
95.2042 + int off = 0;
95.2043 + while (off + 20 < elen) { // HeaderID+DataSize+Data
95.2044 + int sz = SH(extra, off + 2);
95.2045 + if (SH(extra, off) == EXTID_ZIP64 && sz == 16) {
95.2046 + size = LL(extra, off + 4);
95.2047 + csize = LL(extra, off + 12);
95.2048 + hasZip64 = true;
95.2049 + break;
95.2050 + }
95.2051 + off += (sz + 4);
95.2052 + }
95.2053 + }
95.2054 + pos += (method == METHOD_STORED ? size : csize);
95.2055 + }
95.2056 + endPos = pos;
95.2057 + return this;
95.2058 + }
95.2059 +
95.2060 + int writeLOC(OutputStream os)
95.2061 + throws IOException
95.2062 + {
95.2063 + writeInt(os, LOCSIG); // LOC header signature
95.2064 +
95.2065 + int version = version();
95.2066 + if ((flag & FLAG_DATADESCR) != 0) {
95.2067 + writeShort(os, version()); // version needed to extract
95.2068 + writeShort(os, flag); // general purpose bit flag
95.2069 + writeShort(os, method); // compression method
95.2070 + writeInt(os, mtime); // last modification time
95.2071 +
95.2072 + // store size, uncompressed size, and crc-32 in data descriptor
95.2073 + // immediately following compressed entry data
95.2074 + writeInt(os, 0);
95.2075 + writeInt(os, 0);
95.2076 + writeInt(os, 0);
95.2077 + } else {
95.2078 + if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) {
95.2079 + hasZip64 = true;
95.2080 + writeShort(os, 45); // ver 4.5 for zip64
95.2081 + } else {
95.2082 + writeShort(os, version()); // version needed to extract
95.2083 + }
95.2084 + writeShort(os, flag); // general purpose bit flag
95.2085 + writeShort(os, method); // compression method
95.2086 + writeInt(os, mtime); // last modification time
95.2087 + writeInt(os, crc); // crc-32
95.2088 + if (hasZip64) {
95.2089 + writeInt(os, ZIP64_MINVAL);
95.2090 + writeInt(os, ZIP64_MINVAL);
95.2091 + //TBD: e.elen += 20; //headid(2) + size(2) + size(8) + csize(8)
95.2092 + } else {
95.2093 + writeInt(os, csize); // compressed size
95.2094 + writeInt(os, size); // uncompressed size
95.2095 + }
95.2096 + }
95.2097 + writeShort(os, name.length);
95.2098 + writeShort(os, elen + (hasZip64 ? 20 : 0));
95.2099 + writeBytes(os, name);
95.2100 + if (hasZip64) {
95.2101 + // TBD: should we update extra directory?
95.2102 + writeShort(os, EXTID_ZIP64);
95.2103 + writeShort(os, 16);
95.2104 + writeLong(os, size);
95.2105 + writeLong(os, csize);
95.2106 + }
95.2107 + if (extra != null) {
95.2108 + writeBytes(os, extra);
95.2109 + }
95.2110 + return LOCHDR + name.length + elen + (hasZip64 ? 20 : 0);
95.2111 + }
95.2112 +
95.2113 + // Data Descriptior
95.2114 + int writeEXT(OutputStream os)
95.2115 + throws IOException
95.2116 + {
95.2117 + writeInt(os, EXTSIG); // EXT header signature
95.2118 + writeInt(os, crc); // crc-32
95.2119 + if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) {
95.2120 + writeLong(os, csize);
95.2121 + writeLong(os, size);
95.2122 + return 24;
95.2123 + } else {
95.2124 + writeInt(os, csize); // compressed size
95.2125 + writeInt(os, size); // uncompressed size
95.2126 + return 16;
95.2127 + }
95.2128 + }
95.2129 +
95.2130 + // read NTFS, UNIX and ZIP64 data from cen.extra
95.2131 + void readExtra() {
95.2132 + if (extra == null)
95.2133 + return;
95.2134 + int elen = extra.length;
95.2135 + int off = 0;
95.2136 + while (off + 4 < elen) {
95.2137 + // extra spec: HeaderID+DataSize+Data
95.2138 + int sz = SH(extra, off + 2);
95.2139 + int tag = SH(extra, off);
95.2140 + off += 4;
95.2141 + int pos = off;
95.2142 + if (pos + sz > elen) // invalid data
95.2143 + break;
95.2144 + switch (tag) {
95.2145 + case EXTID_ZIP64 :
95.2146 + if (size == ZIP64_MINVAL) {
95.2147 + if (pos + 8 > elen) // invalid zip64 extra
95.2148 + break; // fields, just skip
95.2149 + size = LL(extra, pos);
95.2150 + pos += 8;
95.2151 + }
95.2152 + if (csize == ZIP64_MINVAL) {
95.2153 + if (pos + 8 > elen)
95.2154 + break;
95.2155 + csize = LL(extra, pos);
95.2156 + pos += 8;
95.2157 + }
95.2158 + if (locoff == ZIP64_MINVAL) {
95.2159 + if (pos + 8 > elen)
95.2160 + break;
95.2161 + locoff = LL(extra, pos);
95.2162 + pos += 8;
95.2163 + }
95.2164 + break;
95.2165 + case EXTID_NTFS:
95.2166 + pos += 4; // reserved 4 bytes
95.2167 + if (SH(extra, pos) != 0x0001)
95.2168 + break;
95.2169 + if (SH(extra, pos + 2) != 24)
95.2170 + break;
95.2171 + mtime = LL(extra, pos + 4);
95.2172 + atime = LL(extra, pos + 12);
95.2173 + ctime = LL(extra, pos + 20);
95.2174 + break;
95.2175 + case EXTID_UNIX:
95.2176 + atime = LG(extra, pos);
95.2177 + mtime = LG(extra, pos + 4);
95.2178 + break;
95.2179 + default: // unknow
95.2180 + }
95.2181 + off += sz;
95.2182 + }
95.2183 + }
95.2184 + }
95.2185 +
95.2186 + private static class ExChannelCloser {
95.2187 + Path path;
95.2188 + SeekableByteChannel ch;
95.2189 + Set<InputStream> streams;
95.2190 + ExChannelCloser(Path path,
95.2191 + SeekableByteChannel ch,
95.2192 + Set<InputStream> streams)
95.2193 + {
95.2194 + this.path = path;
95.2195 + this.ch = ch;
95.2196 + this.streams = streams;
95.2197 + }
95.2198 + }
95.2199 +
95.2200 + // ZIP directory has two issues:
95.2201 + // (1) ZIP spec does not require the ZIP file to include
95.2202 + // directory entry
95.2203 + // (2) all entries are not stored/organized in a "tree"
95.2204 + // structure.
95.2205 + // A possible solution is to build the node tree ourself as
95.2206 + // implemented below.
95.2207 + private HashMap<EntryName, IndexNode> dirs;
95.2208 + private IndexNode root;
95.2209 + private IndexNode addToDir(EntryName child) {
95.2210 + IndexNode cinode = dirs.get(child);
95.2211 + if (cinode != null)
95.2212 + return cinode;
95.2213 +
95.2214 + byte[] cname = child.name;
95.2215 + byte[] pname = getParent(cname);
95.2216 + IndexNode pinode;
95.2217 +
95.2218 + if (pname != null)
95.2219 + pinode = addToDir(new EntryName(pname));
95.2220 + else
95.2221 + pinode = root;
95.2222 + cinode = inodes.get(child);
95.2223 + if (cname[cname.length -1] != '/') { // not a dir
95.2224 + cinode.sibling = pinode.child;
95.2225 + pinode.child = cinode;
95.2226 + return null;
95.2227 + }
95.2228 + cinode = dirs.get(child);
95.2229 + if (cinode == null) // pseudo directry entry
95.2230 + cinode = new IndexNode(cname, -1);
95.2231 + cinode.sibling = pinode.child;
95.2232 + pinode.child = cinode;
95.2233 +
95.2234 + dirs.put(child, cinode);
95.2235 + return cinode;
95.2236 + }
95.2237 +
95.2238 + private HashMap<EntryName, IndexNode> getDirs()
95.2239 + throws IOException
95.2240 + {
95.2241 + if (hasUpdate)
95.2242 + sync();
95.2243 + if (dirs != null)
95.2244 + return dirs;
95.2245 + dirs = new HashMap<EntryName, IndexNode>();
95.2246 + byte[] empty = new byte[0];
95.2247 + root = new IndexNode(empty, -1);
95.2248 + dirs.put(new EntryName(empty), root);
95.2249 +
95.2250 + EntryName[] names = inodes.keySet().toArray(new EntryName[0]);
95.2251 + int i = names.length;
95.2252 + while (--i >= 0) {
95.2253 + addToDir(names[i]);
95.2254 + }
95.2255 + // for (int i EntryName en : inodes.keySet()) {
95.2256 + // addToDir(en);
95.2257 + // }
95.2258 + return dirs;
95.2259 + }
95.2260 +}
96.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
96.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystemProvider.java Mon Oct 18 11:25:28 2010 -0400
96.3 @@ -0,0 +1,152 @@
96.4 +/*
96.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
96.6 + *
96.7 + * Redistribution and use in source and binary forms, with or without
96.8 + * modification, are permitted provided that the following conditions
96.9 + * are met:
96.10 + *
96.11 + * - Redistributions of source code must retain the above copyright
96.12 + * notice, this list of conditions and the following disclaimer.
96.13 + *
96.14 + * - Redistributions in binary form must reproduce the above copyright
96.15 + * notice, this list of conditions and the following disclaimer in the
96.16 + * documentation and/or other materials provided with the distribution.
96.17 + *
96.18 + * - Neither the name of Oracle nor the names of its
96.19 + * contributors may be used to endorse or promote products derived
96.20 + * from this software without specific prior written permission.
96.21 + *
96.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
96.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
96.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
96.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
96.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
96.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
96.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
96.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
96.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
96.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96.33 + */
96.34 +
96.35 +package com.sun.nio.zipfs;
96.36 +
96.37 +import java.io.IOException;
96.38 +import java.nio.channels.FileChannel;
96.39 +import java.nio.file.FileRef;
96.40 +import java.nio.file.FileSystem;
96.41 +import java.nio.file.FileSystemNotFoundException;
96.42 +import java.nio.file.FileSystemAlreadyExistsException;
96.43 +import java.nio.file.OpenOption;
96.44 +import java.nio.file.Path;
96.45 +import java.nio.file.Paths;
96.46 +import java.nio.file.ProviderMismatchException;
96.47 +import java.nio.file.attribute.FileAttribute;
96.48 +import java.nio.file.spi.FileSystemProvider;
96.49 +import java.net.URI;
96.50 +import java.net.URISyntaxException;
96.51 +import java.util.HashMap;
96.52 +import java.util.Map;
96.53 +import java.util.Set;
96.54 +
96.55 +/*
96.56 + *
96.57 + * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
96.58 + */
96.59 +
96.60 +public class ZipFileSystemProvider extends FileSystemProvider {
96.61 + private final Map<Path, ZipFileSystem> filesystems = new HashMap<>();
96.62 +
96.63 + public ZipFileSystemProvider() {}
96.64 +
96.65 + @Override
96.66 + public String getScheme() {
96.67 + return "zip";
96.68 + }
96.69 +
96.70 + protected Path uriToPath(URI uri) {
96.71 + String scheme = uri.getScheme();
96.72 + if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) {
96.73 + throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'");
96.74 + }
96.75 + try {
96.76 + return Paths.get(new URI("file", uri.getHost(), uri.getPath(), null))
96.77 + .toAbsolutePath();
96.78 + } catch (URISyntaxException e) {
96.79 + throw new AssertionError(e); //never thrown
96.80 + }
96.81 + }
96.82 +
96.83 + @Override
96.84 + public FileSystem newFileSystem(URI uri, Map<String, ?> env)
96.85 + throws IOException
96.86 + {
96.87 + return newFileSystem(uriToPath(uri), env);
96.88 + }
96.89 +
96.90 + @Override
96.91 + public FileSystem newFileSystem(FileRef file, Map<String, ?> env)
96.92 + throws IOException
96.93 + {
96.94 + if (!(file instanceof Path))
96.95 + throw new UnsupportedOperationException();
96.96 + Path path = (Path)file;
96.97 + if (!path.toUri().getScheme().equalsIgnoreCase("file")) {
96.98 + throw new UnsupportedOperationException();
96.99 + }
96.100 + return newFileSystem(path, env);
96.101 + }
96.102 +
96.103 + private FileSystem newFileSystem(Path path, Map<String, ?> env)
96.104 + throws IOException
96.105 + {
96.106 + synchronized(filesystems) {
96.107 + if (filesystems.containsKey(path))
96.108 + throw new FileSystemAlreadyExistsException();
96.109 + ZipFileSystem zipfs = new ZipFileSystem(this, path, env);
96.110 + filesystems.put(path, zipfs);
96.111 + return zipfs;
96.112 + }
96.113 + }
96.114 +
96.115 + @Override
96.116 + public Path getPath(URI uri) {
96.117 + FileSystem fs = getFileSystem(uri);
96.118 + String fragment = uri.getFragment();
96.119 + if (fragment == null) {
96.120 + throw new IllegalArgumentException("URI: "
96.121 + + uri
96.122 + + " does not contain path fragment ex. zip:///c:/foo.zip#/BAR");
96.123 + }
96.124 + return fs.getPath(fragment);
96.125 + }
96.126 +
96.127 + @Override
96.128 + public FileChannel newFileChannel(Path path,
96.129 + Set<? extends OpenOption> options,
96.130 + FileAttribute<?>... attrs)
96.131 + throws IOException
96.132 + {
96.133 + if (path == null)
96.134 + throw new NullPointerException("path is null");
96.135 + if (path instanceof ZipPath)
96.136 + return ((ZipPath)path).newFileChannel(options, attrs);
96.137 + throw new ProviderMismatchException();
96.138 + }
96.139 +
96.140 + @Override
96.141 + public FileSystem getFileSystem(URI uri) {
96.142 + synchronized (filesystems) {
96.143 + ZipFileSystem zipfs = filesystems.get(uriToPath(uri));
96.144 + if (zipfs == null)
96.145 + throw new FileSystemNotFoundException();
96.146 + return zipfs;
96.147 + }
96.148 + }
96.149 +
96.150 + void removeFileSystem(Path zfpath) {
96.151 + synchronized (filesystems) {
96.152 + filesystems.remove(zfpath);
96.153 + }
96.154 + }
96.155 +}
97.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
97.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipInfo.java Mon Oct 18 11:25:28 2010 -0400
97.3 @@ -0,0 +1,132 @@
97.4 +/*
97.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
97.6 + *
97.7 + * Redistribution and use in source and binary forms, with or without
97.8 + * modification, are permitted provided that the following conditions
97.9 + * are met:
97.10 + *
97.11 + * - Redistributions of source code must retain the above copyright
97.12 + * notice, this list of conditions and the following disclaimer.
97.13 + *
97.14 + * - Redistributions in binary form must reproduce the above copyright
97.15 + * notice, this list of conditions and the following disclaimer in the
97.16 + * documentation and/or other materials provided with the distribution.
97.17 + *
97.18 + * - Neither the name of Oracle nor the names of its
97.19 + * contributors may be used to endorse or promote products derived
97.20 + * from this software without specific prior written permission.
97.21 + *
97.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
97.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
97.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
97.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
97.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
97.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
97.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
97.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
97.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
97.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97.33 + */
97.34 +
97.35 +package com.sun.nio.zipfs;
97.36 +
97.37 +import java.io.PrintStream;
97.38 +import java.nio.file.Paths;
97.39 +import java.util.Collections;
97.40 +import java.util.Iterator;
97.41 +import java.util.Map;
97.42 +import com.sun.nio.zipfs.ZipFileSystem.Entry;
97.43 +import static com.sun.nio.zipfs.ZipConstants.*;
97.44 +import static com.sun.nio.zipfs.ZipUtils.*;
97.45 +
97.46 +/**
97.47 + * Print the loc and cen tables of the ZIP file
97.48 + *
97.49 + * @author Xueming Shen
97.50 + */
97.51 +
97.52 +public class ZipInfo {
97.53 +
97.54 + public static void main(String[] args) throws Throwable {
97.55 + if (args.length < 2) {
97.56 + print("Usage: java ZipInfo [cen|loc] zfname");
97.57 + } else {
97.58 + Map<String, ?> env = Collections.emptyMap();
97.59 + ZipFileSystem zfs = (ZipFileSystem)(new ZipFileSystemProvider()
97.60 + .newFileSystem(Paths.get(args[1]), env));
97.61 +
97.62 + long pos = 0;
97.63 +
97.64 + if ("loc".equals(args[0])) {
97.65 + print("[Local File Header]%n");
97.66 + byte[] buf = new byte[1024];
97.67 + for (int i = 0; i < zfs.getEntryNames().length; i++) {
97.68 + Entry loc = Entry.readLOC(zfs, pos, buf);
97.69 + print("--------loc[%x]--------%n", pos);
97.70 + printLOC(loc);
97.71 + pos = loc.endPos;
97.72 + }
97.73 + } if ("cen".equals(args[0])) {
97.74 + int i = 0;
97.75 + Iterator<ZipFileSystem.IndexNode> itr = zfs.inodes.values().iterator();
97.76 + print("[Central Directory Header]%n");
97.77 + while (itr.hasNext()) {
97.78 + Entry cen = Entry.readCEN(zfs.cen, itr.next().pos);
97.79 + print("--------cen[%d]--------%n", i);
97.80 + printCEN(cen);
97.81 + i++;
97.82 + }
97.83 + }
97.84 + zfs.close();
97.85 + }
97.86 + }
97.87 +
97.88 + static void print(String fmt, Object... objs) {
97.89 + System.out.printf(fmt, objs);
97.90 + }
97.91 +
97.92 + static void printLOC(Entry loc) {
97.93 + print(" [%x, %x]%n", loc.startPos, loc.endPos);
97.94 + print(" Signature : %8x%n", LOCSIG);
97.95 + print(" Version : %4x [%d.%d]%n",
97.96 + loc.version, loc. version/10, loc. version%10);
97.97 + print(" Flag : %4x%n", loc.flag);
97.98 + print(" Method : %4x%n", loc. method);
97.99 + print(" LastMTime : %8x [%tc]%n",
97.100 + loc.mtime, dosToJavaTime(loc.mtime));
97.101 + print(" CRC : %8x%n", loc.crc);
97.102 + print(" CSize : %8x%n", loc.csize);
97.103 + print(" Size : %8x%n", loc.size);
97.104 + print(" NameLength : %4x [%s]%n",
97.105 + loc.nlen, new String(loc.name));
97.106 + print(" ExtraLength : %4x%n", loc.elen);
97.107 + if (loc.hasZip64)
97.108 + print(" *ZIP64*%n");
97.109 + }
97.110 +
97.111 + static void printCEN(Entry cen) {
97.112 + print(" Signature : %08x%n", CENSIG);
97.113 + print(" VerMadeby : %4x [%d.%d]%n",
97.114 + cen.versionMade, cen.versionMade/10, cen.versionMade%10);
97.115 + print(" VerExtract : %4x [%d.%d]%n",
97.116 + cen.version, cen.version/10, cen.version%10);
97.117 + print(" Flag : %4x%n", cen.flag);
97.118 + print(" Method : %4x%n", cen.method);
97.119 + print(" LastMTime : %8x [%tc]%n",
97.120 + cen.mtime, dosToJavaTime(cen.mtime));
97.121 + print(" CRC : %8x%n", cen.crc);
97.122 + print(" CSize : %8x%n", cen.csize);
97.123 + print(" Size : %8x%n", cen.size);
97.124 + print(" NameLen : %4x [%s]%n",
97.125 + cen.nlen, new String(cen.name));
97.126 + print(" ExtraLen : %4x%n", cen.elen);
97.127 + print(" CommentLen : %4x%n", cen.clen);
97.128 + print(" DiskStart : %4x%n", cen.disk);
97.129 + print(" Attrs : %4x%n", cen.attrs);
97.130 + print(" AttrsEx : %8x%n", cen.attrsEx);
97.131 + print(" LocOff : %8x%n", cen.locoff);
97.132 + if (cen.hasZip64)
97.133 + print(" *ZIP64*%n");
97.134 + }
97.135 +}
98.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
98.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipPath.java Mon Oct 18 11:25:28 2010 -0400
98.3 @@ -0,0 +1,964 @@
98.4 +/*
98.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
98.6 + *
98.7 + * Redistribution and use in source and binary forms, with or without
98.8 + * modification, are permitted provided that the following conditions
98.9 + * are met:
98.10 + *
98.11 + * - Redistributions of source code must retain the above copyright
98.12 + * notice, this list of conditions and the following disclaimer.
98.13 + *
98.14 + * - Redistributions in binary form must reproduce the above copyright
98.15 + * notice, this list of conditions and the following disclaimer in the
98.16 + * documentation and/or other materials provided with the distribution.
98.17 + *
98.18 + * - Neither the name of Oracle nor the names of its
98.19 + * contributors may be used to endorse or promote products derived
98.20 + * from this software without specific prior written permission.
98.21 + *
98.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
98.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
98.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
98.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
98.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
98.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
98.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
98.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
98.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
98.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98.33 + */
98.34 +
98.35 +package com.sun.nio.zipfs;
98.36 +
98.37 +import java.io.File;
98.38 +import java.io.FilterInputStream;
98.39 +import java.io.IOException;
98.40 +import java.io.InputStream;
98.41 +import java.io.OutputStream;
98.42 +import java.net.URI;
98.43 +import java.nio.ByteBuffer;
98.44 +import java.nio.channels.FileChannel;
98.45 +import java.nio.channels.SeekableByteChannel;
98.46 +import java.nio.file.*;
98.47 +import java.nio.file.DirectoryStream.Filter;
98.48 +import java.nio.file.spi.FileSystemProvider;
98.49 +import java.nio.file.attribute.BasicFileAttributeView;
98.50 +import java.nio.file.attribute.FileAttribute;
98.51 +import java.nio.file.attribute.FileAttributeView;
98.52 +import java.nio.file.attribute.FileTime;
98.53 +import java.util.*;
98.54 +import java.util.regex.Matcher;
98.55 +import java.util.regex.Pattern;
98.56 +import static java.nio.file.StandardOpenOption.*;
98.57 +import static java.nio.file.StandardCopyOption.*;
98.58 +
98.59 +/**
98.60 + *
98.61 + * @author Xueming Shen, Rajendra Gutupalli,Jaya Hangal
98.62 + */
98.63 +
98.64 +public class ZipPath extends Path {
98.65 +
98.66 + private final ZipFileSystem zfs;
98.67 + private final byte[] path;
98.68 + private volatile int[] offsets;
98.69 + private int hashcode = 0; // cached hashcode (created lazily)
98.70 +
98.71 + ZipPath(ZipFileSystem zfs, byte[] path) {
98.72 + this(zfs, path, false);
98.73 + }
98.74 +
98.75 + ZipPath(ZipFileSystem zfs, byte[] path, boolean normalized)
98.76 + {
98.77 + this.zfs = zfs;
98.78 + if (normalized)
98.79 + this.path = path;
98.80 + else
98.81 + this.path = normalize(path);
98.82 + }
98.83 +
98.84 + @Override
98.85 + public ZipPath getRoot() {
98.86 + if (this.isAbsolute())
98.87 + return new ZipPath(zfs, new byte[]{path[0]});
98.88 + else
98.89 + return null;
98.90 + }
98.91 +
98.92 + @Override
98.93 + public Path getName() {
98.94 + initOffsets();
98.95 + int count = offsets.length;
98.96 + if (count == 0)
98.97 + return null; // no elements so no name
98.98 + if (count == 1 && path[0] != '/')
98.99 + return this;
98.100 + int lastOffset = offsets[count-1];
98.101 + int len = path.length - lastOffset;
98.102 + byte[] result = new byte[len];
98.103 + System.arraycopy(path, lastOffset, result, 0, len);
98.104 + return new ZipPath(zfs, result);
98.105 + }
98.106 +
98.107 + @Override
98.108 + public ZipPath getParent() {
98.109 + initOffsets();
98.110 + int count = offsets.length;
98.111 + if (count == 0) // no elements so no parent
98.112 + return null;
98.113 + int len = offsets[count-1] - 1;
98.114 + if (len <= 0) // parent is root only (may be null)
98.115 + return getRoot();
98.116 + byte[] result = new byte[len];
98.117 + System.arraycopy(path, 0, result, 0, len);
98.118 + return new ZipPath(zfs, result);
98.119 + }
98.120 +
98.121 + @Override
98.122 + public int getNameCount() {
98.123 + initOffsets();
98.124 + return offsets.length;
98.125 + }
98.126 +
98.127 + @Override
98.128 + public ZipPath getName(int index) {
98.129 + initOffsets();
98.130 + if (index < 0 || index >= offsets.length)
98.131 + throw new IllegalArgumentException();
98.132 + int begin = offsets[index];
98.133 + int len;
98.134 + if (index == (offsets.length-1))
98.135 + len = path.length - begin;
98.136 + else
98.137 + len = offsets[index+1] - begin - 1;
98.138 + // construct result
98.139 + byte[] result = new byte[len];
98.140 + System.arraycopy(path, begin, result, 0, len);
98.141 + return new ZipPath(zfs, result);
98.142 + }
98.143 +
98.144 + @Override
98.145 + public ZipPath subpath(int beginIndex, int endIndex) {
98.146 + initOffsets();
98.147 + if (beginIndex < 0 ||
98.148 + beginIndex >= offsets.length ||
98.149 + endIndex > offsets.length ||
98.150 + beginIndex >= endIndex)
98.151 + throw new IllegalArgumentException();
98.152 +
98.153 + // starting offset and length
98.154 + int begin = offsets[beginIndex];
98.155 + int len;
98.156 + if (endIndex == offsets.length)
98.157 + len = path.length - begin;
98.158 + else
98.159 + len = offsets[endIndex] - begin - 1;
98.160 + // construct result
98.161 + byte[] result = new byte[len];
98.162 + System.arraycopy(path, begin, result, 0, len);
98.163 + return new ZipPath(zfs, result);
98.164 + }
98.165 +
98.166 + @Override
98.167 + public ZipPath toRealPath(boolean resolveLinks) throws IOException {
98.168 + ZipPath realPath = new ZipPath(zfs, getResolvedPath());
98.169 + realPath.checkAccess();
98.170 + return realPath;
98.171 + }
98.172 +
98.173 + @Override
98.174 + public boolean isHidden() {
98.175 + return false;
98.176 + }
98.177 +
98.178 + @Override
98.179 + public ZipPath toAbsolutePath() {
98.180 + if (isAbsolute()) {
98.181 + return this;
98.182 + } else {
98.183 + //add / bofore the existing path
98.184 + byte[] defaultdir = zfs.getDefaultDir().path;
98.185 + int defaultlen = defaultdir.length;
98.186 + boolean endsWith = (defaultdir[defaultlen - 1] == '/');
98.187 + byte[] t = null;
98.188 + if (endsWith)
98.189 + t = new byte[defaultlen + path.length];
98.190 + else
98.191 + t = new byte[defaultlen + 1 + path.length];
98.192 + System.arraycopy(defaultdir, 0, t, 0, defaultlen);
98.193 + if (!endsWith)
98.194 + t[defaultlen++] = '/';
98.195 + System.arraycopy(path, 0, t, defaultlen, path.length);
98.196 + return new ZipPath(zfs, t, true); // normalized
98.197 + }
98.198 + }
98.199 +
98.200 + @Override
98.201 + public URI toUri() {
98.202 + String zfPath = zfs.toString();
98.203 + if (File.separatorChar == '\\') // replace all separators by '/'
98.204 + zfPath = "/" + zfPath.replace("\\", "/");
98.205 + try {
98.206 + return new URI("zip", "",
98.207 + zfPath,
98.208 + zfs.getString(toAbsolutePath().path));
98.209 + } catch (Exception ex) {
98.210 + throw new AssertionError(ex);
98.211 + }
98.212 + }
98.213 +
98.214 + private boolean equalsNameAt(ZipPath other, int index) {
98.215 + int mbegin = offsets[index];
98.216 + int mlen = 0;
98.217 + if (index == (offsets.length-1))
98.218 + mlen = path.length - mbegin;
98.219 + else
98.220 + mlen = offsets[index + 1] - mbegin - 1;
98.221 + int obegin = other.offsets[index];
98.222 + int olen = 0;
98.223 + if (index == (other.offsets.length - 1))
98.224 + olen = other.path.length - obegin;
98.225 + else
98.226 + olen = other.offsets[index + 1] - obegin - 1;
98.227 + if (mlen != olen)
98.228 + return false;
98.229 + int n = 0;
98.230 + while(n < mlen) {
98.231 + if (path[mbegin + n] != other.path[obegin + n])
98.232 + return false;
98.233 + n++;
98.234 + }
98.235 + return true;
98.236 + }
98.237 +
98.238 + @Override
98.239 + public Path relativize(Path other) {
98.240 + final ZipPath o = checkPath(other);
98.241 + if (o.equals(this))
98.242 + return null;
98.243 + if (/* this.getFileSystem() != o.getFileSystem() || */
98.244 + this.isAbsolute() != o.isAbsolute()) {
98.245 + throw new IllegalArgumentException();
98.246 + }
98.247 + int mc = this.getNameCount();
98.248 + int oc = o.getNameCount();
98.249 + int n = Math.min(mc, oc);
98.250 + int i = 0;
98.251 + while (i < n) {
98.252 + if (!equalsNameAt(o, i))
98.253 + break;
98.254 + i++;
98.255 + }
98.256 + int dotdots = mc - i;
98.257 + int len = dotdots * 3 - 1;
98.258 + if (i < oc)
98.259 + len += (o.path.length - o.offsets[i] + 1);
98.260 + byte[] result = new byte[len];
98.261 +
98.262 + int pos = 0;
98.263 + while (dotdots > 0) {
98.264 + result[pos++] = (byte)'.';
98.265 + result[pos++] = (byte)'.';
98.266 + if (pos < len) // no tailing slash at the end
98.267 + result[pos++] = (byte)'/';
98.268 + dotdots--;
98.269 + }
98.270 + if (i < oc)
98.271 + System.arraycopy(o.path, o.offsets[i],
98.272 + result, pos,
98.273 + o.path.length - o.offsets[i]);
98.274 + return new ZipPath(getFileSystem(), result);
98.275 + }
98.276 +
98.277 + @Override
98.278 + public ZipFileSystem getFileSystem() {
98.279 + return zfs;
98.280 + }
98.281 +
98.282 + @Override
98.283 + public boolean isAbsolute() {
98.284 + return (this.path[0] == '/');
98.285 + }
98.286 +
98.287 + @Override
98.288 + public ZipPath resolve(Path other) {
98.289 + if (other == null)
98.290 + return this;
98.291 + final ZipPath o = checkPath(other);
98.292 + if (o.isAbsolute())
98.293 + return o;
98.294 + byte[] resolved = null;
98.295 + if (this.path[path.length - 1] == '/') {
98.296 + resolved = new byte[path.length + o.path.length];
98.297 + System.arraycopy(path, 0, resolved, 0, path.length);
98.298 + System.arraycopy(o.path, 0, resolved, path.length, o.path.length);
98.299 + } else {
98.300 + resolved = new byte[path.length + 1 + o.path.length];
98.301 + System.arraycopy(path, 0, resolved, 0, path.length);
98.302 + resolved[path.length] = '/';
98.303 + System.arraycopy(o.path, 0, resolved, path.length + 1, o.path.length);
98.304 + }
98.305 + return new ZipPath(zfs, resolved);
98.306 + }
98.307 +
98.308 + @Override
98.309 + public ZipPath resolve(String other) {
98.310 + return resolve(getFileSystem().getPath(other));
98.311 + }
98.312 +
98.313 + @Override
98.314 + public boolean startsWith(Path other) {
98.315 + final ZipPath o = checkPath(other);
98.316 + if (o.isAbsolute() != this.isAbsolute())
98.317 + return false;
98.318 + final int oCount = o.getNameCount();
98.319 + if (getNameCount() < oCount)
98.320 + return false;
98.321 + for (int i = 0; i < oCount; i++) {
98.322 + if (!o.getName(i).equals(getName(i)))
98.323 + return false;
98.324 + }
98.325 + return true;
98.326 + }
98.327 +
98.328 + @Override
98.329 + public boolean endsWith(Path other) {
98.330 + final ZipPath o = checkPath(other);
98.331 + if (o.isAbsolute())
98.332 + return this.isAbsolute() ? this.equals(o) : false;
98.333 + int i = o.getNameCount();
98.334 + int j = this.getNameCount();
98.335 + if (j < i)
98.336 + return false;
98.337 + for (--i, --j; i >= 0; i--, j--) {
98.338 + if (!o.getName(i).equals(this.getName(j)))
98.339 + return false;
98.340 + }
98.341 + return true;
98.342 + }
98.343 +
98.344 + @Override
98.345 + public Path normalize() {
98.346 + byte[] resolved = getResolved();
98.347 + if (resolved == path) // no change
98.348 + return this;
98.349 + if (resolved.length == 0)
98.350 + return null;
98.351 + return new ZipPath(zfs, resolved, true);
98.352 + }
98.353 +
98.354 + private ZipPath checkPath(Path path) {
98.355 + if (path == null)
98.356 + throw new NullPointerException();
98.357 + if (!(path instanceof ZipPath))
98.358 + throw new ProviderMismatchException();
98.359 + return (ZipPath) path;
98.360 + }
98.361 +
98.362 + // create offset list if not already created
98.363 + private void initOffsets() {
98.364 + if (offsets == null) {
98.365 + int count, index;
98.366 + // count names
98.367 + count = 0;
98.368 + index = 0;
98.369 + while (index < path.length) {
98.370 + byte c = path[index++];
98.371 + if (c != '/') {
98.372 + count++;
98.373 + while (index < path.length && path[index] != '/')
98.374 + index++;
98.375 + }
98.376 + }
98.377 + // populate offsets
98.378 + int[] result = new int[count];
98.379 + count = 0;
98.380 + index = 0;
98.381 + while (index < path.length) {
98.382 + byte c = path[index];
98.383 + if (c == '/') {
98.384 + index++;
98.385 + } else {
98.386 + result[count++] = index++;
98.387 + while (index < path.length && path[index] != '/')
98.388 + index++;
98.389 + }
98.390 + }
98.391 + synchronized (this) {
98.392 + if (offsets == null)
98.393 + offsets = result;
98.394 + }
98.395 + }
98.396 + }
98.397 +
98.398 + // resolved path for locating zip entry inside the zip file,
98.399 + // the result path does not contain ./ and .. components
98.400 + private volatile byte[] resolved = null;
98.401 + byte[] getResolvedPath() {
98.402 + byte[] r = resolved;
98.403 + if (r == null) {
98.404 + if (isAbsolute())
98.405 + r = getResolved();
98.406 + else
98.407 + r = toAbsolutePath().getResolvedPath();
98.408 + if (r[0] == '/')
98.409 + r = Arrays.copyOfRange(r, 1, r.length);
98.410 + resolved = r;
98.411 + }
98.412 + return resolved;
98.413 + }
98.414 +
98.415 + // removes redundant slashs, replace "\" to zip separator "/"
98.416 + // and check for invalid characters
98.417 + private byte[] normalize(byte[] path) {
98.418 + if (path.length == 0)
98.419 + return path;
98.420 + byte prevC = 0;
98.421 + for (int i = 0; i < path.length; i++) {
98.422 + byte c = path[i];
98.423 + if (c == '\\')
98.424 + return normalize(path, i);
98.425 + if (c == (byte)'/' && prevC == '/')
98.426 + return normalize(path, i - 1);
98.427 + if (c == '\u0000')
98.428 + throw new InvalidPathException(zfs.getString(path),
98.429 + "Path: nul character not allowed");
98.430 + prevC = c;
98.431 + }
98.432 + return path;
98.433 + }
98.434 +
98.435 + private byte[] normalize(byte[] path, int off) {
98.436 + byte[] to = new byte[path.length];
98.437 + int n = 0;
98.438 + while (n < off) {
98.439 + to[n] = path[n];
98.440 + n++;
98.441 + }
98.442 + int m = n;
98.443 + byte prevC = 0;
98.444 + while (n < path.length) {
98.445 + byte c = path[n++];
98.446 + if (c == (byte)'\\')
98.447 + c = (byte)'/';
98.448 + if (c == (byte)'/' && prevC == (byte)'/')
98.449 + continue;
98.450 + if (c == '\u0000')
98.451 + throw new InvalidPathException(zfs.getString(path),
98.452 + "Path: nul character not allowed");
98.453 + to[m++] = c;
98.454 + prevC = c;
98.455 + }
98.456 + if (m > 1 && to[m - 1] == '/')
98.457 + m--;
98.458 + return (m == to.length)? to : Arrays.copyOf(to, m);
98.459 + }
98.460 +
98.461 + // Remove DotSlash(./) and resolve DotDot (..) components
98.462 + private byte[] getResolved() {
98.463 + if (path.length == 0)
98.464 + return path;
98.465 + for (int i = 0; i < path.length; i++) {
98.466 + byte c = path[i];
98.467 + if (c == (byte)'.')
98.468 + return resolve0();
98.469 + }
98.470 + return path;
98.471 + }
98.472 +
98.473 + // TBD: performance, avoid initOffsets
98.474 + private byte[] resolve0() {
98.475 + byte[] to = new byte[path.length];
98.476 + int nc = getNameCount();
98.477 + int[] lastM = new int[nc];
98.478 + int lastMOff = -1;
98.479 + int m = 0;
98.480 + for (int i = 0; i < nc; i++) {
98.481 + int n = offsets[i];
98.482 + int len = (i == offsets.length - 1)?
98.483 + (path.length - n):(offsets[i + 1] - n - 1);
98.484 + if (len == 1 && path[n] == (byte)'.')
98.485 + continue;
98.486 + if (len == 2 && path[n] == '.' && path[n + 1] == '.') {
98.487 + if (lastMOff >= 0) {
98.488 + m = lastM[lastMOff--]; // retreat
98.489 + continue;
98.490 + }
98.491 + if (path[0] == '/') { // "/../xyz" skip
98.492 + if (m == 0)
98.493 + to[m++] = '/';
98.494 + } else { // "../xyz" -> "../xyz"
98.495 + if (m != 0 && to[m-1] != '/')
98.496 + to[m++] = '/';
98.497 + while (len-- > 0)
98.498 + to[m++] = path[n++];
98.499 + }
98.500 + continue;
98.501 + }
98.502 + if (m == 0 && path[0] == '/' || // absolute path
98.503 + m != 0 && to[m-1] != '/') { // not the first name
98.504 + to[m++] = '/';
98.505 + }
98.506 + lastM[++lastMOff] = m;
98.507 + while (len-- > 0)
98.508 + to[m++] = path[n++];
98.509 + }
98.510 + if (m > 1 && to[m - 1] == '/')
98.511 + m--;
98.512 + return (m == to.length)? to : Arrays.copyOf(to, m);
98.513 + }
98.514 +
98.515 + @Override
98.516 + public String toString() {
98.517 + return zfs.getString(path);
98.518 + }
98.519 +
98.520 + @Override
98.521 + public int hashCode() {
98.522 + int h = hashcode;
98.523 + if (h == 0)
98.524 + hashcode = h = Arrays.hashCode(path);
98.525 + return h;
98.526 + }
98.527 +
98.528 + @Override
98.529 + public boolean equals(Object obj) {
98.530 + return obj != null &&
98.531 + obj instanceof ZipPath &&
98.532 + this.zfs == ((ZipPath)obj).zfs &&
98.533 + compareTo((Path) obj) == 0;
98.534 + }
98.535 +
98.536 + @Override
98.537 + public int compareTo(Path other) {
98.538 + final ZipPath o = checkPath(other);
98.539 + int len1 = this.path.length;
98.540 + int len2 = o.path.length;
98.541 +
98.542 + int n = Math.min(len1, len2);
98.543 + byte v1[] = this.path;
98.544 + byte v2[] = o.path;
98.545 +
98.546 + int k = 0;
98.547 + while (k < n) {
98.548 + int c1 = v1[k] & 0xff;
98.549 + int c2 = v2[k] & 0xff;
98.550 + if (c1 != c2)
98.551 + return c1 - c2;
98.552 + k++;
98.553 + }
98.554 + return len1 - len2;
98.555 + }
98.556 +
98.557 + @Override
98.558 + public Path createSymbolicLink(
98.559 + Path target, FileAttribute<?>... attrs) throws IOException {
98.560 + throw new UnsupportedOperationException("Not supported.");
98.561 + }
98.562 +
98.563 + @Override
98.564 + public Path createLink(
98.565 + Path existing) throws IOException {
98.566 + throw new UnsupportedOperationException("Not supported.");
98.567 + }
98.568 +
98.569 + @Override
98.570 + public Path readSymbolicLink() throws IOException {
98.571 + throw new UnsupportedOperationException("Not supported.");
98.572 + }
98.573 +
98.574 + @Override
98.575 + public Path createDirectory(FileAttribute<?>... attrs)
98.576 + throws IOException
98.577 + {
98.578 + zfs.createDirectory(getResolvedPath(), attrs);
98.579 + return this;
98.580 + }
98.581 +
98.582 + public final Path createFile(FileAttribute<?>... attrs)
98.583 + throws IOException
98.584 + {
98.585 + OutputStream os = newOutputStream(CREATE_NEW, WRITE);
98.586 + try {
98.587 + os.close();
98.588 + } catch (IOException x) {}
98.589 + return this;
98.590 + }
98.591 +
98.592 + @Override
98.593 + public InputStream newInputStream(OpenOption... options)
98.594 + throws IOException {
98.595 + if (options.length > 0) {
98.596 + for (OpenOption opt : options) {
98.597 + if (opt != READ)
98.598 + throw new UnsupportedOperationException("'" + opt + "' not allowed");
98.599 + }
98.600 + }
98.601 + return zfs.newInputStream(getResolvedPath());
98.602 + }
98.603 +
98.604 + private static final DirectoryStream.Filter<Path> acceptAllFilter =
98.605 + new DirectoryStream.Filter<Path>() {
98.606 + @Override public boolean accept(Path entry) { return true; }
98.607 + };
98.608 +
98.609 + @Override
98.610 + public final DirectoryStream<Path> newDirectoryStream() throws IOException {
98.611 + return newDirectoryStream(acceptAllFilter);
98.612 + }
98.613 +
98.614 + @Override
98.615 + public DirectoryStream<Path> newDirectoryStream(Filter<? super Path> filter)
98.616 + throws IOException
98.617 + {
98.618 + return new ZipDirectoryStream(this, filter);
98.619 + }
98.620 +
98.621 + @Override
98.622 + public final DirectoryStream<Path> newDirectoryStream(String glob)
98.623 + throws IOException
98.624 + {
98.625 + // avoid creating a matcher if all entries are required.
98.626 + if (glob.equals("*"))
98.627 + return newDirectoryStream();
98.628 +
98.629 + // create a matcher and return a filter that uses it.
98.630 + final PathMatcher matcher = getFileSystem().getPathMatcher("glob:" + glob);
98.631 + DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
98.632 + @Override
98.633 + public boolean accept(Path entry) {
98.634 + return matcher.matches(entry.getName());
98.635 + }
98.636 + };
98.637 + return newDirectoryStream(filter);
98.638 + }
98.639 +
98.640 + @Override
98.641 + public final void delete() throws IOException {
98.642 + zfs.deleteFile(getResolvedPath(), true);
98.643 + }
98.644 +
98.645 + @Override
98.646 + public final void deleteIfExists() throws IOException {
98.647 + zfs.deleteFile(getResolvedPath(), false);
98.648 + }
98.649 +
98.650 + ZipFileAttributes getAttributes() throws IOException
98.651 + {
98.652 + ZipFileAttributes zfas = zfs.getFileAttributes(getResolvedPath());
98.653 + if (zfas == null)
98.654 + throw new NoSuchFileException(toString());
98.655 + return zfas;
98.656 + }
98.657 +
98.658 + @Override
98.659 + @SuppressWarnings("unchecked")
98.660 + public <V extends FileAttributeView> V getFileAttributeView(Class<V> type,
98.661 + LinkOption... options)
98.662 + {
98.663 + return (V)ZipFileAttributeView.get(this, type);
98.664 + }
98.665 +
98.666 + @Override
98.667 + public void setAttribute(String attribute,
98.668 + Object value,
98.669 + LinkOption... options)
98.670 + throws IOException
98.671 + {
98.672 + String type = null;
98.673 + String attr = null;
98.674 + int colonPos = attribute.indexOf(':');
98.675 + if (colonPos == -1) {
98.676 + type = "basic";
98.677 + attr = attribute;
98.678 + } else {
98.679 + type = attribute.substring(0, colonPos++);
98.680 + attr = attribute.substring(colonPos);
98.681 + }
98.682 + ZipFileAttributeView view = ZipFileAttributeView.get(this, type);
98.683 + if (view == null)
98.684 + throw new UnsupportedOperationException("view <" + view + "> is not supported");
98.685 + view.setAttribute(attr, value);
98.686 + }
98.687 +
98.688 + void setTimes(FileTime mtime, FileTime atime, FileTime ctime)
98.689 + throws IOException
98.690 + {
98.691 + zfs.setTimes(getResolvedPath(), mtime, atime, ctime);
98.692 + }
98.693 +
98.694 + private Object getAttributesImpl(String attribute, boolean domap)
98.695 + throws IOException
98.696 + {
98.697 + String view = null;
98.698 + String attr = null;
98.699 + int colonPos = attribute.indexOf(':');
98.700 + if (colonPos == -1) {
98.701 + view = "basic";
98.702 + attr = attribute;
98.703 + } else {
98.704 + view = attribute.substring(0, colonPos++);
98.705 + attr = attribute.substring(colonPos);
98.706 + }
98.707 + ZipFileAttributeView zfv = ZipFileAttributeView.get(this, view);
98.708 + if (zfv == null) {
98.709 + throw new UnsupportedOperationException("view not supported");
98.710 + }
98.711 + return zfv.getAttribute(attr, domap);
98.712 + }
98.713 +
98.714 + @Override
98.715 + public Object getAttribute(String attribute, LinkOption... options)
98.716 + throws IOException
98.717 + {
98.718 + return getAttributesImpl(attribute, false);
98.719 + }
98.720 +
98.721 + @Override
98.722 + public Map<String,?> readAttributes(String attribute, LinkOption... options)
98.723 + throws IOException
98.724 + {
98.725 + return (Map<String, ?>)getAttributesImpl(attribute, true);
98.726 + }
98.727 +
98.728 + @Override
98.729 + public FileStore getFileStore() throws IOException {
98.730 + // each ZipFileSystem only has one root (as requested for now)
98.731 + if (exists())
98.732 + return zfs.getFileStore(this);
98.733 + throw new NoSuchFileException(zfs.getString(path));
98.734 + }
98.735 +
98.736 + @Override
98.737 + public boolean isSameFile(Path other) throws IOException {
98.738 + if (other == null ||
98.739 + this.getFileSystem() != other.getFileSystem())
98.740 + return false;
98.741 + this.checkAccess();
98.742 + other.checkAccess();
98.743 + return Arrays.equals(this.getResolvedPath(),
98.744 + ((ZipPath)other).getResolvedPath());
98.745 + }
98.746 +
98.747 + public WatchKey register(
98.748 + WatchService watcher,
98.749 + WatchEvent.Kind<?>[] events,
98.750 + WatchEvent.Modifier... modifiers) {
98.751 + if (watcher == null || events == null || modifiers == null) {
98.752 + throw new NullPointerException();
98.753 + }
98.754 + throw new UnsupportedOperationException();
98.755 + }
98.756 +
98.757 + @Override
98.758 + public WatchKey register(WatchService watcher, WatchEvent.Kind<?>... events) {
98.759 + return register(watcher, events, new WatchEvent.Modifier[0]);
98.760 + }
98.761 +
98.762 + @Override
98.763 + public Iterator<Path> iterator() {
98.764 + return new Iterator<Path>() {
98.765 + private int i = 0;
98.766 +
98.767 + @Override
98.768 + public boolean hasNext() {
98.769 + return (i < getNameCount());
98.770 + }
98.771 +
98.772 + @Override
98.773 + public Path next() {
98.774 + if (i < getNameCount()) {
98.775 + Path result = getName(i);
98.776 + i++;
98.777 + return result;
98.778 + } else {
98.779 + throw new NoSuchElementException();
98.780 + }
98.781 + }
98.782 +
98.783 + @Override
98.784 + public void remove() {
98.785 + throw new ReadOnlyFileSystemException();
98.786 + }
98.787 + };
98.788 + }
98.789 +
98.790 + @Override
98.791 + public SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
98.792 + FileAttribute<?>... attrs)
98.793 + throws IOException
98.794 + {
98.795 + return zfs.newByteChannel(getResolvedPath(), options, attrs);
98.796 + }
98.797 +
98.798 +
98.799 + FileChannel newFileChannel(Set<? extends OpenOption> options,
98.800 + FileAttribute<?>... attrs)
98.801 + throws IOException
98.802 + {
98.803 + return zfs.newFileChannel(getResolvedPath(), options, attrs);
98.804 + }
98.805 +
98.806 + @Override
98.807 + public SeekableByteChannel newByteChannel(OpenOption... options)
98.808 + throws IOException {
98.809 + Set<OpenOption> set = new HashSet<OpenOption>(options.length);
98.810 + Collections.addAll(set, options);
98.811 + return newByteChannel(set);
98.812 + }
98.813 +
98.814 + @Override
98.815 + public void checkAccess(AccessMode... modes) throws IOException {
98.816 + boolean w = false;
98.817 + boolean x = false;
98.818 + for (AccessMode mode : modes) {
98.819 + switch (mode) {
98.820 + case READ:
98.821 + break;
98.822 + case WRITE:
98.823 + w = true;
98.824 + break;
98.825 + case EXECUTE:
98.826 + x = true;
98.827 + break;
98.828 + default:
98.829 + throw new UnsupportedOperationException();
98.830 + }
98.831 + }
98.832 + ZipFileAttributes attrs = zfs.getFileAttributes(getResolvedPath());
98.833 + if (attrs == null && (path.length != 1 || path[0] != '/'))
98.834 + throw new NoSuchFileException(toString());
98.835 + if (w) {
98.836 + if (zfs.isReadOnly())
98.837 + throw new AccessDeniedException(toString());
98.838 + }
98.839 + if (x)
98.840 + throw new AccessDeniedException(toString());
98.841 +
98.842 + }
98.843 +
98.844 + @Override
98.845 + public boolean exists() {
98.846 + if (path.length == 1 && path[0] == '/')
98.847 + return true;
98.848 + try {
98.849 + return zfs.exists(getResolvedPath());
98.850 + } catch (IOException x) {}
98.851 + return false;
98.852 + }
98.853 +
98.854 + @Override
98.855 + public boolean notExists() {
98.856 + return !exists();
98.857 + }
98.858 +
98.859 +
98.860 + @Override
98.861 + public OutputStream newOutputStream(OpenOption... options)
98.862 + throws IOException
98.863 + {
98.864 + if (options.length == 0)
98.865 + return zfs.newOutputStream(getResolvedPath(),
98.866 + CREATE_NEW, WRITE);
98.867 + return zfs.newOutputStream(getResolvedPath(), options);
98.868 + }
98.869 +
98.870 + @Override
98.871 + public Path moveTo(Path target, CopyOption... options)
98.872 + throws IOException
98.873 + {
98.874 + if (this.zfs.provider() == target.getFileSystem().provider() &&
98.875 + this.zfs.getZipFile().isSameFile(((ZipPath)target).zfs.getZipFile()))
98.876 + {
98.877 + zfs.copyFile(true,
98.878 + getResolvedPath(),
98.879 + ((ZipPath)target).getResolvedPath(),
98.880 + options);
98.881 + } else {
98.882 + copyToTarget(target, options);
98.883 + delete();
98.884 + }
98.885 + return target;
98.886 + }
98.887 +
98.888 + @Override
98.889 + public Path copyTo(Path target, CopyOption... options)
98.890 + throws IOException
98.891 + {
98.892 + if (this.zfs.provider() == target.getFileSystem().provider() &&
98.893 + this.zfs.getZipFile().isSameFile(((ZipPath)target).zfs.getZipFile()))
98.894 + {
98.895 + zfs.copyFile(false,
98.896 + getResolvedPath(),
98.897 + ((ZipPath)target).getResolvedPath(),
98.898 + options);
98.899 + } else {
98.900 + copyToTarget(target, options);
98.901 + }
98.902 + return target;
98.903 + }
98.904 +
98.905 + private void copyToTarget(Path target, CopyOption... options)
98.906 + throws IOException
98.907 + {
98.908 + boolean replaceExisting = false;
98.909 + boolean copyAttrs = false;
98.910 + for (CopyOption opt : options) {
98.911 + if (opt == REPLACE_EXISTING)
98.912 + replaceExisting = true;
98.913 + else if (opt == COPY_ATTRIBUTES)
98.914 + copyAttrs = false;
98.915 + }
98.916 + // attributes of source file
98.917 + ZipFileAttributes zfas = getAttributes();
98.918 + // check if target exists
98.919 + boolean exists;
98.920 + if (replaceExisting) {
98.921 + try {
98.922 + target.deleteIfExists();
98.923 + exists = false;
98.924 + } catch (DirectoryNotEmptyException x) {
98.925 + exists = true;
98.926 + }
98.927 + } else {
98.928 + exists = target.exists();
98.929 + }
98.930 + if (exists)
98.931 + throw new FileAlreadyExistsException(target.toString());
98.932 +
98.933 + if (zfas.isDirectory()) {
98.934 + // create directory or file
98.935 + target.createDirectory();
98.936 + } else {
98.937 + InputStream is = zfs.newInputStream(getResolvedPath());
98.938 + try {
98.939 + OutputStream os = target.newOutputStream();
98.940 + try {
98.941 + byte[] buf = new byte[8192];
98.942 + int n = 0;
98.943 + while ((n = is.read(buf)) != -1) {
98.944 + os.write(buf, 0, n);
98.945 + }
98.946 + } finally {
98.947 + os.close();
98.948 + }
98.949 + } finally {
98.950 + is.close();
98.951 + }
98.952 + }
98.953 + if (copyAttrs) {
98.954 + BasicFileAttributeView view =
98.955 + target.getFileAttributeView(BasicFileAttributeView.class);
98.956 + try {
98.957 + view.setTimes(zfas.lastModifiedTime(), null, null);
98.958 + } catch (IOException x) {
98.959 + // rollback?
98.960 + try {
98.961 + target.delete();
98.962 + } catch (IOException ignore) { }
98.963 + throw x;
98.964 + }
98.965 + }
98.966 + }
98.967 +}
99.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
99.2 +++ b/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipUtils.java Mon Oct 18 11:25:28 2010 -0400
99.3 @@ -0,0 +1,289 @@
99.4 +/*
99.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
99.6 + *
99.7 + * Redistribution and use in source and binary forms, with or without
99.8 + * modification, are permitted provided that the following conditions
99.9 + * are met:
99.10 + *
99.11 + * - Redistributions of source code must retain the above copyright
99.12 + * notice, this list of conditions and the following disclaimer.
99.13 + *
99.14 + * - Redistributions in binary form must reproduce the above copyright
99.15 + * notice, this list of conditions and the following disclaimer in the
99.16 + * documentation and/or other materials provided with the distribution.
99.17 + *
99.18 + * - Neither the name of Oracle nor the names of its
99.19 + * contributors may be used to endorse or promote products derived
99.20 + * from this software without specific prior written permission.
99.21 + *
99.22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
99.23 + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
99.24 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
99.25 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
99.26 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
99.27 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
99.28 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
99.29 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
99.30 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
99.31 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99.32 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99.33 + */
99.34 +
99.35 +package com.sun.nio.zipfs;
99.36 +
99.37 +import java.io.IOException;
99.38 +import java.io.OutputStream;
99.39 +import java.util.Arrays;
99.40 +import java.util.Date;
99.41 +import java.util.regex.PatternSyntaxException;
99.42 +
99.43 +/**
99.44 + *
99.45 + * @author Xueming Shen
99.46 + */
99.47 +
99.48 +class ZipUtils {
99.49 +
99.50 + /*
99.51 + * Writes a 16-bit short to the output stream in little-endian byte order.
99.52 + */
99.53 + public static void writeShort(OutputStream os, int v) throws IOException {
99.54 + os.write((v >>> 0) & 0xff);
99.55 + os.write((v >>> 8) & 0xff);
99.56 + }
99.57 +
99.58 + /*
99.59 + * Writes a 32-bit int to the output stream in little-endian byte order.
99.60 + */
99.61 + public static void writeInt(OutputStream os, long v) throws IOException {
99.62 + os.write((int)((v >>> 0) & 0xff));
99.63 + os.write((int)((v >>> 8) & 0xff));
99.64 + os.write((int)((v >>> 16) & 0xff));
99.65 + os.write((int)((v >>> 24) & 0xff));
99.66 + }
99.67 +
99.68 + /*
99.69 + * Writes a 64-bit int to the output stream in little-endian byte order.
99.70 + */
99.71 + public static void writeLong(OutputStream os, long v) throws IOException {
99.72 + os.write((int)((v >>> 0) & 0xff));
99.73 + os.write((int)((v >>> 8) & 0xff));
99.74 + os.write((int)((v >>> 16) & 0xff));
99.75 + os.write((int)((v >>> 24) & 0xff));
99.76 + os.write((int)((v >>> 32) & 0xff));
99.77 + os.write((int)((v >>> 40) & 0xff));
99.78 + os.write((int)((v >>> 48) & 0xff));
99.79 + os.write((int)((v >>> 56) & 0xff));
99.80 + }
99.81 +
99.82 + /*
99.83 + * Writes an array of bytes to the output stream.
99.84 + */
99.85 + public static void writeBytes(OutputStream os, byte[] b)
99.86 + throws IOException
99.87 + {
99.88 + os.write(b, 0, b.length);
99.89 + }
99.90 +
99.91 + /*
99.92 + * Writes an array of bytes to the output stream.
99.93 + */
99.94 + public static void writeBytes(OutputStream os, byte[] b, int off, int len)
99.95 + throws IOException
99.96 + {
99.97 + os.write(b, off, len);
99.98 + }
99.99 +
99.100 + /*
99.101 + * Append a slash at the end, if it does not have one yet
99.102 + */
99.103 + public static byte[] toDirectoryPath(byte[] dir) {
99.104 + if (dir.length != 0 && dir[dir.length - 1] != '/') {
99.105 + dir = Arrays.copyOf(dir, dir.length + 1);
99.106 + dir[dir.length - 1] = '/';
99.107 + }
99.108 + return dir;
99.109 + }
99.110 +
99.111 + /*
99.112 + * Converts DOS time to Java time (number of milliseconds since epoch).
99.113 + */
99.114 + public static long dosToJavaTime(long dtime) {
99.115 + Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80),
99.116 + (int)(((dtime >> 21) & 0x0f) - 1),
99.117 + (int)((dtime >> 16) & 0x1f),
99.118 + (int)((dtime >> 11) & 0x1f),
99.119 + (int)((dtime >> 5) & 0x3f),
99.120 + (int)((dtime << 1) & 0x3e));
99.121 + return d.getTime();
99.122 + }
99.123 +
99.124 + /*
99.125 + * Converts Java time to DOS time.
99.126 + */
99.127 + public static long javaToDosTime(long time) {
99.128 + Date d = new Date(time);
99.129 + int year = d.getYear() + 1900;
99.130 + if (year < 1980) {
99.131 + return (1 << 21) | (1 << 16);
99.132 + }
99.133 + return (year - 1980) << 25 | (d.getMonth() + 1) << 21 |
99.134 + d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 |
99.135 + d.getSeconds() >> 1;
99.136 + }
99.137 +
99.138 + private static final String regexMetaChars = ".^$+{[]|()";
99.139 + private static final String globMetaChars = "\\*?[{";
99.140 + private static boolean isRegexMeta(char c) {
99.141 + return regexMetaChars.indexOf(c) != -1;
99.142 + }
99.143 + private static boolean isGlobMeta(char c) {
99.144 + return globMetaChars.indexOf(c) != -1;
99.145 + }
99.146 + private static char EOL = 0; //TBD
99.147 + private static char next(String glob, int i) {
99.148 + if (i < glob.length()) {
99.149 + return glob.charAt(i);
99.150 + }
99.151 + return EOL;
99.152 + }
99.153 +
99.154 + /*
99.155 + * Creates a regex pattern from the given glob expression.
99.156 + *
99.157 + * @throws PatternSyntaxException
99.158 + */
99.159 + public static String toRegexPattern(String globPattern) {
99.160 + boolean inGroup = false;
99.161 + StringBuilder regex = new StringBuilder("^");
99.162 +
99.163 + int i = 0;
99.164 + while (i < globPattern.length()) {
99.165 + char c = globPattern.charAt(i++);
99.166 + switch (c) {
99.167 + case '\\':
99.168 + // escape special characters
99.169 + if (i == globPattern.length()) {
99.170 + throw new PatternSyntaxException("No character to escape",
99.171 + globPattern, i - 1);
99.172 + }
99.173 + char next = globPattern.charAt(i++);
99.174 + if (isGlobMeta(next) || isRegexMeta(next)) {
99.175 + regex.append('\\');
99.176 + }
99.177 + regex.append(next);
99.178 + break;
99.179 + case '/':
99.180 + regex.append(c);
99.181 + break;
99.182 + case '[':
99.183 + // don't match name separator in class
99.184 + regex.append("[[^/]&&[");
99.185 + if (next(globPattern, i) == '^') {
99.186 + // escape the regex negation char if it appears
99.187 + regex.append("\\^");
99.188 + i++;
99.189 + } else {
99.190 + // negation
99.191 + if (next(globPattern, i) == '!') {
99.192 + regex.append('^');
99.193 + i++;
99.194 + }
99.195 + // hyphen allowed at start
99.196 + if (next(globPattern, i) == '-') {
99.197 + regex.append('-');
99.198 + i++;
99.199 + }
99.200 + }
99.201 + boolean hasRangeStart = false;
99.202 + char last = 0;
99.203 + while (i < globPattern.length()) {
99.204 + c = globPattern.charAt(i++);
99.205 + if (c == ']') {
99.206 + break;
99.207 + }
99.208 + if (c == '/') {
99.209 + throw new PatternSyntaxException("Explicit 'name separator' in class",
99.210 + globPattern, i - 1);
99.211 + }
99.212 + // TBD: how to specify ']' in a class?
99.213 + if (c == '\\' || c == '[' ||
99.214 + c == '&' && next(globPattern, i) == '&') {
99.215 + // escape '\', '[' or "&&" for regex class
99.216 + regex.append('\\');
99.217 + }
99.218 + regex.append(c);
99.219 +
99.220 + if (c == '-') {
99.221 + if (!hasRangeStart) {
99.222 + throw new PatternSyntaxException("Invalid range",
99.223 + globPattern, i - 1);
99.224 + }
99.225 + if ((c = next(globPattern, i++)) == EOL || c == ']') {
99.226 + break;
99.227 + }
99.228 + if (c < last) {
99.229 + throw new PatternSyntaxException("Invalid range",
99.230 + globPattern, i - 3);
99.231 + }
99.232 + regex.append(c);
99.233 + hasRangeStart = false;
99.234 + } else {
99.235 + hasRangeStart = true;
99.236 + last = c;
99.237 + }
99.238 + }
99.239 + if (c != ']') {
99.240 + throw new PatternSyntaxException("Missing ']", globPattern, i - 1);
99.241 + }
99.242 + regex.append("]]");
99.243 + break;
99.244 + case '{':
99.245 + if (inGroup) {
99.246 + throw new PatternSyntaxException("Cannot nest groups",
99.247 + globPattern, i - 1);
99.248 + }
99.249 + regex.append("(?:(?:");
99.250 + inGroup = true;
99.251 + break;
99.252 + case '}':
99.253 + if (inGroup) {
99.254 + regex.append("))");
99.255 + inGroup = false;
99.256 + } else {
99.257 + regex.append('}');
99.258 + }
99.259 + break;
99.260 + case ',':
99.261 + if (inGroup) {
99.262 + regex.append(")|(?:");
99.263 + } else {
99.264 + regex.append(',');
99.265 + }
99.266 + break;
99.267 + case '*':
99.268 + if (next(globPattern, i) == '*') {
99.269 + // crosses directory boundaries
99.270 + regex.append(".*");
99.271 + i++;
99.272 + } else {
99.273 + // within directory boundary
99.274 + regex.append("[^/]*");
99.275 + }
99.276 + break;
99.277 + case '?':
99.278 + regex.append("[^/]");
99.279 + break;
99.280 + default:
99.281 + if (isRegexMeta(c)) {
99.282 + regex.append('\\');
99.283 + }
99.284 + regex.append(c);
99.285 + }
99.286 + }
99.287 + if (inGroup) {
99.288 + throw new PatternSyntaxException("Missing '}", globPattern, i - 1);
99.289 + }
99.290 + return regex.append('$').toString();
99.291 + }
99.292 +}
100.1 --- a/src/share/native/java/lang/System.c Tue Oct 12 13:34:59 2010 -0400
100.2 +++ b/src/share/native/java/lang/System.c Mon Oct 18 11:25:28 2010 -0400
100.3 @@ -97,14 +97,20 @@
100.4 } else ((void) 0)
100.5
100.6 #ifndef VENDOR /* Third party may overwrite this. */
100.7 -#define VENDOR "Sun Microsystems Inc."
100.8 -#define VENDOR_URL "http://java.sun.com/"
100.9 +#define VENDOR "Oracle Corporation"
100.10 +#define VENDOR_URL "http://java.oracle.com/"
100.11 #define VENDOR_URL_BUG "http://java.sun.com/cgi-bin/bugreport.cgi"
100.12 #endif
100.13
100.14 #define JAVA_MAX_SUPPORTED_VERSION 51
100.15 #define JAVA_MAX_SUPPORTED_MINOR_VERSION 0
100.16
100.17 +#ifdef JAVA_SPECIFICATION_VENDOR /* Third party may NOT overwrite this. */
100.18 + #error "ERROR: No override of JAVA_SPECIFICATION_VENDOR is allowed"
100.19 +#else
100.20 + #define JAVA_SPECIFICATION_VENDOR "Oracle Corporation"
100.21 +#endif
100.22 +
100.23 static int fmtdefault; // boolean value
100.24 jobject fillI18nProps(JNIEnv *env, jobject props, char *baseKey,
100.25 char *platformDispVal, char *platformFmtVal,
100.26 @@ -185,7 +191,8 @@
100.27 JDK_MAJOR_VERSION "." JDK_MINOR_VERSION);
100.28 PUTPROP(props, "java.specification.name",
100.29 "Java Platform API Specification");
100.30 - PUTPROP(props, "java.specification.vendor", "Sun Microsystems Inc.");
100.31 + PUTPROP(props, "java.specification.vendor",
100.32 + JAVA_SPECIFICATION_VENDOR);
100.33
100.34 PUTPROP(props, "java.version", RELEASE);
100.35 PUTPROP(props, "java.vendor", VENDOR);
100.36 @@ -239,7 +246,7 @@
100.37 /* Printing properties */
100.38 /* Note: java.awt.printerjob is an implementation private property which
100.39 * just happens to have a java.* name because it is referenced in
100.40 - * a java.awt class. It is the mechanism by which the Sun implementation
100.41 + * a java.awt class. It is the mechanism by which the implementation
100.42 * finds the appropriate class in the JRE for the platform.
100.43 * It is explicitly not designed to be overridden by clients as
100.44 * a way of replacing the implementation class, and in any case
100.45 @@ -267,7 +274,7 @@
100.46 /* Java2D properties */
100.47 /* Note: java.awt.graphicsenv is an implementation private property which
100.48 * just happens to have a java.* name because it is referenced in
100.49 - * a java.awt class. It is the mechanism by which the Sun implementation
100.50 + * a java.awt class. It is the mechanism by which the implementation
100.51 * finds the appropriate class in the JRE for the platform.
100.52 * It is explicitly not designed to be overridden by clients as
100.53 * a way of replacing the implementation class, and in any case
101.1 --- a/src/share/sample/nio/file/Chmod.java Tue Oct 12 13:34:59 2010 -0400
101.2 +++ b/src/share/sample/nio/file/Chmod.java Mon Oct 18 11:25:28 2010 -0400
101.3 @@ -285,18 +285,12 @@
101.4 }
101.5
101.6 @Override
101.7 - public FileVisitResult preVisitDirectory(FileRef dir) {
101.8 + public FileVisitResult preVisitDirectory(FileRef dir, BasicFileAttributes attrs) {
101.9 chmod(dir, changer);
101.10 return CONTINUE;
101.11 }
101.12
101.13 @Override
101.14 - public FileVisitResult preVisitDirectoryFailed(FileRef dir, IOException exc) {
101.15 - System.err.println("WARNING: " + exc);
101.16 - return CONTINUE;
101.17 - }
101.18 -
101.19 - @Override
101.20 public FileVisitResult visitFile(FileRef file, BasicFileAttributes attrs) {
101.21 chmod(file, changer);
101.22 return CONTINUE;
102.1 --- a/src/share/sample/nio/file/Copy.java Tue Oct 12 13:34:59 2010 -0400
102.2 +++ b/src/share/sample/nio/file/Copy.java Mon Oct 18 11:25:28 2010 -0400
102.3 @@ -85,7 +85,7 @@
102.4 }
102.5
102.6 @Override
102.7 - public FileVisitResult preVisitDirectory(Path dir) {
102.8 + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
102.9 // before visiting entries in a directory we copy the directory
102.10 // (okay if directory already exists).
102.11 CopyOption[] options = (preserve) ?
102.12 @@ -104,19 +104,9 @@
102.13 }
102.14
102.15 @Override
102.16 - public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
102.17 - System.err.format("Unable to copy: %s: %s%n", dir, exc);
102.18 - return CONTINUE;
102.19 - }
102.20 -
102.21 - @Override
102.22 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
102.23 - if (attrs.isDirectory()) {
102.24 - System.err.println("cycle detected: " + file);
102.25 - } else {
102.26 - copyFile(file, target.resolve(source.relativize(file)),
102.27 - prompt, preserve);
102.28 - }
102.29 + copyFile(file, target.resolve(source.relativize(file)),
102.30 + prompt, preserve);
102.31 return CONTINUE;
102.32 }
102.33
102.34 @@ -137,7 +127,11 @@
102.35
102.36 @Override
102.37 public FileVisitResult visitFileFailed(Path file, IOException exc) {
102.38 - System.err.format("Unable to copy: %s: %s%n", file, exc);
102.39 + if (exc instanceof FileSystemLoopException) {
102.40 + System.err.println("cycle detected: " + file);
102.41 + } else {
102.42 + System.err.format("Unable to copy: %s: %s%n", file, exc);
102.43 + }
102.44 return CONTINUE;
102.45 }
102.46 }
103.1 --- a/src/share/sample/nio/file/WatchDir.java Tue Oct 12 13:34:59 2010 -0400
103.2 +++ b/src/share/sample/nio/file/WatchDir.java Mon Oct 18 11:25:28 2010 -0400
103.3 @@ -78,12 +78,10 @@
103.4 // register directory and sub-directories
103.5 Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
103.6 @Override
103.7 - public FileVisitResult preVisitDirectory(Path dir) {
103.8 - try {
103.9 - register(dir);
103.10 - } catch (IOException x) {
103.11 - throw new IOError(x);
103.12 - }
103.13 + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
103.14 + throws IOException
103.15 + {
103.16 + register(dir);
103.17 return FileVisitResult.CONTINUE;
103.18 }
103.19 });
104.1 --- a/src/solaris/classes/java/lang/UNIXProcess.java.linux Tue Oct 12 13:34:59 2010 -0400
104.2 +++ b/src/solaris/classes/java/lang/UNIXProcess.java.linux Mon Oct 18 11:25:28 2010 -0400
104.3 @@ -176,7 +176,13 @@
104.4 }});
104.5 }
104.6
104.7 - synchronized void processExited(int exitcode) {
104.8 + void processExited(int exitcode) {
104.9 + synchronized (this) {
104.10 + this.exitcode = exitcode;
104.11 + hasExited = true;
104.12 + notifyAll();
104.13 + }
104.14 +
104.15 if (stdout instanceof ProcessPipeInputStream)
104.16 ((ProcessPipeInputStream) stdout).processExited();
104.17
104.18 @@ -185,10 +191,6 @@
104.19
104.20 if (stdin instanceof ProcessPipeOutputStream)
104.21 ((ProcessPipeOutputStream) stdin).processExited();
104.22 -
104.23 - this.exitcode = exitcode;
104.24 - hasExited = true;
104.25 - notifyAll();
104.26 }
104.27
104.28 public OutputStream getOutputStream() {
105.1 --- a/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java Tue Oct 12 13:34:59 2010 -0400
105.2 +++ b/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java Mon Oct 18 11:25:28 2010 -0400
105.3 @@ -64,7 +64,10 @@
105.4 accessor.setFile(fd, null);
105.5 accessor.setFiles(fd, null, null);
105.6 } else {
105.7 - accessor.setDirectory(fd, directory);
105.8 + // Fix 6987233: add the trailing slash if it's absent
105.9 + accessor.setDirectory(fd, directory +
105.10 + (directory.endsWith(File.separator) ?
105.11 + "" : File.separator));
105.12 accessor.setFile(fd, filenames[0]);
105.13 accessor.setFiles(fd, directory, filenames);
105.14 }
106.1 --- a/src/solaris/classes/sun/awt/X11/XBaseWindow.java Tue Oct 12 13:34:59 2010 -0400
106.2 +++ b/src/solaris/classes/sun/awt/X11/XBaseWindow.java Mon Oct 18 11:25:28 2010 -0400
106.3 @@ -705,12 +705,8 @@
106.4 throw new IllegalStateException("Attempt to resize uncreated window");
106.5 }
106.6 insLog.fine("Setting bounds on " + this + " to (" + x + ", " + y + "), " + width + "x" + height);
106.7 - if (width <= 0) {
106.8 - width = 1;
106.9 - }
106.10 - if (height <= 0) {
106.11 - height = 1;
106.12 - }
106.13 + width = Math.max(MIN_SIZE, width);
106.14 + height = Math.max(MIN_SIZE, height);
106.15 XToolkit.awtLock();
106.16 try {
106.17 XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), getWindow(), x,y,width,height);
107.1 --- a/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java Tue Oct 12 13:34:59 2010 -0400
107.2 +++ b/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java Mon Oct 18 11:25:28 2010 -0400
107.3 @@ -763,12 +763,8 @@
107.4 }
107.5
107.6 private void checkShellRectSize(Rectangle shellRect) {
107.7 - if (shellRect.width < 0) {
107.8 - shellRect.width = 1;
107.9 - }
107.10 - if (shellRect.height < 0) {
107.11 - shellRect.height = 1;
107.12 - }
107.13 + shellRect.width = Math.max(MIN_SIZE, shellRect.width);
107.14 + shellRect.height = Math.max(MIN_SIZE, shellRect.height);
107.15 }
107.16
107.17 private void checkShellRectPos(Rectangle shellRect) {
108.1 --- a/src/solaris/classes/sun/awt/X11/XEmbeddedFrame.java Tue Oct 12 13:34:59 2010 -0400
108.2 +++ b/src/solaris/classes/sun/awt/X11/XEmbeddedFrame.java Mon Oct 18 11:25:28 2010 -0400
108.3 @@ -28,9 +28,12 @@
108.4 import sun.awt.EmbeddedFrame;
108.5 import java.awt.*;
108.6 import java.awt.AWTKeyStroke;
108.7 +import java.util.logging.Logger;
108.8
108.9 public class XEmbeddedFrame extends EmbeddedFrame {
108.10
108.11 + private static final Logger log = Logger.getLogger(XEmbeddedFrame.class.getName());
108.12 +
108.13 long handle;
108.14 public XEmbeddedFrame() {
108.15 }
108.16 @@ -70,6 +73,21 @@
108.17 this(handle, supportsXEmbed, false);
108.18 }
108.19
108.20 + /*
108.21 + * The method shouldn't be called in case of active XEmbed.
108.22 + */
108.23 + public boolean traverseIn(boolean direction) {
108.24 + XEmbeddedFramePeer peer = (XEmbeddedFramePeer)getPeer();
108.25 + if (peer != null) {
108.26 + if (peer.supportsXEmbed() && peer.isXEmbedActive()) {
108.27 + log.fine("The method shouldn't be called when XEmbed is active!");
108.28 + } else {
108.29 + return super.traverseIn(direction);
108.30 + }
108.31 + }
108.32 + return false;
108.33 + }
108.34 +
108.35 protected boolean traverseOut(boolean direction) {
108.36 XEmbeddedFramePeer xefp = (XEmbeddedFramePeer) getPeer();
108.37 if (direction == FORWARD) {
108.38 @@ -81,6 +99,20 @@
108.39 return true;
108.40 }
108.41
108.42 + /*
108.43 + * The method shouldn't be called in case of active XEmbed.
108.44 + */
108.45 + public void synthesizeWindowActivation(boolean doActivate) {
108.46 + XEmbeddedFramePeer peer = (XEmbeddedFramePeer)getPeer();
108.47 + if (peer != null) {
108.48 + if (peer.supportsXEmbed() && peer.isXEmbedActive()) {
108.49 + log.fine("The method shouldn't be called when XEmbed is active!");
108.50 + } else {
108.51 + peer.synthesizeFocusInOut(doActivate);
108.52 + }
108.53 + }
108.54 + }
108.55 +
108.56 public void registerAccelerator(AWTKeyStroke stroke) {
108.57 XEmbeddedFramePeer xefp = (XEmbeddedFramePeer) getPeer();
108.58 if (xefp != null) {
109.1 --- a/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java Tue Oct 12 13:34:59 2010 -0400
109.2 +++ b/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java Mon Oct 18 11:25:28 2010 -0400
109.3 @@ -35,6 +35,8 @@
109.4 import sun.awt.EmbeddedFrame;
109.5 import sun.awt.SunToolkit;
109.6
109.7 +import static sun.awt.X11.XConstants.*;
109.8 +
109.9 public class XEmbeddedFramePeer extends XFramePeer {
109.10
109.11 private static final PlatformLogger xembedLog = PlatformLogger.getLogger("sun.awt.X11.xembed.XEmbeddedFramePeer");
109.12 @@ -305,4 +307,20 @@
109.13 EmbeddedFrame frame = (EmbeddedFrame)target;
109.14 frame.notifyModalBlocked(blocker, blocked);
109.15 }
109.16 +
109.17 + public void synthesizeFocusInOut(boolean doFocus) {
109.18 + XFocusChangeEvent xev = new XFocusChangeEvent();
109.19 +
109.20 + XToolkit.awtLock();
109.21 + try {
109.22 + xev.set_type(doFocus ? FocusIn : FocusOut);
109.23 + xev.set_window(getFocusProxy().getWindow());
109.24 + xev.set_mode(NotifyNormal);
109.25 + XlibWrapper.XSendEvent(XToolkit.getDisplay(), getFocusProxy().getWindow(), false,
109.26 + NoEventMask, xev.pData);
109.27 + } finally {
109.28 + XToolkit.awtUnlock();
109.29 + xev.dispose();
109.30 + }
109.31 + }
109.32 }
110.1 --- a/src/solaris/classes/sun/awt/X11/XToolkit.java Tue Oct 12 13:34:59 2010 -0400
110.2 +++ b/src/solaris/classes/sun/awt/X11/XToolkit.java Mon Oct 18 11:25:28 2010 -0400
110.3 @@ -1482,8 +1482,19 @@
110.4 try {
110.5 if (numberOfButtons == 0) {
110.6 numberOfButtons = getNumberOfButtonsImpl();
110.7 + numberOfButtons = (numberOfButtons > MAX_BUTTONS_SUPPORTED)? MAX_BUTTONS_SUPPORTED : numberOfButtons;
110.8 + //4th and 5th buttons are for wheel and shouldn't be reported as buttons.
110.9 + //If we have more than 3 physical buttons and a wheel, we report N-2 buttons.
110.10 + //If we have 3 physical buttons and a wheel, we report 3 buttons.
110.11 + //If we have 1,2,3 physical buttons, we report it as is i.e. 1,2 or 3 respectively.
110.12 + if (numberOfButtons >=5) {
110.13 + numberOfButtons -= 2;
110.14 + } else if (numberOfButtons == 4 || numberOfButtons ==5){
110.15 + numberOfButtons = 3;
110.16 + }
110.17 }
110.18 - return (numberOfButtons > MAX_BUTTONS_SUPPORTED)? MAX_BUTTONS_SUPPORTED : numberOfButtons;
110.19 + //Assume don't have to re-query the number again and again.
110.20 + return numberOfButtons;
110.21 } finally {
110.22 awtUnlock();
110.23 }
111.1 --- a/src/solaris/classes/sun/nio/fs/LinuxFileStore.java Tue Oct 12 13:34:59 2010 -0400
111.2 +++ b/src/solaris/classes/sun/nio/fs/LinuxFileStore.java Mon Oct 18 11:25:28 2010 -0400
111.3 @@ -156,9 +156,4 @@
111.4 return supportsFileAttributeView(UserDefinedFileAttributeView.class);
111.5 return super.supportsFileAttributeView(name);
111.6 }
111.7 -
111.8 - @Override
111.9 - boolean isLoopback() {
111.10 - return false;
111.11 - }
111.12 }
112.1 --- a/src/solaris/classes/sun/nio/fs/SolarisFileStore.java Tue Oct 12 13:34:59 2010 -0400
112.2 +++ b/src/solaris/classes/sun/nio/fs/SolarisFileStore.java Mon Oct 18 11:25:28 2010 -0400
112.3 @@ -108,9 +108,4 @@
112.4 return supportsFileAttributeView(UserDefinedFileAttributeView.class);
112.5 return super.supportsFileAttributeView(name);
112.6 }
112.7 -
112.8 - @Override
112.9 - boolean isLoopback() {
112.10 - return type().equals("lofs");
112.11 - }
112.12 }
113.1 --- a/src/solaris/classes/sun/nio/fs/UnixFileStore.java Tue Oct 12 13:34:59 2010 -0400
113.2 +++ b/src/solaris/classes/sun/nio/fs/UnixFileStore.java Mon Oct 18 11:25:28 2010 -0400
113.3 @@ -76,12 +76,6 @@
113.4 */
113.5 abstract UnixMountEntry findMountEntry() throws IOException;
113.6
113.7 - /**
113.8 - * Returns true if this file store represents a loopback file system that
113.9 - * will have the same device ID as underlying file system.
113.10 - */
113.11 - abstract boolean isLoopback();
113.12 -
113.13 UnixPath file() {
113.14 return file;
113.15 }
113.16 @@ -169,22 +163,13 @@
113.17 if (!(ob instanceof UnixFileStore))
113.18 return false;
113.19 UnixFileStore other = (UnixFileStore)ob;
113.20 - if (dev != other.dev)
113.21 - return false;
113.22 - // deviceIDs are equal but they may not be equal if one or both of
113.23 - // them is a loopback file system
113.24 - boolean thisIsLoopback = isLoopback();
113.25 - if (thisIsLoopback != other.isLoopback())
113.26 - return false; // one, but not both, are lofs
113.27 - if (!thisIsLoopback)
113.28 - return true; // neither is lofs
113.29 - // both are lofs so compare mount points
113.30 - return Arrays.equals(this.entry.dir(), other.entry.dir());
113.31 + return (this.dev == other.dev) &&
113.32 + Arrays.equals(this.entry.dir(), other.entry.dir());
113.33 }
113.34
113.35 @Override
113.36 public int hashCode() {
113.37 - return (int)(dev ^ (dev >>> 32));
113.38 + return (int)(dev ^ (dev >>> 32)) ^ Arrays.hashCode(entry.dir());
113.39 }
113.40
113.41 @Override
114.1 --- a/src/solaris/native/java/io/io_util_md.c Tue Oct 12 13:34:59 2010 -0400
114.2 +++ b/src/solaris/native/java/io/io_util_md.c Mon Oct 18 11:25:28 2010 -0400
114.3 @@ -83,8 +83,6 @@
114.4 close(devnull);
114.5 }
114.6 } else if (JVM_Close(fd) == -1) {
114.7 - SET_FD(this, fd, fid); // restore fd
114.8 - printf("JVM_Close returned -1\n");
114.9 - JNU_ThrowIOExceptionWithLastError(env, "close failed");
114.10 + JNU_ThrowIOExceptionWithLastError(env, "close failed");
114.11 }
114.12 }
115.1 --- a/src/solaris/native/java/net/Inet6AddressImpl.c Tue Oct 12 13:34:59 2010 -0400
115.2 +++ b/src/solaris/native/java/net/Inet6AddressImpl.c Mon Oct 18 11:25:28 2010 -0400
115.3 @@ -124,7 +124,7 @@
115.4 static int initialized = 0;
115.5
115.6 /*
115.7 - * Find an internet address for a given hostname. Not this this
115.8 + * Find an internet address for a given hostname. Note that this
115.9 * code only works for addresses of type INET. The translation
115.10 * of %d.%d.%d.%d to an address (int) occurs in java now, so the
115.11 * String "host" shouldn't *ever* be a %d.%d.%d.%d string
115.12 @@ -200,7 +200,7 @@
115.13 */
115.14 if (isspace((unsigned char)hostname[0])) {
115.15 JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
115.16 - (char *)hostname);
115.17 + hostname);
115.18 JNU_ReleaseStringPlatformChars(env, host, hostname);
115.19 return NULL;
115.20 }
115.21 @@ -210,8 +210,7 @@
115.22
115.23 if (error) {
115.24 /* report error */
115.25 - JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
115.26 - (char *)hostname);
115.27 + ThrowUnknownHostExceptionWithGaiError(env, hostname, error);
115.28 JNU_ReleaseStringPlatformChars(env, host, hostname);
115.29 return NULL;
115.30 } else {
115.31 @@ -407,7 +406,7 @@
115.32 addr |= ((caddr[1] <<16) & 0xff0000);
115.33 addr |= ((caddr[2] <<8) & 0xff00);
115.34 addr |= (caddr[3] & 0xff);
115.35 - memset((char *) &him4, 0, sizeof(him4));
115.36 + memset((void *) &him4, 0, sizeof(him4));
115.37 him4.sin_addr.s_addr = (uint32_t) htonl(addr);
115.38 him4.sin_family = AF_INET;
115.39 sa = (struct sockaddr *) &him4;
115.40 @@ -417,7 +416,7 @@
115.41 * For IPv6 address construct a sockaddr_in6 structure.
115.42 */
115.43 (*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr);
115.44 - memset((char *) &him6, 0, sizeof(him6));
115.45 + memset((void *) &him6, 0, sizeof(him6));
115.46 memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) );
115.47 him6.sin6_family = AF_INET6;
115.48 sa = (struct sockaddr *) &him6 ;
115.49 @@ -579,8 +578,8 @@
115.50 ifArray, ttl);
115.51 }
115.52
115.53 - memset((char *) caddr, 0, 16);
115.54 - memset((char *) &him6, 0, sizeof(him6));
115.55 + memset((void *) caddr, 0, 16);
115.56 + memset((void *) &him6, 0, sizeof(him6));
115.57 (*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr);
115.58 memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) );
115.59 him6.sin6_family = AF_INET6;
115.60 @@ -600,8 +599,8 @@
115.61 * for it.
115.62 */
115.63 if (!(IS_NULL(ifArray))) {
115.64 - memset((char *) caddr, 0, 16);
115.65 - memset((char *) &inf6, 0, sizeof(inf6));
115.66 + memset((void *) caddr, 0, 16);
115.67 + memset((void *) &inf6, 0, sizeof(inf6));
115.68 (*env)->GetByteArrayRegion(env, ifArray, 0, 16, caddr);
115.69 memcpy((void *)&(inf6.sin6_addr), caddr, sizeof(struct in6_addr) );
115.70 inf6.sin6_family = AF_INET6;
116.1 --- a/src/solaris/native/java/net/net_util_md.c Tue Oct 12 13:34:59 2010 -0400
116.2 +++ b/src/solaris/native/java/net/net_util_md.c Mon Oct 18 11:25:28 2010 -0400
116.3 @@ -61,6 +61,7 @@
116.4
116.5 getaddrinfo_f getaddrinfo_ptr = NULL;
116.6 freeaddrinfo_f freeaddrinfo_ptr = NULL;
116.7 +gai_strerror_f gai_strerror_ptr = NULL;
116.8 getnameinfo_f getnameinfo_ptr = NULL;
116.9
116.10 /*
116.11 @@ -342,11 +343,14 @@
116.12 freeaddrinfo_ptr = (freeaddrinfo_f)
116.13 JVM_FindLibraryEntry(RTLD_DEFAULT, "freeaddrinfo");
116.14
116.15 + gai_strerror_ptr = (gai_strerror_f)
116.16 + JVM_FindLibraryEntry(RTLD_DEFAULT, "gai_strerror");
116.17 +
116.18 getnameinfo_ptr = (getnameinfo_f)
116.19 JVM_FindLibraryEntry(RTLD_DEFAULT, "getnameinfo");
116.20
116.21 if (freeaddrinfo_ptr == NULL || getnameinfo_ptr == NULL) {
116.22 - /* Wee need all 3 of them */
116.23 + /* We need all 3 of them */
116.24 getaddrinfo_ptr = NULL;
116.25 }
116.26
116.27 @@ -355,6 +359,35 @@
116.28 #endif /* AF_INET6 */
116.29 }
116.30
116.31 +void ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
116.32 + const char* hostname,
116.33 + int gai_error)
116.34 +{
116.35 + int size;
116.36 + char *buf;
116.37 + const char *format = "%s: %s";
116.38 + const char *error_string =
116.39 + (gai_strerror_ptr == NULL) ? NULL : (*gai_strerror_ptr)(gai_error);
116.40 + if (error_string == NULL)
116.41 + error_string = "unknown error";
116.42 +
116.43 + size = strlen(format) + strlen(hostname) + strlen(error_string) + 2;
116.44 + buf = (char *) malloc(size);
116.45 + if (buf) {
116.46 + jstring s;
116.47 + sprintf(buf, format, hostname, error_string);
116.48 + s = JNU_NewStringPlatform(env, buf);
116.49 + if (s != NULL) {
116.50 + jobject x = JNU_NewObjectByName(env,
116.51 + "java/net/UnknownHostException",
116.52 + "(Ljava/lang/String;)V", s);
116.53 + if (x != NULL)
116.54 + (*env)->Throw(env, x);
116.55 + }
116.56 + free(buf);
116.57 + }
116.58 +}
116.59 +
116.60 void
116.61 NET_AllocSockaddr(struct sockaddr **him, int *len) {
116.62 #ifdef AF_INET6
116.63 @@ -1173,19 +1206,26 @@
116.64 }
116.65
116.66 /*
116.67 - * SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On Solaris need to
116.68 - * ensure that value is <= max_buf as otherwise we get
116.69 - * an invalid argument.
116.70 + * SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On Solaris we may need to clamp
116.71 + * the value when it exceeds the system limit.
116.72 */
116.73 #ifdef __solaris__
116.74 if (level == SOL_SOCKET) {
116.75 if (opt == SO_SNDBUF || opt == SO_RCVBUF) {
116.76 int sotype, arglen;
116.77 int *bufsize, maxbuf;
116.78 + int ret;
116.79 +
116.80 + /* Attempt with the original size */
116.81 + ret = setsockopt(fd, level, opt, arg, len);
116.82 + if ((ret == 0) || (ret == -1 && errno != ENOBUFS))
116.83 + return ret;
116.84 +
116.85 + /* Exceeded system limit so clamp and retry */
116.86
116.87 if (!init_max_buf) {
116.88 - tcp_max_buf = getParam("/dev/tcp", "tcp_max_buf", 64*1024);
116.89 - udp_max_buf = getParam("/dev/udp", "udp_max_buf", 64*1024);
116.90 + tcp_max_buf = getParam("/dev/tcp", "tcp_max_buf", 1024*1024);
116.91 + udp_max_buf = getParam("/dev/udp", "udp_max_buf", 2048*1024);
116.92 init_max_buf = 1;
116.93 }
116.94
117.1 --- a/src/solaris/native/java/net/net_util_md.h Tue Oct 12 13:34:59 2010 -0400
117.2 +++ b/src/solaris/native/java/net/net_util_md.h Mon Oct 18 11:25:28 2010 -0400
117.3 @@ -84,11 +84,13 @@
117.4
117.5 /* needed from libsocket on Solaris 8 */
117.6
117.7 -typedef int (*getaddrinfo_f)(const char *nodename, const char *servname,
117.8 - const struct addrinfo *hints, struct addrinfo **res);
117.9 +typedef int (*getaddrinfo_f)(const char *nodename, const char *servname,
117.10 + const struct addrinfo *hints, struct addrinfo **res);
117.11
117.12 typedef void (*freeaddrinfo_f)(struct addrinfo *);
117.13
117.14 +typedef const char * (*gai_strerror_f)(int ecode);
117.15 +
117.16 typedef int (*getnameinfo_f)(const struct sockaddr *, size_t,
117.17 char *, size_t, char *, size_t, int);
117.18
117.19 @@ -96,6 +98,10 @@
117.20 extern freeaddrinfo_f freeaddrinfo_ptr;
117.21 extern getnameinfo_f getnameinfo_ptr;
117.22
117.23 +void ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
117.24 + const char* hostname,
117.25 + int gai_error);
117.26 +
117.27 /* do we have address translation support */
117.28
117.29 extern jboolean NET_addrtransAvailable();
118.1 --- a/src/solaris/native/sun/awt/awt_InputMethod.c Tue Oct 12 13:34:59 2010 -0400
118.2 +++ b/src/solaris/native/sun/awt/awt_InputMethod.c Mon Oct 18 11:25:28 2010 -0400
118.3 @@ -1473,6 +1473,10 @@
118.4 static void DestroyXIMCallback(XIM im, XPointer client_data, XPointer call_data) {
118.5 /* mark that XIM server was destroyed */
118.6 X11im = NULL;
118.7 + JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
118.8 + /* free the old pX11IMData and set it to null. this also avoids crashing
118.9 + * the jvm if the XIM server reappears */
118.10 + X11InputMethodData *pX11IMData = getX11InputMethodData(env, currentX11InputMethodInstance);
118.11 }
118.12
118.13 /*
119.1 --- a/src/windows/classes/sun/awt/windows/WComponentPeer.java Tue Oct 12 13:34:59 2010 -0400
119.2 +++ b/src/windows/classes/sun/awt/windows/WComponentPeer.java Mon Oct 18 11:25:28 2010 -0400
119.3 @@ -556,24 +556,26 @@
119.4
119.5 Component target = (Component)getTarget();
119.6 Window window = SunToolkit.getContainingWindow(target);
119.7 - if (window != null && !window.isOpaque()) {
119.8 - // Non-opaque windows do not support heavyweight children.
119.9 - // Redirect all painting to the Window's Graphics instead.
119.10 - // The caller is responsible for calling the
119.11 - // WindowPeer.updateWindow() after painting has finished.
119.12 - int x = 0, y = 0;
119.13 - for (Component c = target; c != window; c = c.getParent()) {
119.14 - x += c.getX();
119.15 - y += c.getY();
119.16 - }
119.17 -
119.18 + if (window != null) {
119.19 Graphics g =
119.20 ((WWindowPeer)window.getPeer()).getTranslucentGraphics();
119.21 + // getTranslucentGraphics() returns non-null value for non-opaque windows only
119.22 + if (g != null) {
119.23 + // Non-opaque windows do not support heavyweight children.
119.24 + // Redirect all painting to the Window's Graphics instead.
119.25 + // The caller is responsible for calling the
119.26 + // WindowPeer.updateWindow() after painting has finished.
119.27 + int x = 0, y = 0;
119.28 + for (Component c = target; c != window; c = c.getParent()) {
119.29 + x += c.getX();
119.30 + y += c.getY();
119.31 + }
119.32
119.33 - g.translate(x, y);
119.34 - g.clipRect(0, 0, target.getWidth(), target.getHeight());
119.35 + g.translate(x, y);
119.36 + g.clipRect(0, 0, target.getWidth(), target.getHeight());
119.37
119.38 - return g;
119.39 + return g;
119.40 + }
119.41 }
119.42
119.43 SurfaceData surfaceData = this.surfaceData;
120.1 --- a/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java Tue Oct 12 13:34:59 2010 -0400
120.2 +++ b/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java Mon Oct 18 11:25:28 2010 -0400
120.3 @@ -191,9 +191,20 @@
120.4 public void activateEmbeddingTopLevel() {
120.5 }
120.6
120.7 - public void synthesizeWindowActivation(boolean doActivate) {
120.8 - ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(doActivate);
120.9 + public void synthesizeWindowActivation(final boolean doActivate) {
120.10 + if (!doActivate || EventQueue.isDispatchThread()) {
120.11 + ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(doActivate);
120.12 + } else {
120.13 + // To avoid focus concurrence b/w IE and EmbeddedFrame
120.14 + // activation is postponed by means of posting it to EDT.
120.15 + EventQueue.invokeLater(new Runnable() {
120.16 + public void run() {
120.17 + ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(true);
120.18 + }
120.19 + });
120.20 + }
120.21 }
120.22 +
120.23 public void registerAccelerator(AWTKeyStroke stroke) {}
120.24 public void unregisterAccelerator(AWTKeyStroke stroke) {}
120.25
121.1 --- a/src/windows/classes/sun/awt/windows/WWindowPeer.java Tue Oct 12 13:34:59 2010 -0400
121.2 +++ b/src/windows/classes/sun/awt/windows/WWindowPeer.java Mon Oct 18 11:25:28 2010 -0400
121.3 @@ -595,16 +595,6 @@
121.4 }
121.5
121.6 @Override
121.7 - public Graphics getGraphics() {
121.8 - synchronized (getStateLock()) {
121.9 - if (!isOpaque) {
121.10 - return getTranslucentGraphics();
121.11 - }
121.12 - }
121.13 - return super.getGraphics();
121.14 - }
121.15 -
121.16 - @Override
121.17 public void setBackground(Color c) {
121.18 super.setBackground(c);
121.19 synchronized (getStateLock()) {
122.1 --- a/src/windows/lib/tzmappings Tue Oct 12 13:34:59 2010 -0400
122.2 +++ b/src/windows/lib/tzmappings Mon Oct 18 11:25:28 2010 -0400
122.3 @@ -1,5 +1,4 @@
122.4 #
122.5 -#
122.6 # This file describes mapping information between Windows and Java
122.7 # time zones.
122.8 # Format: Each line should include a colon separated fields of Windows
122.9 @@ -11,7 +10,7 @@
122.10 # NOTE
122.11 # This table format is not a public interface of any Java
122.12 # platforms. No applications should depend on this file in any form.
122.13 -#
122.14 +#
122.15 # This table has been generated by a program and should not be edited
122.16 # manually.
122.17 #
122.18 @@ -84,8 +83,8 @@
122.19 Ekaterinburg Standard Time:10,11::Asia/Yekaterinburg:
122.20 West Asia:10,11:UZ:Asia/Tashkent:
122.21 West Asia Standard Time:10,11:UZ:Asia/Tashkent:
122.22 -Central Asia:12,13::Asia/Dhaka:
122.23 -Central Asia Standard Time:12,13::Asia/Dhaka:
122.24 +Central Asia:12,13::Asia/Almaty:
122.25 +Central Asia Standard Time:12,13::Asia/Almaty:
122.26 N. Central Asia Standard Time:12,13::Asia/Novosibirsk:
122.27 Bangkok:14,15::Asia/Bangkok:
122.28 Bangkok Standard Time:14,15::Asia/Bangkok:
122.29 @@ -167,22 +166,27 @@
122.30 Greenwich Standard Time:88,89::GMT:
122.31 Argentina Standard Time:900,900::America/Buenos_Aires:
122.32 Azerbaijan Standard Time:901,901:AZ:Asia/Baku:
122.33 -Central Brazilian Standard Time:902,902:BR:America/Manaus:
122.34 -Central Standard Time (Mexico):903,903::America/Mexico_City:
122.35 -Georgian Standard Time:904,904:GE:Asia/Tbilisi:
122.36 -Jordan Standard Time:905,905:JO:Asia/Amman:
122.37 -Mauritius Standard Time:906,906:MU:Indian/Mauritius:
122.38 -Middle East Standard Time:907,907:LB:Asia/Beirut:
122.39 -Montevideo Standard Time:908,908:UY:America/Montevideo:
122.40 -Morocco Standard Time:909,909:MA:Africa/Casablanca:
122.41 -Mountain Standard Time (Mexico):910,910:MX:America/Chihuahua:
122.42 -Namibia Standard Time:911,911:NA:Africa/Windhoek:
122.43 -Pacific Standard Time (Mexico):912,912:MX:America/Tijuana:
122.44 -Pakistan Standard Time:913,913::Asia/Karachi:
122.45 -UTC:914,914::UTC:
122.46 -Venezuela Standard Time:915,915::America/Caracas:
122.47 -Kamchatka Standard Time:916,916:RU:Asia/Kamchatka:
122.48 -Paraguay Standard Time:917,917:PY:America/Asuncion:
122.49 -Western Brazilian Standard Time:918,918:BR:America/Rio_Branco:
122.50 -Ulaanbaatar Standard Time:919,919::Asia/Ulaanbaatar:
122.51 -Armenian Standard Time:920,920:AM:Asia/Yerevan:
122.52 +Bangladesh Standard Time:902,902::Asia/Dhaka:
122.53 +Central Brazilian Standard Time:903,903:BR:America/Manaus:
122.54 +Central Standard Time (Mexico):904,904::America/Mexico_City:
122.55 +Georgian Standard Time:905,905:GE:Asia/Tbilisi:
122.56 +Jordan Standard Time:906,906:JO:Asia/Amman:
122.57 +Kamchatka Standard Time:907,907:RU:Asia/Kamchatka:
122.58 +Mauritius Standard Time:908,908:MU:Indian/Mauritius:
122.59 +Middle East Standard Time:909,909:LB:Asia/Beirut:
122.60 +Montevideo Standard Time:910,910:UY:America/Montevideo:
122.61 +Morocco Standard Time:911,911:MA:Africa/Casablanca:
122.62 +Mountain Standard Time (Mexico):912,912:MX:America/Chihuahua:
122.63 +Namibia Standard Time:913,913:NA:Africa/Windhoek:
122.64 +Pacific Standard Time (Mexico):914,914:MX:America/Tijuana:
122.65 +Pakistan Standard Time:915,915::Asia/Karachi:
122.66 +Paraguay Standard Time:916,916:PY:America/Asuncion:
122.67 +Syria Standard Time:917,917:SY:Asia/Damascus:
122.68 +UTC:918,918::UTC:
122.69 +UTC+12:919,919::GMT+1200:
122.70 +UTC-02:920,920::GMT-0200:
122.71 +UTC-11:921,921::GMT-1100:
122.72 +Ulaanbaatar Standard Time:922,922::Asia/Ulaanbaatar:
122.73 +Venezuela Standard Time:923,923::America/Caracas:
122.74 +Western Brazilian Standard Time:924,924:BR:America/Rio_Branco:
122.75 +Armenian Standard Time:925,925:AM:Asia/Yerevan:
123.1 --- a/src/windows/native/java/io/io_util_md.c Tue Oct 12 13:34:59 2010 -0400
123.2 +++ b/src/windows/native/java/io/io_util_md.c Mon Oct 18 11:25:28 2010 -0400
123.3 @@ -531,7 +531,6 @@
123.4 SET_FD(this, -1, fid);
123.5
123.6 if (CloseHandle(h) == 0) { /* Returns zero on failure */
123.7 - SET_FD(this, fd, fid); // restore fd
123.8 JNU_ThrowIOExceptionWithLastError(env, "close failed");
123.9 }
123.10 return 0;
124.1 --- a/src/windows/native/sun/net/spi/DefaultProxySelector.c Tue Oct 12 13:34:59 2010 -0400
124.2 +++ b/src/windows/native/sun/net/spi/DefaultProxySelector.c Mon Oct 18 11:25:28 2010 -0400
124.3 @@ -250,6 +250,10 @@
124.4 return proxy;
124.5 }
124.6 }
124.7 + } else {
124.8 + /* ProxyEnable == 0 or Query failed */
124.9 + /* close the handle to the registry key */
124.10 + RegCloseKey(hKey);
124.11 }
124.12 }
124.13
125.1 --- a/src/windows/native/sun/windows/awt_Component.cpp Tue Oct 12 13:34:59 2010 -0400
125.2 +++ b/src/windows/native/sun/windows/awt_Component.cpp Mon Oct 18 11:25:28 2010 -0400
125.3 @@ -2329,6 +2329,19 @@
125.4 MSG msg;
125.5 InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
125.6
125.7 + AwtWindow *toplevel = GetContainer();
125.8 + if (toplevel && !toplevel->IsSimpleWindow()) {
125.9 + /*
125.10 + * The frame should be focused by click in case it is
125.11 + * the active window but not the focused window. See 6886678.
125.12 + */
125.13 + if (toplevel->GetHWnd() == ::GetActiveWindow() &&
125.14 + toplevel->GetHWnd() != AwtComponent::GetFocusedWindow())
125.15 + {
125.16 + toplevel->AwtSetActiveWindow();
125.17 + }
125.18 + }
125.19 +
125.20 SendMouseEvent(java_awt_event_MouseEvent_MOUSE_PRESSED, now, x, y,
125.21 GetJavaModifiers(), clickCount, JNI_FALSE,
125.22 GetButton(button), &msg);
126.1 --- a/src/windows/native/sun/windows/awt_Desktop.cpp Tue Oct 12 13:34:59 2010 -0400
126.2 +++ b/src/windows/native/sun/windows/awt_Desktop.cpp Mon Oct 18 11:25:28 2010 -0400
126.3 @@ -59,15 +59,17 @@
126.4 FORMAT_MESSAGE_FROM_SYSTEM |
126.5 FORMAT_MESSAGE_IGNORE_INSERTS,
126.6 NULL,
126.7 - GetLastError(),
126.8 + (int)retval,
126.9 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
126.10 (LPTSTR)&buffer,
126.11 0,
126.12 NULL );
126.13
126.14 - jstring errmsg = JNU_NewStringPlatform(env, buffer, len);
126.15 - LocalFree(buffer);
126.16 - return errmsg;
126.17 + if (buffer) {
126.18 + jstring errmsg = JNU_NewStringPlatform(env, buffer);
126.19 + LocalFree(buffer);
126.20 + return errmsg;
126.21 + }
126.22 }
126.23
126.24 return NULL;
127.1 --- a/src/windows/native/sun/windows/awt_DesktopProperties.cpp Tue Oct 12 13:34:59 2010 -0400
127.2 +++ b/src/windows/native/sun/windows/awt_DesktopProperties.cpp Mon Oct 18 11:25:28 2010 -0400
127.3 @@ -505,7 +505,8 @@
127.4 SetIntegerProperty(TEXT("win.drag.width"), cxdrag);
127.5 SetIntegerProperty(TEXT("win.drag.height"), cydrag);
127.6 SetIntegerProperty(TEXT("DnD.gestureMotionThreshold"), max(cxdrag, cydrag)/2);
127.7 - SetIntegerProperty(TEXT("awt.mouse.numButtons"), GetSystemMetrics(SM_CMOUSEBUTTONS));
127.8 + SetIntegerProperty(TEXT("awt.mouse.numButtons"), AwtToolkit::GetNumberOfButtons());
127.9 +
127.10 SetIntegerProperty(TEXT("awt.multiClickInterval"), GetDoubleClickTime());
127.11
127.12 // BEGIN cross-platform properties
128.1 --- a/src/windows/native/sun/windows/awt_Toolkit.cpp Tue Oct 12 13:34:59 2010 -0400
128.2 +++ b/src/windows/native/sun/windows/awt_Toolkit.cpp Mon Oct 18 11:25:28 2010 -0400
128.3 @@ -133,6 +133,8 @@
128.4
128.5 static LPCTSTR szAwtToolkitClassName = TEXT("SunAwtToolkit");
128.6
128.7 +static const int MOUSE_BUTTONS_WINDOWS_SUPPORTED = 5; //three standard buttons + XBUTTON1 + XBUTTON2.
128.8 +
128.9 UINT AwtToolkit::GetMouseKeyState()
128.10 {
128.11 static BOOL mbSwapped = ::GetSystemMetrics(SM_SWAPBUTTON);
128.12 @@ -2310,5 +2312,9 @@
128.13
128.14 JNIEXPORT jint JNICALL Java_sun_awt_windows_WToolkit_getNumberOfButtonsImpl
128.15 (JNIEnv *, jobject self) {
128.16 - return GetSystemMetrics(SM_CMOUSEBUTTONS);
128.17 + return AwtToolkit::GetNumberOfButtons();
128.18 }
128.19 +
128.20 +UINT AwtToolkit::GetNumberOfButtons() {
128.21 + return MOUSE_BUTTONS_WINDOWS_SUPPORTED;
128.22 +}
129.1 --- a/src/windows/native/sun/windows/awt_Toolkit.h Tue Oct 12 13:34:59 2010 -0400
129.2 +++ b/src/windows/native/sun/windows/awt_Toolkit.h Mon Oct 18 11:25:28 2010 -0400
129.3 @@ -185,6 +185,7 @@
129.4 BOOL IsDynamicLayoutActive();
129.5 BOOL areExtraMouseButtonsEnabled();
129.6 void setExtraMouseButtonsEnabled(BOOL enable);
129.7 + static UINT GetNumberOfButtons();
129.8
129.9 INLINE BOOL localPump() { return m_localPump; }
129.10 INLINE BOOL VerifyComponents() { return FALSE; } // TODO: Use new DebugHelper class to set this flag
130.1 --- a/test/ProblemList.txt Tue Oct 12 13:34:59 2010 -0400
130.2 +++ b/test/ProblemList.txt Mon Oct 18 11:25:28 2010 -0400
130.3 @@ -165,6 +165,12 @@
130.4 # very small tests and could greatly benefit from a samevm test run.
130.5 # So a large batch of beans tests are currently run with othervm mode.
130.6
130.7 +# Filed 6986807
130.8 +java/beans/Introspector/TestTypeResolver.java generic-all
130.9 +
130.10 +# Filed 6986813
130.11 +java/beans/Introspector/memory/Test4508780.java generic-all
130.12 +
130.13 # Linux, some kind of problems with X11 display
130.14 java/beans/PropertyChangeSupport/Test4682386.java generic-all
130.15 java/beans/PropertyChangeSupport/TestSynchronization.java generic-all
130.16 @@ -493,6 +499,9 @@
130.17
130.18 # jdk_security
130.19
130.20 +# Filed 6986868
130.21 +sun/security/tools/jarsigner/crl.sh generic-all
130.22 +
130.23 # Filed 6951285, not sure how often this fails, last was Linux 64bit Fedora 9
130.24 sun/security/krb5/auto/MaxRetries.java generic-all
130.25
130.26 @@ -689,10 +698,22 @@
130.27
130.28 # jdk_tools
130.29
130.30 +# Filed 6952105
130.31 +com/sun/jdi/SuspendThreadTest.java generic-all
130.32 +
130.33 +# Filed 6986875
130.34 +sun/tools/jps/jps-Vvml.sh generic-all
130.35 +
130.36 +# Filed 6979016
130.37 +sun/tools/jconsole/ResourceCheckTest.sh generic-all
130.38 +
130.39 ############################################################################
130.40
130.41 # jdk_util
130.42
130.43 +# Filed 6933803
130.44 +java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java generic-all
130.45 +
130.46 # Fails with assertion error on windows
130.47 # 11 separate stacktraces created... file reuse problem?
130.48 java/util/zip/ZipFile/ReadLongZipFileName.java generic-all
131.1 --- a/test/com/sun/security/sasl/ntlm/NTLMTest.java Tue Oct 12 13:34:59 2010 -0400
131.2 +++ b/test/com/sun/security/sasl/ntlm/NTLMTest.java Mon Oct 18 11:25:28 2010 -0400
131.3 @@ -31,8 +31,6 @@
131.4 import javax.security.auth.callback.*;
131.5 import java.util.*;
131.6
131.7 -import com.sun.security.ntlm.NTLMException;
131.8 -
131.9 public class NTLMTest {
131.10
131.11 private static final String MECH = "NTLM";
131.12 @@ -95,19 +93,13 @@
131.13 checkVersion("LM/NTLM", "LMv2");
131.14 throw new Exception("Should not succeed");
131.15 } catch (SaslException se) {
131.16 - NTLMException ne = (NTLMException)se.getCause();
131.17 - if (ne.errorCode() != NTLMException.AUTH_FAILED) {
131.18 - throw new Exception("Failed false");
131.19 - }
131.20 + // OK
131.21 }
131.22 try {
131.23 checkVersion("LMv2/NTLMv2", "LM");
131.24 throw new Exception("Should not succeed");
131.25 } catch (SaslException se) {
131.26 - NTLMException ne = (NTLMException)se.getCause();
131.27 - if (ne.errorCode() != NTLMException.AUTH_FAILED) {
131.28 - throw new Exception("Failed false");
131.29 - }
131.30 + // OK
131.31 }
131.32
131.33 }
132.1 --- a/test/com/sun/servicetag/JavaServiceTagTest.java Tue Oct 12 13:34:59 2010 -0400
132.2 +++ b/test/com/sun/servicetag/JavaServiceTagTest.java Mon Oct 18 11:25:28 2010 -0400
132.3 @@ -124,8 +124,9 @@
132.4 throw new RuntimeException("Unexpected platform_arch: " +
132.5 st.getPlatformArch());
132.6 }
132.7 + String vendor = System.getProperty("java.vendor");
132.8 if (!st.getProductVendor().
132.9 - equals("Sun Microsystems")) {
132.10 + equals(vendor)) {
132.11 throw new RuntimeException("Unexpected product_vendor: " +
132.12 st.getProductVendor());
132.13 }
133.1 --- a/test/com/sun/servicetag/JavaServiceTagTest1.java Tue Oct 12 13:34:59 2010 -0400
133.2 +++ b/test/com/sun/servicetag/JavaServiceTagTest1.java Mon Oct 18 11:25:28 2010 -0400
133.3 @@ -196,8 +196,10 @@
133.4 throw new RuntimeException("Unexpected platform_arch: " +
133.5 st.getPlatformArch());
133.6 }
133.7 +
133.8 + String vendor = System.getProperty("java.vendor");
133.9 if (!st.getProductVendor().
133.10 - equals("Sun Microsystems")) {
133.11 + equals(vendor)) {
133.12 throw new RuntimeException("Unexpected product_vendor: " +
133.13 st.getProductVendor());
133.14 }
134.1 --- a/test/com/sun/servicetag/Util.java Tue Oct 12 13:34:59 2010 -0400
134.2 +++ b/test/com/sun/servicetag/Util.java Mon Oct 18 11:25:28 2010 -0400
134.3 @@ -162,6 +162,8 @@
134.4 for (ServiceTag st : svcTags) {
134.5 ServiceTag st1 = stMap.get(st.getInstanceURN());
134.6 if (!matches(st, st1)) {
134.7 + System.err.println(st);
134.8 + System.err.println(st1);
134.9 throw new RuntimeException("ServiceTag in the registry " +
134.10 "does not match the one in the map");
134.11 }
135.1 --- a/test/com/sun/servicetag/environ.properties Tue Oct 12 13:34:59 2010 -0400
135.2 +++ b/test/com/sun/servicetag/environ.properties Mon Oct 18 11:25:28 2010 -0400
135.3 @@ -4,6 +4,6 @@
135.4 osVersion=5.10
135.5 osArchitecture=sparc
135.6 systemModel=Sun-Fire-V440
135.7 -systemManufacturer=Sun Microsystems
135.8 -cpuManufacturer=Sun Microsystems
135.9 +systemManufacturer=Oracle Corporation
135.10 +cpuManufacturer=Oracle Corporation
135.11 serialNumber=BEL078932
136.1 --- a/test/com/sun/servicetag/missing-environ-field.xml Tue Oct 12 13:34:59 2010 -0400
136.2 +++ b/test/com/sun/servicetag/missing-environ-field.xml Mon Oct 18 11:25:28 2010 -0400
136.3 @@ -19,7 +19,7 @@
136.4 <product_parent_urn>urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3</product_parent_urn>
136.5 <product_parent>Java Platform Standard Edition 6 (Java SE 6)</product_parent>
136.6 <product_defined_inst_id>id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc</product_defined_inst_id>
136.7 -<product_vendor>Sun Microsystems</product_vendor>
136.8 +<product_vendor>Oracle Corporation</product_vendor>
136.9 <platform_arch>sparc</platform_arch>
136.10 <timestamp>2007-11-12 06:15:11 GMT</timestamp>
136.11 <container>global</container>
136.12 @@ -34,7 +34,7 @@
136.13 <product_parent_urn>urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3</product_parent_urn>
136.14 <product_parent>Java Platform Standard Edition 6 (Java SE 6)</product_parent>
136.15 <product_defined_inst_id>id=1.6.0_05-b01 sparc,dir=/myjdk/solaris-i586</product_defined_inst_id>
136.16 -<product_vendor>Sun Microsystems</product_vendor>
136.17 +<product_vendor>Oracle Corporation</product_vendor>
136.18 <platform_arch>i386</platform_arch>
136.19 <timestamp>2007-11-12 06:15:11 GMT</timestamp>
136.20 <container>global</container>
137.1 --- a/test/com/sun/servicetag/newer-registry-version.xml Tue Oct 12 13:34:59 2010 -0400
137.2 +++ b/test/com/sun/servicetag/newer-registry-version.xml Mon Oct 18 11:25:28 2010 -0400
137.3 @@ -20,7 +20,7 @@
137.4 <product_parent_urn>urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3</product_parent_urn>
137.5 <product_parent>Java Platform Standard Edition 6 (Java SE 6)</product_parent>
137.6 <product_defined_inst_id>id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc</product_defined_inst_id>
137.7 -<product_vendor>Sun Microsystems</product_vendor>
137.8 +<product_vendor>Oracle Corporation</product_vendor>
137.9 <platform_arch>sparc</platform_arch>
137.10 <timestamp>2007-11-13 00:49:01 GMT</timestamp>
137.11 <container>global</container>
138.1 --- a/test/com/sun/servicetag/registration.xml Tue Oct 12 13:34:59 2010 -0400
138.2 +++ b/test/com/sun/servicetag/registration.xml Mon Oct 18 11:25:28 2010 -0400
138.3 @@ -7,8 +7,8 @@
138.4 <osVersion>5.10</osVersion>
138.5 <osArchitecture>sparc</osArchitecture>
138.6 <systemModel>Sun-Fire-V440</systemModel>
138.7 -<systemManufacturer>Sun Microsystems</systemManufacturer>
138.8 -<cpuManufacturer>Sun Microsystems</cpuManufacturer>
138.9 +<systemManufacturer>Oracle Corporation</systemManufacturer>
138.10 +<cpuManufacturer>Oracle Corporation</cpuManufacturer>
138.11 <serialNumber>BEL078932</serialNumber>
138.12 </environment>
138.13 <registry urn="urn:st:9543ffaa-a4f1-4f77-b2d1-f561922d4e4a" version="1.0">
138.14 @@ -20,7 +20,7 @@
138.15 <product_parent_urn>urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3</product_parent_urn>
138.16 <product_parent>Java Platform Standard Edition 6 (Java SE 6)</product_parent>
138.17 <product_defined_inst_id>id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc</product_defined_inst_id>
138.18 -<product_vendor>Sun Microsystems</product_vendor>
138.19 +<product_vendor>Oracle Corporation</product_vendor>
138.20 <platform_arch>sparc</platform_arch>
138.21 <timestamp>2007-11-13 00:49:01 GMT</timestamp>
138.22 <container>global</container>
138.23 @@ -35,7 +35,7 @@
138.24 <product_parent_urn>urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3</product_parent_urn>
138.25 <product_parent>Java Platform Standard Edition 6 (Java SE 6)</product_parent>
138.26 <product_defined_inst_id>id=1.6.0_05-b01 i386,dir=/myjdk/solaris-i586</product_defined_inst_id>
138.27 -<product_vendor>Sun Microsystems</product_vendor>
138.28 +<product_vendor>Oracle Corporation</product_vendor>
138.29 <platform_arch>i386</platform_arch>
138.30 <timestamp>2007-11-13 00:49:01 GMT</timestamp>
138.31 <container>global</container>
138.32 @@ -50,7 +50,7 @@
138.33 <product_parent_urn>urn:uuid:596ffcfa-63d5-11d7-9886-ac816a682f92</product_parent_urn>
138.34 <product_parent>Solaris Operating System</product_parent>
138.35 <product_defined_inst_id/>
138.36 -<product_vendor>Sun Microsystems</product_vendor>
138.37 +<product_vendor>Oracle Corporation</product_vendor>
138.38 <platform_arch>sparc</platform_arch>
138.39 <timestamp>2007-11-13 00:49:01 GMT</timestamp>
138.40 <container>global</container>
139.1 --- a/test/com/sun/servicetag/servicetag1.properties Tue Oct 12 13:34:59 2010 -0400
139.2 +++ b/test/com/sun/servicetag/servicetag1.properties Mon Oct 18 11:25:28 2010 -0400
139.3 @@ -5,7 +5,7 @@
139.4 product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3
139.5 product_parent=Java Platform Standard Edition 6 (Java SE 6)
139.6 product_defined_inst_id=id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc
139.7 -product_vendor=Sun Microsystems
139.8 +product_vendor=Oracle Corporation
139.9 platform_arch=sparc
139.10 timestamp=2007-11-12 05:19:40 GMT
139.11 container=global
140.1 --- a/test/com/sun/servicetag/servicetag2.properties Tue Oct 12 13:34:59 2010 -0400
140.2 +++ b/test/com/sun/servicetag/servicetag2.properties Mon Oct 18 11:25:28 2010 -0400
140.3 @@ -5,7 +5,7 @@
140.4 product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3
140.5 product_parent=Java Platform Standard Edition 6 (Java SE 6)
140.6 product_defined_inst_id=id=1.6.0_05-b01 i386,dir=/myjdk/solaris-i586
140.7 -product_vendor=Sun Microsystems
140.8 +product_vendor=Oracle Corporation
140.9 platform_arch=i386
140.10 timestamp=2007-11-12 06:12:21 GMT
140.11 container=global
141.1 --- a/test/com/sun/servicetag/servicetag3.properties Tue Oct 12 13:34:59 2010 -0400
141.2 +++ b/test/com/sun/servicetag/servicetag3.properties Mon Oct 18 11:25:28 2010 -0400
141.3 @@ -5,7 +5,7 @@
141.4 product_parent_urn=urn:uuid:596ffcfa-63d5-11d7-9886-ac816a682f92
141.5 product_parent=Solaris Operating System
141.6 product_defined_inst_id=
141.7 -product_vendor=Sun Microsystems
141.8 +product_vendor=Oracle Corporation
141.9 platform_arch=sparc
141.10 timestamp=2007-06-20 22:07:11 GMT
141.11 container=global
142.1 --- a/test/com/sun/servicetag/servicetag4.properties Tue Oct 12 13:34:59 2010 -0400
142.2 +++ b/test/com/sun/servicetag/servicetag4.properties Mon Oct 18 11:25:28 2010 -0400
142.3 @@ -5,7 +5,7 @@
142.4 product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3
142.5 product_parent=Java Platform Standard Edition 6 (Java SE 6)
142.6 product_defined_inst_id=id=1.6.0_05-b01 amd64,dir=/myjdk/linux-amd64
142.7 -product_vendor=Sun Microsystems
142.8 +product_vendor=Oracle Corporation
142.9 platform_arch=x64
142.10 timestamp=2007-12-12 05:19:40 GMT
142.11 container=global
143.1 --- a/test/com/sun/servicetag/servicetag5.properties Tue Oct 12 13:34:59 2010 -0400
143.2 +++ b/test/com/sun/servicetag/servicetag5.properties Mon Oct 18 11:25:28 2010 -0400
143.3 @@ -5,7 +5,7 @@
143.4 product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3
143.5 product_parent=Java Platform Standard Edition 6 (Java SE 6)
143.6 product_defined_inst_id=id=1.6.0_06-b06 i386,dir=/w/mchung/bundles/jdk1.6.0_05/jre
143.7 -product_vendor=Sun Microsystems
143.8 +product_vendor=Oracle Corporation
143.9 platform_arch=x86
143.10 timestamp=2007-11-29 17:59:42 GMT
143.11 container=global
144.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
144.2 +++ b/test/demo/zipfs/Basic.java Mon Oct 18 11:25:28 2010 -0400
144.3 @@ -0,0 +1,159 @@
144.4 +/*
144.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
144.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
144.7 + *
144.8 + * This code is free software; you can redistribute it and/or modify it
144.9 + * under the terms of the GNU General Public License version 2 only, as
144.10 + * published by the Free Software Foundation.
144.11 + *
144.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
144.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
144.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
144.15 + * version 2 for more details (a copy is included in the LICENSE file that
144.16 + * accompanied this code).
144.17 + *
144.18 + * You should have received a copy of the GNU General Public License version
144.19 + * 2 along with this work; if not, write to the Free Software Foundation,
144.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
144.21 + *
144.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
144.23 + * or visit www.oracle.com if you need additional information or have any
144.24 + * questions.
144.25 + */
144.26 +
144.27 +import java.nio.file.*;
144.28 +import java.nio.file.attribute.*;
144.29 +import java.nio.file.spi.FileSystemProvider;
144.30 +import java.util.*;
144.31 +import java.net.URI;
144.32 +import java.io.IOException;
144.33 +
144.34 +/**
144.35 + * Basic test for zip provider
144.36 + */
144.37 +
144.38 +public class Basic {
144.39 + public static void main(String[] args) throws Exception {
144.40 + Path zipfile = Paths.get(args[0]);
144.41 +
144.42 + // Test: zip should should be returned in provider list
144.43 + boolean found = false;
144.44 +
144.45 + for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
144.46 + if (provider.getScheme().equalsIgnoreCase("zip")) {
144.47 + found = true;
144.48 + break;
144.49 + }
144.50 + }
144.51 + if (!found)
144.52 + throw new RuntimeException("'zip' provider not installed");
144.53 +
144.54 + // Test: FileSystems#newFileSystem(FileRef)
144.55 + Map<String,?> env = new HashMap<String,Object>();
144.56 + FileSystems.newFileSystem(zipfile, env, null).close();
144.57 +
144.58 + // Test: FileSystems#newFileSystem(URI)
144.59 + URI uri = URI.create("zip" + zipfile.toUri().toString().substring(4));
144.60 + FileSystem fs = FileSystems.newFileSystem(uri, env, null);
144.61 +
144.62 + // Test: exercise toUri method
144.63 + String expected = uri.toString() + "#/foo";
144.64 + String actual = fs.getPath("/foo").toUri().toString();
144.65 + if (!actual.equals(expected)) {
144.66 + throw new RuntimeException("toUri returned '" + actual +
144.67 + "', expected '" + expected + "'");
144.68 + }
144.69 +
144.70 + // Test: exercise directory iterator and retrieval of basic attributes
144.71 + Files.walkFileTree(fs.getPath("/"), new FileTreePrinter());
144.72 +
144.73 + // Test: DirectoryStream
144.74 + found = false;
144.75 + DirectoryStream<Path> stream = fs.getPath("/").newDirectoryStream();
144.76 + try {
144.77 + for (Path entry: stream) {
144.78 + found = entry.toString().equals("/META-INF/");
144.79 + if (found) break;
144.80 + }
144.81 + } finally {
144.82 + stream.close();
144.83 + }
144.84 +
144.85 + if (!found)
144.86 + throw new RuntimeException("Expected file not found");
144.87 +
144.88 + // Test: copy file from zip file to current (scratch) directory
144.89 + Path source = fs.getPath("/META-INF/services/java.nio.file.spi.FileSystemProvider");
144.90 + if (source.exists()) {
144.91 + Path target = Paths.get(source.getName().toString());
144.92 + source.copyTo(target, StandardCopyOption.REPLACE_EXISTING);
144.93 + try {
144.94 + long s1 = Attributes.readBasicFileAttributes(source).size();
144.95 + long s2 = Attributes.readBasicFileAttributes(target).size();
144.96 + if (s2 != s1)
144.97 + throw new RuntimeException("target size != source size");
144.98 + } finally {
144.99 + target.delete();
144.100 + }
144.101 + }
144.102 +
144.103 + // Test: FileStore
144.104 + FileStore store = fs.getPath("/").getFileStore();
144.105 + if (!store.supportsFileAttributeView("basic"))
144.106 + throw new RuntimeException("BasicFileAttributeView should be supported");
144.107 +
144.108 + // Test: ClosedFileSystemException
144.109 + fs.close();
144.110 + if (fs.isOpen())
144.111 + throw new RuntimeException("FileSystem should be closed");
144.112 + try {
144.113 + fs.getPath("/missing").checkAccess(AccessMode.READ);
144.114 + } catch (ClosedFileSystemException x) { }
144.115 + }
144.116 +
144.117 + // FileVisitor that pretty prints a file tree
144.118 + static class FileTreePrinter extends SimpleFileVisitor<Path> {
144.119 + private int indent = 0;
144.120 +
144.121 + private void indent() {
144.122 + StringBuilder sb = new StringBuilder(indent);
144.123 + for (int i=0; i<indent; i++) sb.append(" ");
144.124 + System.out.print(sb);
144.125 + }
144.126 +
144.127 + @Override
144.128 + public FileVisitResult preVisitDirectory(Path dir,
144.129 + BasicFileAttributes attrs)
144.130 + {
144.131 + if (dir.getName() != null) {
144.132 + indent();
144.133 + System.out.println(dir.getName() + "/");
144.134 + indent++;
144.135 + }
144.136 + return FileVisitResult.CONTINUE;
144.137 + }
144.138 +
144.139 + @Override
144.140 + public FileVisitResult visitFile(Path file,
144.141 + BasicFileAttributes attrs)
144.142 + {
144.143 + indent();
144.144 + System.out.print(file.getName());
144.145 + if (attrs.isRegularFile())
144.146 + System.out.format(" (%d)", attrs.size());
144.147 + System.out.println();
144.148 + return FileVisitResult.CONTINUE;
144.149 + }
144.150 +
144.151 + @Override
144.152 + public FileVisitResult postVisitDirectory(Path dir, IOException exc)
144.153 + throws IOException
144.154 + {
144.155 + if (exc != null)
144.156 + super.postVisitDirectory(dir, exc);
144.157 + if (dir.getName() != null)
144.158 + indent--;
144.159 + return FileVisitResult.CONTINUE;
144.160 + }
144.161 + }
144.162 +}
145.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
145.2 +++ b/test/demo/zipfs/PathOps.java Mon Oct 18 11:25:28 2010 -0400
145.3 @@ -0,0 +1,416 @@
145.4 +/*
145.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
145.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
145.7 + *
145.8 + * This code is free software; you can redistribute it and/or modify it
145.9 + * under the terms of the GNU General Public License version 2 only, as
145.10 + * published by the Free Software Foundation.
145.11 + *
145.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
145.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
145.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
145.15 + * version 2 for more details (a copy is included in the LICENSE file that
145.16 + * accompanied this code).
145.17 + *
145.18 + * You should have received a copy of the GNU General Public License version
145.19 + * 2 along with this work; if not, write to the Free Software Foundation,
145.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
145.21 + *
145.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
145.23 + * or visit www.oracle.com if you need additional information or have any
145.24 + * questions.
145.25 + */
145.26 +
145.27 +import java.nio.file.*;
145.28 +import java.net.*;
145.29 +import java.util.*;
145.30 +import java.io.IOException;
145.31 +
145.32 +/**
145.33 + * Tests path operations for zip provider.
145.34 + */
145.35 +
145.36 +public class PathOps {
145.37 +
145.38 + static final java.io.PrintStream out = System.out;
145.39 + static FileSystem fs;
145.40 +
145.41 + private String input;
145.42 + private Path path;
145.43 + private Exception exc;
145.44 +
145.45 + private PathOps(String s) {
145.46 + out.println();
145.47 + input = s;
145.48 + try {
145.49 + path = fs.getPath(s);
145.50 + out.format("%s -> %s", s, path);
145.51 + } catch (Exception x) {
145.52 + exc = x;
145.53 + out.format("%s -> %s", s, x);
145.54 + }
145.55 + out.println();
145.56 + }
145.57 +
145.58 + Path path() {
145.59 + return path;
145.60 + }
145.61 +
145.62 + void fail() {
145.63 + throw new RuntimeException("PathOps failed");
145.64 + }
145.65 +
145.66 + void checkPath() {
145.67 + if (path == null) {
145.68 + throw new InternalError("path is null");
145.69 + }
145.70 + }
145.71 +
145.72 + void check(Object result, String expected) {
145.73 + out.format("\tExpected: %s\n", expected);
145.74 + out.format("\tActual: %s\n", result);
145.75 + if (result == null) {
145.76 + if (expected == null) return;
145.77 + } else {
145.78 + // compare string representations
145.79 + if (expected != null && result.toString().equals(expected.toString()))
145.80 + return;
145.81 + }
145.82 + fail();
145.83 + }
145.84 +
145.85 + void check(Object result, boolean expected) {
145.86 + check(result, Boolean.toString(expected));
145.87 + }
145.88 +
145.89 + PathOps root(String expected) {
145.90 + out.println("check root");
145.91 + checkPath();
145.92 + check(path.getRoot(), expected);
145.93 + return this;
145.94 + }
145.95 +
145.96 + PathOps parent(String expected) {
145.97 + out.println("check parent");
145.98 + checkPath();
145.99 + check(path.getParent(), expected);
145.100 + return this;
145.101 + }
145.102 +
145.103 + PathOps name(String expected) {
145.104 + out.println("check name");
145.105 + checkPath();
145.106 + check(path.getName(), expected);
145.107 + return this;
145.108 + }
145.109 +
145.110 + PathOps element(int index, String expected) {
145.111 + out.format("check element %d\n", index);
145.112 + checkPath();
145.113 + check(path.getName(index), expected);
145.114 + return this;
145.115 + }
145.116 +
145.117 + PathOps subpath(int startIndex, int endIndex, String expected) {
145.118 + out.format("test subpath(%d,%d)\n", startIndex, endIndex);
145.119 + checkPath();
145.120 + check(path.subpath(startIndex, endIndex), expected);
145.121 + return this;
145.122 + }
145.123 +
145.124 + PathOps starts(String prefix) {
145.125 + out.format("test startsWith with %s\n", prefix);
145.126 + checkPath();
145.127 + Path s = fs.getPath(prefix);
145.128 + check(path.startsWith(s), true);
145.129 + return this;
145.130 + }
145.131 +
145.132 + PathOps notStarts(String prefix) {
145.133 + out.format("test not startsWith with %s\n", prefix);
145.134 + checkPath();
145.135 + Path s = fs.getPath(prefix);
145.136 + check(path.startsWith(s), false);
145.137 + return this;
145.138 + }
145.139 +
145.140 + PathOps ends(String suffix) {
145.141 + out.format("test endsWith %s\n", suffix);
145.142 + checkPath();
145.143 + Path s = fs.getPath(suffix);
145.144 + check(path.endsWith(s), true);
145.145 + return this;
145.146 + }
145.147 +
145.148 + PathOps notEnds(String suffix) {
145.149 + out.format("test not endsWith %s\n", suffix);
145.150 + checkPath();
145.151 + Path s = fs.getPath(suffix);
145.152 + check(path.endsWith(s), false);
145.153 + return this;
145.154 + }
145.155 +
145.156 + PathOps absolute() {
145.157 + out.println("check path is absolute");
145.158 + checkPath();
145.159 + check(path.isAbsolute(), true);
145.160 + return this;
145.161 + }
145.162 +
145.163 + PathOps notAbsolute() {
145.164 + out.println("check path is not absolute");
145.165 + checkPath();
145.166 + check(path.isAbsolute(), false);
145.167 + return this;
145.168 + }
145.169 +
145.170 + PathOps resolve(String other, String expected) {
145.171 + out.format("test resolve %s\n", other);
145.172 + checkPath();
145.173 + check(path.resolve(other), expected);
145.174 + return this;
145.175 + }
145.176 +
145.177 + PathOps relativize(String other, String expected) {
145.178 + out.format("test relativize %s\n", other);
145.179 + checkPath();
145.180 + Path that = fs.getPath(other);
145.181 + check(path.relativize(that), expected);
145.182 + return this;
145.183 + }
145.184 +
145.185 + PathOps normalize(String expected) {
145.186 + out.println("check normalized path");
145.187 + checkPath();
145.188 + check(path.normalize(), expected);
145.189 + return this;
145.190 + }
145.191 +
145.192 + PathOps string(String expected) {
145.193 + out.println("check string representation");
145.194 + checkPath();
145.195 + check(path, expected);
145.196 + return this;
145.197 + }
145.198 +
145.199 + PathOps invalid() {
145.200 + if (!(exc instanceof InvalidPathException)) {
145.201 + out.println("InvalidPathException not thrown as expected");
145.202 + fail();
145.203 + }
145.204 + return this;
145.205 + }
145.206 +
145.207 + static PathOps test(String s) {
145.208 + return new PathOps(s);
145.209 + }
145.210 +
145.211 + // -- PathOpss --
145.212 +
145.213 + static void header(String s) {
145.214 + out.println();
145.215 + out.println();
145.216 + out.println("-- " + s + " --");
145.217 + }
145.218 +
145.219 + static void doPathOpTests() {
145.220 + header("Path operations");
145.221 +
145.222 + // all components
145.223 + test("/a/b/c")
145.224 + .root("/")
145.225 + .parent("/a/b")
145.226 + .name("c");
145.227 +
145.228 + // root component only
145.229 + test("/")
145.230 + .root("/")
145.231 + .parent(null)
145.232 + .name(null);
145.233 +
145.234 + // no root component
145.235 + test("a/b")
145.236 + .root(null)
145.237 + .parent("a")
145.238 + .name("b");
145.239 +
145.240 + // name component only
145.241 + test("foo")
145.242 + .root(null)
145.243 + .parent(null)
145.244 + .name("foo");
145.245 +
145.246 + // startsWith
145.247 + test("/")
145.248 + .starts("/")
145.249 + .notStarts("/foo");
145.250 + test("/foo")
145.251 + .starts("/")
145.252 + .starts("/foo")
145.253 + .notStarts("/f");
145.254 + test("/foo/bar")
145.255 + .starts("/")
145.256 + .starts("/foo")
145.257 + .starts("/foo/bar")
145.258 + .notStarts("/f")
145.259 + .notStarts("foo")
145.260 + .notStarts("foo/bar");
145.261 + test("foo")
145.262 + .starts("foo")
145.263 + .notStarts("f");
145.264 + test("foo/bar")
145.265 + .starts("foo")
145.266 + .starts("foo/bar")
145.267 + .notStarts("f")
145.268 + .notStarts("/foo")
145.269 + .notStarts("/foo/bar");
145.270 +
145.271 + // endsWith
145.272 + test("/")
145.273 + .ends("/")
145.274 + .notEnds("foo")
145.275 + .notEnds("/foo");
145.276 + test("/foo")
145.277 + .ends("foo")
145.278 + .ends("/foo")
145.279 + .notEnds("/");
145.280 + test("/foo/bar")
145.281 + .ends("bar")
145.282 + .ends("foo/bar")
145.283 + .ends("/foo/bar")
145.284 + .notEnds("/bar");
145.285 + test("foo")
145.286 + .ends("foo");
145.287 + test("foo/bar")
145.288 + .ends("bar")
145.289 + .ends("foo/bar");
145.290 +
145.291 + // elements
145.292 + test("a/b/c")
145.293 + .element(0,"a")
145.294 + .element(1,"b")
145.295 + .element(2,"c");
145.296 +
145.297 + // isAbsolute
145.298 + test("/")
145.299 + .absolute();
145.300 + test("/tmp")
145.301 + .absolute();
145.302 + test("tmp")
145.303 + .notAbsolute();
145.304 +
145.305 + // resolve
145.306 + test("/tmp")
145.307 + .resolve("foo", "/tmp/foo")
145.308 + .resolve("/foo", "/foo");
145.309 + test("tmp")
145.310 + .resolve("foo", "tmp/foo")
145.311 + .resolve("/foo", "/foo");
145.312 +
145.313 + // relativize
145.314 + test("/a/b/c")
145.315 + .relativize("/a/b/c", null)
145.316 + .relativize("/a/b/c/d/e", "d/e")
145.317 + .relativize("/a/x", "../../x");
145.318 +
145.319 + // normalize
145.320 + test("/")
145.321 + .normalize("/");
145.322 + test("foo")
145.323 + .normalize("foo");
145.324 + test("/foo")
145.325 + .normalize("/foo");
145.326 + test(".")
145.327 + .normalize(null);
145.328 + test("..")
145.329 + .normalize("..");
145.330 + test("/..")
145.331 + .normalize("/");
145.332 + test("/../..")
145.333 + .normalize("/");
145.334 + test("foo/.")
145.335 + .normalize("foo");
145.336 + test("./foo")
145.337 + .normalize("foo");
145.338 + test("foo/..")
145.339 + .normalize(null);
145.340 + test("../foo")
145.341 + .normalize("../foo");
145.342 + test("../../foo")
145.343 + .normalize("../../foo");
145.344 + test("foo/bar/..")
145.345 + .normalize("foo");
145.346 + test("foo/bar/gus/../..")
145.347 + .normalize("foo");
145.348 + test("/foo/bar/gus/../..")
145.349 + .normalize("/foo");
145.350 +
145.351 + // invalid
145.352 + test("foo\u0000bar")
145.353 + .invalid();
145.354 + test("\u0000foo")
145.355 + .invalid();
145.356 + test("bar\u0000")
145.357 + .invalid();
145.358 + test("//foo\u0000bar")
145.359 + .invalid();
145.360 + test("//\u0000foo")
145.361 + .invalid();
145.362 + test("//bar\u0000")
145.363 + .invalid();
145.364 +
145.365 + // normalization
145.366 + test("//foo//bar")
145.367 + .string("/foo/bar")
145.368 + .root("/")
145.369 + .parent("/foo")
145.370 + .name("bar");
145.371 + }
145.372 +
145.373 + static void npes() {
145.374 + header("NullPointerException");
145.375 +
145.376 + Path path = fs.getPath("foo");
145.377 +
145.378 + try {
145.379 + path.resolve((String)null);
145.380 + throw new RuntimeException("NullPointerException not thrown");
145.381 + } catch (NullPointerException npe) {
145.382 + }
145.383 +
145.384 + try {
145.385 + path.relativize(null);
145.386 + throw new RuntimeException("NullPointerException not thrown");
145.387 + } catch (NullPointerException npe) {
145.388 + }
145.389 +
145.390 + try {
145.391 + path.compareTo(null);
145.392 + throw new RuntimeException("NullPointerException not thrown");
145.393 + } catch (NullPointerException npe) {
145.394 + }
145.395 +
145.396 + try {
145.397 + path.startsWith(null);
145.398 + throw new RuntimeException("NullPointerException not thrown");
145.399 + } catch (NullPointerException npe) {
145.400 + }
145.401 +
145.402 + try {
145.403 + path.endsWith(null);
145.404 + throw new RuntimeException("NullPointerException not thrown");
145.405 + } catch (NullPointerException npe) {
145.406 + }
145.407 +
145.408 + }
145.409 +
145.410 + public static void main(String[] args) throws Throwable {
145.411 +
145.412 + Path zipfile = Paths.get(args[0]);
145.413 + Map<String,?> env = new HashMap<String,Object>();
145.414 + fs = FileSystems.newFileSystem(zipfile, env, null);
145.415 + npes();
145.416 + doPathOpTests();
145.417 + fs.close();
145.418 + }
145.419 +}
146.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
146.2 +++ b/test/demo/zipfs/ZipFSTester.java Mon Oct 18 11:25:28 2010 -0400
146.3 @@ -0,0 +1,633 @@
146.4 +/*
146.5 + * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
146.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
146.7 + *
146.8 + * This code is free software; you can redistribute it and/or modify it
146.9 + * under the terms of the GNU General Public License version 2 only, as
146.10 + * published by the Free Software Foundation.
146.11 + *
146.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
146.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
146.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
146.15 + * version 2 for more details (a copy is included in the LICENSE file that
146.16 + * accompanied this code).
146.17 + *
146.18 + * You should have received a copy of the GNU General Public License version
146.19 + * 2 along with this work; if not, write to the Free Software Foundation,
146.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
146.21 + *
146.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
146.23 + * or visit www.oracle.com if you need additional information or have any
146.24 + * questions.
146.25 + */
146.26 +
146.27 +import java.io.*;
146.28 +import java.nio.*;
146.29 +import java.nio.channels.*;
146.30 +import java.nio.file.*;
146.31 +import java.nio.file.attribute.*;
146.32 +import java.net.*;
146.33 +import java.util.*;
146.34 +
146.35 +import static java.nio.file.StandardOpenOption.*;
146.36 +import static java.nio.file.StandardCopyOption.*;
146.37 +
146.38 +/*
146.39 + * Tests various zipfs operations.
146.40 + */
146.41 +
146.42 +public class ZipFSTester {
146.43 +
146.44 + public static void main(String[] args) throws Throwable {
146.45 + FileSystem fs = null;
146.46 + try {
146.47 + fs = newZipFileSystem(Paths.get(args[0]), new HashMap<String, Object>());
146.48 + test(fs);
146.49 + test2(fs); // more tests
146.50 + } finally {
146.51 + if (fs != null)
146.52 + fs.close();
146.53 + }
146.54 + }
146.55 +
146.56 + static void test(FileSystem fs)
146.57 + throws Exception
146.58 + {
146.59 + Random rdm = new Random();
146.60 +
146.61 + // clone a fs and test on it
146.62 + Path tmpfsPath = getTempPath();
146.63 + Map<String, Object> env = new HashMap<String, Object>();
146.64 + env.put("createNew", true);
146.65 + FileSystem fs0 = newZipFileSystem(tmpfsPath, env);
146.66 + z2zcopy(fs, fs0, "/", 0);
146.67 + fs0.close(); // sync to file
146.68 +
146.69 + fs = newZipFileSystem(tmpfsPath, new HashMap<String, Object>());
146.70 +
146.71 + try {
146.72 + // prepare a src
146.73 + Path src = getTempPath();
146.74 + String tmpName = src.toString();
146.75 + OutputStream os = src.newOutputStream();
146.76 + byte[] bits = new byte[12345];
146.77 + rdm.nextBytes(bits);
146.78 + os.write(bits);
146.79 + os.close();
146.80 +
146.81 + // copyin
146.82 + Path dst = getPathWithParents(fs, tmpName);
146.83 + src.copyTo(dst);
146.84 + checkEqual(src, dst);
146.85 +
146.86 + // copy
146.87 + Path dst2 = getPathWithParents(fs, "/xyz" + rdm.nextInt(100) +
146.88 + "/efg" + rdm.nextInt(100) + "/foo.class");
146.89 + dst.copyTo(dst2);
146.90 + //dst.moveTo(dst2);
146.91 + checkEqual(src, dst2);
146.92 +
146.93 + // delete
146.94 + dst.delete();
146.95 + if (dst.exists())
146.96 + throw new RuntimeException("Failed!");
146.97 +
146.98 + // moveout
146.99 + Path dst3 = Paths.get(tmpName + "_Tmp");
146.100 + dst2.moveTo(dst3);
146.101 + checkEqual(src, dst3);
146.102 +
146.103 + // delete
146.104 + if (dst2.exists())
146.105 + throw new RuntimeException("Failed!");
146.106 + dst3.delete();
146.107 + if (dst3.exists())
146.108 + throw new RuntimeException("Failed!");
146.109 +
146.110 + // newInputStream on dir
146.111 + Path parent = dst2.getParent();
146.112 + try {
146.113 + parent.newInputStream();
146.114 + throw new RuntimeException("Failed");
146.115 + } catch (FileSystemException e) {
146.116 + e.printStackTrace(); // expected fse
146.117 + }
146.118 +
146.119 + // rmdirs
146.120 + try {
146.121 + rmdirs(parent);
146.122 + } catch (IOException x) {
146.123 + x.printStackTrace();
146.124 + }
146.125 +
146.126 + // newFileChannel() copy in, out and verify via fch
146.127 + fchCopy(src, dst); // in
146.128 + checkEqual(src, dst);
146.129 + Path tmp = Paths.get(tmpName + "_Tmp");
146.130 + fchCopy(dst, tmp); // out
146.131 + checkEqual(src, tmp);
146.132 + tmp.delete();
146.133 +
146.134 + // test channels
146.135 + channel(fs, dst);
146.136 + dst.delete();
146.137 + src.delete();
146.138 + } finally {
146.139 + if (fs != null)
146.140 + fs.close();
146.141 + if (tmpfsPath.exists())
146.142 + tmpfsPath.delete();
146.143 + }
146.144 + }
146.145 +
146.146 + static void test2(FileSystem fs) throws Exception {
146.147 +
146.148 + Path fs1Path = getTempPath();
146.149 + Path fs2Path = getTempPath();
146.150 + Path fs3Path = getTempPath();
146.151 +
146.152 + if (fs1Path.exists())
146.153 + fs1Path.delete();
146.154 + if (fs2Path.exists())
146.155 + fs2Path.delete();
146.156 + if (fs3Path.exists())
146.157 + fs3Path.delete();
146.158 +
146.159 + // create a new filesystem, copy everything from fs
146.160 + Map<String, Object> env = new HashMap<String, Object>();
146.161 + env.put("createNew", true);
146.162 + FileSystem fs0 = newZipFileSystem(fs1Path, env);
146.163 +
146.164 + final FileSystem fs2 = newZipFileSystem(fs2Path, env);
146.165 + final FileSystem fs3 = newZipFileSystem(fs3Path, env);
146.166 +
146.167 + System.out.println("copy src: fs -> fs0...");
146.168 + z2zcopy(fs, fs0, "/", 0); // copy fs -> fs1
146.169 + fs0.close(); // dump to file
146.170 +
146.171 + System.out.println("open fs0 as fs1");
146.172 + env = new HashMap<String, Object>();
146.173 + final FileSystem fs1 = newZipFileSystem(fs1Path, env);
146.174 +
146.175 + System.out.println("listing...");
146.176 + final ArrayList<String> files = new ArrayList<>();
146.177 + final ArrayList<String> dirs = new ArrayList<>();
146.178 + list(fs1.getPath("/"), files, dirs);
146.179 +
146.180 + Thread t0 = new Thread(new Runnable() {
146.181 + public void run() {
146.182 + List<String> list = new ArrayList<>(dirs);
146.183 + Collections.shuffle(list);
146.184 + for (String path : list) {
146.185 + try {
146.186 + z2zcopy(fs1, fs2, path, 0);
146.187 + } catch (Exception x) {
146.188 + x.printStackTrace();
146.189 + }
146.190 + }
146.191 + }
146.192 +
146.193 + });
146.194 +
146.195 + Thread t1 = new Thread(new Runnable() {
146.196 + public void run() {
146.197 + List<String> list = new ArrayList<>(dirs);
146.198 + Collections.shuffle(list);
146.199 + for (String path : list) {
146.200 + try {
146.201 + z2zcopy(fs1, fs2, path, 1);
146.202 + } catch (Exception x) {
146.203 + x.printStackTrace();
146.204 + }
146.205 + }
146.206 + }
146.207 +
146.208 + });
146.209 +
146.210 + Thread t2 = new Thread(new Runnable() {
146.211 + public void run() {
146.212 + List<String> list = new ArrayList<>(dirs);
146.213 + Collections.shuffle(list);
146.214 + for (String path : list) {
146.215 + try {
146.216 + z2zcopy(fs1, fs2, path, 2);
146.217 + } catch (Exception x) {
146.218 + x.printStackTrace();
146.219 + }
146.220 + }
146.221 + }
146.222 +
146.223 + });
146.224 +
146.225 + Thread t3 = new Thread(new Runnable() {
146.226 + public void run() {
146.227 + List<String> list = new ArrayList<>(files);
146.228 + Collections.shuffle(list);
146.229 + while (!list.isEmpty()) {
146.230 + Iterator<String> itr = list.iterator();
146.231 + while (itr.hasNext()) {
146.232 + String path = itr.next();
146.233 + try {
146.234 + if (fs2.getPath(path).exists()) {
146.235 + z2zmove(fs2, fs3, path);
146.236 + itr.remove();
146.237 + }
146.238 + } catch (FileAlreadyExistsException x){
146.239 + itr.remove();
146.240 + } catch (Exception x) {
146.241 + x.printStackTrace();
146.242 + }
146.243 + }
146.244 + }
146.245 + }
146.246 +
146.247 + });
146.248 +
146.249 + System.out.println("copying/removing...");
146.250 + t0.start(); t1.start(); t2.start(); t3.start();
146.251 + t0.join(); t1.join(); t2.join(); t3.join();
146.252 +
146.253 + System.out.println("closing: fs1, fs2");
146.254 + fs1.close();
146.255 + fs2.close();
146.256 +
146.257 + int failed = 0;
146.258 + System.out.println("checkEqual: fs vs fs3");
146.259 + for (String path : files) {
146.260 + try {
146.261 + checkEqual(fs.getPath(path), fs3.getPath(path));
146.262 + } catch (IOException x) {
146.263 + //x.printStackTrace();
146.264 + failed++;
146.265 + }
146.266 + }
146.267 + System.out.println("closing: fs3");
146.268 + fs3.close();
146.269 +
146.270 + System.out.println("opening: fs3 as fs4");
146.271 + FileSystem fs4 = newZipFileSystem(fs3Path, env);
146.272 +
146.273 +
146.274 + ArrayList<String> files2 = new ArrayList<>();
146.275 + ArrayList<String> dirs2 = new ArrayList<>();
146.276 + list(fs4.getPath("/"), files2, dirs2);
146.277 +
146.278 + System.out.println("checkEqual: fs vs fs4");
146.279 + for (String path : files2) {
146.280 + checkEqual(fs.getPath(path), fs4.getPath(path));
146.281 + }
146.282 + System.out.println("walking: fs4");
146.283 + walk(fs4.getPath("/"));
146.284 + System.out.println("closing: fs4");
146.285 + fs4.close();
146.286 +
146.287 + System.out.printf("failed=%d%n", failed);
146.288 +
146.289 + fs1Path.delete();
146.290 + fs2Path.delete();
146.291 + fs3Path.delete();
146.292 + }
146.293 +
146.294 + private static FileSystem newZipFileSystem(Path path, Map<String, ?> env)
146.295 + throws IOException
146.296 + {
146.297 + return FileSystems.newFileSystem(
146.298 + URI.create("zip" +
146.299 + path.toUri().toString().substring(4)),
146.300 + env,
146.301 + null);
146.302 + }
146.303 +
146.304 + private static Path getTempPath() throws IOException
146.305 + {
146.306 + File tmp = File.createTempFile("testzipfs_", "zip");
146.307 + tmp.delete(); // we need a clean path, no file
146.308 + return tmp.toPath();
146.309 + }
146.310 +
146.311 + private static void list(Path path, List<String> files, List<String> dirs )
146.312 + throws IOException
146.313 + {
146.314 + if (Attributes.readBasicFileAttributes(path).isDirectory()) {
146.315 + DirectoryStream<Path> ds = path.newDirectoryStream();
146.316 + for (Path child : ds)
146.317 + list(child, files, dirs);
146.318 + ds.close();
146.319 + dirs.add(path.toString());
146.320 + } else {
146.321 + files.add(path.toString());
146.322 + }
146.323 + }
146.324 +
146.325 + private static void z2zcopy(FileSystem src, FileSystem dst, String path,
146.326 + int method)
146.327 + throws IOException
146.328 + {
146.329 + Path srcPath = src.getPath(path);
146.330 + Path dstPath = dst.getPath(path);
146.331 +
146.332 + if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) {
146.333 + if (!dstPath.exists()) {
146.334 + try {
146.335 + mkdirs(dstPath);
146.336 + } catch (FileAlreadyExistsException x) {}
146.337 + }
146.338 + DirectoryStream<Path> ds = srcPath.newDirectoryStream();
146.339 + for (Path child : ds) {
146.340 + z2zcopy(src, dst,
146.341 + path + (path.endsWith("/")?"":"/") + child.getName(),
146.342 + method);
146.343 + }
146.344 + ds.close();
146.345 + } else {
146.346 + try {
146.347 + if (dstPath.exists())
146.348 + return;
146.349 + switch (method) {
146.350 + case 0:
146.351 + srcPath.copyTo(dstPath);
146.352 + break;
146.353 + case 1:
146.354 + chCopy(srcPath, dstPath);
146.355 + break;
146.356 + case 2:
146.357 + //fchCopy(srcPath, dstPath);
146.358 + streamCopy(srcPath, dstPath);
146.359 + break;
146.360 + }
146.361 + } catch (FileAlreadyExistsException x) {}
146.362 + }
146.363 + }
146.364 +
146.365 + private static void z2zmove(FileSystem src, FileSystem dst, String path)
146.366 + throws IOException
146.367 + {
146.368 + Path srcPath = src.getPath(path);
146.369 + Path dstPath = dst.getPath(path);
146.370 +
146.371 + if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) {
146.372 + if (!dstPath.exists())
146.373 + mkdirs(dstPath);
146.374 + DirectoryStream<Path> ds = srcPath.newDirectoryStream();
146.375 + for (Path child : ds) {
146.376 + z2zmove(src, dst,
146.377 + path + (path.endsWith("/")?"":"/") + child.getName());
146.378 + }
146.379 + ds.close();
146.380 + } else {
146.381 + //System.out.println("moving..." + path);
146.382 + Path parent = dstPath.getParent();
146.383 + if (parent != null && parent.notExists())
146.384 + mkdirs(parent);
146.385 + srcPath.moveTo(dstPath);
146.386 + }
146.387 + }
146.388 +
146.389 + private static void walk(Path path) throws IOException
146.390 + {
146.391 + Files.walkFileTree(
146.392 + path,
146.393 + new SimpleFileVisitor<Path>() {
146.394 + private int indent = 0;
146.395 + private void indent() {
146.396 + int n = 0;
146.397 + while (n++ < indent)
146.398 + System.out.printf(" ");
146.399 + }
146.400 +
146.401 + @Override
146.402 + public FileVisitResult visitFile(Path file,
146.403 + BasicFileAttributes attrs)
146.404 + {
146.405 + indent();
146.406 + System.out.printf("%s%n", file.getName().toString());
146.407 + return FileVisitResult.CONTINUE;
146.408 + }
146.409 +
146.410 + @Override
146.411 + public FileVisitResult preVisitDirectory(Path dir,
146.412 + BasicFileAttributes attrs)
146.413 + {
146.414 + indent();
146.415 + System.out.printf("[%s]%n", dir.toString());
146.416 + indent += 2;
146.417 + return FileVisitResult.CONTINUE;
146.418 + }
146.419 +
146.420 + @Override
146.421 + public FileVisitResult postVisitDirectory(Path dir,
146.422 + IOException ioe)
146.423 + throws IOException
146.424 + {
146.425 + indent -= 2;
146.426 + return FileVisitResult.CONTINUE;
146.427 + }
146.428 + });
146.429 + }
146.430 +
146.431 + private static void mkdirs(Path path) throws IOException {
146.432 + path = path.toAbsolutePath();
146.433 + Path parent = path.getParent();
146.434 + if (parent != null) {
146.435 + if (parent.notExists())
146.436 + mkdirs(parent);
146.437 + }
146.438 + path.createDirectory();
146.439 + }
146.440 +
146.441 + private static void rmdirs(Path path) throws IOException {
146.442 + while (path != null && path.getNameCount() != 0) {
146.443 + path.delete();
146.444 + path = path.getParent();
146.445 + }
146.446 + }
146.447 +
146.448 + // check the content of two paths are equal
146.449 + private static void checkEqual(Path src, Path dst) throws IOException
146.450 + {
146.451 + //System.out.printf("checking <%s> vs <%s>...%n",
146.452 + // src.toString(), dst.toString());
146.453 +
146.454 + //streams
146.455 + InputStream isSrc = src.newInputStream();
146.456 + InputStream isDst = dst.newInputStream();
146.457 + byte[] bufSrc = new byte[8192];
146.458 + byte[] bufDst = new byte[8192];
146.459 +
146.460 + try {
146.461 + int nSrc = 0;
146.462 + while ((nSrc = isSrc.read(bufSrc)) != -1) {
146.463 + int nDst = 0;
146.464 + while (nDst < nSrc) {
146.465 + int n = isDst.read(bufDst, nDst, nSrc - nDst);
146.466 + if (n == -1) {
146.467 + System.out.printf("checking <%s> vs <%s>...%n",
146.468 + src.toString(), dst.toString());
146.469 + throw new RuntimeException("CHECK FAILED!");
146.470 + }
146.471 + nDst += n;
146.472 + }
146.473 + while (--nSrc >= 0) {
146.474 + if (bufSrc[nSrc] != bufDst[nSrc]) {
146.475 + System.out.printf("checking <%s> vs <%s>...%n",
146.476 + src.toString(), dst.toString());
146.477 + throw new RuntimeException("CHECK FAILED!");
146.478 + }
146.479 + nSrc--;
146.480 + }
146.481 + }
146.482 + } finally {
146.483 + isSrc.close();
146.484 + isDst.close();
146.485 + }
146.486 +
146.487 + // channels
146.488 + SeekableByteChannel chSrc = src.newByteChannel();
146.489 + SeekableByteChannel chDst = dst.newByteChannel();
146.490 + if (chSrc.size() != chDst.size()) {
146.491 + System.out.printf("src[%s].size=%d, dst[%s].size=%d%n",
146.492 + chSrc.toString(), chSrc.size(),
146.493 + chDst.toString(), chDst.size());
146.494 + throw new RuntimeException("CHECK FAILED!");
146.495 + }
146.496 + ByteBuffer bbSrc = ByteBuffer.allocate(8192);
146.497 + ByteBuffer bbDst = ByteBuffer.allocate(8192);
146.498 +
146.499 + try {
146.500 + int nSrc = 0;
146.501 + while ((nSrc = chSrc.read(bbSrc)) != -1) {
146.502 + int nDst = chDst.read(bbDst);
146.503 + if (nSrc != nDst) {
146.504 + System.out.printf("checking <%s> vs <%s>...%n",
146.505 + src.toString(), dst.toString());
146.506 + throw new RuntimeException("CHECK FAILED!");
146.507 + }
146.508 + while (--nSrc >= 0) {
146.509 + if (bbSrc.get(nSrc) != bbDst.get(nSrc)) {
146.510 + System.out.printf("checking <%s> vs <%s>...%n",
146.511 + src.toString(), dst.toString());
146.512 + throw new RuntimeException("CHECK FAILED!");
146.513 + }
146.514 + nSrc--;
146.515 + }
146.516 + bbSrc.flip();
146.517 + bbDst.flip();
146.518 + }
146.519 + } catch (IOException x) {
146.520 + x.printStackTrace();
146.521 + } finally {
146.522 + chSrc.close();
146.523 + chDst.close();
146.524 + }
146.525 + }
146.526 +
146.527 + private static void fchCopy(Path src, Path dst) throws IOException
146.528 + {
146.529 + Set<OpenOption> read = new HashSet<>();
146.530 + read.add(READ);
146.531 + Set<OpenOption> openwrite = new HashSet<>();
146.532 + openwrite.add(CREATE_NEW);
146.533 + openwrite.add(WRITE);
146.534 +
146.535 + FileChannel srcFc = src.getFileSystem()
146.536 + .provider()
146.537 + .newFileChannel(src, read);
146.538 + FileChannel dstFc = dst.getFileSystem()
146.539 + .provider()
146.540 + .newFileChannel(dst, openwrite);
146.541 +
146.542 + try {
146.543 + ByteBuffer bb = ByteBuffer.allocate(8192);
146.544 + while (srcFc.read(bb) >= 0) {
146.545 + bb.flip();
146.546 + dstFc.write(bb);
146.547 + bb.clear();
146.548 + }
146.549 + } finally {
146.550 + srcFc.close();
146.551 + dstFc.close();
146.552 + }
146.553 + }
146.554 +
146.555 + private static void chCopy(Path src, Path dst) throws IOException
146.556 + {
146.557 + Set<OpenOption> read = new HashSet<>();
146.558 + read.add(READ);
146.559 + Set<OpenOption> openwrite = new HashSet<>();
146.560 + openwrite.add(CREATE_NEW);
146.561 + openwrite.add(WRITE);
146.562 +
146.563 + SeekableByteChannel srcCh = src.newByteChannel(read);
146.564 + SeekableByteChannel dstCh = dst.newByteChannel(openwrite);
146.565 +
146.566 + try {
146.567 + ByteBuffer bb = ByteBuffer.allocate(8192);
146.568 + while (srcCh.read(bb) >= 0) {
146.569 + bb.flip();
146.570 + dstCh.write(bb);
146.571 + bb.clear();
146.572 + }
146.573 + } finally {
146.574 + srcCh.close();
146.575 + dstCh.close();
146.576 + }
146.577 + }
146.578 +
146.579 + private static void streamCopy(Path src, Path dst) throws IOException
146.580 + {
146.581 + InputStream isSrc = src.newInputStream();
146.582 + OutputStream osDst = dst.newOutputStream();
146.583 + byte[] buf = new byte[8192];
146.584 + try {
146.585 + int n = 0;
146.586 + while ((n = isSrc.read(buf)) != -1) {
146.587 + osDst.write(buf, 0, n);
146.588 + }
146.589 + } finally {
146.590 + isSrc.close();
146.591 + osDst.close();
146.592 + }
146.593 + }
146.594 +
146.595 + static void channel(FileSystem fs, Path path)
146.596 + throws Exception
146.597 + {
146.598 + System.out.println("test ByteChannel...");
146.599 + SeekableByteChannel sbc = path.newByteChannel();
146.600 + Set<OpenOption> read = new HashSet<>();
146.601 + read.add(READ);
146.602 + System.out.printf(" sbc[0]: pos=%d, size=%d%n", sbc.position(), sbc.size());
146.603 + ByteBuffer bb = ByteBuffer.allocate((int)sbc.size());
146.604 + int n = sbc.read(bb);
146.605 + System.out.printf(" sbc[1]: read=%d, pos=%d, size=%d%n",
146.606 + n, sbc.position(), sbc.size());
146.607 + ByteBuffer bb2 = ByteBuffer.allocate((int)sbc.size());
146.608 + int N = 120;
146.609 + sbc.close();
146.610 +
146.611 + // sbc.position(pos) is not supported in current version
146.612 + // try the FileChannel
146.613 + sbc = fs.provider().newFileChannel(path, read);
146.614 + sbc.position(N);
146.615 + System.out.printf(" sbc[2]: pos=%d, size=%d%n",
146.616 + sbc.position(), sbc.size());
146.617 + bb2.limit(100);
146.618 + n = sbc.read(bb2);
146.619 + System.out.printf(" sbc[3]: read=%d, pos=%d, size=%d%n",
146.620 + n, sbc.position(), sbc.size());
146.621 + System.out.printf(" sbc[4]: bb[%d]=%d, bb1[0]=%d%n",
146.622 + N, bb.get(N) & 0xff, bb2.get(0) & 0xff);
146.623 + sbc.close();
146.624 + }
146.625 +
146.626 + // create parents if does not exist
146.627 + static Path getPathWithParents(FileSystem fs, String name)
146.628 + throws Exception
146.629 + {
146.630 + Path path = fs.getPath(name);
146.631 + Path parent = path.getParent();
146.632 + if (parent != null && parent.notExists())
146.633 + mkdirs(parent);
146.634 + return path;
146.635 + }
146.636 +}
147.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
147.2 +++ b/test/demo/zipfs/basic.sh Mon Oct 18 11:25:28 2010 -0400
147.3 @@ -0,0 +1,73 @@
147.4 +#
147.5 +# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
147.6 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
147.7 +#
147.8 +# This code is free software; you can redistribute it and/or modify it
147.9 +# under the terms of the GNU General Public License version 2 only, as
147.10 +# published by the Free Software Foundation.
147.11 +#
147.12 +# This code is distributed in the hope that it will be useful, but WITHOUT
147.13 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
147.14 +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
147.15 +# version 2 for more details (a copy is included in the LICENSE file that
147.16 +# accompanied this code).
147.17 +#
147.18 +# You should have received a copy of the GNU General Public License version
147.19 +# 2 along with this work; if not, write to the Free Software Foundation,
147.20 +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
147.21 +#
147.22 +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
147.23 +# or visit www.oracle.com if you need additional information or have any
147.24 +# questions.
147.25 +#
147.26 +# @test
147.27 +# @bug 6990846
147.28 +# @summary Test ZipFileSystem demo
147.29 +# @build Basic PathOps ZipFSTester
147.30 +# @run shell basic.sh
147.31 +
147.32 +if [ -z "${TESTJAVA}" ]; then
147.33 + echo "Test must be run with jtreg"
147.34 + exit 0
147.35 +fi
147.36 +
147.37 +ZIPFS="${TESTJAVA}/demo/nio/zipfs/zipfs.jar"
147.38 +if [ ! -r "${ZIPFS}" ]; then
147.39 + echo "${ZIPFS} not found"
147.40 + exit 0
147.41 +fi
147.42 +
147.43 +OS=`uname -s`
147.44 +case "$OS" in
147.45 + Windows_* )
147.46 + CLASSPATH="${TESTCLASSES};${ZIPFS}"
147.47 + ;;
147.48 + * )
147.49 + CLASSPATH="${TESTCLASSES}:${ZIPFS}"
147.50 + ;;
147.51 +esac
147.52 +export CLASSPATH
147.53 +
147.54 +failures=0
147.55 +
147.56 +go() {
147.57 + echo ""
147.58 + ${TESTJAVA}/bin/java $1 $2 $3 2>&1
147.59 + if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
147.60 +}
147.61 +
147.62 +# Run the tests
147.63 +
147.64 +go Basic "${ZIPFS}"
147.65 +go PathOps "${ZIPFS}"
147.66 +go ZipFSTester "${ZIPFS}"
147.67 +
147.68 +#
147.69 +# Results
147.70 +#
147.71 +
147.72 +if [ $failures -gt 0 ];
147.73 +then echo "$failures tests failed";
147.74 +else echo "All tests passed";
147.75 +fi
147.76 +exit $failures
148.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
148.2 +++ b/test/java/awt/Focus/FocusOwnerFrameOnClick/FocusOwnerFrameOnClick.java Mon Oct 18 11:25:28 2010 -0400
148.3 @@ -0,0 +1,125 @@
148.4 +/*
148.5 + * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
148.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
148.7 + *
148.8 + * This code is free software; you can redistribute it and/or modify it
148.9 + * under the terms of the GNU General Public License version 2 only, as
148.10 + * published by the Free Software Foundation. Oracle designates this
148.11 + * particular file as subject to the "Classpath" exception as provided
148.12 + * by Oracle in the LICENSE file that accompanied this code.
148.13 + *
148.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
148.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
148.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
148.17 + * version 2 for more details (a copy is included in the LICENSE file that
148.18 + * accompanied this code).
148.19 + *
148.20 + * You should have received a copy of the GNU General Public License version
148.21 + * 2 along with this work; if not, write to the Free Software Foundation,
148.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
148.23 + *
148.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
148.25 + * or visit www.oracle.com if you need additional information or have any
148.26 + * questions.
148.27 + */
148.28 +
148.29 +/*
148.30 + @test FocusOwnerFrameOnClick.java %W% %E%
148.31 + @bug 6886678
148.32 + @summary Tests that clicking an owner frame switches focus from its owned window.
148.33 + @author Anton Tarasov: area=awt.focus
148.34 + @library ../../regtesthelpers
148.35 + @build Util
148.36 + @run main FocusOwnerFrameOnClick
148.37 +*/
148.38 +
148.39 +import java.awt.*;
148.40 +import java.awt.event.*;
148.41 +import java.applet.Applet;
148.42 +import java.util.concurrent.atomic.AtomicBoolean;
148.43 +import java.lang.reflect.InvocationTargetException;
148.44 +import test.java.awt.regtesthelpers.Util;
148.45 +
148.46 +public class FocusOwnerFrameOnClick extends Applet {
148.47 + Robot robot;
148.48 + Frame frame = new Frame("Frame");
148.49 + Window window = new Window(frame);
148.50 + Button fButton = new Button("fButton");
148.51 + Button wButton = new Button("wButton");
148.52 +
148.53 + AtomicBoolean focused = new AtomicBoolean(false);
148.54 +
148.55 + public static void main(String[] args) {
148.56 + FocusOwnerFrameOnClick app = new FocusOwnerFrameOnClick();
148.57 + app.init();
148.58 + app.start();
148.59 + }
148.60 +
148.61 + public void init() {
148.62 + robot = Util.createRobot();
148.63 +
148.64 + frame.setLayout(new FlowLayout());
148.65 + frame.setSize(200, 200);
148.66 + frame.add(fButton);
148.67 +
148.68 + window.setLocation(300, 0);
148.69 + window.add(wButton);
148.70 + window.pack();
148.71 + }
148.72 +
148.73 + public void start() {
148.74 + frame.setVisible(true);
148.75 + Util.waitForIdle(robot);
148.76 +
148.77 + window.setVisible(true);
148.78 + Util.waitForIdle(robot);
148.79 +
148.80 + if (!wButton.hasFocus()) {
148.81 + if (!Util.trackFocusGained(wButton, new Runnable() {
148.82 + public void run() {
148.83 + Util.clickOnComp(wButton, robot);
148.84 + }
148.85 + }, 2000, false))
148.86 + {
148.87 + throw new TestErrorException("wButton didn't gain focus on showing");
148.88 + }
148.89 + }
148.90 +
148.91 + Runnable clickAction = new Runnable() {
148.92 + public void run() {
148.93 + Point loc = fButton.getLocationOnScreen();
148.94 + Dimension dim = fButton.getSize();
148.95 +
148.96 + robot.mouseMove(loc.x, loc.y + dim.height + 20);
148.97 + robot.delay(50);
148.98 + robot.mousePress(InputEvent.BUTTON1_MASK);
148.99 + robot.delay(50);
148.100 + robot.mouseRelease(InputEvent.BUTTON1_MASK);
148.101 + }
148.102 + };
148.103 +
148.104 + if (!Util.trackWindowGainedFocus(frame, clickAction, 2000, true)) {
148.105 + throw new TestFailedException("The frame wasn't focused on click");
148.106 + }
148.107 +
148.108 + System.out.println("Test passed.");
148.109 + }
148.110 +}
148.111 +
148.112 +/**
148.113 + * Thrown when the behavior being verified is found wrong.
148.114 + */
148.115 +class TestFailedException extends RuntimeException {
148.116 + TestFailedException(String msg) {
148.117 + super("Test failed: " + msg);
148.118 + }
148.119 +}
148.120 +
148.121 +/**
148.122 + * Thrown when an error not related to the behavior being verified is encountered.
148.123 + */
148.124 +class TestErrorException extends RuntimeException {
148.125 + TestErrorException(String msg) {
148.126 + super("Unexpected error: " + msg);
148.127 + }
148.128 +}
149.1 --- a/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java Tue Oct 12 13:34:59 2010 -0400
149.2 +++ b/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java Mon Oct 18 11:25:28 2010 -0400
149.3 @@ -21,16 +21,15 @@
149.4 static final int SHIFT = 1;
149.5 static final int CTRL = 2;
149.6 static final int ALT = 3;
149.7 - static CheckingModifierAdapter adapterTest1;
149.8 - static CheckingModifierAdapter adapterTest2;
149.9 - static CheckingModifierAdapter adapterTest3;
149.10 - static CheckingModifierAdapter adapterTest4;
149.11 + static CheckingModifierAdapterExtra adapterTest1;
149.12 + static CheckingModifierAdapterExtra adapterTest2;
149.13 + static CheckingModifierAdapterExtra adapterTest3;
149.14 + static CheckingModifierAdapterExtra adapterTest4;
149.15
149.16 static boolean debug = true; //dump all errors (debug) or throw first(under jtreg) exception
149.17 static boolean autorun = false; //use robot or manual run
149.18 static int testModifier = NONE;
149.19
149.20 - static int [] mouseButtons;
149.21 static int [] mouseButtonDownMasks;
149.22
149.23 //an arrays representing a modifiersEx of extra mouse buttons while using ALT/CTRL/SHIFT or none of them
149.24 @@ -39,7 +38,6 @@
149.25 static int [] modifiersExStandardCTRL;
149.26 static int [] modifiersExStandardALT;
149.27
149.28 - // final static int [] mouseButtons = new int [] {MouseEvent.BUTTON1_MASK, MouseEvent.BUTTON2_MASK, MouseEvent.BUTTON3_MASK};
149.29 // BUTTON1, 2, 3 press-release.
149.30 final static int modifiersStandard = 0; //InputEvent.BUTTON_DOWN_MASK;
149.31
149.32 @@ -56,7 +54,7 @@
149.33
149.34 if (modifiersEx != curStandardExModifiers[index]){
149.35 // System.out.println(">>>>>>>>>>>>>>> Pressed. modifiersEx "+modifiersEx +" : "+!= curStandardExModifiers");
149.36 - MessageLogger.reportError("Test failed : Pressed. modifiersEx != curStandardExModifiers");
149.37 + MessageLogger.reportError("Test failed : Pressed. modifiersEx != curStandardExModifiers. Got: " + modifiersEx + " , Expected: " + curStandardExModifiers[index]);
149.38 }
149.39
149.40 //check event.paramString() output
149.41 @@ -168,7 +166,7 @@
149.42 }
149.43
149.44 if (modifiersEx != curStandardExModifiers[index]){
149.45 - MessageLogger.reportError("Test failed : Released. modifiersEx != curStandardExModifiers");
149.46 + MessageLogger.reportError("Test failed : Released. modifiersEx != curStandardExModifiers. Got: " + modifiersEx + " , Expected: " + curStandardExModifiers[index]);
149.47 }
149.48
149.49 //check event.paramString() output
149.50 @@ -191,7 +189,7 @@
149.51 }
149.52
149.53 if (modifiersEx != curStandardExModifiers[index]){
149.54 - MessageLogger.reportError("Test failed : Clicked. modifiersEx != curStandardExModifiers");
149.55 + MessageLogger.reportError("Test failed : Clicked. modifiersEx != curStandardExModifiers. Got: " + modifiersEx + " , Expected: " + curStandardExModifiers[index]);
149.56 }
149.57
149.58 //check event.paramString() output
149.59 @@ -275,11 +273,11 @@
149.60 this.addMouseListener(adapterTest1);
149.61 robot.delay(1000);
149.62 robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
149.63 - for (int i = 3; i< mouseButtons.length; i++){
149.64 - System.out.println("testNONE() => " +mouseButtons[i] );
149.65 - robot.mousePress(mouseButtons[i]);
149.66 + for (int i = 3; i< mouseButtonDownMasks.length; i++){
149.67 + System.out.println("testNONE() => " +mouseButtonDownMasks[i] );
149.68 + robot.mousePress(mouseButtonDownMasks[i]);
149.69 robot.delay(100);
149.70 - robot.mouseRelease(mouseButtons[i]);
149.71 + robot.mouseRelease(mouseButtonDownMasks[i]);
149.72 }
149.73 robot.delay(1000);
149.74 this.removeMouseListener(adapterTest1);
149.75 @@ -289,12 +287,12 @@
149.76 this.addMouseListener(adapterTest2);
149.77 robot.delay(1000);
149.78 robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
149.79 - for (int i = 3; i< mouseButtons.length; i++){
149.80 + for (int i = 3; i< mouseButtonDownMasks.length; i++){
149.81 robot.keyPress(KeyEvent.VK_SHIFT);
149.82 - System.out.println("testSHIFT() => " +mouseButtons[i] );
149.83 - robot.mousePress(mouseButtons[i]);
149.84 + System.out.println("testSHIFT() => " +mouseButtonDownMasks[i] );
149.85 + robot.mousePress(mouseButtonDownMasks[i]);
149.86 robot.delay(100);
149.87 - robot.mouseRelease(mouseButtons[i]);
149.88 + robot.mouseRelease(mouseButtonDownMasks[i]);
149.89 robot.keyRelease(KeyEvent.VK_SHIFT);
149.90 }
149.91 robot.delay(1000);
149.92 @@ -305,12 +303,12 @@
149.93 this.addMouseListener(adapterTest3);
149.94 robot.delay(1000);
149.95 robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
149.96 - for (int i = 3; i< mouseButtons.length; i++){
149.97 + for (int i = 3; i< mouseButtonDownMasks.length; i++){
149.98 robot.keyPress(KeyEvent.VK_CONTROL);
149.99 - System.out.println("testCTRL() => " +mouseButtons[i] );
149.100 - robot.mousePress(mouseButtons[i]);
149.101 + System.out.println("testCTRL() => " +mouseButtonDownMasks[i] );
149.102 + robot.mousePress(mouseButtonDownMasks[i]);
149.103 robot.delay(100);
149.104 - robot.mouseRelease(mouseButtons[i]);
149.105 + robot.mouseRelease(mouseButtonDownMasks[i]);
149.106 robot.keyRelease(KeyEvent.VK_CONTROL);
149.107 }
149.108 robot.delay(1000);
149.109 @@ -321,12 +319,12 @@
149.110 this.addMouseListener(adapterTest4);
149.111 robot.delay(1000);
149.112 robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
149.113 - for (int i = 3; i< mouseButtons.length; i++){
149.114 + for (int i = 3; i< mouseButtonDownMasks.length; i++){
149.115 robot.keyPress(KeyEvent.VK_ALT);
149.116 - System.out.println("testALT() => " +mouseButtons[i] );
149.117 - robot.mousePress(mouseButtons[i]);
149.118 + System.out.println("testALT() => " +mouseButtonDownMasks[i] );
149.119 + robot.mousePress(mouseButtonDownMasks[i]);
149.120 robot.delay(100);
149.121 - robot.mouseRelease(mouseButtons[i]);
149.122 + robot.mouseRelease(mouseButtonDownMasks[i]);
149.123 robot.keyRelease(KeyEvent.VK_ALT);
149.124 }
149.125 robot.delay(1000);
149.126 @@ -368,52 +366,52 @@
149.127 }
149.128
149.129 public static void initAdapters(){
149.130 - adapterTest1 = new CheckingModifierAdapter(NONE);
149.131 - adapterTest2 = new CheckingModifierAdapter(SHIFT);
149.132 - adapterTest3 = new CheckingModifierAdapter(CTRL);
149.133 - adapterTest4 = new CheckingModifierAdapter(ALT);
149.134 + adapterTest1 = new CheckingModifierAdapterExtra(NONE);
149.135 + adapterTest2 = new CheckingModifierAdapterExtra(SHIFT);
149.136 + adapterTest3 = new CheckingModifierAdapterExtra(CTRL);
149.137 + adapterTest4 = new CheckingModifierAdapterExtra(ALT);
149.138 }
149.139
149.140 public static void initVars(){
149.141 - int [] tmp = new int [MouseInfo.getNumberOfButtons()];
149.142 - for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
149.143 - tmp[i] = InputEvent.getMaskForButton(i+1);
149.144 - // System.out.println("TEST: "+tmp[i]);
149.145 + //Init the array of the mouse button masks. It will be used for generating mouse events.
149.146 + mouseButtonDownMasks = new int [MouseInfo.getNumberOfButtons()];
149.147 + for (int i = 0; i < mouseButtonDownMasks.length; i++){
149.148 + mouseButtonDownMasks[i] = InputEvent.getMaskForButton(i+1);
149.149 + System.out.println("MouseArray [i] == "+mouseButtonDownMasks[i]);
149.150 }
149.151
149.152 - mouseButtons = Arrays.copyOf(tmp, tmp.length);
149.153 -
149.154 - for (int i = 0; i < mouseButtons.length; i++){
149.155 - System.out.println("MouseArray [i] == "+mouseButtons[i]);
149.156 - }
149.157 -
149.158 - mouseButtonDownMasks = Arrays.copyOf(tmp, tmp.length);
149.159 -
149.160 // So we need to get the number of extra buttons on the mouse: "MouseInfo.getNumberOfButtons() - 3"
149.161 // and multyply on 3 because each button will generate three events : PRESS, RELEASE and CLICK.
149.162 - tmp = new int [(MouseInfo.getNumberOfButtons()-3)*3];
149.163 + int [] tmp = new int [(MouseInfo.getNumberOfButtons()-3)*3];
149.164 +
149.165 + //Fill array of expected results for the case when mouse buttons are only used (no-modifier keys)
149.166 Arrays.fill(tmp, 0);
149.167 -
149.168 for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
149.169 tmp[i] = mouseButtonDownMasks[j];
149.170 }
149.171 modifiersExStandard = Arrays.copyOf(tmp, tmp.length);
149.172
149.173 + //Fill array of expected results for the case when mouse buttons are only used with SHIFT modifier key
149.174 Arrays.fill(tmp, InputEvent.SHIFT_DOWN_MASK);
149.175 - for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){
149.176 - tmp[i] = tmp[j] | mouseButtonDownMasks[j];
149.177 + for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
149.178 + System.out.println("modifiersExStandardSHIFT FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]);
149.179 + tmp[i] = tmp[i] | mouseButtonDownMasks[j];
149.180 }
149.181 modifiersExStandardSHIFT = Arrays.copyOf(tmp, tmp.length);
149.182
149.183 + //Fill array of expected results for the case when mouse buttons are only used with CTRL modifier key
149.184 Arrays.fill(tmp, InputEvent.CTRL_DOWN_MASK);
149.185 - for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){
149.186 - tmp[i] = tmp[j] | mouseButtonDownMasks[j];
149.187 + for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
149.188 + System.out.println("modifiersExStandardCTRL FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]);
149.189 + tmp[i] = tmp[i] | mouseButtonDownMasks[j];
149.190 }
149.191 modifiersExStandardCTRL = Arrays.copyOf(tmp, tmp.length);
149.192
149.193 + //Fill array of expected results for the case when mouse buttons are only used with ALT modifier key
149.194 Arrays.fill(tmp, InputEvent.ALT_DOWN_MASK);
149.195 - for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){
149.196 - tmp[i] = tmp[j] | mouseButtonDownMasks[j];
149.197 + for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
149.198 + System.out.println("modifiersExStandardALT FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]);
149.199 + tmp[i] = tmp[i] | mouseButtonDownMasks[j];
149.200 }
149.201 modifiersExStandardALT = Arrays.copyOf(tmp, tmp.length);
149.202 }
149.203 @@ -436,9 +434,9 @@
149.204 /* A class that invoke appropriate verification
149.205 * routine with current modifier.
149.206 */
149.207 -class CheckingModifierAdapter extends MouseAdapter{
149.208 +class CheckingModifierAdapterExtra extends MouseAdapter{
149.209 int modifier;
149.210 - public CheckingModifierAdapter(int modifier){
149.211 + public CheckingModifierAdapterExtra(int modifier){
149.212 this.modifier = modifier;
149.213 }
149.214
150.1 --- a/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java Tue Oct 12 13:34:59 2010 -0400
150.2 +++ b/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java Mon Oct 18 11:25:28 2010 -0400
150.3 @@ -90,7 +90,7 @@
150.4 int [] buttonMasks = new int[MouseInfo.getNumberOfButtons()]; // = InputEvent.getButtonDownMasks();
150.5 for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
150.6 buttonMasks[i] = InputEvent.getMaskForButton(i+1);
150.7 - System.out.println("TEST: "+buttonMasks[i]);
150.8 + System.out.println("TEST: buttonMasks["+ i +"] = " + buttonMasks[i]);
150.9 }
150.10
150.11 for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
151.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
151.2 +++ b/test/java/awt/image/GetSamplesTest.java Mon Oct 18 11:25:28 2010 -0400
151.3 @@ -0,0 +1,121 @@
151.4 +/*
151.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
151.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
151.7 + *
151.8 + * This code is free software; you can redistribute it and/or modify it
151.9 + * under the terms of the GNU General Public License version 2 only, as
151.10 + * published by the Free Software Foundation.
151.11 + *
151.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
151.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
151.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
151.15 + * version 2 for more details (a copy is included in the LICENSE file that
151.16 + * accompanied this code).
151.17 + *
151.18 + * You should have received a copy of the GNU General Public License version
151.19 + * 2 along with this work; if not, write to the Free Software Foundation,
151.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
151.21 + *
151.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
151.23 + * or visit www.oracle.com if you need additional information or have any
151.24 + * questions.
151.25 + */
151.26 +
151.27 +/*
151.28 + * @test
151.29 + * @bug 6735275
151.30 + * @summary Test verifies that SampleModel.getSamples() throws an appropriate
151.31 + * exception if coordinates are not in bounds.
151.32 + *
151.33 + * @run main GetSamplesTest
151.34 + */
151.35 +
151.36 +import java.awt.image.BandedSampleModel;
151.37 +import java.awt.image.ComponentSampleModel;
151.38 +import java.awt.image.DataBuffer;
151.39 +import java.awt.image.MultiPixelPackedSampleModel;
151.40 +import java.awt.image.PixelInterleavedSampleModel;
151.41 +import java.awt.image.SampleModel;
151.42 +import java.awt.image.SinglePixelPackedSampleModel;
151.43 +import java.util.Vector;
151.44 +
151.45 +public class GetSamplesTest {
151.46 +
151.47 + public static int width = 100;
151.48 + public static int height = 100;
151.49 + public static int dataType = DataBuffer.TYPE_BYTE;
151.50 + public static int numBands = 4;
151.51 +
151.52 + public static void main(String[] args) {
151.53 + Vector<Class<? extends SampleModel>> classes = new Vector<Class<? extends SampleModel>>();
151.54 +
151.55 + classes.add(ComponentSampleModel.class);
151.56 + classes.add(MultiPixelPackedSampleModel.class);
151.57 + classes.add(SinglePixelPackedSampleModel.class);
151.58 + classes.add(BandedSampleModel.class);
151.59 + classes.add(PixelInterleavedSampleModel.class);
151.60 +
151.61 + for (Class<? extends SampleModel> c : classes) {
151.62 + doTest(c);
151.63 + }
151.64 + }
151.65 + private static void doTest(Class<? extends SampleModel> c) {
151.66 + System.out.println("Test for: " + c.getName());
151.67 + SampleModel sm = createSampleModel(c);
151.68 +
151.69 + DataBuffer db = sm.createDataBuffer();
151.70 +
151.71 + int[] iArray = new int[ width * height + numBands];
151.72 + float[] fArray = new float[ width * height + numBands];
151.73 + double[] dArray = new double[ width * height + numBands];
151.74 +
151.75 + boolean iOk = false;
151.76 + boolean fOk = false;
151.77 + boolean dOk = false;
151.78 +
151.79 + try {
151.80 + sm.getSamples(Integer.MAX_VALUE, 0, 1, 1, 0, iArray, db);
151.81 + } catch (ArrayIndexOutOfBoundsException e) {
151.82 + System.out.println(e.getMessage());
151.83 + iOk = true;
151.84 + }
151.85 +
151.86 + try {
151.87 + sm.getSamples(Integer.MAX_VALUE, 0, 1, 1, 0, fArray, db);
151.88 + } catch (ArrayIndexOutOfBoundsException e) {
151.89 + System.out.println(e.getMessage());
151.90 + fOk = true;
151.91 + }
151.92 +
151.93 + try {
151.94 + sm.getSamples(0, Integer.MAX_VALUE, 1, 1, 0, dArray, db);
151.95 + } catch (ArrayIndexOutOfBoundsException e) {
151.96 + System.out.println(e.getMessage());
151.97 + dOk = true;
151.98 + }
151.99 + if (!iOk || !fOk || !dOk) {
151.100 + throw new RuntimeException("Test for " + c.getSimpleName() +
151.101 + " failed: iOk=" + iOk + "; fOk=" + fOk + "; dOk=" + dOk);
151.102 + }
151.103 + }
151.104 +
151.105 + private static SampleModel createSampleModel(Class<? extends SampleModel> cls) {
151.106 + SampleModel res = null;
151.107 +
151.108 + if (cls == ComponentSampleModel.class) {
151.109 + res = new ComponentSampleModel(dataType, width, height, 4, width * 4, new int[] { 0, 1, 2, 3 } );
151.110 + } else if (cls == MultiPixelPackedSampleModel.class) {
151.111 + res = new MultiPixelPackedSampleModel(dataType, width, height, 4);
151.112 + } else if (cls == SinglePixelPackedSampleModel.class) {
151.113 + res = new SinglePixelPackedSampleModel(dataType, width, height,
151.114 + new int[]{ 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff });
151.115 + } else if (cls == BandedSampleModel.class) {
151.116 + res = new BandedSampleModel(dataType, width, height, numBands);
151.117 + } else if (cls == PixelInterleavedSampleModel.class) {
151.118 + res = new PixelInterleavedSampleModel(dataType, width, height, 4, width * 4, new int[] { 0, 1, 2, 3 });
151.119 + } else {
151.120 + throw new RuntimeException("Unknown class " + cls);
151.121 + }
151.122 + return res;
151.123 + }
151.124 +}
152.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
152.2 +++ b/test/java/beans/Introspector/6976577/Test6976577.java Mon Oct 18 11:25:28 2010 -0400
152.3 @@ -0,0 +1,71 @@
152.4 +/*
152.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
152.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
152.7 + *
152.8 + * This code is free software; you can redistribute it and/or modify it
152.9 + * under the terms of the GNU General Public License version 2 only, as
152.10 + * published by the Free Software Foundation.
152.11 + *
152.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
152.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
152.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
152.15 + * version 2 for more details (a copy is included in the LICENSE file that
152.16 + * accompanied this code).
152.17 + *
152.18 + * You should have received a copy of the GNU General Public License version
152.19 + * 2 along with this work; if not, write to the Free Software Foundation,
152.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
152.21 + *
152.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
152.23 + * or visit www.oracle.com if you need additional information or have any
152.24 + * questions.
152.25 + */
152.26 +
152.27 +/*
152.28 + * @test
152.29 + * @bug 6976577
152.30 + * @summary Tests public methods in non-public beans
152.31 + * @author Sergey Malenkov
152.32 + */
152.33 +
152.34 +import test.Accessor;
152.35 +
152.36 +import java.beans.EventSetDescriptor;
152.37 +import java.beans.IndexedPropertyDescriptor;
152.38 +import java.beans.PropertyDescriptor;
152.39 +import java.lang.reflect.Method;
152.40 +
152.41 +public class Test6976577 {
152.42 +
152.43 + public static void main(String[] args) throws Exception {
152.44 + Class<?> bt = Accessor.getBeanType();
152.45 + Class<?> lt = Accessor.getListenerType();
152.46 +
152.47 + // test PropertyDescriptor
152.48 + PropertyDescriptor pd = new PropertyDescriptor("boolean", bt);
152.49 + test(pd.getReadMethod());
152.50 + test(pd.getWriteMethod());
152.51 +
152.52 + // test IndexedPropertyDescriptor
152.53 + IndexedPropertyDescriptor ipd = new IndexedPropertyDescriptor("indexed", bt);
152.54 + test(ipd.getReadMethod());
152.55 + test(ipd.getWriteMethod());
152.56 + test(ipd.getIndexedReadMethod());
152.57 + test(ipd.getIndexedWriteMethod());
152.58 +
152.59 + // test EventSetDescriptor
152.60 + EventSetDescriptor esd = new EventSetDescriptor(bt, "test", lt, "process");
152.61 + test(esd.getAddListenerMethod());
152.62 + test(esd.getRemoveListenerMethod());
152.63 + test(esd.getGetListenerMethod());
152.64 + test(esd.getListenerMethods());
152.65 + }
152.66 +
152.67 + private static void test(Method... methods) {
152.68 + for (Method method : methods) {
152.69 + if (method == null) {
152.70 + throw new Error("public method is not found");
152.71 + }
152.72 + }
152.73 + }
152.74 +}
153.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
153.2 +++ b/test/java/beans/Introspector/6976577/test/Accessor.java Mon Oct 18 11:25:28 2010 -0400
153.3 @@ -0,0 +1,81 @@
153.4 +package test;
153.5 +
153.6 +import java.beans.PropertyChangeListener;
153.7 +import java.beans.PropertyChangeSupport;
153.8 +import java.util.EventListener;
153.9 +import java.util.TooManyListenersException;
153.10 +
153.11 +public class Accessor {
153.12 +
153.13 + public static Class<?> getBeanType() {
153.14 + return Bean.class;
153.15 + }
153.16 +
153.17 + public static Class<?> getListenerType() {
153.18 + return TestListener.class;
153.19 + }
153.20 +}
153.21 +
153.22 +interface TestEvent {
153.23 +}
153.24 +
153.25 +interface TestListener extends EventListener {
153.26 + void process(TestEvent event);
153.27 +}
153.28 +
153.29 +class Bean {
153.30 +
153.31 + private boolean b;
153.32 + private int[] indexed;
153.33 + private TestListener listener;
153.34 + private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
153.35 +
153.36 + public void addPropertyChangeListener(PropertyChangeListener listener) {
153.37 + this.pcs.addPropertyChangeListener(listener);
153.38 + }
153.39 +
153.40 + public void addTestListener(TestListener listener) throws TooManyListenersException {
153.41 + if (listener != null) {
153.42 + if (this.listener != null) {
153.43 + throw new TooManyListenersException();
153.44 + }
153.45 + this.listener = listener;
153.46 + }
153.47 + }
153.48 +
153.49 + public void removeTestListener(TestListener listener) {
153.50 + if (this.listener == listener) {
153.51 + this.listener = null;
153.52 + }
153.53 + }
153.54 +
153.55 + public TestListener[] getTestListeners() {
153.56 + return (this.listener != null)
153.57 + ? new TestListener[] { this.listener }
153.58 + : new TestListener[0];
153.59 + }
153.60 +
153.61 + public boolean isBoolean() {
153.62 + return this.b;
153.63 + }
153.64 +
153.65 + public void setBoolean(boolean b) {
153.66 + this.b = b;
153.67 + }
153.68 +
153.69 + public int[] getIndexed() {
153.70 + return this.indexed;
153.71 + }
153.72 +
153.73 + public void setIndexed(int[] values) {
153.74 + this.indexed = values;
153.75 + }
153.76 +
153.77 + public int getIndexed(int index) {
153.78 + return this.indexed[index];
153.79 + }
153.80 +
153.81 + public void setIndexed(int index, int value) {
153.82 + this.indexed[index] = value;
153.83 + }
153.84 +}
154.1 --- a/test/java/lang/ProcessBuilder/Basic.java Tue Oct 12 13:34:59 2010 -0400
154.2 +++ b/test/java/lang/ProcessBuilder/Basic.java Mon Oct 18 11:25:28 2010 -0400
154.3 @@ -1825,6 +1825,64 @@
154.4 } catch (Throwable t) { unexpected(t); }
154.5
154.6 //----------------------------------------------------------------
154.7 + // Check that subprocesses which create subprocesses of their
154.8 + // own do not cause parent to hang waiting for file
154.9 + // descriptors to be closed.
154.10 + //----------------------------------------------------------------
154.11 + try {
154.12 + if (Unix.is()
154.13 + && new File("/bin/bash").exists()
154.14 + && new File("/bin/sleep").exists()) {
154.15 + final String[] cmd = { "/bin/bash", "-c", "(/bin/sleep 6666)" };
154.16 + final ProcessBuilder pb = new ProcessBuilder(cmd);
154.17 + final Process p = pb.start();
154.18 + final InputStream stdout = p.getInputStream();
154.19 + final InputStream stderr = p.getErrorStream();
154.20 + final OutputStream stdin = p.getOutputStream();
154.21 + final Thread reader = new Thread() {
154.22 + public void run() {
154.23 + try { stdout.read(); }
154.24 + catch (IOException e) {
154.25 + // e.printStackTrace();
154.26 + if (EnglishUnix.is() &&
154.27 + ! (e.getMessage().matches(".*Bad file descriptor.*")))
154.28 + unexpected(e);
154.29 + }
154.30 + catch (Throwable t) { unexpected(t); }}};
154.31 + reader.setDaemon(true);
154.32 + reader.start();
154.33 + Thread.sleep(100);
154.34 + p.destroy();
154.35 + // Subprocess is now dead, but file descriptors remain open.
154.36 + check(p.waitFor() != 0);
154.37 + check(p.exitValue() != 0);
154.38 + stdout.close();
154.39 + stderr.close();
154.40 + stdin.close();
154.41 + //----------------------------------------------------------
154.42 + // There remain unsolved issues with asynchronous close.
154.43 + // Here's a highly non-portable experiment to demonstrate:
154.44 + //----------------------------------------------------------
154.45 + if (Boolean.getBoolean("wakeupJeff!")) {
154.46 + System.out.println("wakeupJeff!");
154.47 + // Initialize signal handler for INTERRUPT_SIGNAL.
154.48 + new FileInputStream("/bin/sleep").getChannel().close();
154.49 + // Send INTERRUPT_SIGNAL to every thread in this java.
154.50 + String[] wakeupJeff = {
154.51 + "/bin/bash", "-c",
154.52 + "/bin/ps --noheaders -Lfp $PPID | " +
154.53 + "/usr/bin/perl -nale 'print $F[3]' | " +
154.54 + // INTERRUPT_SIGNAL == 62 on my machine du jour.
154.55 + "/usr/bin/xargs kill -62"
154.56 + };
154.57 + new ProcessBuilder(wakeupJeff).start().waitFor();
154.58 + // If wakeupJeff worked, reader probably got EBADF.
154.59 + reader.join();
154.60 + }
154.61 + }
154.62 + } catch (Throwable t) { unexpected(t); }
154.63 +
154.64 + //----------------------------------------------------------------
154.65 // Attempt to start process with insufficient permissions fails.
154.66 //----------------------------------------------------------------
154.67 try {
155.1 --- a/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java Tue Oct 12 13:34:59 2010 -0400
155.2 +++ b/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java Mon Oct 18 11:25:28 2010 -0400
155.3 @@ -29,7 +29,9 @@
155.4
155.5 import java.nio.channels.*;
155.6 import java.net.*;
155.7 +import static java.net.StandardSocketOption.*;
155.8 import java.io.IOException;
155.9 +import java.util.Set;
155.10 import java.util.concurrent.ExecutionException;
155.11 import java.util.concurrent.Future;
155.12 import java.util.concurrent.atomic.AtomicReference;
155.13 @@ -39,6 +41,7 @@
155.14 public static void main(String[] args) throws Exception {
155.15 testBind();
155.16 testAccept();
155.17 + testSocketOptions();
155.18 }
155.19
155.20 static void testBind() throws Exception {
155.21 @@ -131,4 +134,39 @@
155.22 }
155.23
155.24 }
155.25 +
155.26 + static void testSocketOptions() throws Exception {
155.27 + System.out.println("-- socket options --");
155.28 + AsynchronousServerSocketChannel ch = AsynchronousServerSocketChannel.open();
155.29 + try {
155.30 + // check supported options
155.31 + Set<SocketOption<?>> options = ch.supportedOptions();
155.32 + if (!options.contains(SO_REUSEADDR))
155.33 + throw new RuntimeException("SO_REUSEADDR should be supported");
155.34 + if (!options.contains(SO_RCVBUF))
155.35 + throw new RuntimeException("SO_RCVBUF should be supported");
155.36 +
155.37 + // allowed to change when not bound
155.38 + ch.setOption(SO_RCVBUF, 256*1024); // can't check
155.39 + int before = ch.getOption(SO_RCVBUF);
155.40 + int after = ch.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
155.41 + if (after < before)
155.42 + throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
155.43 + ch.setOption(SO_REUSEADDR, true);
155.44 + checkOption(ch, SO_REUSEADDR, true);
155.45 + ch.setOption(SO_REUSEADDR, false);
155.46 + checkOption(ch, SO_REUSEADDR, false);
155.47 + } finally {
155.48 + ch.close();
155.49 + }
155.50 + }
155.51 +
155.52 + static void checkOption(AsynchronousServerSocketChannel ch,
155.53 + SocketOption name, Object expectedValue)
155.54 + throws IOException
155.55 + {
155.56 + Object value = ch.getOption(name);
155.57 + if (!value.equals(expectedValue))
155.58 + throw new RuntimeException("value not as expected");
155.59 + }
155.60 }
156.1 --- a/test/java/nio/channels/AsynchronousSocketChannel/Basic.java Tue Oct 12 13:34:59 2010 -0400
156.2 +++ b/test/java/nio/channels/AsynchronousSocketChannel/Basic.java Mon Oct 18 11:25:28 2010 -0400
156.3 @@ -121,8 +121,20 @@
156.4 AsynchronousSocketChannel ch = AsynchronousSocketChannel.open()
156.5 .setOption(SO_RCVBUF, 128*1024)
156.6 .setOption(SO_SNDBUF, 128*1024)
156.7 - .setOption(SO_REUSEADDR, true)
156.8 - .bind(new InetSocketAddress(0));
156.9 + .setOption(SO_REUSEADDR, true);
156.10 +
156.11 + // check SO_SNDBUF/SO_RCVBUF limits
156.12 + int before, after;
156.13 + before = ch.getOption(SO_SNDBUF);
156.14 + after = ch.setOption(SO_SNDBUF, Integer.MAX_VALUE).getOption(SO_SNDBUF);
156.15 + if (after < before)
156.16 + throw new RuntimeException("setOption caused SO_SNDBUF to decrease");
156.17 + before = ch.getOption(SO_RCVBUF);
156.18 + after = ch.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
156.19 + if (after < before)
156.20 + throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
156.21 +
156.22 + ch.bind(new InetSocketAddress(0));
156.23
156.24 // default values
156.25 if ((Boolean)ch.getOption(SO_KEEPALIVE))
157.1 --- a/test/java/nio/channels/DatagramChannel/SocketOptionTests.java Tue Oct 12 13:34:59 2010 -0400
157.2 +++ b/test/java/nio/channels/DatagramChannel/SocketOptionTests.java Mon Oct 18 11:25:28 2010 -0400
157.3 @@ -68,8 +68,17 @@
157.4 checkOption(dc, SO_BROADCAST, true);
157.5 dc.setOption(SO_BROADCAST, false);
157.6 checkOption(dc, SO_BROADCAST, false);
157.7 - dc.setOption(SO_SNDBUF, 16*1024); // can't check
157.8 - dc.setOption(SO_RCVBUF, 16*1024); // can't check
157.9 + dc.setOption(SO_SNDBUF, 128*1024); // can't check
157.10 + dc.setOption(SO_RCVBUF, 128*1024); // can't check
157.11 + int before, after;
157.12 + before = dc.getOption(SO_SNDBUF);
157.13 + after = dc.setOption(SO_SNDBUF, Integer.MAX_VALUE).getOption(SO_SNDBUF);
157.14 + if (after < before)
157.15 + throw new RuntimeException("setOption caused SO_SNDBUF to decrease");
157.16 + before = dc.getOption(SO_RCVBUF);
157.17 + after = dc.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
157.18 + if (after < before)
157.19 + throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
157.20 dc.setOption(SO_REUSEADDR, true);
157.21 checkOption(dc, SO_REUSEADDR, true);
157.22 dc.setOption(SO_REUSEADDR, false);
158.1 --- a/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java Tue Oct 12 13:34:59 2010 -0400
158.2 +++ b/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java Mon Oct 18 11:25:28 2010 -0400
158.3 @@ -56,6 +56,10 @@
158.4
158.5 // allowed to change when not bound
158.6 ssc.setOption(SO_RCVBUF, 256*1024); // can't check
158.7 + int before = ssc.getOption(SO_RCVBUF);
158.8 + int after = ssc.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
158.9 + if (after < before)
158.10 + throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
158.11 ssc.setOption(SO_REUSEADDR, true);
158.12 checkOption(ssc, SO_REUSEADDR, true);
158.13 ssc.setOption(SO_REUSEADDR, false);
159.1 --- a/test/java/nio/channels/SocketChannel/SocketOptionTests.java Tue Oct 12 13:34:59 2010 -0400
159.2 +++ b/test/java/nio/channels/SocketChannel/SocketOptionTests.java Mon Oct 18 11:25:28 2010 -0400
159.3 @@ -70,6 +70,15 @@
159.4 checkOption(sc, SO_KEEPALIVE, false);
159.5 sc.setOption(SO_SNDBUF, 128*1024); // can't check
159.6 sc.setOption(SO_RCVBUF, 256*1024); // can't check
159.7 + int before, after;
159.8 + before = sc.getOption(SO_SNDBUF);
159.9 + after = sc.setOption(SO_SNDBUF, Integer.MAX_VALUE).getOption(SO_SNDBUF);
159.10 + if (after < before)
159.11 + throw new RuntimeException("setOption caused SO_SNDBUF to decrease");
159.12 + before = sc.getOption(SO_RCVBUF);
159.13 + after = sc.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
159.14 + if (after < before)
159.15 + throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
159.16 sc.setOption(SO_REUSEADDR, true);
159.17 checkOption(sc, SO_REUSEADDR, true);
159.18 sc.setOption(SO_REUSEADDR, false);
160.1 --- a/test/java/nio/file/FileStore/Basic.java Tue Oct 12 13:34:59 2010 -0400
160.2 +++ b/test/java/nio/file/FileStore/Basic.java Mon Oct 18 11:25:28 2010 -0400
160.3 @@ -22,7 +22,7 @@
160.4 */
160.5
160.6 /* @test
160.7 - * @bug 4313887 6873621
160.8 + * @bug 4313887 6873621 6979526
160.9 * @summary Unit test for java.nio.file.FileStore
160.10 * @library ..
160.11 */
161.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
161.2 +++ b/test/java/nio/file/Files/MaxDepth.java Mon Oct 18 11:25:28 2010 -0400
161.3 @@ -0,0 +1,67 @@
161.4 +/*
161.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
161.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
161.7 + *
161.8 + * This code is free software; you can redistribute it and/or modify it
161.9 + * under the terms of the GNU General Public License version 2 only, as
161.10 + * published by the Free Software Foundation.
161.11 + *
161.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
161.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
161.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
161.15 + * version 2 for more details (a copy is included in the LICENSE file that
161.16 + * accompanied this code).
161.17 + *
161.18 + * You should have received a copy of the GNU General Public License version
161.19 + * 2 along with this work; if not, write to the Free Software Foundation,
161.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
161.21 + *
161.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
161.23 + * or visit www.oracle.com if you need additional information or have any
161.24 + * questions.
161.25 + */
161.26 +
161.27 +import java.nio.file.*;
161.28 +import java.nio.file.attribute.*;
161.29 +import java.io.IOException;
161.30 +import java.util.*;
161.31 +
161.32 +/**
161.33 + * Unit test for Files.walkFileTree to test maxDepth parameter
161.34 + */
161.35 +
161.36 +public class MaxDepth {
161.37 + public static void main(String[] args) throws Exception {
161.38 + final Path top = Paths.get(args[0]);
161.39 +
161.40 + for (int i=0; i<5; i++) {
161.41 + Set<FileVisitOption> opts = Collections.emptySet();
161.42 + final int maxDepth = i;
161.43 + Files.walkFileTree(top, opts, maxDepth, new SimpleFileVisitor<Path>() {
161.44 + // compute depth based on relative path to top directory
161.45 + private int depth(Path file) {
161.46 + Path rp = file.relativize(top);
161.47 + return (rp == null) ? 0 : rp.getNameCount();
161.48 + }
161.49 +
161.50 + @Override
161.51 + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
161.52 + int d = depth(dir);
161.53 + if (d == maxDepth)
161.54 + throw new RuntimeException("Should not open directories at maxDepth");
161.55 + if (d > maxDepth)
161.56 + throw new RuntimeException("Too deep");
161.57 + return FileVisitResult.CONTINUE;
161.58 + }
161.59 +
161.60 + @Override
161.61 + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
161.62 + int d = depth(file);
161.63 + if (d > maxDepth)
161.64 + throw new RuntimeException("Too deep");
161.65 + return FileVisitResult.CONTINUE;
161.66 + }
161.67 + });
161.68 + }
161.69 + }
161.70 +}
162.1 --- a/test/java/nio/file/Files/Misc.java Tue Oct 12 13:34:59 2010 -0400
162.2 +++ b/test/java/nio/file/Files/Misc.java Mon Oct 18 11:25:28 2010 -0400
162.3 @@ -30,6 +30,7 @@
162.4
162.5 import java.nio.file.*;
162.6 import java.nio.file.attribute.Attributes;
162.7 +import java.nio.file.attribute.BasicFileAttributes;
162.8 import java.io.IOException;
162.9 import java.util.*;
162.10
162.11 @@ -117,25 +118,25 @@
162.12
162.13 SimpleFileVisitor<Path> visitor = new SimpleFileVisitor<Path>() { };
162.14 boolean ranTheGauntlet = false;
162.15 - try { visitor.preVisitDirectory(null);
162.16 + BasicFileAttributes attrs = Attributes.readBasicFileAttributes(Paths.get("."));
162.17 +
162.18 + try { visitor.preVisitDirectory(null, attrs);
162.19 } catch (NullPointerException x0) {
162.20 - try { visitor.preVisitDirectoryFailed(null, new IOException());
162.21 + try { visitor.preVisitDirectory(dir, null);
162.22 } catch (NullPointerException x1) {
162.23 - try { visitor.preVisitDirectoryFailed(dir, null);
162.24 + try { visitor.visitFile(null, attrs);
162.25 } catch (NullPointerException x2) {
162.26 - try { visitor.visitFile(null, Attributes.readBasicFileAttributes(Paths.get(".")));
162.27 + try { visitor.visitFile(dir, null);
162.28 } catch (NullPointerException x3) {
162.29 - try { visitor.visitFile(dir, null);
162.30 + try { visitor.visitFileFailed(null, new IOException());
162.31 } catch (NullPointerException x4) {
162.32 - try { visitor.visitFileFailed(null, new IOException());
162.33 + try { visitor.visitFileFailed(dir, null);
162.34 } catch (NullPointerException x5) {
162.35 - try { visitor.visitFileFailed(dir, null);
162.36 + try { visitor.postVisitDirectory(null, new IOException());
162.37 } catch (NullPointerException x6) {
162.38 - try { visitor.postVisitDirectory(null, new IOException());
162.39 - } catch (NullPointerException x7) {
162.40 // if we get here then all visit* methods threw NPE as expected
162.41 ranTheGauntlet = true;
162.42 - }}}}}}}}
162.43 + }}}}}}}
162.44 if (!ranTheGauntlet)
162.45 throw new RuntimeException("A visit method did not throw NPE");
162.46 }
163.1 --- a/test/java/nio/file/Files/PrintFileTree.java Tue Oct 12 13:34:59 2010 -0400
163.2 +++ b/test/java/nio/file/Files/PrintFileTree.java Mon Oct 18 11:25:28 2010 -0400
163.3 @@ -56,29 +56,34 @@
163.4
163.5 final boolean reportCycles = printCycles;
163.6 Files.walkFileTree(dir, options, Integer.MAX_VALUE, new FileVisitor<FileRef>() {
163.7 - public FileVisitResult preVisitDirectory(FileRef dir) {
163.8 + @Override
163.9 + public FileVisitResult preVisitDirectory(FileRef dir, BasicFileAttributes attrs) {
163.10 System.out.println(dir);
163.11 return FileVisitResult.CONTINUE;
163.12 }
163.13 - public FileVisitResult preVisitDirectoryFailed(FileRef dir, IOException exc) {
163.14 - exc.printStackTrace();
163.15 - return FileVisitResult.CONTINUE;
163.16 - }
163.17 + @Override
163.18 public FileVisitResult visitFile(FileRef file, BasicFileAttributes attrs) {
163.19 if (!attrs.isDirectory() || reportCycles)
163.20 System.out.println(file);
163.21 return FileVisitResult.CONTINUE;
163.22 }
163.23 - public FileVisitResult postVisitDirectory(FileRef dir, IOException exc) {
163.24 - if (exc != null) {
163.25 - exc.printStackTrace();
163.26 - return FileVisitResult.TERMINATE;
163.27 - }
163.28 + @Override
163.29 + public FileVisitResult postVisitDirectory(FileRef dir, IOException exc)
163.30 + throws IOException
163.31 + {
163.32 + if (exc != null)
163.33 + throw exc;
163.34 return FileVisitResult.CONTINUE;
163.35 }
163.36 - public FileVisitResult visitFileFailed(FileRef file, IOException exc) {
163.37 - exc.printStackTrace();
163.38 - return FileVisitResult.TERMINATE;
163.39 + @Override
163.40 + public FileVisitResult visitFileFailed(FileRef file, IOException exc)
163.41 + throws IOException
163.42 + {
163.43 + if (reportCycles && (exc instanceof FileSystemLoopException)) {
163.44 + System.out.println(file);
163.45 + return FileVisitResult.CONTINUE;
163.46 + }
163.47 + throw exc;
163.48 }
163.49 });
163.50 }
164.1 --- a/test/java/nio/file/Files/SkipSiblings.java Tue Oct 12 13:34:59 2010 -0400
164.2 +++ b/test/java/nio/file/Files/SkipSiblings.java Mon Oct 18 11:25:28 2010 -0400
164.3 @@ -54,32 +54,28 @@
164.4 public static void main(String[] args) throws Exception {
164.5 Path dir = Paths.get(args[0]);
164.6
164.7 - Files.walkFileTree(dir, new FileVisitor<Path>() {
164.8 - public FileVisitResult preVisitDirectory(Path dir) {
164.9 + Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
164.10 + @Override
164.11 + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
164.12 check(dir);
164.13 if (skip(dir))
164.14 return FileVisitResult.SKIP_SIBLINGS;
164.15 return FileVisitResult.CONTINUE;
164.16 }
164.17 - public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
164.18 - throw new RuntimeException(exc);
164.19 - }
164.20 -
164.21 + @Override
164.22 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
164.23 check(file);
164.24 if (skip(file))
164.25 return FileVisitResult.SKIP_SIBLINGS;
164.26 return FileVisitResult.CONTINUE;
164.27 }
164.28 + @Override
164.29 public FileVisitResult postVisitDirectory(Path dir, IOException x) {
164.30 if (x != null)
164.31 throw new RuntimeException(x);
164.32 check(dir);
164.33 return FileVisitResult.CONTINUE;
164.34 }
164.35 - public FileVisitResult visitFileFailed(Path file, IOException x) {
164.36 - throw new RuntimeException(x);
164.37 - }
164.38 });
164.39 }
164.40 }
165.1 --- a/test/java/nio/file/Files/TerminateWalk.java Tue Oct 12 13:34:59 2010 -0400
165.2 +++ b/test/java/nio/file/Files/TerminateWalk.java Mon Oct 18 11:25:28 2010 -0400
165.3 @@ -49,22 +49,19 @@
165.4 public static void main(String[] args) throws Exception {
165.5 Path dir = Paths.get(args[0]);
165.6
165.7 - Files.walkFileTree(dir, new FileVisitor<Path>() {
165.8 - public FileVisitResult preVisitDirectory(Path dir) {
165.9 + Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
165.10 + @Override
165.11 + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
165.12 return maybeTerminate();
165.13 }
165.14 - public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
165.15 - return maybeTerminate();
165.16 - }
165.17 + @Override
165.18 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
165.19 return maybeTerminate();
165.20 }
165.21 + @Override
165.22 public FileVisitResult postVisitDirectory(Path dir, IOException x) {
165.23 return maybeTerminate();
165.24 }
165.25 - public FileVisitResult visitFileFailed(Path file, IOException x) {
165.26 - return maybeTerminate();
165.27 - }
165.28 });
165.29 }
165.30 }
166.1 --- a/test/java/nio/file/Files/WalkWithSecurity.java Tue Oct 12 13:34:59 2010 -0400
166.2 +++ b/test/java/nio/file/Files/WalkWithSecurity.java Mon Oct 18 11:25:28 2010 -0400
166.3 @@ -116,7 +116,7 @@
166.4 }
166.5
166.6 @Override
166.7 - public FileVisitResult preVisitDirectory(Path dir) {
166.8 + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
166.9 System.out.println(dir);
166.10 count++;
166.11 return FileVisitResult.CONTINUE;
167.1 --- a/test/java/nio/file/Files/walk_file_tree.sh Tue Oct 12 13:34:59 2010 -0400
167.2 +++ b/test/java/nio/file/Files/walk_file_tree.sh Mon Oct 18 11:25:28 2010 -0400
167.3 @@ -22,9 +22,9 @@
167.4 #
167.5
167.6 # @test
167.7 -# @bug 4313887
167.8 +# @bug 4313887 6907737
167.9 # @summary Unit test for walkFileTree method
167.10 -# @build CreateFileTree PrintFileTree SkipSiblings TerminateWalk
167.11 +# @build CreateFileTree PrintFileTree SkipSiblings TerminateWalk MaxDepth
167.12 # @run shell walk_file_tree.sh
167.13
167.14 # if TESTJAVA isn't set then we assume an interactive run.
167.15 @@ -84,6 +84,10 @@
167.16 $JAVA TerminateWalk "$ROOT"
167.17 if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
167.18
167.19 +# test maxDepth
167.20 +$JAVA MaxDepth "$ROOT"
167.21 +if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
167.22 +
167.23 # clean-up
167.24 rm -r "$ROOT"
167.25
168.1 --- a/test/java/nio/file/TestUtil.java Tue Oct 12 13:34:59 2010 -0400
168.2 +++ b/test/java/nio/file/TestUtil.java Mon Oct 18 11:25:28 2010 -0400
168.3 @@ -44,15 +44,10 @@
168.4 return createTemporaryDirectory(System.getProperty("java.io.tmpdir"));
168.5 }
168.6
168.7 - static void removeAll(Path dir) {
168.8 + static void removeAll(Path dir) throws IOException {
168.9 Files.walkFileTree(dir, new FileVisitor<Path>() {
168.10 @Override
168.11 - public FileVisitResult preVisitDirectory(Path dir) {
168.12 - return FileVisitResult.CONTINUE;
168.13 - }
168.14 - @Override
168.15 - public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
168.16 - System.err.format("Error occured accessing directory %s\n", dir, exc);
168.17 + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
168.18 return FileVisitResult.CONTINUE;
168.19 }
168.20 @Override
169.1 --- a/test/java/util/Collection/BiggernYours.java Tue Oct 12 13:34:59 2010 -0400
169.2 +++ b/test/java/util/Collection/BiggernYours.java Mon Oct 18 11:25:28 2010 -0400
169.3 @@ -174,6 +174,11 @@
169.4 public int size() {return randomize(super.size());}});
169.5
169.6 testCollections(
169.7 + new ConcurrentLinkedDeque(),
169.8 + new ConcurrentLinkedDeque() {
169.9 + public int size() {return randomize(super.size());}});
169.10 +
169.11 + testCollections(
169.12 new ConcurrentLinkedQueue(),
169.13 new ConcurrentLinkedQueue() {
169.14 public int size() {return randomize(super.size());}});
170.1 --- a/test/java/util/Collection/IteratorAtEnd.java Tue Oct 12 13:34:59 2010 -0400
170.2 +++ b/test/java/util/Collection/IteratorAtEnd.java Mon Oct 18 11:25:28 2010 -0400
170.3 @@ -48,6 +48,7 @@
170.4 testCollection(new PriorityQueue());
170.5 testCollection(new LinkedBlockingQueue());
170.6 testCollection(new ArrayBlockingQueue(100));
170.7 + testCollection(new ConcurrentLinkedDeque());
170.8 testCollection(new ConcurrentLinkedQueue());
170.9 testCollection(new LinkedTransferQueue());
170.10
171.1 --- a/test/java/util/Collection/MOAT.java Tue Oct 12 13:34:59 2010 -0400
171.2 +++ b/test/java/util/Collection/MOAT.java Mon Oct 18 11:25:28 2010 -0400
171.3 @@ -75,6 +75,7 @@
171.4 testCollection(new ArrayBlockingQueue<Integer>(20));
171.5 testCollection(new LinkedBlockingQueue<Integer>(20));
171.6 testCollection(new LinkedBlockingDeque<Integer>(20));
171.7 + testCollection(new ConcurrentLinkedDeque<Integer>());
171.8 testCollection(new ConcurrentLinkedQueue<Integer>());
171.9 testCollection(new LinkedTransferQueue<Integer>());
171.10 testCollection(new ConcurrentSkipListSet<Integer>());
171.11 @@ -431,8 +432,9 @@
171.12 q.poll();
171.13 equal(q.size(), 4);
171.14 checkFunctionalInvariants(q);
171.15 - if ((q instanceof LinkedBlockingQueue) ||
171.16 - (q instanceof LinkedBlockingDeque) ||
171.17 + if ((q instanceof LinkedBlockingQueue) ||
171.18 + (q instanceof LinkedBlockingDeque) ||
171.19 + (q instanceof ConcurrentLinkedDeque) ||
171.20 (q instanceof ConcurrentLinkedQueue)) {
171.21 testQueueIteratorRemove(q);
171.22 }
172.1 --- a/test/java/util/Collections/RacingCollections.java Tue Oct 12 13:34:59 2010 -0400
172.2 +++ b/test/java/util/Collections/RacingCollections.java Mon Oct 18 11:25:28 2010 -0400
172.3 @@ -235,6 +235,7 @@
172.4 new ArrayList<Queue<Integer>>(newConcurrentDeques());
172.5 list.add(new LinkedBlockingQueue<Integer>(10));
172.6 list.add(new LinkedTransferQueue<Integer>());
172.7 + list.add(new ConcurrentLinkedQueue<Integer>());
172.8 return list;
172.9 }
172.10
172.11 @@ -248,6 +249,7 @@
172.12 private static List<Deque<Integer>> newConcurrentDeques() {
172.13 List<Deque<Integer>> list = new ArrayList<Deque<Integer>>();
172.14 list.add(new LinkedBlockingDeque<Integer>(10));
172.15 + list.add(new ConcurrentLinkedDeque<Integer>());
172.16 return list;
172.17 }
172.18
173.1 --- a/test/java/util/Deque/ChorusLine.java Tue Oct 12 13:34:59 2010 -0400
173.2 +++ b/test/java/util/Deque/ChorusLine.java Mon Oct 18 11:25:28 2010 -0400
173.3 @@ -129,6 +129,7 @@
173.4 deqs.add(new ArrayDeque<Integer>());
173.5 deqs.add(new LinkedList<Integer>());
173.6 deqs.add(new LinkedBlockingDeque<Integer>());
173.7 + deqs.add(new ConcurrentLinkedDeque<Integer>());
173.8
173.9 equal(deqs);
173.10
174.1 --- a/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java Tue Oct 12 13:34:59 2010 -0400
174.2 +++ b/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java Mon Oct 18 11:25:28 2010 -0400
174.3 @@ -55,6 +55,7 @@
174.4
174.5 Collection<Queue<Integer>> concurrentQueues() {
174.6 List<Queue<Integer>> queues = new ArrayList<Queue<Integer>>();
174.7 + queues.add(new ConcurrentLinkedDeque<Integer>());
174.8 queues.add(new ConcurrentLinkedQueue<Integer>());
174.9 queues.add(new ArrayBlockingQueue<Integer>(items, false));
174.10 //queues.add(new ArrayBlockingQueue<Integer>(count, true));
174.11 @@ -105,7 +106,7 @@
174.12 final Queue<Integer> queue;
174.13 final CyclicBarrier barrier;
174.14 int items;
174.15 - Stage (Queue<Integer> q, CyclicBarrier b, int items) {
174.16 + Stage(Queue<Integer> q, CyclicBarrier b, int items) {
174.17 queue = q;
174.18 barrier = b;
174.19 this.items = items;
175.1 --- a/test/java/util/concurrent/ConcurrentQueues/GCRetention.java Tue Oct 12 13:34:59 2010 -0400
175.2 +++ b/test/java/util/concurrent/ConcurrentQueues/GCRetention.java Mon Oct 18 11:25:28 2010 -0400
175.3 @@ -40,6 +40,7 @@
175.4
175.5 import java.util.concurrent.ArrayBlockingQueue;
175.6 import java.util.concurrent.ConcurrentHashMap;
175.7 +import java.util.concurrent.ConcurrentLinkedDeque;
175.8 import java.util.concurrent.ConcurrentLinkedQueue;
175.9 import java.util.concurrent.LinkedBlockingDeque;
175.10 import java.util.concurrent.LinkedBlockingQueue;
175.11 @@ -62,6 +63,7 @@
175.12
175.13 Collection<Queue<Boolean>> queues() {
175.14 List<Queue<Boolean>> queues = new ArrayList<Queue<Boolean>>();
175.15 + queues.add(new ConcurrentLinkedDeque<Boolean>());
175.16 queues.add(new ConcurrentLinkedQueue<Boolean>());
175.17 queues.add(new ArrayBlockingQueue<Boolean>(count, false));
175.18 queues.add(new ArrayBlockingQueue<Boolean>(count, true));
176.1 --- a/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java Tue Oct 12 13:34:59 2010 -0400
176.2 +++ b/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java Mon Oct 18 11:25:28 2010 -0400
176.3 @@ -48,6 +48,7 @@
176.4 test(new LinkedBlockingQueue(20));
176.5 test(new LinkedBlockingDeque());
176.6 test(new LinkedBlockingDeque(20));
176.7 + test(new ConcurrentLinkedDeque());
176.8 test(new ConcurrentLinkedQueue());
176.9 test(new LinkedTransferQueue());
176.10 // Other concurrent queues (e.g. ArrayBlockingQueue) do not
177.1 --- a/test/java/util/concurrent/ConcurrentQueues/OfferRemoveLoops.java Tue Oct 12 13:34:59 2010 -0400
177.2 +++ b/test/java/util/concurrent/ConcurrentQueues/OfferRemoveLoops.java Mon Oct 18 11:25:28 2010 -0400
177.3 @@ -55,6 +55,7 @@
177.4 testQueue(new LinkedBlockingDeque());
177.5 testQueue(new ArrayBlockingQueue(10));
177.6 testQueue(new PriorityBlockingQueue(10));
177.7 + testQueue(new ConcurrentLinkedDeque());
177.8 testQueue(new ConcurrentLinkedQueue());
177.9 testQueue(new LinkedTransferQueue());
177.10 }
178.1 --- a/test/java/util/concurrent/ConcurrentQueues/RemovePollRace.java Tue Oct 12 13:34:59 2010 -0400
178.2 +++ b/test/java/util/concurrent/ConcurrentQueues/RemovePollRace.java Mon Oct 18 11:25:28 2010 -0400
178.3 @@ -41,6 +41,7 @@
178.4
178.5 import java.util.concurrent.ArrayBlockingQueue;
178.6 import java.util.concurrent.ConcurrentHashMap;
178.7 +import java.util.concurrent.ConcurrentLinkedDeque;
178.8 import java.util.concurrent.ConcurrentLinkedQueue;
178.9 import java.util.concurrent.CountDownLatch;
178.10 import java.util.concurrent.LinkedBlockingDeque;
178.11 @@ -62,6 +63,7 @@
178.12
178.13 Collection<Queue<Boolean>> concurrentQueues() {
178.14 List<Queue<Boolean>> queues = new ArrayList<Queue<Boolean>>();
178.15 + queues.add(new ConcurrentLinkedDeque<Boolean>());
178.16 queues.add(new ConcurrentLinkedQueue<Boolean>());
178.17 queues.add(new ArrayBlockingQueue<Boolean>(count, false));
178.18 queues.add(new ArrayBlockingQueue<Boolean>(count, true));
179.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
179.2 +++ b/test/javax/swing/JComboBox/6632953/bug6632953.java Mon Oct 18 11:25:28 2010 -0400
179.3 @@ -0,0 +1,44 @@
179.4 +/*
179.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
179.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
179.7 + *
179.8 + * This code is free software; you can redistribute it and/or modify it
179.9 + * under the terms of the GNU General Public License version 2 only, as
179.10 + * published by the Free Software Foundation.
179.11 + *
179.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
179.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
179.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
179.15 + * version 2 for more details (a copy is included in the LICENSE file that
179.16 + * accompanied this code).
179.17 + *
179.18 + * You should have received a copy of the GNU General Public License version
179.19 + * 2 along with this work; if not, write to the Free Software Foundation,
179.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
179.21 + *
179.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
179.23 + * or visit www.oracle.com if you need additional information or have any
179.24 + * questions.
179.25 + */
179.26 +
179.27 +/* @test
179.28 + * @bug 6632953
179.29 + * @summary MetalComboBoxUI.getBaseline(JComponent, int, int) throws IAE for valid width/height
179.30 + * @author Alexander Potochkin
179.31 + */
179.32 +
179.33 +import javax.swing.JComboBox;
179.34 +import javax.swing.plaf.metal.MetalComboBoxUI;
179.35 +
179.36 +public class bug6632953 {
179.37 +
179.38 + public static void main(String... args) throws Exception {
179.39 + MetalComboBoxUI ui = new MetalComboBoxUI();
179.40 + ui.installUI(new JComboBox());
179.41 + ui.getBaseline(new JComboBox(), 0, 0);
179.42 + ui.getBaseline(new JComboBox(), 1, 1);
179.43 + ui.getBaseline(new JComboBox(), 2, 2);
179.44 + ui.getBaseline(new JComboBox(), 3, 3);
179.45 + ui.getBaseline(new JComboBox(), 4, 4);
179.46 + }
179.47 +}
180.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
180.2 +++ b/test/javax/swing/JScrollBar/6542335/bug6542335.java Mon Oct 18 11:25:28 2010 -0400
180.3 @@ -0,0 +1,92 @@
180.4 +/*
180.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
180.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
180.7 + *
180.8 + * This code is free software; you can redistribute it and/or modify it
180.9 + * under the terms of the GNU General Public License version 2 only, as
180.10 + * published by the Free Software Foundation.
180.11 + *
180.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
180.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
180.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
180.15 + * version 2 for more details (a copy is included in the LICENSE file that
180.16 + * accompanied this code).
180.17 + *
180.18 + * You should have received a copy of the GNU General Public License version
180.19 + * 2 along with this work; if not, write to the Free Software Foundation,
180.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
180.21 + *
180.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
180.23 + * or visit www.oracle.com if you need additional information or have any
180.24 + * questions.
180.25 + */
180.26 +
180.27 +/* @test
180.28 + @bug 6542335
180.29 + @summary different behavior on knob of scroll bar between 1.4.2 and 5.0
180.30 + @author Alexander Potochkin
180.31 + @run main bug6542335
180.32 +*/
180.33 +
180.34 +import sun.awt.SunToolkit;
180.35 +
180.36 +import javax.swing.*;
180.37 +import javax.swing.plaf.basic.BasicScrollBarUI;
180.38 +import java.awt.*;
180.39 +import java.awt.event.InputEvent;
180.40 +
180.41 +public class bug6542335 {
180.42 + private static JScrollBar sb;
180.43 + private static MyScrollBarUI ui;
180.44 +
180.45 + public static void main(String[] args) throws Exception {
180.46 + Robot robot = new Robot();
180.47 + robot.setAutoDelay(10);
180.48 +
180.49 + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
180.50 +
180.51 + SwingUtilities.invokeAndWait(new Runnable() {
180.52 + public void run() {
180.53 + final JFrame frame = new JFrame("bug6542335");
180.54 + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
180.55 +
180.56 + sb = new JScrollBar(0, 0, 1, 0, 1);
180.57 +
180.58 + ui = new MyScrollBarUI();
180.59 + sb.setUI(ui);
180.60 +
180.61 + sb.setPreferredSize(new Dimension(200, 17));
180.62 + DefaultBoundedRangeModel rangeModel = new DefaultBoundedRangeModel();
180.63 + rangeModel.setMaximum(100);
180.64 + rangeModel.setMinimum(0);
180.65 + rangeModel.setExtent(50);
180.66 + rangeModel.setValue(50);
180.67 +
180.68 + sb.setModel(rangeModel);
180.69 + frame.add(sb);
180.70 +
180.71 + frame.setSize(200, 100);
180.72 + frame.setVisible(true);
180.73 + }
180.74 + });
180.75 +
180.76 + Rectangle thumbBounds = new Rectangle(ui.getThumbBounds());
180.77 +
180.78 + toolkit.realSync();
180.79 + Point l = sb.getLocationOnScreen();
180.80 + robot.mouseMove(l.x + (int) (0.75 * sb.getWidth()), l.y + sb.getHeight()/2);
180.81 + robot.mousePress(InputEvent.BUTTON1_MASK);
180.82 + robot.mouseRelease(InputEvent.BUTTON1_MASK);
180.83 + toolkit.realSync();
180.84 +
180.85 + if (!thumbBounds.equals(ui.getThumbBounds())) {
180.86 + throw new RuntimeException("Test failed");
180.87 + }
180.88 + }
180.89 +
180.90 + static class MyScrollBarUI extends BasicScrollBarUI {
180.91 + public Rectangle getThumbBounds() {
180.92 + return super.getThumbBounds();
180.93 + }
180.94 + }
180.95 +}
181.1 --- a/test/javax/swing/JTable/Test6888156.java Tue Oct 12 13:34:59 2010 -0400
181.2 +++ b/test/javax/swing/JTable/Test6888156.java Mon Oct 18 11:25:28 2010 -0400
181.3 @@ -1,5 +1,5 @@
181.4 /*
181.5 - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
181.6 + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
181.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
181.8 *
181.9 * This code is free software; you can redistribute it and/or modify it
181.10 @@ -71,14 +71,14 @@
181.11 table = new JTable(model);
181.12 }
181.13
181.14 - public void test(final LookAndFeel laf) throws Exception {
181.15 + public void test(final String laf) throws Exception {
181.16 SwingUtilities.invokeAndWait(new Runnable() {
181.17 @Override public void run() {
181.18 try {
181.19 + System.out.println(laf);
181.20 UIManager.setLookAndFeel(laf);
181.21 - } catch (UnsupportedLookAndFeelException e) {
181.22 - System.err.println(laf.getDescription() +
181.23 - " is unsupported; continuing");
181.24 + } catch (Exception e) {
181.25 + System.err.println(laf + " is unsupported; continuing");
181.26 return;
181.27 }
181.28 SwingUtilities.updateComponentTreeUI(table);
181.29 @@ -92,8 +92,10 @@
181.30
181.31 public static void main(String[] args) throws Exception {
181.32 Test6888156 t = new Test6888156();
181.33 - t.test(new javax.swing.plaf.nimbus.NimbusLookAndFeel());
181.34 - t.test(new com.sun.java.swing.plaf.gtk.GTKLookAndFeel());
181.35 + t.test("javax.swing.plaf.nimbus.NimbusLookAndFeel");
181.36 + t.test("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
181.37 + for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
181.38 + t.test(laf.getClassName());
181.39 + }
181.40 }
181.41 }
181.42 -
182.1 --- a/test/javax/swing/JTextArea/6940863/bug6940863.java Tue Oct 12 13:34:59 2010 -0400
182.2 +++ b/test/javax/swing/JTextArea/6940863/bug6940863.java Mon Oct 18 11:25:28 2010 -0400
182.3 @@ -56,6 +56,7 @@
182.4 public static void main(String[] args) throws Exception {
182.5 if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) {
182.6 System.out.println("The test is suitable only for Windows OS. Skipped");
182.7 + return;
182.8 }
182.9
182.10 UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
183.1 --- a/test/sun/net/www/http/ChunkedInputStream/ChunkedCharEncoding.sh Tue Oct 12 13:34:59 2010 -0400
183.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
183.3 @@ -1,62 +0,0 @@
183.4 -#
183.5 -# Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
183.6 -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
183.7 -#
183.8 -# This code is free software; you can redistribute it and/or modify it
183.9 -# under the terms of the GNU General Public License version 2 only, as
183.10 -# published by the Free Software Foundation.
183.11 -#
183.12 -# This code is distributed in the hope that it will be useful, but WITHOUT
183.13 -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
183.14 -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
183.15 -# version 2 for more details (a copy is included in the LICENSE file that
183.16 -# accompanied this code).
183.17 -#
183.18 -# You should have received a copy of the GNU General Public License version
183.19 -# 2 along with this work; if not, write to the Free Software Foundation,
183.20 -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
183.21 -#
183.22 -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
183.23 -# or visit www.oracle.com if you need additional information or have any
183.24 -# questions.
183.25 -#
183.26 -
183.27 - # @test
183.28 - # @bug 6502503
183.29 - # @run shell/timeout=140 ChunkedCharEncoding.sh
183.30 - # @summary Http URL connection don't work when default encoding is Cp037: HTTP Transfer-Encoding:chunked
183.31 -
183.32 -OS=`uname -s`
183.33 -case "$OS" in
183.34 - SunOS | Linux )
183.35 - PS=":"
183.36 - FS="/"
183.37 - ;;
183.38 - CYGWIN* )
183.39 - PS=";"
183.40 - FS="/"
183.41 - ;;
183.42 - Windows* )
183.43 - PS=";"
183.44 - FS="\\"
183.45 - ;;
183.46 - * )
183.47 - echo "Unrecognized system!"
183.48 - exit 1;
183.49 - ;;
183.50 -esac
183.51 -
183.52 -# compile
183.53 -${TESTJAVA}${FS}bin${FS}javac -d . ${TESTSRC}${FS}TestAvailable.java
183.54 -
183.55 -# run with CP037 encoding specified.
183.56 -${TESTJAVA}${FS}bin${FS}java -Dfile.encoding=Cp037 TestAvailable 2>&1
183.57 -
183.58 -result=$?
183.59 -if [ "$result" -ne "0" ]; then
183.60 - exit 1
183.61 -fi
183.62 -
183.63 -# no failures, exit.
183.64 -exit 0
183.65 -
184.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
184.2 +++ b/test/sun/net/www/http/HttpClient/StreamingRetry.java Mon Oct 18 11:25:28 2010 -0400
184.3 @@ -0,0 +1,89 @@
184.4 +/*
184.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
184.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
184.7 + *
184.8 + * This code is free software; you can redistribute it and/or modify it
184.9 + * under the terms of the GNU General Public License version 2 only, as
184.10 + * published by the Free Software Foundation.
184.11 + *
184.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
184.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
184.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
184.15 + * version 2 for more details (a copy is included in the LICENSE file that
184.16 + * accompanied this code).
184.17 + *
184.18 + * You should have received a copy of the GNU General Public License version
184.19 + * 2 along with this work; if not, write to the Free Software Foundation,
184.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
184.21 + *
184.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
184.23 + * or visit www.oracle.com if you need additional information or have any
184.24 + * questions.
184.25 + */
184.26 +
184.27 +/*
184.28 + * @test
184.29 + * @bug 6672144
184.30 + * @summary HttpURLConnection.getInputStream sends POST request after failed chunked send
184.31 + */
184.32 +
184.33 +import java.net.HttpURLConnection;
184.34 +import java.net.ServerSocket;
184.35 +import java.net.URL;
184.36 +import java.io.IOException;
184.37 +import java.io.InputStream;
184.38 +import java.io.OutputStream;
184.39 +
184.40 +public class StreamingRetry implements Runnable {
184.41 + static final int ACCEPT_TIMEOUT = 20 * 1000; // 20 seconds
184.42 + ServerSocket ss;
184.43 +
184.44 + public static void main(String[] args) throws IOException {
184.45 + (new StreamingRetry()).instanceMain();
184.46 + }
184.47 +
184.48 + void instanceMain() throws IOException {
184.49 + test();
184.50 + if (failed > 0) throw new RuntimeException("Some tests failed");
184.51 + }
184.52 +
184.53 + void test() throws IOException {
184.54 + ss = new ServerSocket(0);
184.55 + ss.setSoTimeout(ACCEPT_TIMEOUT);
184.56 + int port = ss.getLocalPort();
184.57 +
184.58 + (new Thread(this)).start();
184.59 +
184.60 + try {
184.61 + URL url = new URL("http://localhost:" + port + "/");
184.62 + HttpURLConnection uc = (HttpURLConnection) url.openConnection();
184.63 + uc.setDoOutput(true);
184.64 + uc.setChunkedStreamingMode(4096);
184.65 + OutputStream os = uc.getOutputStream();
184.66 + os.write("Hello there".getBytes());
184.67 +
184.68 + InputStream is = uc.getInputStream();
184.69 + is.close();
184.70 + } catch (IOException expected) {
184.71 + //expected.printStackTrace();
184.72 + } finally {
184.73 + ss.close();
184.74 + }
184.75 + }
184.76 +
184.77 + // Server
184.78 + public void run() {
184.79 + try {
184.80 + (ss.accept()).close();
184.81 + (ss.accept()).close();
184.82 + ss.close();
184.83 + fail("The server shouldn't accept a second connection");
184.84 + } catch (IOException e) {
184.85 + //OK, the clien will close the server socket if successfull
184.86 + }
184.87 + }
184.88 +
184.89 + volatile int failed = 0;
184.90 + void fail() {failed++; Thread.dumpStack();}
184.91 + void fail(String msg) {System.err.println(msg); fail();}
184.92 +}
185.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
185.2 +++ b/test/sun/net/www/protocol/http/6550798/TestCache.java Mon Oct 18 11:25:28 2010 -0400
185.3 @@ -0,0 +1,133 @@
185.4 +/*
185.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
185.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
185.7 + *
185.8 + * This code is free software; you can redistribute it and/or modify it
185.9 + * under the terms of the GNU General Public License version 2 only, as
185.10 + * published by the Free Software Foundation.
185.11 + *
185.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
185.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
185.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
185.15 + * version 2 for more details (a copy is included in the LICENSE file that
185.16 + * accompanied this code).
185.17 + *
185.18 + * You should have received a copy of the GNU General Public License version
185.19 + * 2 along with this work; if not, write to the Free Software Foundation,
185.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
185.21 + *
185.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
185.23 + * or visit www.oracle.com if you need additional information or have any
185.24 + * questions.
185.25 + */
185.26 +
185.27 +import java.net.*;
185.28 +import java.io.*;
185.29 +import java.io.IOException;
185.30 +import java.io.InputStream;
185.31 +import java.io.OutputStream;
185.32 +import java.io.FileInputStream;
185.33 +import java.io.FileOutputStream;
185.34 +import java.io.BufferedInputStream;
185.35 +import java.io.ByteArrayInputStream;
185.36 +import java.io.PrintStream;
185.37 +import java.io.InputStream;
185.38 +import java.io.File;
185.39 +import java.net.CacheRequest;
185.40 +import java.net.CacheResponse;
185.41 +import java.net.ResponseCache;
185.42 +import java.net.URI;
185.43 +import java.net.URL;
185.44 +import java.net.URLConnection;
185.45 +import java.util.ArrayList;
185.46 +import java.util.HashMap;
185.47 +import java.util.Map;
185.48 +import java.util.List;
185.49 +import java.util.Iterator;
185.50 +import java.util.StringTokenizer;
185.51 +import java.util.jar.JarInputStream;
185.52 +import java.util.jar.JarFile;
185.53 +import java.security.AccessController;
185.54 +import java.security.PrivilegedAction;
185.55 +import java.security.PrivilegedExceptionAction;
185.56 +import java.security.PrivilegedActionException;
185.57 +import java.security.Principal;
185.58 +import java.security.cert.Certificate;
185.59 +import javax.net.ssl.SSLPeerUnverifiedException;
185.60 +
185.61 +public class TestCache extends java.net.ResponseCache {
185.62 + private boolean inCacheHandler = false;
185.63 + private boolean _downloading = false;
185.64 +
185.65 + public static volatile boolean fail = false;
185.66 +
185.67 + public static void reset() {
185.68 + // Set system wide cache handler
185.69 + System.out.println("install deploy cache handler");
185.70 + ResponseCache.setDefault(new TestCache());
185.71 + }
185.72 +
185.73 + public synchronized CacheResponse get(final URI uri, String rqstMethod,
185.74 + Map requestHeaders) throws IOException {
185.75 + System.out.println("get: " + uri);
185.76 + Thread.currentThread().dumpStack();
185.77 + return null;
185.78 + }
185.79 +
185.80 + public synchronized CacheRequest put(URI uri, URLConnection conn)
185.81 + throws IOException {
185.82 + System.out.println("put: " + uri);
185.83 + Thread.currentThread().dumpStack();
185.84 + URL url = uri.toURL();
185.85 + return new DeployCacheRequest(url, conn);
185.86 +
185.87 + }
185.88 +}
185.89 +
185.90 +class DeployByteArrayOutputStream extends java.io.ByteArrayOutputStream {
185.91 +
185.92 + private URL _url;
185.93 + private URLConnection _conn;
185.94 +
185.95 + DeployByteArrayOutputStream(URL url, URLConnection conn) {
185.96 + _url = url;
185.97 + _conn = conn;
185.98 + }
185.99 +
185.100 +
185.101 + public void close() throws IOException {
185.102 +
185.103 + System.out.println("contentLength: " + _conn.getContentLength());
185.104 + System.out.println("byte array size: " + size());
185.105 + if ( _conn.getContentLength() == size()) {
185.106 + System.out.println("correct content length");
185.107 + } else {
185.108 + System.out.println("wrong content length");
185.109 + System.out.println("TEST FAILED");
185.110 + TestCache.fail = true;
185.111 + }
185.112 + super.close();
185.113 + }
185.114 +}
185.115 +
185.116 +class DeployCacheRequest extends java.net.CacheRequest {
185.117 +
185.118 + private URL _url;
185.119 + private URLConnection _conn;
185.120 + private boolean _downloading = false;
185.121 +
185.122 + DeployCacheRequest(URL url, URLConnection conn) {
185.123 + System.out.println("DeployCacheRequest ctor for: " + url);
185.124 + _url = url;
185.125 + _conn = conn;
185.126 + }
185.127 +
185.128 + public void abort() {
185.129 + System.out.println("abort called");
185.130 + }
185.131 +
185.132 + public OutputStream getBody() throws IOException {
185.133 + System.out.println("getBody called");
185.134 + return new DeployByteArrayOutputStream(_url, _conn);
185.135 + }
185.136 +}
186.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
186.2 +++ b/test/sun/net/www/protocol/http/6550798/test.java Mon Oct 18 11:25:28 2010 -0400
186.3 @@ -0,0 +1,90 @@
186.4 +/*
186.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
186.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
186.7 + *
186.8 + * This code is free software; you can redistribute it and/or modify it
186.9 + * under the terms of the GNU General Public License version 2 only, as
186.10 + * published by the Free Software Foundation.
186.11 + *
186.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
186.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
186.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
186.15 + * version 2 for more details (a copy is included in the LICENSE file that
186.16 + * accompanied this code).
186.17 + *
186.18 + * You should have received a copy of the GNU General Public License version
186.19 + * 2 along with this work; if not, write to the Free Software Foundation,
186.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
186.21 + *
186.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
186.23 + * or visit www.oracle.com if you need additional information or have any
186.24 + * questions.
186.25 + */
186.26 +
186.27 +/**
186.28 + * @test
186.29 + * @bug 6550798
186.30 + * @summary Using InputStream.skip with ResponseCache will cause partial data to be cached
186.31 + * @run main/othervm test
186.32 + */
186.33 +
186.34 +import java.net.*;
186.35 +import com.sun.net.httpserver.*;
186.36 +import java.io.*;
186.37 +
186.38 +public class test {
186.39 +
186.40 + final static int LEN = 16 * 1024;
186.41 +
186.42 + public static void main(String[] args) throws Exception {
186.43 +
186.44 + TestCache.reset();
186.45 + HttpServer s = HttpServer.create (new InetSocketAddress(0), 10);
186.46 + s.createContext ("/", new HttpHandler () {
186.47 + public void handle (HttpExchange e) {
186.48 + try {
186.49 + byte[] buf = new byte [LEN];
186.50 + OutputStream o = e.getResponseBody();
186.51 + e.sendResponseHeaders(200, LEN);
186.52 + o.write (buf);
186.53 + e.close();
186.54 + } catch (IOException ex) {
186.55 + ex.printStackTrace();
186.56 + TestCache.fail = true;
186.57 + }
186.58 + }
186.59 + });
186.60 + s.start();
186.61 +
186.62 + System.out.println("http request with cache hander");
186.63 + URL u = new URL("http://127.0.0.1:"+s.getAddress().getPort()+"/f");
186.64 + URLConnection conn = u.openConnection();
186.65 +
186.66 + InputStream is = null;
186.67 + try {
186.68 + // this calls into TestCache.get
186.69 + byte[] buf = new byte[8192];
186.70 + is = new BufferedInputStream(conn.getInputStream());
186.71 +
186.72 + is.skip(1000);
186.73 +
186.74 + while (is.read(buf) != -1) {
186.75 + }
186.76 + } finally {
186.77 + if (is != null) {
186.78 + // this calls into TestCache.put
186.79 + // TestCache.put will check if the resource
186.80 + // should be cached
186.81 + is.close();
186.82 + }
186.83 + s.stop(0);
186.84 + }
186.85 +
186.86 + if (TestCache.fail) {
186.87 + System.out.println ("TEST FAILED");
186.88 + throw new RuntimeException ();
186.89 + } else {
186.90 + System.out.println ("TEST OK");
186.91 + }
186.92 + }
186.93 +}
187.1 --- a/test/sun/security/tools/jarsigner/crl.sh Tue Oct 12 13:34:59 2010 -0400
187.2 +++ b/test/sun/security/tools/jarsigner/crl.sh Mon Oct 18 11:25:28 2010 -0400
187.3 @@ -63,7 +63,15 @@
187.4 $KT -alias b -dname CN=b -keyalg rsa -genkey -validity 300
187.5 $KT -alias b -gencrl -id 5:1 -id 6:2 -file crl3
187.6
187.7 -$TESTJAVA${FS}bin${FS}jrunscript -e 'println(new File("crl1").toURI())' > uri
187.8 +cat > ToURI.java <<EOF
187.9 +class ToURI {
187.10 + public static void main(String[] args) throws Exception {
187.11 + System.out.println(new java.io.File("crl1").toURI());
187.12 + }
187.13 +}
187.14 +EOF
187.15 +$TESTJAVA${FS}bin${FS}javac ToURI.java
187.16 +$TESTJAVA${FS}bin${FS}java ToURI > uri
187.17 $KT -alias c -dname CN=c -keyalg rsa -genkey -validity 300 \
187.18 -ext crl=uri:`cat uri`
187.19