OpenJDK / jdk / jdk12
changeset 6977:58ca130ef652
Merge
author | acorn |
---|---|
date | Tue, 26 Oct 2010 14:43:21 -0400 |
parents | dc8fa18c4c60 8581cacbdee7 |
children | 2c819a885d10 |
files | jdk/make/common/Rules-SCCS.gmk jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedCharEncoding.sh langtools/test/tools/javac/processing/Xprint.java |
diffstat | 360 files changed, 14509 insertions(+), 2775 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Mon Oct 25 13:31:55 2010 -0400 +++ b/.hgignore Tue Oct 26 14:43:21 2010 -0400 @@ -1,3 +1,4 @@ ^build/ ^dist/ /nbproject/private/ +^webrev
--- a/.hgtags Mon Oct 25 13:31:55 2010 -0400 +++ b/.hgtags Tue Oct 26 14:43:21 2010 -0400 @@ -87,3 +87,5 @@ a6442d6bc38a44152e0662688213ce4d2701f42a jdk7-b110 69f3edf083477955b5bd2f754252c7504167d8e1 jdk7-b111 f960f117f1623629f64203e2b09a92a8f6f14ff5 jdk7-b112 +1fee41c7ed2b3388970a756a85aa693c0de8407a jdk7-b113 +750c1ccb2f2d1ddfa95ab6c7f897fdab2f87f7e9 jdk7-b114
--- a/.hgtags-top-repo Mon Oct 25 13:31:55 2010 -0400 +++ b/.hgtags-top-repo Tue Oct 26 14:43:21 2010 -0400 @@ -87,3 +87,5 @@ 2a02d4a6955c7c078aee9a604cb3be409800d82c jdk7-b110 9702d6fef68e17533ee7fcf5923b11ead3e912ce jdk7-b111 b852103caf73da70068473777ae867a457bb3ae1 jdk7-b112 +c1df968c4527bfab5f97662a89245f15d12d378b jdk7-b113 +27985a5c6e5268014d25d55886e0ecb96af4763d jdk7-b114
--- a/Makefile Mon Oct 25 13:31:55 2010 -0400 +++ b/Makefile Tue Oct 26 14:43:21 2010 -0400 @@ -558,9 +558,12 @@ # rule to test ################################################################ -.NOTPARALLEL: test +.NOTPARALLEL: test_run -test: test_clean test_start test_summary +test: + $(MAKE) test_run + +test_run: test_clean test_start test_summary test_start: @$(ECHO) "Tests started at `$(DATE)`" @@ -586,7 +589,7 @@ # Get failure list from log $(OUTPUTDIR)/test_failures.txt: $(OUTPUTDIR)/test_log.txt @$(RM) $@ - @( $(EGREP) '^FAILED:' $< || $(ECHO) "" ) > $@ + @( $(EGREP) '^FAILED:' $< || $(ECHO) "" ) | $(NAWK) 'length>0' > $@ # Get log file of all tests run JDK_TO_TEST := $(shell \ @@ -598,10 +601,11 @@ $(ECHO) "$(PRODUCT_HOME)"; \ fi \ ) +TEST_TARGETS=all $(OUTPUTDIR)/test_log.txt: $(RM) $@ - ( $(CD) test && \ - $(MAKE) NO_STOPPING=- PRODUCT_HOME=$(JDK_TO_TEST) \ + ( $(CD) test && \ + $(MAKE) NO_STOPPING=- PRODUCT_HOME=$(JDK_TO_TEST) $(TEST_TARGETS) \ ) | tee $@ ################################################################ @@ -614,7 +618,7 @@ # PHONY ################################################################ -.PHONY: all test test_start test_summary test_clean \ +.PHONY: all test test_run test_start test_summary test_clean \ generic_build_repo_series \ what clobber insane \ dev dev-build dev-sanity dev-clobber \
--- a/corba/.hgtags Mon Oct 25 13:31:55 2010 -0400 +++ b/corba/.hgtags Tue Oct 26 14:43:21 2010 -0400 @@ -87,3 +87,5 @@ 0e1f80fda2271f53d4bbb59ec3f301dfbcef6a0a jdk7-b110 640fa4d4e2ad4c2d7e4815c955026740d8c52b7a jdk7-b111 cc67fdc4fee9a5b25caee4e71b51a8ff24ae7d1a jdk7-b112 +a89a6c5be9d1a754868d3d359cbf7ad36aa95631 jdk7-b113 +88fddb73c5c4a4b50c319cbae9380caf5172ab45 jdk7-b114
--- a/hotspot/.hgtags Mon Oct 25 13:31:55 2010 -0400 +++ b/hotspot/.hgtags Tue Oct 26 14:43:21 2010 -0400 @@ -122,4 +122,6 @@ 2f25f2b8de2700a1822463b1bd3d02b5e218018f jdk7-b110 07b042e13dde4f3479ba9ec55120fcd5e8623323 jdk7-b111 5511edd5d719f3fc9fdd04879482026a3d2c8652 jdk7-b112 +beef35b96b81129c375d572357fb9548d9020db1 jdk7-b113 +68d6141ea19de3a9ba98ef753f0da41a61f736a0 jdk7-b114 5511edd5d719f3fc9fdd04879482026a3d2c8652 hs20-b01
--- a/hotspot/make/hotspot_version Mon Oct 25 13:31:55 2010 -0400 +++ b/hotspot/make/hotspot_version Tue Oct 26 14:43:21 2010 -0400 @@ -35,7 +35,7 @@ HS_MAJOR_VER=20 HS_MINOR_VER=0 -HS_BUILD_NUMBER=01 +HS_BUILD_NUMBER=02 JDK_MAJOR_VER=1 JDK_MINOR_VER=7
--- a/hotspot/src/share/vm/runtime/arguments.cpp Mon Oct 25 13:31:55 2010 -0400 +++ b/hotspot/src/share/vm/runtime/arguments.cpp Tue Oct 26 14:43:21 2010 -0400 @@ -2979,6 +2979,13 @@ UseCompressedOops = false; #endif +#if defined(_LP64) + if ((DumpSharedSpaces || RequireSharedSpaces) && UseCompressedOops) { + // Disable compressed oops with shared spaces + UseCompressedOops = false; + } +#endif + // Set object alignment values. set_object_alignment();
--- a/hotspot/src/share/vm/runtime/globals.hpp Mon Oct 25 13:31:55 2010 -0400 +++ b/hotspot/src/share/vm/runtime/globals.hpp Tue Oct 26 14:43:21 2010 -0400 @@ -3545,7 +3545,7 @@ product(uintx, SharedDummyBlockSize, 512*M, \ "Size of dummy block used to shift heap addresses (in bytes)") \ \ - product(uintx, SharedReadWriteSize, 12*M, \ + product(uintx, SharedReadWriteSize, NOT_LP64(12*M) LP64_ONLY(13*M), \ "Size of read-write space in permanent generation (in bytes)") \ \ product(uintx, SharedReadOnlySize, 10*M, \
--- a/jaxp/.hgtags Mon Oct 25 13:31:55 2010 -0400 +++ b/jaxp/.hgtags Tue Oct 26 14:43:21 2010 -0400 @@ -87,3 +87,5 @@ d422dbdd09766269344b796b3a46a5b3f74557e1 jdk7-b110 8106c747067c905d814a737a57fea0e29057b33f jdk7-b111 1b05254242881527b4d5d711295c0fe708c8823a jdk7-b112 +bc0c84ce54c34d3e8b0604b94da0d7c75c26755e jdk7-b113 +d57197d22c2bfc39d1a860040f655b466ab46f52 jdk7-b114
--- a/jaxws/.hgtags Mon Oct 25 13:31:55 2010 -0400 +++ b/jaxws/.hgtags Tue Oct 26 14:43:21 2010 -0400 @@ -87,3 +87,5 @@ 95ecac35fb11530752bd0404c9bf02bcfb30990e jdk7-b110 2575ebca96c7fb1b78f6ae025a97321210aba309 jdk7-b111 8e0f0054817f0f73fb33e80fb1333fb45b1d513d jdk7-b112 +d35c94fd22362f478f75b4bfcd2bef6a83cb9b3f jdk7-b113 +400f494c81c5ec87714b705648afbb3cb680bf73 jdk7-b114
--- a/jdk/.hgtags Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/.hgtags Tue Oct 26 14:43:21 2010 -0400 @@ -87,3 +87,5 @@ 176586cd040e4dd17a5ff6e91f72df10d7442453 jdk7-b110 fb63a2688db807a73e2a3de7d9bab298f1bff0e8 jdk7-b111 b53f226b1d91473ac54184afa827be07b87e0319 jdk7-b112 +61d3b9fbb26bdef56cfa41b9af5bc312a22cbeb8 jdk7-b113 +e250cef36ea05e627e7e6f7d75e5e19f529e2ba3 jdk7-b114
--- a/jdk/make/Makefile Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/make/Makefile Tue Oct 26 14:43:21 2010 -0400 @@ -75,7 +75,6 @@ import_fastdebug -- copy in the fastdebug components \n\ import_debug -- copy in the debug components \n\ modules -- build the jdk and jre module images (experimental) \n\ -sccs_get -- make sure all SCCS files are up-to-date (need SCCS) \n\ create_links -- create softlinks in Solaris 32bit build to 64bit dirs \n\ " @@ -278,21 +277,6 @@ $(OUTPUTDIR) $(TEMPDIR): $(MKDIR) -p $@ -# cleanup everything. If the workspace is not being built by the control -# workspace, and if it is a Teamware workspace, then see if there are -# any files which are not under SCCS control. -clean clobber:: -ifndef EXTERNALSANITYCONTROL - @if [ -d $(TOPDIR)/Codemgr_wsdata ]; then \ - $(ECHO) '\nPerforming workspace scan for remnant files.\n' \ - ' Any files listed below are not under SCCS control in the workspace\n' \ - ' and you should review them and possibly remove them manually:' ; \ - $(FIND) $(TOPDIR)/make $(TOPDIR)/src -type f | \ - $(SED) 's+SCCS/[ps]\.++' | $(SORT) | $(UNIQ) -c | $(NAWK) '$$1<2 {print $$2;}' ; \ - $(ECHO) 'End of workspace scan.' ; \ - fi -endif - # this should be the last rule in this file: all:: @if [ -r $(WARNING_FILE) ]; then \ @@ -341,16 +325,70 @@ include $(BUILDDIR)/common/internal/BinaryPlugs.gmk # -# Get top level sccs_get rule +# Test rule # -include $(BUILDDIR)/common/Rules-SCCS.gmk + +.NOTPARALLEL: test_run + +test: + $(MAKE) test_run + +test_run: test_clean test_start test_summary + +test_start: + @$(ECHO) "Tests started at `$(DATE)`" + +test_clean: + $(RM) $(OUTPUTDIR)/test_failures.txt $(OUTPUTDIR)/test_log.txt +test_summary: $(OUTPUTDIR)/test_failures.txt + @$(ECHO) "#################################################" + @$(ECHO) "Tests completed at `$(DATE)`" + @( $(EGREP) '^TEST STATS:' $(OUTPUTDIR)/test_log.txt \ + || $(ECHO) "No TEST STATS seen in log" ) + @$(ECHO) "For complete details see: $(OUTPUTDIR)/test_log.txt" + @$(ECHO) "#################################################" + @if [ -s $< ] ; then \ + $(ECHO) "ERROR: Test failure count: `$(CAT) $< | $(WC) -l`"; \ + $(CAT) $<; \ + exit 1; \ + else \ + $(ECHO) "Success! No failures detected"; \ + fi + +# Get failure list from log +$(OUTPUTDIR)/test_failures.txt: $(OUTPUTDIR)/test_log.txt + @$(RM) $@ + @( $(EGREP) '^FAILED:' $< || $(ECHO) "" ) | $(NAWK) 'length>0' > $@ + +# Get log file of all tests run +JDK_TO_TEST := $(shell \ + if [ -d "$(ABS_OUTPUTDIR)/j2sdk-image" ] ; then \ + $(ECHO) "$(ABS_OUTPUTDIR)/j2sdk-image"; \ + elif [ -d "$(ABS_OUTPUTDIR)/bin" ] ; then \ + $(ECHO) "$(ABS_OUTPUTDIR)"; \ + elif [ "$(PRODUCT_HOME)" != "" -a -d "$(PRODUCT_HOME)/bin" ] ; then \ + $(ECHO) "$(PRODUCT_HOME)"; \ + fi \ +) + +TEST_TARGETS=jdk_all +$(OUTPUTDIR)/test_log.txt: + $(RM) $@ + ( $(CD) ../test && \ + $(MAKE) NO_STOPPING=- PRODUCT_HOME=$(JDK_TO_TEST) $(TEST_TARGETS) \ + ) | tee $@ + +# # JPRT rules +# + include jprt.gmk # # Phonies to avoid accidents. # .PHONY: all build clean clobber optimized debug fastdebug create_links \ - import import_product import_fastdebug import_debug + import import_product import_fastdebug import_debug \ + test test_run test_start test_clean test_summary
--- a/jdk/make/common/Cscope.gmk Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/make/common/Cscope.gmk Tue Oct 26 14:43:21 2010 -0400 @@ -76,7 +76,7 @@ # What files should we include? A simple rule might be just those files under # SCM control, however this would miss files we create like the opcodes and # CClassHeaders. The following attempts to find everything that is *useful*. -# (.del files are created by sccsrm, demo directories contain many .java files +# (demo directories contain many .java files # that probably aren't useful for development, and the pkgarchive may contain # duplicates of files within the source hierarchy). The ordering of the .raw # file is an attempt to make cscope display the most relevant files first.
--- a/jdk/make/common/Defs.gmk Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/make/common/Defs.gmk Tue Oct 26 14:43:21 2010 -0400 @@ -334,7 +334,7 @@ DOCSDIRSUFFIX = # The MESSAGE, WARNING and ERROR files are used to store sanityck and -# SCCS check messages, warnings and errors. +# warnings and errors. ifndef ERROR_FILE ERROR_FILE = $(OUTPUTDIR)/sanityCheckErrors.txt endif @@ -634,38 +634,6 @@ VERSION_DEFINES = -DRELEASE='"$(RELEASE)"' -# Note: As a rule, GNU Make rules should not appear in any of the -# Defs*.gmk files. These were added for Kestrel-Solaris and do address -# a TeamWare bug. They should be moved elsewhere for Merlin. -# -# Override gnumake built-in rules which do sccs get operations badly. -# (They put the checked out code in the current directory, not in the -# directory of the original file.) -# Since this is a symptom of a teamware failure, complain and die on the spot. - -# This message immediately goes to stdout and the build terminates. -define SCCS-trouble -$(error \ -"ERROR: File $@ referenced while building in $(CURRENT_DIRECTORY) \ - is out of date with respect to its SCCS file $<. \ - This can happen from an unresolved Teamware conflict, a file movement, or \ - a failure in which SCCS files are updated but the 'sccs get' was not done. \ - You should double check for other out of date files in your workspace. \ - Or run: cd $(TOPDIR) && $(MAKE) sccs_get") -endef - -%:: s.% - @$(SCCS-trouble) -%:: SCCS/s.% - @$(SCCS-trouble) - @$(ECHO) " is out of date with respect to its SCCS file." >> $(WARNING_FILE) - @$(ECHO) " This file may be from an unresolved Teamware conflict." >> $(WARNING_FILE) - @$(ECHO) " This is also a symptom of a Teamware bringover/putback failure" >> $(WARNING_FILE) - @$(ECHO) " in which SCCS files are updated but not checked out." >> $(WARNING_FILE) - @$(ECHO) " Check for other out of date files in your workspace." >> $(WARNING_FILE) - @$(ECHO) "" >> $(WARNING_FILE) - @#exit 666 - ifdef INSANE export INSANE endif
--- a/jdk/make/common/Rules-SCCS.gmk Mon Oct 25 13:31:55 2010 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -# -# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# -# Only get these rules if SCCS is available -# - -ifdef SCCS - -# SCCS command to extract out latest source -SCCS_GET=$(SCCS) get -s - -# -# Make sure all files in workspace are fresh -# -TEMP_ALL_FILES=$(JDK_TOPDIR)/temp_filelist -$(TEMP_ALL_FILES): $(JDK_TOPDIR)/Codemgr_wsdata/nametable - $(prep-target) - @$(CUT) -d' ' -f1 $< \ - | $(GREP) -v '^VERSION' \ - | $(GREP) -v '^deleted_files' \ - | $(GREP) -v '^Codemgr_wsdata' > $@ - -sccs_get: $(TEMP_ALL_FILES) - @$(PRINTF) "Workspace has %d files\n" `$(CAT) $< | $(WC) -l` - @count=0; \ - for i in `$(CAT) $<` ; do \ - f=$(JDK_TOPDIR)/$$i; \ - count=`$(EXPR) $$count '+' 1`; \ - if [ `$(EXPR) $$count '%' 100` = 0 ] ; then \ - $(PRINTF) "\rChecked $$count files"; \ - fi; \ - if [ ! -f $$f ] ; then \ - $(PRINTF) "\r$(SCCS_GET) $$f\n"; \ - (cd `$(DIRNAME) $$f` && $(SCCS_GET) `$(BASENAME) $$f`); \ - elif /usr/bin/test $$f -ot `$(DIRNAME) $$f`/SCCS/s.`$(BASENAME) $$f` ; then \ - $(PRINTF) "\r$(SCCS_GET) $$f\n"; \ - (cd `$(DIRNAME) $$f` && $(SCCS_GET) `$(BASENAME) $$f`); \ - fi; \ - done; \ - $(PRINTF) "\rChecked $$count files\n" - -# -# Phonies to avoid accidents. -# -.PHONY: sccs_get - -endif
--- a/jdk/make/common/internal/Resources.gmk Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/make/common/internal/Resources.gmk Tue Oct 26 14:43:21 2010 -0400 @@ -251,13 +251,13 @@ # Make sure the build rule creates all the properties resources: -ifneq ($(PROPERTIES_FILES),) +ifneq ($(strip $(PROPERTIES_FILES)),) resources: strip_prop_options_clean strip_all_props clobber clean:: $(RM) $(STRIP_PROP_FILES) $(STRIP_PROP_options) endif -ifneq ($(COMPILED_PROPERTIES),) +ifneq ($(strip $(COMPILED_PROPERTIES)),) resources: compile_prop_options_clean compile_all_props clobber clean:: $(RM) $(COMPILE_PROP_JAVA_FILES) $(COMPILE_PROP_options)
--- a/jdk/make/common/shared/Defs-javadoc.gmk Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/make/common/shared/Defs-javadoc.gmk Tue Oct 26 14:43:21 2010 -0400 @@ -45,7 +45,7 @@ PLUGIN2_FIRST_COPYRIGHT_YEAR = 2007 # Oracle name -COMPANY_NAME = Oracle and/or its affiliates +FULL_COMPANY_NAME = Oracle and/or its affiliates # Copyright address COMPANY_ADDRESS = 500 Oracle Parkway<br>Redwood Shores, CA 94065 USA.
--- a/jdk/make/common/shared/Defs-utils.gmk Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/make/common/shared/Defs-utils.gmk Tue Oct 26 14:43:21 2010 -0400 @@ -33,7 +33,7 @@ # UTILS_COMMAND_PATH # /usr/bin/ # UTILS_USR_BIN_PATH -# /usr/ccs/bin/ (sccs, m4, lex, yacc, as, ar, strip, mcs) +# /usr/ccs/bin/ (m4, lex, yacc, as, ar, strip, mcs) # UTILS_CCS_BIN_PATH # Dev Tools: zip, unzip, etc that we may have special versions of # UTILS_DEVTOOL_PATH @@ -117,7 +117,6 @@ RMDIR = $(UTILS_COMMAND_PATH)rmdir RPM = $(UTILS_COMMAND_PATH)rpm RPMBUILD = $(UTILS_COMMAND_PATH)rpmbuild -SCCS = $(UTILS_CCS_BIN_PATH)sccs SED = $(UTILS_COMMAND_PATH)sed SH = $(UTILS_COMMAND_PATH)sh SHOWREV = $(UTILS_USR_BIN_PATH)showrev @@ -183,7 +182,7 @@ NAWK = $(USRBIN_PATH)gawk # Intrinsic unix command, with backslash-escaped character interpretation ECHO = /bin/echo -e - # These are really in UTILS_USR_BIN_PATH on Linux (only sccs is not) + # These are really in UTILS_USR_BIN_PATH on Linux AR = $(UTILS_USR_BIN_PATH)ar AS = $(UTILS_USR_BIN_PATH)as LD = $(UTILS_USR_BIN_PATH)ld
--- a/jdk/make/common/shared/Defs.gmk Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/make/common/shared/Defs.gmk Tue Oct 26 14:43:21 2010 -0400 @@ -219,7 +219,7 @@ PRODUCT_NAME = Java(TM) PRODUCT_SUFFIX = SE Runtime Environment JDK_RC_PLATFORM_NAME = Platform SE - COMPANY_NAME = Oracle + COMPANY_NAME = Oracle Corporation endif RUNTIME_NAME = $(PRODUCT_NAME) $(PRODUCT_SUFFIX) @@ -341,7 +341,33 @@ include $(_PRIVATE_DEFS_FILE) endif +# OUTPUTDIR: Location of all output for the build +ifdef ALT_OUTPUTDIR + OUTPUTDIR:=$(subst \,/,$(ALT_OUTPUTDIR)) + # Assumes this is absolute (checks later) + ABS_OUTPUTDIR:=$(OUTPUTDIR) +else + ifndef _OUTPUTDIR + # Default: Get "build" parent directory, which should always exist + ifndef BUILD_PARENT_DIRECTORY + BUILD_PARENT_DIRECTORY=$(BUILDDIR)/.. + endif + ifdef OPENJDK + _OUTPUTDIRNAME=$(PLATFORM)-$(ARCH)$(OPENJDK_SUFFIX) + else + _OUTPUTDIRNAME=$(PLATFORM)-$(ARCH) + endif + _OUTPUTDIR=$(BUILD_PARENT_DIRECTORY)/build/$(_OUTPUTDIRNAME) + endif + OUTPUTDIR:=$(_OUTPUTDIR) +endif +# Check for spaces and null value +OUTPUTDIR:=$(call AltCheckSpaces,OUTPUTDIR) +OUTPUTDIR:=$(call AltCheckValue,OUTPUTDIR) + # Get platform specific settings +# NB: OUTPUTDIR must be defined. Otherwise hotspot import detection will not work correctly +# On other hand this must be included early as it provides platform specific defines such as FullPath include $(JDK_MAKE_SHARED_DIR)/Defs-$(PLATFORM).gmk # Components @@ -478,32 +504,6 @@ CACERTS_FILE:=$(call AltCheckSpaces,CACERTS_FILE) CACERTS_FILE:=$(call AltCheckValue,CACERTS_FILE) -# OUTPUTDIR: Location of all output for the build -ifdef ALT_OUTPUTDIR - OUTPUTDIR:=$(subst \,/,$(ALT_OUTPUTDIR)) - # Assumes this is absolute (checks later) - ABS_OUTPUTDIR:=$(OUTPUTDIR) -else - ifndef _OUTPUTDIR - # Default: Get "build" parent directory, which should always exist - ifndef BUILD_PARENT_DIRECTORY - BUILD_PARENT_DIRECTORY=$(BUILDDIR)/.. - endif - ABS_BUILD_PARENT_DIRECTORY:=$(call FullPath,$(BUILD_PARENT_DIRECTORY)) - ifdef OPENJDK - _OUTPUTDIRNAME=$(PLATFORM)-$(ARCH)$(OPENJDK_SUFFIX) - else - _OUTPUTDIRNAME=$(PLATFORM)-$(ARCH) - endif - _OUTPUTDIR=$(BUILD_PARENT_DIRECTORY)/build/$(_OUTPUTDIRNAME) - ABS_OUTPUTDIR:=$(ABS_BUILD_PARENT_DIRECTORY)/build/$(_OUTPUTDIRNAME) - endif - OUTPUTDIR:=$(_OUTPUTDIR) -endif -# Check for spaces and null value -OUTPUTDIR:=$(call AltCheckSpaces,OUTPUTDIR) -OUTPUTDIR:=$(call AltCheckValue,OUTPUTDIR) - # # When signing the JCE framework and provider, we could be using built # bits on a read-only filesystem. If so, this test will fail and crash @@ -519,7 +519,13 @@ # Define absolute path if needed and check for spaces and null value ifndef ABS_OUTPUTDIR - ABS_OUTPUTDIR:=$(call FullPath,$(OUTPUTDIR)) + ifdef _OUTPUTDIRNAME + #Could not define this at the same time as _OUTPUTDIRNAME as FullPath is not defined at that point + ABS_BUILD_PARENT_DIRECTORY:=$(call FullPath,$(BUILD_PARENT_DIRECTORY)) + ABS_OUTPUTDIR:=$(ABS_BUILD_PARENT_DIRECTORY)/build/$(_OUTPUTDIRNAME) + else + ABS_OUTPUTDIR:=$(call FullPath,$(OUTPUTDIR)) + endif endif ABS_OUTPUTDIR:=$(call AltCheckSpaces,ABS_OUTPUTDIR) ABS_OUTPUTDIR:=$(call AltCheckValue,ABS_OUTPUTDIR) @@ -572,10 +578,23 @@ ANT_HOME := $(call DirExists,$(JDK_DEVTOOLS_DIR)/share/ant/latest,,) endif endif + +# There are few problems with ant we need to workaround: +# 1) ant is using temporary directory java.io.tmpdir +# However, this directory is not unique enough and two separate ant processes +# can easily end up using the exact same temp directory. This may lead to weird build failures +# To workaround this we will define tmp dir explicitly +# 2) ant attempts to detect JDK location based on java.exe location +# This is fragile as developer may have JRE first on the PATH. +# To workaround this we will specify JAVA_HOME explicitly + +ANT_TMPDIR = $(ABS_OUTPUTDIR)/tmp +ANT_WORKAROUNDS = ANT_OPTS=-Djava.io.tmpdir='$(ANT_TMPDIR)' JAVA_HOME='$(BOOTDIR)' + ifeq ($(ANT_HOME),) - ANT = ant + ANT = $(ANT_WORKAROUNDS) ant else - ANT = $(ANT_HOME)/bin/ant + ANT = $(ANT_WORKAROUNDS) $(ANT_HOME)/bin/ant endif ifdef ALT_COPYRIGHT_YEAR
--- a/jdk/make/docs/Makefile Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/make/docs/Makefile Tue Oct 26 14:43:21 2010 -0400 @@ -57,7 +57,7 @@ # Common Java trademark line JAVA_TRADEMARK_LINE = Java is a trademark or registered trademark of \ -$(COMPANY_NAME) in the US and other countries. +$(FULL_COMPANY_NAME) in the US and other countries. # # Definitions for imported components
--- a/jdk/make/java/java/FILES_java.gmk Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/make/java/java/FILES_java.gmk Tue Oct 26 14:43:21 2010 -0400 @@ -284,6 +284,7 @@ java/util/concurrent/CancellationException.java \ java/util/concurrent/CompletionService.java \ java/util/concurrent/ConcurrentHashMap.java \ + java/util/concurrent/ConcurrentLinkedDeque.java \ java/util/concurrent/ConcurrentLinkedQueue.java \ java/util/concurrent/ConcurrentMap.java \ java/util/concurrent/ConcurrentNavigableMap.java \
--- a/jdk/make/jprt.properties Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/make/jprt.properties Tue Oct 26 14:43:21 2010 -0400 @@ -25,43 +25,265 @@ # Properties for jprt -# Use whatever release that the submitted job requests +# At submit time, the release supplied will be in jprt.submit.release +# and will be one of the official release names defined in jprt. +# jprt supports property value expansion using ${property.name} syntax. + +# This tells jprt what default release we want to build jprt.tools.default.release=${jprt.submit.release} # The different build flavors we want, we override here so we just get these 2 jprt.build.flavors=product,fastdebug -# Standard test target for everybody -jprt.test.targets=*-*-*-jvm98 +# Define the Windows we want (temporary) +jprt.my.windows.i586.jdk7b107=windows_i586_5.0 +jprt.my.windows.i586.jdk7temp=windows_i586_5.0 +jprt.my.windows.i586.jdk7=windows_i586_5.1 +jprt.my.windows.i586=${jprt.my.windows.i586.${jprt.tools.default.release}} + +# Standard list of jprt build targets for this source tree +jprt.build.targets= \ + solaris_sparc_5.10-{product|fastdebug}, \ + solaris_sparcv9_5.10-{product|fastdebug}, \ + solaris_i586_5.10-{product|fastdebug}, \ + solaris_x64_5.10-{product|fastdebug}, \ + linux_i586_2.6-{product|fastdebug}, \ + linux_x64_2.6-{product|fastdebug}, \ + ${jprt.my.windows.i586}-{product|fastdebug}, \ + windows_x64_5.2-{product|fastdebug} + +# Standard vm test target +jprt.test.targets= \ + solaris_sparc_5.10-product-c1-jvm98, \ + solaris_sparcv9_5.10-product-c2-jvm98, \ + solaris_i586_5.10-product-c1-jvm98, \ + solaris_x64_5.10-product-c2-jvm98, \ + linux_i586_2.6-product-{c1|c2}-jvm98, \ + linux_x64_2.6-product-c2-jvm98, \ + ${jprt.my.windows.i586}-product-c1-jvm98, \ + windows_x64_5.2-product-c2-jvm98 + +# User can select the test set with jprt submit "-testset name" option +jprt.my.test.set=${jprt.test.set} -# Test targets in test/Makefile (some longer running tests only test c2) -jprt.make.rule.test.targets= \ - *-product-*-jdk_beans1, \ - *-product-*-jdk_beans2, \ - *-product-*-jdk_beans3, \ - *-product-*-jdk_io, \ - *-product-*-jdk_lang, \ - *-product-*-jdk_management1, \ - *-product-*-jdk_management2, \ - *-product-*-jdk_math, \ - *-product-*-jdk_misc, \ - *-product-*-jdk_net, \ - *-product-*-jdk_nio1, \ - *-product-*-jdk_nio2, \ - *-product-*-jdk_nio3, \ - *-product-*-jdk_security1, \ - *-product-*-jdk_security2, \ - *-product-*-jdk_security3, \ - *-product-*-jdk_text, \ - *-product-*-jdk_tools1, \ - *-product-*-jdk_tools2, \ - *-product-*-jdk_util +# Default jdk test targets in test/Makefile (no fastdebug & limited c2) +jprt.make.rule.default.test.targets= \ + \ + solaris_sparc_5.10-product-c1-jdk_beans1, \ + solaris_sparcv9_5.10-product-c2-jdk_beans1, \ + solaris_i586_5.10-product-c1-jdk_beans1, \ + solaris_x64_5.10-product-c2-jdk_beans1, \ + linux_i586_2.6-product-{c1|c2}-jdk_beans1, \ + linux_x64_2.6-product-c2-jdk_beans1, \ + ${jprt.my.windows.i586}-product-c1-jdk_beans1, \ + windows_x64_5.2-product-c2-jdk_beans1, \ + \ + solaris_sparc_5.10-product-c1-jdk_io, \ + solaris_sparcv9_5.10-product-c2-jdk_io, \ + solaris_i586_5.10-product-c1-jdk_io, \ + solaris_x64_5.10-product-c2-jdk_io, \ + linux_i586_2.6-product-{c1|c2}-jdk_io, \ + linux_x64_2.6-product-c2-jdk_io, \ + ${jprt.my.windows.i586}-product-c1-jdk_io, \ + windows_x64_5.2-product-c2-jdk_io, \ + \ + solaris_sparc_5.10-product-c1-jdk_lang, \ + solaris_sparcv9_5.10-product-c2-jdk_lang, \ + solaris_i586_5.10-product-c1-jdk_lang, \ + solaris_x64_5.10-product-c2-jdk_lang, \ + linux_i586_2.6-product-{c1|c2}-jdk_lang, \ + linux_x64_2.6-product-c2-jdk_lang, \ + ${jprt.my.windows.i586}-product-c1-jdk_lang, \ + windows_x64_5.2-product-c2-jdk_lang, \ + \ + solaris_sparc_5.10-product-c1-jdk_math, \ + solaris_sparcv9_5.10-product-c2-jdk_math, \ + solaris_i586_5.10-product-c1-jdk_math, \ + solaris_x64_5.10-product-c2-jdk_math, \ + linux_i586_2.6-product-{c1|c2}-jdk_math, \ + linux_x64_2.6-product-c2-jdk_math, \ + ${jprt.my.windows.i586}-product-c1-jdk_math, \ + windows_x64_5.2-product-c2-jdk_math, \ + \ + solaris_sparc_5.10-product-c1-jdk_misc, \ + solaris_sparcv9_5.10-product-c2-jdk_misc, \ + solaris_i586_5.10-product-c1-jdk_misc, \ + solaris_x64_5.10-product-c2-jdk_misc, \ + linux_i586_2.6-product-{c1|c2}-jdk_misc, \ + linux_x64_2.6-product-c2-jdk_misc, \ + ${jprt.my.windows.i586}-product-c1-jdk_misc, \ + windows_x64_5.2-product-c2-jdk_misc, \ + \ + solaris_sparc_5.10-product-c1-jdk_net, \ + solaris_sparcv9_5.10-product-c2-jdk_net, \ + solaris_i586_5.10-product-c1-jdk_net, \ + solaris_x64_5.10-product-c2-jdk_net, \ + linux_i586_2.6-product-{c1|c2}-jdk_net, \ + linux_x64_2.6-product-c2-jdk_net, \ + ${jprt.my.windows.i586}-product-c1-jdk_net, \ + windows_x64_5.2-product-c2-jdk_net, \ + \ + solaris_sparc_5.10-product-c1-jdk_nio1, \ + solaris_sparcv9_5.10-product-c2-jdk_nio1, \ + solaris_i586_5.10-product-c1-jdk_nio1, \ + solaris_x64_5.10-product-c2-jdk_nio1, \ + linux_i586_2.6-product-{c1|c2}-jdk_nio1, \ + linux_x64_2.6-product-c2-jdk_nio1, \ + ${jprt.my.windows.i586}-product-c1-jdk_nio1, \ + windows_x64_5.2-product-c2-jdk_nio1, \ + \ + solaris_sparc_5.10-product-c1-jdk_nio2, \ + solaris_sparcv9_5.10-product-c2-jdk_nio2, \ + solaris_i586_5.10-product-c1-jdk_nio2, \ + solaris_x64_5.10-product-c2-jdk_nio2, \ + linux_i586_2.6-product-{c1|c2}-jdk_nio2, \ + linux_x64_2.6-product-c2-jdk_nio2, \ + ${jprt.my.windows.i586}-product-c1-jdk_nio2, \ + windows_x64_5.2-product-c2-jdk_nio2, \ + \ + solaris_sparc_5.10-product-c1-jdk_nio3, \ + solaris_sparcv9_5.10-product-c2-jdk_nio3, \ + solaris_i586_5.10-product-c1-jdk_nio3, \ + solaris_x64_5.10-product-c2-jdk_nio3, \ + linux_i586_2.6-product-{c1|c2}-jdk_nio3, \ + linux_x64_2.6-product-c2-jdk_nio3, \ + ${jprt.my.windows.i586}-product-c1-jdk_nio3, \ + windows_x64_5.2-product-c2-jdk_nio3, \ + \ + solaris_sparc_5.10-product-c1-jdk_security1, \ + solaris_sparcv9_5.10-product-c2-jdk_security1, \ + solaris_i586_5.10-product-c1-jdk_security1, \ + solaris_x64_5.10-product-c2-jdk_security1, \ + linux_i586_2.6-product-{c1|c2}-jdk_security1, \ + linux_x64_2.6-product-c2-jdk_security1, \ + ${jprt.my.windows.i586}-product-c1-jdk_security1, \ + windows_x64_5.2-product-c2-jdk_security1, \ + \ + solaris_sparc_5.10-product-c1-jdk_text, \ + solaris_sparcv9_5.10-product-c2-jdk_text, \ + solaris_i586_5.10-product-c1-jdk_text, \ + solaris_x64_5.10-product-c2-jdk_text, \ + linux_i586_2.6-product-{c1|c2}-jdk_text, \ + linux_x64_2.6-product-c2-jdk_text, \ + ${jprt.my.windows.i586}-product-c1-jdk_text, \ + windows_x64_5.2-product-c2-jdk_text, \ + \ + solaris_sparc_5.10-product-c1-jdk_tools1, \ + solaris_sparcv9_5.10-product-c2-jdk_tools1, \ + solaris_i586_5.10-product-c1-jdk_tools1, \ + solaris_x64_5.10-product-c2-jdk_tools1, \ + linux_i586_2.6-product-{c1|c2}-jdk_tools1, \ + linux_x64_2.6-product-c2-jdk_tools1, \ + ${jprt.my.windows.i586}-product-c1-jdk_tools1, \ + windows_x64_5.2-product-c2-jdk_tools1, \ + \ + solaris_sparc_5.10-product-c1-jdk_util, \ + solaris_sparcv9_5.10-product-c2-jdk_util, \ + solaris_i586_5.10-product-c1-jdk_util, \ + solaris_x64_5.10-product-c2-jdk_util, \ + linux_i586_2.6-product-{c1|c2}-jdk_util, \ + linux_x64_2.6-product-c2-jdk_util, \ + ${jprt.my.windows.i586}-product-c1-jdk_util, \ + windows_x64_5.2-product-c2-jdk_util -# Some of these are crashing Xvfb or windows manager, need dedicated DISPLAY per test batch -jprt2.make.rule.test.targets= \ - *-product-*-jdk_awt, \ - *-product-*-jdk_rmi, \ - *-product-*-jdk_swing, \ +# All jdk test targets in test/Makefile (still no fastdebug & limited c2) +jprt.make.rule.all.test.targets= \ + \ + ${jprt.make.rule.default.test.targets}, \ + \ + solaris_sparc_5.10-product-c1-jdk_awt, \ + solaris_sparcv9_5.10-product-c2-jdk_awt, \ + solaris_i586_5.10-product-c1-jdk_awt, \ + solaris_x64_5.10-product-c2-jdk_awt, \ + linux_i586_2.6-product-{c1|c2}-jdk_awt, \ + linux_x64_2.6-product-c2-jdk_awt, \ + ${jprt.my.windows.i586}-product-c1-jdk_awt, \ + windows_x64_5.2-product-c2-jdk_awt, \ + \ + solaris_sparc_5.10-product-c1-jdk_beans2, \ + solaris_sparcv9_5.10-product-c2-jdk_beans2, \ + solaris_i586_5.10-product-c1-jdk_beans2, \ + solaris_x64_5.10-product-c2-jdk_beans2, \ + linux_i586_2.6-product-{c1|c2}-jdk_beans2, \ + linux_x64_2.6-product-c2-jdk_beans2, \ + ${jprt.my.windows.i586}-product-c1-jdk_beans2, \ + windows_x64_5.2-product-c2-jdk_beans2, \ + \ + solaris_sparc_5.10-product-c1-jdk_beans3, \ + solaris_sparcv9_5.10-product-c2-jdk_beans3, \ + solaris_i586_5.10-product-c1-jdk_beans3, \ + solaris_x64_5.10-product-c2-jdk_beans3, \ + linux_i586_2.6-product-{c1|c2}-jdk_beans3, \ + linux_x64_2.6-product-c2-jdk_beans3, \ + ${jprt.my.windows.i586}-product-c1-jdk_beans3, \ + windows_x64_5.2-product-c2-jdk_beans3, \ + \ + solaris_sparc_5.10-product-c1-jdk_management1, \ + solaris_sparcv9_5.10-product-c2-jdk_management1, \ + solaris_i586_5.10-product-c1-jdk_management1, \ + solaris_x64_5.10-product-c2-jdk_management1, \ + linux_i586_2.6-product-{c1|c2}-jdk_management1, \ + linux_x64_2.6-product-c2-jdk_management1, \ + ${jprt.my.windows.i586}-product-c1-jdk_management1, \ + windows_x64_5.2-product-c2-jdk_management1, \ + \ + solaris_sparc_5.10-product-c1-jdk_management2, \ + solaris_sparcv9_5.10-product-c2-jdk_management2, \ + solaris_i586_5.10-product-c1-jdk_management2, \ + solaris_x64_5.10-product-c2-jdk_management2, \ + linux_i586_2.6-product-{c1|c2}-jdk_management2, \ + linux_x64_2.6-product-c2-jdk_management2, \ + ${jprt.my.windows.i586}-product-c1-jdk_management2, \ + windows_x64_5.2-product-c2-jdk_management2, \ + \ + solaris_sparc_5.10-product-c1-jdk_rmi, \ + solaris_sparcv9_5.10-product-c2-jdk_rmi, \ + solaris_i586_5.10-product-c1-jdk_rmi, \ + solaris_x64_5.10-product-c2-jdk_rmi, \ + linux_i586_2.6-product-{c1|c2}-jdk_rmi, \ + linux_x64_2.6-product-c2-jdk_rmi, \ + ${jprt.my.windows.i586}-product-c1-jdk_rmi, \ + windows_x64_5.2-product-c2-jdk_rmi, \ + \ + solaris_sparc_5.10-product-c1-jdk_security2, \ + solaris_sparcv9_5.10-product-c2-jdk_security2, \ + solaris_i586_5.10-product-c1-jdk_security2, \ + solaris_x64_5.10-product-c2-jdk_security2, \ + linux_i586_2.6-product-{c1|c2}-jdk_security2, \ + linux_x64_2.6-product-c2-jdk_security2, \ + ${jprt.my.windows.i586}-product-c1-jdk_security2, \ + windows_x64_5.2-product-c2-jdk_security2, \ + \ + solaris_sparc_5.10-product-c1-jdk_security3, \ + solaris_sparcv9_5.10-product-c2-jdk_security3, \ + solaris_i586_5.10-product-c1-jdk_security3, \ + solaris_x64_5.10-product-c2-jdk_security3, \ + linux_i586_2.6-product-{c1|c2}-jdk_security3, \ + linux_x64_2.6-product-c2-jdk_security3, \ + ${jprt.my.windows.i586}-product-c1-jdk_security3, \ + windows_x64_5.2-product-c2-jdk_security3, \ + \ + solaris_sparc_5.10-product-c1-jdk_swing, \ + solaris_sparcv9_5.10-product-c2-jdk_swing, \ + solaris_i586_5.10-product-c1-jdk_swing, \ + solaris_x64_5.10-product-c2-jdk_swing, \ + linux_i586_2.6-product-{c1|c2}-jdk_swing, \ + linux_x64_2.6-product-c2-jdk_swing, \ + ${jprt.my.windows.i586}-product-c1-jdk_swing, \ + windows_x64_5.2-product-c2-jdk_swing, \ + \ + solaris_sparc_5.10-product-c1-jdk_tools2, \ + solaris_sparcv9_5.10-product-c2-jdk_tools2, \ + solaris_i586_5.10-product-c1-jdk_tools2, \ + solaris_x64_5.10-product-c2-jdk_tools2, \ + linux_i586_2.6-product-{c1|c2}-jdk_tools2, \ + linux_x64_2.6-product-c2-jdk_tools2, \ + ${jprt.my.windows.i586}-product-c1-jdk_tools2, \ + windows_x64_5.2-product-c2-jdk_tools2 + +# Select list to use (allow for testset to be empty too) +jprt.make.rule..test.targets=${jprt.make.rule.default.test.targets} +jprt.make.rule.test.targets=${jprt.make.rule.${jprt.my.test.set}.test.targets} # Directories to be excluded from the source bundles jprt.bundle.exclude.src.dirs=build dist webrev
--- a/jdk/make/mkdemo/Makefile Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/make/mkdemo/Makefile Tue Oct 26 14:43:21 2010 -0400 @@ -31,7 +31,7 @@ PRODUCT = demos include $(BUILDDIR)/common/Defs.gmk -SUBDIRS = jni +SUBDIRS = jni nio SUBDIRS_desktop = applets jfc SUBDIRS_management = management SUBDIRS_misc = scripting
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/make/mkdemo/nio/Makefile Tue Oct 26 14:43:21 2010 -0400 @@ -0,0 +1,39 @@ +# +# Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# +# Makefile for building the jfc demos +# + +BUILDDIR = ../.. +PRODUCT = demos +include $(BUILDDIR)/common/Defs.gmk + +SUBDIRS = zipfs +include $(BUILDDIR)/common/Subdirs.gmk + +all build clean clobber:: + $(SUBDIRS-loop) +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/make/mkdemo/nio/zipfs/Makefile Tue Oct 26 14:43:21 2010 -0400 @@ -0,0 +1,44 @@ +# +# Copyright (c) 1997, 2002, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# +# Makefile to build the ZipFileSystem demo. +# + +BUILDDIR = ../../.. +PRODUCT = demo/zipfs +DEMONAME = zipfs +include $(BUILDDIR)/common/Defs.gmk + +DEMO_ROOT = $(SHARE_SRC)/demo/nio/$(DEMONAME) +DEMO_TOPFILES = ./README.txt +DEMO_SRCDIR = $(DEMO_ROOT) +DEMO_DESTDIR = $(DEMODIR)/nio/$(DEMONAME) + +# +# Demo jar building rules. +# +include $(BUILDDIR)/common/Demo.gmk +
--- a/jdk/make/sun/cmm/lcms/Makefile Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/make/sun/cmm/lcms/Makefile Tue Oct 26 14:43:21 2010 -0400 @@ -80,7 +80,12 @@ vpath %.c $(SHARE_SRC)/native/sun/java2d ifeq ($(PLATFORM), windows) -OTHER_CFLAGS += -DCMS_IS_WINDOWS_ -Dsqrtf=sqrt +OTHER_CFLAGS += -DCMS_IS_WINDOWS_ + +ifeq ($(COMPILER_VERSION), VS2003) +OTHER_CFLAGS += -Dsqrtf=sqrt +endif + OTHER_LDLIBS = $(OBJDIR)/../../../sun.awt/awt/$(OBJDIRNAME)/awt.lib OTHER_INCLUDES += -I$(SHARE_SRC)/native/sun/java2d \ -I$(SHARE_SRC)/native/sun/awt/debug
--- a/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java Tue Oct 26 14:43:21 2010 -0400 @@ -525,7 +525,7 @@ iMatchColumns = new Vector(10); for(int i = 0; i < 10 ; i++) { - iMatchColumns.add(i,new Integer(-1)); + iMatchColumns.add(i,Integer.valueOf(-1)); } strMatchColumns = new Vector(10); @@ -889,7 +889,12 @@ success = false; } else { tWriter = (TransactionalWriter)rowSetWriter; - ((CachedRowSetWriter)tWriter).commit(this, updateOnInsert); + if (tWriter instanceof CachedRowSetWriter) { + ((CachedRowSetWriter)tWriter).commit(this, updateOnInsert); + } else { + tWriter.commit(); + } + success = true; } } @@ -1294,7 +1299,7 @@ tMap = new TreeMap(); for (int i = 0; i<numRows; i++) { - tMap.put(new Integer(i), rvh.get(i)); + tMap.put(Integer.valueOf(i), rvh.get(i)); } return (tMap.values()); @@ -1806,7 +1811,7 @@ return (byte)0; } try { - return ((new Byte(value.toString())).byteValue()); + return ((Byte.valueOf(value.toString())).byteValue()); } catch (NumberFormatException ex) { throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.bytefail").toString(), new Object[] {value.toString().trim(), columnIndex})); @@ -1850,7 +1855,7 @@ } try { - return ((new Short(value.toString().trim())).shortValue()); + return ((Short.valueOf(value.toString().trim())).shortValue()); } catch (NumberFormatException ex) { throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.shortfail").toString(), new Object[] {value.toString().trim(), columnIndex})); @@ -1893,7 +1898,7 @@ } try { - return ((new Integer(value.toString().trim())).intValue()); + return ((Integer.valueOf(value.toString().trim())).intValue()); } catch (NumberFormatException ex) { throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.intfail").toString(), new Object[] {value.toString().trim(), columnIndex})); @@ -1936,7 +1941,7 @@ return (long)0; } try { - return ((new Long(value.toString().trim())).longValue()); + return ((Long.valueOf(value.toString().trim())).longValue()); } catch (NumberFormatException ex) { throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.longfail").toString(), new Object[] {value.toString().trim(), columnIndex})); @@ -4014,18 +4019,18 @@ try { switch (trgType) { case java.sql.Types.BIT: - Integer i = new Integer(srcObj.toString().trim()); - return i.equals(new Integer((int)0)) ? - new Boolean(false) : - new Boolean(true); + Integer i = Integer.valueOf(srcObj.toString().trim()); + return i.equals(Integer.valueOf((int)0)) ? + Boolean.valueOf(false) : + Boolean.valueOf(true); case java.sql.Types.TINYINT: - return new Byte(srcObj.toString().trim()); + return Byte.valueOf(srcObj.toString().trim()); case java.sql.Types.SMALLINT: - return new Short(srcObj.toString().trim()); + return Short.valueOf(srcObj.toString().trim()); case java.sql.Types.INTEGER: - return new Integer(srcObj.toString().trim()); + return Integer.valueOf(srcObj.toString().trim()); case java.sql.Types.BIGINT: - return new Long(srcObj.toString().trim()); + return Long.valueOf(srcObj.toString().trim()); case java.sql.Types.NUMERIC: case java.sql.Types.DECIMAL: return new BigDecimal(srcObj.toString().trim()); @@ -4037,7 +4042,7 @@ case java.sql.Types.CHAR: case java.sql.Types.VARCHAR: case java.sql.Types.LONGVARCHAR: - return new String(srcObj.toString()); + return srcObj.toString(); default: throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()+ trgType); } @@ -4134,7 +4139,7 @@ case java.sql.Types.CHAR: case java.sql.Types.VARCHAR: case java.sql.Types.LONGVARCHAR: - return new String(srcObj.toString()); + return srcObj.toString(); default: throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); } @@ -4181,12 +4186,12 @@ try { switch (trgType) { case java.sql.Types.BIT: - Integer i = new Integer(srcObj.toString().trim()); - return i.equals(new Integer((int)0)) ? - new Boolean(false) : - new Boolean(true); + Integer i = Integer.valueOf(srcObj.toString().trim()); + return i.equals(Integer.valueOf((int)0)) ? + Boolean.valueOf(false) : + Boolean.valueOf(true); case java.sql.Types.BOOLEAN: - return new Boolean(srcObj.toString().trim()); + return Boolean.valueOf(srcObj.toString().trim()); default: throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()+ trgType); } @@ -4260,7 +4265,7 @@ checkIndex(columnIndex); // make sure the cursor is on a valid row checkCursor(); - Object obj = convertBoolean(new Boolean(x), + Object obj = convertBoolean(Boolean.valueOf(x), java.sql.Types.BIT, RowSetMD.getColumnType(columnIndex)); @@ -4296,7 +4301,7 @@ // make sure the cursor is on a valid row checkCursor(); - Object obj = convertNumeric(new Byte(x), + Object obj = convertNumeric(Byte.valueOf(x), java.sql.Types.TINYINT, RowSetMD.getColumnType(columnIndex)); @@ -4332,7 +4337,7 @@ // make sure the cursor is on a valid row checkCursor(); - Object obj = convertNumeric(new Short(x), + Object obj = convertNumeric(Short.valueOf(x), java.sql.Types.SMALLINT, RowSetMD.getColumnType(columnIndex)); @@ -4367,7 +4372,7 @@ checkIndex(columnIndex); // make sure the cursor is on a valid row checkCursor(); - Object obj = convertNumeric(new Integer(x), + Object obj = convertNumeric(Integer.valueOf(x), java.sql.Types.INTEGER, RowSetMD.getColumnType(columnIndex)); @@ -4403,7 +4408,7 @@ // make sure the cursor is on a valid row checkCursor(); - Object obj = convertNumeric(new Long(x), + Object obj = convertNumeric(Long.valueOf(x), java.sql.Types.BIGINT, RowSetMD.getColumnType(columnIndex)); @@ -6429,7 +6434,7 @@ if (tabName == null) throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.tablename").toString()); else - tableName = new String(tabName); + tableName = tabName; } /** @@ -6940,7 +6945,7 @@ } for( int i = 0;i < columnIdxes.length ;i++) { - iMatchColumns.set(i,new Integer(-1)); + iMatchColumns.set(i,Integer.valueOf(-1)); } } @@ -7049,7 +7054,7 @@ } } for(int i = 0 ;i < columnIdxes.length; i++) { - iMatchColumns.add(i,new Integer(columnIdxes[i])); + iMatchColumns.add(i,Integer.valueOf(columnIdxes[i])); } } @@ -7104,7 +7109,7 @@ throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols1").toString()); } else { // set iMatchColumn - iMatchColumns.set(0, new Integer(columnIdx)); + iMatchColumns.set(0, Integer.valueOf(columnIdx)); //strMatchColumn = null; } } @@ -7126,7 +7131,7 @@ */ public void setMatchColumn(String columnName) throws SQLException { // validate, if col is ok to be set - if(columnName.equals(null) || ((columnName = columnName.trim()) == "" )) { + if(columnName == null || (columnName= columnName.trim()).equals("") ) { throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols2").toString()); } else { // set strMatchColumn @@ -7151,13 +7156,13 @@ */ public void unsetMatchColumn(int columnIdx) throws SQLException { // check if we are unsetting the SAME column - if(! iMatchColumns.get(0).equals(new Integer(columnIdx) ) ) { + if(! iMatchColumns.get(0).equals(Integer.valueOf(columnIdx) ) ) { throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch").toString()); } else if(strMatchColumns.get(0) != null) { throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch1").toString()); } else { // that is, we are unsetting it. - iMatchColumns.set(0, new Integer(-1)); + iMatchColumns.set(0, Integer.valueOf(-1)); } }
--- a/jdk/src/share/classes/com/sun/rowset/FilteredRowSetImpl.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/com/sun/rowset/FilteredRowSetImpl.java Tue Oct 26 14:43:21 2010 -0400 @@ -499,7 +499,7 @@ if(onInsertRow) { if(p != null) { - bool = p.evaluate(new Integer(x),columnIndex); + bool = p.evaluate(Integer.valueOf(x),columnIndex); if(!bool) { throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString()); @@ -566,7 +566,7 @@ if(onInsertRow) { if(p != null) { - bool = p.evaluate(new Boolean(x) , columnIndex); + bool = p.evaluate(Boolean.valueOf(x) , columnIndex); if(!bool) { throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString()); @@ -634,7 +634,7 @@ if(onInsertRow) { if(p != null) { - bool = p.evaluate(new Byte(x),columnIndex); + bool = p.evaluate(Byte.valueOf(x),columnIndex); if(!bool) { throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString()); @@ -703,7 +703,7 @@ if(onInsertRow) { if(p != null) { - bool = p.evaluate(new Short(x), columnIndex); + bool = p.evaluate(Short.valueOf(x), columnIndex); if(!bool) { throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString()); @@ -771,7 +771,7 @@ if(onInsertRow) { if(p != null) { - bool = p.evaluate(new Long(x), columnIndex); + bool = p.evaluate(Long.valueOf(x), columnIndex); if(!bool) { throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString()); @@ -1106,12 +1106,12 @@ public void updateBytes(int columnIndex , byte []x) throws SQLException { boolean bool; - String val = new String(); + String val = ""; Byte [] obj_arr = new Byte[x.length]; for(int i = 0; i < x.length; i++) { - obj_arr[i] = new Byte(x[i]); + obj_arr[i] = Byte.valueOf(x[i]); val = val.concat(obj_arr[i].toString()); }
--- a/jdk/src/share/classes/com/sun/rowset/JdbcRowSetImpl.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/com/sun/rowset/JdbcRowSetImpl.java Tue Oct 26 14:43:21 2010 -0400 @@ -215,7 +215,7 @@ iMatchColumns = new Vector(10); for(int i = 0; i < 10 ; i++) { - iMatchColumns.add(i,new Integer(-1)); + iMatchColumns.add(i,Integer.valueOf(-1)); } strMatchColumns = new Vector(10); @@ -288,7 +288,7 @@ iMatchColumns = new Vector(10); for(int i = 0; i < 10 ; i++) { - iMatchColumns.add(i,new Integer(-1)); + iMatchColumns.add(i,Integer.valueOf(-1)); } strMatchColumns = new Vector(10); @@ -375,7 +375,7 @@ iMatchColumns = new Vector(10); for(int i = 0; i < 10 ; i++) { - iMatchColumns.add(i,new Integer(-1)); + iMatchColumns.add(i,Integer.valueOf(-1)); } strMatchColumns = new Vector(10); @@ -465,7 +465,7 @@ iMatchColumns = new Vector(10); for(int i = 0; i < 10 ; i++) { - iMatchColumns.add(i,new Integer(-1)); + iMatchColumns.add(i,Integer.valueOf(-1)); } strMatchColumns = new Vector(10); @@ -3754,7 +3754,7 @@ } for( int i = 0;i < columnIdxes.length ;i++) { - iMatchColumns.set(i,new Integer(-1)); + iMatchColumns.set(i,Integer.valueOf(-1)); } } @@ -3863,7 +3863,7 @@ } } for(int i = 0 ;i < columnIdxes.length; i++) { - iMatchColumns.add(i,new Integer(columnIdxes[i])); + iMatchColumns.add(i,Integer.valueOf(columnIdxes[i])); } } @@ -3918,7 +3918,7 @@ throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.matchcols1").toString()); } else { // set iMatchColumn - iMatchColumns.set(0, new Integer(columnIdx)); + iMatchColumns.set(0, Integer.valueOf(columnIdx)); //strMatchColumn = null; } } @@ -3940,7 +3940,7 @@ */ public void setMatchColumn(String columnName) throws SQLException { // validate, if col is ok to be set - if(columnName.equals(null) || ((columnName = columnName.trim()) == "" )) { + if(columnName == null || (columnName= columnName.trim()).equals("")) { throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.matchcols2").toString()); } else { // set strMatchColumn @@ -3965,13 +3965,13 @@ */ public void unsetMatchColumn(int columnIdx) throws SQLException { // check if we are unsetting the SAME column - if(! iMatchColumns.get(0).equals(new Integer(columnIdx) ) ) { + if(! iMatchColumns.get(0).equals(Integer.valueOf(columnIdx) ) ) { throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.unsetmatch").toString()); } else if(strMatchColumns.get(0) != null) { throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.usecolname").toString()); } else { // that is, we are unsetting it. - iMatchColumns.set(0, new Integer(-1)); + iMatchColumns.set(0, Integer.valueOf(-1)); } }
--- a/jdk/src/share/classes/com/sun/rowset/JoinRowSetImpl.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/com/sun/rowset/JoinRowSetImpl.java Tue Oct 26 14:43:21 2010 -0400 @@ -33,6 +33,8 @@ import java.util.*; import javax.sql.rowset.*; +import javax.sql.rowset.spi.SyncProvider; +import javax.sql.rowset.spi.SyncProviderException; /** * The standard implementation of the <code>JoinRowSet</code> @@ -550,7 +552,7 @@ // This 'if' will be removed after all joins are implemented. throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.notsupported").toString()); } else { - Integer Intgr = new Integer(JoinRowSet.INNER_JOIN); + Integer Intgr = Integer.valueOf(JoinRowSet.INNER_JOIN); vecJoinType.add(Intgr); } } else { @@ -874,8 +876,8 @@ String strWhereClause = "Select "; String whereClause; - String tabName= null; - String strTabName = null; + String tabName= ""; + String strTabName = ""; int sz,cols; int j; CachedRowSetImpl crs; @@ -889,8 +891,6 @@ // tableNameX.(rowsetX.getMatchColumnName()) == // tableNameZ.(rowsetZ.getMatchColumnName())); - tabName = new String(); - strTabName = new String(); sz = vecRowSetsInJOIN.size(); for(int i=0;i<sz; i++) { crs = (CachedRowSetImpl)vecRowSetsInJOIN.get(i); @@ -4311,6 +4311,27 @@ return crsInternal.createCopySchema(); } + /** + * {@inheritDoc} + */ + public void setSyncProvider(String providerStr) throws SQLException { + crsInternal.setSyncProvider(providerStr); + } + + /** + * {@inheritDoc} + */ + public void acceptChanges() throws SyncProviderException { + crsInternal.acceptChanges(); + } + + /** + * {@inheritDoc} + */ + public SyncProvider getSyncProvider() throws SQLException { + return crsInternal.getSyncProvider(); + } + /** * This method re populates the resBundle * during the deserialization process
--- a/jdk/src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java Tue Oct 26 14:43:21 2010 -0400 @@ -338,11 +338,11 @@ if (crs.rowDeleted()) { // The row has been deleted. if (conflict = (deleteOriginalRow(crs, this.crsResolve)) == true) { - status.add(rows, new Integer(SyncResolver.DELETE_ROW_CONFLICT)); + status.add(rows, Integer.valueOf(SyncResolver.DELETE_ROW_CONFLICT)); } else { // delete happened without any occurrence of conflicts // so update status accordingly - status.add(rows, new Integer(SyncResolver.NO_ROW_CONFLICT)); + status.add(rows, Integer.valueOf(SyncResolver.NO_ROW_CONFLICT)); } } else if (crs.rowInserted()) { @@ -350,20 +350,20 @@ pstmtIns = con.prepareStatement(insertCmd); if ( (conflict = insertNewRow(crs, pstmtIns, this.crsResolve)) == true) { - status.add(rows, new Integer(SyncResolver.INSERT_ROW_CONFLICT)); + status.add(rows, Integer.valueOf(SyncResolver.INSERT_ROW_CONFLICT)); } else { // insert happened without any occurrence of conflicts // so update status accordingly - status.add(rows, new Integer(SyncResolver.NO_ROW_CONFLICT)); + status.add(rows, Integer.valueOf(SyncResolver.NO_ROW_CONFLICT)); } } else if (crs.rowUpdated()) { // The row has been updated. if ( conflict = (updateOriginalRow(crs)) == true) { - status.add(rows, new Integer(SyncResolver.UPDATE_ROW_CONFLICT)); + status.add(rows, Integer.valueOf(SyncResolver.UPDATE_ROW_CONFLICT)); } else { // update happened without any occurrence of conflicts // so update status accordingly - status.add(rows, new Integer(SyncResolver.NO_ROW_CONFLICT)); + status.add(rows, Integer.valueOf(SyncResolver.NO_ROW_CONFLICT)); } } else { @@ -375,7 +375,7 @@ * that is fine. **/ int icolCount = crs.getMetaData().getColumnCount(); - status.add(rows, new Integer(SyncResolver.NO_ROW_CONFLICT)); + status.add(rows, Integer.valueOf(SyncResolver.NO_ROW_CONFLICT)); this.crsResolve.moveToInsertRow(); for(int cols=0;cols<iColCount;cols++) { @@ -398,7 +398,7 @@ boolean boolConf = false; for (int j=1;j<status.size();j++){ // ignore status for index = 0 which is set to null - if(! ((status.get(j)).equals(new Integer(SyncResolver.NO_ROW_CONFLICT)))) { + if(! ((status.get(j)).equals(Integer.valueOf(SyncResolver.NO_ROW_CONFLICT)))) { // there is at least one conflict which needs to be resolved boolConf = true; break; @@ -541,7 +541,7 @@ // how many fields need to be updated int colsNotChanged = 0; Vector cols = new Vector(); - String updateExec = new String(updateCmd); + String updateExec = updateCmd; Object orig; Object curr; Object rsval; @@ -652,7 +652,7 @@ updateExec += ", "; } updateExec += crs.getMetaData().getColumnName(i); - cols.add(new Integer(i)); + cols.add(Integer.valueOf(i)); updateExec += " = ? "; first = false; @@ -698,7 +698,7 @@ updateExec += ", "; } updateExec += crs.getMetaData().getColumnName(i); - cols.add(new Integer(i)); + cols.add(Integer.valueOf(i)); updateExec += " = ? "; flag = false; } else { @@ -1184,7 +1184,7 @@ // trim all the leading and trailing whitespaces, // white spaces can never be catalog, schema or a table name. - String cmd = new String(); + String cmd = ""; catalog = catalog.trim(); schema = schema.trim();
--- a/jdk/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java Tue Oct 26 14:43:21 2010 -0400 @@ -248,7 +248,7 @@ String strProvider = strProviderInstance.substring(0, (caller.getSyncProvider()).toString().indexOf("@")); propString("sync-provider-name", strProvider); - propString("sync-provider-vendor", "Sun Microsystems Inc."); + propString("sync-provider-vendor", "Oracle Corporation"); propString("sync-provider-version", "1.0"); propInteger("sync-provider-grade", caller.getSyncProvider().getProviderGrade()); propInteger("data-source-lock", caller.getSyncProvider().getDataSourceLock()); @@ -387,7 +387,7 @@ if (caller.wasNull()) writeNull(); else - writeInteger(caller.getInt(idx)); + writeInteger(i); break; case java.sql.Types.BIGINT: long l = caller.getLong(idx); @@ -574,7 +574,7 @@ } private void writeBoolean(boolean b) throws java.io.IOException { - writer.write(new Boolean(b).toString()); + writer.write(Boolean.valueOf(b).toString()); } private void writeFloat(float f) throws java.io.IOException { @@ -641,7 +641,7 @@ return null; } char []charStr = s.toCharArray(); - String specialStr = new String(); + String specialStr = ""; for(int i = 0; i < charStr.length; i++) { if(charStr[i] == '&') {
--- a/jdk/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java Tue Oct 26 14:43:21 2010 -0400 @@ -441,9 +441,9 @@ updates = new Vector(); // start out with the empty string - columnValue = new String(""); - propertyValue = new String(""); - metaDataValue = new String(""); + columnValue = ""; + propertyValue = ""; + metaDataValue = ""; nullVal = false; idx = 0; @@ -481,21 +481,21 @@ items = properties.length; for (i=0;i<items;i++) { - propMap.put(properties[i], new Integer(i)); + propMap.put(properties[i], Integer.valueOf(i)); } colDefMap = new HashMap(); items = colDef.length; for (i=0;i<items;i++) { - colDefMap.put(colDef[i], new Integer(i)); + colDefMap.put(colDef[i], Integer.valueOf(i)); } dataMap = new HashMap(); items = data.length; for (i=0;i<items;i++) { - dataMap.put(data[i], new Integer(i)); + dataMap.put(data[i], Integer.valueOf(i)); } //Initialize connection map here @@ -686,7 +686,7 @@ } // propertyValue need to be reset to an empty string - propertyValue = new String(""); + propertyValue = ""; setTag(-1); break; case METADATA: @@ -710,7 +710,7 @@ } // metaDataValue needs to be reset to an empty string - metaDataValue = new String(""); + metaDataValue = ""; } setTag(-1); break; @@ -736,7 +736,7 @@ insertValue(tempStr); } // columnValue now need to be reset to the empty string - columnValue = new String(""); + columnValue = ""; } catch (SQLException ex) { throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errinsert").toString(), ex.getMessage())); } @@ -981,7 +981,7 @@ private boolean getBooleanValue(String s) { - return new Boolean(s).booleanValue(); + return Boolean.valueOf(s).booleanValue(); } private java.math.BigDecimal getBigDecimalValue(String s) { @@ -1316,7 +1316,7 @@ **/ tempUpdate = tempUpdate.concat(new String(ch,start,len)); - upd[0] = new Integer(idx); + upd[0] = Integer.valueOf(idx); upd[1] = tempUpdate; //updates.add(upd);
--- a/jdk/src/share/classes/com/sun/rowset/providers/RIOptimisticProvider.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/com/sun/rowset/providers/RIOptimisticProvider.java Tue Oct 26 14:43:21 2010 -0400 @@ -93,14 +93,14 @@ private CachedRowSetWriter writer; /** - * The unique provider indentifier. + * The unique provider identifier. */ private String providerID = "com.sun.rowset.providers.RIOptimisticProvider"; /** * The vendor name of this SyncProvider implementation */ - private String vendorName = "Sun Microsystems Inc."; + private String vendorName = "Oracle Corporation"; /** * The version number of this SyncProvider implementation @@ -236,8 +236,8 @@ } /** - * Returns the vendor name of the Reference Implemntation Optimistic - * Syncchronication Provider + * Returns the vendor name of the Reference Implementation Optimistic + * Synchronization Provider * * @return the <code>String</code> detailing the vendor name of this * SyncProvider
--- a/jdk/src/share/classes/com/sun/rowset/providers/RIXMLProvider.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/com/sun/rowset/providers/RIXMLProvider.java Tue Oct 26 14:43:21 2010 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -85,7 +85,7 @@ /** * The vendor name of this SyncProvider implementation. */ - private String vendorName = "Sun Microsystems Inc."; + private String vendorName = "Oracle Corporation"; /** * The version number of this SyncProvider implementation.
--- a/jdk/src/share/classes/com/sun/servicetag/Installer.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/com/sun/servicetag/Installer.java Tue Oct 26 14:43:21 2010 -0400 @@ -43,7 +43,8 @@ "servicetag.dir.path"; private static String SVCTAG_ENABLE_REGISTRATION = "servicetag.registration.enabled"; - private final static String SUN_VENDOR = "Sun Microsystems"; + private final static String ORACLE = "Oracle"; + private final static String SUN = "Sun Microsystems"; private final static String REGISTRATION_XML = "registration.xml"; private final static String SERVICE_TAG_FILE = "servicetag"; private final static String REGISTRATION_HTML_NAME = "register"; @@ -84,9 +85,10 @@ // Implementation of ServiceTag.getJavaServiceTag(String) method static ServiceTag getJavaServiceTag(String source) throws IOException { - if (!System.getProperty("java.vendor").startsWith(SUN_VENDOR)) { + String vendor = System.getProperty("java.vendor", ""); + if (!vendor.startsWith(SUN) && !vendor.startsWith(ORACLE)) { // Products bundling this implementation may run on - // Mac OS which is not a Sun JDK + // Mac OS which is not a Sun/Oracle JDK return null; } boolean cleanup = false; @@ -365,7 +367,7 @@ props.getProperty("servicetag.parent.name"), props.getProperty("servicetag.parent.urn"), getProductDefinedId(), - SUN_VENDOR, + System.getProperty("java.vendor"), System.getProperty("os.arch"), getZoneName(), svcTagSource);
--- a/jdk/src/share/classes/com/sun/servicetag/RegistrationData.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/com/sun/servicetag/RegistrationData.java Tue Oct 26 14:43:21 2010 -0400 @@ -80,12 +80,12 @@ * <tr> * <td><tt>systemManufacturer</tt></td> * <td>System manufacturer</td> - * <td> e.g. Sun Microsystems</td> + * <td> e.g. Oracle Corporation</td> * </tr> * <tr> * <td><tt>cpuManufacturer</tt></td> * <td>CPU manufacturer</td> - * <td> e.g. Sun Microsystems</td> + * <td> e.g. Oracle Corporation</td> * </tr> * <tr> * <td><tt>serialNumber</tt></td>
--- a/jdk/src/share/classes/com/sun/servicetag/Registry.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/com/sun/servicetag/Registry.java Tue Oct 26 14:43:21 2010 -0400 @@ -90,7 +90,7 @@ stclient = getWindowsStClientFile(); } else { if (isVerbose()) { - System.out.println("Running on non-Sun JDK"); + System.out.println("Running on unsupported platform"); } } initialized = true;
--- a/jdk/src/share/classes/com/sun/servicetag/SolarisSystemEnvironment.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/com/sun/servicetag/SolarisSystemEnvironment.java Tue Oct 26 14:43:21 2010 -0400 @@ -44,6 +44,7 @@ * Solaris implementation of the SystemEnvironment class. */ class SolarisSystemEnvironment extends SystemEnvironment { + private static final String ORACLE = "Oracle Corporation"; SolarisSystemEnvironment() { setHostId(getCommandOutput("/usr/bin/hostid")); setSystemModel(getCommandOutput("/usr/bin/uname", "-i")); @@ -59,7 +60,7 @@ private String getSolarisCpuManufacturer() { // not fully accurate, this could be another manufacturer (fujitsu for example) if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) { - return "Sun Microsystems, Inc"; + return ORACLE; } // if we're here, then we'll try smbios (type 4) @@ -73,7 +74,7 @@ private String getSolarisSystemManufacturer() { // not fully accurate, this could be another manufacturer (fujitsu for example) if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) { - return "Sun Microsystems, Inc"; + return ORACLE; } // if we're here, then we'll try smbios (type 1) @@ -117,7 +118,7 @@ // ID SIZE TYPE // 1 150 SMB_TYPE_SYSTEM (system information) // - // Manufacturer: Sun Microsystems + // Manufacturer: Oracle Corporation // Product: Sun Fire X4600 // Version: To Be Filled By O.E.M. // Serial Number: 00:14:4F:45:0C:2A
--- a/jdk/src/share/classes/java/awt/Dialog.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/awt/Dialog.java Tue Oct 26 14:43:21 2010 -0400 @@ -1068,7 +1068,7 @@ modalityPushed(); try { EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue(); - secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 5000); + secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 0); if (!secondaryLoop.enter()) { secondaryLoop = null; }
--- a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java Tue Oct 26 14:43:21 2010 -0400 @@ -142,6 +142,9 @@ public void removeLastFocusRequest(Component heavyweight) { KeyboardFocusManager.removeLastFocusRequest(heavyweight); } + public void setMostRecentFocusOwner(Window window, Component component) { + KeyboardFocusManager.setMostRecentFocusOwner(window, component); + } } ); }
--- a/jdk/src/share/classes/java/awt/event/ActionEvent.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/awt/event/ActionEvent.java Tue Oct 26 14:43:21 2010 -0400 @@ -51,7 +51,7 @@ * in the range from {@code ACTION_FIRST} to {@code ACTION_LAST}. * * @see ActionListener - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/eventmodel.html">Tutorial: Java 1.1 Event Model</a> + * @see <a href="http://java.sun.com/docs/books/tutorial/uiswing/events/actionlistener.html">Tutorial: How to Write an Action Listener</a> * * @author Carl Quinn * @since 1.1
--- a/jdk/src/share/classes/java/awt/image/SampleModel.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/awt/image/SampleModel.java Tue Oct 26 14:43:21 2010 -0400 @@ -937,14 +937,22 @@ int iArray[], DataBuffer data) { int pixels[]; int Offset=0; + int x1 = x + w; + int y1 = y + h; + + if (x < 0 || x1 < x || x1 > width || + y < 0 || y1 < y || y1 > height) + { + throw new ArrayIndexOutOfBoundsException("Invalid coordinates."); + } if (iArray != null) pixels = iArray; else pixels = new int[w * h]; - for(int i=y; i<(h+y); i++) { - for (int j=x; j<(w+x); j++) { + for(int i=y; i<y1; i++) { + for (int j=x; j<x1; j++) { pixels[Offset++] = getSample(j, i, b, data); } } @@ -978,14 +986,22 @@ DataBuffer data) { float pixels[]; int Offset=0; + int x1 = x + w; + int y1 = y + h; + + if (x < 0 || x1 < x || x1 > width || + y < 0 || y1 < y || y1 > height) + { + throw new ArrayIndexOutOfBoundsException("Invalid coordinates"); + } if (fArray != null) pixels = fArray; else pixels = new float[w * h]; - for (int i=y; i<(h+y); i++) { - for (int j=x; j<(w+x); j++) { + for (int i=y; i<y1; i++) { + for (int j=x; j<x1; j++) { pixels[Offset++] = getSampleFloat(j, i, b, data); } } @@ -1019,14 +1035,22 @@ DataBuffer data) { double pixels[]; int Offset=0; + int x1 = x + w; + int y1 = y + h; + + if (x < 0 || x1 < x || x1 > width || + y < 0 || y1 < y || y1 > height) + { + throw new ArrayIndexOutOfBoundsException("Invalid coordinates"); + } if (dArray != null) pixels = dArray; else pixels = new double[w * h]; - for (int i=y; i<(y+h); i++) { - for (int j=x; j<(x+w); j++) { + for (int i=y; i<y1; i++) { + for (int j=x; j<x1; j++) { pixels[Offset++] = getSampleDouble(j, i, b, data); } }
--- a/jdk/src/share/classes/java/beans/EventSetDescriptor.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/beans/EventSetDescriptor.java Tue Oct 26 14:43:21 2010 -0400 @@ -176,8 +176,9 @@ setRemoveListenerMethod(getMethod(sourceClass, removeListenerMethodName, 1)); // Be more forgiving of not finding the getListener method. - if (getListenerMethodName != null) { - setGetListenerMethod(Introspector.findInstanceMethod(sourceClass, getListenerMethodName)); + Method method = Introspector.findMethod(sourceClass, getListenerMethodName, 0); + if (method != null) { + setGetListenerMethod(method); } }
--- a/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java Tue Oct 26 14:43:21 2010 -0400 @@ -189,11 +189,13 @@ indexedReadMethodName = Introspector.GET_PREFIX + getBaseName(); } } - indexedReadMethod = Introspector.findInstanceMethod(cls, indexedReadMethodName, int.class); + + Class[] args = { int.class }; + indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args); if (indexedReadMethod == null) { // no "is" method, so look for a "get" method. indexedReadMethodName = Introspector.GET_PREFIX + getBaseName(); - indexedReadMethod = Introspector.findInstanceMethod(cls, indexedReadMethodName, int.class); + indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args); } setIndexedReadMethod0(indexedReadMethod); } @@ -265,7 +267,9 @@ if (indexedWriteMethodName == null) { indexedWriteMethodName = Introspector.SET_PREFIX + getBaseName(); } - indexedWriteMethod = Introspector.findInstanceMethod(cls, indexedWriteMethodName, int.class, type); + + Class[] args = (type == null) ? null : new Class[] { int.class, type }; + indexedWriteMethod = Introspector.findMethod(cls, indexedWriteMethodName, 2, args); if (indexedWriteMethod != null) { if (!indexedWriteMethod.getReturnType().equals(void.class)) { indexedWriteMethod = null;
--- a/jdk/src/share/classes/java/beans/Introspector.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/beans/Introspector.java Tue Oct 26 14:43:21 2010 -0400 @@ -28,7 +28,6 @@ import com.sun.beans.WeakCache; import com.sun.beans.finder.BeanInfoFinder; import com.sun.beans.finder.ClassFinder; -import com.sun.beans.finder.MethodFinder; import java.lang.ref.Reference; import java.lang.ref.SoftReference; @@ -843,8 +842,8 @@ Method read = result.getReadMethod(); if (read == null && write != null) { - read = findInstanceMethod(result.getClass0(), - GET_PREFIX + NameGenerator.capitalize(result.getName())); + read = findMethod(result.getClass0(), + GET_PREFIX + NameGenerator.capitalize(result.getName()), 0); if (read != null) { try { result.setReadMethod(read); @@ -854,9 +853,9 @@ } } if (write == null && read != null) { - write = findInstanceMethod(result.getClass0(), - SET_PREFIX + NameGenerator.capitalize(result.getName()), - FeatureDescriptor.getReturnType(result.getClass0(), read)); + write = findMethod(result.getClass0(), + SET_PREFIX + NameGenerator.capitalize(result.getName()), 1, + new Class[] { FeatureDescriptor.getReturnType(result.getClass0(), read) }); if (write != null) { try { result.setWriteMethod(write); @@ -1280,27 +1279,90 @@ // Package private support methods. //====================================================================== - static Method findMethod(Class<?> type, String name, int args) { - for (Method method : type.getMethods()) { - if (method.getName().equals(name) && (args == method.getParameterTypes().length)) { - try { - return MethodFinder.findAccessibleMethod(method); + /** + * Internal support for finding a target methodName with a given + * parameter list on a given class. + */ + private static Method internalFindMethod(Class start, String methodName, + int argCount, Class args[]) { + // For overriden methods we need to find the most derived version. + // So we start with the given class and walk up the superclass chain. + + Method method = null; + + for (Class cl = start; cl != null; cl = cl.getSuperclass()) { + Method methods[] = getPublicDeclaredMethods(cl); + for (int i = 0; i < methods.length; i++) { + method = methods[i]; + if (method == null) { + continue; } - catch (NoSuchMethodException exception) { - // continue search for a method with the specified count of parameters + + // make sure method signature matches. + Class params[] = FeatureDescriptor.getParameterTypes(start, method); + if (method.getName().equals(methodName) && + params.length == argCount) { + if (args != null) { + boolean different = false; + if (argCount > 0) { + for (int j = 0; j < argCount; j++) { + if (params[j] != args[j]) { + different = true; + continue; + } + } + if (different) { + continue; + } + } + } + return method; } } } - return null; + method = null; + + // Now check any inherited interfaces. This is necessary both when + // the argument class is itself an interface, and when the argument + // class is an abstract class. + Class ifcs[] = start.getInterfaces(); + for (int i = 0 ; i < ifcs.length; i++) { + // Note: The original implementation had both methods calling + // the 3 arg method. This is preserved but perhaps it should + // pass the args array instead of null. + method = internalFindMethod(ifcs[i], methodName, argCount, null); + if (method != null) { + break; + } + } + return method; } - static Method findInstanceMethod(Class<?> type, String name, Class<?>... args) { - try { - return MethodFinder.findInstanceMethod(type, name, args); - } - catch (NoSuchMethodException exception) { + /** + * Find a target methodName on a given class. + */ + static Method findMethod(Class cls, String methodName, int argCount) { + return findMethod(cls, methodName, argCount, null); + } + + /** + * Find a target methodName with specific parameter list on a given class. + * <p> + * Used in the contructors of the EventSetDescriptor, + * PropertyDescriptor and the IndexedPropertyDescriptor. + * <p> + * @param cls The Class object on which to retrieve the method. + * @param methodName Name of the method. + * @param argCount Number of arguments for the desired method. + * @param args Array of argument types for the method. + * @return the method or null if not found + */ + static Method findMethod(Class cls, String methodName, int argCount, + Class args[]) { + if (methodName == null) { return null; } + return internalFindMethod(cls, methodName, argCount, args); } /**
--- a/jdk/src/share/classes/java/beans/MethodDescriptor.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/beans/MethodDescriptor.java Tue Oct 26 14:43:21 2010 -0400 @@ -90,13 +90,13 @@ // Find methods for up to 2 params. We are guessing here. // This block should never execute unless the classloader // that loaded the argument classes disappears. - method = Introspector.findMethod(cls, name, i); + method = Introspector.findMethod(cls, name, i, null); if (method != null) { break; } } } else { - method = Statement.getMethod(cls, name, params); + method = Introspector.findMethod(cls, name, params.length, params); } setMethod(method); }
--- a/jdk/src/share/classes/java/beans/PropertyDescriptor.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/beans/PropertyDescriptor.java Tue Oct 26 14:43:21 2010 -0400 @@ -112,7 +112,8 @@ // If this class or one of its base classes allow PropertyChangeListener, // then we assume that any properties we discover are "bound". // See Introspector.getTargetPropertyInfo() method. - this.bound = null != Introspector.findInstanceMethod(beanClass, "addPropertyChangeListener", PropertyChangeListener.class); + Class[] args = { PropertyChangeListener.class }; + this.bound = null != Introspector.findMethod(beanClass, "addPropertyChangeListener", args.length, args); } /** @@ -223,10 +224,10 @@ // property type is. For booleans, there can be "is" and "get" // methods. If an "is" method exists, this is the official // reader method so look for this one first. - readMethod = Introspector.findInstanceMethod(cls, readMethodName); + readMethod = Introspector.findMethod(cls, readMethodName, 0); if (readMethod == null) { readMethodName = Introspector.GET_PREFIX + getBaseName(); - readMethod = Introspector.findInstanceMethod(cls, readMethodName); + readMethod = Introspector.findMethod(cls, readMethodName, 0); } try { setReadMethod(readMethod); @@ -291,7 +292,8 @@ writeMethodName = Introspector.SET_PREFIX + getBaseName(); } - writeMethod = Introspector.findInstanceMethod(cls, writeMethodName, type); + Class[] args = (type == null) ? null : new Class[] { type }; + writeMethod = Introspector.findMethod(cls, writeMethodName, 1, args); if (writeMethod != null) { if (!writeMethod.getReturnType().equals(void.class)) { writeMethod = null;
--- a/jdk/src/share/classes/java/lang/System.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/lang/System.java Tue Oct 26 14:43:21 2010 -0400 @@ -1101,22 +1101,12 @@ lineSeparator = props.getProperty("line.separator"); sun.misc.Version.init(); - // Workaround until DownloadManager initialization is revisited. - // Make JavaLangAccess available early enough for internal - // Shutdown hooks to be registered - setJavaLangAccess(); - // Gets and removes system properties that configure the Integer // cache used to support the object identity semantics of autoboxing. // At this time, the size of the cache may be controlled by the // vm option -XX:AutoBoxCacheMax=<size>. Integer.getAndRemoveCacheProperties(); - // Load the zip library now in order to keep java.util.zip.ZipFile - // from trying to use itself to load this library later. - loadLibrary("zip"); - - FileInputStream fdIn = new FileInputStream(FileDescriptor.in); FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out); FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err); @@ -1124,6 +1114,10 @@ setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true)); setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true)); + // Load the zip library now in order to keep java.util.zip.ZipFile + // from trying to use itself to load this library later. + loadLibrary("zip"); + // Setup Java signal handlers for HUP, TERM, and INT (where available). Terminator.setup(); @@ -1153,6 +1147,9 @@ // way as other threads; we must do it ourselves here. Thread current = Thread.currentThread(); current.getThreadGroup().add(current); + + // register shared secrets + setJavaLangAccess(); } private static void setJavaLangAccess() {
--- a/jdk/src/share/classes/java/net/InetAddress.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/net/InetAddress.java Tue Oct 26 14:43:21 2010 -0400 @@ -677,19 +677,20 @@ static InetAddressImpl impl; - private static HashMap lookupTable = new HashMap(); + private static HashMap<String, InetAddress[]> lookupTable + = new HashMap<String, InetAddress[]>(); /** * Represents a cache entry */ static final class CacheEntry { - CacheEntry(Object address, long expiration) { - this.address = address; + CacheEntry(InetAddress[] addresses, long expiration) { + this.addresses = addresses; this.expiration = expiration; } - Object address; + InetAddress[] addresses; long expiration; } @@ -698,7 +699,7 @@ * at creation time. */ static final class Cache { - private LinkedHashMap cache; + private LinkedHashMap<String, CacheEntry> cache; private Type type; enum Type {Positive, Negative}; @@ -708,7 +709,7 @@ */ public Cache(Type type) { this.type = type; - cache = new LinkedHashMap(); + cache = new LinkedHashMap<String, CacheEntry>(); } private int getPolicy() { @@ -724,7 +725,7 @@ * entry then for this host then the entry will be * replaced. */ - public Cache put(String host, Object address) { + public Cache put(String host, InetAddress[] addresses) { int policy = getPolicy(); if (policy == InetAddressCachePolicy.NEVER) { return this; @@ -736,12 +737,10 @@ // As we iterate in insertion order we can // terminate when a non-expired entry is found. - LinkedList expired = new LinkedList(); - Iterator i = cache.keySet().iterator(); + LinkedList<String> expired = new LinkedList<String>(); long now = System.currentTimeMillis(); - while (i.hasNext()) { - String key = (String)i.next(); - CacheEntry entry = (CacheEntry)cache.get(key); + for (String key : cache.keySet()) { + CacheEntry entry = cache.get(key); if (entry.expiration >= 0 && entry.expiration < now) { expired.add(key); @@ -750,9 +749,8 @@ } } - i = expired.iterator(); - while (i.hasNext()) { - cache.remove(i.next()); + for (String key : expired) { + cache.remove(key); } } @@ -766,7 +764,7 @@ } else { expiration = System.currentTimeMillis() + (policy * 1000); } - CacheEntry entry = new CacheEntry(address, expiration); + CacheEntry entry = new CacheEntry(addresses, expiration); cache.put(host, entry); return this; } @@ -780,7 +778,7 @@ if (policy == InetAddressCachePolicy.NEVER) { return null; } - CacheEntry entry = (CacheEntry)cache.get(host); + CacheEntry entry = cache.get(host); // check if entry has expired if (entry != null && policy != InetAddressCachePolicy.FOREVER) { @@ -814,42 +812,41 @@ } /* - * Cache the given hostname and address. + * Cache the given hostname and addresses. */ - private static void cacheAddress(String hostname, Object address, - boolean success) { + private static void cacheAddresses(String hostname, + InetAddress[] addresses, + boolean success) { hostname = hostname.toLowerCase(); synchronized (addressCache) { cacheInitIfNeeded(); if (success) { - addressCache.put(hostname, address); + addressCache.put(hostname, addresses); } else { - negativeCache.put(hostname, address); + negativeCache.put(hostname, addresses); } } } /* * Lookup hostname in cache (positive & negative cache). If - * found return address, null if not found. + * found return addresses, null if not found. */ - private static Object getCachedAddress(String hostname) { + private static InetAddress[] getCachedAddresses(String hostname) { hostname = hostname.toLowerCase(); // search both positive & negative caches synchronized (addressCache) { - CacheEntry entry; - cacheInitIfNeeded(); - entry = addressCache.get(hostname); + CacheEntry entry = addressCache.get(hostname); if (entry == null) { entry = negativeCache.get(hostname); } if (entry != null) { - return entry.address; + return entry.addresses; } } @@ -911,7 +908,7 @@ static { // create the impl - impl = (new InetAddressImplFactory()).create(); + impl = InetAddressImplFactory.create(); // get name service if provided and requested String provider = null;; @@ -931,7 +928,7 @@ } // if not designate any name services provider, - // creat a default one + // create a default one if (nameServices.size() == 0) { NameService ns = createNSProvider("default"); nameServices.add(ns); @@ -939,7 +936,7 @@ } /** - * Create an InetAddress based on the provided host name and IP address + * Creates an InetAddress based on the provided host name and IP address. * No name service is checked for the validity of the address. * * <p> The host name can either be a machine name, such as @@ -1067,13 +1064,13 @@ boolean ipv6Expected = false; if (host.charAt(0) == '[') { - // This is supposed to be an IPv6 litteral + // This is supposed to be an IPv6 literal if (host.length() > 2 && host.charAt(host.length()-1) == ']') { host = host.substring(1, host.length() -1); ipv6Expected = true; } else { // This was supposed to be a IPv6 address, but it's not! - throw new UnknownHostException(host); + throw new UnknownHostException(host + ": invalid IPv6 address"); } } @@ -1180,8 +1177,6 @@ throws UnknownHostException { /* If it gets here it is presumed to be a hostname */ /* Cache.get can return: null, unknownAddress, or InetAddress[] */ - Object obj = null; - Object objcopy = null; /* make sure the connection to the host is allowed, before we * give out a hostname @@ -1193,26 +1188,23 @@ } } - obj = getCachedAddress(host); + InetAddress[] addresses = getCachedAddresses(host); /* If no entry in cache, then do the host lookup */ - if (obj == null) { - obj = getAddressFromNameService(host); + if (addresses == null) { + addresses = getAddressesFromNameService(host); } - if (obj == unknown_array) + if (addresses == unknown_array) throw new UnknownHostException(host); - /* Make a copy of the InetAddress array */ - objcopy = ((InetAddress [])obj).clone(); - - return (InetAddress [])objcopy; + return addresses.clone(); } - private static Object getAddressFromNameService(String host) + private static InetAddress[] getAddressesFromNameService(String host) throws UnknownHostException { - Object obj = null; + InetAddress[] addresses = null; boolean success = false; UnknownHostException ex = null; @@ -1226,16 +1218,16 @@ // would be blocked until the host is removed // from the lookupTable. Then this thread // should try to look up the addressCache. - // i) if it found the address in the + // i) if it found the addresses in the // addressCache, checkLookupTable() would - // return the address. - // ii) if it didn't find the address in the + // return the addresses. + // ii) if it didn't find the addresses in the // addressCache for any reason, // it should add the host in the // lookupTable and return null so the // following code would do a lookup itself. - if ((obj = checkLookupTable(host)) == null) { - // This is the first thread which looks up the address + if ((addresses = checkLookupTable(host)) == null) { + // This is the first thread which looks up the addresses // this host or the cache entry for this host has been // expired so this thread should do the lookup. for (NameService nameService : nameServices) { @@ -1246,26 +1238,26 @@ * allocating space when the lookup fails. */ - obj = nameService.lookupAllHostAddr(host); + addresses = nameService.lookupAllHostAddr(host); success = true; break; } catch (UnknownHostException uhe) { if (host.equalsIgnoreCase("localhost")) { InetAddress[] local = new InetAddress[] { impl.loopbackAddress() }; - obj = local; + addresses = local; success = true; break; } else { - obj = unknown_array; + addresses = unknown_array; success = false; ex = uhe; } } } - // Cache the address. - cacheAddress(host, obj, success); + // Cache the addresses. + cacheAddresses(host, addresses, success); // Delete the host from the lookupTable, and // notify all threads waiting for the monitor // for lookupTable. @@ -1274,13 +1266,13 @@ throw ex; } - return obj; + return addresses; } - private static Object checkLookupTable(String host) { - // make sure obj is null. - Object obj = null; + private static InetAddress[] checkLookupTable(String host) { + // make sure addresses is null. + InetAddress[] addresses = null; synchronized (lookupTable) { // If the host isn't in the lookupTable, add it in the @@ -1288,11 +1280,11 @@ // the lookup. if (lookupTable.containsKey(host) == false) { lookupTable.put(host, null); - return obj; + return addresses; } // If the host is in the lookupTable, it means that another - // thread is trying to look up the address of this host. + // thread is trying to look up the addresses of this host. // This thread should wait. while (lookupTable.containsKey(host)) { try { @@ -1302,18 +1294,18 @@ } } - // The other thread has finished looking up the address of - // the host. This thread should retry to get the address - // from the addressCache. If it doesn't get the address from - // the cache, it will try to look up the address itself. - obj = getCachedAddress(host); - if (obj == null) { + // The other thread has finished looking up the addresses of + // the host. This thread should retry to get the addresses + // from the addressCache. If it doesn't get the addresses from + // the cache, it will try to look up the addresses itself. + addresses = getCachedAddresses(host); + if (addresses == null) { synchronized (lookupTable) { lookupTable.put(host, null); } } - return obj; + return addresses; } private static void updateLookupTable(String host) { @@ -1396,15 +1388,20 @@ cachedLocalHost = null; } - // we are calling getAddressFromNameService directly + // we are calling getAddressesFromNameService directly // to avoid getting localHost from cache if (ret == null) { InetAddress[] localAddrs; try { localAddrs = - (InetAddress[]) InetAddress.getAddressFromNameService(local); + InetAddress.getAddressesFromNameService(local); } catch (UnknownHostException uhe) { - throw new UnknownHostException(local + ": " + uhe.getMessage()); + // Rethrow with a more informative error message. + UnknownHostException uhe2 = + new UnknownHostException(local + ": " + + uhe.getMessage()); + uhe2.initCause(uhe); + throw uhe2; } cachedLocalHost = localAddrs[0]; cacheTime = now; @@ -1434,8 +1431,8 @@ /* * Load and instantiate an underlying impl class */ - static Object loadImpl(String implName) { - Object impl; + static InetAddressImpl loadImpl(String implName) { + Object impl = null; /* * Property "impl.prefix" will be prepended to the classname @@ -1446,7 +1443,6 @@ */ String prefix = AccessController.doPrivileged( new GetPropertyAction("impl.prefix", "")); - impl = null; try { impl = Class.forName("java.net." + prefix + implName).newInstance(); } catch (ClassNotFoundException e) { @@ -1471,7 +1467,7 @@ } } - return impl; + return (InetAddressImpl) impl; } private void readObjectNoData (ObjectInputStream s) throws @@ -1498,13 +1494,8 @@ class InetAddressImplFactory { static InetAddressImpl create() { - Object o; - if (isIPv6Supported()) { - o = InetAddress.loadImpl("Inet6AddressImpl"); - } else { - o = InetAddress.loadImpl("Inet4AddressImpl"); - } - return (InetAddressImpl)o; + return InetAddress.loadImpl(isIPv6Supported() ? + "Inet6AddressImpl" : "Inet4AddressImpl"); } static native boolean isIPv6Supported();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/java/nio/file/FileSystemLoopException.java Tue Oct 26 14:43:21 2010 -0400 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.nio.file; + +/** + * Checked exception thrown when a file system loop, or cycle, is encountered. + * + * @since 1.7 + * @see Files#walkFileTree + */ + +public class FileSystemLoopException + extends FileSystemException +{ + private static final long serialVersionUID = 4843039591949217617L; + + /** + * Constructs an instance of this class. + * + * @param file + * a string identifying the file causing the cycle or {@code null} if + * not known + */ + public FileSystemLoopException(String file) { + super(file); + } +}
--- a/jdk/src/share/classes/java/nio/file/FileTreeWalker.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/nio/file/FileTreeWalker.java Tue Oct 26 14:43:21 2010 -0400 @@ -38,7 +38,6 @@ class FileTreeWalker { private final boolean followLinks; - private final boolean detectCycles; private final LinkOption[] linkOptions; private final FileVisitor<? super Path> visitor; private final int maxDepth; @@ -48,17 +47,15 @@ int maxDepth) { boolean fl = false; - boolean dc = false; for (FileVisitOption option: options) { + // will throw NPE if options contains null switch (option) { - case FOLLOW_LINKS : fl = true; break; - case DETECT_CYCLES : dc = true; break; + case FOLLOW_LINKS : fl = true; break; default: throw new AssertionError("Should not get here"); } } this.followLinks = fl; - this.detectCycles = fl | dc; this.linkOptions = (fl) ? new LinkOption[0] : new LinkOption[] { LinkOption.NOFOLLOW_LINKS }; this.visitor = visitor; @@ -68,13 +65,11 @@ /** * Walk file tree starting at the given file */ - void walk(Path start) { + void walk(Path start) throws IOException { FileVisitResult result = walk(start, 0, new ArrayList<AncestorDirectory>()); - if (result == null) { - throw new NullPointerException("Visitor returned 'null'"); - } + Objects.nonNull(result, "FileVisitor returned null"); } /** @@ -88,11 +83,8 @@ private FileVisitResult walk(Path file, int depth, List<AncestorDirectory> ancestors) + throws IOException { - // depth check - if (depth > maxDepth) - return FileVisitResult.CONTINUE; - // if attributes are cached then use them if possible BasicFileAttributes attrs = null; if ((depth > 0) && @@ -137,13 +129,13 @@ return visitor.visitFileFailed(file, exc); } - // file is not a directory so invoke visitFile method - if (!attrs.isDirectory()) { + // at maximum depth or file is not a directory + if (depth >= maxDepth || !attrs.isDirectory()) { return visitor.visitFile(file, attrs); } - // check for cycles - if (detectCycles) { + // check for cycles when following links + if (followLinks) { Object key = attrs.fileKey(); // if this directory and ancestor has a file key then we compare @@ -153,19 +145,23 @@ if (key != null && ancestorKey != null) { if (key.equals(ancestorKey)) { // cycle detected - return visitor.visitFile(file, attrs); + return visitor.visitFileFailed(file, + new FileSystemLoopException(file.toString())); } } else { + boolean isSameFile = false; try { - if (file.isSameFile(ancestor.file())) { - // cycle detected - return visitor.visitFile(file, attrs); - } + isSameFile = file.isSameFile(ancestor.file()); } catch (IOException x) { // ignore } catch (SecurityException x) { // ignore } + if (isSameFile) { + // cycle detected + return visitor.visitFileFailed(file, + new FileSystemLoopException(file.toString())); + } } } @@ -181,7 +177,7 @@ try { stream = file.newDirectoryStream(); } catch (IOException x) { - return visitor.preVisitDirectoryFailed(file, x); + return visitor.visitFileFailed(file, x); } catch (SecurityException x) { // ignore, as per spec return FileVisitResult.CONTINUE; @@ -192,20 +188,14 @@ // invoke preVisitDirectory and then visit each entry try { - result = visitor.preVisitDirectory(file); + result = visitor.preVisitDirectory(file, attrs); if (result != FileVisitResult.CONTINUE) { return result; } - // if an I/O occurs during iteration then a CME is thrown. We - // need to distinguish this from a CME thrown by the visitor. - boolean inAction = false; - try { for (Path entry: stream) { - inAction = true; result = walk(entry, depth+1, ancestors); - inAction = false; // returning null will cause NPE to be thrown if (result == null || result == FileVisitResult.TERMINATE) @@ -215,17 +205,9 @@ if (result == FileVisitResult.SKIP_SIBLINGS) break; } - } catch (ConcurrentModificationException x) { - // if CME thrown because the iteration failed then remember - // the IOException so that it is notified to postVisitDirectory - if (!inAction) { - // iteration failed - Throwable t = x.getCause(); - if (t instanceof IOException) - ioe = (IOException)t; - } - if (ioe == null) - throw x; + } catch (DirectoryIteratorException e) { + // IOException will be notified to postVisitDirectory + ioe = e.getCause(); } } finally { try { @@ -238,7 +220,7 @@ } finally { // remove key from trail if doing cycle detection - if (detectCycles) { + if (followLinks) { ancestors.remove(ancestors.size()-1); } }
--- a/jdk/src/share/classes/java/nio/file/FileVisitOption.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/nio/file/FileVisitOption.java Tue Oct 26 14:43:21 2010 -0400 @@ -37,9 +37,5 @@ /** * Follow symbolic links. */ - FOLLOW_LINKS, - /** - * Detect cycles in the file tree. - */ - DETECT_CYCLES; + FOLLOW_LINKS; }
--- a/jdk/src/share/classes/java/nio/file/FileVisitor.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/nio/file/FileVisitor.java Tue Oct 26 14:43:21 2010 -0400 @@ -40,33 +40,28 @@ * Path start = ... * Files.walkFileTree(start, new SimpleFileVisitor<Path>() { * @Override - * public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { - * try { - * file.delete(); - * } catch (IOException exc) { - * // failed to delete, do error handling here - * } + * public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) + * throws IOException + * { + * file.delete(); * return FileVisitResult.CONTINUE; * } * @Override - * public FileVisitResult postVisitDirectory(Path dir, IOException e) { - * if (e == null) { - * try { - * dir.delete(); - * } catch (IOException exc) { - * // failed to delete, do error handling here - * } - * } else { + * public FileVisitResult postVisitDirectory(Path dir, IOException e) + * throws IOException + * { + * if (e != null) { * // directory iteration failed + * throw e; * } + * dir.delete(); * return FileVisitResult.CONTINUE; * } * }); * </pre> - * <p> Furthermore, suppose we want to copy a file tree rooted at a source - * directory to a target location. In that case, symbolic links should be - * followed and the target directory should be created before the entries in - * the directory are copied. + * <p> Furthermore, suppose we want to copy a file tree to a target location. + * In that case, symbolic links should be followed and the target directory + * should be created before the entries in the directory are copied. * <pre> * final Path source = ... * final Path target = ... @@ -74,25 +69,21 @@ * Files.walkFileTree(source, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, * new SimpleFileVisitor<Path>() { * @Override - * public FileVisitResult preVisitDirectory(Path dir) { + * public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) + * throws IOException + * { * try { * dir.copyTo(target.resolve(source.relativize(dir))); * } catch (FileAlreadyExistsException e) { * // ignore - * } catch (IOException e) { - * // copy failed, do error handling here - * // skip rest of directory and descendants - * return SKIP_SUBTREE; * } * return CONTINUE; * } * @Override - * public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { - * try { - * file.copyTo(target.resolve(source.relativize(file))); - * } catch (IOException e) { - * // copy failed, do error handling here - * } + * public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) + * throws IOException + * { + * file.copyTo(target.resolve(source.relativize(file))); * return CONTINUE; * } * }); @@ -114,22 +105,16 @@ * * @param dir * a reference to the directory + * @param attrs + * the directory's basic attributes * * @return the visit result + * + * @throws IOException + * if an I/O error occurs */ - FileVisitResult preVisitDirectory(T dir); - - /** - * Invoked for a directory that could not be opened. - * - * @param dir - * a reference to the directory - * @param exc - * the I/O exception thrown from the attempt to open the directory - * - * @return the visit result - */ - FileVisitResult preVisitDirectoryFailed(T dir, IOException exc); + FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs) + throws IOException; /** * Invoked for a file in a directory. @@ -140,21 +125,30 @@ * the file's basic attributes * * @return the visit result + * + * @throws IOException + * if an I/O error occurs */ - FileVisitResult visitFile(T file, BasicFileAttributes attrs); + FileVisitResult visitFile(T file, BasicFileAttributes attrs) + throws IOException; /** - * Invoked for a file when its basic file attributes could not be read. + * Invoked for a file that could not be visited. This method is invoked + * if the file's attributes could not be read, the file is a directory + * that could not be opened, and other reasons. * * @param file * a reference to the file * @param exc - * the I/O exception thrown from the attempt to read the file - * attributes + * the I/O exception that prevented the file from being visited * * @return the visit result + * + * @throws IOException + * if an I/O error occurs */ - FileVisitResult visitFileFailed(T file, IOException exc); + FileVisitResult visitFileFailed(T file, IOException exc) + throws IOException; /** * Invoked for a directory after entries in the directory, and all of their @@ -171,6 +165,10 @@ * of the directory to complete prematurely * * @return the visit result + * + * @throws IOException + * if an I/O error occurs */ - FileVisitResult postVisitDirectory(T dir, IOException exc); + FileVisitResult postVisitDirectory(T dir, IOException exc) + throws IOException; }
--- a/jdk/src/share/classes/java/nio/file/Files.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/nio/file/Files.java Tue Oct 26 14:43:21 2010 -0400 @@ -135,9 +135,9 @@ * FileVisitor} invoked for each file encountered. File tree traversal * completes when all accessible files in the tree have been visited, or a * visit method returns a result of {@link FileVisitResult#TERMINATE - * TERMINATE}. Where a visit method terminates due an uncaught error or - * runtime exception then the traversal is terminated and the error or - * exception is propagated to the caller of this method. + * TERMINATE}. Where a visit method terminates due an {@code IOException}, + * an uncaught error, or runtime exception, then the traversal is terminated + * and the error or exception is propagated to the caller of this method. * * <p> For each file encountered this method attempts to gets its {@link * java.nio.file.attribute.BasicFileAttributes}. If the file is not a @@ -146,12 +146,10 @@ * due to an I/O exception, then the {@link FileVisitor#visitFileFailed * visitFileFailed} method is invoked with the I/O exception. * - * <p> Where the file is a directory, this method attempts to open it by - * invoking its {@link Path#newDirectoryStream newDirectoryStream} method. - * Where the directory could not be opened, due to an {@code IOException}, - * then the {@link FileVisitor#preVisitDirectoryFailed preVisitDirectoryFailed} - * method is invoked with the I/O exception, after which, the file tree walk - * continues, by default, at the next <em>sibling</em> of the directory. + * <p> Where the file is a directory, and the directory could not be opened, + * then the {@code visitFileFailed} method is invoked with the I/O exception, + * after which, the file tree walk continues, by default, at the next + * <em>sibling</em> of the directory. * * <p> Where the directory is opened successfully, then the entries in the * directory, and their <em>descendants</em> are visited. When all entries @@ -171,26 +169,25 @@ * method is invoked as specified above). * * <p> If the {@code options} parameter contains the {@link - * FileVisitOption#DETECT_CYCLES DETECT_CYCLES} or {@link - * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} options then this method keeps + * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then this method keeps * track of directories visited so that cycles can be detected. A cycle * arises when there is an entry in a directory that is an ancestor of the * directory. Cycle detection is done by recording the {@link * java.nio.file.attribute.BasicFileAttributes#fileKey file-key} of directories, * or if file keys are not available, by invoking the {@link Path#isSameFile * isSameFile} method to test if a directory is the same file as an - * ancestor. When a cycle is detected the {@link FileVisitor#visitFile - * visitFile} is invoked with the attributes of the directory. The {@link - * java.nio.file.attribute.BasicFileAttributes#isDirectory isDirectory} - * method may be used to test if the file is a directory and that a cycle is - * detected. The {@code preVisitDirectory} and {@code postVisitDirectory} - * methods are not invoked. + * ancestor. When a cycle is detected it is treated as an I/O error, and the + * {@link FileVisitor#visitFileFailed visitFileFailed} method is invoked with + * an instance of {@link FileSystemLoopException}. * * <p> The {@code maxDepth} parameter is the maximum number of levels of * directories to visit. A value of {@code 0} means that only the starting * file is visited, unless denied by the security manager. A value of * {@link Integer#MAX_VALUE MAX_VALUE} may be used to indicate that all - * levels should be visited. + * levels should be visited. The {@code visitFile} method is invoked for all + * files, including directories, encountered at {@code maxDepth}, unless the + * basic file attributes cannot be read, in which case the {@code + * visitFileFailed} method is invoked. * * <p> If a visitor returns a result of {@code null} then {@code * NullPointerException} is thrown. @@ -215,11 +212,14 @@ * In the case of the default provider, the {@link * SecurityManager#checkRead(String) checkRead} method is invoked * to check read access to the directory. + * @throws IOException + * If an I/O error is thrown by a visitor method */ public static void walkFileTree(Path start, Set<FileVisitOption> options, int maxDepth, FileVisitor<? super Path> visitor) + throws IOException { if (maxDepth < 0) throw new IllegalArgumentException("'maxDepth' is negative"); @@ -245,8 +245,12 @@ * In the case of the default provider, the {@link * SecurityManager#checkRead(String) checkRead} method is invoked * to check read access to the directory. + * @throws IOException + * If an I/O error is thrown by a visitor method */ - public static void walkFileTree(Path start, FileVisitor<? super Path> visitor) { + public static void walkFileTree(Path start, FileVisitor<? super Path> visitor) + throws IOException + { walkFileTree(start, EnumSet.noneOf(FileVisitOption.class), Integer.MAX_VALUE,
--- a/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java Tue Oct 26 14:43:21 2010 -0400 @@ -27,7 +27,7 @@ import java.nio.file.attribute.BasicFileAttributes; import java.io.IOException; -import java.io.IOError; +import java.util.Objects; /** * A simple visitor of files with default behavior to visit all files and to @@ -48,70 +48,47 @@ } /** - * Throws NullPointerException if obj is null. - */ - private static void checkNotNull(Object obj) { - if (obj == null) - throw new NullPointerException(); - } - - /** * Invoked for a directory before entries in the directory are visited. * * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE * CONTINUE}. */ @Override - public FileVisitResult preVisitDirectory(T dir) { - checkNotNull(dir); + public FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs) + throws IOException + { + Objects.nonNull(dir); + Objects.nonNull(attrs); return FileVisitResult.CONTINUE; } /** - * Invoked for a directory that could not be opened. - * - * <p> Unless overridden, this method throws {@link IOError} with the I/O - * exception as cause. - * - * @throws IOError - * with the I/O exception thrown when the attempt to open the - * directory failed - */ - @Override - public FileVisitResult preVisitDirectoryFailed(T dir, IOException exc) { - checkNotNull(dir); - checkNotNull(exc); - throw new IOError(exc); - } - - /** * Invoked for a file in a directory. * * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE * CONTINUE}. */ @Override - public FileVisitResult visitFile(T file, BasicFileAttributes attrs) { - checkNotNull(file); - checkNotNull(attrs); + public FileVisitResult visitFile(T file, BasicFileAttributes attrs) + throws IOException + { + Objects.nonNull(file); + Objects.nonNull(attrs); return FileVisitResult.CONTINUE; } /** - * Invoked for a file when its basic file attributes could not be read. + * Invoked for a file that could not be visited. * - * <p> Unless overridden, this method throws {@link IOError} with the I/O - * exception as cause. - * - * @throws IOError - * with the I/O exception thrown when the attempt to read the file - * attributes failed + * <p> Unless overridden, this method re-throws the I/O exception that prevented + * the file from being visited. */ @Override - public FileVisitResult visitFileFailed(T file, IOException exc) { - checkNotNull(file); - checkNotNull(exc); - throw new IOError(exc); + public FileVisitResult visitFileFailed(T file, IOException exc) + throws IOException + { + Objects.nonNull(file); + throw exc; } /** @@ -120,18 +97,16 @@ * * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE * CONTINUE} if the directory iteration completes without an I/O exception; - * otherwise this method throws {@link IOError} with the I/O exception as - * cause. - * - * @throws IOError - * with the I/O exception thrown when iteration of the directory - * completed prematurely due to an I/O error + * otherwise this method re-throws the I/O exception that caused the iteration + * of the directory to terminate prematurely. */ @Override - public FileVisitResult postVisitDirectory(T dir, IOException exc) { - checkNotNull(dir); + public FileVisitResult postVisitDirectory(T dir, IOException exc) + throws IOException + { + Objects.nonNull(dir); if (exc != null) - throw new IOError(exc); + throw exc; return FileVisitResult.CONTINUE; } }
--- a/jdk/src/share/classes/java/sql/DatabaseMetaData.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/sql/DatabaseMetaData.java Tue Oct 26 14:43:21 2010 -0400 @@ -3643,7 +3643,7 @@ /** * Retrieves whether a generated key will always be returned if the column - * name(s) or indexe(s) specified for the auto generated key column(s) + * name(s) or index(es) specified for the auto generated key column(s) * are valid and the statement succeeds. The key that is returned may or * may not be based on the column(s) for the auto generated key. * Consult your JDBC driver documentation for additional details.
--- a/jdk/src/share/classes/java/sql/Statement.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/sql/Statement.java Tue Oct 26 14:43:21 2010 -0400 @@ -1051,9 +1051,9 @@ /** * Returns a value indicating whether this {@code Statement} will be - * closed when all dependent objects such as resultsets are closed. + * closed when all its dependent result sets are closed. * @return {@code true} if the {@code Statement} will be closed when all - * of its dependent objects are closed; {@code false} otherwise + * of its dependent result sets are closed; {@code false} otherwise * @throws SQLException if this method is called on a closed * {@code Statement} * @since 1.7
--- a/jdk/src/share/classes/java/util/Locale.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/util/Locale.java Tue Oct 26 14:43:21 2010 -0400 @@ -569,6 +569,9 @@ * @exception NullPointerException thrown if any argument is null. */ public Locale(String language, String country, String variant) { + if (language== null || country == null || variant == null) { + throw new NullPointerException(); + } _baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), "", country, variant); _extensions = getCompatibilityExtensions(language, "", country, variant); }
--- a/jdk/src/share/classes/java/util/ResourceBundle.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/util/ResourceBundle.java Tue Oct 26 14:43:21 2010 -0400 @@ -293,16 +293,6 @@ = new ConcurrentHashMap<CacheKey, BundleReference>(INITIAL_CACHE_SIZE); /** - * This ConcurrentMap is used to keep multiple threads from loading the - * same bundle concurrently. The table entries are <CacheKey, Thread> - * where CacheKey is the key for the bundle that is under construction - * and Thread is the thread that is constructing the bundle. - * This list is manipulated in findBundleInCache and putBundleInCache. - */ - private static final ConcurrentMap<CacheKey, Thread> underConstruction - = new ConcurrentHashMap<CacheKey, Thread>(); - - /** * Queue for reference objects referring to class loaders or bundles. */ private static final ReferenceQueue referenceQueue = new ReferenceQueue(); @@ -1381,7 +1371,7 @@ boolean expiredBundle = false; // First, look up the cache to see if it's in the cache, without - // declaring beginLoading. + // attempting to load bundle. cacheKey.setLocale(targetLocale); ResourceBundle bundle = findBundleInCache(cacheKey, control); if (isValidBundle(bundle)) { @@ -1408,56 +1398,25 @@ CacheKey constKey = (CacheKey) cacheKey.clone(); try { - // Try declaring loading. If beginLoading() returns true, - // then we can proceed. Otherwise, we need to take a look - // at the cache again to see if someone else has loaded - // the bundle and put it in the cache while we've been - // waiting for other loading work to complete. - while (!beginLoading(constKey)) { - bundle = findBundleInCache(cacheKey, control); - if (bundle == null) { - continue; + bundle = loadBundle(cacheKey, formats, control, expiredBundle); + if (bundle != null) { + if (bundle.parent == null) { + bundle.setParent(parent); } - if (bundle == NONEXISTENT_BUNDLE) { - // If the bundle is NONEXISTENT_BUNDLE, the bundle doesn't exist. - return parent; - } - expiredBundle = bundle.expired; - if (!expiredBundle) { - if (bundle.parent == parent) { - return bundle; - } - BundleReference bundleRef = cacheList.get(cacheKey); - if (bundleRef != null && bundleRef.get() == bundle) { - cacheList.remove(cacheKey, bundleRef); - } - } + bundle.locale = targetLocale; + bundle = putBundleInCache(cacheKey, bundle, control); + return bundle; } - try { - bundle = loadBundle(cacheKey, formats, control, expiredBundle); - if (bundle != null) { - if (bundle.parent == null) { - bundle.setParent(parent); - } - bundle.locale = targetLocale; - bundle = putBundleInCache(cacheKey, bundle, control); - return bundle; - } - - // Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle - // instance for the locale. - putBundleInCache(cacheKey, NONEXISTENT_BUNDLE, control); - } finally { - endLoading(constKey); - } + // Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle + // instance for the locale. + putBundleInCache(cacheKey, NONEXISTENT_BUNDLE, control); } finally { if (constKey.getCause() instanceof InterruptedException) { Thread.currentThread().interrupt(); } } } - assert underConstruction.get(cacheKey) != Thread.currentThread(); return parent; } @@ -1465,7 +1424,6 @@ List<String> formats, Control control, boolean reload) { - assert underConstruction.get(cacheKey) == Thread.currentThread(); // Here we actually load the bundle in the order of formats // specified by the getFormats() value. @@ -1498,7 +1456,6 @@ break; } } - assert underConstruction.get(cacheKey) == Thread.currentThread(); return bundle; } @@ -1530,57 +1487,6 @@ } /** - * Declares the beginning of actual resource bundle loading. This method - * returns true if the declaration is successful and the current thread has - * been put in underConstruction. If someone else has already begun - * loading, this method waits until that loading work is complete and - * returns false. - */ - private static final boolean beginLoading(CacheKey constKey) { - Thread me = Thread.currentThread(); - Thread worker; - // We need to declare by putting the current Thread (me) to - // underConstruction that we are working on loading the specified - // resource bundle. If we are already working the loading, it means - // that the resource loading requires a recursive call. In that case, - // we have to proceed. (4300693) - if (((worker = underConstruction.putIfAbsent(constKey, me)) == null) - || worker == me) { - return true; - } - - // If someone else is working on the loading, wait until - // the Thread finishes the bundle loading. - synchronized (worker) { - while (underConstruction.get(constKey) == worker) { - try { - worker.wait(); - } catch (InterruptedException e) { - // record the interruption - constKey.setCause(e); - } - } - } - return false; - } - - /** - * Declares the end of the bundle loading. This method calls notifyAll - * for those who are waiting for this completion. - */ - private static final void endLoading(CacheKey constKey) { - // Remove this Thread from the underConstruction map and wake up - // those who have been waiting for me to complete this bundle - // loading. - Thread me = Thread.currentThread(); - assert (underConstruction.get(constKey) == me); - underConstruction.remove(constKey); - synchronized (me) { - me.notifyAll(); - } - } - - /** * Throw a MissingResourceException with proper message */ private static final void throwMissingResourceException(String baseName,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java Tue Oct 26 14:43:21 2010 -0400 @@ -0,0 +1,1445 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Written by Doug Lea and Martin Buchholz with assistance from members of + * JCP JSR-166 Expert Group and released to the public domain, as explained + * at http://creativecommons.org/licenses/publicdomain + */ + +package java.util.concurrent; + +import java.util.AbstractCollection; +import java.util.ArrayList; +import java.util.Collection; +import java.util.ConcurrentModificationException; +import java.util.Deque; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Queue; + +/** + * An unbounded concurrent {@linkplain Deque deque} based on linked nodes. + * Concurrent insertion, removal, and access operations execute safely + * across multiple threads. + * A {@code ConcurrentLinkedDeque} is an appropriate choice when + * many threads will share access to a common collection. + * Like most other concurrent collection implementations, this class + * does not permit the use of {@code null} elements. + * + * <p>Iterators are <i>weakly consistent</i>, returning elements + * reflecting the state of the deque at some point at or since the + * creation of the iterator. They do <em>not</em> throw {@link + * java.util.ConcurrentModificationException + * ConcurrentModificationException}, and may proceed concurrently with + * other operations. + * + * <p>Beware that, unlike in most collections, the {@code size} + * method is <em>NOT</em> a constant-time operation. Because of the + * asynchronous nature of these deques, determining the current number + * of elements requires a traversal of the elements. + * + * <p>This class and its iterator implement all of the <em>optional</em> + * methods of the {@link Deque} and {@link Iterator} interfaces. + * + * <p>Memory consistency effects: As with other concurrent collections, + * actions in a thread prior to placing an object into a + * {@code ConcurrentLinkedDeque} + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> + * actions subsequent to the access or removal of that element from + * the {@code ConcurrentLinkedDeque} in another thread. + * + * <p>This class is a member of the + * <a href="{@docRoot}/../technotes/guides/collections/index.html"> + * Java Collections Framework</a>. + * + * @since 1.7 + * @author Doug Lea + * @author Martin Buchholz + * @param <E> the type of elements held in this collection + */ + +public class ConcurrentLinkedDeque<E> + extends AbstractCollection<E> + implements Deque<E>, java.io.Serializable { + + /* + * This is an implementation of a concurrent lock-free deque + * supporting interior removes but not interior insertions, as + * required to support the entire Deque interface. + * + * We extend the techniques developed for ConcurrentLinkedQueue and + * LinkedTransferQueue (see the internal docs for those classes). + * Understanding the ConcurrentLinkedQueue implementation is a + * prerequisite for understanding the implementation of this class. + * + * The data structure is a symmetrical doubly-linked "GC-robust" + * linked list of nodes. We minimize the number of volatile writes + * using two techniques: advancing multiple hops with a single CAS + * and mixing volatile and non-volatile writes of the same memory + * locations. + * + * A node contains the expected E ("item") and links to predecessor + * ("prev") and successor ("next") nodes: + * + * class Node<E> { volatile Node<E> prev, next; volatile E item; } + * + * A node p is considered "live" if it contains a non-null item + * (p.item != null). When an item is CASed to null, the item is + * atomically logically deleted from the collection. + * + * At any time, there is precisely one "first" node with a null + * prev reference that terminates any chain of prev references + * starting at a live node. Similarly there is precisely one + * "last" node terminating any chain of next references starting at + * a live node. The "first" and "last" nodes may or may not be live. + * The "first" and "last" nodes are always mutually reachable. + * + * A new element is added atomically by CASing the null prev or + * next reference in the first or last node to a fresh node + * containing the element. The element's node atomically becomes + * "live" at that point. + * + * A node is considered "active" if it is a live node, or the + * first or last node. Active nodes cannot be unlinked. + * + * A "self-link" is a next or prev reference that is the same node: + * p.prev == p or p.next == p + * Self-links are used in the node unlinking process. Active nodes + * never have self-links. + * + * A node p is active if and only if: + * + * p.item != null || + * (p.prev == null && p.next != p) || + * (p.next == null && p.prev != p) + * + * The deque object has two node references, "head" and "tail". + * The head and tail are only approximations to the first and last + * nodes of the deque. The first node can always be found by + * following prev pointers from head; likewise for tail. However, + * it is permissible for head and tail to be referring to deleted + * nodes that have been unlinked and so may not be reachable from + * any live node. + * + * There are 3 stages of node deletion; + * "logical deletion", "unlinking", and "gc-unlinking". + * + * 1. "logical deletion" by CASing item to null atomically removes + * the element from the collection, and makes the containing node + * eligible for unlinking. + * + * 2. "unlinking" makes a deleted node unreachable from active + * nodes, and thus eventually reclaimable by GC. Unlinked nodes + * may remain reachable indefinitely from an iterator. + * + * Physical node unlinking is merely an optimization (albeit a + * critical one), and so can be performed at our convenience. At + * any time, the set of live nodes maintained by prev and next + * links are identical, that is, the live nodes found via next + * links from the first node is equal to the elements found via + * prev links from the last node. However, this is not true for + * nodes that have already been logically deleted - such nodes may + * be reachable in one direction only. + * + * 3. "gc-unlinking" takes unlinking further by making active + * nodes unreachable from deleted nodes, making it easier for the + * GC to reclaim future deleted nodes. This step makes the data + * structure "gc-robust", as first described in detail by Boehm + * (http://portal.acm.org/citation.cfm?doid=503272.503282). + * + * GC-unlinked nodes may remain reachable indefinitely from an + * iterator, but unlike unlinked nodes, are never reachable from + * head or tail. + * + * Making the data structure GC-robust will eliminate the risk of + * unbounded memory retention with conservative GCs and is likely + * to improve performance with generational GCs. + * + * When a node is dequeued at either end, e.g. via poll(), we would + * like to break any references from the node to active nodes. We + * develop further the use of self-links that was very effective in + * other concurrent collection classes. The idea is to replace + * prev and next pointers with special values that are interpreted + * to mean off-the-list-at-one-end. These are approximations, but + * good enough to preserve the properties we want in our + * traversals, e.g. we guarantee that a traversal will never visit + * the same element twice, but we don't guarantee whether a + * traversal that runs out of elements will be able to see more + * elements later after enqueues at that end. Doing gc-unlinking + * safely is particularly tricky, since any node can be in use + * indefinitely (for example by an iterator). We must ensure that + * the nodes pointed at by head/tail never get gc-unlinked, since + * head/tail are needed to get "back on track" by other nodes that + * are gc-unlinked. gc-unlinking accounts for much of the + * implementation complexity. + * + * Since neither unlinking nor gc-unlinking are necessary for + * correctness, there are many implementation choices regarding + * frequency (eagerness) of these operations. Since volatile + * reads are likely to be much cheaper than CASes, saving CASes by + * unlinking multiple adjacent nodes at a time may be a win. + * gc-unlinking can be performed rarely and still be effective, + * since it is most important that long chains of deleted nodes + * are occasionally broken. + * + * The actual representation we use is that p.next == p means to + * goto the first node (which in turn is reached by following prev + * pointers from head), and p.next == null && p.prev == p means + * that the iteration is at an end and that p is a (final static) + * dummy node, NEXT_TERMINATOR, and not the last active node. + * Finishing the iteration when encountering such a TERMINATOR is + * good enough for read-only traversals, so such traversals can use + * p.next == null as the termination condition. When we need to + * find the last (active) node, for enqueueing a new node, we need + * to check whether we have reached a TERMINATOR node; if so, + * restart traversal from tail. + * + * The implementation is completely directionally symmetrical, + * except that most public methods that iterate through the list + * follow next pointers ("forward" direction). + * + * We believe (without full proof) that all single-element deque + * operations (e.g., addFirst, peekLast, pollLast) are linearizable + * (see Herlihy and Shavit's book). However, some combinations of + * operations are known not to be linearizable. In particular, + * when an addFirst(A) is racing with pollFirst() removing B, it is + * possible for an observer iterating over the elements to observe + * A B C and subsequently observe A C, even though no interior + * removes are ever performed. Nevertheless, iterators behave + * reasonably, providing the "weakly consistent" guarantees. + * + * Empirically, microbenchmarks suggest that this class adds about + * 40% overhead relative to ConcurrentLinkedQueue, which feels as + * good as we can hope for. + */ + + private static final long serialVersionUID = 876323262645176354L; + + /** + * A node from which the first node on list (that is, the unique node p + * with p.prev == null && p.next != p) can be reached in O(1) time. + * Invariants: + * - the first node is always O(1) reachable from head via prev links + * - all live nodes are reachable from the first node via succ() + * - head != null + * - (tmp = head).next != tmp || tmp != head + * - head is never gc-unlinked (but may be unlinked) + * Non-invariants: + * - head.item may or may not be null + * - head may not be reachable from the first or last node, or from tail + */ + private transient volatile Node<E> head; + + /** + * A node from which the last node on list (that is, the unique node p + * with p.next == null && p.prev != p) can be reached in O(1) time. + * Invariants: + * - the last node is always O(1) reachable from tail via next links + * - all live nodes are reachable from the last node via pred() + * - tail != null + * - tail is never gc-unlinked (but may be unlinked) + * Non-invariants: + * - tail.item may or may not be null + * - tail may not be reachable from the first or last node, or from head + */ + private transient volatile Node<E> tail; + + private final static Node<Object> PREV_TERMINATOR, NEXT_TERMINATOR; + + static { + PREV_TERMINATOR = new Node<Object>(null); + PREV_TERMINATOR.next = PREV_TERMINATOR; + NEXT_TERMINATOR = new Node<Object>(null); + NEXT_TERMINATOR.prev = NEXT_TERMINATOR; + } + + @SuppressWarnings("unchecked") + Node<E> prevTerminator() { + return (Node<E>) PREV_TERMINATOR; + } + + @SuppressWarnings("unchecked") + Node<E> nextTerminator() { + return (Node<E>) NEXT_TERMINATOR; + } + + static final class Node<E> { + volatile Node<E> prev; + volatile E item; + volatile Node<E> next; + + /** + * Constructs a new node. Uses relaxed write because item can + * only be seen after publication via casNext or casPrev. + */ + Node(E item) { + UNSAFE.putObject(this, itemOffset, item); + } + + boolean casItem(E cmp, E val) { + return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val); + } + + void lazySetNext(Node<E> val) { + UNSAFE.putOrderedObject(this, nextOffset, val); + } + + boolean casNext(Node<E> cmp, Node<E> val) { + return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val); + } + + void lazySetPrev(Node<E> val) { + UNSAFE.putOrderedObject(this, prevOffset, val); + } + + boolean casPrev(Node<E> cmp, Node<E> val) { + return UNSAFE.compareAndSwapObject(this, prevOffset, cmp, val); + } + + // Unsafe mechanics + + private static final sun.misc.Unsafe UNSAFE = + sun.misc.Unsafe.getUnsafe(); + private static final long prevOffset = + objectFieldOffset(UNSAFE, "prev", Node.class); + private static final long itemOffset = + objectFieldOffset(UNSAFE, "item", Node.class); + private static final long nextOffset = + objectFieldOffset(UNSAFE, "next", Node.class); + } + + /** + * Links e as first element. + */ + private void linkFirst(E e) { + checkNotNull(e); + final Node<E> newNode = new Node<E>(e); + + restartFromHead: + for (;;) + for (Node<E> h = head, p = h, q;;) { + if ((q = p.prev) != null && + (q = (p = q).prev) != null) + // Check for head updates every other hop. + // If p == q, we are sure to follow head instead. + p = (h != (h = head)) ? h : q; + else if (p.next == p) // PREV_TERMINATOR + continue restartFromHead; + else { + // p is first node + newNode.lazySetNext(p); // CAS piggyback + if (p.casPrev(null, newNode)) { + // Successful CAS is the linearization point + // for e to become an element of this deque, + // and for newNode to become "live". + if (p != h) // hop two nodes at a time + casHead(h, newNode); // Failure is OK. + return; + } + // Lost CAS race to another thread; re-read prev + } + } + } + + /** + * Links e as last element. + */ + private void linkLast(E e) { + checkNotNull(e); + final Node<E> newNode = new Node<E>(e); + + restartFromTail: + for (;;) + for (Node<E> t = tail, p = t, q;;) { + if ((q = p.next) != null && + (q = (p = q).next) != null) + // Check for tail updates every other hop. + // If p == q, we are sure to follow tail instead. + p = (t != (t = tail)) ? t : q; + else if (p.prev == p) // NEXT_TERMINATOR + continue restartFromTail; + else { + // p is last node + newNode.lazySetPrev(p); // CAS piggyback + if (p.casNext(null, newNode)) { + // Successful CAS is the linearization point + // for e to become an element of this deque, + // and for newNode to become "live". + if (p != t) // hop two nodes at a time + casTail(t, newNode); // Failure is OK. + return; + } + // Lost CAS race to another thread; re-read next + } + } + } + + private final static int HOPS = 2; + + /** + * Unlinks non-null node x. + */ + void unlink(Node<E> x) { + // assert x != null; + // assert x.item == null; + // assert x != PREV_TERMINATOR; + // assert x != NEXT_TERMINATOR; + + final Node<E> prev = x.prev; + final Node<E> next = x.next; + if (prev == null) { + unlinkFirst(x, next); + } else if (next == null) { + unlinkLast(x, prev); + } else { + // Unlink interior node. + // + // This is the common case, since a series of polls at the + // same end will be "interior" removes, except perhaps for + // the first one, since end nodes cannot be unlinked. + // + // At any time, all active nodes are mutually reachable by + // following a sequence of either next or prev pointers. + // + // Our strategy is to find the unique active predecessor + // and successor of x. Try to fix up their links so that + // they point to each other, leaving x unreachable from + // active nodes. If successful, and if x has no live + // predecessor/successor, we additionally try to gc-unlink, + // leaving active nodes unreachable from x, by rechecking + // that the status of predecessor and successor are + // unchanged and ensuring that x is not reachable from + // tail/head, before setting x's prev/next links to their + // logical approximate replacements, self/TERMINATOR. + Node<E> activePred, activeSucc; + boolean isFirst, isLast; + int hops = 1; + + // Find active predecessor + for (Node<E> p = prev; ; ++hops) { + if (p.item != null) { + activePred = p; + isFirst = false; + break; + } + Node<E> q = p.prev; + if (q == null) { + if (p.next == p) + return; + activePred = p; + isFirst = true; + break; + } + else if (p == q) + return; + else + p = q; + } + + // Find active successor + for (Node<E> p = next; ; ++hops) { + if (p.item != null) { + activeSucc = p; + isLast = false; + break; + } + Node<E> q = p.next; + if (q == null) { + if (p.prev == p) + return; + activeSucc = p; + isLast = true; + break; + } + else if (p == q) + return; + else + p = q; + } + + // TODO: better HOP heuristics + if (hops < HOPS + // always squeeze out interior deleted nodes + && (isFirst | isLast)) + return; + + // Squeeze out deleted nodes between activePred and + // activeSucc, including x. + skipDeletedSuccessors(activePred); + skipDeletedPredecessors(activeSucc); + + // Try to gc-unlink, if possible + if ((isFirst | isLast) && + + // Recheck expected state of predecessor and successor + (activePred.next == activeSucc) && + (activeSucc.prev == activePred) && + (isFirst ? activePred.prev == null : activePred.item != null) && + (isLast ? activeSucc.next == null : activeSucc.item != null)) { + + updateHead(); // Ensure x is not reachable from head + updateTail(); // Ensure x is not reachable from tail + + // Finally, actually gc-unlink + x.lazySetPrev(isFirst ? prevTerminator() : x); + x.lazySetNext(isLast ? nextTerminator() : x); + } + } + } + + /** + * Unlinks non-null first node. + */ + private void unlinkFirst(Node<E> first, Node<E> next) { + // assert first != null; + // assert next != null; + // assert first.item == null; + for (Node<E> o = null, p = next, q;;) { + if (p.item != null || (q = p.next) == null) { + if (o != null && p.prev != p && first.casNext(next, p)) { + skipDeletedPredecessors(p); + if (first.prev == null && + (p.next == null || p.item != null) && + p.prev == first) { + + updateHead(); // Ensure o is not reachable from head + updateTail(); // Ensure o is not reachable from tail + + // Finally, actually gc-unlink + o.lazySetNext(o); + o.lazySetPrev(prevTerminator()); + } + } + return; + } + else if (p == q) + return; + else { + o = p; + p = q; + } + } + } + + /** + * Unlinks non-null last node. + */ + private void unlinkLast(Node<E> last, Node<E> prev) { + // assert last != null; + // assert prev != null; + // assert last.item == null; + for (Node<E> o = null, p = prev, q;;) { + if (p.item != null || (q = p.prev) == null) { + if (o != null && p.next != p && last.casPrev(prev, p)) { + skipDeletedSuccessors(p); + if (last.next == null && + (p.prev == null || p.item != null) && + p.next == last) { + + updateHead(); // Ensure o is not reachable from head + updateTail(); // Ensure o is not reachable from tail + + // Finally, actually gc-unlink + o.lazySetPrev(o); + o.lazySetNext(nextTerminator()); + } + } + return; + } + else if (p == q) + return; + else { + o = p; + p = q; + } + } + } + + /** + * Guarantees that any node which was unlinked before a call to + * this method will be unreachable from head after it returns. + * Does not guarantee to eliminate slack, only that head will + * point to a node that was active while this method was running. + */ + private final void updateHead() { + // Either head already points to an active node, or we keep + // trying to cas it to the first node until it does. + Node<E> h, p, q; + restartFromHead: + while ((h = head).item == null && (p = h.prev) != null) { + for (;;) { + if ((q = p.prev) == null || + (q = (p = q).prev) == null) { + // It is possible that p is PREV_TERMINATOR, + // but if so, the CAS is guaranteed to fail. + if (casHead(h, p)) + return; + else + continue restartFromHead; + } + else if (h != head) + continue restartFromHead; + else + p = q; + } + } + } + + /** + * Guarantees that any node which was unlinked before a call to + * this method will be unreachable from tail after it returns. + * Does not guarantee to eliminate slack, only that tail will + * point to a node that was active while this method was running. + */ + private final void updateTail() { + // Either tail already points to an active node, or we keep + // trying to cas it to the last node until it does. + Node<E> t, p, q; + restartFromTail: + while ((t = tail).item == null && (p = t.next) != null) { + for (;;) { + if ((q = p.next) == null || + (q = (p = q).next) == null) { + // It is possible that p is NEXT_TERMINATOR, + // but if so, the CAS is guaranteed to fail. + if (casTail(t, p)) + return; + else + continue restartFromTail; + } + else if (t != tail) + continue restartFromTail; + else + p = q; + } + } + } + + private void skipDeletedPredecessors(Node<E> x) { + whileActive: + do { + Node<E> prev = x.prev; + // assert prev != null; + // assert x != NEXT_TERMINATOR; + // assert x != PREV_TERMINATOR; + Node<E> p = prev; + findActive: + for (;;) { + if (p.item != null) + break findActive; + Node<E> q = p.prev; + if (q == null) { + if (p.next == p) + continue whileActive; + break findActive; + } + else if (p == q) + continue whileActive; + else + p = q; + } + + // found active CAS target + if (prev == p || x.casPrev(prev, p)) + return; + + } while (x.item != null || x.next == null); + } + + private void skipDeletedSuccessors(Node<E> x) { + whileActive: + do { + Node<E> next = x.next; + // assert next != null; + // assert x != NEXT_TERMINATOR; + // assert x != PREV_TERMINATOR; + Node<E> p = next; + findActive: + for (;;) { + if (p.item != null) + break findActive; + Node<E> q = p.next; + if (q == null) { + if (p.prev == p) + continue whileActive; + break findActive; + } + else if (p == q) + continue whileActive; + else + p = q; + } + + // found active CAS target + if (next == p || x.casNext(next, p)) + return; + + } while (x.item != null || x.prev == null); + } + + /** + * Returns the successor of p, or the first node if p.next has been + * linked to self, which will only be true if traversing with a + * stale pointer that is now off the list. + */ + final Node<E> succ(Node<E> p) { + // TODO: should we skip deleted nodes here? + Node<E> q = p.next; + return (p == q) ? first() : q; + } + + /** + * Returns the predecessor of p, or the last node if p.prev has been + * linked to self, which will only be true if traversing with a + * stale pointer that is now off the list. + */ + final Node<E> pred(Node<E> p) { + Node<E> q = p.prev; + return (p == q) ? last() : q; + } + + /** + * Returns the first node, the unique node p for which: + * p.prev == null && p.next != p + * The returned node may or may not be logically deleted. + * Guarantees that head is set to the returned node. + */ + Node<E> first() { + restartFromHead: + for (;;) + for (Node<E> h = head, p = h, q;;) { + if ((q = p.prev) != null && + (q = (p = q).prev) != null) + // Check for head updates every other hop. + // If p == q, we are sure to follow head instead. + p = (h != (h = head)) ? h : q; + else if (p == h + // It is possible that p is PREV_TERMINATOR, + // but if so, the CAS is guaranteed to fail. + || casHead(h, p)) + return p; + else + continue restartFromHead; + } + } + + /** + * Returns the last node, the unique node p for which: + * p.next == null && p.prev != p + * The returned node may or may not be logically deleted. + * Guarantees that tail is set to the returned node. + */ + Node<E> last() { + restartFromTail: + for (;;) + for (Node<E> t = tail, p = t, q;;) { + if ((q = p.next) != null && + (q = (p = q).next) != null) + // Check for tail updates every other hop. + // If p == q, we are sure to follow tail instead. + p = (t != (t = tail)) ? t : q; + else if (p == t + // It is possible that p is NEXT_TERMINATOR, + // but if so, the CAS is guaranteed to fail. + || casTail(t, p)) + return p; + else + continue restartFromTail; + } + } + + // Minor convenience utilities + + /** + * Throws NullPointerException if argument is null. + * + * @param v the element + */ + private static void checkNotNull(Object v) { + if (v == null) + throw new NullPointerException(); + } + + /** + * Returns element unless it is null, in which case throws + * NoSuchElementException. + * + * @param v the element + * @return the element + */ + private E screenNullResult(E v) { + if (v == null) + throw new NoSuchElementException(); + return v; + } + + /** + * Creates an array list and fills it with elements of this list. + * Used by toArray. + * + * @return the arrayList + */ + private ArrayList<E> toArrayList() { + ArrayList<E> list = new ArrayList<E>(); + for (Node<E> p = first(); p != null; p = succ(p)) { + E item = p.item; + if (item != null) + list.add(item); + } + return list; + } + + /** + * Constructs an empty deque. + */ + public ConcurrentLinkedDeque() { + head = tail = new Node<E>(null); + } + + /** + * Constructs a deque initially containing the elements of + * the given collection, added in traversal order of the + * collection's iterator. + * + * @param c the collection of elements to initially contain + * @throws NullPointerException if the specified collection or any + * of its elements are null + */ + public ConcurrentLinkedDeque(Collection<? extends E> c) { + // Copy c into a private chain of Nodes + Node<E> h = null, t = null; + for (E e : c) { + checkNotNull(e); + Node<E> newNode = new Node<E>(e); + if (h == null) + h = t = newNode; + else { + t.lazySetNext(newNode); + newNode.lazySetPrev(t); + t = newNode; + } + } + initHeadTail(h, t); + } + + /** + * Initializes head and tail, ensuring invariants hold. + */ + private void initHeadTail(Node<E> h, Node<E> t) { + if (h == t) { + if (h == null) + h = t = new Node<E>(null); + else { + // Avoid edge case of a single Node with non-null item. + Node<E> newNode = new Node<E>(null); + t.lazySetNext(newNode); + newNode.lazySetPrev(t); + t = newNode; + } + } + head = h; + tail = t; + } + + /** + * Inserts the specified element at the front of this deque. + * + * @throws NullPointerException {@inheritDoc} + */ + public void addFirst(E e) { + linkFirst(e); + } + + /** + * Inserts the specified element at the end of this deque. + * + * <p>This method is equivalent to {@link #add}. + * + * @throws NullPointerException {@inheritDoc} + */ + public void addLast(E e) { + linkLast(e); + } + + /** + * Inserts the specified element at the front of this deque. + * + * @return {@code true} always + * @throws NullPointerException {@inheritDoc} + */ + public boolean offerFirst(E e) { + linkFirst(e); + return true; + } + + /** + * Inserts the specified element at the end of this deque. + * + * <p>This method is equivalent to {@link #add}. + * + * @return {@code true} always + * @throws NullPointerException {@inheritDoc} + */ + public boolean offerLast(E e) { + linkLast(e); + return true; + } + + public E peekFirst() { + for (Node<E> p = first(); p != null; p = succ(p)) { + E item = p.item; + if (item != null) + return item; + } + return null; + } + + public E peekLast() { + for (Node<E> p = last(); p != null; p = pred(p)) { + E item = p.item; + if (item != null) + return item; + } + return null; + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public E getFirst() { + return screenNullResult(peekFirst()); + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public E getLast() { + return screenNullResult(peekLast()); + } + + public E pollFirst() { + for (Node<E> p = first(); p != null; p = succ(p)) { + E item = p.item; + if (item != null && p.casItem(item, null)) { + unlink(p); + return item; + } + } + return null; + } + + public E pollLast() { + for (Node<E> p = last(); p != null; p = pred(p)) { + E item = p.item; + if (item != null && p.casItem(item, null)) { + unlink(p); + return item; + } + } + return null; + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public E removeFirst() { + return screenNullResult(pollFirst()); + } + + /** + * @throws NoSuchElementException {@inheritDoc} + */ + public E removeLast() { + return screenNullResult(pollLast()); + } + + // *** Queue and stack methods *** + + /** + * Inserts the specified element at the tail of this deque. + * + * @return {@code true} (as specified by {@link Queue#offer}) + * @throws NullPointerException if the specified element is null + */ + public boolean offer(E e) { + return offerLast(e); + } + + /** + * Inserts the specified element at the tail of this deque. + * + * @return {@code true} (as specified by {@link Collection#add}) + * @throws NullPointerException if the specified element is null + */ + public boolean add(E e) { + return offerLast(e); + } + + public E poll() { return pollFirst(); } + public E remove() { return removeFirst(); } + public E peek() { return peekFirst(); } + public E element() { return getFirst(); } + public void push(E e) { addFirst(e); } + public E pop() { return removeFirst(); } + + /** + * Removes the first element {@code e} such that + * {@code o.equals(e)}, if such an element exists in this deque. + * If the deque does not contain the element, it is unchanged. + * + * @param o element to be removed from this deque, if present + * @return {@code true} if the deque contained the specified element + * @throws NullPointerException if the specified element is {@code null} + */ + public boolean removeFirstOccurrence(Object o) { + checkNotNull(o); + for (Node<E> p = first(); p != null; p = succ(p)) { + E item = p.item; + if (item != null && o.equals(item) && p.casItem(item, null)) { + unlink(p); + return true; + } + } + return false; + } + + /** + * Removes the last element {@code e} such that + * {@code o.equals(e)}, if such an element exists in this deque. + * If the deque does not contain the element, it is unchanged. + * + * @param o element to be removed from this deque, if present + * @return {@code true} if the deque contained the specified element + * @throws NullPointerException if the specified element is {@code null} + */ + public boolean removeLastOccurrence(Object o) { + checkNotNull(o); + for (Node<E> p = last(); p != null; p = pred(p)) { + E item = p.item; + if (item != null && o.equals(item) && p.casItem(item, null)) { + unlink(p); + return true; + } + } + return false; + } + + /** + * Returns {@code true} if this deque contains at least one + * element {@code e} such that {@code o.equals(e)}. + * + * @param o element whose presence in this deque is to be tested + * @return {@code true} if this deque contains the specified element + */ + public boolean contains(Object o) { + if (o == null) return false; + for (Node<E> p = first(); p != null; p = succ(p)) { + E item = p.item; + if (item != null && o.equals(item)) + return true; + } + return false; + } + + /** + * Returns {@code true} if this collection contains no elements. + * + * @return {@code true} if this collection contains no elements + */ + public boolean isEmpty() { + return peekFirst() == null; + } + + /** + * Returns the number of elements in this deque. If this deque + * contains more than {@code Integer.MAX_VALUE} elements, it + * returns {@code Integer.MAX_VALUE}. + * + * <p>Beware that, unlike in most collections, this method is + * <em>NOT</em> a constant-time operation. Because of the + * asynchronous nature of these deques, determining the current + * number of elements requires traversing them all to count them. + * Additionally, it is possible for the size to change during + * execution of this method, in which case the returned result + * will be inaccurate. Thus, this method is typically not very + * useful in concurrent applications. + * + * @return the number of elements in this deque + */ + public int size() { + int count = 0; + for (Node<E> p = first(); p != null; p = succ(p)) + if (p.item != null) + // Collection.size() spec says to max out + if (++count == Integer.MAX_VALUE) + break; + return count; + } + + /** + * Removes the first element {@code e} such that + * {@code o.equals(e)}, if such an element exists in this deque. + * If the deque does not contain the element, it is unchanged. + * + * @param o element to be removed from this deque, if present + * @return {@code true} if the deque contained the specified element + * @throws NullPointerException if the specified element is {@code null} + */ + public boolean remove(Object o) { + return removeFirstOccurrence(o); + } + + /** + * Appends all of the elements in the specified collection to the end of + * this deque, in the order that they are returned by the specified + * collection's iterator. Attempts to {@code addAll} of a deque to + * itself result in {@code IllegalArgumentException}. + * + * @param c the elements to be inserted into this deque + * @return {@code true} if this deque changed as a result of the call + * @throws NullPointerException if the specified collection or any + * of its elements are null + * @throws IllegalArgumentException if the collection is this deque + */ + public boolean addAll(Collection<? extends E> c) { + if (c == this) + // As historically specified in AbstractQueue#addAll + throw new IllegalArgumentException(); + + // Copy c into a private chain of Nodes + Node<E> beginningOfTheEnd = null, last = null; + for (E e : c) { + checkNotNull(e); + Node<E> newNode = new Node<E>(e); + if (beginningOfTheEnd == null) + beginningOfTheEnd = last = newNode; + else { + last.lazySetNext(newNode); + newNode.lazySetPrev(last); + last = newNode; + } + } + if (beginningOfTheEnd == null) + return false; + + // Atomically append the chain at the tail of this collection + restartFromTail: + for (;;) + for (Node<E> t = tail, p = t, q;;) { + if ((q = p.next) != null && + (q = (p = q).next) != null) + // Check for tail updates every other hop. + // If p == q, we are sure to follow tail instead. + p = (t != (t = tail)) ? t : q; + else if (p.prev == p) // NEXT_TERMINATOR + continue restartFromTail; + else { + // p is last node + beginningOfTheEnd.lazySetPrev(p); // CAS piggyback + if (p.casNext(null, beginningOfTheEnd)) { + // Successful CAS is the linearization point + // for all elements to be added to this queue. + if (!casTail(t, last)) { + // Try a little harder to update tail, + // since we may be adding many elements. + t = tail; + if (last.next == null) + casTail(t, last); + } + return true; + } + // Lost CAS race to another thread; re-read next + } + } + } + + /** + * Removes all of the elements from this deque. + */ + public void clear() { + while (pollFirst() != null) + ; + } + + /** + * Returns an array containing all of the elements in this deque, in + * proper sequence (from first to last element). + * + * <p>The returned array will be "safe" in that no references to it are + * maintained by this deque. (In other words, this method must allocate + * a new array). The caller is thus free to modify the returned array. + * + * <p>This method acts as bridge between array-based and collection-based + * APIs. + * + * @return an array containing all of the elements in this deque + */ + public Object[] toArray() { + return toArrayList().toArray(); + } + + /** + * Returns an array containing all of the elements in this deque, + * in proper sequence (from first to last element); the runtime + * type of the returned array is that of the specified array. If + * the deque fits in the specified array, it is returned therein. + * Otherwise, a new array is allocated with the runtime type of + * the specified array and the size of this deque. + * + * <p>If this deque fits in the specified array with room to spare + * (i.e., the array has more elements than this deque), the element in + * the array immediately following the end of the deque is set to + * {@code null}. + * + * <p>Like the {@link #toArray()} method, this method acts as + * bridge between array-based and collection-based APIs. Further, + * this method allows precise control over the runtime type of the + * output array, and may, under certain circumstances, be used to + * save allocation costs. + * + * <p>Suppose {@code x} is a deque known to contain only strings. + * The following code can be used to dump the deque into a newly + * allocated array of {@code String}: + * + * <pre> + * String[] y = x.toArray(new String[0]);</pre> + * + * Note that {@code toArray(new Object[0])} is identical in function to + * {@code toArray()}. + * + * @param a the array into which the elements of the deque are to + * be stored, if it is big enough; otherwise, a new array of the + * same runtime type is allocated for this purpose + * @return an array containing all of the elements in this deque + * @throws ArrayStoreException if the runtime type of the specified array + * is not a supertype of the runtime type of every element in + * this deque + * @throws NullPointerException if the specified array is null + */ + public <T> T[] toArray(T[] a) { + return toArrayList().toArray(a); + } + + /** + * Returns an iterator over the elements in this deque in proper sequence. + * The elements will be returned in order from first (head) to last (tail). + * + * <p>The returned {@code Iterator} is a "weakly consistent" iterator that + * will never throw {@link java.util.ConcurrentModificationException + * ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + * + * @return an iterator over the elements in this deque in proper sequence + */ + public Iterator<E> iterator() { + return new Itr(); + } + + /** + * Returns an iterator over the elements in this deque in reverse + * sequential order. The elements will be returned in order from + * last (tail) to first (head). + * + * <p>The returned {@code Iterator} is a "weakly consistent" iterator that + * will never throw {@link java.util.ConcurrentModificationException + * ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + * + * @return an iterator over the elements in this deque in reverse order + */ + public Iterator<E> descendingIterator() { + return new DescendingItr(); + } + + private abstract class AbstractItr implements Iterator<E> { + /** + * Next node to return item for. + */ + private Node<E> nextNode; + + /** + * nextItem holds on to item fields because once we claim + * that an element exists in hasNext(), we must return it in + * the following next() call even if it was in the process of + * being removed when hasNext() was called. + */ + private E nextItem; + + /** + * Node returned by most recent call to next. Needed by remove. + * Reset to null if this element is deleted by a call to remove. + */ + private Node<E> lastRet; + + abstract Node<E> startNode(); + abstract Node<E> nextNode(Node<E> p); + + AbstractItr() { + advance(); + } + + /** + * Sets nextNode and nextItem to next valid node, or to null + * if no such. + */ + private void advance() { + lastRet = nextNode; + + Node<E> p = (nextNode == null) ? startNode() : nextNode(nextNode); + for (;; p = nextNode(p)) { + if (p == null) { + // p might be active end or TERMINATOR node; both are OK + nextNode = null; + nextItem = null; + break; + } + E item = p.item; + if (item != null) { + nextNode = p; + nextItem = item; + break; + } + } + } + + public boolean hasNext() { + return nextItem != null; + } + + public E next() { + E item = nextItem; + if (item == null) throw new NoSuchElementException(); + advance(); + return item; + } + + public void remove() { + Node<E> l = lastRet; + if (l == null) throw new IllegalStateException(); + l.item = null; + unlink(l); + lastRet = null; + } + } + + /** Forward iterator */ + private class Itr extends AbstractItr { + Node<E> startNode() { return first(); } + Node<E> nextNode(Node<E> p) { return succ(p); } + } + + /** Descending iterator */ + private class DescendingItr extends AbstractItr { + Node<E> startNode() { return last(); } + Node<E> nextNode(Node<E> p) { return pred(p); } + } + + /** + * Saves the state to a stream (that is, serializes it). + * + * @serialData All of the elements (each an {@code E}) in + * the proper order, followed by a null + * @param s the stream + */ + private void writeObject(java.io.ObjectOutputStream s) + throws java.io.IOException { + + // Write out any hidden stuff + s.defaultWriteObject(); + + // Write out all elements in the proper order. + for (Node<E> p = first(); p != null; p = succ(p)) { + E item = p.item; + if (item != null) + s.writeObject(item); + } + + // Use trailing null as sentinel + s.writeObject(null); + } + + /** + * Reconstitutes the instance from a stream (that is, deserializes it). + * @param s the stream + */ + private void readObject(java.io.ObjectInputStream s) + throws java.io.IOException, ClassNotFoundException { + s.defaultReadObject(); + + // Read in elements until trailing null sentinel found + Node<E> h = null, t = null; + Object item; + while ((item = s.readObject()) != null) { + @SuppressWarnings("unchecked") + Node<E> newNode = new Node<E>((E) item); + if (h == null) + h = t = newNode; + else { + t.lazySetNext(newNode); + newNode.lazySetPrev(t); + t = newNode; + } + } + initHeadTail(h, t); + } + + // Unsafe mechanics + + private static final sun.misc.Unsafe UNSAFE = + sun.misc.Unsafe.getUnsafe(); + private static final long headOffset = + objectFieldOffset(UNSAFE, "head", ConcurrentLinkedDeque.class); + private static final long tailOffset = + objectFieldOffset(UNSAFE, "tail", ConcurrentLinkedDeque.class); + + private boolean casHead(Node<E> cmp, Node<E> val) { + return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val); + } + + private boolean casTail(Node<E> cmp, Node<E> val) { + return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val); + } + + static long objectFieldOffset(sun.misc.Unsafe UNSAFE, + String field, Class<?> klazz) { + try { + return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field)); + } catch (NoSuchFieldException e) { + // Convert Exception to corresponding Error + NoSuchFieldError error = new NoSuchFieldError(field); + error.initCause(e); + throw error; + } + } +}
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java Tue Oct 26 14:43:21 2010 -0400 @@ -28,9 +28,9 @@ * However, the following notice accompanied the original version of this * file: * - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain + * Written by Doug Lea and Martin Buchholz with assistance from members of + * JCP JSR-166 Expert Group and released to the public domain, as explained + * at http://creativecommons.org/licenses/publicdomain */ package java.util.concurrent; @@ -53,7 +53,8 @@ * operations obtain elements at the head of the queue. * A {@code ConcurrentLinkedQueue} is an appropriate choice when * many threads will share access to a common collection. - * This queue does not permit {@code null} elements. + * Like most other concurrent collection implementations, this class + * does not permit the use of {@code null} elements. * * <p>This implementation employs an efficient "wait-free" * algorithm based on one described in <a @@ -61,14 +62,20 @@ * Fast, and Practical Non-Blocking and Blocking Concurrent Queue * Algorithms</a> by Maged M. Michael and Michael L. Scott. * + * <p>Iterators are <i>weakly consistent</i>, returning elements + * reflecting the state of the queue at some point at or since the + * creation of the iterator. They do <em>not</em> throw {@link + * ConcurrentModificationException}, and may proceed concurrently with + * other operations. Elements contained in the queue since the creation + * of the iterator will be returned exactly once. + * * <p>Beware that, unlike in most collections, the {@code size} method * is <em>NOT</em> a constant-time operation. Because of the * asynchronous nature of these queues, determining the current number * of elements requires a traversal of the elements. * - * <p>This class and its iterator implement all of the - * <em>optional</em> methods of the {@link Collection} and {@link - * Iterator} interfaces. + * <p>This class and its iterator implement all of the <em>optional</em> + * methods of the {@link Queue} and {@link Iterator} interfaces. * * <p>Memory consistency effects: As with other concurrent * collections, actions in a thread prior to placing an object into a @@ -132,9 +139,10 @@ * * Both head and tail are permitted to lag. In fact, failing to * update them every time one could is a significant optimization - * (fewer CASes). This is controlled by local "hops" variables - * that only trigger helping-CASes after experiencing multiple - * lags. + * (fewer CASes). As with LinkedTransferQueue (see the internal + * documentation for that class), we use a slack threshold of two; + * that is, we update head/tail when the current pointer appears + * to be two or more steps away from the first/last node. * * Since head and tail are updated concurrently and independently, * it is possible for tail to lag behind head (why not)? @@ -148,8 +156,8 @@ * this is merely an optimization. * * When constructing a Node (before enqueuing it) we avoid paying - * for a volatile write to item by using lazySet instead of a - * normal write. This allows the cost of enqueue to be + * for a volatile write to item by using Unsafe.putObject instead + * of a normal write. This allows the cost of enqueue to be * "one-and-a-half" CASes. * * Both head and tail may or may not point to a Node with a @@ -161,38 +169,25 @@ */ private static class Node<E> { - private volatile E item; - private volatile Node<E> next; + volatile E item; + volatile Node<E> next; + /** + * Constructs a new node. Uses relaxed write because item can + * only be seen after publication via casNext. + */ Node(E item) { - // Piggyback on imminent casNext() - lazySetItem(item); - } - - E getItem() { - return item; + UNSAFE.putObject(this, itemOffset, item); } boolean casItem(E cmp, E val) { return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val); } - void setItem(E val) { - item = val; - } - - void lazySetItem(E val) { - UNSAFE.putOrderedObject(this, itemOffset, val); - } - void lazySetNext(Node<E> val) { UNSAFE.putOrderedObject(this, nextOffset, val); } - Node<E> getNext() { - return next; - } - boolean casNext(Node<E> cmp, Node<E> val) { return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val); } @@ -219,7 +214,7 @@ * - it is permitted for tail to lag behind head, that is, for tail * to not be reachable from head! */ - private transient volatile Node<E> head = new Node<E>(null); + private transient volatile Node<E> head; /** * A node from which the last node on list (that is, the unique @@ -233,25 +228,41 @@ * to not be reachable from head! * - tail.next may or may not be self-pointing to tail. */ - private transient volatile Node<E> tail = head; + private transient volatile Node<E> tail; /** * Creates a {@code ConcurrentLinkedQueue} that is initially empty. */ - public ConcurrentLinkedQueue() {} + public ConcurrentLinkedQueue() { + head = tail = new Node<E>(null); + } /** * Creates a {@code ConcurrentLinkedQueue} * initially containing the elements of the given collection, * added in traversal order of the collection's iterator. + * * @param c the collection of elements to initially contain * @throws NullPointerException if the specified collection or any * of its elements are null */ public ConcurrentLinkedQueue(Collection<? extends E> c) { - for (E e : c) - add(e); + Node<E> h = null, t = null; + for (E e : c) { + checkNotNull(e); + Node<E> newNode = new Node<E>(e); + if (h == null) + h = t = newNode; + else { + t.lazySetNext(newNode); + t = newNode; + } + } + if (h == null) + h = t = new Node<E>(null); + head = h; + tail = t; } // Have to override just to update the javadoc @@ -267,13 +278,6 @@ } /** - * We don't bother to update head or tail pointers if fewer than - * HOPS links from "true" location. We assume that volatile - * writes are significantly more expensive than volatile reads. - */ - private static final int HOPS = 1; - - /** * Try to CAS head to p. If successful, repoint old head to itself * as sentinel for succ(), below. */ @@ -288,7 +292,7 @@ * stale pointer that is now off the list. */ final Node<E> succ(Node<E> p) { - Node<E> next = p.getNext(); + Node<E> next = p.next; return (p == next) ? head : next; } @@ -299,68 +303,75 @@ * @throws NullPointerException if the specified element is null */ public boolean offer(E e) { - if (e == null) throw new NullPointerException(); - Node<E> n = new Node<E>(e); - retry: - for (;;) { - Node<E> t = tail; - Node<E> p = t; - for (int hops = 0; ; hops++) { - Node<E> next = succ(p); - if (next != null) { - if (hops > HOPS && t != tail) - continue retry; - p = next; - } else if (p.casNext(null, n)) { - if (hops >= HOPS) - casTail(t, n); // Failure is OK. + checkNotNull(e); + final Node<E> newNode = new Node<E>(e); + + for (Node<E> t = tail, p = t;;) { + Node<E> q = p.next; + if (q == null) { + // p is last node + if (p.casNext(null, newNode)) { + // Successful CAS is the linearization point + // for e to become an element of this queue, + // and for newNode to become "live". + if (p != t) // hop two nodes at a time + casTail(t, newNode); // Failure is OK. return true; - } else { - p = succ(p); } + // Lost CAS race to another thread; re-read next } + else if (p == q) + // We have fallen off list. If tail is unchanged, it + // will also be off-list, in which case we need to + // jump to head, from which all live nodes are always + // reachable. Else the new tail is a better bet. + p = (t != (t = tail)) ? t : head; + else + // Check for tail updates after two hops. + p = (p != t && t != (t = tail)) ? t : q; } } public E poll() { - Node<E> h = head; - Node<E> p = h; - for (int hops = 0; ; hops++) { - E item = p.getItem(); + restartFromHead: + for (;;) { + for (Node<E> h = head, p = h, q;;) { + E item = p.item; - if (item != null && p.casItem(item, null)) { - if (hops >= HOPS) { - Node<E> q = p.getNext(); - updateHead(h, (q != null) ? q : p); + if (item != null && p.casItem(item, null)) { + // Successful CAS is the linearization point + // for item to be removed from this queue. + if (p != h) // hop two nodes at a time + updateHead(h, ((q = p.next) != null) ? q : p); + return item; } - return item; + else if ((q = p.next) == null) { + updateHead(h, p); + return null; + } + else if (p == q) + continue restartFromHead; + else + p = q; } - Node<E> next = succ(p); - if (next == null) { - updateHead(h, p); - break; - } - p = next; } - return null; } public E peek() { - Node<E> h = head; - Node<E> p = h; - E item; + restartFromHead: for (;;) { - item = p.getItem(); - if (item != null) - break; - Node<E> next = succ(p); - if (next == null) { - break; + for (Node<E> h = head, p = h, q;;) { + E item = p.item; + if (item != null || (q = p.next) == null) { + updateHead(h, p); + return item; + } + else if (p == q) + continue restartFromHead; + else + p = q; } - p = next; } - updateHead(h, p); - return item; } /** @@ -372,24 +383,20 @@ * of losing a race to a concurrent poll(). */ Node<E> first() { - Node<E> h = head; - Node<E> p = h; - Node<E> result; + restartFromHead: for (;;) { - E item = p.getItem(); - if (item != null) { - result = p; - break; + for (Node<E> h = head, p = h, q;;) { + boolean hasItem = (p.item != null); + if (hasItem || (q = p.next) == null) { + updateHead(h, p); + return hasItem ? p : null; + } + else if (p == q) + continue restartFromHead; + else + p = q; } - Node<E> next = succ(p); - if (next == null) { - result = null; - break; - } - p = next; } - updateHead(h, p); - return result; } /** @@ -410,18 +417,20 @@ * <em>NOT</em> a constant-time operation. Because of the * asynchronous nature of these queues, determining the current * number of elements requires an O(n) traversal. + * Additionally, if elements are added or removed during execution + * of this method, the returned result may be inaccurate. Thus, + * this method is typically not very useful in concurrent + * applications. * * @return the number of elements in this queue */ public int size() { int count = 0; - for (Node<E> p = first(); p != null; p = succ(p)) { - if (p.getItem() != null) { - // Collections.size() spec says to max out + for (Node<E> p = first(); p != null; p = succ(p)) + if (p.item != null) + // Collection.size() spec says to max out if (++count == Integer.MAX_VALUE) break; - } - } return count; } @@ -436,9 +445,8 @@ public boolean contains(Object o) { if (o == null) return false; for (Node<E> p = first(); p != null; p = succ(p)) { - E item = p.getItem(); - if (item != null && - o.equals(item)) + E item = p.item; + if (item != null && o.equals(item)) return true; } return false; @@ -459,7 +467,7 @@ if (o == null) return false; Node<E> pred = null; for (Node<E> p = first(); p != null; p = succ(p)) { - E item = p.getItem(); + E item = p.item; if (item != null && o.equals(item) && p.casItem(item, null)) { @@ -474,6 +482,69 @@ } /** + * Appends all of the elements in the specified collection to the end of + * this queue, in the order that they are returned by the specified + * collection's iterator. Attempts to {@code addAll} of a queue to + * itself result in {@code IllegalArgumentException}. + * + * @param c the elements to be inserted into this queue + * @return {@code true} if this queue changed as a result of the call + * @throws NullPointerException if the specified collection or any + * of its elements are null + * @throws IllegalArgumentException if the collection is this queue + */ + public boolean addAll(Collection<? extends E> c) { + if (c == this) + // As historically specified in AbstractQueue#addAll + throw new IllegalArgumentException(); + + // Copy c into a private chain of Nodes + Node<E> beginningOfTheEnd = null, last = null; + for (E e : c) { + checkNotNull(e); + Node<E> newNode = new Node<E>(e); + if (beginningOfTheEnd == null) + beginningOfTheEnd = last = newNode; + else { + last.lazySetNext(newNode); + last = newNode; + } + } + if (beginningOfTheEnd == null) + return false; + + // Atomically append the chain at the tail of this collection + for (Node<E> t = tail, p = t;;) { + Node<E> q = p.next; + if (q == null) { + // p is last node + if (p.casNext(null, beginningOfTheEnd)) { + // Successful CAS is the linearization point + // for all elements to be added to this queue. + if (!casTail(t, last)) { + // Try a little harder to update tail, + // since we may be adding many elements. + t = tail; + if (last.next == null) + casTail(t, last); + } + return true; + } + // Lost CAS race to another thread; re-read next + } + else if (p == q) + // We have fallen off list. If tail is unchanged, it + // will also be off-list, in which case we need to + // jump to head, from which all live nodes are always + // reachable. Else the new tail is a better bet. + p = (t != (t = tail)) ? t : head; + else + // Check for tail updates after two hops. + p = (p != t && t != (t = tail)) ? t : q; + } + } + + /** * Returns an array containing all of the elements in this queue, in * proper sequence. * @@ -490,7 +561,7 @@ // Use ArrayList to deal with resizing. ArrayList<E> al = new ArrayList<E>(); for (Node<E> p = first(); p != null; p = succ(p)) { - E item = p.getItem(); + E item = p.item; if (item != null) al.add(item); } @@ -539,7 +610,7 @@ int k = 0; Node<E> p; for (p = first(); p != null && k < a.length; p = succ(p)) { - E item = p.getItem(); + E item = p.item; if (item != null) a[k++] = (T)item; } @@ -552,7 +623,7 @@ // If won't fit, use ArrayList version ArrayList<E> al = new ArrayList<E>(); for (Node<E> q = first(); q != null; q = succ(q)) { - E item = q.getItem(); + E item = q.item; if (item != null) al.add(item); } @@ -561,7 +632,9 @@ /** * Returns an iterator over the elements in this queue in proper sequence. - * The returned iterator is a "weakly consistent" iterator that + * The elements will be returned in order from first (head) to last (tail). + * + * <p>The returned {@code Iterator} is a "weakly consistent" iterator that * will never throw {@link java.util.ConcurrentModificationException * ConcurrentModificationException}, * and guarantees to traverse elements as they existed upon @@ -620,7 +693,7 @@ nextItem = null; return x; } - E item = p.getItem(); + E item = p.item; if (item != null) { nextNode = p; nextItem = item; @@ -648,13 +721,13 @@ Node<E> l = lastRet; if (l == null) throw new IllegalStateException(); // rely on a future traversal to relink. - l.setItem(null); + l.item = null; lastRet = null; } } /** - * Save the state to a stream (that is, serialize it). + * Saves the state to a stream (that is, serializes it). * * @serialData All of the elements (each an {@code E}) in * the proper order, followed by a null @@ -668,7 +741,7 @@ // Write out all elements in the proper order. for (Node<E> p = first(); p != null; p = succ(p)) { - Object item = p.getItem(); + Object item = p.item; if (item != null) s.writeObject(item); } @@ -678,25 +751,40 @@ } /** - * Reconstitute the Queue instance from a stream (that is, - * deserialize it). + * Reconstitutes the instance from a stream (that is, deserializes it). * @param s the stream */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { - // Read in capacity, and any hidden stuff s.defaultReadObject(); - head = new Node<E>(null); - tail = head; - // Read in all elements and place in queue - for (;;) { + + // Read in elements until trailing null sentinel found + Node<E> h = null, t = null; + Object item; + while ((item = s.readObject()) != null) { @SuppressWarnings("unchecked") - E item = (E)s.readObject(); - if (item == null) - break; - else - offer(item); + Node<E> newNode = new Node<E>((E) item); + if (h == null) + h = t = newNode; + else { + t.lazySetNext(newNode); + t = newNode; + } } + if (h == null) + h = t = new Node<E>(null); + head = h; + tail = t; + } + + /** + * Throws NullPointerException if argument is null. + * + * @param v the element + */ + private static void checkNotNull(Object v) { + if (v == null) + throw new NullPointerException(); } // Unsafe mechanics @@ -715,10 +803,6 @@ return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val); } - private void lazySetHead(Node<E> val) { - UNSAFE.putOrderedObject(this, headOffset, val); - } - static long objectFieldOffset(sun.misc.Unsafe UNSAFE, String field, Class<?> klazz) { try {
--- a/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java Tue Oct 26 14:43:21 2010 -0400 @@ -42,7 +42,6 @@ import java.util.List; import java.util.concurrent.AbstractExecutorService; import java.util.concurrent.Callable; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.RejectedExecutionException; @@ -823,15 +822,13 @@ (workerCounts & RUNNING_COUNT_MASK) <= 1); long startTime = untimed? 0 : System.nanoTime(); Thread.interrupted(); // clear/ignore interrupt - if (eventCount != ec || w.runState != 0 || - runState >= TERMINATING) // recheck after clear - break; + if (eventCount != ec || w.isTerminating()) + break; // recheck after clear if (untimed) LockSupport.park(w); else { LockSupport.parkNanos(w, SHRINK_RATE_NANOS); - if (eventCount != ec || w.runState != 0 || - runState >= TERMINATING) + if (eventCount != ec || w.isTerminating()) break; if (System.nanoTime() - startTime >= SHRINK_RATE_NANOS) tryShutdownUnusedWorker(ec); @@ -899,16 +896,23 @@ UNSAFE.compareAndSwapInt(this, workerCountsOffset, wc, wc + (ONE_RUNNING|ONE_TOTAL))) { ForkJoinWorkerThread w = null; + Throwable fail = null; try { w = factory.newThread(this); - } finally { // adjust on null or exceptional factory return - if (w == null) { - decrementWorkerCounts(ONE_RUNNING, ONE_TOTAL); - tryTerminate(false); // handle failure during shutdown - } + } catch (Throwable ex) { + fail = ex; } - if (w == null) + if (w == null) { // null or exceptional factory return + decrementWorkerCounts(ONE_RUNNING, ONE_TOTAL); + tryTerminate(false); // handle failure during shutdown + // If originating from an external caller, + // propagate exception, else ignore + if (fail != null && runState < TERMINATING && + !(Thread.currentThread() instanceof + ForkJoinWorkerThread)) + UNSAFE.throwException(fail); break; + } w.start(recordWorker(w), ueh); if ((workerCounts >>> TOTAL_COUNT_SHIFT) >= pc) { int c; // advance event count @@ -997,8 +1001,12 @@ boolean active = w.active; boolean inactivate = false; int pc = parallelism; - int rs; - while (w.runState == 0 && (rs = runState) < TERMINATING) { + while (w.runState == 0) { + int rs = runState; + if (rs >= TERMINATING) { // propagate shutdown + w.shutdown(); + break; + } if ((inactivate || (active && (rs & ACTIVE_COUNT_MASK) >= pc)) && UNSAFE.compareAndSwapInt(this, runStateOffset, rs, rs - 1)) inactivate = active = w.active = false; @@ -1126,6 +1134,7 @@ return true; } + /** * Actions on transition to TERMINATING * @@ -1149,7 +1158,7 @@ if (passes > 0 && !w.isTerminated()) { w.cancelTasks(); LockSupport.unpark(w); - if (passes > 1) { + if (passes > 1 && !w.isInterrupted()) { try { w.interrupt(); } catch (SecurityException ignore) { @@ -1726,6 +1735,13 @@ } /** + * Returns true if terminating or terminated. Used by ForkJoinWorkerThread. + */ + final boolean isAtLeastTerminating() { + return runState >= TERMINATING; + } + + /** * Returns {@code true} if this pool has been shut down. * * @return {@code true} if this pool has been shut down
--- a/jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java Tue Oct 26 14:43:21 2010 -0400 @@ -55,10 +55,10 @@ * start other subtasks. As indicated by the name of this class, * many programs using {@code ForkJoinTask} employ only methods * {@link #fork} and {@link #join}, or derivatives such as {@link - * #invokeAll}. However, this class also provides a number of other - * methods that can come into play in advanced usages, as well as - * extension mechanics that allow support of new forms of fork/join - * processing. + * #invokeAll(ForkJoinTask...) invokeAll}. However, this class also + * provides a number of other methods that can come into play in + * advanced usages, as well as extension mechanics that allow + * support of new forms of fork/join processing. * * <p>A {@code ForkJoinTask} is a lightweight form of {@link Future}. * The efficiency of {@code ForkJoinTask}s stems from a set of @@ -250,7 +250,7 @@ int s; // the odd construction reduces lock bias effects while ((s = status) >= 0) { try { - synchronized(this) { + synchronized (this) { if (UNSAFE.compareAndSwapInt(this, statusOffset, s,SIGNAL)) wait(); } @@ -270,7 +270,7 @@ int s; if ((s = status) >= 0) { try { - synchronized(this) { + synchronized (this) { if (UNSAFE.compareAndSwapInt(this, statusOffset, s,SIGNAL)) wait(millis, 0); } @@ -288,7 +288,7 @@ private void externalAwaitDone() { int s; while ((s = status) >= 0) { - synchronized(this) { + synchronized (this) { if (UNSAFE.compareAndSwapInt(this, statusOffset, s, SIGNAL)){ boolean interrupted = false; while (status >= 0) { @@ -669,11 +669,34 @@ setCompletion(NORMAL); } + /** + * Waits if necessary for the computation to complete, and then + * retrieves its result. + * + * @return the computed result + * @throws CancellationException if the computation was cancelled + * @throws ExecutionException if the computation threw an + * exception + * @throws InterruptedException if the current thread is not a + * member of a ForkJoinPool and was interrupted while waiting + */ public final V get() throws InterruptedException, ExecutionException { - quietlyJoin(); - if (Thread.interrupted()) - throw new InterruptedException(); - int s = status; + int s; + if (Thread.currentThread() instanceof ForkJoinWorkerThread) { + quietlyJoin(); + s = status; + } + else { + while ((s = status) >= 0) { + synchronized (this) { // interruptible form of awaitDone + if (UNSAFE.compareAndSwapInt(this, statusOffset, + s, SIGNAL)) { + while (status >= 0) + wait(); + } + } + } + } if (s < NORMAL) { Throwable ex; if (s == CANCELLED) @@ -684,6 +707,20 @@ return getRawResult(); } + /** + * Waits if necessary for at most the given time for the computation + * to complete, and then retrieves its result, if available. + * + * @param timeout the maximum time to wait + * @param unit the time unit of the timeout argument + * @return the computed result + * @throws CancellationException if the computation was cancelled + * @throws ExecutionException if the computation threw an + * exception + * @throws InterruptedException if the current thread is not a + * member of a ForkJoinPool and was interrupted while waiting + * @throws TimeoutException if the wait timed out + */ public final V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { Thread t = Thread.currentThread(); @@ -725,7 +762,7 @@ long ms = nt / 1000000; int ns = (int) (nt % 1000000); try { - synchronized(this) { + synchronized (this) { if (status >= 0) wait(ms, ns); }
--- a/jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java Tue Oct 26 14:43:21 2010 -0400 @@ -778,11 +778,20 @@ // status check methods used mainly by ForkJoinPool final boolean isRunning() { return runState == 0; } - final boolean isTerminating() { return (runState & TERMINATING) != 0; } final boolean isTerminated() { return (runState & TERMINATED) != 0; } final boolean isSuspended() { return (runState & SUSPENDED) != 0; } final boolean isTrimmed() { return (runState & TRIMMED) != 0; } + final boolean isTerminating() { + if ((runState & TERMINATING) != 0) + return true; + if (pool.isAtLeastTerminating()) { // propagate pool state + shutdown(); + return true; + } + return false; + } + /** * Sets state to TERMINATING. Does NOT unpark or interrupt * to wake up if currently blocked. Callers must do so if desired.
--- a/jdk/src/share/classes/java/util/concurrent/RecursiveAction.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/util/concurrent/RecursiveAction.java Tue Oct 26 14:43:21 2010 -0400 @@ -138,7 +138,7 @@ * if (right.tryUnfork()) // directly calculate if not stolen * sum += right.atLeaf(right.lo, right.hi); * else { - * right.helpJoin(); + * right.join(); * sum += right.result; * } * right = right.next;
--- a/jdk/src/share/classes/java/util/logging/LogManager.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/util/logging/LogManager.java Tue Oct 26 14:43:21 2010 -0400 @@ -690,6 +690,11 @@ * Note that since untrusted code may create loggers with * arbitrary names this method should not be relied on to * find Loggers for security sensitive logging. + * It is also important to note that the Logger associated with the + * String {@code name} may be garbage collected at any time if there + * is no strong reference to the Logger. The caller of this method + * must check the return value for null in order to properly handle + * the case where the Logger has been garbage collected. * <p> * @param name name of the logger * @return matching logger or null if none is found @@ -713,6 +718,14 @@ * <p> * Note: Loggers may be added dynamically as new classes are loaded. * This method only reports on the loggers that are currently registered. + * It is also important to note that this method only returns the name + * of a Logger, not a strong reference to the Logger itself. + * The returned String does nothing to prevent the Logger from being + * garbage collected. In particular, if the returned name is passed + * to {@code LogManager.getLogger()}, then the caller must check the + * return value from {@code LogManager.getLogger()} for null to properly + * handle the case where the Logger has been garbage collected in the + * time since its name was returned by this method. * <p> * @return enumeration of logger name strings */
--- a/jdk/src/share/classes/java/util/logging/Logger.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/java/util/logging/Logger.java Tue Oct 26 14:43:21 2010 -0400 @@ -42,7 +42,10 @@ * <p> * Logger objects may be obtained by calls on one of the getLogger * factory methods. These will either create a new Logger or - * return a suitable existing Logger. + * return a suitable existing Logger. It is important to note that + * the Logger returned by one of the {@code getLogger} factory methods + * may be garbage collected at any time if a strong reference to the + * Logger is not kept. * <p> * Logging messages will be forwarded to registered Handler * objects, which can forward the messages to a variety of @@ -210,7 +213,9 @@ * who are making serious use of the logging package (for example * in products) should create and use their own Logger objects, * with appropriate names, so that logging can be controlled on a - * suitable per-Logger granularity. + * suitable per-Logger granularity. Developers also need to keep a + * strong reference to their Logger objects to prevent them from + * being garbage collected. * <p> * @deprecated Initialization of this field is prone to deadlocks. * The field must be initialized by the Logger class initialization @@ -287,6 +292,15 @@ * based on the LogManager configuration and it will configured * to also send logging output to its parent's Handlers. It will * be registered in the LogManager global namespace. + * <p> + * Note: The LogManager may only retain a weak reference to the newly + * created Logger. It is important to understand that a previously + * created Logger with the given name may be garbage collected at any + * time if there is no strong reference to the Logger. In particular, + * this means that two back-to-back calls like + * {@code getLogger("MyLogger").log(...)} may use different Logger + * objects named "MyLogger" if there is no strong reference to the + * Logger named "MyLogger" elsewhere in the program. * * @param name A name for the logger. This should * be a dot-separated name and should normally @@ -311,6 +325,15 @@ * output to its parent's Handlers. It will be registered in * the LogManager global namespace. * <p> + * Note: The LogManager may only retain a weak reference to the newly + * created Logger. It is important to understand that a previously + * created Logger with the given name may be garbage collected at any + * time if there is no strong reference to the Logger. In particular, + * this means that two back-to-back calls like + * {@code getLogger("MyLogger", ...).log(...)} may use different Logger + * objects named "MyLogger" if there is no strong reference to the + * Logger named "MyLogger" elsewhere in the program. + * <p> * If the named Logger already exists and does not yet have a * localization resource bundle then the given resource bundle * name is used. If the named Logger already exists and has
--- a/jdk/src/share/classes/javax/sql/rowset/BaseRowSet.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/javax/sql/rowset/BaseRowSet.java Tue Oct 26 14:43:21 2010 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -734,7 +734,7 @@ throw new SQLException("Set initParams() before setCommand"); } params.clear(); - command = new String(cmd); + command = cmd; } } @@ -797,7 +797,7 @@ throw new SQLException("Invalid url string detected. " + "Cannot be of length less than 1"); } else { - URL = new String(url); + URL = url; } dataSource = null; @@ -854,7 +854,7 @@ } else if (name.equals("")) { throw new SQLException("DataSource name cannot be empty string"); } else { - dataSource = new String(name); + dataSource = name; } URL = null; @@ -889,7 +889,7 @@ { username = null; } else { - username = new String(name); + username = name; } } @@ -924,7 +924,7 @@ { password = null; } else { - password = new String(pass); + password = pass; } } @@ -1563,13 +1563,13 @@ nullVal = new Object[2]; nullVal[0] = null; - nullVal[1] = new Integer(sqlType); + nullVal[1] = Integer.valueOf(sqlType); if (params == null){ throw new SQLException("Set initParams() before setNull"); } - params.put(new Integer(parameterIndex - 1), nullVal); + params.put(Integer.valueOf(parameterIndex - 1), nullVal); } /** @@ -1644,14 +1644,14 @@ nullVal = new Object[3]; nullVal[0] = null; - nullVal[1] = new Integer(sqlType); - nullVal[2] = new String(typeName); + nullVal[1] = Integer.valueOf(sqlType); + nullVal[2] = typeName; if(params == null){ throw new SQLException("Set initParams() before setNull"); } - params.put(new Integer(parameterIndex - 1), nullVal); + params.put(Integer.valueOf(parameterIndex - 1), nullVal); } @@ -1686,7 +1686,7 @@ throw new SQLException("Set initParams() before setNull"); } - params.put(new Integer(parameterIndex - 1), new Boolean(x)); + params.put(Integer.valueOf(parameterIndex - 1), Boolean.valueOf(x)); } /** @@ -1720,7 +1720,7 @@ throw new SQLException("Set initParams() before setByte"); } - params.put(new Integer(parameterIndex - 1), new Byte(x)); + params.put(Integer.valueOf(parameterIndex - 1), Byte.valueOf(x)); } /** @@ -1754,7 +1754,7 @@ throw new SQLException("Set initParams() before setShort"); } - params.put(new Integer(parameterIndex - 1), new Short(x)); + params.put(Integer.valueOf(parameterIndex - 1), Short.valueOf(x)); } /** @@ -1786,7 +1786,7 @@ if(params == null){ throw new SQLException("Set initParams() before setInt"); } - params.put(new Integer(parameterIndex - 1), new Integer(x)); + params.put(Integer.valueOf(parameterIndex - 1), Integer.valueOf(x)); } /** @@ -1818,7 +1818,7 @@ if(params == null){ throw new SQLException("Set initParams() before setLong"); } - params.put(new Integer(parameterIndex - 1), new Long(x)); + params.put(Integer.valueOf(parameterIndex - 1), Long.valueOf(x)); } /** @@ -1850,7 +1850,7 @@ if(params == null){ throw new SQLException("Set initParams() before setFloat"); } - params.put(new Integer(parameterIndex - 1), new Float(x)); + params.put(Integer.valueOf(parameterIndex - 1), new Float(x)); } /** @@ -1882,7 +1882,7 @@ if(params == null){ throw new SQLException("Set initParams() before setDouble"); } - params.put(new Integer(parameterIndex - 1), new Double(x)); + params.put(Integer.valueOf(parameterIndex - 1), new Double(x)); } /** @@ -1914,7 +1914,7 @@ if(params == null){ throw new SQLException("Set initParams() before setBigDecimal"); } - params.put(new Integer(parameterIndex - 1), x); + params.put(Integer.valueOf(parameterIndex - 1), x); } /** @@ -1948,7 +1948,7 @@ if(params == null){ throw new SQLException("Set initParams() before setString"); } - params.put(new Integer(parameterIndex - 1), x); + params.put(Integer.valueOf(parameterIndex - 1), x); } /** @@ -1982,7 +1982,7 @@ if(params == null){ throw new SQLException("Set initParams() before setBytes"); } - params.put(new Integer(parameterIndex - 1), x); + params.put(Integer.valueOf(parameterIndex - 1), x); } /** @@ -2024,7 +2024,7 @@ if(params == null){ throw new SQLException("Set initParams() before setDate"); } - params.put(new Integer(parameterIndex - 1), x); + params.put(Integer.valueOf(parameterIndex - 1), x); } /** @@ -2069,7 +2069,7 @@ throw new SQLException("Set initParams() before setTime"); } - params.put(new Integer(parameterIndex - 1), x); + params.put(Integer.valueOf(parameterIndex - 1), x); } /** @@ -2112,7 +2112,7 @@ throw new SQLException("Set initParams() before setTimestamp"); } - params.put(new Integer(parameterIndex - 1), x); + params.put(Integer.valueOf(parameterIndex - 1), x); } /** @@ -2185,14 +2185,14 @@ asciiStream = new Object[3]; asciiStream[0] = x; - asciiStream[1] = new Integer(length); - asciiStream[2] = new Integer(ASCII_STREAM_PARAM); + asciiStream[1] = Integer.valueOf(length); + asciiStream[2] = Integer.valueOf(ASCII_STREAM_PARAM); if(params == null){ throw new SQLException("Set initParams() before setAsciiStream"); } - params.put(new Integer(parameterIndex - 1), asciiStream); + params.put(Integer.valueOf(parameterIndex - 1), asciiStream); } /** @@ -2290,13 +2290,13 @@ binaryStream = new Object[3]; binaryStream[0] = x; - binaryStream[1] = new Integer(length); - binaryStream[2] = new Integer(BINARY_STREAM_PARAM); + binaryStream[1] = Integer.valueOf(length); + binaryStream[2] = Integer.valueOf(BINARY_STREAM_PARAM); if(params == null){ throw new SQLException("Set initParams() before setBinaryStream"); } - params.put(new Integer(parameterIndex - 1), binaryStream); + params.put(Integer.valueOf(parameterIndex - 1), binaryStream); } @@ -2396,12 +2396,12 @@ unicodeStream = new Object[3]; unicodeStream[0] = x; - unicodeStream[1] = new Integer(length); - unicodeStream[2] = new Integer(UNICODE_STREAM_PARAM); + unicodeStream[1] = Integer.valueOf(length); + unicodeStream[2] = Integer.valueOf(UNICODE_STREAM_PARAM); if(params == null){ throw new SQLException("Set initParams() before setUnicodeStream"); } - params.put(new Integer(parameterIndex - 1), unicodeStream); + params.put(Integer.valueOf(parameterIndex - 1), unicodeStream); } /** @@ -2475,11 +2475,11 @@ charStream = new Object[2]; charStream[0] = reader; - charStream[1] = new Integer(length); + charStream[1] = Integer.valueOf(length); if(params == null){ throw new SQLException("Set initParams() before setCharacterStream"); } - params.put(new Integer(parameterIndex - 1), charStream); + params.put(Integer.valueOf(parameterIndex - 1), charStream); } /** @@ -2591,12 +2591,12 @@ obj = new Object[3]; obj[0] = x; - obj[1] = new Integer(targetSqlType); - obj[2] = new Integer(scale); + obj[1] = Integer.valueOf(targetSqlType); + obj[2] = Integer.valueOf(scale); if(params == null){ throw new SQLException("Set initParams() before setObject"); } - params.put(new Integer(parameterIndex - 1), obj); + params.put(Integer.valueOf(parameterIndex - 1), obj); } /** @@ -2654,11 +2654,11 @@ obj = new Object[2]; obj[0] = x; - obj[1] = new Integer(targetSqlType); + obj[1] = Integer.valueOf(targetSqlType); if (params == null){ throw new SQLException("Set initParams() before setObject"); } - params.put(new Integer(parameterIndex - 1), obj); + params.put(Integer.valueOf(parameterIndex - 1), obj); } /** @@ -2726,7 +2726,7 @@ if (params == null) { throw new SQLException("Set initParams() before setObject"); } - params.put(new Integer(parameterIndex - 1), x); + params.put(Integer.valueOf(parameterIndex - 1), x); } /** @@ -2773,7 +2773,7 @@ if (params == null) { throw new SQLException("Set initParams() before setRef"); } - params.put(new Integer(parameterIndex - 1), new SerialRef(ref)); + params.put(Integer.valueOf(parameterIndex - 1), new SerialRef(ref)); } /** @@ -2817,7 +2817,7 @@ if(params == null){ throw new SQLException("Set initParams() before setBlob"); } - params.put(new Integer(parameterIndex - 1), new SerialBlob(x)); + params.put(Integer.valueOf(parameterIndex - 1), new SerialBlob(x)); } /** @@ -2862,7 +2862,7 @@ if(params == null){ throw new SQLException("Set initParams() before setClob"); } - params.put(new Integer(parameterIndex - 1), new SerialClob(x)); + params.put(Integer.valueOf(parameterIndex - 1), new SerialClob(x)); } /** @@ -2910,7 +2910,7 @@ if (params == null){ throw new SQLException("Set initParams() before setArray"); } - params.put(new Integer(parameterIndex - 1), new SerialArray(array)); + params.put(Integer.valueOf(parameterIndex - 1), new SerialArray(array)); } /** @@ -2975,7 +2975,7 @@ if(params == null){ throw new SQLException("Set initParams() before setDate"); } - params.put(new Integer(parameterIndex - 1), date); + params.put(Integer.valueOf(parameterIndex - 1), date); } /** @@ -3041,7 +3041,7 @@ if(params == null){ throw new SQLException("Set initParams() before setTime"); } - params.put(new Integer(parameterIndex - 1), time); + params.put(Integer.valueOf(parameterIndex - 1), time); } /** @@ -3107,7 +3107,7 @@ if(params == null){ throw new SQLException("Set initParams() before setTimestamp"); } - params.put(new Integer(parameterIndex - 1), timestamp); + params.put(Integer.valueOf(parameterIndex - 1), timestamp); } /** @@ -3181,7 +3181,7 @@ Object[] paramsArray = new Object[params.size()]; for (int i = 0; i < params.size(); i++) { - paramsArray[i] = params.get(new Integer(i)); + paramsArray[i] = params.get(Integer.valueOf(i)); if (paramsArray[i] == null) { throw new SQLException("missing parameter: " + (i + 1)); } //end if
--- a/jdk/src/share/classes/javax/sql/rowset/CachedRowSet.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/javax/sql/rowset/CachedRowSet.java Tue Oct 26 14:43:21 2010 -0400 @@ -39,7 +39,7 @@ * <code>CachedRowSet</code> must implement. * <P> * The reference implementation of the <code>CachedRowSet</code> interface provided - * by Sun Microsystems is a standard implementation. Developers may use this implementation + * by Oracle Corporation is a standard implementation. Developers may use this implementation * just as it is, they may extend it, or they may choose to write their own implementations * of this interface. * <P> @@ -1623,4 +1623,3 @@ public boolean previousPage() throws SQLException; } -
--- a/jdk/src/share/classes/javax/sql/rowset/RowSetMetaDataImpl.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/javax/sql/rowset/RowSetMetaDataImpl.java Tue Oct 26 14:43:21 2010 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -306,9 +306,9 @@ public void setColumnLabel(int columnIndex, String label) throws SQLException { checkColRange(columnIndex); if (label != null) { - colInfo[columnIndex].columnLabel = new String(label); + colInfo[columnIndex].columnLabel = label; } else { - colInfo[columnIndex].columnLabel = new String(""); + colInfo[columnIndex].columnLabel = ""; } } @@ -326,9 +326,9 @@ public void setColumnName(int columnIndex, String columnName) throws SQLException { checkColRange(columnIndex); if (columnName != null) { - colInfo[columnIndex].columnName = new String(columnName); + colInfo[columnIndex].columnName = columnName; } else { - colInfo[columnIndex].columnName = new String(""); + colInfo[columnIndex].columnName = ""; } } @@ -348,9 +348,9 @@ public void setSchemaName(int columnIndex, String schemaName) throws SQLException { checkColRange(columnIndex); if (schemaName != null ) { - colInfo[columnIndex].schemaName = new String(schemaName); + colInfo[columnIndex].schemaName = schemaName; } else { - colInfo[columnIndex].schemaName = new String(""); + colInfo[columnIndex].schemaName = ""; } } @@ -411,9 +411,9 @@ public void setTableName(int columnIndex, String tableName) throws SQLException { checkColRange(columnIndex); if (tableName != null) { - colInfo[columnIndex].tableName = new String(tableName); + colInfo[columnIndex].tableName = tableName; } else { - colInfo[columnIndex].tableName = new String(""); + colInfo[columnIndex].tableName = ""; } } @@ -432,9 +432,9 @@ public void setCatalogName(int columnIndex, String catalogName) throws SQLException { checkColRange(columnIndex); if (catalogName != null) - colInfo[columnIndex].catName = new String(catalogName); + colInfo[columnIndex].catName = catalogName; else - colInfo[columnIndex].catName = new String(""); + colInfo[columnIndex].catName = ""; } /** @@ -474,9 +474,9 @@ throws SQLException { checkColRange(columnIndex); if (typeName != null) { - colInfo[columnIndex].colTypeName = new String(typeName); + colInfo[columnIndex].colTypeName = typeName; } else { - colInfo[columnIndex].colTypeName = new String(""); + colInfo[columnIndex].colTypeName = ""; } } @@ -827,7 +827,7 @@ * or the given column number is out of bounds */ public String getColumnClassName(int columnIndex) throws SQLException { - String className = (new String()).getClass().getName(); + String className = String.class.getName(); int sqlType = getColumnType(columnIndex); @@ -835,65 +835,62 @@ case Types.NUMERIC: case Types.DECIMAL: - className = (new java.math.BigDecimal(0)).getClass().getName (); + className = java.math.BigDecimal.class.getName(); break; case Types.BIT: - className = (new Boolean(false)).getClass().getName (); + className = java.lang.Boolean.class.getName(); break; case Types.TINYINT: - className = (new Byte("0")).getClass().getName (); + className = java.lang.Byte.class.getName(); break; case Types.SMALLINT: - className = (new Short("0")).getClass().getName (); + className = java.lang.Short.class.getName(); break; case Types.INTEGER: - className = (new Integer(0)).getClass().getName (); + className = java.lang.Integer.class.getName(); break; case Types.BIGINT: - className = (new Long(0)).getClass().getName (); + className = java.lang.Long.class.getName(); break; case Types.REAL: - className = (new Float(0)).getClass().getName (); + className = java.lang.Float.class.getName(); break; case Types.FLOAT: case Types.DOUBLE: - className = (new Double(0)).getClass().getName(); + className = java.lang.Double.class.getName(); break; case Types.BINARY: case Types.VARBINARY: case Types.LONGVARBINARY: - byte[] b = {}; - className = (b.getClass()).getName(); + className = "byte[]"; break; case Types.DATE: - className = (new java.sql.Date(123456)).getClass().getName (); + className = java.sql.Date.class.getName(); break; case Types.TIME: - className = (new java.sql.Time(123456)).getClass().getName (); + className = java.sql.Time.class.getName(); break; case Types.TIMESTAMP: - className = (new java.sql.Timestamp(123456)).getClass().getName (); + className = java.sql.Timestamp.class.getName(); break; case Types.BLOB: - byte[] blob = {}; - className = (blob.getClass()).getName(); + className = java.sql.Blob.class.getName(); break; case Types.CLOB: - char[] c = {}; - className = (c.getClass()).getName(); + className = java.sql.Clob.class.getName(); break; }
--- a/jdk/src/share/classes/javax/sql/rowset/RowSetProvider.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/javax/sql/rowset/RowSetProvider.java Tue Oct 26 14:43:21 2010 -0400 @@ -29,7 +29,6 @@ import java.security.PrivilegedAction; import java.sql.SQLException; import java.util.ServiceLoader; -import javax.sql.rowset.RowSetFactory; /** * A factory API that enables applications to obtain a @@ -82,15 +81,15 @@ * the <code>RowSetFactory</code> implementation class to load:</p> * <ul> * <li> - * The System property {@code javax.sql.rowset.RowsetFactory}. For example: + * The System property {@code javax.sql.rowset.RowSetFactory}. For example: * <ul> * <li> - * -Djavax.sql.rowset.RowsetFactory=com.sun.rowset.RowSetFactoryImpl + * -Djavax.sql.rowset.RowSetFactory=com.sun.rowset.RowSetFactoryImpl * </li> * </ul> * <li> - * The ServiceLocator API. The ServiceLocator API will look - * for a classname in the file + * The {@link ServiceLoader} API. The {@code ServiceLoader} API will look + * for a class name in the file * {@code META-INF/services/javax.sql.rowset.RowSetFactory} * in jars available to the runtime. For example, to have the the RowSetFactory * implementation {@code com.sun.rowset.RowSetFactoryImpl } loaded, the @@ -271,7 +270,7 @@ /** * Returns the requested System Property. If a {@code SecurityException} * occurs, just return NULL - * @param propName - System property to retreive + * @param propName - System property to retrieve * @return The System property value or NULL if the property does not exist * or a {@code SecurityException} occurs. */
--- a/jdk/src/share/classes/javax/sql/rowset/WebRowSet.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/javax/sql/rowset/WebRowSet.java Tue Oct 26 14:43:21 2010 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -115,7 +115,7 @@ * <<font color=red>url</font>>jdbc:thin:oracle<<font color=red>/url</font>> * <<font color=red>sync-provider</font>> * <<font color=red>sync-provider-name</font>>.com.rowset.provider.RIOptimisticProvider<<font color=red>/sync-provider-name</font>> - * <<font color=red>sync-provider-vendor</font>>Sun Microsystems<<font color=red>/sync-provider-vendor</font>> + * <<font color=red>sync-provider-vendor</font>>Oracle Corporation<<font color=red>/sync-provider-vendor</font>> * <<font color=red>sync-provider-version</font>>1.0<<font color=red>/sync-provider-name</font>> * <<font color=red>sync-provider-grade</font>>LOW<<font color=red>/sync-provider-grade</font>> * <<font color=red>data-source-lock</font>>NONE<<font color=red>/data-source-lock</font>> @@ -489,7 +489,7 @@ * tags and their valid values for a <code>WebRowSet</code> implementation. */ public static String PUBLIC_XML_SCHEMA = - "--//Sun Microsystems, Inc.//XSD Schema//EN"; + "--//Oracle Corporation//XSD Schema//EN"; /** * The URL for the XML Schema definition file that defines the XML tags and
--- a/jdk/src/share/classes/javax/sql/rowset/rowset.properties Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/javax/sql/rowset/rowset.properties Tue Oct 26 14:43:21 2010 -0400 @@ -3,10 +3,10 @@ # Optimistic synchonriztaion provider rowset.provider.classname.0=com.sun.rowset.providers.RIOptimisticProvider -rowset.provider.vendor.0=Sun Microsystems Inc +rowset.provider.vendor.0=Oracle Corporation rowset.provider.version.0=1.0 # XML Provider using standard XML schema rowset.provider.classname.1=com.sun.rowset.providers.RIXMLProvider -rowset.provider.vendor.1=Sun Microsystems Inc. +rowset.provider.vendor.1=Oracle Corporation rowset.provider.version.1=1.0
--- a/jdk/src/share/classes/javax/sql/rowset/serial/SQLOutputImpl.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/javax/sql/rowset/serial/SQLOutputImpl.java Tue Oct 26 14:43:21 2010 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -137,7 +137,7 @@ * values of a UDT to the database. */ public void writeBoolean(boolean x) throws SQLException { - attribs.add(new Boolean(x)); + attribs.add(Boolean.valueOf(x)); } /** @@ -151,7 +151,7 @@ * values of a UDT to the database. */ public void writeByte(byte x) throws SQLException { - attribs.add(new Byte(x)); + attribs.add(Byte.valueOf(x)); } /** @@ -165,7 +165,7 @@ * values of a UDT to the database. */ public void writeShort(short x) throws SQLException { - attribs.add(new Short(x)); + attribs.add(Short.valueOf(x)); } /** @@ -179,7 +179,7 @@ * values of a UDT to the database. */ public void writeInt(int x) throws SQLException { - attribs.add(new Integer(x)); + attribs.add(Integer.valueOf(x)); } /** @@ -193,7 +193,7 @@ * values of a UDT to the database. */ public void writeLong(long x) throws SQLException { - attribs.add(new Long(x)); + attribs.add(Long.valueOf(x)); } /**
--- a/jdk/src/share/classes/javax/sql/rowset/serial/SerialRef.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/javax/sql/rowset/serial/SerialRef.java Tue Oct 26 14:43:21 2010 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -77,7 +77,7 @@ throw new SQLException("Cannot instantiate a SerialRef object " + "that returns a null base type name"); } else { - baseTypeName = new String(ref.getBaseTypeName()); + baseTypeName = ref.getBaseTypeName(); } } @@ -110,7 +110,7 @@ throws SerialException { map = new Hashtable(map); - if (!object.equals(null)) { + if (object != null) { return map.get(object); } else { throw new SerialException("The object is not set");
--- a/jdk/src/share/classes/javax/sql/rowset/serial/SerialStruct.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/javax/sql/rowset/serial/SerialStruct.java Tue Oct 26 14:43:21 2010 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -94,7 +94,7 @@ try { // get the type name - SQLTypeName = new String(in.getSQLTypeName()); + SQLTypeName = in.getSQLTypeName(); System.out.println("SQLTypeName: " + SQLTypeName); // get the attributes of the struct @@ -137,7 +137,7 @@ try { //set the type name - SQLTypeName = new String(in.getSQLTypeName()); + SQLTypeName = in.getSQLTypeName(); Vector tmp = new Vector(); in.writeSQL(new SQLOutputImpl(tmp, map)); @@ -247,7 +247,7 @@ } /** - * The identifier that assists in the serialization of this + * The identifier that assists in the serialization of this * <code>SerialStruct</code> object. */ static final long serialVersionUID = -8322445504027483372L;
--- a/jdk/src/share/classes/javax/sql/rowset/spi/SyncFactory.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/javax/sql/rowset/spi/SyncFactory.java Tue Oct 26 14:43:21 2010 -0400 @@ -125,12 +125,12 @@ * * # Optimistic synchronization provider * rowset.provider.classname.0=com.sun.rowset.providers.RIOptimisticProvider - * rowset.provider.vendor.0=Sun Microsystems Inc + * rowset.provider.vendor.0=Oracle Corporation * rowset.provider.version.0=1.0 * * # XML Provider using standard XML schema * rowset.provider.classname.1=com.sun.rowset.providers.RIXMLProvider - * rowset.provider.vendor.1=Sun Microsystems Inc. + * rowset.provider.vendor.1=Oracle Corporation * rowset.provider.version.1=1.0 * </PRE> * The <code>SyncFactory</code> checks this file and registers the @@ -369,7 +369,7 @@ try { // check if user is supplying his Synchronisation Provider - // Implementation if not use Sun's implementation. + // Implementation if not using Oracle's implementation. // properties.load(new FileInputStream(ROWSET_PROPERTIES)); // The rowset.properties needs to be in jdk/jre/lib when
--- a/jdk/src/share/classes/javax/sql/rowset/spi/SyncProvider.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/javax/sql/rowset/spi/SyncProvider.java Tue Oct 26 14:43:21 2010 -0400 @@ -91,8 +91,8 @@ * </pre> * <p> * A vendor can register a <code>SyncProvider</code> implementation class name - * with Sun Microsystems, Inc. by sending email to jdbc@sun.com. - * Sun will maintain a database listing the + * with Oracle Corporation by sending email to jdbc@sun.com. + * Oracle will maintain a database listing the * available <code>SyncProvider</code> implementations for use with compliant * <code>RowSet</code> implementations. This database will be similar to the * one already maintained to list available JDBC drivers.
--- a/jdk/src/share/classes/javax/sql/rowset/spi/package.html Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/javax/sql/rowset/spi/package.html Tue Oct 26 14:43:21 2010 -0400 @@ -8,7 +8,7 @@ <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]"> <!-- -Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. +Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. This code is free software; you can redistribute it and/or modify it @@ -199,7 +199,7 @@ Vendors may develop a <tt>SyncProvider</tt> implementation with any one of the possible levels of synchronization, thus giving <code>RowSet</code> objects a choice of synchronization mechanisms. A vendor can make its implementation available by -registering the fully qualified class name with Sun Microsystems at +registering the fully qualified class name with Oracle Corporation at <code>jdbc@sun.com</code>. This process is discussed in further detail below. <P>
--- a/jdk/src/share/classes/javax/swing/GroupLayout.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/javax/swing/GroupLayout.java Tue Oct 26 14:43:21 2010 -0400 @@ -1464,8 +1464,8 @@ * <= {@code pref} <= {@code max}. * <p> * Similarly any methods that take a {@code Component} throw a - * {@code NullPointerException} if passed {@code null} and any methods - * that take a {@code Group} throw an {@code IllegalArgumentException} if + * {@code IllegalArgumentException} if passed {@code null} and any methods + * that take a {@code Group} throw an {@code NullPointerException} if * passed {@code null}. * * @see #createSequentialGroup
--- a/jdk/src/share/classes/javax/swing/JComponent.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/javax/swing/JComponent.java Tue Oct 26 14:43:21 2010 -0400 @@ -4787,6 +4787,17 @@ * @see RepaintManager#addDirtyRegion */ public void repaint(long tm, int x, int y, int width, int height) { + Container p = this; + while ((p = p.getParent()) instanceof JComponent) { + JComponent jp = (JComponent) p; + if (jp.isPaintingOrigin()) { + Rectangle rectangle = SwingUtilities.convertRectangle( + this, new Rectangle(x, y, width, height), jp); + jp.repaint(tm, + rectangle.x, rectangle.y, rectangle.width, rectangle.height); + return; + } + } RepaintManager.currentManager(this).addDirtyRegion(this, x, y, width, height); }
--- a/jdk/src/share/classes/javax/swing/JDesktopPane.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/javax/swing/JDesktopPane.java Tue Oct 26 14:43:21 2010 -0400 @@ -215,7 +215,8 @@ /** * Sets the <code>DesktopManger</code> that will handle - * desktop-specific UI actions. + * desktop-specific UI actions. This may be overridden by + * {@code LookAndFeel}. * * @param d the <code>DesktopManager</code> to use *
--- a/jdk/src/share/classes/javax/swing/JLayer.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/javax/swing/JLayer.java Tue Oct 26 14:43:21 2010 -0400 @@ -25,17 +25,17 @@ package javax.swing; +import sun.awt.AWTAccessor; + import javax.swing.plaf.LayerUI; +import javax.swing.border.Border; import java.awt.*; import java.awt.event.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; import java.io.ObjectInputStream; -import java.io.Serializable; -import java.lang.ref.WeakReference; import java.util.ArrayList; -import java.util.Iterator; import java.security.AccessController; import java.security.PrivilegedAction; @@ -156,8 +156,6 @@ private LayerUI<? super V> layerUI; private JPanel glassPane; private boolean isPainting; - private static final DefaultLayerLayout sharedLayoutInstance = - new DefaultLayerLayout(); private long eventMask; private static final LayerEventController eventController = @@ -165,7 +163,7 @@ /** * Creates a new {@code JLayer} object with a {@code null} view component - * and {@code null} {@link javax.swing.plaf.LayerUI}. + * and default {@link javax.swing.plaf.LayerUI}. * * @see #setView * @see #setUI @@ -176,14 +174,14 @@ /** * Creates a new {@code JLayer} object - * with {@code null} {@link javax.swing.plaf.LayerUI}. + * with default {@link javax.swing.plaf.LayerUI}. * * @param view the component to be decorated by this {@code JLayer} * * @see #setUI */ public JLayer(V view) { - this(view, null); + this(view, new LayerUI<V>()); } /** @@ -195,7 +193,6 @@ * to be used by this {@code JLayer} */ public JLayer(V view, LayerUI<V> ui) { - setLayout(sharedLayoutInstance); setGlassPane(createGlassPane()); setView(view); setUI(ui); @@ -279,10 +276,15 @@ */ public void setGlassPane(JPanel glassPane) { Component oldGlassPane = getGlassPane(); + boolean isGlassPaneVisible = false; if (oldGlassPane != null) { + isGlassPaneVisible = oldGlassPane.isVisible(); super.remove(oldGlassPane); } if (glassPane != null) { + AWTAccessor.getComponentAccessor().setMixingCutoutShape(glassPane, + new Rectangle()); + glassPane.setVisible(isGlassPaneVisible); super.addImpl(glassPane, null, 0); } this.glassPane = glassPane; @@ -303,6 +305,40 @@ } /** + * Sets the layout manager for this container. This method is + * overridden to prevent the layout manager from being set. + * <p/>Note: If {@code mgr} is non-{@code null}, this + * method will throw an exception as layout managers are not supported on + * a {@code JLayer}. + * + * @param mgr the specified layout manager + * @exception IllegalArgumentException this method is not supported + */ + public void setLayout(LayoutManager mgr) { + if (mgr != null) { + throw new IllegalArgumentException("JLayer.setLayout() not supported"); + } + } + + /** + * A non-{@code null] border, or non-zero insets, isn't supported, to prevent the geometry + * of this component from becoming complex enough to inhibit + * subclassing of {@code LayerUI} class. To create a {@code JLayer} with a border, + * add it to a {@code JPanel} that has a border. + * <p/>Note: If {@code border} is non-{@code null}, this + * method will throw an exception as borders are not supported on + * a {@code JLayer}. + * + * @param border the {@code Border} to set + * @exception IllegalArgumentException this method is not supported + */ + public void setBorder(Border border) { + if (border != null) { + throw new IllegalArgumentException("JLayer.setBorder() not supported"); + } + } + + /** * This method is not supported by {@code JLayer} * and always throws {@code UnsupportedOperationException} * @@ -341,6 +377,32 @@ } /** + * Always returns {@code true} to cause painting to originate from {@code JLayer}, + * or one of its ancestors. + * + * @return true + * @see JComponent#isPaintingOrigin() + */ + boolean isPaintingOrigin() { + return true; + } + + /** + * Delegates repainting to {@link javax.swing.plaf.LayerUI#repaint} method. + * + * @param tm this parameter is not used + * @param x the x value of the dirty region + * @param y the y value of the dirty region + * @param width the width of the dirty region + * @param height the height of the dirty region + */ + public void repaint(long tm, int x, int y, int width, int height) { + if (getUI() != null) { + getUI().repaint(tm, x, y, width, height, this); + } + } + + /** * Delegates all painting to the {@link javax.swing.plaf.LayerUI} object. * * @param g the {@code Graphics} to render to @@ -364,14 +426,18 @@ } /** - * To enable the correct painting of the {@code glassPane} and view component, - * the {@code JLayer} overrides the default implementation of - * this method to return {@code false} when the {@code glassPane} is visible. + * The {@code JLayer} overrides the default implementation of + * this method (in {@code JComponent}) to return {@code false}. + * This ensures + * that the drawing machinery will call the {@code JLayer}'s + * {@code paint} + * implementation rather than messaging the {@code JLayer}'s + * children directly. * - * @return false if {@code JLayer}'s {@code glassPane} is visible + * @return false */ public boolean isOptimizedDrawingEnabled() { - return glassPane == null || !glassPane.isVisible(); + return false; } /** @@ -461,17 +527,16 @@ /** * Returns the preferred size of the viewport for a view component. * <p/> - * If the ui delegate of this layer is not {@code null}, this method delegates its - * implementation to the {@code LayerUI.getPreferredScrollableViewportSize(JLayer)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return the preferred size of the viewport for a view component * * @see Scrollable - * @see LayerUI#getPreferredScrollableViewportSize(JLayer) */ public Dimension getPreferredScrollableViewportSize() { - if (getUI() != null) { - return getUI().getPreferredScrollableViewportSize(this); + if (getView() instanceof Scrollable) { + return ((Scrollable)getView()).getPreferredScrollableViewportSize(); } return getPreferredSize(); } @@ -481,18 +546,17 @@ * that display logical rows or columns in order to completely expose * one block of rows or columns, depending on the value of orientation. * <p/> - * If the ui delegate of this layer is not {@code null}, this method delegates its - * implementation to the {@code LayerUI.getScrollableBlockIncrement(JLayer,Rectangle,int,int)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return the "block" increment for scrolling in the specified direction * * @see Scrollable - * @see LayerUI#getScrollableBlockIncrement(JLayer, Rectangle, int, int) */ public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { - if (getUI() != null) { - return getUI().getScrollableBlockIncrement(this, visibleRect, + if (getView() instanceof Scrollable) { + return ((Scrollable)getView()).getScrollableBlockIncrement(visibleRect, orientation, direction); } return (orientation == SwingConstants.VERTICAL) ? visibleRect.height : @@ -504,17 +568,16 @@ * determine the height of the layer, unless the preferred height * of the layer is smaller than the height of the viewport. * <p/> - * If the ui delegate of this layer is not null, this method delegates its - * implementation to the {@code LayerUI.getScrollableTracksViewportHeight(JLayer)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return whether the layer should track the height of the viewport * * @see Scrollable - * @see LayerUI#getScrollableTracksViewportHeight(JLayer) */ public boolean getScrollableTracksViewportHeight() { - if (getUI() != null) { - return getUI().getScrollableTracksViewportHeight(this); + if (getView() instanceof Scrollable) { + return ((Scrollable)getView()).getScrollableTracksViewportHeight(); } return false; } @@ -524,17 +587,16 @@ * determine the width of the layer, unless the preferred width * of the layer is smaller than the width of the viewport. * <p/> - * If the ui delegate of this layer is not null, this method delegates its - * implementation to the {@code LayerUI.getScrollableTracksViewportWidth(JLayer)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return whether the layer should track the width of the viewport * * @see Scrollable - * @see LayerUI#getScrollableTracksViewportWidth(JLayer) */ public boolean getScrollableTracksViewportWidth() { - if (getUI() != null) { - return getUI().getScrollableTracksViewportWidth(this); + if (getView() instanceof Scrollable) { + return ((Scrollable)getView()).getScrollableTracksViewportWidth(); } return false; } @@ -549,20 +611,19 @@ * Scrolling containers, like {@code JScrollPane}, will use this method * each time the user requests a unit scroll. * <p/> - * If the ui delegate of this layer is not {@code null}, this method delegates its - * implementation to the {@code LayerUI.getScrollableUnitIncrement(JLayer,Rectangle,int,int)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return The "unit" increment for scrolling in the specified direction. * This value should always be positive. * * @see Scrollable - * @see LayerUI#getScrollableUnitIncrement(JLayer, Rectangle, int, int) */ public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { - if (getUI() != null) { - return getUI().getScrollableUnitIncrement( - this, visibleRect, orientation, direction); + if (getView() instanceof Scrollable) { + return ((Scrollable) getView()).getScrollableUnitIncrement( + visibleRect, orientation, direction); } return 1; } @@ -595,6 +656,16 @@ } /** + * Delegates its functionality to the {@link javax.swing.plaf.LayerUI#doLayout(JLayer)} method, + * if {@code LayerUI} is set. + */ + public void doLayout() { + if (getUI() != null) { + getUI().doLayout(this); + } + } + + /** * static AWTEventListener to be shared with all AbstractLayerUIs */ private static class LayerEventController implements AWTEventListener { @@ -625,8 +696,8 @@ JLayer l = (JLayer) component; LayerUI ui = l.getUI(); if (ui != null && - isEventEnabled(l.getLayerEventMask(), - event.getID())) { + isEventEnabled(l.getLayerEventMask(), event.getID()) && + (!(event instanceof InputEvent) || !((InputEvent)event).isConsumed())) { ui.eventDispatched(event, l); } } @@ -758,82 +829,4 @@ return super.contains(x, y); } } - - /** - * The default layout manager for the {@link javax.swing.JLayer}.<br/> - * It places the glassPane on top of the view component - * and makes it the same size as {@code JLayer}, - * it also makes the view component the same size but minus layer's insets<br/> - */ - private static class DefaultLayerLayout implements LayoutManager, Serializable { - /** - * {@inheritDoc} - */ - public void layoutContainer(Container parent) { - JLayer layer = (JLayer) parent; - Component view = layer.getView(); - Component glassPane = layer.getGlassPane(); - if (view != null) { - Insets insets = layer.getInsets(); - view.setLocation(insets.left, insets.top); - view.setSize(layer.getWidth() - insets.left - insets.right, - layer.getHeight() - insets.top - insets.bottom); - } - if (glassPane != null) { - glassPane.setLocation(0, 0); - glassPane.setSize(layer.getWidth(), layer.getHeight()); - } - } - - /** - * {@inheritDoc} - */ - public Dimension minimumLayoutSize(Container parent) { - JLayer layer = (JLayer) parent; - Insets insets = layer.getInsets(); - Dimension ret = new Dimension(insets.left + insets.right, - insets.top + insets.bottom); - Component view = layer.getView(); - if (view != null) { - Dimension size = view.getMinimumSize(); - ret.width += size.width; - ret.height += size.height; - } - if (ret.width == 0 || ret.height == 0) { - ret.width = ret.height = 4; - } - return ret; - } - - /** - * {@inheritDoc} - */ - public Dimension preferredLayoutSize(Container parent) { - JLayer layer = (JLayer) parent; - Insets insets = layer.getInsets(); - Dimension ret = new Dimension(insets.left + insets.right, - insets.top + insets.bottom); - Component view = layer.getView(); - if (view != null) { - Dimension size = view.getPreferredSize(); - if (size.width > 0 && size.height > 0) { - ret.width += size.width; - ret.height += size.height; - } - } - return ret; - } - - /** - * {@inheritDoc} - */ - public void addLayoutComponent(String name, Component comp) { - } - - /** - * {@inheritDoc} - */ - public void removeLayoutComponent(Component comp) { - } - } }
--- a/jdk/src/share/classes/javax/swing/JTable.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/javax/swing/JTable.java Tue Oct 26 14:43:21 2010 -0400 @@ -4574,9 +4574,8 @@ * @see TableColumnModelListener */ public void columnMoved(TableColumnModelEvent e) { - // If I'm currently editing, then I should stop editing - if (isEditing()) { - removeEditor(); + if (isEditing() && !getCellEditor().stopCellEditing()) { + getCellEditor().cancelCellEditing(); } repaint(); } @@ -4593,8 +4592,8 @@ * @see TableColumnModelListener */ public void columnMarginChanged(ChangeEvent e) { - if (isEditing()) { - removeEditor(); + if (isEditing() && !getCellEditor().stopCellEditing()) { + getCellEditor().cancelCellEditing(); } TableColumn resizingColumn = getResizingColumn(); // Need to do this here, before the parent's
--- a/jdk/src/share/classes/javax/swing/ToolTipManager.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/javax/swing/ToolTipManager.java Tue Oct 26 14:43:21 2010 -0400 @@ -459,7 +459,7 @@ if (insideComponent == null) { // Drag exit } - if (window != null && event.getSource() == window) { + if (window != null && event.getSource() == window && insideComponent != null) { // if we get an exit and have a heavy window // we need to check if it if overlapping the inside component Container insideComponentWindow = insideComponent.getTopLevelAncestor();
--- a/jdk/src/share/classes/javax/swing/plaf/LayerUI.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/javax/swing/plaf/LayerUI.java Tue Oct 26 14:43:21 2010 -0400 @@ -600,104 +600,6 @@ } /** - * Returns the preferred size of the viewport for a view component. - * - * @param l the {@code JLayer} component where this UI delegate is being installed - * @return the preferred size of the viewport for a view component - * @see Scrollable#getPreferredScrollableViewportSize() - */ - public Dimension getPreferredScrollableViewportSize(JLayer<? extends V> l) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getPreferredScrollableViewportSize(); - } - return l.getPreferredSize(); - } - - /** - * Returns a scroll increment, which is required for components - * that display logical rows or columns in order to completely expose - * one block of rows or columns, depending on the value of orientation. - * - * @param l the {@code JLayer} component where this UI delegate is being installed - * @param visibleRect The view area visible within the viewport - * @param orientation Either SwingConstants.VERTICAL or SwingConstants.HORIZONTAL. - * @param direction Less than zero to scroll up/left, greater than zero for down/right. - * @return the "block" increment for scrolling in the specified direction - * @see Scrollable#getScrollableBlockIncrement(Rectangle, int, int) - */ - public int getScrollableBlockIncrement(JLayer<? extends V> l, - Rectangle visibleRect, - int orientation, int direction) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getScrollableBlockIncrement( - visibleRect,orientation, direction); - } - return (orientation == SwingConstants.VERTICAL) ? visibleRect.height : - visibleRect.width; - } - - /** - * Returns {@code false} to indicate that the height of the viewport does not - * determine the height of the layer, unless the preferred height - * of the layer is smaller than the height of the viewport. - * - * @param l the {@code JLayer} component where this UI delegate is being installed - * @return whether the layer should track the height of the viewport - * @see Scrollable#getScrollableTracksViewportHeight() - */ - public boolean getScrollableTracksViewportHeight(JLayer<? extends V> l) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getScrollableTracksViewportHeight(); - } - return false; - } - - /** - * Returns {@code false} to indicate that the width of the viewport does not - * determine the width of the layer, unless the preferred width - * of the layer is smaller than the width of the viewport. - * - * @param l the {@code JLayer} component where this UI delegate is being installed - * @return whether the layer should track the width of the viewport - * @see Scrollable - * @see LayerUI#getScrollableTracksViewportWidth(JLayer) - */ - public boolean getScrollableTracksViewportWidth(JLayer<? extends V> l) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getScrollableTracksViewportWidth(); - } - return false; - } - - /** - * Returns a scroll increment, which is required for components - * that display logical rows or columns in order to completely expose - * one new row or column, depending on the value of orientation. - * Ideally, components should handle a partially exposed row or column - * by returning the distance required to completely expose the item. - * <p> - * Scrolling containers, like JScrollPane, will use this method - * each time the user requests a unit scroll. - * - * @param l the {@code JLayer} component where this UI delegate is being installed - * @param visibleRect The view area visible within the viewport - * @param orientation Either SwingConstants.VERTICAL or SwingConstants.HORIZONTAL. - * @param direction Less than zero to scroll up/left, greater than zero for down/right. - * @return The "unit" increment for scrolling in the specified direction. - * This value should always be positive. - * @see Scrollable#getScrollableUnitIncrement(Rectangle, int, int) - */ - public int getScrollableUnitIncrement(JLayer<? extends V> l, - Rectangle visibleRect, - int orientation, int direction) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getScrollableUnitIncrement( - visibleRect, orientation, direction); - } - return 1; - } - - /** * If the {@code JLayer}'s view component is not {@code null}, * this calls the view's {@code getBaseline()} method. * Otherwise, the default implementation is called. @@ -718,7 +620,7 @@ /** * If the {@code JLayer}'s view component is not {@code null}, - * this calls the view's {@code getBaselineResizeBehavior()} method. + * this returns the result of the view's {@code getBaselineResizeBehavior()} method. * Otherwise, the default implementation is called. * * @param c {@code JLayer} to return baseline resize behavior for @@ -732,4 +634,90 @@ } return super.getBaselineResizeBehavior(c); } + + /** + * Causes the passed instance of {@code JLayer} to lay out its components. + * + * @param l the {@code JLayer} component where this UI delegate is being installed + */ + public void doLayout(JLayer<? extends V> l) { + Component view = l.getView(); + if (view != null) { + view.setBounds(0, 0, l.getWidth(), l.getHeight()); + } + Component glassPane = l.getGlassPane(); + if (glassPane != null) { + glassPane.setBounds(0, 0, l.getWidth(), l.getHeight()); + } + } + + /** + * If the {@code JLayer}'s view component is not {@code null}, + * this returns the result of the view's {@code getPreferredSize()} method. + * Otherwise, the default implementation is used. + * + * @param c {@code JLayer} to return preferred size for + * @return preferred size for the passed {@code JLayer} + */ + public Dimension getPreferredSize(JComponent c) { + JLayer l = (JLayer) c; + Component view = l.getView(); + if (view != null) { + return view.getPreferredSize(); + } + return super.getPreferredSize(c); + } + + /** + * If the {@code JLayer}'s view component is not {@code null}, + * this returns the result of the view's {@code getMinimalSize()} method. + * Otherwise, the default implementation is used. + * + * @param c {@code JLayer} to return preferred size for + * @return minimal size for the passed {@code JLayer} + */ + public Dimension getMinimumSize(JComponent c) { + JLayer l = (JLayer) c; + Component view = l.getView(); + if (view != null) { + return view.getMinimumSize(); + } + return super.getMinimumSize(c); + } + + /** + * If the {@code JLayer}'s view component is not {@code null}, + * this returns the result of the view's {@code getMaximumSize()} method. + * Otherwise, the default implementation is used. + * + * @param c {@code JLayer} to return preferred size for + * @return maximun size for the passed {@code JLayer} + */ + public Dimension getMaximumSize(JComponent c) { + JLayer l = (JLayer) c; + Component view = l.getView(); + if (view != null) { + return view.getMaximumSize(); + } + return super.getMaximumSize(c); + } + + /** + * Adds the specified region to the dirty region list if the component + * is showing. The component will be repainted after all of the + * currently pending events have been dispatched. + * <p/> + * This method is to be overridden when the dirty region needs to be changed. + * + * @param tm this parameter is not used + * @param x the x value of the dirty region + * @param y the y value of the dirty region + * @param width the width of the dirty region + * @param height the height of the dirty region + * @see java.awt.Component#isShowing + * @see RepaintManager#addDirtyRegion + */ + public void repaint(long tm, int x, int y, int width, int height, JLayer<? extends V> l) { + RepaintManager.currentManager(l).addDirtyRegion(l, x, y, width, height); + } }
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java Tue Oct 26 14:43:21 2010 -0400 @@ -1603,6 +1603,7 @@ BoundedRangeModel newModel = (BoundedRangeModel)e.getNewValue(); oldModel.removeChangeListener(modelListener); newModel.addChangeListener(modelListener); + scrollBarValue = scrollbar.getValue(); scrollbar.repaint(); scrollbar.revalidate(); } else if ("orientation" == propertyName) {
--- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalComboBoxUI.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalComboBoxUI.java Tue Oct 26 14:43:21 2010 -0400 @@ -144,7 +144,7 @@ */ public int getBaseline(JComponent c, int width, int height) { int baseline; - if (MetalLookAndFeel.usingOcean()) { + if (MetalLookAndFeel.usingOcean() && height >= 4) { height -= 4; baseline = super.getBaseline(c, width, height); if (baseline >= 0) {
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java Tue Oct 26 14:43:21 2010 -0400 @@ -115,6 +115,9 @@ return new SynthTabbedPaneUI(); } + private SynthTabbedPaneUI() { + } + private boolean scrollableTabLayoutEnabled() { return (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT); }
--- a/jdk/src/share/classes/sun/awt/AWTAccessor.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/sun/awt/AWTAccessor.java Tue Oct 26 14:43:21 2010 -0400 @@ -344,6 +344,11 @@ * Removes the last focus request for the heavyweight from the queue. */ void removeLastFocusRequest(Component heavyweight); + + /* + * Sets the most recent focus owner in the window. + */ + void setMostRecentFocusOwner(Window window, Component component); } /*
--- a/jdk/src/share/classes/sun/awt/EmbeddedFrame.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/sun/awt/EmbeddedFrame.java Tue Oct 26 14:43:21 2010 -0400 @@ -70,7 +70,10 @@ // JDK 1.1 compatibility private static final long serialVersionUID = 2967042741780317130L; - // Use these in traverseOut method to determine directions + /* + * The constants define focus traversal directions. + * Use them in {@code traverseIn}, {@code traverseOut} methods. + */ protected static final boolean FORWARD = true; protected static final boolean BACKWARD = false; @@ -284,6 +287,41 @@ } /** + * This method is called by the embedder when we should receive focus as element + * of the traversal chain. The method requests focus on: + * 1. the first Component of this EmbeddedFrame if user moves focus forward + * in the focus traversal cycle. + * 2. the last Component of this EmbeddedFrame if user moves focus backward + * in the focus traversal cycle. + * + * The direction parameter specifies which of the two mentioned cases is + * happening. Use FORWARD and BACKWARD constants defined in the EmbeddedFrame class + * to avoid confusing boolean values. + * + * A concrete implementation of this method is defined in the platform-dependent + * subclasses. + * + * @param direction FORWARD or BACKWARD + * @return true, if the EmbeddedFrame wants to get focus, false otherwise. + */ + public boolean traverseIn(boolean direction) { + Component comp = null; + + if (direction == FORWARD) { + comp = getFocusTraversalPolicy().getFirstComponent(this); + } else { + comp = getFocusTraversalPolicy().getLastComponent(this); + } + if (comp != null) { + // comp.requestFocus(); - Leads to a hung. + + AWTAccessor.getKeyboardFocusManagerAccessor().setMostRecentFocusOwner(this, comp); + synthesizeWindowActivation(true); + } + return (null != comp); + } + + /** * This method is called from dispatchKeyEvent in the following two cases: * 1. The focus is on the first Component of this EmbeddedFrame and we are * about to transfer the focus backward.
--- a/jdk/src/share/classes/sun/net/www/http/HttpClient.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/sun/net/www/http/HttpClient.java Tue Oct 26 14:43:21 2010 -0400 @@ -55,6 +55,9 @@ // Http data we send with the headers PosterOutputStream poster = null; + // true if we are in streaming mode (fixed length or chunked) + boolean streaming; + // if we've had one io error boolean failedOnce = false; @@ -275,6 +278,10 @@ ret.cachedHttpClient = true; assert ret.inCache; ret.inCache = false; + PlatformLogger logger = HttpURLConnection.getHttpLogger(); + if (logger.isLoggable(PlatformLogger.FINEST)) { + logger.finest("KeepAlive stream retrieved from the cache, " + ret); + } } } else { // We cannot return this connection to the cache as it's @@ -545,6 +552,13 @@ serverOutput.flush(); } + public void writeRequests(MessageHeader head, + PosterOutputStream pos, + boolean streaming) throws IOException { + this.streaming = streaming; + writeRequests(head, pos); + } + /** Parse the first line of the HTTP request. It usually looks something like: "HTTP/1.0 <number> comment\r\n". */ @@ -577,11 +591,11 @@ closeServer(); cachedHttpClient = false; if (!failedOnce && requests != null) { - if (httpuc.getRequestMethod().equals("POST") && !retryPostProp) { + failedOnce = true; + if (httpuc.getRequestMethod().equals("POST") && (!retryPostProp || streaming)) { // do not retry the request } else { // try once more - failedOnce = true; openServer(); if (needsTunneling()) { httpuc.doTunneling(); @@ -684,10 +698,10 @@ } } else if (nread != 8) { if (!failedOnce && requests != null) { - if (httpuc.getRequestMethod().equals("POST") && !retryPostProp) { + failedOnce = true; + if (httpuc.getRequestMethod().equals("POST") && (!retryPostProp || streaming)) { // do not retry the request } else { - failedOnce = true; closeServer(); cachedHttpClient = false; openServer();
--- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Tue Oct 26 14:43:21 2010 -0400 @@ -494,7 +494,7 @@ if (logger.isLoggable(PlatformLogger.FINE)) { logger.fine(requests.toString()); } - http.writeRequests(requests, poster); + http.writeRequests(requests, poster, streaming()); if (ps.checkError()) { String proxyHost = http.getProxyHostUsed(); int proxyPort = http.getProxyPortUsed(); @@ -2825,6 +2825,38 @@ } } + /* skip() calls read() in order to ensure that entire response gets + * cached. same implementation as InputStream.skip */ + + private byte[] skipBuffer; + private static final int SKIP_BUFFER_SIZE = 8096; + + @Override + public long skip (long n) throws IOException { + + long remaining = n; + int nr; + if (skipBuffer == null) + skipBuffer = new byte[SKIP_BUFFER_SIZE]; + + byte[] localSkipBuffer = skipBuffer; + + if (n <= 0) { + return 0; + } + + while (remaining > 0) { + nr = read(localSkipBuffer, 0, + (int) Math.min(SKIP_BUFFER_SIZE, remaining)); + if (nr < 0) { + break; + } + remaining -= nr; + } + + return n - remaining; + } + @Override public void close () throws IOException { try {
--- a/jdk/src/share/classes/sun/security/tools/KeyTool.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/sun/security/tools/KeyTool.java Tue Oct 26 14:43:21 2010 -0400 @@ -281,7 +281,7 @@ RFC("rfc", null, "output in RFC style"), SIGALG("sigalg", "<sigalg>", "signature algorithm name"), SRCALIAS("srcalias", "<srcalias>", "source alias"), - SRCKEYPASS("srckeypass", "<arg>", "source keystore password"), + SRCKEYPASS("srckeypass", "<arg>", "source key password"), SRCKEYSTORE("srckeystore", "<srckeystore>", "source keystore name"), SRCPROTECTED("srcprotected", null, "source keystore password protected"), SRCPROVIDERNAME("srcprovidername", "<srcprovidername>", "source keystore provider name"),
--- a/jdk/src/share/classes/sun/security/util/Resources.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/sun/security/util/Resources.java Tue Oct 26 14:43:21 2010 -0400 @@ -116,11 +116,9 @@ {"X.509 extension", "X.509 extension"}, //-ext {"output file name", - "output file name"}, //-file + "output file name"}, //-file and -outfile {"input file name", - "input file name"}, //-file - {"input file name", - "input file name"}, //-infile + "input file name"}, //-file and -infile {"key algorithm name", "key algorithm name"}, //-keyalg {"key password", @@ -133,8 +131,6 @@ "new password"}, //-new {"do not prompt", "do not prompt"}, //-noprompt - {"output file name", - "output file name"}, //-outfile {"password through protected mechanism", "password through protected mechanism"}, //-protected {"provider argument", @@ -151,8 +147,8 @@ "signature algorithm name"}, //-sigalg {"source alias", "source alias"}, //-srcalias - {"source keystore password", - "source keystore password"}, //-srckeypass + {"source key password", + "source key password"}, //-srckeypass {"source keystore name", "source keystore name"}, //-srckeystore {"source keystore password protected", @@ -276,8 +272,6 @@ "Alias <{0}> has no certificate"}, {"Key pair not generated, alias <alias> already exists", "Key pair not generated, alias <{0}> already exists"}, - {"Cannot derive signature algorithm", - "Cannot derive signature algorithm"}, {"Generating keysize bit keyAlgName key pair and self-signed certificate (sigAlgName) with a validity of validality days\n\tfor: x500Name", "Generating {0} bit {1} key pair and self-signed certificate ({2}) with a validity of {3} days\n\tfor: {4}"}, {"Enter key password for <alias>", "Enter key password for <{0}>"}, @@ -321,8 +315,6 @@ {"Failed to parse input", "Failed to parse input"}, {"Empty input", "Empty input"}, {"Not X.509 certificate", "Not X.509 certificate"}, - {"Cannot derive signature algorithm", - "Cannot derive signature algorithm"}, {"alias has no public key", "{0} has no public key"}, {"alias has no X.509 certificate", "{0} has no X.509 certificate"}, {"New certificate (self-signed):", "New certificate (self-signed):"}, @@ -552,7 +544,6 @@ {"package name", "package name"}, {"policy type", "policy type"}, {"property name", "property name"}, - {"provider name", "provider name"}, {"Principal List", "Principal List"}, {"Permission List", "Permission List"}, {"Code Base", "Code Base"},
--- a/jdk/src/share/classes/sun/util/locale/BaseLocale.java Mon Oct 25 13:31:55 2010 -0400 +++ b/jdk/src/share/classes/sun/util/locale/BaseLocale.java Tue Oct 26 14:43:21 2010 -0400 @@ -64,12 +64,14 @@ public static BaseLocale getInstance(String language, String script, String region, String variant) { // JDK uses deprecated ISO639.1 language codes for he, yi and id - if (AsciiUtil.caseIgnoreMatch(language, "he")) { - language = "iw"; - } else if (AsciiUtil.caseIgnoreMatch(language, "yi")) { - language = "ji"; - } else if (AsciiUtil.caseIgnoreMatch(language, "id")) { - language = "in"; + if (language != null) { + if (AsciiUtil.caseIgnoreMatch(language, "he")) { + language = "iw"; + } else if (AsciiUtil.caseIgnoreMatch(language, "yi")) { + language = "ji"; + } else if (AsciiUtil.caseIgnoreMatch(language, "id")) { + language = "in"; + } } Key key = new Key(language, script, region, variant);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/demo/nio/zipfs/Demo.java Tue Oct 26 14:43:21 2010 -0400 @@ -0,0 +1,664 @@ +/* + * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.io.*; +import java.nio.*; +import java.nio.channels.*; +import java.nio.file.*; +import java.nio.file.attribute.*; +import java.net.*; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +import static java.nio.file.StandardOpenOption.*; +import static java.nio.file.StandardCopyOption.*; + +/* + * ZipFileSystem usage demo + * + * java [-cp .../zipfs.jar:./] Demo action ZipfileName [...] + * + * To deploy the provider, either copy the zipfs.jar into JDK/JRE + * extensions directory or add + * <JDK_HOME>/demo/nio/ZipFileSystem/zipfs.jar + * into your class path as showed above. + * + * @author Xueming Shen + */ + +public class Demo { + + static enum Action { + rename, // <java Demo rename zipfile src dst> + // rename entry src to dst inside zipfile + + movein, // <java Demo movein zipfile src dst> + // move an external src file into zipfile + // as entry dst + + moveout, // <java Demo moveout zipfile src dst> + // move a zipfile entry src out to dst + + copy, // <java Demo copy zipfile src dst> + // copy entry src to dst inside zipfile + + copyin, // <java Demo copyin zipfile src dst> + // copy an external src file into zipfile + // as entry dst + + copyout, // <java Demo copyout zipfile src dst> + // copy zipfile entry src" out to file dst + + zzmove, // <java Demo zzmove zfsrc zfdst path> + // move entry path/dir from zfsrc to zfdst + + zzcopy, // <java Demo zzcopy zfsrc zfdst path> + // copy path from zipfile zfsrc to zipfile + // zfdst + + attrs, // <java Demo attrs zipfile path> + // printout the attributes of entry path + + attrsspace, // <java Demo attrsspace zipfile path> + // printout the storespace attrs of entry path + + setmtime, // <java Demo setmtime zipfile "MM/dd/yy-HH:mm:ss" path...> + // set the lastModifiedTime of entry path + + lsdir, // <java Demo lsdir zipfile dir> + // list dir's direct child files/dirs + + mkdir, // <java Demo mkdir zipfile dir> + + mkdirs, // <java Demo mkdirs zipfile dir> + + rmdirs, // <java Demo rmdirs zipfile dir> + + list, // <java Demo list zipfile [dir]> + // recursively list all entries of dir + // via DirectoryStream + + tlist, // <java Demo tlist zipfile [dir]> + // list with buildDirTree=true + + vlist, // <java Demo vlist zipfile [dir]> + // recursively verbose list all entries of + // dir via DirectoryStream + + walk, // <java Demo walk zipfile [dir]> + // recursively walk all entries of dir + // via Files.walkFileTree + + twalk, // <java Demo twalk zipfile [dir]> + // walk with buildDirTree=true + + extract, // <java Demo extract zipfile file [...]> + + update, // <java Demo extract zipfile file [...]> + + delete, // <java Demo delete zipfile file [...]> + + add, // <java Demo add zipfile file [...]> + + create, // <java Demo create zipfile file [...]> + // create a new zipfile if it doesn't exit + // and then add the file(s) into it. + + attrs2, // <java Demo attrs2 zipfile file [...]> + // test different ways to print attrs + } + + public static void main(String[] args) throws Throwable { + + Action action = Action.valueOf(args[0]);; + Map<String, Object> env = env = new HashMap<String, Object>(); + if (action == Action.create) + env.put("createNew", true); + if (action == Action.tlist || action == Action.twalk) + env.put("buildDirTree", true); + + FileSystem fs = FileSystems.newFileSystem( + URI.create("zip" + Paths.get(args[1]).toUri().toString().substring(4)), + env, + null); + try { + FileSystem fs2; + Path path, src, dst; + boolean isRename = false; + switch (action) { + case rename: + src = fs.getPath(args[2]); + dst = fs.getPath(args[3]); + src.moveTo(dst); + break; + case moveout: + src = fs.getPath(args[2]); + dst = Paths.get(args[3]); + src.moveTo(dst); + break; + case movein: + src = Paths.get(args[2]); + dst = fs.getPath(args[3]); + src.moveTo(dst); + break; + case copy: + src = fs.getPath(args[2]); + dst = fs.getPath(args[3]); + src.copyTo(dst); + break; + case copyout: + src = fs.getPath(args[2]); + dst = Paths.get(args[3]); + src.copyTo(dst); + break; + case copyin: + src = Paths.get(args[2]); + dst = fs.getPath(args[3]); + src.copyTo(dst); + break; + case zzmove: + fs2 = FileSystems.newFileSystem( + URI.create("zip" + Paths.get(args[2]).toUri().toString().substring(4)), + env, + null); + //sf1.getPath(args[3]).moveTo(fs2.getPath(args[3])); + z2zmove(fs, fs2, args[3]); + fs2.close(); + break; + case zzcopy: + fs2 = FileSystems.newFileSystem( + URI.create("zip" + Paths.get(args[2]).toUri().toString().substring(4)), + env, + null); + //sf1.getPath(args[3]).copyTo(fs2.getPath(args[3])); + z2zcopy(fs, fs2, args[3]); + fs2.close(); + break; + case attrs: + for (int i = 2; i < args.length; i++) { + path = fs.getPath(args[i]); + System.out.println( + Attributes.readBasicFileAttributes(path).toString()); + } + break; + case setmtime: + DateFormat df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss"); + Date newDatetime = df.parse(args[2]); + for (int i = 3; i < args.length; i++) { + path = fs.getPath(args[i]); + path.setAttribute("lastModifiedTime", + FileTime.fromMillis(newDatetime.getTime())); + System.out.println( + Attributes.readBasicFileAttributes(path).toString()); + } + break; + case attrsspace: + path = fs.getPath("/"); + FileStore fstore = path.getFileStore(); + //System.out.println(fstore.getFileStoreAttributeView(FileStoreSpaceAttributeView.class) + // .readAttributes()); + // or + System.out.printf("filestore[%s]%n", fstore.name()); + System.out.printf(" totalSpace: %d%n", + (Long)fstore.getAttribute("space:totalSpace")); + System.out.printf(" usableSpace: %d%n", + (Long)fstore.getAttribute("space:usableSpace")); + System.out.printf(" unallocSpace: %d%n", + (Long)fstore.getAttribute("space:unallocatedSpace")); + break; + case list: + case tlist: + if (args.length < 3) + list(fs.getPath("/"), false); + else + list(fs.getPath(args[2]), false); + break; + case vlist: + if (args.length < 3) + list(fs.getPath("/"), true); + else + list(fs.getPath(args[2]), true); + break; + case twalk: + case walk: + walk(fs.getPath((args.length > 2)? args[2] : "/")); + break; + case extract: + if (args.length == 2) { + extract(fs, "/"); + } else { + for (int i = 2; i < args.length; i++) { + extract(fs, args[i]); + } + } + break; + case delete: + for (int i = 2; i < args.length; i++) + fs.getPath(args[i]).delete(); + break; + case create: + case add: + case update: + for (int i = 2; i < args.length; i++) { + update(fs, args[i]); + } + break; + case lsdir: + path = fs.getPath(args[2]); + final String fStr = (args.length > 3)?args[3]:""; + DirectoryStream<Path> ds = path.newDirectoryStream( + new DirectoryStream.Filter<Path>() { + public boolean accept(Path path) { + return path.toString().contains(fStr); + } + }); + for (Path p : ds) + System.out.println(p); + break; + case mkdir: + fs.getPath(args[2]).createDirectory(); + break; + case mkdirs: + mkdirs(fs.getPath(args[2])); + break; + case attrs2: + for (int i = 2; i < args.length; i++) { + path = fs.getPath(args[i]); + System.out.println("-------(1)---------"); + System.out.println( + Attributes.readBasicFileAttributes(path).toString()); + System.out.println("-------(2)---------"); + Map<String, ?> map = path.readAttributes("zip:*"); + for (Map.Entry<String, ?> e : map.entrySet()) { + System.out.printf(" %s : %s%n", e.getKey(), e.getValue()); + } + System.out.println("-------(3)---------"); + map = path.readAttributes("size,lastModifiedTime,isDirectory"); + for (Map.Entry<String, ?> e : map.entrySet()) { + System.out.printf(" %s : %s%n", e.getKey(), e.getValue()); + } + } + break; + } + } catch (Exception x) { + x.printStackTrace(); + } finally { + if (fs != null) + fs.close(); + } + } + + private static byte[] getBytes(String name) { + return name.getBytes(); + } + + private static String getString(byte[] name) { + return new String(name); + } + + private static void walk(Path path) throws IOException + { + Files.walkFileTree( + path, + new SimpleFileVisitor<Path>() { + private int indent = 0; + private void indent() { + int n = 0; + while (n++ < indent) + System.out.printf(" "); + } + + @Override + public FileVisitResult visitFile(Path file, + BasicFileAttributes attrs) + { + indent(); + System.out.printf("%s%n", file.getName().toString()); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult preVisitDirectory(Path dir, + BasicFileAttributes attrs) + { + indent(); + System.out.printf("[%s]%n", dir.toString()); + indent += 2; + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, + IOException ioe) + { + indent -= 2; + return FileVisitResult.CONTINUE; + } + }); + } + + private static void update(FileSystem fs, String path) throws Throwable{ + Path src = FileSystems.getDefault().getPath(path); + if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) { + DirectoryStream<Path> ds = src.newDirectoryStream(); + for (Path child : ds) + update(fs, child.toString()); + ds.close(); + } else { + Path dst = fs.getPath(path); + Path parent = dst.getParent(); + if (parent != null && parent.notExists()) + mkdirs(parent); + src.copyTo(dst, REPLACE_EXISTING); + } + } + + private static void extract(FileSystem fs, String path) throws Throwable{ + Path src = fs.getPath(path); + if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) { + DirectoryStream<Path> ds = src.newDirectoryStream(); + for (Path child : ds) + extract(fs, child.toString()); + ds.close(); + } else { + if (path.startsWith("/")) + path = path.substring(1); + Path dst = FileSystems.getDefault().getPath(path); + Path parent = dst.getParent(); + if (parent.notExists()) + mkdirs(parent); + src.copyTo(dst, REPLACE_EXISTING); + } + } + + // use DirectoryStream + private static void z2zcopy(FileSystem src, FileSystem dst, String path) + throws IOException + { + Path srcPath = src.getPath(path); + Path dstPath = dst.getPath(path); + + if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) { + if (!dstPath.exists()) { + try { + mkdirs(dstPath); + } catch (FileAlreadyExistsException x) {} + } + DirectoryStream<Path> ds = srcPath.newDirectoryStream(); + for (Path child : ds) { + z2zcopy(src, dst, + path + (path.endsWith("/")?"":"/") + child.getName()); + } + ds.close(); + } else { + //System.out.println("copying..." + path); + srcPath.copyTo(dstPath); + } + } + + // use TreeWalk to move + private static void z2zmove(FileSystem src, FileSystem dst, String path) + throws IOException + { + final Path srcPath = src.getPath(path).toAbsolutePath(); + final Path dstPath = dst.getPath(path).toAbsolutePath(); + + Files.walkFileTree(srcPath, new SimpleFileVisitor<Path>() { + + @Override + public FileVisitResult visitFile(Path file, + BasicFileAttributes attrs) + { + Path dst = srcPath.relativize(file); + dst = dstPath.resolve(dst); + try { + Path parent = dstPath.getParent(); + if (parent != null && parent.notExists()) + mkdirs(parent); + file.moveTo(dst); + } catch (IOException x) { + x.printStackTrace(); + } + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult preVisitDirectory(Path dir, + BasicFileAttributes attrs) + { + Path dst = srcPath.relativize(dir); + dst = dstPath.resolve(dst); + try { + + if (dst.notExists()) + mkdirs(dst); + } catch (IOException x) { + x.printStackTrace(); + } + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, + IOException ioe) + throws IOException + { + try { + dir.delete(); + } catch (IOException x) { + //x.printStackTrace(); + } + return FileVisitResult.CONTINUE; + } + }); + + } + + private static void mkdirs(Path path) throws IOException { + path = path.toAbsolutePath(); + Path parent = path.getParent(); + if (parent != null) { + if (parent.notExists()) + mkdirs(parent); + } + path.createDirectory(); + } + + private static void rmdirs(Path path) throws IOException { + while (path != null && path.getNameCount() != 0) { + path.delete(); + path = path.getParent(); + } + } + + private static void list(Path path, boolean verbose ) throws IOException { + if (verbose) + System.out.println(Attributes.readBasicFileAttributes(path).toString()); + else + System.out.printf(" %s%n", path.toString()); + if (path.notExists()) + return; + if (Attributes.readBasicFileAttributes(path).isDirectory()) { + DirectoryStream<Path> ds = path.newDirectoryStream(); + for (Path child : ds) + list(child, verbose); + ds.close(); + } + } + + // check the content of two paths are equal + private static void checkEqual(Path src, Path dst) throws IOException + { + //System.out.printf("checking <%s> vs <%s>...%n", + // src.toString(), dst.toString()); + + //streams + InputStream isSrc = src.newInputStream(); + InputStream isDst = dst.newInputStream(); + byte[] bufSrc = new byte[8192]; + byte[] bufDst = new byte[8192]; + + try { + int nSrc = 0; + while ((nSrc = isSrc.read(bufSrc)) != -1) { + int nDst = 0; + while (nDst < nSrc) { + int n = isDst.read(bufDst, nDst, nSrc - nDst); + if (n == -1) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + nDst += n; + } + while (--nSrc >= 0) { + if (bufSrc[nSrc] != bufDst[nSrc]) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + nSrc--; + } + } + } finally { + isSrc.close(); + isDst.close(); + } + + // channels + SeekableByteChannel chSrc = src.newByteChannel(); + SeekableByteChannel chDst = dst.newByteChannel(); + if (chSrc.size() != chDst.size()) { + System.out.printf("src[%s].size=%d, dst[%s].size=%d%n", + chSrc.toString(), chSrc.size(), + chDst.toString(), chDst.size()); + throw new RuntimeException("CHECK FAILED!"); + } + ByteBuffer bbSrc = ByteBuffer.allocate(8192); + ByteBuffer bbDst = ByteBuffer.allocate(8192); + + try { + int nSrc = 0; + while ((nSrc = chSrc.read(bbSrc)) != -1) { + int nDst = chDst.read(bbDst); + if (nSrc != nDst) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + while (--nSrc >= 0) { + if (bbSrc.get(nSrc) != bbDst.get(nSrc)) { + System.out.printf("checking <%s> vs <%s>...%n", + src.toString(), dst.toString()); + throw new RuntimeException("CHECK FAILED!"); + } + nSrc--; + } + bbSrc.flip(); + bbDst.flip(); + } + } catch (IOException x) { + x.printStackTrace(); + } finally { + chSrc.close(); + chDst.close(); + } + } + + private static void fchCopy(Path src, Path dst) throws IOException + { + Set<OpenOption> read = new HashSet<>(); + read.add(READ); + Set<OpenOption> openwrite = new HashSet<>(); + openwrite.add(CREATE_NEW); + openwrite.add(WRITE); + + FileChannel srcFc = src.getFileSystem() + .provider() + .newFileChannel(src, read); + FileChannel dstFc = dst.getFileSystem() + .provider() + .newFileChannel(dst, openwrite); + + try { + ByteBuffer bb = ByteBuffer.allocate(8192); + while (srcFc.read(bb) >= 0) { + bb.flip(); + dstFc.write(bb); + bb.clear(); + } + } finally { + srcFc.close(); + dstFc.close(); + } + } + + private static void chCopy(Path src, Path dst) throws IOException + { + Set<OpenOption> read = new HashSet<>(); + read.add(READ); + Set<OpenOption> openwrite = new HashSet<>(); + openwrite.add(CREATE_NEW); + openwrite.add(WRITE); + + SeekableByteChannel srcCh = src.newByteChannel(read); + SeekableByteChannel dstCh = dst.newByteChannel(openwrite); + + try { + ByteBuffer bb = ByteBuffer.allocate(8192); + while (srcCh.read(bb) >= 0) { + bb.flip(); + dstCh.write(bb); + bb.clear(); + } + } finally { + srcCh.close(); + dstCh.close(); + } + } + + private static void streamCopy(Path src, Path dst) throws IOException + { + InputStream isSrc = src.newInputStream(); + OutputStream osDst = dst.newOutputStream(); + byte[] buf = new byte[8192]; + try { + int n = 0; + while ((n = isSrc.read(buf)) != -1) { + osDst.write(buf, 0, n); + } + } finally { + isSrc.close(); + osDst.close(); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/demo/nio/zipfs/META-INF/services/java.nio.file.spi.FileSystemProvider Tue Oct 26 14:43:21 2010 -0400 @@ -0,0 +1,3 @@ +com.sun.nio.zipfs.ZipFileSystemProvider +com.sun.nio.zipfs.JarFileSystemProvider +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/demo/nio/zipfs/README.txt Tue Oct 26 14:43:21 2010 -0400 @@ -0,0 +1,29 @@ +ZipFileSystem is a file system provider that treats the contents of a zip or +JAR file as a java.nio.file.FileSystem. + +To deploy the provider you must copy zipfs.jar into your extensions +directory or else add <JDK_HOME>/demo/nio/ZipFileSystem/zipfs.jar +to your class path. + +The factory methods defined by the java.nio.file.FileSystems class can be +used to create a FileSystem, eg: + + // use file type detection + Map<String,?> env = Collections.emptyMap(); + Path jarfile = Path.get("foo.jar"); + FileSystem fs = FileSystems.newFileSystem(jarfile, env); + +-or + + // locate file system by URI + Map<String,?> env = Collections.emptyMap(); + URI uri = URI.create("zip:///mydir/foo.jar"); + FileSystem fs = FileSystems.newFileSystem(uri, env); + +Once a FileSystem is created then classes in the java.nio.file package +can be used to access files in the zip/JAR file, eg: + + Path mf = fs.getPath("/META-INF/MANIFEST.MF"); + InputStream in = mf.newInputStream(); + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/JarFileSystemProvider.java Tue Oct 26 14:43:21 2010 -0400 @@ -0,0 +1,71 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Sun Microsystems nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.sun.nio.zipfs; + +import java.nio.file.*; +import java.nio.file.spi.*; +import java.nio.file.attribute.*; +import java.nio.file.spi.FileSystemProvider; + +import java.net.URI; +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.channels.FileChannel; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public class JarFileSystemProvider extends ZipFileSystemProvider +{ + + @Override + public String getScheme() { + return "jar"; + } + + @Override + protected Path uriToPath(URI uri) { + String scheme = uri.getScheme(); + if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) { + throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'"); + } + try { + String uristr = uri.toString(); + int end = uristr.indexOf("!/"); + uristr = uristr.substring(4, (end == -1) ? uristr.length() : end); + uri = new URI(uristr); + return Paths.get(new URI("file", uri.getHost(), uri.getPath(), null)) + .toAbsolutePath(); + } catch (URISyntaxException e) { + throw new AssertionError(e); //never thrown + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipCoder.java Tue Oct 26 14:43:21 2010 -0400 @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.sun.nio.zipfs; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CoderResult; +import java.nio.charset.CodingErrorAction; +import java.util.Arrays; + +/** + * Utility class for zipfile name and comment decoding and encoding + * + * @author Xueming Shen + */ + +final class ZipCoder { + + String toString(byte[] ba, int length) { + CharsetDecoder cd = decoder().reset(); + int len = (int)(length * cd.maxCharsPerByte()); + char[] ca = new char[len]; + if (len == 0) + return new String(ca); + ByteBuffer bb = ByteBuffer.wrap(ba, 0, length); + CharBuffer cb = CharBuffer.wrap(ca); + CoderResult cr = cd.decode(bb, cb, true); + if (!cr.isUnderflow()) + throw new IllegalArgumentException(cr.toString()); + cr = cd.flush(cb); + if (!cr.isUnderflow()) + throw new IllegalArgumentException(cr.toString()); + return new String(ca, 0, cb.position()); + } + + String toString(byte[] ba) { + return toString(ba, ba.length); + } + + byte[] getBytes(String s) { + CharsetEncoder ce = encoder().reset(); + char[] ca = s.toCharArray(); + int len = (int)(ca.length * ce.maxBytesPerChar()); + byte[] ba = new byte[len]; + if (len == 0) + return ba; + ByteBuffer bb = ByteBuffer.wrap(ba); + CharBuffer cb = CharBuffer.wrap(ca); + CoderResult cr = ce.encode(cb, bb, true); + if (!cr.isUnderflow()) + throw new IllegalArgumentException(cr.toString()); + cr = ce.flush(bb); + if (!cr.isUnderflow()) + throw new IllegalArgumentException(cr.toString()); + if (bb.position() == ba.length) // defensive copy? + return ba; + else + return Arrays.copyOf(ba, bb.position()); + } + + // assume invoked only if "this" is not utf8 + byte[] getBytesUTF8(String s) { + if (isutf8) + return getBytes(s); + if (utf8 == null) + utf8 = new ZipCoder(Charset.forName("UTF-8")); + return utf8.getBytes(s); + } + + String toStringUTF8(byte[] ba, int len) { + if (isutf8) + return toString(ba, len); + if (utf8 == null) + utf8 = new ZipCoder(Charset.forName("UTF-8")); + return utf8.toString(ba, len); + } + + boolean isUTF8() { + return isutf8; + } + + private Charset cs; + private boolean isutf8; + private ZipCoder utf8; + + private ZipCoder(Charset cs) { + this.cs = cs; + this.isutf8 = cs.name().equals("UTF-8"); + } + + static ZipCoder get(Charset charset) { + return new ZipCoder(charset); + } + + static ZipCoder get(String csn) { + try { + return new ZipCoder(Charset.forName(csn)); + } catch (Throwable t) { + t.printStackTrace(); + } + return new ZipCoder(Charset.defaultCharset()); + } + + private final ThreadLocal<CharsetDecoder> decTL = new ThreadLocal<>(); + private final ThreadLocal<CharsetEncoder> encTL = new ThreadLocal<>(); + + private CharsetDecoder decoder() { + CharsetDecoder dec = decTL.get(); + if (dec == null) { + dec = cs.newDecoder() + .onMalformedInput(CodingErrorAction.REPORT) + .onUnmappableCharacter(CodingErrorAction.REPORT); + decTL.set(dec); + } + return dec; + } + + private CharsetEncoder encoder() { + CharsetEncoder enc = encTL.get(); + if (enc == null) { + enc = cs.newEncoder() + .onMalformedInput(CodingErrorAction.REPORT) + .onUnmappableCharacter(CodingErrorAction.REPORT); + encTL.set(enc); + } + return enc; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipConstants.java Tue Oct 26 14:43:21 2010 -0400 @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.sun.nio.zipfs; + +import java.nio.ByteBuffer; + +/** + * + * @author Xueming Shen + */ + +class ZipConstants { + /* + * Compression methods + */ + static final int METHOD_STORED = 0; + static final int METHOD_DEFLATED = 8; + static final int METHOD_DEFLATED64 = 9; + static final int METHOD_BZIP2 = 12; + static final int METHOD_LZMA = 14; + static final int METHOD_LZ77 = 19; + + /* + * General purpose big flag + */ + static final int FLAG_ENCRYPTED = 0x01; + static final int FLAG_DATADESCR = 0x08; // crc, size and csize in dd + static final int FLAG_EFS = 0x800; // If this bit is set the filename and + // comment fields for this file must be + // encoded using UTF-8. + /* + * Header signatures + */ + static long LOCSIG = 0x04034b50L; // "PK\003\004" + static long EXTSIG = 0x08074b50L; // "PK\007\008" + static long CENSIG = 0x02014b50L; // "PK\001\002" + static long ENDSIG = 0x06054b50L; // "PK\005\006" + + /* + * Header sizes in bytes (including signatures) + */ + static final int LOCHDR = 30; // LOC header size + static final int EXTHDR = 16; // EXT header size + static final int CENHDR = 46; // CEN header size + static final int ENDHDR = 22; // END header size + + /* + * Local file (LOC) header field offsets + */ + static final int LOCVER = 4; // version needed to extract + static final int LOCFLG = 6; // general purpose bit flag + static final int LOCHOW = 8; // compression method + static final int LOCTIM = 10; // modification time + static final int LOCCRC = 14; // uncompressed file crc-32 value + static final int LOCSIZ = 18; // compressed size + static final int LOCLEN = 22; // uncompressed size + static final int LOCNAM = 26; // filename length + static final int LOCEXT = 28; // extra field length + + /* + * Extra local (EXT) header field offsets + */ + static final int EXTCRC = 4; // uncompressed file crc-32 value + static final int EXTSIZ = 8; // compressed size + static final int EXTLEN = 12; // uncompressed size + + /* + * Central directory (CEN) header field offsets + */ + static final int CENVEM = 4; // version made by + static final int CENVER = 6; // version needed to extract + static final int CENFLG = 8; // encrypt, decrypt flags + static final int CENHOW = 10; // compression method + static final int CENTIM = 12; // modification time + static final int CENCRC = 16; // uncompressed file crc-32 value + static final int CENSIZ = 20; // compressed size + static final int CENLEN = 24; // uncompressed size + static final int CENNAM = 28; // filename length + static final int CENEXT = 30; // extra field length + static final int CENCOM = 32; // comment length + static final int CENDSK = 34; // disk number start + static final int CENATT = 36; // internal file attributes + static final int CENATX = 38; // external file attributes + static final int CENOFF = 42; // LOC header offset + + /* + * End of central directory (END) header field offsets + */ + static final int ENDSUB = 8; // number of entries on this disk + static final int ENDTOT = 10; // total number of entries + static final int ENDSIZ = 12; // central directory size in bytes + static final int ENDOFF = 16; // offset of first CEN header + static final int ENDCOM = 20; // zip file comment length + + /* + * ZIP64 constants + */ + static final long ZIP64_ENDSIG = 0x06064b50L; // "PK\006\006" + static final long ZIP64_LOCSIG = 0x07064b50L; // "PK\006\007" + static final int ZIP64_ENDHDR = 56; // ZIP64 end header size + static final int ZIP64_LOCHDR = 20; // ZIP64 end loc header size + static final int ZIP64_EXTHDR = 24; // EXT header size + static final int ZIP64_EXTID = 0x0001; // Extra field Zip64 header ID + + static final int ZIP64_MINVAL32 = 0xFFFF; + static final long ZIP64_MINVAL = 0xFFFFFFFFL; + + /* + * Zip64 End of central directory (END) header field offsets + */ + static final int ZIP64_ENDLEN = 4; // size of zip64 end of central dir + static final int ZIP64_ENDVEM = 12; // version made by + static final int ZIP64_ENDVER = 14; // version needed to extract + static final int ZIP64_ENDNMD = 16; // number of this disk + static final int ZIP64_ENDDSK = 20; // disk number of start + static final int ZIP64_ENDTOD = 24; // total number of entries on this disk + static final int ZIP64_ENDTOT = 32; // total number of entries + static final int ZIP64_ENDSIZ = 40; // central directory size in bytes + static final int ZIP64_ENDOFF = 48; // offset of first CEN header + static final int ZIP64_ENDEXT = 56; // zip64 extensible data sector + + /* + * Zip64 End of central directory locator field offsets + */ + static final int ZIP64_LOCDSK = 4; // disk number start + static final int ZIP64_LOCOFF = 8; // offset of zip64 end + static final int ZIP64_LOCTOT = 16; // total number of disks + + /* + * Zip64 Extra local (EXT) header field offsets + */ + static final int ZIP64_EXTCRC = 4; // uncompressed file crc-32 value + static final int ZIP64_EXTSIZ = 8; // compressed size, 8-byte + static final int ZIP64_EXTLEN = 16; // uncompressed size, 8-byte + + /* + * Extra field header ID + */ + static final int EXTID_ZIP64 = 0x0001; // ZIP64 + static final int EXTID_NTFS = 0x000a; // NTFS + static final int EXTID_UNIX = 0x000d; // UNIX + + + /* + * fields access methods + */ + /////////////////////////////////////////////////////// + static final int CH(byte[] b, int n) { + return b[n] & 0xff; + } + + static final int SH(byte[] b, int n) { + return (b[n] & 0xff) | ((b[n + 1] & 0xff) << 8); + } + + static final long LG(byte[] b, int n) { + return ((SH(b, n)) | (SH(b, n + 2) << 16)) & 0xffffffffL; + } + + static final long LL(byte[] b, int n) { + return (LG(b, n)) | (LG(b, n + 4) << 32); + } + + static final long GETSIG(byte[] b) { + return LG(b, 0); + } + + // local file (LOC) header fields + static final long LOCSIG(byte[] b) { return LG(b, 0); } // signature + static final int LOCVER(byte[] b) { return SH(b, 4); } // version needed to extract + static final int LOCFLG(byte[] b) { return SH(b, 6); } // general purpose bit flags + static final int LOCHOW(byte[] b) { return SH(b, 8); } // compression method + static final long LOCTIM(byte[] b) { return LG(b, 10);} // modification time + static final long LOCCRC(byte[] b) { return LG(b, 14);} // crc of uncompressed data + static final long LOCSIZ(byte[] b) { return LG(b, 18);} // compressed data size + static final long LOCLEN(byte[] b) { return LG(b, 22);} // uncompressed data size + static final int LOCNAM(byte[] b) { return SH(b, 26);} // filename length + static final int LOCEXT(byte[] b) { return SH(b, 28);} // extra field length + + // extra local (EXT) header fields + static final long EXTCRC(byte[] b) { return LG(b, 4);} // crc of uncompressed data + static final long EXTSIZ(byte[] b) { return LG(b, 8);} // compressed size + static final long EXTLEN(byte[] b) { return LG(b, 12);} // uncompressed size + + // end of central directory header (END) fields + static final int ENDSUB(byte[] b) { return SH(b, 8); } // number of entries on this disk + static final int ENDTOT(byte[] b) { return SH(b, 10);} // total number of entries + static final long ENDSIZ(byte[] b) { return LG(b, 12);} // central directory size + static final long ENDOFF(byte[] b) { return LG(b, 16);} // central directory offset + static final int ENDCOM(byte[] b) { return SH(b, 20);} // size of zip file comment + static final int ENDCOM(byte[] b, int off) { return SH(b, off + 20);} + + // zip64 end of central directory recoder fields + static final long ZIP64_ENDTOD(byte[] b) { return LL(b, 24);} // total number of entries on disk + static final long ZIP64_ENDTOT(byte[] b) { return LL(b, 32);} // total number of entries + static final long ZIP64_ENDSIZ(byte[] b) { return LL(b, 40);} // central directory size + static final long ZIP64_ENDOFF(byte[] b) { return LL(b, 48);} // central directory offset + static final long ZIP64_LOCOFF(byte[] b) { return LL(b, 8);} // zip64 end offset + + ////////////////////////////////////////// + static final int CH(ByteBuffer b, int pos) { + return b.get(pos) & 0xff; + } + static final int SH(ByteBuffer b, int pos) { + return b.getShort(pos) & 0xffff; + } + static final long LG(ByteBuffer b, int pos) { + return b.getInt(pos) & 0xffffffffL; + } + + // central directory header (END) fields + static final long CENSIG(ByteBuffer b, int pos) { return LG(b, pos + 0); } + static final int CENVEM(ByteBuffer b, int pos) { return SH(b, pos + 4); } + static final int CENVER(ByteBuffer b, int pos) { return SH(b, pos + 6); } + static final int CENFLG(ByteBuffer b, int pos) { return SH(b, pos + 8); } + static final int CENHOW(ByteBuffer b, int pos) { return SH(b, pos + 10);} + static final long CENTIM(ByteBuffer b, int pos) { return LG(b, pos + 12);} + static final long CENCRC(ByteBuffer b, int pos) { return LG(b, pos + 16);} + static final long CENSIZ(ByteBuffer b, int pos) { return LG(b, pos + 20);} + static final long CENLEN(ByteBuffer b, int pos) { return LG(b, pos + 24);} + static final int CENNAM(ByteBuffer b, int pos) { return SH(b, pos + 28);} + static final int CENEXT(ByteBuffer b, int pos) { return SH(b, pos + 30);} + static final int CENCOM(ByteBuffer b, int pos) { return SH(b, pos + 32);} + static final int CENDSK(ByteBuffer b, int pos) { return SH(b, pos + 34);} + static final int CENATT(ByteBuffer b, int pos) { return SH(b, pos + 36);} + static final long CENATX(ByteBuffer b, int pos) { return LG(b, pos + 38);} + static final long CENOFF(ByteBuffer b, int pos) { return LG(b, pos + 42);} + + /* The END header is followed by a variable length comment of size < 64k. */ + static final long END_MAXLEN = 0xFFFF + ENDHDR; + static final int READBLOCKSZ = 128; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipDirectoryStream.java Tue Oct 26 14:43:21 2010 -0400 @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.sun.nio.zipfs; + +import ja