diff --git a/.hgtags b/.hgtags index 898e4a75668c25e209d91df689d7d6463da590b1..6eaa20bbab7adc13b0fbd4d568d9af3feeb9476a 100644 --- a/.hgtags +++ b/.hgtags @@ -1 +1,2 @@ 37a05a11f281b4d238e2f9e7ebb67c63f64d0e77 jdk7-b24 +75fca0b0ab83ab1392e615910cea020f66535390 jdk7-b25 diff --git a/make/common/Defs-linux.gmk b/make/common/Defs-linux.gmk index 51d638f96ab8f66a0b259565bb0540b15cf10254..674b6f6a0e69717974b92813bdf24b98410d16e3 100644 --- a/make/common/Defs-linux.gmk +++ b/make/common/Defs-linux.gmk @@ -50,13 +50,13 @@ CC_DEPEND = -MM CC_DEPEND_FILTER = $(SED) -e 's!$*\.$(OBJECT_SUFFIX)!$(dir $@)& $(dir $@)$*.$(DEPEND_SUFFIX)!g' ifndef PLATFORM_SRC - PLATFORM_SRC = $(JDK_TOPDIR)/src/solaris + PLATFORM_SRC = $(BUILDDIR)/../src/solaris endif # PLATFORM_SRC # Platform specific closed sources ifndef OPENJDK ifndef CLOSED_PLATFORM_SRC - CLOSED_PLATFORM_SRC = $(JDK_TOPDIR)/src/closed/solaris + CLOSED_PLATFORM_SRC = $(BUILDDIR)/../src/closed/solaris endif endif diff --git a/make/common/Defs-solaris.gmk b/make/common/Defs-solaris.gmk index 800c0b75ddbe2b90ebc06e76f82282c28dab19dd..052c0c88fc810b9ea7fcd0102709e980c9ca4d4b 100644 --- a/make/common/Defs-solaris.gmk +++ b/make/common/Defs-solaris.gmk @@ -45,13 +45,13 @@ include $(JDK_MAKE_SHARED_DIR)/Defs.gmk ifndef PLATFORM_SRC -PLATFORM_SRC = $(JDK_TOPDIR)/src/solaris +PLATFORM_SRC = $(BUILDDIR)/../src/solaris endif # PLATFORM_SRC # Platform specific closed sources ifndef OPENJDK ifndef CLOSED_PLATFORM_SRC - CLOSED_PLATFORM_SRC = $(JDK_TOPDIR)/src/closed/solaris + CLOSED_PLATFORM_SRC = $(BUILDDIR)/../src/closed/solaris endif endif diff --git a/make/common/Defs-windows.gmk b/make/common/Defs-windows.gmk index 6f53eb72f3bb52ea25fef3d72227c1579390a759..e9bdea85278ecaab844c89f706c817bf813f60a1 100644 --- a/make/common/Defs-windows.gmk +++ b/make/common/Defs-windows.gmk @@ -51,13 +51,13 @@ ifndef LIB_LOCATION endif # LIB_LOCATION ifndef PLATFORM_SRC - PLATFORM_SRC = $(JDK_TOPDIR)/src/windows + PLATFORM_SRC = $(BUILDDIR)/../src/windows endif # PLATFORM_SRC # Platform specific closed sources ifndef OPENJDK ifndef CLOSED_PLATFORM_SRC - CLOSED_PLATFORM_SRC = $(JDK_TOPDIR)/src/closed/windows + CLOSED_PLATFORM_SRC = $(BUILDDIR)/../src/closed/windows endif endif @@ -367,7 +367,7 @@ else endif # Settings for the VERSIONINFO tap on windows. -VERSIONINFO_RESOURCE = $(JDK_TOPDIR)/src/windows/resource/version.rc +VERSIONINFO_RESOURCE = $(BUILDDIR)/../src/windows/resource/version.rc ifneq ($(JDK_BUILD_NUMBER),) COOKED_BUILD_NUMBER = $(shell $(ECHO) $(JDK_BUILD_NUMBER) | $(SED) -e 's/^b//' -e 's/^0//') diff --git a/make/common/Defs.gmk b/make/common/Defs.gmk index 9dd781b2f7e428fe4547437b833a42f0e5c4917a..268533ba608e8af13ba656b52203422e289804d0 100644 --- a/make/common/Defs.gmk +++ b/make/common/Defs.gmk @@ -32,6 +32,13 @@ # So when it includes other files, it must use JDK_TOPDIR. # +# Check for strange explicit settings (change to empty or true) +ifdef OPENJDK + ifneq ($(OPENJDK),true) + x:=$(error "OPENJDK (if defined) can only be set to true") + endif +endif + # # On Solaris, the 'make' utility from Sun will not work with these makefiles. # This little rule is only understood by Sun's make, and is harmless @@ -41,7 +48,15 @@ SUN_MAKE_TEST:sh = echo "ERROR: PLEASE USE GNU VERSION OF MAKE"; exit 33 ifndef JDK_TOPDIR - JDK_TOPDIR=$(BUILDDIR)/.. + ifdef BUILDDIR + JDK_TOPDIR=$(BUILDDIR)/.. + else + JDK_TOPDIR:=$(error "ERROR: Cannot define top of jdk repository") + endif +endif +ifndef BUILDDIR + # Hack, due to deploy repository using this file. + BUILDDIR=$(JDK_TOPDIR)/make endif ifndef JDK_MAKE_SHARED_DIR JDK_MAKE_SHARED_DIR=$(JDK_TOPDIR)/make/common/shared @@ -59,13 +74,13 @@ include $(JDK_TOPDIR)/make/common/CancelImplicits.gmk # there yet. # ifndef SHARE_SRC - SHARE_SRC = $(JDK_TOPDIR)/src/share + SHARE_SRC = $(BUILDDIR)/../src/share endif # Files that cannot be included in the OpenJDK distribution are # collected under a parent directory which contains just those files. ifndef CLOSED_SRC - CLOSED_SRC = $(JDK_TOPDIR)/src/closed + CLOSED_SRC = $(BUILDDIR)/../src/closed endif # If we have no closed directory, force it to an openjdk build @@ -79,19 +94,6 @@ ifeq ($(CLOSED_SRC_DIR_EXISTS), false) OPENJDK = true endif -# Check for strange explicit settings (change to empty or true) -ifdef OPENJDK - ifeq ($(OPENJDK),false) - # Silently treat as not defined - OPENJDK = - else - ifneq ($(OPENJDK),true) - dummy := $(warning "WARNING: OPENKJDK=$(OPENJDK) being treated as true") - OPENJDK = true - endif - endif -endif - # Define where closed directories are ifdef OPENJDK CLOSED_SRC = @@ -170,14 +172,6 @@ ifdef OPENJDK endif endif # OPENJDK -# Default output directory -ifdef OPENJDK -_OUTPUTDIR=$(JDK_TOPDIR)/build/$(PLATFORM)-$(ARCH)$(OPENJDK_SUFFIX) -else -_OUTPUTDIR=$(JDK_TOPDIR)/build/$(PLATFORM)-$(ARCH) -endif - - # # Get platform definitions # diff --git a/make/common/shared/Defs-control.gmk b/make/common/shared/Defs-control.gmk index ec94a2ed7ae031df100e4b03d989ddd3f1cabd68..172166aed919a0fe3f51ef985ef55ede9e44553d 100644 --- a/make/common/shared/Defs-control.gmk +++ b/make/common/shared/Defs-control.gmk @@ -36,7 +36,7 @@ ifndef JDK_MAKE_SHARED_DIR endif ifndef CONTROL_TOPDIR - CONTROL_TOPDIR=$(TOPDIR)/control + CONTROL_TOPDIR=$(TOPDIR) endif ifndef HOTSPOT_TOPDIR HOTSPOT_TOPDIR=$(TOPDIR)/hotspot @@ -70,7 +70,8 @@ endif include $(JDK_MAKE_SHARED_DIR)/Platform.gmk # Default output directory -_OUTPUTDIR=$(CONTROL_TOPDIR)/build/$(PLATFORM)-$(ARCH) +BUILD_PARENT_DIRECTORY=$(TOPDIR) +_OUTPUTDIR=$(TOPDIR)/build/$(PLATFORM)-$(ARCH) # Get platform specific settings include $(JDK_MAKE_SHARED_DIR)/Defs.gmk diff --git a/make/common/shared/Defs-utils.gmk b/make/common/shared/Defs-utils.gmk index dc84d795b7616d8e992674f63373aa5cebd3b5c8..3886ee65ce4af7f965a2be12bb6c83c94a5a75cb 100644 --- a/make/common/shared/Defs-utils.gmk +++ b/make/common/shared/Defs-utils.gmk @@ -67,16 +67,6 @@ ifeq ($(PLATFORM),windows) UTILS_DEVTOOL_PATH=$(DEVTOOLS_PATH) endif -# Utilities ant and findbugs -ifndef ANT_HOME - ANT_HOME = $(JDK_DEVTOOLS_DIR)/share/ant/latest -endif -ANT = $(ANT_HOME)/bin/ant -ifndef FINDBUGS_HOME - FINDBUGS_HOME = $(JDK_DEVTOOLS_DIR)/share/findbugs/latest -endif -FINDBUGS = $(FINDBUGS_HOME)/bin/findbugs - # Utilities ADB = $(UTILS_COMMAND_PATH)adb AR = $(UTILS_CCS_BIN_PATH)ar diff --git a/make/common/shared/Defs.gmk b/make/common/shared/Defs.gmk index c2a8278bddf13ce75b88684b98311fed1dc2bd84..6b0adfcb533b52800edb6f7dcc93aab0d3b2d1d3 100644 --- a/make/common/shared/Defs.gmk +++ b/make/common/shared/Defs.gmk @@ -55,7 +55,10 @@ include $(JDK_MAKE_SHARED_DIR)/Defs-utils.gmk # Simple pwd path define PwdPath -$(shell cd $1 2> $(DEV_NULL) && pwd) +$(shell $(CD) $1 2> $(DEV_NULL) && $(PWD)) +endef +define AbsPwdPathCheck +$(shell $(CD) .. 2> $(DEV_NULL) && $(CD) $1 2> $(DEV_NULL) && $(PWD)) endef # Checks an ALT value for spaces (should be one word), @@ -422,23 +425,54 @@ CACERTS_FILE:=$(call AltCheckSpaces,CACERTS_FILE) CACERTS_FILE:=$(call AltCheckValue,CACERTS_FILE) # OUTPUTDIR: Location of all output for the build -_BACKUP_OUTPUTDIR = $(TEMP_DISK)/$(USER)/jdk-outputdir ifdef ALT_OUTPUTDIR - _POSSIBLE_OUTPUTDIR =$(subst \,/,$(ALT_OUTPUTDIR)) + OUTPUTDIR:=$(subst \,/,$(ALT_OUTPUTDIR)) + # Assumes this is absolute (checks later) + ABS_OUTPUTDIR:=$(OUTPUTDIR) else ifndef _OUTPUTDIR - _OUTPUTDIR = $(_BACKUP_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 - _POSSIBLE_OUTPUTDIR =$(_OUTPUTDIR) -endif -_create_outputdir1:=$(shell mkdir -p $(_POSSIBLE_OUTPUTDIR) > $(DEV_NULL) 2>&1) -OUTPUTDIR:=$(call WriteDirExists,$(_POSSIBLE_OUTPUTDIR),$(_BACKUP_OUTPUTDIR)) -_create_outputdir2:=$(shell mkdir -p $(OUTPUTDIR) > $(DEV_NULL) 2>&1) -ifeq "$(OUTPUTDIR)" "$(_BACKUP_OUTPUTDIR)" - _outputdir_warning:=$(warning "WARNING: OUTPUTDIR '$(_POSSIBLE_OUTPUTDIR)' not writable, will use '$(_BACKUP_OUTPUTDIR)'") + OUTPUTDIR:=$(_OUTPUTDIR) endif +# Check for spaces and null value OUTPUTDIR:=$(call AltCheckSpaces,OUTPUTDIR) OUTPUTDIR:=$(call AltCheckValue,OUTPUTDIR) +# Create the output directory and make sure it exists and is writable +_create_outputdir:=$(shell $(MKDIR) -p "$(OUTPUTDIR)" > $(DEV_NULL) 2>&1) +ifeq ($(call WriteDirExists,$(OUTPUTDIR),/dev/null),/dev/null) + _outputdir_error:=$(error "ERROR: OUTPUTDIR '$(OUTPUTDIR)' not created or not writable") +endif +# Define absolute path if needed and check for spaces and null value +ifndef ABS_OUTPUTDIR + ABS_OUTPUTDIR:=$(call FullPath,$(OUTPUTDIR)) +endif +ABS_OUTPUTDIR:=$(call AltCheckSpaces,ABS_OUTPUTDIR) +ABS_OUTPUTDIR:=$(call AltCheckValue,ABS_OUTPUTDIR) +# Make doubly sure this is a full path +ifeq ($(call AbsPwdPathCheck,$(ABS_OUTPUTDIR)), ) + ifdef ALT_OUTPUTDIR + _outputdir_error:=$(error "ERROR: Trouble with the absolute path for OUTPUTDIR '$(OUTPUTDIR)', was ALT_OUTPUTDIR '$(ALT_OUTPUTDIR)' an absolute path?") + else + _outputdir_error:=$(error "ERROR: Trouble with the absolute path for OUTPUTDIR '$(OUTPUTDIR)'") + endif +endif +_dir1:=$(call FullPath,$(ABS_OUTPUTDIR)) +_dir2:=$(call FullPath,$(OUTPUTDIR)) +ifneq ($(_dir1),$(_dir2)) + _outputdir_error:=$(error "ERROR: ABS_OUTPUTDIR '$(ABS_OUTPUTDIR)' is not the same directory as OUTPUTDIR '$(OUTPUTDIR)', '$(_dir1)'!='$(_dir2)'") +endif # Bin directory # NOTE: ISA_DIR is usually empty, on Solaris it might be /sparcv9 or /amd64 @@ -469,15 +503,30 @@ JDK_CUPS_HEADERS_PATH=$(JDK_DEVTOOLS_DIR)/share/cups/include endif endif +# Utilities ant and findbugs +ifeq ($(ANT_HOME),) + ANT_HOME := $(call DirExists,/usr/share/ant,$(JDK_DEVTOOLS_DIR)/share/ant/latest,) +endif +ifeq ($(ANT_HOME),) + ANT = ant +else + ANT = $(ANT_HOME)/bin/ant +endif +ifeq ($(FINDBUGS_HOME),) + FINDBUGS_HOME := $(call DirExists,/usr/share/findbugs,$(JDK_DEVTOOLS_DIR)/share/findbugs/latest,) +endif +ifeq ($(FINDBUGS_HOME),) + FINDBUGS = findbugs +else + FINDBUGS = $(FINDBUGS_HOME)/bin/findbugs +endif + ifdef ALT_COPYRIGHT_YEAR COPYRIGHT_YEAR = $(ALT_COPYRIGHT_YEAR) else COPYRIGHT_YEAR = $(shell $(DATE) '+%Y') endif -# Absolute path to output directory -ABS_OUTPUTDIR:=$(call FullPath,$(OUTPUTDIR)) - # Get shared compiler settings include $(JDK_MAKE_SHARED_DIR)/Compiler.gmk diff --git a/make/common/shared/Platform.gmk b/make/common/shared/Platform.gmk index f9f229a8548de54577d1f24fa150fbc82a4d90e6..32cb08e34737b10e8748fcb7480cc29194953d0b 100644 --- a/make/common/shared/Platform.gmk +++ b/make/common/shared/Platform.gmk @@ -93,20 +93,18 @@ SYSTEM_UNAME := $(shell uname) # Normal boot jdk is previous release, but a hard requirement is a 1.5 boot REQUIRED_BOOT_VER = 1.5 -#This is specific to OpenJDK build -ifdef OPENJDK - REQUIRED_FREETYPE_VERSION=2.3.0 -endif +# If we are using freetype, this is the required version +REQUIRED_FREETYPE_VERSION=2.3.0 # # Prune out all known SCM (Source Code Management) directories # so they will not be included when copying directory trees # or packaging up .jar files, etc. This applies to all workspaces. # -SCM_DIRs = .hg .svn CVS RCS SCCS Codemgr_wsdata deleted_files +SCM_DIRs = .hg .svn CVS RCS SCCS Codemgr_wsdata deleted_files .hgignore .hgtags # When changing SCM_DIRs also change SCM_DIRS_rexp and SCM_DIRS_prune: -SCM_DIRS_rexp = ".hg|.svn|CVS|RCS|SCCS|Codemgr_wsdata|deleted_files" -SCM_DIRS_prune = \( -name .hg -o -name .svn -o -name CVS -o -name RCS -o -name SCCS -o -name Codemgr_wsdata -o -name deleted_files \) -prune +SCM_DIRS_rexp = ".hg|.svn|CVS|RCS|SCCS|Codemgr_wsdata|deleted_files|.hgignore|.hgtags" +SCM_DIRS_prune = \( -name .hg -o -name .svn -o -name CVS -o -name RCS -o -name SCCS -o -name Codemgr_wsdata -o -name deleted_files -o -name .hgignore -o -name .hgtags \) -prune # Don't define this unless it's not defined ifndef VARIANT @@ -272,7 +270,7 @@ ifeq ($(SYSTEM_UNAME), Linux) REQUIRED_ALSA_VERSION = ^((0[.]9[.][1-9])|(1[.]0[.][0-9]))[0-9]* endif # How much RAM does this machine have: - MB_OF_MEMORY := $(shell free -m | fgrep Mem: | sed -e 's@\ \ *@ @g' | cut -d' ' -f2) + MB_OF_MEMORY := $(shell free -m | fgrep Mem: | awk '{print $$2;}' ) endif # Windows with and without CYGWIN will be slightly different @@ -376,45 +374,35 @@ ifeq ($(PLATFORM), windows) REQUIRED_DXSDK_VER = 0x0700 OS_VENDOR = Microsoft # How much RAM does this machine have: - MB_OF_MEMORY := $(shell \ - if [ -f "C:/cygwin/bin/free.exe" ] ; then \ - ( C:/cygwin/bin/bash.exe -c "C:/cygwin/bin/free.exe -m" ) | \ - grep Mem: | \ - sed -e 's@\ \ *@ @g' | cut -d' ' -f2 ; \ - else \ - echo "512"; \ - fi) -endif - -# Machines with 512Mb or less of real memory are considered low memory -# build machines and adjustments will be made to prevent excessing -# system swapping during the build. -# If we don't know, assume 512. Subtract 128 from MB for VM MAX. -# Don't set VM max over 1024-128=896. -ifneq ($(MB_OF_MEMORY),) - LOW_MEMORY_MACHINE := $(shell \ - if [ $(MB_OF_MEMORY) -le 512 ] ; then \ - echo "true"; \ - else \ - echo "false"; \ - fi) - MAX_VM_MEMORY := $(shell \ - if [ $(MB_OF_MEMORY) -le 1024 ] ; then \ - expr $(MB_OF_MEMORY) '-' 128 ; \ - else \ - echo "896"; \ - fi) - MIN_VM_MEMORY := $(shell \ - if [ $(MAX_VM_MEMORY) -le 128 ] ; then \ - expr $(MAX_VM_MEMORY) '-' 8 ; \ - else \ - echo "128"; \ - fi) -else - MB_OF_MEMORY := unknown - LOW_MEMORY_MACHINE := true - MAX_VM_MEMORY := 384 - MIN_VM_MEMORY := 128 + ifeq ($(USING_CYGWIN),true) + # CYGWIN has the 'free' utility + _MB_OF_MEMORY := \ + $(shell free -m | grep Mem: | awk '{print $$2;}' ) + else + # Windows 2000 has the mem utility, but two memory areas + # extended memory is what is beyond 1024M + _B_OF_EXT_MEMORY := \ + $(shell mem 2> $(DEV_NULL) | grep 'total contiguous extended memory' | awk '{print $$1;}') + ifeq ($(_B_OF_EXT_MEMORY),) + _B_OF_MEMORY := \ + $(shell mem 2> $(DEV_NULL) | grep 'total conventional memory' | awk '{print $$1;}') + else + _B_OF_MEMORY := \ + $(shell expr 1048576 '+' $(_B_OF_EXT_MEMORY) 2> $(DEV_NULL)) + endif + ifeq ($(_B_OF_MEMORY),) + # Windows 2003 has the systeminfo utility use it if mem doesn't work + _MB_OF_MEMORY := \ + $(shell systeminfo 2> $(DEV_NULL) | grep 'Total Physical Memory:' | awk '{print $$4;}' | sed -e 's@,@@') + else + _MB_OF_MEMORY := $(shell expr $(_B_OF_MEMORY) '/' 1024 2> $(DEV_NULL)) + endif + endif + ifeq ($(shell expr $(_MB_OF_MEMORY) '+' 0 2> $(DEV_NULL)), $(_MB_OF_MEMORY)) + MB_OF_MEMORY := $(_MB_OF_MEMORY) + else + MB_OF_MEMORY := 512 + endif endif REQUIRED_ZIP_VER = 2.2 @@ -454,6 +442,37 @@ ifneq ($(PLATFORM), windows) ARCH_VM_SUBDIR=jre/lib/$(LIBARCH) endif +# Machines with 512Mb or less of real memory are considered low memory +# build machines and adjustments will be made to prevent excessing +# system swapping during the build. +# If we don't know, assume 512. Subtract 128 from MB for VM MAX. +# Don't set VM max over 1024-128=896. +ifneq ($(MB_OF_MEMORY),) + LOW_MEMORY_MACHINE := $(shell \ + if [ $(MB_OF_MEMORY) -le 512 ] ; then \ + echo "true"; \ + else \ + echo "false"; \ + fi) + MAX_VM_MEMORY := $(shell \ + if [ $(MB_OF_MEMORY) -le 1024 ] ; then \ + expr $(MB_OF_MEMORY) '-' 128 2> $(DEV_NULL) ; \ + else \ + echo "896"; \ + fi) + MIN_VM_MEMORY := $(shell \ + if [ $(MAX_VM_MEMORY) -le 128 ] ; then \ + expr $(MAX_VM_MEMORY) '-' 8 2> $(DEV_NULL) ; \ + else \ + echo "128"; \ + fi) +else + MB_OF_MEMORY := unknown + LOW_MEMORY_MACHINE := true + MAX_VM_MEMORY := 384 + MIN_VM_MEMORY := 128 +endif + # If blanks in the username, use the first 4 words and pack them together _USER1:=$(subst ', ,$(_USER)) _USER2:=$(subst ", ,$(_USER1)) diff --git a/make/common/shared/Sanity.gmk b/make/common/shared/Sanity.gmk index a97ddddd534510649300c61d89d2837632b3b2c4..9f6bd2a55abcecf3a1adf83e0c1cca2995d58a5e 100644 --- a/make/common/shared/Sanity.gmk +++ b/make/common/shared/Sanity.gmk @@ -105,13 +105,21 @@ ZIP_VER :=$(call GetVersion,"$(_ZIP_VER)") UNZIP_VER :=$(call GetVersion,"$(_UNZIP_VER)") BOOT_VER :=$(call GetVersion,"$(_BOOT_VER)") -REQUIRED_ANT_VER := 1.6.3 -_ANT_VER :=$(shell $(ANT) -version 2>&1 ) -ANT_VER :=$(call GetVersion,"$(_ANT_VER)") +REQUIRED_ANT_VER := 1.6.3 +ifeq ($(ANT_HOME),) + _ANT_VER:=$(shell JAVACMD="$(BOOTDIR)/bin/java" $(ANT) -version 2>&1 ) +else + _ANT_VER:=$(shell JAVACMD="$(BOOTDIR)/bin/java" ANT_HOME="$(ANT_HOME)" $(ANT) -version 2>&1 ) +endif +ANT_VER:=$(call GetVersion,"$(_ANT_VER)") -REQUIRED_FINDBUGS_VER := 1.1 -_FINDBUGS_VER :=$(shell $(FINDBUGS) -version 2>&1 ) -FINDBUGS_VER :=$(call GetVersion,"$(_FINDBUGS_VER)") +REQUIRED_FINDBUGS_VER := 1.2 +ifeq ($(FINDBUGS_HOME),) + _FINDBUGS_VER:=$(shell $(FINDBUGS) -javahome "$(BOOTDIR)" -textui -version 2>&1 ) +else + _FINDBUGS_VER:=$(shell FINDBUGS_HOME="$(FINDBUGS_HOME)" $(FINDBUGS) -javahome "$(BOOTDIR)" -textui -version 2>&1 ) +endif +FINDBUGS_VER:=$(call GetVersion,"$(_FINDBUGS_VER)") ifdef ALT_BINDIR ALT_BINDIR_VERSION := $(shell $(ALT_BINDIR)/java$(EXE_SUFFIX) -version 2>&1 | $(NAWK) -F'"' '{ print $$2 }') @@ -1564,31 +1572,31 @@ ifeq ($(ARCH_DATA_MODEL), 32) endif -###################################################### -# SECURITY_BASELINE_142 test -###################################################### -security_baseline_142: -ifeq ($(PLATFORM), windows) - @if [ -z "$(SECURITY_BASELINE_142)" ]; then \ - $(ECHO) "WARNING: Your SECURITY_BASELINE_142 setting is empty.\n" \ - " Setting it to the default value of 1.4.2_10.\n" \ - " It is recommended to set SECURITY_BASELINE_142.\n" \ - "" >> $(WARNING_FILE) ; \ - fi -endif - -###################################################### -# SECURITY_BASELINE_150 test -###################################################### -security_baseline_150: -ifeq ($(PLATFORM), windows) - @if [ -z "$(SECURITY_BASELINE_150)" ]; then \ - $(ECHO) "WARNING: Your SECURITY_BASELINE_150 setting is empty.\n" \ - " Setting it to the default value of 1.5.0_07.\n" \ - " It is recommended to set SECURITY_BASELINE_150.\n" \ - "" >> $(WARNING_FILE) ; \ - fi -endif +###################################################### +# SECURITY_BASELINE_142 test +###################################################### +security_baseline_142: +ifeq ($(PLATFORM), windows) + @if [ -z "$(SECURITY_BASELINE_142)" ]; then \ + $(ECHO) "WARNING: Your SECURITY_BASELINE_142 setting is empty.\n" \ + " Setting it to the default value of 1.4.2_10.\n" \ + " It is recommended to set SECURITY_BASELINE_142.\n" \ + "" >> $(WARNING_FILE) ; \ + fi +endif + +###################################################### +# SECURITY_BASELINE_150 test +###################################################### +security_baseline_150: +ifeq ($(PLATFORM), windows) + @if [ -z "$(SECURITY_BASELINE_150)" ]; then \ + $(ECHO) "WARNING: Your SECURITY_BASELINE_150 setting is empty.\n" \ + " Setting it to the default value of 1.5.0_07.\n" \ + " It is recommended to set SECURITY_BASELINE_150.\n" \ + "" >> $(WARNING_FILE) ; \ + fi +endif ###################################################### diff --git a/make/docs/CORE_PKGS.gmk b/make/docs/CORE_PKGS.gmk index dce55eea7563f66d47a9a420a095b3aad9917b0d..03d95a606aaf95b76b068769665c5d722927cea7 100644 --- a/make/docs/CORE_PKGS.gmk +++ b/make/docs/CORE_PKGS.gmk @@ -49,8 +49,8 @@ EXCLUDE_PKGS = \ # ACTIVE_JSR_PKGS are packages that are part of an active JSR process-- # one that is doing its own review. These packages are not included when # creating diff pages for the platform's JCP process. -# -# (see /java/pubs/apisrc/jdk/6.0/beta/make/docs/active_jsr_pkgs) +# +# (see /java/pubs/apisrc/jdk/6.0/beta/make/docs/active_jsr_pkgs) # Note: # This is a list of regular expressions. So foo.* matches "foo" and "foo.bar". # @@ -72,13 +72,13 @@ ACTIVE_JSR_PKGS= \ # CORE_PKGS is the list of packages that form the # Java API Specification. # -### ***IMPORTANT NOTE*** -### There is also a "REGEXP" variable in the docs/makefile that -### determines which table the packages go in on the main page. -### Currently, there is only table ("Platform Packages") and -### everything goes in it, so REGEXP is "*". But if that policy -### changes, packages added will need to be reflected in that -### list of wildcard expressions, as well. +### ***IMPORTANT NOTE*** +### There is also a "REGEXP" variable in the docs/makefile that +### determines which table the packages go in on the main page. +### Currently, there is only table ("Platform Packages") and +### everything goes in it, so REGEXP is "*". But if that policy +### changes, packages added will need to be reflected in that +### list of wildcard expressions, as well. ### CORE_PKGS = \ java.applet \ diff --git a/make/java/java/mapfile-vers b/make/java/java/mapfile-vers index 4599570449ea88ffc40c3ae433d52f5d2689a4c5..38f9e126d825266c11c686c7329970e67e5b2dfe 100644 --- a/make/java/java/mapfile-vers +++ b/make/java/java/mapfile-vers @@ -85,7 +85,6 @@ SUNWprivate_1.1 { Java_java_io_FileOutputStream_close0; Java_java_io_FileOutputStream_initIDs; Java_java_io_FileOutputStream_open; - Java_java_io_FileOutputStream_openAppend; Java_java_io_FileOutputStream_write; Java_java_io_FileOutputStream_writeBytes; Java_java_io_FileSystem_getFileSystem; diff --git a/make/java/jli/Makefile b/make/java/jli/Makefile index fb8868fd37dab991f1730a8e7e9ebdd70866fc71..236654fd4a9bd1d1eedabf46bf877efa580bd973 100644 --- a/make/java/jli/Makefile +++ b/make/java/jli/Makefile @@ -107,6 +107,7 @@ endif # PLATFORM ifeq ($(PLATFORM), windows) EXTRA_LIBS = advapi32.lib \ + comctl32.lib \ user32.lib JAVALIB = diff --git a/make/java/main/java/Makefile b/make/java/main/java/Makefile index ad924f6663e72df28eee5bb346e418381f6ff846..5c876294c98da4ea5aa0749fbb73483e1b25d2fd 100644 --- a/make/java/main/java/Makefile +++ b/make/java/main/java/Makefile @@ -43,7 +43,7 @@ include $(BUILDDIR)/common/Defs.gmk # Override the default version info with our own resource file (see 5106536) ifeq ($(PLATFORM), windows) -LDLIBS_COMMON += user32.lib +LDLIBS_COMMON += user32.lib comctl32.lib ifdef OPENJDK RC_FLAGS += -i "$(PLATFORM_SRC)/resource/icons" else diff --git a/make/java/main/javaw/Makefile b/make/java/main/javaw/Makefile index 9afb5d0133db74a76aedfc492b4591690c2e969f..1c03b23fab73e07d7436aa4ba1a44828257d0425 100644 --- a/make/java/main/javaw/Makefile +++ b/make/java/main/javaw/Makefile @@ -46,7 +46,7 @@ STATIC_JLI = true include $(BUILDDIR)/common/Defs.gmk OTHER_CPPFLAGS += -DJAVAW -LDLIBS_COMMON += user32.lib +LDLIBS_COMMON += user32.lib comctl32.lib # Override the default version info with our own resource file (see 5106536) ifeq ($(PLATFORM), windows) diff --git a/make/java/nio/Makefile b/make/java/nio/Makefile index 98a838831a27b6c0f6097ed403d1c740c248afd8..0a9070f8257b78ece943d227ddebc02a5eb468fd 100644 --- a/make/java/nio/Makefile +++ b/make/java/nio/Makefile @@ -191,7 +191,7 @@ sources: $(SPP) $(FILES_genout) GEN_BUFFER_SH = genBuffer.sh -GEN_BUFFER_CMD = SPP="$(SPP_CMD)" NAWK=$(NAWK) SED=$(SED) \ +GEN_BUFFER_CMD = SPP="$(SPP_CMD)" NAWK=$(NAWK) SED=$(SED) SH=$(SH) \ $(SH) $(GEN_BUFFER_SH) # Public abstract buffer classes @@ -582,7 +582,7 @@ $(BUF_GEN)/ByteBufferAsDoubleBuffer%L.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.jav GEN_CODER_SH = genCoder.sh -GEN_CODER_CMD = SPP="$(SPP_CMD)" SED=$(SED) NAWK=$(NAWK) $(SH) $(GEN_CODER_SH) +GEN_CODER_CMD = SPP="$(SPP_CMD)" SED=$(SED) NAWK=$(NAWK) SH=$(SH) $(SH) $(GEN_CODER_SH) $(CS_GEN)/CharsetDecoder.java: $(CS_SRC)/Charset-X-Coder.java $(GEN_CODER_SH) $(prep-target) @@ -602,7 +602,7 @@ $(CS_GEN)/CharsetEncoder.java: $(CS_SRC)/Charset-X-Coder.java $(GEN_CODER_SH) GEN_EX_SH = genExceptions.sh -GEN_EX_CMD = NAWK=$(NAWK) $(SHELL) $(GEN_EX_SH) +GEN_EX_CMD = NAWK=$(NAWK) SH=$(SH) $(SH) $(GEN_EX_SH) $(CH_GEN)/%Exception.java: genExceptions.sh $(CH_SRC)/exceptions $(prep-target) @@ -635,8 +635,8 @@ $(SCS_GEN)/StandardCharsets.java: genCharsetProvider.sh \ $(HASHER_JARFILE) $(SCS_SRC)/standard-charsets $(prep-target) @$(RM) $@.temp - NAWK=$(NAWK) TEMPDIR=$(TEMPDIR) \ + NAWK=$(NAWK) TEMPDIR=$(TEMPDIR) SH=$(SH) \ HASHER="$(BOOT_JAVA_CMD) -jar $(HASHER_JARFILE)" \ - $(SHELL) -e genCharsetProvider.sh $(SCS_SRC)/standard-charsets $(SCS_GEN) + $(SH) -e genCharsetProvider.sh $(SCS_SRC)/standard-charsets $(SCS_GEN) .PHONY: sources diff --git a/make/java/nio/genCharsetProvider.sh b/make/java/nio/genCharsetProvider.sh index 1c344dacabd65e5e29200093ef2e1285b7734b28..574722fb4a94f98792a2eab175b042c8ad970e06 100644 --- a/make/java/nio/genCharsetProvider.sh +++ b/make/java/nio/genCharsetProvider.sh @@ -48,7 +48,7 @@ echo '-->' $OUT # Header # -$SHELL addNotices.sh "$COPYRIGHT_YEARS" > $OUT +$SH ./addNotices.sh "$COPYRIGHT_YEARS" > $OUT cat <<__END__ >>$OUT diff --git a/make/java/nio/genExceptions.sh b/make/java/nio/genExceptions.sh index 0e2020c2c1fa8bedfc9e8afae6c4fb3c95047d78..2de5e9cd784e8f55c67a121e8744872690d73982 100644 --- a/make/java/nio/genExceptions.sh +++ b/make/java/nio/genExceptions.sh @@ -41,7 +41,7 @@ gen() { echo '-->' $DST/$ID.java out=$DST/${ID}.java - $SHELL addNotices.sh "$COPYRIGHT_YEARS" > $out + $SH ./addNotices.sh "$COPYRIGHT_YEARS" > $out cat >>$out <<__END__ diff --git a/make/sun/splashscreen/Makefile b/make/sun/splashscreen/Makefile index 1b51d3a6484f2537734a7b1d8095752aa336b1f8..8a0dffe62c924f1bd29443ed408cf39b94badac0 100644 --- a/make/sun/splashscreen/Makefile +++ b/make/sun/splashscreen/Makefile @@ -85,3 +85,13 @@ vpath %.c $(PLATFORM_SRC)/native/$(PKGDIR)/splashscreen CPPFLAGS += -I$(PLATFORM_SRC)/native/$(PKGDIR)/splashscreen -I$(SHARE_SRC)/native/$(PKGDIR)/splashscreen CPPFLAGS += -I$(SHARE_SRC)/native/$(PKGDIR)/image/jpeg -I$(SHARE_SRC)/native/java/util/zip/zlib-1.1.3 +ifeq ($(PLATFORM), linux) + ifeq ($(ARCH_DATA_MODEL), 64) + # 64-bit gcc has problems compiling MMX instructions. + # Google it for more details. Possibly the newer versions of + # the PNG-library and/or the new compiler will not need this + # option in the future. + CPPFLAGS += -DPNG_NO_MMX_CODE + endif +endif + diff --git a/make/sun/xawt/Makefile b/make/sun/xawt/Makefile index e0f59b738dbf4360cf67b8f2650d4b6740758a6e..4c56c5ea9a4a7ef445ec5854919a0e6ffd5a35bd 100644 --- a/make/sun/xawt/Makefile +++ b/make/sun/xawt/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2002-2008 Sun Microsystems, Inc. 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 @@ -246,7 +246,7 @@ $(SIZES): $(SIZERS) @if [ "$(DOCOMPARE)$(suffix $@)" = "true.64" ]; then \ $(ECHO) COMPARING $@ and $(STORED_SIZES_TMPL_$(PLATFORM)_$(LIBARCH)); \ $(DIFF) $@ $(STORED_SIZES_TMPL_$(PLATFORM)_$(LIBARCH)); \ - fi + fi $(TEMPDIR)/.gen.wrappers: $(SIZES) $(WRAPPER_GENERATOR_CLASS) $(XLIBTYPES) $(BOOT_JAVA_CMD) -cp $(WRAPPER_GENERATOR_TEMPDIR) WrapperGenerator \ @@ -256,10 +256,11 @@ touch.wrappers: $(TEMPDIR)/.gen.wrappers $(MKDIR) -p $(TEMPDIR) $(TOUCH) $(TEMPDIR)/.gen.wrappers -generated.clean: +generated.clean: $(RM) -r $(WRAPPER_GENERATOR_TEMPDIR) $(RM) -r $(WRAPPER_GENERATOR_DIR) $(RM) -r $(GEN_DIR)/*.java + $(RM) -r $(TEMPDIR)/.gen_icons ifdef OPENJDK ICONS_PATH_PREFIX=$(PLATFORM_SRC) diff --git a/make/tools/freetypecheck/Makefile b/make/tools/freetypecheck/Makefile index c2a3e644ba7def7cb51056b06796015f9ceb23be..7bcfe6300c16629bcfd490ae66659384d1bc3842 100644 --- a/make/tools/freetypecheck/Makefile +++ b/make/tools/freetypecheck/Makefile @@ -38,7 +38,14 @@ FT_TEST_PATH = $(TEMPDIR)/$(FT_TEST) all: $(FT_TEST_PATH) -FT_OPTIONS = -I$(FT_HEADERS) -I$(FT_HEADERS)/freetype2 +# Start with CFLAGS (which gets us the required -xarch setting on solaris) +ifeq ($(PLATFORM), windows) + FT_OPTIONS = +else + FT_OPTIONS = $(CFLAGS) +endif + +FT_OPTIONS += -I$(FT_HEADERS) -I$(FT_HEADERS)/freetype2 FT_OPTIONS += $(XARCH) #add runtime library search path diff --git a/make/tools/freetypecheck/freetypecheck.c b/make/tools/freetypecheck/freetypecheck.c index 00f460d7dc11dcbf32c173608e0c3d83d7dca0e3..12b26f7e88b725ea4a7c047f28990ae3ccc9bb6f 100644 --- a/make/tools/freetypecheck/freetypecheck.c +++ b/make/tools/freetypecheck/freetypecheck.c @@ -26,13 +26,16 @@ /* Test program for freetype sanity check. Prints "Failed" messages to STDOUT if check fails. */ +#include +#include + #include "ft2build.h" #include FT_FREETYPE_H #define QUOTEMACRO(x) QUOTEME(x) #define QUOTEME(x) #x -int main(char** argv, int argc) { +int main(int argc, char** argv) { char v[50]; FT_Int major, minor, patch; FT_Library library; diff --git a/make/tools/src/build/tools/jdwpgen/CommandNode.java b/make/tools/src/build/tools/jdwpgen/CommandNode.java index 4cdda4249cb142a0eee5e488546a85d62b06fce6..ec8666453ae08dc91e1ef872fc81564c2db2b8c1 100644 --- a/make/tools/src/build/tools/jdwpgen/CommandNode.java +++ b/make/tools/src/build/tools/jdwpgen/CommandNode.java @@ -32,9 +32,9 @@ class CommandNode extends AbstractCommandNode { void constrain(Context ctx) { if (components.size() == 3) { - Node out = (Node)components.get(0); - Node reply = (Node)components.get(1); - Node error = (Node)components.get(2); + Node out = components.get(0); + Node reply = components.get(1); + Node error = components.get(2); if (!(out instanceof OutNode)) { error("Expected 'Out' item, got: " + out); } @@ -45,7 +45,7 @@ class CommandNode extends AbstractCommandNode { error("Expected 'ErrorSet' item, got: " + error); } } else if (components.size() == 1) { - Node evt = (Node)components.get(0); + Node evt = components.get(0); if (!(evt instanceof EventNode)) { error("Expected 'Event' item, got: " + evt); } diff --git a/make/tools/src/build/tools/jdwpgen/ConstantSetNode.java b/make/tools/src/build/tools/jdwpgen/ConstantSetNode.java index 6d688dd7f72a478ebcc9b993b8bb6fdb80c29374..325ebc9ef46154e5c4a0883f65a27ee37e187432 100644 --- a/make/tools/src/build/tools/jdwpgen/ConstantSetNode.java +++ b/make/tools/src/build/tools/jdwpgen/ConstantSetNode.java @@ -98,7 +98,7 @@ class ConstantSetNode extends AbstractNamedNode { if (constantMap == null) { return ""; } - String com = (String) constantMap.get(key); + String com = constantMap.get(key); if(com == null){ return ""; } else { diff --git a/make/tools/src/build/tools/jdwpgen/RepeatNode.java b/make/tools/src/build/tools/jdwpgen/RepeatNode.java index 40d4e0899bd570da0621cf169d91a427c62d44d7..4c8f20982f2bfae3688602f5d700689f8877f661 100644 --- a/make/tools/src/build/tools/jdwpgen/RepeatNode.java +++ b/make/tools/src/build/tools/jdwpgen/RepeatNode.java @@ -37,7 +37,7 @@ class RepeatNode extends AbstractTypeNode { if (components.size() != 1) { error("Repeat must have exactly one member, use Group for more"); } - member = (Node)(components.get(0)); + member = components.get(0); if (!(member instanceof TypeNode)) { error("Repeat member must be type specifier"); } diff --git a/make/tools/winver/bin/winver.exe b/make/tools/winver/bin/winver.exe old mode 100644 new mode 100755 diff --git a/src/share/bin/java.c b/src/share/bin/java.c index 2e86de9a401a4e2b1cc08c8b434b71d449e4eee3..47c2fc17cd0cfd0fb5a19f19bef68e84fe1cf9f9 100644 --- a/src/share/bin/java.c +++ b/src/share/bin/java.c @@ -205,9 +205,7 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */ _wc_enabled = cpwildcard; _ergo_policy = ergo; - if (javaw == JNI_TRUE) - SetJavaw(); - + InitLauncher(javaw); DumpState(); /* diff --git a/src/share/bin/java.h b/src/share/bin/java.h index c86c5d107db40bc68c6d096c40e6866886ef07e7..291b6755690bf836deffd7216cb1752e2c79da21 100644 --- a/src/share/bin/java.h +++ b/src/share/bin/java.h @@ -172,7 +172,6 @@ const char* GetDotVersion(); const char* GetFullVersion(); jboolean IsJavaArgs(); jboolean IsJavaw(); -void SetJavaw(); jint GetErgoPolicy(); jboolean ServerClassMachine(); @@ -180,5 +179,9 @@ jboolean ServerClassMachine(); static int ContinueInNewThread(InvocationFunctions* ifn, int argc, char** argv, char* jarfile, char* classname, int ret); +/* + * Initialize platform specific settings + */ +void InitLauncher(jboolean javaw); #endif /* _JAVA_H_ */ diff --git a/src/share/bin/main.c b/src/share/bin/main.c index 7052159f2672d7a4f12c69bf208c9aa011651ce1..88d9190a555eb86c99bd2c43bd2a3a60187db2b8 100644 --- a/src/share/bin/main.c +++ b/src/share/bin/main.c @@ -64,8 +64,6 @@ main(int argc, char ** argv) margv = argv; #endif /* JAVAW */ - JLI_SetTraceLauncher(); - return JLI_Launch(margc, margv, sizeof(const_jargs) / sizeof(char *), const_jargs, sizeof(const_appclasspath) / sizeof(char *), const_appclasspath, diff --git a/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java b/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java index afb9b3e94a559cfeee86fd5e8f3d58bcc84af791..ee5ed5a9229797b3f93e470dde01d3a8dbed7d69 100644 --- a/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java +++ b/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java @@ -34,6 +34,7 @@ import java.security.KeyRep; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; import java.security.spec.InvalidKeySpecException; import javax.crypto.Mac; import javax.crypto.SecretKey; @@ -107,12 +108,17 @@ final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey { throw new InvalidKeySpecException("Key length is negative"); } try { - this.prf = Mac.getInstance(prfAlgo, new SunJCE()); + this.prf = Mac.getInstance(prfAlgo, "SunJCE"); } catch (NoSuchAlgorithmException nsae) { // not gonna happen; re-throw just in case InvalidKeySpecException ike = new InvalidKeySpecException(); ike.initCause(nsae); throw ike; + } catch (NoSuchProviderException nspe) { + // Again, not gonna happen; re-throw just in case + InvalidKeySpecException ike = new InvalidKeySpecException(); + ike.initCause(nspe); + throw ike; } this.key = deriveKey(prf, passwdBytes, salt, iterCount, keyLength); } diff --git a/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames.properties b/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames.properties index e592c36caba0207519290ad5481130315a4802f3..f0feb6395c034f33c150f09061e2453ce4881610 100644 --- a/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames.properties +++ b/src/share/classes/com/sun/inputmethods/internal/indicim/resources/DisplayNames.properties @@ -1,5 +1,6 @@ -# -# Default Input method display names for Indic input methods -# - -DisplayName.Devanagari = Devanagari Input Method +# +# Default Input method display names for Indic input methods +# + +DisplayName.Devanagari = Devanagari Input Method + diff --git a/src/share/classes/com/sun/inputmethods/internal/thaiim/resources/DisplayNames.properties b/src/share/classes/com/sun/inputmethods/internal/thaiim/resources/DisplayNames.properties index f88a4bf2dcaa8817cadb516ff9610f604babeb0c..e4528a49a5337f0fe21ffbbe1b06062ac5708f4e 100644 --- a/src/share/classes/com/sun/inputmethods/internal/thaiim/resources/DisplayNames.properties +++ b/src/share/classes/com/sun/inputmethods/internal/thaiim/resources/DisplayNames.properties @@ -1,5 +1,6 @@ -# -# Default Input method display names for Thai input methods -# - -DisplayName.Thai = Thai Input Method +# +# Default Input method display names for Thai input methods +# + +DisplayName.Thai = Thai Input Method + diff --git a/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java b/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java index b68fd28ffa75af2f269185e3ad39baec4fc09e6c..2a72f3d222f4e334e4cb7c20b9f915318f62cd39 100644 --- a/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java +++ b/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java @@ -43,6 +43,13 @@ import javax.management.MBeanInfo; import javax.management.NotCompliantMBeanException; import com.sun.jmx.mbeanserver.Util; +import com.sun.jmx.remote.util.EnvHelp; +import java.beans.BeanInfo; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Array; +import java.lang.reflect.InvocationTargetException; +import javax.management.AttributeNotFoundException; +import javax.management.openmbean.CompositeData; /** * This class contains the methods for performing all the tests needed to verify @@ -482,4 +489,33 @@ public class Introspector { return null; } + + public static Object elementFromComplex(Object complex, String element) + throws AttributeNotFoundException { + try { + if (complex.getClass().isArray() && element.equals("length")) { + return Array.getLength(complex); + } else if (complex instanceof CompositeData) { + return ((CompositeData) complex).get(element); + } else { + // Java Beans introspection + // + BeanInfo bi = java.beans.Introspector.getBeanInfo(complex.getClass()); + PropertyDescriptor[] pds = bi.getPropertyDescriptors(); + for (PropertyDescriptor pd : pds) + if (pd.getName().equals(element)) + return pd.getReadMethod().invoke(complex); + throw new AttributeNotFoundException( + "Could not find the getter method for the property " + + element + " using the Java Beans introspector"); + } + } catch (InvocationTargetException e) { + throw new IllegalArgumentException(e); + } catch (AttributeNotFoundException e) { + throw e; + } catch (Exception e) { + throw EnvHelp.initCause( + new AttributeNotFoundException(e.getMessage()), e); + } + } } diff --git a/src/share/classes/com/sun/org/apache/xml/internal/security/resource/config.dtd b/src/share/classes/com/sun/org/apache/xml/internal/security/resource/config.dtd index f57b9fabe4d3aa59de28f6c0c3930a8251a2a916..1e886bf17760aad26920c92726ae1c9554deb86a 100644 --- a/src/share/classes/com/sun/org/apache/xml/internal/security/resource/config.dtd +++ b/src/share/classes/com/sun/org/apache/xml/internal/security/resource/config.dtd @@ -1,73 +1,73 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml b/src/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml index e6881361512371981f7ef7e20a5c5f2d226b3dd5..d0d6edcee6956942553a2055b1362f08fa2f8e60 100644 --- a/src/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml +++ b/src/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml @@ -1,380 +1,380 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/etsi.xsd b/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/etsi.xsd index d69852ff8421c3400819831b6c16b56ce3f8d0af..3a08c64f4b6a93c30b83468c3827df0fe0231c9c 100644 --- a/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/etsi.xsd +++ b/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/etsi.xsd @@ -1,347 +1,347 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_en.properties b/src/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_en.properties index 1b8e97bfd633971f6c88b0130b4bca5cba396c54..8c8b2ab1f8dc85b7ff0a6a10ae90d5c95ddd9b35 100644 --- a/src/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_en.properties +++ b/src/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_en.properties @@ -1,123 +1,123 @@ -algorithm.alreadyRegistered = URI {0} already assigned to class {1} -algorithm.classDoesNotExist = Cannot register URI {0} to class {1} because this class does not exist in CLASSPATH -algorithm.ClassDoesNotExist = Class {0} does not exist -algorithm.extendsWrongClass = Cannot register URI {0} to class {1} because it does not extend {2} -algorithms.CannotUseAlgorithmParameterSpecOnDSA = Sorry, but you cannot use a AlgorithmParameterSpec object for creating DSA signatures. -algorithms.CannotUseAlgorithmParameterSpecOnRSA = Sorry, but you cannot use a AlgorithmParameterSpec object for creating RSA signatures. -algorithms.CannotUseSecureRandomOnMAC = Sorry, but you cannot use a SecureRandom object for creating MACs. -algorithms.HMACOutputLengthOnlyForHMAC = A HMACOutputLength can only be specified for HMAC integrity algorithms -algorithms.NoSuchAlgorithm = The requested algorithm {0} does not exist. Original Message was: {1} -algorithms.NoSuchMap = The algorithm URI "{0}" could not be mapped to a JCE algorithm -algorithms.NoSuchProvider = The specified Provider {0} does not exist. Original Message was: {1} -algorithms.operationOnlyVerification = A public key can only used for verification of a signature. -algorithms.WrongKeyForThisOperation = Sorry, you supplied the wrong key type for this operation! You supplied a {0} but a {1} is needed. -attributeValueIllegal = The attribute {0} has value {1} but must be {2} -c14n.Canonicalizer.Exception = Exception during Canonicalization: Original Message was {0} -c14n.Canonicalizer.IllegalNode = Illegal node type {0}, node name was {1} -c14n.Canonicalizer.NoSuchCanonicalizer = No canonicalizer found with URI {0} -c14n.Canonicalizer.ParserConfigurationException = ParserConfigurationException during Canonicalization: Original Message was {0} -c14n.Canonicalizer.RelativeNamespace = Element {0} has a relative namespace: {1}="{2}" -c14n.Canonicalizer.SAXException = SAXException during Canonicalization: Original Message was {0} -c14n.Canonicalizer.TraversalNotSupported = This DOM document does not support Traversal {0} -c14n.Canonicalizer.UnsupportedEncoding = Unsupported encoding {0} -c14n.Canonicalizer.UnsupportedOperation = This canonicalizer does not support this operation -c14n.XMLUtils.circumventBug2650forgotten = The tree has not been prepared for canonicalization using XMLUtils#circumventBug2650(Document) -certificate.noSki.lowVersion = Certificate cannot contain a SubjectKeyIdentifier because it is only X509v{0} -certificate.noSki.notOctetString = Certificates SubjectKeyIdentifier is not a OctetString -certificate.noSki.null = Certificate does not contain a SubjectKeyIdentifier -defaultNamespaceCannotBeSetHere = Default namespace cannot be set here -ElementProxy.nullElement = Cannot create an ElementProxy from a null argument -empty = {0} -encryption.algorithmCannotBeUsedForEncryptedData = encryption.algorithmCannotBeUsedForEncryptedData {0} -encryption.algorithmCannotEatInitParams = encryption.algorithmCannotEatInitParams -encryption.algorithmCannotEncryptDecrypt = encryption.algorithmCannotEncryptDecrypt -encryption.algorithmCannotWrapUnWrap = encryption.algorithmCannotWrapUnWrap -encryption.ExplicitKeySizeMismatch = The xenc:KeySize element requests a key size of {0} bit but the algorithm implements {1} bit -encryption.nonceLongerThanDecryptedPlaintext = The given nonce is longer than the available plaintext. I Cannot strip away this. -encryption.RSAOAEP.dataHashWrong = data hash wrong -encryption.RSAOAEP.dataStartWrong = data wrong start {0} -encryption.RSAOAEP.dataTooShort = data too short -encryption.RSAPKCS15.blockTruncated = block truncated -encryption.RSAPKCS15.noDataInBlock = no data in block -encryption.RSAPKCS15.unknownBlockType = unknown block type -encryption.nokey = No Key Encryption Key loaded and cannot determine using key resolvers -endorsed.jdk1.4.0 = Since it seems that nobody reads our installation notes, we must do it in the exception messages. Hope you read them. You did NOT use the endorsed mechanism from JDK 1.4 properly; look at how to solve this problem. -errorMessages.InvalidDigestValueException = INVALID signature -- check reference resolution. -errorMessages.InvalidSignatureValueException = INVALID signature -- core validation failed. -errorMessages.IOException = Other file I/O and similar exceptions. -errorMessages.MissingKeyFailureException = Cannot verify because of missing public key. Provide it via addResource and try again. -errorMessages.MissingResourceFailureException = Cannot verify because of unresolved references. Provide it via addResource and try again. -errorMessages.NoSuchAlgorithmException = Unknown Algorithm {0} -errorMessages.NotYetImplementedException = Functionality not yet there. -errorMessages.XMLSignatureException = Verification failed for some other reason. -decoding.divisible.four = It should be divisible by four -decoding.general = Error while decoding -FileKeyStorageImpl.addToDefaultFromRemoteNotImplemented = Method addToDefaultFromRemote() not yet implemented. -FileKeyStorageImpl.NoCert.Context = Not found such a X509Certificate including context {0} -FileKeyStorageImpl.NoCert.IssNameSerNo = Not found such a X509Certificate with IssuerName {0} and serial number {1} -FileKeyStorageImpl.NoCert.SubjName = Not found such a X509Certificate including SubjectName {0} -generic.dontHaveConstructionElement = I do not have a construction Element -generic.EmptyMessage = {0} -generic.NotYetImplemented = {0} Not YET implemented ;-(( -java.security.InvalidKeyException = Invalid key -java.security.NoSuchProviderException = Unknown or unsupported provider -java.security.UnknownKeyType = Unknown or unsupported key type {0} -KeyInfo.needKeyResolver = More than one keyResovler have to be registered -KeyInfo.nokey = Cannot get key from {0} -KeyInfo.noKey = Cannot get the public key -KeyInfo.wrongNumberOfObject = Need {0} keyObjects -KeyInfo.wrongUse = This object was made for getting {0} -keyResolver.alreadyRegistered = {1} class has already been registered for {0} -KeyResolver.needStorageResolver = Need a StorageResolver to retrieve a Certificate from a {0} -KeyResoverSpiImpl.cannotGetCert = Cannot get the Certificate that include or in {1} in implement class {0} -KeyResoverSpiImpl.elementGeneration = Cannot make {1} element in implement class {0} -KeyResoverSpiImpl.getPoublicKey = Cannot get the public key from implement class {0} -KeyResoverSpiImpl.InvalidElement = Cannot set (2) Element in implement class {0} -KeyResoverSpiImpl.keyStore = KeyStorage error in implement class {0} -KeyResoverSpiImpl.need.Element = {1} type of Element is needed in implement class {0} -KeyResoverSpiImpl.wrongCRLElement = Cannot make CRL from {1} in implement class {0} -KeyResoverSpiImpl.wrongKeyObject = Need {1} type of KeyObject for generation Element in implement class{0} -KeyResoverSpiImpl.wrongNumberOfObject = Need {1} keyObject in implement class {0} -KeyStore.alreadyRegistered = {0} Class has already been registered for {1} -KeyStore.register = {1} type class register error in class {0} -KeyStore.registerStore.register = Registeration error for type {0} -KeyValue.IllegalArgument = Cannot create a {0} from {1} -namespacePrefixAlreadyUsedByOtherURI = Namespace prefix {0} already used by other URI {1} -notYetInitialized = The module {0} is not yet initialized -prefix.AlreadyAssigned = You want to assign {0} as prefix for namespace {1} but it is already assigned for {2} -signature.Canonicalizer.UnknownCanonicalizer = Unknown canonicalizer. No handler installed for URI {0} -signature.DSA.invalidFormat = Invalid ASN.1 encoding of the DSA signature -signature.Generation.signBeforeGetValue = You have to XMLSignature.sign(java.security.PrivateKey) first -signature.signaturePropertyHasNoTarget = The Target attribute of the SignatureProperty must be set -signature.Transform.ErrorDuringTransform = A {1} was thrown during the {0} transform -signature.Transform.NotYetImplemented = Transform {0} not yet implemented -signature.Transform.NullPointerTransform = Null pointer as URI. Programming bug? -signature.Transform.UnknownTransform = Unknown transformation. No handler installed for URI {0} -signature.Transform.node = Current Node: {0} -signature.Transform.nodeAndType = Current Node: {0}, type: {1} -signature.Util.BignumNonPositive = bigInteger.signum() must be positive -signature.Util.NonTextNode = Not a text node -signature.Util.TooManyChilds = Too many childs of Type {0} in {1} -signature.Verification.certificateError = Certificate error -signature.Verification.IndexOutOfBounds = Index {0} illegal. We only have {1} References -signature.Verification.internalError = Internal error -signature.Verification.InvalidDigestOrReference = Invalid digest of reference {0} -signature.Verification.keyStore = KeyStore error -signature.Verification.MissingID = Cannot resolve element with ID {0} -signature.Verification.MissingResources = Cannot resolve external resource {0} -signature.Verification.NoSignatureElement = Input document contains no {0} Element in namespace {1} -signature.Verification.Reference.NoInput = The Reference for URI {0} has no XMLSignatureInput -signature.Verification.SignatureError = Signature error -signature.XMLSignatureInput.MissingConstuctor = Cannot construct a XMLSignatureInput from class {0} -signature.XMLSignatureInput.SerializeDOM = Input initialized with DOM Element. Use Canonicalization to serialize it -signature.XMLSignatureInput.nodesetReference = Unable to convert to nodeset the reference -transform.Init.IllegalContextArgument = Invalid context argument of class {0}. Must be String, org.w3c.dom.NodeList or java.io.InputStream. -transform.init.NotInitialized = -transform.init.wrongURI = Initialized with wrong URI. How could this happen? We implement {0} but {1} was used during initialization -utils.Base64.IllegalBitlength = Illegal byte length; Data to be decoded must be a multiple of 4 -Base64Decoding = Error while decoding -utils.resolver.noClass = Could not find a resolver for URI {0} and Base {1} -xml.WrongContent = Cannot find {0} in {1} -xml.WrongElement = Cannot create a {0} from a {1} element -xpath.funcHere.documentsDiffer = The XPath is not in the same document as the context node -xpath.funcHere.noXPathContext = Try to evaluate an XPath which uses the here() function but XPath is not inside an ds:XPath Element. XPath was : {0} +algorithm.alreadyRegistered = URI {0} already assigned to class {1} +algorithm.classDoesNotExist = Cannot register URI {0} to class {1} because this class does not exist in CLASSPATH +algorithm.ClassDoesNotExist = Class {0} does not exist +algorithm.extendsWrongClass = Cannot register URI {0} to class {1} because it does not extend {2} +algorithms.CannotUseAlgorithmParameterSpecOnDSA = Sorry, but you cannot use a AlgorithmParameterSpec object for creating DSA signatures. +algorithms.CannotUseAlgorithmParameterSpecOnRSA = Sorry, but you cannot use a AlgorithmParameterSpec object for creating RSA signatures. +algorithms.CannotUseSecureRandomOnMAC = Sorry, but you cannot use a SecureRandom object for creating MACs. +algorithms.HMACOutputLengthOnlyForHMAC = A HMACOutputLength can only be specified for HMAC integrity algorithms +algorithms.NoSuchAlgorithm = The requested algorithm {0} does not exist. Original Message was: {1} +algorithms.NoSuchMap = The algorithm URI "{0}" could not be mapped to a JCE algorithm +algorithms.NoSuchProvider = The specified Provider {0} does not exist. Original Message was: {1} +algorithms.operationOnlyVerification = A public key can only used for verification of a signature. +algorithms.WrongKeyForThisOperation = Sorry, you supplied the wrong key type for this operation! You supplied a {0} but a {1} is needed. +attributeValueIllegal = The attribute {0} has value {1} but must be {2} +c14n.Canonicalizer.Exception = Exception during Canonicalization: Original Message was {0} +c14n.Canonicalizer.IllegalNode = Illegal node type {0}, node name was {1} +c14n.Canonicalizer.NoSuchCanonicalizer = No canonicalizer found with URI {0} +c14n.Canonicalizer.ParserConfigurationException = ParserConfigurationException during Canonicalization: Original Message was {0} +c14n.Canonicalizer.RelativeNamespace = Element {0} has a relative namespace: {1}="{2}" +c14n.Canonicalizer.SAXException = SAXException during Canonicalization: Original Message was {0} +c14n.Canonicalizer.TraversalNotSupported = This DOM document does not support Traversal {0} +c14n.Canonicalizer.UnsupportedEncoding = Unsupported encoding {0} +c14n.Canonicalizer.UnsupportedOperation = This canonicalizer does not support this operation +c14n.XMLUtils.circumventBug2650forgotten = The tree has not been prepared for canonicalization using XMLUtils#circumventBug2650(Document) +certificate.noSki.lowVersion = Certificate cannot contain a SubjectKeyIdentifier because it is only X509v{0} +certificate.noSki.notOctetString = Certificates SubjectKeyIdentifier is not a OctetString +certificate.noSki.null = Certificate does not contain a SubjectKeyIdentifier +defaultNamespaceCannotBeSetHere = Default namespace cannot be set here +ElementProxy.nullElement = Cannot create an ElementProxy from a null argument +empty = {0} +encryption.algorithmCannotBeUsedForEncryptedData = encryption.algorithmCannotBeUsedForEncryptedData {0} +encryption.algorithmCannotEatInitParams = encryption.algorithmCannotEatInitParams +encryption.algorithmCannotEncryptDecrypt = encryption.algorithmCannotEncryptDecrypt +encryption.algorithmCannotWrapUnWrap = encryption.algorithmCannotWrapUnWrap +encryption.ExplicitKeySizeMismatch = The xenc:KeySize element requests a key size of {0} bit but the algorithm implements {1} bit +encryption.nonceLongerThanDecryptedPlaintext = The given nonce is longer than the available plaintext. I Cannot strip away this. +encryption.RSAOAEP.dataHashWrong = data hash wrong +encryption.RSAOAEP.dataStartWrong = data wrong start {0} +encryption.RSAOAEP.dataTooShort = data too short +encryption.RSAPKCS15.blockTruncated = block truncated +encryption.RSAPKCS15.noDataInBlock = no data in block +encryption.RSAPKCS15.unknownBlockType = unknown block type +encryption.nokey = No Key Encryption Key loaded and cannot determine using key resolvers +endorsed.jdk1.4.0 = Since it seems that nobody reads our installation notes, we must do it in the exception messages. Hope you read them. You did NOT use the endorsed mechanism from JDK 1.4 properly; look at how to solve this problem. +errorMessages.InvalidDigestValueException = INVALID signature -- check reference resolution. +errorMessages.InvalidSignatureValueException = INVALID signature -- core validation failed. +errorMessages.IOException = Other file I/O and similar exceptions. +errorMessages.MissingKeyFailureException = Cannot verify because of missing public key. Provide it via addResource and try again. +errorMessages.MissingResourceFailureException = Cannot verify because of unresolved references. Provide it via addResource and try again. +errorMessages.NoSuchAlgorithmException = Unknown Algorithm {0} +errorMessages.NotYetImplementedException = Functionality not yet there. +errorMessages.XMLSignatureException = Verification failed for some other reason. +decoding.divisible.four = It should be divisible by four +decoding.general = Error while decoding +FileKeyStorageImpl.addToDefaultFromRemoteNotImplemented = Method addToDefaultFromRemote() not yet implemented. +FileKeyStorageImpl.NoCert.Context = Not found such a X509Certificate including context {0} +FileKeyStorageImpl.NoCert.IssNameSerNo = Not found such a X509Certificate with IssuerName {0} and serial number {1} +FileKeyStorageImpl.NoCert.SubjName = Not found such a X509Certificate including SubjectName {0} +generic.dontHaveConstructionElement = I do not have a construction Element +generic.EmptyMessage = {0} +generic.NotYetImplemented = {0} Not YET implemented ;-(( +java.security.InvalidKeyException = Invalid key +java.security.NoSuchProviderException = Unknown or unsupported provider +java.security.UnknownKeyType = Unknown or unsupported key type {0} +KeyInfo.needKeyResolver = More than one keyResovler have to be registered +KeyInfo.nokey = Cannot get key from {0} +KeyInfo.noKey = Cannot get the public key +KeyInfo.wrongNumberOfObject = Need {0} keyObjects +KeyInfo.wrongUse = This object was made for getting {0} +keyResolver.alreadyRegistered = {1} class has already been registered for {0} +KeyResolver.needStorageResolver = Need a StorageResolver to retrieve a Certificate from a {0} +KeyResoverSpiImpl.cannotGetCert = Cannot get the Certificate that include or in {1} in implement class {0} +KeyResoverSpiImpl.elementGeneration = Cannot make {1} element in implement class {0} +KeyResoverSpiImpl.getPoublicKey = Cannot get the public key from implement class {0} +KeyResoverSpiImpl.InvalidElement = Cannot set (2) Element in implement class {0} +KeyResoverSpiImpl.keyStore = KeyStorage error in implement class {0} +KeyResoverSpiImpl.need.Element = {1} type of Element is needed in implement class {0} +KeyResoverSpiImpl.wrongCRLElement = Cannot make CRL from {1} in implement class {0} +KeyResoverSpiImpl.wrongKeyObject = Need {1} type of KeyObject for generation Element in implement class{0} +KeyResoverSpiImpl.wrongNumberOfObject = Need {1} keyObject in implement class {0} +KeyStore.alreadyRegistered = {0} Class has already been registered for {1} +KeyStore.register = {1} type class register error in class {0} +KeyStore.registerStore.register = Registeration error for type {0} +KeyValue.IllegalArgument = Cannot create a {0} from {1} +namespacePrefixAlreadyUsedByOtherURI = Namespace prefix {0} already used by other URI {1} +notYetInitialized = The module {0} is not yet initialized +prefix.AlreadyAssigned = You want to assign {0} as prefix for namespace {1} but it is already assigned for {2} +signature.Canonicalizer.UnknownCanonicalizer = Unknown canonicalizer. No handler installed for URI {0} +signature.DSA.invalidFormat = Invalid ASN.1 encoding of the DSA signature +signature.Generation.signBeforeGetValue = You have to XMLSignature.sign(java.security.PrivateKey) first +signature.signaturePropertyHasNoTarget = The Target attribute of the SignatureProperty must be set +signature.Transform.ErrorDuringTransform = A {1} was thrown during the {0} transform +signature.Transform.NotYetImplemented = Transform {0} not yet implemented +signature.Transform.NullPointerTransform = Null pointer as URI. Programming bug? +signature.Transform.UnknownTransform = Unknown transformation. No handler installed for URI {0} +signature.Transform.node = Current Node: {0} +signature.Transform.nodeAndType = Current Node: {0}, type: {1} +signature.Util.BignumNonPositive = bigInteger.signum() must be positive +signature.Util.NonTextNode = Not a text node +signature.Util.TooManyChilds = Too many childs of Type {0} in {1} +signature.Verification.certificateError = Certificate error +signature.Verification.IndexOutOfBounds = Index {0} illegal. We only have {1} References +signature.Verification.internalError = Internal error +signature.Verification.InvalidDigestOrReference = Invalid digest of reference {0} +signature.Verification.keyStore = KeyStore error +signature.Verification.MissingID = Cannot resolve element with ID {0} +signature.Verification.MissingResources = Cannot resolve external resource {0} +signature.Verification.NoSignatureElement = Input document contains no {0} Element in namespace {1} +signature.Verification.Reference.NoInput = The Reference for URI {0} has no XMLSignatureInput +signature.Verification.SignatureError = Signature error +signature.XMLSignatureInput.MissingConstuctor = Cannot construct a XMLSignatureInput from class {0} +signature.XMLSignatureInput.SerializeDOM = Input initialized with DOM Element. Use Canonicalization to serialize it +signature.XMLSignatureInput.nodesetReference = Unable to convert to nodeset the reference +transform.Init.IllegalContextArgument = Invalid context argument of class {0}. Must be String, org.w3c.dom.NodeList or java.io.InputStream. +transform.init.NotInitialized = +transform.init.wrongURI = Initialized with wrong URI. How could this happen? We implement {0} but {1} was used during initialization +utils.Base64.IllegalBitlength = Illegal byte length; Data to be decoded must be a multiple of 4 +Base64Decoding = Error while decoding +utils.resolver.noClass = Could not find a resolver for URI {0} and Base {1} +xml.WrongContent = Cannot find {0} in {1} +xml.WrongElement = Cannot create a {0} from a {1} element +xpath.funcHere.documentsDiffer = The XPath is not in the same document as the context node +xpath.funcHere.noXPathContext = Try to evaluate an XPath which uses the here() function but XPath is not inside an ds:XPath Element. XPath was : {0} diff --git a/src/share/classes/com/sun/tools/example/debug/bdi/EventRequestSpec.java b/src/share/classes/com/sun/tools/example/debug/bdi/EventRequestSpec.java index 07b38826496fec00f7685cfe797932d0dda00ab0..96a9ef5322b1d24d8aed95e1e44371389e8e56a3 100644 --- a/src/share/classes/com/sun/tools/example/debug/bdi/EventRequestSpec.java +++ b/src/share/classes/com/sun/tools/example/debug/bdi/EventRequestSpec.java @@ -91,9 +91,7 @@ abstract public class EventRequestSpec { void attemptImmediateResolve(VirtualMachine vm) { // try to resolve immediately - Iterator iter = vm.allClasses().iterator(); - while (iter.hasNext()) { - ReferenceType refType = (ReferenceType)iter.next(); + for (ReferenceType refType : vm.allClasses()) { if (refSpec.matches(refType)) { try { resolve(refType); diff --git a/src/share/classes/com/sun/tools/example/debug/bdi/EventRequestSpecList.java b/src/share/classes/com/sun/tools/example/debug/bdi/EventRequestSpecList.java index dcc9b0c351708ebf24629a9aac40f6528be536ce..e04c851f186f95c4313a94cb9cb63d45cf0e5f3e 100644 --- a/src/share/classes/com/sun/tools/example/debug/bdi/EventRequestSpecList.java +++ b/src/share/classes/com/sun/tools/example/debug/bdi/EventRequestSpecList.java @@ -47,9 +47,8 @@ class EventRequestSpecList { */ void resolve(ReferenceType refType) { synchronized(eventRequestSpecs) { - Iterator iter = eventRequestSpecs.iterator(); - while (iter.hasNext()) { - ((EventRequestSpec)iter.next()).attemptResolve(refType); + for (EventRequestSpec spec : eventRequestSpecs) { + spec.attemptResolve(refType); } } } @@ -79,7 +78,7 @@ class EventRequestSpecList { BreakpointSpec createMethodBreakpoint(String classPattern, - String methodId, List methodArgs) { + String methodId, List methodArgs) { ReferenceTypeSpec refSpec = new PatternReferenceTypeSpec(classPattern); return new MethodBreakpointSpec(this, refSpec, @@ -132,47 +131,48 @@ class EventRequestSpecList { // -------- notify routines -------------------- - private Vector specListeners() { - return (Vector)runtime.specListeners.clone(); + @SuppressWarnings("unchecked") + private Vector specListeners() { + return (Vector)runtime.specListeners.clone(); } void notifySet(EventRequestSpec spec) { - Vector l = specListeners(); + Vector l = specListeners(); SpecEvent evt = new SpecEvent(spec); for (int i = 0; i < l.size(); i++) { - spec.notifySet((SpecListener)l.elementAt(i), evt); + spec.notifySet(l.elementAt(i), evt); } } void notifyDeferred(EventRequestSpec spec) { - Vector l = specListeners(); + Vector l = specListeners(); SpecEvent evt = new SpecEvent(spec); for (int i = 0; i < l.size(); i++) { - spec.notifyDeferred((SpecListener)l.elementAt(i), evt); + spec.notifyDeferred(l.elementAt(i), evt); } } void notifyDeleted(EventRequestSpec spec) { - Vector l = specListeners(); + Vector l = specListeners(); SpecEvent evt = new SpecEvent(spec); for (int i = 0; i < l.size(); i++) { - spec.notifyDeleted((SpecListener)l.elementAt(i), evt); + spec.notifyDeleted(l.elementAt(i), evt); } } void notifyResolved(EventRequestSpec spec) { - Vector l = specListeners(); + Vector l = specListeners(); SpecEvent evt = new SpecEvent(spec); for (int i = 0; i < l.size(); i++) { - spec.notifyResolved((SpecListener)l.elementAt(i), evt); + spec.notifyResolved(l.elementAt(i), evt); } } void notifyError(EventRequestSpec spec, Exception exc) { - Vector l = specListeners(); + Vector l = specListeners(); SpecErrorEvent evt = new SpecErrorEvent(spec, exc); for (int i = 0; i < l.size(); i++) { - spec.notifyError((SpecListener)l.elementAt(i), evt); + spec.notifyError(l.elementAt(i), evt); } } } diff --git a/src/share/classes/com/sun/tools/example/debug/bdi/ExecutionManager.java b/src/share/classes/com/sun/tools/example/debug/bdi/ExecutionManager.java index e533bb54c83a9b601ca1ed5e92f7efc16cc289f6..245590ec7fd661f44234b9a67954db2b18394932 100644 --- a/src/share/classes/com/sun/tools/example/debug/bdi/ExecutionManager.java +++ b/src/share/classes/com/sun/tools/example/debug/bdi/ExecutionManager.java @@ -232,10 +232,7 @@ public class ExecutionManager { if (pattern.startsWith("*.")) { // Wildcard matches any leading package name. pattern = pattern.substring(1); - List classes = vm().allClasses(); - Iterator iter = classes.iterator(); - while (iter.hasNext()) { - ReferenceType type = ((ReferenceType)iter.next()); + for (ReferenceType type : vm().allClasses()) { if (type.name().endsWith(pattern)) { result.add(type); } @@ -278,7 +275,7 @@ public class ExecutionManager { public ThreadGroupReference systemThreadGroup() throws NoSessionException { ensureActiveSession(); - return (ThreadGroupReference)vm().topLevelThreadGroups().get(0); + return vm().topLevelThreadGroups().get(0); } /* @@ -349,10 +346,9 @@ public class ExecutionManager { * attach sessions. */ VirtualMachineManager mgr = Bootstrap.virtualMachineManager(); - List connectors = mgr.attachingConnectors(); - AttachingConnector connector = (AttachingConnector)connectors.get(0); + AttachingConnector connector = mgr.attachingConnectors().get(0); Map arguments = connector.defaultArguments(); - ((Connector.Argument)arguments.get("port")).setValue(portName); + arguments.get("port").setValue(portName); Session newSession = internalAttach(connector, arguments); if (newSession != null) { @@ -504,10 +500,7 @@ public class ExecutionManager { * if so, it gets removed here. */ EventRequestManager mgr = vm().eventRequestManager(); - List requests = mgr.stepRequests(); - Iterator iter = requests.iterator(); - while (iter.hasNext()) { - StepRequest request = (StepRequest)iter.next(); + for (StepRequest request : mgr.stepRequests()) { if (request.thread().equals(thread)) { mgr.deleteEventRequest(request); break; @@ -591,7 +584,7 @@ public class ExecutionManager { if (session == null || thread == null) { return null; } - ThreadInfo info = (ThreadInfo)threadInfoMap.get(thread); + ThreadInfo info = threadInfoMap.get(thread); if (info == null) { //### Should not hardcode initial frame count and prefetch here! //info = new ThreadInfo(thread, 10, 10); @@ -607,24 +600,22 @@ public class ExecutionManager { void validateThreadInfo() { session.interrupted = true; - Iterator iter = threadInfoList.iterator(); - while (iter.hasNext()) { - ((ThreadInfo)iter.next()).validate(); + for (ThreadInfo threadInfo : threadInfoList) { + threadInfo.validate(); } } private void invalidateThreadInfo() { if (session != null) { session.interrupted = false; - Iterator iter = threadInfoList.iterator(); - while (iter.hasNext()) { - ((ThreadInfo)iter.next()).invalidate(); + for (ThreadInfo threadInfo : threadInfoList) { + threadInfo.invalidate(); } } } void removeThreadInfo(ThreadReference thread) { - ThreadInfo info = (ThreadInfo)threadInfoMap.get(thread); + ThreadInfo info = threadInfoMap.get(thread); if (info != null) { info.invalidate(); threadInfoMap.remove(thread); @@ -702,7 +693,7 @@ public class ExecutionManager { while (inputBuffer.size() < 1) { inputLock.wait(); } - line = (String)inputBuffer.removeLast(); + line = inputBuffer.removeLast(); } catch (InterruptedException e) {} } } @@ -774,7 +765,7 @@ public class ExecutionManager { public BreakpointSpec createMethodBreakpoint(String classPattern, - String methodId, List methodArgs) { + String methodId, List methodArgs) { return specList.createMethodBreakpoint(classPattern, methodId, methodArgs); } @@ -811,7 +802,7 @@ public class ExecutionManager { specList.install(spec, vm()); } - public List eventRequestSpecs() { + public List eventRequestSpecs() { return specList.eventRequestSpecs(); } } diff --git a/src/share/classes/com/sun/tools/example/debug/bdi/JDIEventSource.java b/src/share/classes/com/sun/tools/example/debug/bdi/JDIEventSource.java index 2bd45c2fc387e47a7ae0149da0787fd1026ddf0b..97fc6a7f2b0c3c3529d4f657141df10dadd1461c 100644 --- a/src/share/classes/com/sun/tools/example/debug/bdi/JDIEventSource.java +++ b/src/share/classes/com/sun/tools/example/debug/bdi/JDIEventSource.java @@ -82,9 +82,7 @@ class JDIEventSource extends Thread { boolean interrupted = es.suspendedAll(); es.notify(firstListener); boolean wantInterrupt = JDIEventSource.this.wantInterrupt; - for (Iterator it = session.runtime.jdiListeners.iterator(); - it.hasNext(); ) { - JDIListener jl = (JDIListener)it.next(); + for (JDIListener jl : session.runtime.jdiListeners) { es.notify(jl); } if (interrupted && !wantInterrupt) { diff --git a/src/share/classes/com/sun/tools/example/debug/bdi/LineBreakpointSpec.java b/src/share/classes/com/sun/tools/example/debug/bdi/LineBreakpointSpec.java index 0d9c0cc05dd58acdc033dedb75d16c93cac73666..29f05ced6b7dedc894a44665a30f2ac4360f97fa 100644 --- a/src/share/classes/com/sun/tools/example/debug/bdi/LineBreakpointSpec.java +++ b/src/share/classes/com/sun/tools/example/debug/bdi/LineBreakpointSpec.java @@ -58,12 +58,12 @@ public class LineBreakpointSpec extends BreakpointSpec { LineNotFoundException { Location location = null; try { - List locs = clazz.locationsOfLine(lineNumber()); + List locs = clazz.locationsOfLine(lineNumber()); if (locs.size() == 0) { throw new LineNotFoundException(); } // TODO handle multiple locations - location = (Location)locs.get(0); + location = locs.get(0); if (location.method() == null) { throw new LineNotFoundException(); } diff --git a/src/share/classes/com/sun/tools/example/debug/bdi/MethodBreakpointSpec.java b/src/share/classes/com/sun/tools/example/debug/bdi/MethodBreakpointSpec.java index 6a4f5e5a2633e022ff275dce42da86542d0d24f6..0732ed9c2c1965ee50097ee1c029cda16745d7d0 100644 --- a/src/share/classes/com/sun/tools/example/debug/bdi/MethodBreakpointSpec.java +++ b/src/share/classes/com/sun/tools/example/debug/bdi/MethodBreakpointSpec.java @@ -34,11 +34,11 @@ import java.util.Iterator; public class MethodBreakpointSpec extends BreakpointSpec { String methodId; - List methodArgs; + List methodArgs; MethodBreakpointSpec(EventRequestSpecList specs, ReferenceTypeSpec refSpec, - String methodId, List methodArgs) { + String methodId, List methodArgs) { super(specs, refSpec); this.methodId = methodId; this.methodArgs = methodArgs; @@ -76,7 +76,7 @@ public class MethodBreakpointSpec extends BreakpointSpec { return methodId; } - public List methodArgs() { + public List methodArgs() { return methodArgs; } @@ -120,14 +120,13 @@ public class MethodBreakpointSpec extends BreakpointSpec { buffer.append('.'); buffer.append(methodId); if (methodArgs != null) { - Iterator iter = methodArgs.iterator(); boolean first = true; buffer.append('('); - while (iter.hasNext()) { + for (String name : methodArgs) { if (!first) { buffer.append(','); } - buffer.append((String)iter.next()); + buffer.append(name); first = false; } buffer.append(")"); @@ -151,8 +150,8 @@ public class MethodBreakpointSpec extends BreakpointSpec { * and if the number of arguments in the method matches the * number of names passed */ - private boolean compareArgTypes(Method method, List nameList) { - List argTypeNames = method.argumentTypeNames(); + private boolean compareArgTypes(Method method, List nameList) { + List argTypeNames = method.argumentTypeNames(); // If argument counts differ, we can stop here if (argTypeNames.size() != nameList.size()) { @@ -162,8 +161,8 @@ public class MethodBreakpointSpec extends BreakpointSpec { // Compare each argument type's name int nTypes = argTypeNames.size(); for (int i = 0; i < nTypes; ++i) { - String comp1 = (String)argTypeNames.get(i); - String comp2 = (String)nameList.get(i); + String comp1 = argTypeNames.get(i); + String comp2 = nameList.get(i); if (! comp1.equals(comp2)) { /* * We have to handle varargs. EG, the @@ -288,22 +287,17 @@ public class MethodBreakpointSpec extends BreakpointSpec { List argTypeNames = null; if (methodArgs() != null) { argTypeNames = new ArrayList(methodArgs().size()); - Iterator iter = methodArgs().iterator(); - while (iter.hasNext()) { - String name = (String)iter.next(); + for (String name : methodArgs()) { name = normalizeArgTypeName(name); argTypeNames.add(name); } } // Check each method in the class for matches - Iterator iter = clazz.methods().iterator(); Method firstMatch = null; // first method with matching name Method exactMatch = null; // (only) method with same name & sig int matchCount = 0; // > 1 implies overload - while (iter.hasNext()) { - Method candidate = (Method)iter.next(); - + for (Method candidate : clazz.methods()) { if (candidate.name().equals(methodName())) { matchCount++; diff --git a/src/share/classes/com/sun/tools/example/debug/bdi/ThreadGroupIterator.java b/src/share/classes/com/sun/tools/example/debug/bdi/ThreadGroupIterator.java index d9b375cfde8eb326dc5203a81349fc931ea22983..d41901320dd81f54c7521f37e34693b936b7093a 100644 --- a/src/share/classes/com/sun/tools/example/debug/bdi/ThreadGroupIterator.java +++ b/src/share/classes/com/sun/tools/example/debug/bdi/ThreadGroupIterator.java @@ -36,7 +36,7 @@ import java.util.Iterator; * Descend the tree of thread groups. * @author Robert G. Field */ -public class ThreadGroupIterator implements Iterator { +public class ThreadGroupIterator implements Iterator { private final Stack> stack = new Stack>(); @@ -56,8 +56,8 @@ public class ThreadGroupIterator implements Iterator { } */ - private Iterator top() { - return (Iterator)stack.peek(); + private Iterator top() { + return stack.peek(); } /** @@ -77,12 +77,12 @@ public class ThreadGroupIterator implements Iterator { return !stack.isEmpty(); } - public Object next() { + public ThreadGroupReference next() { return nextThreadGroup(); } public ThreadGroupReference nextThreadGroup() { - ThreadGroupReference tg = (ThreadGroupReference)top().next(); + ThreadGroupReference tg = top().next(); push(tg.threadGroups()); return tg; } diff --git a/src/share/classes/com/sun/tools/example/debug/bdi/ThreadIterator.java b/src/share/classes/com/sun/tools/example/debug/bdi/ThreadIterator.java index 36b71e460238dd9c413c79da2d85566e862ab676..bfe57d14a92d304efb30ee5a05f4759b09184333 100644 --- a/src/share/classes/com/sun/tools/example/debug/bdi/ThreadIterator.java +++ b/src/share/classes/com/sun/tools/example/debug/bdi/ThreadIterator.java @@ -30,8 +30,8 @@ import com.sun.jdi.ThreadReference; import java.util.List; import java.util.Iterator; -public class ThreadIterator implements Iterator { - Iterator it = null; +public class ThreadIterator implements Iterator { + Iterator it = null; ThreadGroupIterator tgi; public ThreadIterator(ThreadGroupReference tg) { @@ -53,12 +53,12 @@ public class ThreadIterator implements Iterator { return true; } - public Object next() { + public ThreadReference next() { return it.next(); } public ThreadReference nextThread() { - return (ThreadReference)next(); + return next(); } public void remove() { diff --git a/src/share/classes/com/sun/tools/example/debug/expr/LValue.java b/src/share/classes/com/sun/tools/example/debug/expr/LValue.java index 6b65e0c57a2bcbee79066f86a1b7b8f55016ea11..ae9711d9f0929ed0ac8a9c179c44756d94de9066 100644 --- a/src/share/classes/com/sun/tools/example/debug/expr/LValue.java +++ b/src/share/classes/com/sun/tools/example/debug/expr/LValue.java @@ -191,11 +191,12 @@ abstract class LValue { return field; } - static List methodsByName(ReferenceType refType, String name, int kind) { - List list = refType.methodsByName(name); - Iterator iter = list.iterator(); + static List methodsByName(ReferenceType refType, + String name, int kind) { + List list = refType.methodsByName(name); + Iterator iter = list.iterator(); while (iter.hasNext()) { - Method method = (Method)iter.next(); + Method method = iter.next(); boolean isStatic = method.isStatic(); if (((kind == STATIC) && !isStatic) || ((kind == INSTANCE) && isStatic)) { @@ -231,21 +232,21 @@ abstract class LValue { * argType is not assignable from the type of the argument value. * IE, one is an Apple and the other is an Orange. */ - static int argumentsMatch(List argTypes, List arguments) { + static int argumentsMatch(List argTypes, List arguments) { if (argTypes.size() != arguments.size()) { return DIFFERENT; } - Iterator typeIter = argTypes.iterator(); - Iterator valIter = arguments.iterator(); + Iterator typeIter = argTypes.iterator(); + Iterator valIter = arguments.iterator(); int result = SAME; // If any pair aren't the same, change the // result to ASSIGNABLE. If any pair aren't // assignable, return DIFFERENT while (typeIter.hasNext()) { - Type argType = (Type)typeIter.next(); - Value value = (Value)valIter.next(); + Type argType = typeIter.next(); + Value value = valIter.next(); if (value == null) { // Null values can be passed to any non-primitive argument if (primitiveTypeNames.contains(argType.name())) { @@ -333,7 +334,7 @@ abstract class LValue { if (fromType instanceof ArrayType) { return isArrayAssignableTo((ArrayType)fromType, toType); } - List interfaces; + List interfaces; if (fromType instanceof ClassType) { ClassType superclazz = ((ClassType)fromType).superclass(); if ((superclazz != null) && isAssignableTo(superclazz, toType)) { @@ -344,9 +345,7 @@ abstract class LValue { // fromType must be an InterfaceType interfaces = ((InterfaceType)fromType).superinterfaces(); } - Iterator iter = interfaces.iterator(); - while (iter.hasNext()) { - InterfaceType interfaze = (InterfaceType)iter.next(); + for (InterfaceType interfaze : interfaces) { if (isAssignableTo(interfaze, toType)) { return true; } @@ -354,7 +353,8 @@ abstract class LValue { return false; } - static Method resolveOverload(List overloads, List arguments) + static Method resolveOverload(List overloads, + List arguments) throws ParseException { // If there is only one method to call, we'll just choose @@ -362,7 +362,7 @@ abstract class LValue { // the invoke will return a better error message than we // could generate here. if (overloads.size() == 1) { - return (Method)overloads.get(0); + return overloads.get(0); } // Resolving overloads is beyond the scope of this exercise. @@ -374,12 +374,10 @@ abstract class LValue { // methods to call. And, since casts aren't implemented, // the user can't use them to pick a particular overload to call. // IE, the user is out of luck in this case. - Iterator iter = overloads.iterator(); Method retVal = null; int assignableCount = 0; - while (iter.hasNext()) { - Method mm = (Method)iter.next(); - List argTypes; + for (Method mm : overloads) { + List argTypes; try { argTypes = mm.argumentTypes(); } catch (ClassNotLoadedException ee) { @@ -443,7 +441,7 @@ abstract class LValue { final ObjectReference obj; final ThreadReference thread; final Field matchingField; - final List overloads; + final List overloads; Method matchingMethod = null; List methodArguments = null; @@ -510,7 +508,7 @@ abstract class LValue { final ReferenceType refType; final ThreadReference thread; final Field matchingField; - final List overloads; + final List overloads; Method matchingMethod = null; List methodArguments = null; @@ -765,7 +763,7 @@ abstract class LValue { static LValue makeNewObject(VirtualMachine vm, ExpressionParser.GetFrame frameGetter, String className, List arguments) throws ParseException { - List classes = vm.classesByName(className); + List classes = vm.classesByName(className); if (classes.size() == 0) { throw new ParseException("No class named: " + className); } @@ -774,7 +772,7 @@ abstract class LValue { throw new ParseException("More than one class named: " + className); } - ReferenceType refType = (ReferenceType)classes.get(0); + ReferenceType refType = classes.get(0); if (!(refType instanceof ClassType)) { @@ -784,9 +782,9 @@ abstract class LValue { ClassType classType = (ClassType)refType; List methods = new ArrayList(classType.methods()); // writable - Iterator iter = methods.iterator(); + Iterator iter = methods.iterator(); while (iter.hasNext()) { - Method method = (Method)iter.next(); + Method method = iter.next(); if (!method.isConstructor()) { iter.remove(); } @@ -858,13 +856,13 @@ abstract class LValue { } // check for class name while (izer.hasMoreTokens()) { - List classes = vm.classesByName(first); + List classes = vm.classesByName(first); if (classes.size() > 0) { if (classes.size() > 1) { throw new ParseException("More than one class named: " + first); } else { - ReferenceType refType = (ReferenceType)classes.get(0); + ReferenceType refType = classes.get(0); LValue lval = new LValueStaticMember(refType, izer.nextToken(), thread); return nFields(lval, izer, thread); diff --git a/src/share/classes/com/sun/tools/example/debug/gui/ClassTreeTool.java b/src/share/classes/com/sun/tools/example/debug/gui/ClassTreeTool.java index 6ddb558c4f251fb3fb7ae3d7c190a4e5419549c2..bea3a2745e74a68c12aec94106467e500847b358 100644 --- a/src/share/classes/com/sun/tools/example/debug/gui/ClassTreeTool.java +++ b/src/share/classes/com/sun/tools/example/debug/gui/ClassTreeTool.java @@ -124,9 +124,7 @@ public class ClassTreeTool extends JPanel { public void sessionStart(EventObject e) { // Get system classes and any others loaded before attaching. try { - Iterator iter = runtime.allClasses().iterator(); - while (iter.hasNext()) { - ReferenceType type = ((ReferenceType)iter.next()); + for (ReferenceType type : runtime.allClasses()) { root.addClass(type); } } catch (VMDisconnectedException ee) { diff --git a/src/share/classes/com/sun/tools/example/debug/gui/CommandInterpreter.java b/src/share/classes/com/sun/tools/example/debug/gui/CommandInterpreter.java index e0f96e013164d0214f59cbb7fa50a4db1c65a4f9..7b6aaf5469567847d860dce3d7c5be9c9402fd78 100644 --- a/src/share/classes/com/sun/tools/example/debug/gui/CommandInterpreter.java +++ b/src/share/classes/com/sun/tools/example/debug/gui/CommandInterpreter.java @@ -77,7 +77,7 @@ public class CommandInterpreter { while (ti.hasNext()) { tlist.add(ti.nextThread()); } - threads = (ThreadReference[])tlist.toArray(new ThreadReference[tlist.size()]); + threads = tlist.toArray(new ThreadReference[tlist.size()]); } return threads; } @@ -146,11 +146,9 @@ public class CommandInterpreter { // Command: classes private void commandClasses() throws NoSessionException { - List list = runtime.allClasses(); OutputSink out = env.getOutputSink(); //out.println("** classes list **"); - for (int i = 0 ; i < list.size() ; i++) { - ReferenceType refType = (ReferenceType)list.get(i); + for (ReferenceType refType : runtime.allClasses()) { out.println(refType.name()); } out.show(); @@ -167,16 +165,16 @@ public class CommandInterpreter { String idClass = t.nextToken(); ReferenceType cls = findClass(idClass); if (cls != null) { - List methods = cls.allMethods(); + List methods = cls.allMethods(); OutputSink out = env.getOutputSink(); for (int i = 0; i < methods.size(); i++) { - Method method = (Method)methods.get(i); + Method method = methods.get(i); out.print(method.declaringType().name() + " " + method.name() + "("); - Iterator it = method.argumentTypeNames().iterator(); + Iterator it = method.argumentTypeNames().iterator(); if (it.hasNext()) { while (true) { - out.print((String)it.next()); + out.print(it.next()); if (!it.hasNext()) { break; } @@ -193,10 +191,10 @@ public class CommandInterpreter { } private ReferenceType findClass(String pattern) throws NoSessionException { - List results = runtime.findClassesMatchingPattern(pattern); + List results = runtime.findClassesMatchingPattern(pattern); if (results.size() > 0) { //### Should handle multiple results sensibly. - return (ReferenceType)results.get(0); + return results.get(0); } return null; } @@ -235,11 +233,11 @@ public class CommandInterpreter { private int printThreadGroup(OutputSink out, ThreadGroupReference tg, int iThread) { out.println("Group " + tg.name() + ":"); - List tlist = tg.threads(); + List tlist = tg.threads(); int maxId = 0; int maxName = 0; for (int i = 0 ; i < tlist.size() ; i++) { - ThreadReference thr = (ThreadReference)tlist.get(i); + ThreadReference thr = tlist.get(i); int len = Utils.description(thr).length(); if (len > maxId) maxId = len; @@ -254,7 +252,7 @@ public class CommandInterpreter { String maxNumString = String.valueOf(iThread + tlist.size()); int maxNumDigits = maxNumString.length(); for (int i = 0 ; i < tlist.size() ; i++) { - ThreadReference thr = (ThreadReference)tlist.get(i); + ThreadReference thr = tlist.get(i); char buf[] = new char[80]; for (int j = 0; j < 79; j++) { buf[j] = ' '; @@ -283,9 +281,7 @@ public class CommandInterpreter { sbOut.setLength(79); out.println(sbOut.toString()); } - List tglist = tg.threadGroups(); - for (int ig = 0; ig < tglist.size(); ig++) { - ThreadGroupReference tg0 = (ThreadGroupReference)tglist.get(ig); + for (ThreadGroupReference tg0 : tg.threadGroups()) { if (!tg.equals(tg0)) { // TODO ref mgt iThread += printThreadGroup(out, tg0, iThread + tlist.size()); } @@ -733,7 +729,7 @@ public class CommandInterpreter { if (token.toLowerCase().equals("all")) { ThreadIterator it = allThreads(); while (it.hasNext()) { - ThreadReference thread = (ThreadReference)it.next(); + ThreadReference thread = it.next(); out.println(thread.name() + ": "); dumpStack(thread, showPC); } @@ -755,7 +751,7 @@ public class CommandInterpreter { //env.failure("Target VM must be in interrupted state."); //env.failure("Current thread isn't suspended."); //### Should handle extremely long stack traces sensibly for user. - List stack = null; + List stack = null; try { stack = thread.frames(); } catch (IncompatibleThreadStateException e) { @@ -772,7 +768,7 @@ public class CommandInterpreter { OutputSink out = env.getOutputSink(); int nFrames = stack.size(); for (int i = frameIndex; i < nFrames; i++) { - StackFrame frame = (StackFrame)stack.get(i); + StackFrame frame = stack.get(i); Location loc = frame.location(); Method meth = loc.method(); out.print(" [" + (i + 1) + "] "); @@ -780,7 +776,7 @@ public class CommandInterpreter { out.print('.'); out.print(meth.name()); out.print(" ("); - if (meth instanceof Method && ((Method)meth).isNative()) { + if (meth.isNative()) { out.print("native method"); } else if (loc.lineNumber() != -1) { try { @@ -806,14 +802,13 @@ public class CommandInterpreter { private void listEventRequests() throws NoSessionException { // Print set breakpoints - Iterator iter = runtime.eventRequestSpecs().iterator(); - if (!iter.hasNext()) { + List specs = runtime.eventRequestSpecs(); + if (specs.isEmpty()) { env.notice("No breakpoints/watchpoints/exceptions set."); } else { OutputSink out = env.getOutputSink(); out.println("Current breakpoints/watchpoints/exceptions set:"); - while (iter.hasNext()) { - EventRequestSpec bp = (EventRequestSpec)iter.next(); + for (EventRequestSpec bp : specs) { out.println("\t" + bp); } out.show(); @@ -926,13 +921,13 @@ public class CommandInterpreter { //### need 'clear all' BreakpointSpec bpSpec = parseBreakpointSpec(t.nextToken()); if (bpSpec != null) { - Iterator iter = runtime.eventRequestSpecs().iterator(); - if (!iter.hasNext()) { + List specs = runtime.eventRequestSpecs(); + + if (specs.isEmpty()) { env.notice("No breakpoints set."); } else { - List toDelete = new ArrayList(); - while (iter.hasNext()) { - BreakpointSpec spec = (BreakpointSpec)iter.next(); + List toDelete = new ArrayList(); + for (EventRequestSpec spec : specs) { if (spec.equals(bpSpec)) { toDelete.add(spec); } @@ -941,7 +936,7 @@ public class CommandInterpreter { if (toDelete.size() <= 1) { env.notice("No matching breakpoint set."); } - for (BreakpointSpec spec : toDelete) { + for (EventRequestSpec spec : toDelete) { runtime.delete(spec); } } @@ -988,7 +983,7 @@ public class CommandInterpreter { lineno = Integer.valueOf(id).intValue(); } catch (NumberFormatException nfe) { // It isn't -- see if it's a method name. - List meths = refType.methodsByName(id); + List meths = refType.methodsByName(id); if (meths == null || meths.size() == 0) { env.failure(id + " is not a valid line number or " + @@ -1001,7 +996,7 @@ public class CommandInterpreter { refType.name()); return; } - loc = ((Method)meths.get(0)).location(); + loc = meths.get(0).location(); lineno = loc.lineNumber(); } } @@ -1121,7 +1116,7 @@ public class CommandInterpreter { return; } - List vars; + List vars; try { vars = frame.visibleVariables(); if (vars == null || vars.size() == 0) { @@ -1136,15 +1131,13 @@ public class CommandInterpreter { OutputSink out = env.getOutputSink(); out.println("Method arguments:"); - for (Iterator it = vars.iterator(); it.hasNext(); ) { - LocalVariable var = (LocalVariable)it.next(); + for (LocalVariable var : vars) { if (var.isArgument()) { printVar(out, var, frame); } } out.println("Local variables:"); - for (Iterator it = vars.iterator(); it.hasNext(); ) { - LocalVariable var = (LocalVariable)it.next(); + for (LocalVariable var : vars) { if (!var.isArgument()) { printVar(out, var, frame); } @@ -1245,8 +1238,7 @@ public class CommandInterpreter { private void dump(OutputSink out, ObjectReference obj, ReferenceType refType, ReferenceType refTypeBase) { - for (Iterator it = refType.fields().iterator(); it.hasNext(); ) { - Field field = (Field)it.next(); + for (Field field : refType.fields()) { out.print(" "); if (!refType.equals(refTypeBase)) { out.print(refType.name() + "."); @@ -1261,9 +1253,8 @@ public class CommandInterpreter { dump(out, obj, sup, refTypeBase); } } else if (refType instanceof InterfaceType) { - List sups = ((InterfaceType)refType).superinterfaces(); - for (Iterator it = sups.iterator(); it.hasNext(); ) { - dump(out, obj, (ReferenceType)it.next(), refTypeBase); + for (InterfaceType sup : ((InterfaceType)refType).superinterfaces()) { + dump(out, obj, sup, refTypeBase); } } } diff --git a/src/share/classes/com/sun/tools/example/debug/gui/JDBFileFilter.java b/src/share/classes/com/sun/tools/example/debug/gui/JDBFileFilter.java index ddb71921dc1816a22fbddfba83094e8b34730db4..5963ef2e0dfb115838bc866c4631675cc2ad9ac2 100644 --- a/src/share/classes/com/sun/tools/example/debug/gui/JDBFileFilter.java +++ b/src/share/classes/com/sun/tools/example/debug/gui/JDBFileFilter.java @@ -201,11 +201,11 @@ public class JDBFileFilter extends FileFilter { if(description == null || isExtensionListInDescription()) { fullDescription = description==null ? "(" : description + " ("; // build the description from the extension list - Enumeration extensions = filters.keys(); + Enumeration extensions = filters.keys(); if(extensions != null) { - fullDescription += "." + (String) extensions.nextElement(); + fullDescription += "." + extensions.nextElement(); while (extensions.hasMoreElements()) { - fullDescription += ", " + (String) extensions.nextElement(); + fullDescription += ", " + extensions.nextElement(); } } fullDescription += ")"; diff --git a/src/share/classes/com/sun/tools/example/debug/gui/LaunchTool.java b/src/share/classes/com/sun/tools/example/debug/gui/LaunchTool.java index 7aed53869e15fe8d1f45325a36608cb2037f6c99..fc115b9078eb0f69b95ac5c38ec68de6e4ec8498 100644 --- a/src/share/classes/com/sun/tools/example/debug/gui/LaunchTool.java +++ b/src/share/classes/com/sun/tools/example/debug/gui/LaunchTool.java @@ -131,14 +131,13 @@ class LaunchTool { final JPanel radioPanel = new JPanel(); final ButtonGroup radioGroup = new ButtonGroup(); VirtualMachineManager manager = Bootstrap.virtualMachineManager(); - List all = manager.allConnectors(); + List all = manager.allConnectors(); Map modelToConnector = new HashMap(all.size(), 0.5f); dialog.setModal(true); dialog.setTitle("Select Connector Type"); radioPanel.setLayout(new BoxLayout(radioPanel, BoxLayout.Y_AXIS)); - for (Iterator it = all.iterator(); it.hasNext(); ) { - Connector connector = (Connector)it.next(); + for (Connector connector : all) { JRadioButton radio = new JRadioButton(connector.description()); modelToConnector.put(radio.getModel(), connector); radioPanel.add(radio); @@ -166,7 +165,7 @@ class LaunchTool { dialog.show(); return oked[0] ? - (Connector)(modelToConnector.get(radioGroup.getSelection())) : + modelToConnector.get(radioGroup.getSelection()) : null; } @@ -188,13 +187,12 @@ class LaunchTool { // guts.add(new JLabel(connector.description())); final List argReps = new ArrayList(args.size()); - for (Iterator it = args.values().iterator(); it.hasNext(); ) { - Object arg = it.next(); + for (Connector.Argument arg : args.values()) { ArgRep ar; if (arg instanceof Connector.BooleanArgument) { ar = new BooleanArgRep((Connector.BooleanArgument)arg, guts); } else { - ar = new StringArgRep((Connector.Argument)arg, guts); + ar = new StringArgRep(arg, guts); } argReps.add(ar); } @@ -202,8 +200,7 @@ class LaunchTool { JPanel buttonPanel = okCancel( dialog, new ActionListener() { public void actionPerformed(ActionEvent event) { - for (Iterator it = argReps.iterator(); it.hasNext(); ) { - ArgRep ar = (ArgRep)it.next(); + for (ArgRep ar : argReps) { if (!ar.isSpecified()) { JOptionPane.showMessageDialog(dialog, ar.arg.label() + diff --git a/src/share/classes/com/sun/tools/example/debug/gui/SearchPath.java b/src/share/classes/com/sun/tools/example/debug/gui/SearchPath.java index 45f7ac7eb4dff22612f320d2f25a6320d6a15847..1d61c8fa068c76201b2f53d15813ec9b9c4baf4c 100644 --- a/src/share/classes/com/sun/tools/example/debug/gui/SearchPath.java +++ b/src/share/classes/com/sun/tools/example/debug/gui/SearchPath.java @@ -42,7 +42,7 @@ public class SearchPath { dlist.add(st.nextToken()); } pathString = searchPath; - pathArray = (String[])dlist.toArray(new String[dlist.size()]); + pathArray = dlist.toArray(new String[dlist.size()]); } public boolean isEmpty() { @@ -54,7 +54,7 @@ public class SearchPath { } public String[] asArray() { - return (String[])pathArray.clone(); + return pathArray.clone(); } public File resolve(String relativeFileName) { @@ -89,7 +89,7 @@ public class SearchPath { } } } - return (String[])s.toArray(new String[s.size()]); + return s.toArray(new String[s.size()]); } } diff --git a/src/share/classes/com/sun/tools/example/debug/gui/SourceManager.java b/src/share/classes/com/sun/tools/example/debug/gui/SourceManager.java index 56667100dd13c19051219c20ef11e848311d6049..7173b5f1014c1ef7b4247fa23ed266619bf42f05 100644 --- a/src/share/classes/com/sun/tools/example/debug/gui/SourceManager.java +++ b/src/share/classes/com/sun/tools/example/debug/gui/SourceManager.java @@ -113,7 +113,7 @@ public class SourceManager { * Returns null if not available. */ public SourceModel sourceForClass(ReferenceType refType) { - SourceModel sm = (SourceModel)classToSource.get(refType); + SourceModel sm = classToSource.get(refType); if (sm != null) { return sm; } @@ -140,10 +140,10 @@ public class SourceManager { */ //### Use hash table for this? public SourceModel sourceForFile(File path) { - Iterator iter = sourceList.iterator(); + Iterator iter = sourceList.iterator(); SourceModel sm = null; while (iter.hasNext()) { - SourceModel candidate = (SourceModel)iter.next(); + SourceModel candidate = iter.next(); if (candidate.fileName().equals(path)) { sm = candidate; iter.remove(); // Will move to start of list. diff --git a/src/share/classes/com/sun/tools/example/debug/gui/SourceModel.java b/src/share/classes/com/sun/tools/example/debug/gui/SourceModel.java index 6bb1e551e420e53369b1e4dbb50920ddac0ccfb5..75cdca6857d0f9c9478623441f4c3e5c79144049 100644 --- a/src/share/classes/com/sun/tools/example/debug/gui/SourceModel.java +++ b/src/share/classes/com/sun/tools/example/debug/gui/SourceModel.java @@ -187,22 +187,17 @@ public class SourceModel extends AbstractListModel { * when sourceLines is set. */ private void markClassLines(ReferenceType refType) { - List methods = refType.methods(); - for (Iterator mit = methods.iterator(); mit.hasNext();) { - Method meth = (Method)mit.next(); + for (Method meth : refType.methods()) { try { - List lines = meth.allLineLocations(); - for (Iterator lit = lines.iterator(); lit.hasNext();) { - Location loc = (Location)lit.next(); + for (Location loc : meth.allLineLocations()) { showExecutable(loc.lineNumber(), refType); } } catch (AbsentInformationException exc) { // do nothing } } - List bps = env.getExecutionManager().eventRequestManager().breakpointRequests(); - for (Iterator it = bps.iterator(); it.hasNext();) { - BreakpointRequest bp = (BreakpointRequest)it.next(); + for (BreakpointRequest bp : + env.getExecutionManager().eventRequestManager().breakpointRequests()) { if (bp.location() != null) { Location loc = bp.location(); if (loc.declaringType().equals(refType)) { @@ -224,8 +219,8 @@ public class SourceModel extends AbstractListModel { } finally { reader.close(); } - for (Iterator it = classes.iterator(); it.hasNext();) { - markClassLines((ClassType)it.next()); + for (ReferenceType refType : classes) { + markClassLines(refType); } } diff --git a/src/share/classes/com/sun/tools/example/debug/gui/StackTraceTool.java b/src/share/classes/com/sun/tools/example/debug/gui/StackTraceTool.java index 7f4c857895aa54937a77f1f9cfd2823a07e074d4..78476f0d98b820a0f827161c59eedb8e76f281a0 100644 --- a/src/share/classes/com/sun/tools/example/debug/gui/StackTraceTool.java +++ b/src/share/classes/com/sun/tools/example/debug/gui/StackTraceTool.java @@ -139,7 +139,7 @@ public class StackTraceTool extends JPanel { String methName = meth.declaringType().name() + '.' + meth.name(); String position = ""; - if (meth instanceof Method && ((Method)meth).isNative()) { + if (meth.isNative()) { position = " (native method)"; } else if (loc.lineNumber() != -1) { position = ":" + loc.lineNumber(); diff --git a/src/share/classes/com/sun/tools/example/debug/gui/ThreadTreeTool.java b/src/share/classes/com/sun/tools/example/debug/gui/ThreadTreeTool.java index 3b6d5fc4181f86f6372d74bef77caf28481ae0d1..955c5b6cbc19b45f0e3b3d3ce3686af384e7d1b4 100644 --- a/src/share/classes/com/sun/tools/example/debug/gui/ThreadTreeTool.java +++ b/src/share/classes/com/sun/tools/example/debug/gui/ThreadTreeTool.java @@ -133,9 +133,7 @@ public class ThreadTreeTool extends JPanel { public void sessionStart(EventObject e) { try { - Iterator iter = runtime.allThreads().iterator(); - while (iter.hasNext()) { - ThreadReference thread = ((ThreadReference)iter.next()); + for (ThreadReference thread : runtime.allThreads()) { root.addThread(thread); } } catch (VMDisconnectedException ee) { @@ -244,16 +242,16 @@ public class ThreadTreeTool extends JPanel { } } - private void addThread(List threadPath, ThreadReference thread) { + private void addThread(List threadPath, ThreadReference thread) { int size = threadPath.size(); if (size == 0) { return; } else if (size == 1) { - String name = (String)threadPath.get(0); + String name = threadPath.get(0); insertNode(name, thread); } else { - String head = (String)threadPath.get(0); - List tail = threadPath.subList(1, size); + String head = threadPath.get(0); + List tail = threadPath.subList(1, size); ThreadTreeNode child = insertNode(head, null); child.addThread(tail, thread); } @@ -288,17 +286,17 @@ public class ThreadTreeTool extends JPanel { } } - private void removeThread(List threadPath, ThreadReference thread) { + private void removeThread(List threadPath, ThreadReference thread) { int size = threadPath.size(); if (size == 0) { return; } else if (size == 1) { - String name = (String)threadPath.get(0); + String name = threadPath.get(0); ThreadTreeNode child = findLeafNode(thread, name); treeModel.removeNodeFromParent(child); } else { - String head = (String)threadPath.get(0); - List tail = threadPath.subList(1, size); + String head = threadPath.get(0); + List tail = threadPath.subList(1, size); ThreadTreeNode child = findInternalNode(head); child.removeThread(tail, thread); if (child.isThreadGroup() && child.getChildCount() < 1) { diff --git a/src/share/classes/com/sun/tools/example/debug/tty/BreakpointSpec.java b/src/share/classes/com/sun/tools/example/debug/tty/BreakpointSpec.java index c79f17e36082d86c70258e203ad142a342cff90d..c6d437d29e6118b9aaf3a52d05f763bdfaa307ba 100644 --- a/src/share/classes/com/sun/tools/example/debug/tty/BreakpointSpec.java +++ b/src/share/classes/com/sun/tools/example/debug/tty/BreakpointSpec.java @@ -34,7 +34,7 @@ import java.util.Iterator; class BreakpointSpec extends EventRequestSpec { String methodId; - List methodArgs; + List methodArgs; int lineNumber; BreakpointSpec(ReferenceTypeSpec refSpec, int lineNumber) { @@ -45,7 +45,7 @@ class BreakpointSpec extends EventRequestSpec { } BreakpointSpec(ReferenceTypeSpec refSpec, String methodId, - List methodArgs) throws MalformedMemberNameException { + List methodArgs) throws MalformedMemberNameException { super(refSpec); this.methodId = methodId; this.methodArgs = methodArgs; @@ -83,7 +83,7 @@ class BreakpointSpec extends EventRequestSpec { return lineNumber; } - List methodArgs() { + List methodArgs() { return methodArgs; } @@ -146,14 +146,13 @@ class BreakpointSpec extends EventRequestSpec { buffer.append('.'); buffer.append(methodId); if (methodArgs != null) { - Iterator iter = methodArgs.iterator(); boolean first = true; buffer.append('('); - while (iter.hasNext()) { + for (String arg : methodArgs) { if (!first) { buffer.append(','); } - buffer.append((String)iter.next()); + buffer.append(arg); first = false; } buffer.append(")"); @@ -176,12 +175,12 @@ class BreakpointSpec extends EventRequestSpec { location = method.location(); } else { // let AbsentInformationException be thrown - List locs = refType.locationsOfLine(lineNumber()); + List locs = refType.locationsOfLine(lineNumber()); if (locs.size() == 0) { throw new LineNotFoundException(); } // TO DO: handle multiple locations - location = (Location)locs.get(0); + location = locs.get(0); if (location.method() == null) { throw new LineNotFoundException(); } @@ -202,8 +201,8 @@ class BreakpointSpec extends EventRequestSpec { * and if the number of arguments in the method matches the * number of names passed */ - private boolean compareArgTypes(Method method, List nameList) { - List argTypeNames = method.argumentTypeNames(); + private boolean compareArgTypes(Method method, List nameList) { + List argTypeNames = method.argumentTypeNames(); // If argument counts differ, we can stop here if (argTypeNames.size() != nameList.size()) { @@ -213,8 +212,8 @@ class BreakpointSpec extends EventRequestSpec { // Compare each argument type's name int nTypes = argTypeNames.size(); for (int i = 0; i < nTypes; ++i) { - String comp1 = (String)argTypeNames.get(i); - String comp2 = (String)nameList.get(i); + String comp1 = argTypeNames.get(i); + String comp2 = nameList.get(i); if (! comp1.equals(comp2)) { /* * We have to handle varargs. EG, the @@ -331,22 +330,17 @@ class BreakpointSpec extends EventRequestSpec { List argTypeNames = null; if (methodArgs() != null) { argTypeNames = new ArrayList(methodArgs().size()); - Iterator iter = methodArgs().iterator(); - while (iter.hasNext()) { - String name = (String)iter.next(); + for (String name : methodArgs()) { name = normalizeArgTypeName(name); argTypeNames.add(name); } } // Check each method in the class for matches - Iterator iter = refType.methods().iterator(); Method firstMatch = null; // first method with matching name Method exactMatch = null; // (only) method with same name & sig int matchCount = 0; // > 1 implies overload - while (iter.hasNext()) { - Method candidate = (Method)iter.next(); - + for (Method candidate : refType.methods()) { if (candidate.name().equals(methodName())) { matchCount++; diff --git a/src/share/classes/com/sun/tools/example/debug/tty/Commands.java b/src/share/classes/com/sun/tools/example/debug/tty/Commands.java index 0f913eabaec690c8bc5ef90dec849277db59f52a..e607d7165d4b82025888ee7b20274b10d9224535 100644 --- a/src/share/classes/com/sun/tools/example/debug/tty/Commands.java +++ b/src/share/classes/com/sun/tools/example/debug/tty/Commands.java @@ -157,16 +157,16 @@ class Commands { buf.append(method.name()); buf.append("("); - List args = method.argumentTypeNames(); + List args = method.argumentTypeNames(); int lastParam = args.size() - 1; // output param types except for the last for (int ii = 0; ii < lastParam; ii++) { - buf.append((String)args.get(ii)); + buf.append(args.get(ii)); buf.append(", "); } if (lastParam >= 0) { // output the last param - String lastStr = (String)args.get(lastParam); + String lastStr = args.get(lastParam); if (method.isVarArgs()) { // lastParam is an array. Replace the [] with ... buf.append(lastStr.substring(0, lastStr.length() - 2)); @@ -180,12 +180,11 @@ class Commands { } void commandConnectors(VirtualMachineManager vmm) { - Iterator iter = vmm.allConnectors().iterator(); - if (iter.hasNext()) { + Collection ccs = vmm.allConnectors(); + if (ccs.isEmpty()) { MessageOutput.println("Connectors available"); } - while (iter.hasNext()) { - Connector cc = (Connector)iter.next(); + for (Connector cc : ccs) { String transportName = cc.transport() == null ? "null" : cc.transport().name(); MessageOutput.println(); @@ -193,10 +192,7 @@ class Commands { new Object [] {cc.name(), transportName}); MessageOutput.println("Connector description", cc.description()); - Iterator argIter = cc.defaultArguments().values().iterator(); - if (argIter.hasNext()) { - while (argIter.hasNext()) { - Connector.Argument aa = (Connector.Argument)argIter.next(); + for (Connector.Argument aa : cc.defaultArguments().values()) { MessageOutput.println(); boolean requiredArgument = aa.mustSpecify(); @@ -215,16 +211,12 @@ class Commands { } } - } } void commandClasses() { - List list = Env.vm().allClasses(); - StringBuffer classList = new StringBuffer(); - for (int i = 0 ; i < list.size() ; i++) { - ReferenceType refType = (ReferenceType)list.get(i); + for (ReferenceType refType : Env.vm().allClasses()) { classList.append(refType.name()); classList.append("\n"); } @@ -232,7 +224,7 @@ class Commands { } void commandClass(StringTokenizer t) { - List list = Env.vm().allClasses(); + List list = Env.vm().allClasses(); if (!t.hasMoreTokens()) { MessageOutput.println("No class specified."); @@ -265,51 +257,31 @@ class Commands { superclass = showAll ? superclass.superclass() : null; } - List interfaces = showAll ? clazz.allInterfaces() - : clazz.interfaces(); - Iterator iter = interfaces.iterator(); - while (iter.hasNext()) { - InterfaceType interfaze = (InterfaceType)iter.next(); + List interfaces = + showAll ? clazz.allInterfaces() : clazz.interfaces(); + for (InterfaceType interfaze : interfaces) { MessageOutput.println("implements:", interfaze.name()); } - List subs = clazz.subclasses(); - iter = subs.iterator(); - while (iter.hasNext()) { - ClassType sub = (ClassType)iter.next(); + for (ClassType sub : clazz.subclasses()) { MessageOutput.println("subclass:", sub.name()); } - List nested = clazz.nestedTypes(); - iter = nested.iterator(); - while (iter.hasNext()) { - ReferenceType nest = (ReferenceType)iter.next(); + for (ReferenceType nest : clazz.nestedTypes()) { MessageOutput.println("nested:", nest.name()); } } else if (type instanceof InterfaceType) { InterfaceType interfaze = (InterfaceType)type; MessageOutput.println("Interface:", interfaze.name()); - List supers = interfaze.superinterfaces(); - Iterator iter = supers.iterator(); - while (iter.hasNext()) { - InterfaceType superinterface = (InterfaceType)iter.next(); + for (InterfaceType superinterface : interfaze.superinterfaces()) { MessageOutput.println("extends:", superinterface.name()); } - List subs = interfaze.subinterfaces(); - iter = subs.iterator(); - while (iter.hasNext()) { - InterfaceType sub = (InterfaceType)iter.next(); + for (InterfaceType sub : interfaze.subinterfaces()) { MessageOutput.println("subinterface:", sub.name()); } - List implementors = interfaze.implementors(); - iter = implementors.iterator(); - while (iter.hasNext()) { - ClassType implementor = (ClassType)iter.next(); + for (ClassType implementor : interfaze.implementors()) { MessageOutput.println("implementor:", implementor.name()); } - List nested = interfaze.nestedTypes(); - iter = nested.iterator(); - while (iter.hasNext()) { - ReferenceType nest = (ReferenceType)iter.next(); + for (ReferenceType nest : interfaze.nestedTypes()) { MessageOutput.println("nested:", nest.name()); } } else { // array type @@ -327,10 +299,8 @@ class Commands { String idClass = t.nextToken(); ReferenceType cls = Env.getReferenceTypeFromToken(idClass); if (cls != null) { - List methods = cls.allMethods(); StringBuffer methodsList = new StringBuffer(); - for (int i = 0; i < methods.size(); i++) { - Method method = (Method)methods.get(i); + for (Method method : cls.allMethods()) { methodsList.append(method.declaringType().name()); methodsList.append(" "); methodsList.append(typedName(method)); @@ -351,11 +321,10 @@ class Commands { String idClass = t.nextToken(); ReferenceType cls = Env.getReferenceTypeFromToken(idClass); if (cls != null) { - List fields = cls.allFields(); - List visible = cls.visibleFields(); + List fields = cls.allFields(); + List visible = cls.visibleFields(); StringBuffer fieldsList = new StringBuffer(); - for (int i = 0; i < fields.size(); i++) { - Field field = (Field)fields.get(i); + for (Field field : fields) { String s; if (!visible.contains(field)) { s = MessageOutput.format("list field typename and name hidden", @@ -386,7 +355,7 @@ class Commands { int maxIdLength = 0; int maxNameLength = 0; while (threadIter.hasNext()) { - ThreadReference thr = (ThreadReference)threadIter.next(); + ThreadReference thr = threadIter.next(); maxIdLength = Math.max(maxIdLength, Env.description(thr).length()); maxNameLength = Math.max(maxNameLength, @@ -395,7 +364,7 @@ class Commands { threadIter = new ThreadIterator(tg); while (threadIter.hasNext()) { - ThreadReference thr = (ThreadReference)threadIter.next(); + ThreadReference thr = threadIter.next(); if (thr.threadGroup() == null) { continue; } @@ -588,9 +557,7 @@ class Commands { private List allThreads(ThreadGroupReference group) { List list = new ArrayList(); list.addAll(group.threads()); - Iterator iter = group.threadGroups().iterator(); - while (iter.hasNext()) { - ThreadGroupReference child = (ThreadGroupReference)iter.next(); + for (ThreadGroupReference child : group.threadGroups()) { list.addAll(allThreads(child)); } return list; @@ -641,10 +608,7 @@ class Commands { * if so, it gets removed here. */ EventRequestManager mgr = Env.vm().eventRequestManager(); - List requests = mgr.stepRequests(); - Iterator iter = requests.iterator(); - while (iter.hasNext()) { - StepRequest request = (StepRequest)iter.next(); + for (StepRequest request : mgr.stepRequests()) { if (request.thread().equals(thread)) { mgr.deleteEventRequest(request); break; @@ -768,9 +732,7 @@ class Commands { boolean noExceptions = true; // Print a listing of the catch patterns currently in place - Iterator iter = Env.specList.eventRequestSpecs().iterator(); - while (iter.hasNext()) { - EventRequestSpec spec = (EventRequestSpec)iter.next(); + for (EventRequestSpec spec : Env.specList.eventRequestSpecs()) { if (spec instanceof ExceptionSpec) { if (noExceptions) { noExceptions = false; @@ -928,7 +890,7 @@ class Commands { } private void dumpStack(ThreadInfo threadInfo, boolean showPC) { - List stack = null; + List stack = null; try { stack = threadInfo.getStack(); } catch (IncompatibleThreadStateException e) { @@ -940,7 +902,7 @@ class Commands { } else { int nFrames = stack.size(); for (int i = threadInfo.getCurrentFrameIndex(); i < nFrames; i++) { - StackFrame frame = (StackFrame)stack.get(i); + StackFrame frame = stack.get(i); dumpFrame (i, showPC, frame); } } @@ -956,7 +918,7 @@ class Commands { long lineNumber = loc.lineNumber(); String methodInfo = null; - if (meth instanceof Method && ((Method)meth).isNative()) { + if (meth.isNative()) { methodInfo = MessageOutput.format("native method"); } else if (lineNumber != -1) { try { @@ -994,9 +956,7 @@ class Commands { } else { String token = t.nextToken(); if (token.toLowerCase().equals("all")) { - Iterator iter = ThreadInfo.threads().iterator(); - while (iter.hasNext()) { - ThreadInfo threadInfo = (ThreadInfo)iter.next(); + for (ThreadInfo threadInfo : ThreadInfo.threads()) { MessageOutput.println("Thread:", threadInfo.getThread().name()); dumpStack(threadInfo, showPC); @@ -1051,9 +1011,7 @@ class Commands { boolean noBreakpoints = true; // Print set breakpoints - Iterator iter = Env.specList.eventRequestSpecs().iterator(); - while (iter.hasNext()) { - EventRequestSpec spec = (EventRequestSpec)iter.next(); + for (EventRequestSpec spec : Env.specList.eventRequestSpecs()) { if (spec instanceof BreakpointSpec) { if (noBreakpoints) { noBreakpoints = false; @@ -1075,7 +1033,7 @@ class Commands { protected BreakpointSpec parseBreakpointSpec(StringTokenizer t, String atForm, String inForm) { - EventRequestSpec breakpoint = null; + BreakpointSpec breakpoint = null; try { String token = t.nextToken(":( \t\n\r"); @@ -1149,7 +1107,7 @@ class Commands { printBreakpointCommandUsage(atForm, inForm); return null; } - return (BreakpointSpec)breakpoint; + return breakpoint; } private void resolveNow(EventRequestSpec spec) { @@ -1209,8 +1167,8 @@ class Commands { } } - private List parseWatchpointSpec(StringTokenizer t) { - List list = new ArrayList(); + private List parseWatchpointSpec(StringTokenizer t) { + List list = new ArrayList(); boolean access = false; boolean modification = false; int suspendPolicy = EventRequest.SUSPEND_ALL; @@ -1242,7 +1200,7 @@ class Commands { fieldName = fieldName.substring(dot+1); try { - EventRequestSpec spec; + WatchpointSpec spec; if (access) { spec = Env.specList.createAccessWatchpoint(className, fieldName); @@ -1269,9 +1227,8 @@ class Commands { return; } - Iterator iter = parseWatchpointSpec(t).iterator(); - while (iter.hasNext()) { - resolveNow((WatchpointSpec)iter.next()); + for (WatchpointSpec spec : parseWatchpointSpec(t)) { + resolveNow(spec); } } @@ -1281,9 +1238,7 @@ class Commands { return; } - Iterator iter = parseWatchpointSpec(t).iterator(); - while (iter.hasNext()) { - WatchpointSpec spec = (WatchpointSpec)iter.next(); + for (WatchpointSpec spec : parseWatchpointSpec(t)) { if (Env.specList.delete(spec)) { MessageOutput.println("Removed:", spec.toString()); } else { @@ -1482,7 +1437,7 @@ class Commands { lineno = n.intValue(); } catch (java.text.ParseException jtpe) { // It isn't -- see if it's a method name. - List meths = refType.methodsByName(id); + List meths = refType.methodsByName(id); if (meths == null || meths.size() == 0) { MessageOutput.println("is not a valid line number or method name for", new Object [] {id, refType.name()}); @@ -1492,7 +1447,7 @@ class Commands { new Object [] {id, refType.name()}); return; } - loc = ((Method)meths.get(0)).location(); + loc = meths.get(0).location(); lineno = loc.lineNumber(); } } @@ -1539,14 +1494,11 @@ class Commands { try { ReferenceType refType = Env.getReferenceTypeFromToken(idClass); if (refType != null) { - List lines = null; + List lines = null; if (idMethod == null) { lines = refType.allLineLocations(); } else { - List methods = refType.allMethods(); - Iterator iter = methods.iterator(); - while (iter.hasNext()) { - Method method = (Method)iter.next(); + for (Method method : refType.allMethods()) { if (method.name().equals(idMethod)) { lines = method.allLineLocations(); } @@ -1555,9 +1507,7 @@ class Commands { MessageOutput.println("is not a valid method name", idMethod); } } - Iterator iter = lines.iterator(); - while (iter.hasNext()) { - Location line = (Location)iter.next(); + for (Location line : lines) { MessageOutput.printDirectln(line.toString());// Special case: use printDirectln() } } else { @@ -1620,21 +1570,19 @@ class Commands { MessageOutput.println("No local variables"); return; } - Map values = frame.getValues(vars); + Map values = frame.getValues(vars); MessageOutput.println("Method arguments:"); - for (Iterator it = vars.iterator(); it.hasNext(); ) { - LocalVariable var = (LocalVariable)it.next(); + for (LocalVariable var : vars) { if (var.isArgument()) { - Value val = (Value)values.get(var); + Value val = values.get(var); printVar(var, val); } } MessageOutput.println("Local variables:"); - for (Iterator it = vars.iterator(); it.hasNext(); ) { - LocalVariable var = (LocalVariable)it.next(); + for (LocalVariable var : vars) { if (!var.isArgument()) { - Value val = (Value)values.get(var); + Value val = values.get(var); printVar(var, val); } } @@ -1647,9 +1595,8 @@ class Commands { private void dump(ObjectReference obj, ReferenceType refType, ReferenceType refTypeBase) { - for (Iterator it = refType.fields().iterator(); it.hasNext(); ) { + for (Field field : refType.fields()) { StringBuffer o = new StringBuffer(); - Field field = (Field)it.next(); o.append(" "); if (!refType.equals(refTypeBase)) { o.append(refType.name()); @@ -1666,14 +1613,13 @@ class Commands { dump(obj, sup, refTypeBase); } } else if (refType instanceof InterfaceType) { - List sups = ((InterfaceType)refType).superinterfaces(); - for (Iterator it = sups.iterator(); it.hasNext(); ) { - dump(obj, (ReferenceType)it.next(), refTypeBase); + for (InterfaceType sup : ((InterfaceType)refType).superinterfaces()) { + dump(obj, sup, refTypeBase); } } else { /* else refType is an instanceof ArrayType */ if (obj instanceof ArrayReference) { - for (Iterator it = ((ArrayReference)obj).getValues().iterator(); + for (Iterator it = ((ArrayReference)obj).getValues().iterator(); it.hasNext(); ) { MessageOutput.printDirect(it.next().toString());// Special case: use printDirect() if (it.hasNext()) { @@ -1770,13 +1716,11 @@ class Commands { new Object [] {owner.name(), new Integer (object.entryCount())}); } - List waiters = object.waitingThreads(); + List waiters = object.waitingThreads(); if (waiters.size() == 0) { MessageOutput.println("No waiters"); } else { - Iterator iter = waiters.iterator(); - while (iter.hasNext()) { - ThreadReference waiter = (ThreadReference)iter.next(); + for (ThreadReference waiter : waiters) { MessageOutput.println("Waiting thread:", waiter.name()); } } @@ -1800,13 +1744,11 @@ class Commands { ThreadReference thread = threadInfo.getThread(); try { MessageOutput.println("Monitor information for thread", thread.name()); - List owned = thread.ownedMonitors(); + List owned = thread.ownedMonitors(); if (owned.size() == 0) { MessageOutput.println("No monitors owned"); } else { - Iterator iter = owned.iterator(); - while (iter.hasNext()) { - ObjectReference monitor = (ObjectReference)iter.next(); + for (ObjectReference monitor : owned) { MessageOutput.println("Owned monitor:", monitor.toString()); } } @@ -1833,9 +1775,7 @@ class Commands { } String token = t.nextToken(); if (token.toLowerCase().equals("all")) { - Iterator iter = ThreadInfo.threads().iterator(); - while (iter.hasNext()) { - ThreadInfo threadInfo = (ThreadInfo)iter.next(); + for (ThreadInfo threadInfo : ThreadInfo.threads()) { printThreadLockInfo(threadInfo); } } else { @@ -1930,14 +1870,12 @@ class Commands { void commandSave(final StringTokenizer t) { // Undocumented command: useful for testing. if (!t.hasMoreTokens()) { - Set keys = Env.getSaveKeys(); - Iterator iter = keys.iterator(); - if (!iter.hasNext()) { + Set keys = Env.getSaveKeys(); + if (keys.isEmpty()) { MessageOutput.println("No saved values"); return; } - while (iter.hasNext()) { - String key = (String)iter.next(); + for (String key : keys) { Value value = Env.getSavedValue(key); if ((value instanceof ObjectReference) && ((ObjectReference)value).isCollected()) { @@ -1976,7 +1914,7 @@ class Commands { // Overloading is not handled here. String methodName = t.nextToken(); - List classes = Env.vm().classesByName(className); + List classes = Env.vm().classesByName(className); // TO DO: handle multiple classes found if (classes.size() == 0) { if (className.indexOf('.') < 0) { @@ -1987,17 +1925,14 @@ class Commands { return; } - ReferenceType rt = (ReferenceType)classes.get(0); + ReferenceType rt = classes.get(0); if (!(rt instanceof ClassType)) { MessageOutput.println("not a class", className); return; } byte[] bytecodes = null; - List list = rt.methodsByName(methodName); - Iterator iter = list.iterator(); - while (iter.hasNext()) { - Method method = (Method)iter.next(); + for (Method method : rt.methodsByName(methodName)) { if (!method.isAbstract()) { bytecodes = method.bytecodes(); break; @@ -2047,7 +1982,7 @@ class Commands { MessageOutput.println("Specify classes to redefine"); } else { String className = t.nextToken(); - List classes = Env.vm().classesByName(className); + List classes = Env.vm().classesByName(className); if (classes.size() == 0) { MessageOutput.println("No class named", className); return; @@ -2057,7 +1992,7 @@ class Commands { return; } Env.setSourcePath(Env.getSourcePath()); - ReferenceType refType = (ReferenceType)classes.get(0); + ReferenceType refType = classes.get(0); if (!t.hasMoreTokens()) { MessageOutput.println("Specify file name for class", className); return; @@ -2074,7 +2009,8 @@ class Commands { new Object [] {fileName, exc.toString()}); return; } - Map map = new HashMap(); + Map map + = new HashMap(); map.put(refType, bytes); try { Env.vm().redefineClasses(map); diff --git a/src/share/classes/com/sun/tools/example/debug/tty/Env.java b/src/share/classes/com/sun/tools/example/debug/tty/Env.java index be3fb306a578a36a6bc29a4ac9f1631f2a99778f..9d848a0205b1d6337d2ea7d942a3d7a6f83d50cd 100644 --- a/src/share/classes/com/sun/tools/example/debug/tty/Env.java +++ b/src/share/classes/com/sun/tools/example/debug/tty/Env.java @@ -89,7 +89,7 @@ class Env { sourceCache.clear(); } - static void setSourcePath(List srcList) { + static void setSourcePath(List srcList) { sourceMapper = new SourceMapper(srcList); sourceCache.clear(); } @@ -106,10 +106,8 @@ class Env { } static String excludesString() { - Iterator iter = excludes().iterator(); StringBuffer buffer = new StringBuffer(); - while (iter.hasNext()) { - String pattern = (String)iter.next(); + for (String pattern : excludes()) { buffer.append(pattern); buffer.append(","); } @@ -117,25 +115,19 @@ class Env { } static void addExcludes(StepRequest request) { - Iterator iter = excludes().iterator(); - while (iter.hasNext()) { - String pattern = (String)iter.next(); + for (String pattern : excludes()) { request.addClassExclusionFilter(pattern); } } static void addExcludes(MethodEntryRequest request) { - Iterator iter = excludes().iterator(); - while (iter.hasNext()) { - String pattern = (String)iter.next(); + for (String pattern : excludes()) { request.addClassExclusionFilter(pattern); } } static void addExcludes(MethodExitRequest request) { - Iterator iter = excludes().iterator(); - while (iter.hasNext()) { - String pattern = (String)iter.next(); + for (String pattern : excludes()) { request.addClassExclusionFilter(pattern); } } @@ -175,10 +167,10 @@ class Env { try { String fileName = location.sourceName(); - Iterator iter = sourceCache.iterator(); + Iterator iter = sourceCache.iterator(); SourceCode code = null; while (iter.hasNext()) { - SourceCode candidate = (SourceCode)iter.next(); + SourceCode candidate = iter.next(); if (candidate.fileName().equals(fileName)) { code = candidate; iter.remove(); @@ -269,10 +261,7 @@ class Env { // loaded class whose name matches this limited regular // expression is selected. idToken = idToken.substring(1); - List classes = Env.vm().allClasses(); - Iterator iter = classes.iterator(); - while (iter.hasNext()) { - ReferenceType type = ((ReferenceType)iter.next()); + for (ReferenceType type : Env.vm().allClasses()) { if (type.name().endsWith(idToken)) { cls = type; break; @@ -280,21 +269,21 @@ class Env { } } else { // It's a class name - List classes = Env.vm().classesByName(idToken); + List classes = Env.vm().classesByName(idToken); if (classes.size() > 0) { // TO DO: handle multiples - cls = (ReferenceType)classes.get(0); + cls = classes.get(0); } } return cls; } - static Set getSaveKeys() { + static Set getSaveKeys() { return savedValues.keySet(); } static Value getSavedValue(String key) { - return (Value)savedValues.get(key); + return savedValues.get(key); } static void setSavedValue(String key, Value value) { @@ -327,7 +316,7 @@ class Env { if (index >= sourceLines.size()) { return null; } else { - return (String)sourceLines.get(index); + return sourceLines.get(index); } } } diff --git a/src/share/classes/com/sun/tools/example/debug/tty/EventHandler.java b/src/share/classes/com/sun/tools/example/debug/tty/EventHandler.java index 27ef3913ece560c7320a33377809cc6a4acc180a..ee80f9df5387f183f958993563e83af069bd9822 100644 --- a/src/share/classes/com/sun/tools/example/debug/tty/EventHandler.java +++ b/src/share/classes/com/sun/tools/example/debug/tty/EventHandler.java @@ -150,7 +150,7 @@ public class EventHandler implements Runnable { EventSet eventSet = queue.remove(); EventIterator iter = eventSet.eventIterator(); while (iter.hasNext()) { - handleExitEvent((Event)iter.next()); + handleExitEvent(iter.next()); } } catch (InterruptedException exc) { // ignore @@ -183,7 +183,7 @@ public class EventHandler implements Runnable { * If any event in the set has a thread associated with it, * they all will, so just grab the first one. */ - Event event = (Event)set.iterator().next(); // Is there a better way? + Event event = set.iterator().next(); // Is there a better way? thread = eventThread(event); } else { thread = null; diff --git a/src/share/classes/com/sun/tools/example/debug/tty/EventRequestSpec.java b/src/share/classes/com/sun/tools/example/debug/tty/EventRequestSpec.java index bb86c2f3af09fa0ee9db4ab71a27c253d052df63..7169e33f6f026777eef7f7feb3a25ae88839ab0c 100644 --- a/src/share/classes/com/sun/tools/example/debug/tty/EventRequestSpec.java +++ b/src/share/classes/com/sun/tools/example/debug/tty/EventRequestSpec.java @@ -101,10 +101,8 @@ abstract class EventRequestSpec { * so that is all we need to examine. */ ArrayList deleteList = new ArrayList(); - Iterator iter = - Env.vm().eventRequestManager().exceptionRequests().iterator(); - while (iter.hasNext()) { - ExceptionRequest er = (ExceptionRequest)iter.next(); + for (ExceptionRequest er : + Env.vm().eventRequestManager().exceptionRequests()) { if (prs.matches(er.exception())) { deleteList.add (er); } @@ -115,9 +113,7 @@ abstract class EventRequestSpec { } private EventRequest resolveAgainstPreparedClasses() throws Exception { - Iterator iter = Env.vm().allClasses().iterator(); - while (iter.hasNext()) { - ReferenceType refType = (ReferenceType)iter.next(); + for (ReferenceType refType : Env.vm().allClasses()) { if (refType.isPrepared() && refSpec.matches(refType)) { resolved = resolveEventRequest(refType); } diff --git a/src/share/classes/com/sun/tools/example/debug/tty/EventRequestSpecList.java b/src/share/classes/com/sun/tools/example/debug/tty/EventRequestSpecList.java index 2f3286d1a7e9c1b0f7a76a290a3a3ba0245e66aa..e5741efc706d85f11ba7cd14d4d425a1e0141345 100644 --- a/src/share/classes/com/sun/tools/example/debug/tty/EventRequestSpecList.java +++ b/src/share/classes/com/sun/tools/example/debug/tty/EventRequestSpecList.java @@ -55,9 +55,7 @@ class EventRequestSpecList { boolean resolve(ClassPrepareEvent event) { boolean failure = false; synchronized(eventRequestSpecs) { - Iterator iter = eventRequestSpecs.iterator(); - while (iter.hasNext()) { - EventRequestSpec spec = (EventRequestSpec)iter.next(); + for (EventRequestSpec spec : eventRequestSpecs) { if (!spec.isResolved()) { try { EventRequest eventRequest = spec.resolve(event); @@ -77,9 +75,7 @@ class EventRequestSpecList { } void resolveAll() { - Iterator iter = eventRequestSpecs.iterator(); - while (iter.hasNext()) { - EventRequestSpec spec = (EventRequestSpec)iter.next(); + for (EventRequestSpec spec : eventRequestSpecs) { try { EventRequest eventRequest = spec.resolveEagerly(); if (eventRequest != null) { @@ -106,16 +102,16 @@ class EventRequestSpecList { } } - EventRequestSpec createBreakpoint(String classPattern, - int line) throws ClassNotFoundException { + BreakpointSpec createBreakpoint(String classPattern, int line) + throws ClassNotFoundException { ReferenceTypeSpec refSpec = new PatternReferenceTypeSpec(classPattern); return new BreakpointSpec(refSpec, line); } - EventRequestSpec createBreakpoint(String classPattern, + BreakpointSpec createBreakpoint(String classPattern, String methodId, - List methodArgs) + List methodArgs) throws MalformedMemberNameException, ClassNotFoundException { ReferenceTypeSpec refSpec = @@ -132,7 +128,7 @@ class EventRequestSpecList { return new ExceptionSpec(refSpec, notifyCaught, notifyUncaught); } - EventRequestSpec createAccessWatchpoint(String classPattern, + WatchpointSpec createAccessWatchpoint(String classPattern, String fieldId) throws MalformedMemberNameException, ClassNotFoundException { @@ -141,7 +137,7 @@ class EventRequestSpecList { return new AccessWatchpointSpec(refSpec, fieldId); } - EventRequestSpec createModificationWatchpoint(String classPattern, + WatchpointSpec createModificationWatchpoint(String classPattern, String fieldId) throws MalformedMemberNameException, ClassNotFoundException { @@ -154,7 +150,7 @@ class EventRequestSpecList { synchronized (eventRequestSpecs) { int inx = eventRequestSpecs.indexOf(proto); if (inx != -1) { - EventRequestSpec spec = (EventRequestSpec)eventRequestSpecs.get(inx); + EventRequestSpec spec = eventRequestSpecs.get(inx); spec.remove(); eventRequestSpecs.remove(inx); return true; diff --git a/src/share/classes/com/sun/tools/example/debug/tty/SourceMapper.java b/src/share/classes/com/sun/tools/example/debug/tty/SourceMapper.java index da8af944890afdbbe78537e756f34d5ff950a73f..618f41a622c28c4a131325513ccca8711e1b964a 100644 --- a/src/share/classes/com/sun/tools/example/debug/tty/SourceMapper.java +++ b/src/share/classes/com/sun/tools/example/debug/tty/SourceMapper.java @@ -39,15 +39,13 @@ class SourceMapper { private final String[] dirs; - SourceMapper(List sourcepath) { + SourceMapper(List sourcepath) { /* * sourcepath can arrive from the debugee as a List. * (via PathSearchingVirtualMachine.classPath()) */ List dirList = new ArrayList(); - Iterator iter = sourcepath.iterator(); - while (iter.hasNext()) { - String element = (String)iter.next(); + for (String element : sourcepath) { //XXX remove .jar and .zip files; we want only directories on //the source path. (Bug ID 4186582) if ( ! (element.endsWith(".jar") || @@ -55,7 +53,7 @@ class SourceMapper { dirList.add(element); } } - dirs = (String[])dirList.toArray(new String[0]); + dirs = dirList.toArray(new String[0]); } SourceMapper(String sourcepath) { @@ -79,7 +77,7 @@ class SourceMapper { dirList.add(s); } } - dirs = (String[])dirList.toArray(new String[0]); + dirs = dirList.toArray(new String[0]); } /* diff --git a/src/share/classes/com/sun/tools/example/debug/tty/TTY.java b/src/share/classes/com/sun/tools/example/debug/tty/TTY.java index 620891af757d4001f24bb680b2bf4ce9c21c75ec..ec1dc51c6da8cb97bcd83651f1b32a2ec8e907ac 100644 --- a/src/share/classes/com/sun/tools/example/debug/tty/TTY.java +++ b/src/share/classes/com/sun/tools/example/debug/tty/TTY.java @@ -160,9 +160,7 @@ public class TTY implements EventNotifier { // here the next time. Env.setAtExitMethod(null); EventRequestManager erm = Env.vm().eventRequestManager(); - Iterator it = erm.methodExitRequests().iterator(); - while (it.hasNext()) { - EventRequest eReq = (EventRequest)it.next(); + for (EventRequest eReq : erm.methodExitRequests()) { if (eReq.equals(me.request())) { eReq.disable(); } @@ -178,9 +176,8 @@ public class TTY implements EventNotifier { public void vmInterrupted() { Thread.yield(); // fetch output printCurrentLocation(); - Iterator it = monitorCommands.iterator(); - while (it.hasNext()) { - StringTokenizer t = new StringTokenizer((String)it.next()); + for (String cmd : monitorCommands) { + StringTokenizer t = new StringTokenizer(cmd); t.nextToken(); // get rid of monitor number executeCommand(t); } @@ -563,9 +560,8 @@ public class TTY implements EventNotifier { ++monitorCount; monitorCommands.add(monitorCount + ": " + t.nextToken("")); } else { - Iterator it = monitorCommands.iterator(); - while (it.hasNext()) { - MessageOutput.printDirectln((String)it.next());// Special case: use printDirectln() + for (String cmd : monitorCommands) { + MessageOutput.printDirectln(cmd);// Special case: use printDirectln() } } } @@ -581,9 +577,7 @@ public class TTY implements EventNotifier { return; } String monStr = monTok + ":"; - Iterator it = monitorCommands.iterator(); - while (it.hasNext()) { - String cmd = (String)it.next(); + for (String cmd : monitorCommands) { StringTokenizer ct = new StringTokenizer(cmd); if (ct.nextToken().equals(monStr)) { monitorCommands.remove(cmd); @@ -768,10 +762,8 @@ public class TTY implements EventNotifier { } private static boolean supportsSharedMemory() { - List connectors = Bootstrap.virtualMachineManager().allConnectors(); - Iterator iter = connectors.iterator(); - while (iter.hasNext()) { - Connector connector = (Connector)iter.next(); + for (Connector connector : + Bootstrap.virtualMachineManager().allConnectors()) { if (connector.transport() == null) { continue; } diff --git a/src/share/classes/com/sun/tools/example/debug/tty/ThreadGroupIterator.java b/src/share/classes/com/sun/tools/example/debug/tty/ThreadGroupIterator.java index c62a882200376cdc490c7f90f3d7bead662494b4..dc2dc118074379405dc3d850c1957b5ce6c1f13d 100644 --- a/src/share/classes/com/sun/tools/example/debug/tty/ThreadGroupIterator.java +++ b/src/share/classes/com/sun/tools/example/debug/tty/ThreadGroupIterator.java @@ -36,7 +36,7 @@ import java.util.Iterator; * Descend the tree of thread groups. * @author Robert G. Field */ -class ThreadGroupIterator implements Iterator { +class ThreadGroupIterator implements Iterator { private final Stack> stack = new Stack>(); ThreadGroupIterator(List tgl) { @@ -53,8 +53,8 @@ class ThreadGroupIterator implements Iterator { this(Env.vm().topLevelThreadGroups()); } - private Iterator top() { - return (Iterator)stack.peek(); + private Iterator top() { + return stack.peek(); } /** @@ -74,12 +74,12 @@ class ThreadGroupIterator implements Iterator { return !stack.isEmpty(); } - public Object next() { + public ThreadGroupReference next() { return nextThreadGroup(); } public ThreadGroupReference nextThreadGroup() { - ThreadGroupReference tg = (ThreadGroupReference)top().next(); + ThreadGroupReference tg = top().next(); push(tg.threadGroups()); return tg; } diff --git a/src/share/classes/com/sun/tools/example/debug/tty/ThreadInfo.java b/src/share/classes/com/sun/tools/example/debug/tty/ThreadInfo.java index 97c6a88082818c2cf86916c30b3a658a2de84623..e823821c04c47c78540df44ed3e5ff4ae7760794 100644 --- a/src/share/classes/com/sun/tools/example/debug/tty/ThreadInfo.java +++ b/src/share/classes/com/sun/tools/example/debug/tty/ThreadInfo.java @@ -56,9 +56,7 @@ class ThreadInfo { private static void initThreads() { if (!gotInitialThreads) { - Iterator iter = Env.vm().allThreads().iterator(); - while (iter.hasNext()) { - ThreadReference thread = (ThreadReference)iter.next(); + for (ThreadReference thread : Env.vm().allThreads()) { threads.add(new ThreadInfo(thread)); } gotInitialThreads = true; @@ -113,9 +111,7 @@ class ThreadInfo { current = null; group = null; synchronized (threads) { - Iterator iter = threads().iterator(); - while (iter.hasNext()) { - ThreadInfo ti = (ThreadInfo)iter.next(); + for (ThreadInfo ti : threads()) { ti.invalidate(); } } @@ -163,8 +159,7 @@ class ThreadInfo { if (group == null) { // Current thread group defaults to the first top level // thread group. - setThreadGroup((ThreadGroupReference) - Env.vm().topLevelThreadGroups().get(0)); + setThreadGroup(Env.vm().topLevelThreadGroups().get(0)); } return group; } @@ -173,9 +168,7 @@ class ThreadInfo { ThreadInfo retInfo = null; synchronized (threads) { - Iterator iter = threads().iterator(); - while (iter.hasNext()) { - ThreadInfo ti = (ThreadInfo)iter.next(); + for (ThreadInfo ti : threads()) { if (ti.thread.uniqueID() == id) { retInfo = ti; break; @@ -208,7 +201,7 @@ class ThreadInfo { * * @return a List of the stack frames. */ - List getStack() throws IncompatibleThreadStateException { + List getStack() throws IncompatibleThreadStateException { return thread.frames(); } diff --git a/src/share/classes/com/sun/tools/example/debug/tty/ThreadIterator.java b/src/share/classes/com/sun/tools/example/debug/tty/ThreadIterator.java index b753cf742a36ff7bcebf08d97cdd41bb5c01fff6..8baff8ebd48cb8065dda4934874746ab4b6ac19d 100644 --- a/src/share/classes/com/sun/tools/example/debug/tty/ThreadIterator.java +++ b/src/share/classes/com/sun/tools/example/debug/tty/ThreadIterator.java @@ -30,8 +30,8 @@ import com.sun.jdi.ThreadReference; import java.util.List; import java.util.Iterator; -class ThreadIterator implements Iterator { - Iterator it = null; +class ThreadIterator implements Iterator { + Iterator it = null; ThreadGroupIterator tgi; ThreadIterator(ThreadGroupReference tg) { @@ -56,12 +56,12 @@ class ThreadIterator implements Iterator { return true; } - public Object next() { + public ThreadReference next() { return it.next(); } public ThreadReference nextThread() { - return (ThreadReference)next(); + return next(); } public void remove() { diff --git a/src/share/classes/com/sun/tools/example/debug/tty/VMConnection.java b/src/share/classes/com/sun/tools/example/debug/tty/VMConnection.java index 6d3c3be20f858991adddd212bde90fad6b908456..7ab34280f899e01a9d620e99fa9ff94ca138637e 100644 --- a/src/share/classes/com/sun/tools/example/debug/tty/VMConnection.java +++ b/src/share/classes/com/sun/tools/example/debug/tty/VMConnection.java @@ -61,10 +61,8 @@ class VMConnection { } private Connector findConnector(String name) { - List connectors = Bootstrap.virtualMachineManager().allConnectors(); - Iterator iter = connectors.iterator(); - while (iter.hasNext()) { - Connector connector = (Connector)iter.next(); + for (Connector connector : + Bootstrap.virtualMachineManager().allConnectors()) { if (connector.name().equals(name)) { return connector; } @@ -108,7 +106,7 @@ class VMConnection { String value = token.substring(index + 1, token.length() - 1); // Remove comma delimiter - Connector.Argument argument = (Connector.Argument)arguments.get(name); + Connector.Argument argument = arguments.get(name); if (argument == null) { throw new IllegalArgumentException (MessageOutput.format("Argument is not defined for connector:", @@ -195,7 +193,7 @@ class VMConnection { return false; } - Connector.Argument argument = (Connector.Argument)connectorArgs.get(name); + Connector.Argument argument = connectorArgs.get(name); if (argument == null) { return false; } @@ -204,7 +202,7 @@ class VMConnection { } String connectorArg(String name) { - Connector.Argument argument = (Connector.Argument)connectorArgs.get(name); + Connector.Argument argument = connectorArgs.get(name); if (argument == null) { return ""; } diff --git a/src/share/classes/com/sun/tools/hat/internal/server/ClassQuery.java b/src/share/classes/com/sun/tools/hat/internal/server/ClassQuery.java index 60c48f1bce4ac8daad25b46a6319b6068f39d5ec..4fc235f7e2a036979e496fe1aa6935519645cf5d 100644 --- a/src/share/classes/com/sun/tools/hat/internal/server/ClassQuery.java +++ b/src/share/classes/com/sun/tools/hat/internal/server/ClassQuery.java @@ -99,8 +99,7 @@ class ClassQuery extends QueryHandler { } out.println("

Instance Data Members:

"); - JavaField[] ff = clazz.getFields(); - ff = (JavaField[]) ff.clone(); + JavaField[] ff = clazz.getFields().clone(); ArraySorter.sort(ff, new Comparer() { public int compare(Object lhs, Object rhs) { JavaField left = (JavaField) lhs; diff --git a/src/share/classes/com/sun/tools/hat/internal/server/PlatformClasses.java b/src/share/classes/com/sun/tools/hat/internal/server/PlatformClasses.java index 1f6d3bf9d8fe654763d6fd571ba38b0d0fedda29..24db65e2fe730b541abab9d34b0183a71aa3d5c0 100644 --- a/src/share/classes/com/sun/tools/hat/internal/server/PlatformClasses.java +++ b/src/share/classes/com/sun/tools/hat/internal/server/PlatformClasses.java @@ -90,9 +90,7 @@ public class PlatformClasses { // is the right thing to do anyway. } } - int num = list.size(); - names = new String[num]; - names = (String[]) list.toArray(names); + names = list.toArray(new String[list.size()]); } return names; } diff --git a/src/share/classes/com/sun/tools/jdi/AbstractLauncher.java b/src/share/classes/com/sun/tools/jdi/AbstractLauncher.java index 23e9369050d73efd1b3f62f7c3247278419f8a34..48d60f9d8b9cf9b65abdbc75653a0d536f4c5a6c 100644 --- a/src/share/classes/com/sun/tools/jdi/AbstractLauncher.java +++ b/src/share/classes/com/sun/tools/jdi/AbstractLauncher.java @@ -119,7 +119,7 @@ abstract class AbstractLauncher extends ConnectorImpl implements LaunchingConnec String[] tokenArray = new String[tokenList.size()]; for (int i = 0; i < tokenList.size(); i++) { - tokenArray[i] = (String)tokenList.get(i); + tokenArray[i] = tokenList.get(i); } return tokenArray; } diff --git a/src/share/classes/com/sun/tools/jdi/ClassTypeImpl.java b/src/share/classes/com/sun/tools/jdi/ClassTypeImpl.java index fbb613b119aaaef6e4dc77a39c4d689c7b8d26f9..3e68aa727467b247241ae79bb8c07dffcd72e852 100644 --- a/src/share/classes/com/sun/tools/jdi/ClassTypeImpl.java +++ b/src/share/classes/com/sun/tools/jdi/ClassTypeImpl.java @@ -95,11 +95,8 @@ public class ClassTypeImpl extends ReferenceTypeImpl } public List subclasses() { - List all = vm.allClasses(); List subs = new ArrayList(); - Iterator iter = all.iterator(); - while (iter.hasNext()) { - ReferenceType refType = (ReferenceType)iter.next(); + for (ReferenceType refType : vm.allClasses()) { if (refType instanceof ClassType) { ClassType clazz = (ClassType)refType; ClassType superclass = clazz.superclass(); @@ -223,7 +220,7 @@ public class ClassTypeImpl extends ReferenceTypeImpl List arguments = method.validateAndPrepareArgumentsForInvoke(origArguments); - ValueImpl[] args = (ValueImpl[])arguments.toArray(new ValueImpl[0]); + ValueImpl[] args = arguments.toArray(new ValueImpl[0]); JDWP.ClassType.InvokeMethod ret; try { PacketStream stream = @@ -271,7 +268,7 @@ public class ClassTypeImpl extends ReferenceTypeImpl List arguments = method.validateAndPrepareArgumentsForInvoke( origArguments); - ValueImpl[] args = (ValueImpl[])arguments.toArray(new ValueImpl[0]); + ValueImpl[] args = arguments.toArray(new ValueImpl[0]); JDWP.ClassType.NewInstance ret = null; try { PacketStream stream = @@ -301,11 +298,8 @@ public class ClassTypeImpl extends ReferenceTypeImpl } public Method concreteMethodByName(String name, String signature) { - List methods = visibleMethods(); Method method = null; - Iterator iter = methods.iterator(); - while (iter.hasNext()) { - Method candidate = (Method)iter.next(); + for (Method candidate : visibleMethods()) { if (candidate.name().equals(name) && candidate.signature().equals(signature) && !candidate.isAbstract()) { @@ -330,9 +324,7 @@ public class ClassTypeImpl extends ReferenceTypeImpl * Avoid duplicate checking on each method by iterating through * duplicate-free allInterfaces() rather than recursing */ - Iterator iter = allInterfaces().iterator(); - while (iter.hasNext()) { - InterfaceType interfaze = (InterfaceType)iter.next(); + for (InterfaceType interfaze : allInterfaces()) { list.addAll(interfaze.methods()); } diff --git a/src/share/classes/com/sun/tools/jdi/ConcreteMethodImpl.java b/src/share/classes/com/sun/tools/jdi/ConcreteMethodImpl.java index b5d52e6c3e8f094bd13bd5624d323ebcf4bb3b96..6e44338cdfd7537922d6a5e0e15159e1ae2c22df 100644 --- a/src/share/classes/com/sun/tools/jdi/ConcreteMethodImpl.java +++ b/src/share/classes/com/sun/tools/jdi/ConcreteMethodImpl.java @@ -247,7 +247,7 @@ public class ConcreteMethodImpl extends MethodImpl { public byte[] bytecodes() { byte[] bytecodes = (bytecodesRef == null) ? null : - (byte[])bytecodesRef.get(); + bytecodesRef.get(); if (bytecodes == null) { try { bytecodes = JDWP.Method.Bytecodes. @@ -262,7 +262,7 @@ public class ConcreteMethodImpl extends MethodImpl { * to return the cached bytecodes directly; instead, we * make a clone at the cost of using more memory. */ - return (byte[])bytecodes.clone(); + return bytecodes.clone(); } int argSlotCount() throws AbsentInformationException { @@ -279,7 +279,7 @@ public class ConcreteMethodImpl extends MethodImpl { String stratumID = stratum.id(); SoftLocationXRefs info = (softOtherLocationXRefsRef == null) ? null : - (SoftLocationXRefs)softOtherLocationXRefsRef.get(); + softOtherLocationXRefsRef.get(); if (info != null && info.stratumID.equals(stratumID)) { return info; } @@ -348,7 +348,7 @@ public class ConcreteMethodImpl extends MethodImpl { private SoftLocationXRefs getBaseLocations() { SoftLocationXRefs info = (softBaseLocationXRefsRef == null) ? null : - (SoftLocationXRefs)softBaseLocationXRefsRef.get(); + softBaseLocationXRefsRef.get(); if (info != null) { return info; } diff --git a/src/share/classes/com/sun/tools/jdi/EventSetImpl.java b/src/share/classes/com/sun/tools/jdi/EventSetImpl.java index da96ad494ce04474c3a1c86b160e1cdb76e14aac..1a2c61c7bc94866110c10330f789f3c2e5fd455b 100644 --- a/src/share/classes/com/sun/tools/jdi/EventSetImpl.java +++ b/src/share/classes/com/sun/tools/jdi/EventSetImpl.java @@ -56,10 +56,8 @@ public class EventSetImpl extends ArrayList implements EventSet { public String toString() { String string = "event set, policy:" + suspendPolicy + ", count:" + this.size() + " = {"; - Iterator iter = this.iterator(); boolean first = true; - while (iter.hasNext()) { - Event event = (Event)iter.next(); + for (Event event : this) { if (!first) { string += ", "; } @@ -787,9 +785,7 @@ public class EventSetImpl extends ArrayList implements EventSet { } private ThreadReference eventThread() { - Iterator iter = this.iterator(); - while (iter.hasNext()) { - Event event = (Event)iter.next(); + for (Event event : this) { if (event instanceof ThreadedEventImpl) { return ((ThreadedEventImpl)event).thread(); } @@ -846,7 +842,7 @@ public class EventSetImpl extends ArrayList implements EventSet { } public Event nextEvent() { - return (Event)next(); + return next(); } public void remove() { diff --git a/src/share/classes/com/sun/tools/jdi/JNITypeParser.java b/src/share/classes/com/sun/tools/jdi/JNITypeParser.java index 6151d5293e2293225f13fcb6da94062a98bed726..6add99fa6eb9030d01fddedfa01248b44a8c414d 100644 --- a/src/share/classes/com/sun/tools/jdi/JNITypeParser.java +++ b/src/share/classes/com/sun/tools/jdi/JNITypeParser.java @@ -82,7 +82,7 @@ public class JNITypeParser { } String typeName() { - return (String)typeNameList().get(typeNameList().size()-1); + return typeNameList().get(typeNameList().size()-1); } List argumentTypeNames() { @@ -90,7 +90,7 @@ public class JNITypeParser { } String signature() { - return (String)signatureList().get(signatureList().size()-1); + return signatureList().get(signatureList().size()-1); } List argumentSignatures() { diff --git a/src/share/classes/com/sun/tools/jdi/MethodImpl.java b/src/share/classes/com/sun/tools/jdi/MethodImpl.java index 396649355212d4f85877a1f1ccd265c93297bbab..4ad9da94882fcde2a8924b2bff38f394e9b28ff8 100644 --- a/src/share/classes/com/sun/tools/jdi/MethodImpl.java +++ b/src/share/classes/com/sun/tools/jdi/MethodImpl.java @@ -158,7 +158,7 @@ public abstract class MethodImpl extends TypeComponentImpl Type argumentType(int index) throws ClassNotLoadedException { ReferenceTypeImpl enclosing = (ReferenceTypeImpl)declaringType(); - String signature = (String)argumentSignatures().get(index); + String signature = argumentSignatures().get(index); return enclosing.findType(signature); } @@ -263,10 +263,10 @@ public abstract class MethodImpl extends TypeComponentImpl return argumentType(index); } public String typeName(){ - return (String)argumentTypeNames().get(index); + return argumentTypeNames().get(index); } public String signature() { - return (String)argumentSignatures().get(index); + return argumentSignatures().get(index); } public Type findType(String signature) throws ClassNotLoadedException { return MethodImpl.this.findType(signature); @@ -307,7 +307,7 @@ public abstract class MethodImpl extends TypeComponentImpl arguments.add(argArray); return; } - Value nthArgValue = (Value)arguments.get(paramCount - 1); + Value nthArgValue = arguments.get(paramCount - 1); if (nthArgValue == null) { return; } @@ -371,7 +371,7 @@ public abstract class MethodImpl extends TypeComponentImpl } for (int i = 0; i < argSize; i++) { - Value value = (Value)arguments.get(i); + Value value = arguments.get(i); value = ValueImpl.prepareForAssignment(value, new ArgumentContainer(i)); arguments.set(i, value); @@ -386,11 +386,11 @@ public abstract class MethodImpl extends TypeComponentImpl sb.append(name()); sb.append("("); boolean first = true; - for (Iterator it = argumentTypeNames().iterator(); it.hasNext();) { + for (String name : argumentTypeNames()) { if (!first) { sb.append(", "); } - sb.append((String)it.next()); + sb.append(name); first = false; } sb.append(")"); diff --git a/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java b/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java index 82aed8e96bee90785afd1ee2ce3fbc5ca95ce2e4..79f84cdb2b4cad567ed0b9ccf8dce761d6fed303 100644 --- a/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java +++ b/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java @@ -383,7 +383,7 @@ public class ObjectReferenceImpl extends ValueImpl List arguments = method.validateAndPrepareArgumentsForInvoke( origArguments); - ValueImpl[] args = (ValueImpl[])arguments.toArray(new ValueImpl[0]); + ValueImpl[] args = arguments.toArray(new ValueImpl[0]); JDWP.ObjectReference.InvokeMethod ret; try { PacketStream stream = @@ -583,7 +583,7 @@ public class ObjectReferenceImpl extends ValueImpl // Validate assignment ReferenceType destType = (ReferenceTypeImpl)destination.type(); ReferenceTypeImpl myType = (ReferenceTypeImpl)referenceType(); - if (!myType.isAssignableTo((ReferenceType)destType)) { + if (!myType.isAssignableTo(destType)) { JNITypeParser parser = new JNITypeParser(destType.signature()); String destTypeName = parser.typeName(); throw new InvalidTypeException("Can't assign " + diff --git a/src/share/classes/com/sun/tools/jdi/PacketStream.java b/src/share/classes/com/sun/tools/jdi/PacketStream.java index 5ad2fd1b451b2bcda342d13e7010b98b00058502..65db8b31740bef3bdf9d45bd289ab1289cf90e23 100644 --- a/src/share/classes/com/sun/tools/jdi/PacketStream.java +++ b/src/share/classes/com/sun/tools/jdi/PacketStream.java @@ -485,7 +485,7 @@ class PacketStream { * Read field represented as vm specific byte sequence. */ Field readField() { - ReferenceTypeImpl refType = (ReferenceTypeImpl)readReferenceType(); + ReferenceTypeImpl refType = readReferenceType(); long fieldRef = readFieldRef(); return refType.getFieldMirror(fieldRef); } diff --git a/src/share/classes/com/sun/tools/jdi/ReferenceTypeImpl.java b/src/share/classes/com/sun/tools/jdi/ReferenceTypeImpl.java index 4af0e8e8a45939900bf4fc15747a7f2cb504dcca..f66c202f74439c6eebe828d38d447c1d0cb776e3 100644 --- a/src/share/classes/com/sun/tools/jdi/ReferenceTypeImpl.java +++ b/src/share/classes/com/sun/tools/jdi/ReferenceTypeImpl.java @@ -59,7 +59,7 @@ implements ReferenceType { private boolean constantPoolInfoGotten = false; private int constanPoolCount; private byte[] constantPoolBytes; - private SoftReference constantPoolBytesRef = null; + private SoftReference constantPoolBytesRef = null; /* to mark a SourceFile request that returned a genuine JDWP.Error.ABSENT_INFORMATION */ private static final String ABSENT_BASE_SOURCE_NAME = "**ABSENT_BASE_SOURCE_NAME**"; @@ -352,13 +352,10 @@ implements ReferenceType { abstract List inheritedTypes(); void addVisibleFields(List visibleList, Map visibleTable, List ambiguousNames) { - List list = visibleFields(); - Iterator iter = list.iterator(); - while (iter.hasNext()) { - Field field = (Field)iter.next(); + for (Field field : visibleFields()) { String name = field.name(); if (!ambiguousNames.contains(name)) { - Field duplicate = (Field)visibleTable.get(name); + Field duplicate = visibleTable.get(name); if (duplicate == null) { visibleList.add(field); visibleTable.put(name, field); @@ -402,10 +399,8 @@ implements ReferenceType { * hide. */ List retList = new ArrayList(fields()); - iter = retList.iterator(); - while (iter.hasNext()) { - Field field = (Field)iter.next(); - Field hidden = (Field)visibleTable.get(field.name()); + for (Field field : retList) { + Field hidden = visibleTable.get(field.name()); if (hidden != null) { visibleList.remove(hidden); } @@ -515,12 +510,9 @@ implements ReferenceType { * methods. */ void addToMethodMap(Map methodMap, List methodList) { - Iterator iter = methodList.iterator(); - while (iter.hasNext()) { - Method method = (Method)iter.next(); + for (Method method : methodList) methodMap.put(method.name().concat(method.signature()), method); } - } abstract void addVisibleMethods(Map methodMap); @@ -549,9 +541,7 @@ implements ReferenceType { public List methodsByName(String name) { List methods = visibleMethods(); ArrayList retList = new ArrayList(methods.size()); - Iterator iter = methods.iterator(); - while (iter.hasNext()) { - Method candidate = (Method)iter.next(); + for (Method candidate : methods) { if (candidate.name().equals(name)) { retList.add(candidate); } @@ -563,9 +553,7 @@ implements ReferenceType { public List methodsByName(String name, String signature) { List methods = visibleMethods(); ArrayList retList = new ArrayList(methods.size()); - Iterator iter = methods.iterator(); - while (iter.hasNext()) { - Method candidate = (Method)iter.next(); + for (Method candidate : methods) { if (candidate.name().equals(name) && candidate.signature().equals(signature)) { retList.add(candidate); @@ -706,7 +694,7 @@ implements ReferenceType { } public String sourceName() throws AbsentInformationException { - return (String)(sourceNames(vm.getDefaultStratum()).get(0)); + return sourceNames(vm.getDefaultStratum()).get(0); } public List sourceNames(String stratumID) @@ -796,7 +784,7 @@ implements ReferenceType { if (!vm.canGetSourceDebugExtension()) { return NO_SDE_INFO_MARK; } - SDE sde = (sdeRef == null) ? null : (SDE)sdeRef.get(); + SDE sde = (sdeRef == null) ? null : sdeRef.get(); if (sde == null) { String extension = null; try { @@ -1034,13 +1022,13 @@ implements ReferenceType { throw exc; } if (constantPoolBytesRef != null) { - byte[] cpbytes = (byte[])constantPoolBytesRef.get(); + byte[] cpbytes = constantPoolBytesRef.get(); /* * Arrays are always modifiable, so it is a little unsafe * to return the cached bytecodes directly; instead, we * make a clone at the cost of using more memory. */ - return (byte[])cpbytes.clone(); + return cpbytes.clone(); } else { return null; } diff --git a/src/share/classes/com/sun/tools/jdi/SDE.java b/src/share/classes/com/sun/tools/jdi/SDE.java index dd054c1ba0c275e53cf20218721da3f82ff319ee..6f46c81f81195a5d2b463baabb17b713973c5753 100644 --- a/src/share/classes/com/sun/tools/jdi/SDE.java +++ b/src/share/classes/com/sun/tools/jdi/SDE.java @@ -327,7 +327,7 @@ class SDE { ignoreWhite(); while (((ch = sdeRead()) != '\n') && (ch != '\r')) { - sb.append((char)ch); + sb.append(ch); } // check for CR LF if ((ch == '\r') && (sdePeek() == '\n')) { diff --git a/src/share/classes/com/sun/tools/jdi/StackFrameImpl.java b/src/share/classes/com/sun/tools/jdi/StackFrameImpl.java index 5cfd2cbc9011a6611765ac037fe0c255038aac16..a6f867379a0614f0ef1ee794aa775cf948390b94 100644 --- a/src/share/classes/com/sun/tools/jdi/StackFrameImpl.java +++ b/src/share/classes/com/sun/tools/jdi/StackFrameImpl.java @@ -162,7 +162,7 @@ public class StackFrameImpl extends MirrorImpl for (LocalVariable variable : allVariables) { String name = variable.name(); if (variable.isVisible(this)) { - LocalVariable existing = (LocalVariable)map.get(name); + LocalVariable existing = map.get(name); if ((existing == null) || ((LocalVariableImpl)variable).hides(existing)) { map.put(name, variable); @@ -330,7 +330,7 @@ public class StackFrameImpl extends MirrorImpl slot = 1; } for (int ii = 0; ii < count; ++ii) { - char sigChar = (char)argSigs.get(ii).charAt(0); + char sigChar = argSigs.get(ii).charAt(0); slots[ii] = new JDWP.StackFrame.GetValues.SlotInfo(slot++,(byte)sigChar); if (sigChar == 'J' || sigChar == 'D') { slot++; diff --git a/src/share/classes/com/sun/tools/jdi/TargetVM.java b/src/share/classes/com/sun/tools/jdi/TargetVM.java index 2ff9bb1d1264982663c89884d8e15f1dec0e85a9..54ae6af0de4a617f3fbe98c992cee69f87812e31 100644 --- a/src/share/classes/com/sun/tools/jdi/TargetVM.java +++ b/src/share/classes/com/sun/tools/jdi/TargetVM.java @@ -148,7 +148,7 @@ public class TargetVM implements Runnable { idString = String.valueOf(p.id); synchronized(waitingQueue) { - p2 = (Packet)waitingQueue.get(idString); + p2 = waitingQueue.get(idString); if (p2 != null) waitingQueue.remove(idString); diff --git a/src/share/classes/com/sun/tools/jdi/ThreadGroupReferenceImpl.java b/src/share/classes/com/sun/tools/jdi/ThreadGroupReferenceImpl.java index 4e1286ba2e4a515b05d4e1c64dc6a225826cdf46..8dac1f3a3307bca5c13cae013300517584e939b2 100644 --- a/src/share/classes/com/sun/tools/jdi/ThreadGroupReferenceImpl.java +++ b/src/share/classes/com/sun/tools/jdi/ThreadGroupReferenceImpl.java @@ -86,30 +86,22 @@ public class ThreadGroupReferenceImpl extends ObjectReferenceImpl } public void suspend() { - List threads = threads(); - Iterator iter = threads.iterator(); - while (iter.hasNext()) { - ((ThreadReference)iter.next()).suspend(); + for (ThreadReference thread : threads()) { + thread.suspend(); } - List groups = threadGroups(); - iter = groups.iterator(); - while (iter.hasNext()) { - ((ThreadGroupReference)iter.next()).suspend(); + for (ThreadGroupReference threadGroup : threadGroups()) { + threadGroup.suspend(); } } public void resume() { - List threads = threads(); - Iterator iter = threads.iterator(); - while (iter.hasNext()) { - ((ThreadReference)iter.next()).resume(); + for (ThreadReference thread : threads()) { + thread.resume(); } - List groups = threadGroups(); - iter = groups.iterator(); - while (iter.hasNext()) { - ((ThreadGroupReference)iter.next()).resume(); + for (ThreadGroupReference threadGroup : threadGroups()) { + threadGroup.resume(); } } diff --git a/src/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java b/src/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java index 54cb8974b72753f51c5182f49222558f1467d5dc..e6dd311e15253cd299d903c99c3c9b8084099c43 100644 --- a/src/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java +++ b/src/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java @@ -1191,8 +1191,7 @@ class VirtualMachineImpl extends MirrorImpl } requests = new JDWP.VirtualMachine.DisposeObjects.Request[size]; for (int i = 0; i < requests.length; i++) { - SoftObjectReference ref = - (SoftObjectReference)batchedDisposeRequests.get(i); + SoftObjectReference ref = batchedDisposeRequests.get(i); if ((traceFlags & TRACE_OBJREFS) != 0) { printTrace("Disposing object " + ref.key().longValue() + " (ref count = " + ref.count() + ")"); @@ -1436,7 +1435,7 @@ class VirtualMachineImpl extends MirrorImpl } ObjectReferenceImpl object() { - return (ObjectReferenceImpl)get(); + return get(); } } } diff --git a/src/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java b/src/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java index 97131841074edbe40448c8ddbb54821ea3ce3768..2efcdd65154c53575813ebd858dda51beb545fbe 100644 --- a/src/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java +++ b/src/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java @@ -92,7 +92,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManagerService { Connector connector; try { - connector = (Connector)connectors.next(); + connector = connectors.next(); } catch (ThreadDeath x) { throw x; } catch (Exception x) { @@ -121,7 +121,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManagerService { TransportService transportService; try { - transportService = (TransportService)transportServices.next(); + transportService = transportServices.next(); } catch (ThreadDeath x) { throw x; } catch (Exception x) { diff --git a/src/share/classes/java/awt/Component.java b/src/share/classes/java/awt/Component.java index 38d50d5d09fec933cfcbdb8dc94b5e7c13801cad..b48b8c552fda95007167dc9903b2712c0bcea485 100644 --- a/src/share/classes/java/awt/Component.java +++ b/src/share/classes/java/awt/Component.java @@ -634,6 +634,11 @@ public abstract class Component implements ImageObserver, MenuContainer, */ private PropertyChangeSupport changeSupport; + private transient final Object changeSupportLock = new Object(); + private Object getChangeSupportLock() { + return changeSupportLock; + } + boolean isPacked = false; /** @@ -935,24 +940,26 @@ public abstract class Component implements ImageObserver, MenuContainer, */ public GraphicsConfiguration getGraphicsConfiguration() { synchronized(getTreeLock()) { - GraphicsConfiguration gc = graphicsConfig; - Component parent = getParent(); - while ((gc == null) && (parent != null)) { - gc = parent.getGraphicsConfiguration(); - parent = parent.getParent(); + if (graphicsConfig != null) { + return graphicsConfig; + } else if (getParent() != null) { + return getParent().getGraphicsConfiguration(); + } else { + return null; } - return gc; } } final GraphicsConfiguration getGraphicsConfiguration_NoClientCode() { - GraphicsConfiguration gc = this.graphicsConfig; - Component par = this.parent; - while ((gc == null) && (par != null)) { - gc = par.getGraphicsConfiguration_NoClientCode(); - par = par.parent; + GraphicsConfiguration graphicsConfig = this.graphicsConfig; + Container parent = this.parent; + if (graphicsConfig != null) { + return graphicsConfig; + } else if (parent != null) { + return parent.getGraphicsConfiguration_NoClientCode(); + } else { + return null; } - return gc; } /** @@ -4602,7 +4609,8 @@ public abstract class Component implements ImageObserver, MenuContainer, e.isPopupTrigger(), e.getScrollType(), e.getScrollAmount(), - e.getWheelRotation()); + e.getWheelRotation(), + e.getPreciseWheelRotation()); ((AWTEvent)e).copyPrivateDataInto(newMWE); // When dispatching a wheel event to // ancestor, there is no need trying to find descendant @@ -6484,7 +6492,7 @@ public abstract class Component implements ImageObserver, MenuContainer, // will need some help. Container parent = this.parent; if (parent != null && parent.peer instanceof LightweightPeer) { - nativeInLightFixer = new NativeInLightFixer(); + relocateComponent(); } } invalidate(); @@ -6595,10 +6603,6 @@ public abstract class Component implements ImageObserver, MenuContainer, } } - if (nativeInLightFixer != null) { - nativeInLightFixer.uninstall(); - } - ComponentPeer p = peer; if (p != null) { boolean isLightweight = isLightweight(); @@ -7836,15 +7840,17 @@ public abstract class Component implements ImageObserver, MenuContainer, * @see #getPropertyChangeListeners * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener) */ - public synchronized void addPropertyChangeListener( + public void addPropertyChangeListener( PropertyChangeListener listener) { - if (listener == null) { - return; - } - if (changeSupport == null) { - changeSupport = new PropertyChangeSupport(this); + synchronized (getChangeSupportLock()) { + if (listener == null) { + return; + } + if (changeSupport == null) { + changeSupport = new PropertyChangeSupport(this); + } + changeSupport.addPropertyChangeListener(listener); } - changeSupport.addPropertyChangeListener(listener); } /** @@ -7860,12 +7866,14 @@ public abstract class Component implements ImageObserver, MenuContainer, * @see #getPropertyChangeListeners * @see #removePropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener) */ - public synchronized void removePropertyChangeListener( + public void removePropertyChangeListener( PropertyChangeListener listener) { - if (listener == null || changeSupport == null) { - return; + synchronized (getChangeSupportLock()) { + if (listener == null || changeSupport == null) { + return; + } + changeSupport.removePropertyChangeListener(listener); } - changeSupport.removePropertyChangeListener(listener); } /** @@ -7882,11 +7890,13 @@ public abstract class Component implements ImageObserver, MenuContainer, * @see java.beans.PropertyChangeSupport#getPropertyChangeListeners * @since 1.4 */ - public synchronized PropertyChangeListener[] getPropertyChangeListeners() { - if (changeSupport == null) { - return new PropertyChangeListener[0]; + public PropertyChangeListener[] getPropertyChangeListeners() { + synchronized (getChangeSupportLock()) { + if (changeSupport == null) { + return new PropertyChangeListener[0]; + } + return changeSupport.getPropertyChangeListeners(); } - return changeSupport.getPropertyChangeListeners(); } /** @@ -7920,16 +7930,18 @@ public abstract class Component implements ImageObserver, MenuContainer, * @see #getPropertyChangeListeners(java.lang.String) * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener) */ - public synchronized void addPropertyChangeListener( + public void addPropertyChangeListener( String propertyName, PropertyChangeListener listener) { - if (listener == null) { - return; - } - if (changeSupport == null) { - changeSupport = new PropertyChangeSupport(this); + synchronized (getChangeSupportLock()) { + if (listener == null) { + return; + } + if (changeSupport == null) { + changeSupport = new PropertyChangeSupport(this); + } + changeSupport.addPropertyChangeListener(propertyName, listener); } - changeSupport.addPropertyChangeListener(propertyName, listener); } /** @@ -7948,13 +7960,15 @@ public abstract class Component implements ImageObserver, MenuContainer, * @see #getPropertyChangeListeners(java.lang.String) * @see #removePropertyChangeListener(java.beans.PropertyChangeListener) */ - public synchronized void removePropertyChangeListener( + public void removePropertyChangeListener( String propertyName, PropertyChangeListener listener) { - if (listener == null || changeSupport == null) { - return; + synchronized (getChangeSupportLock()) { + if (listener == null || changeSupport == null) { + return; + } + changeSupport.removePropertyChangeListener(propertyName, listener); } - changeSupport.removePropertyChangeListener(propertyName, listener); } /** @@ -7971,12 +7985,14 @@ public abstract class Component implements ImageObserver, MenuContainer, * @see #getPropertyChangeListeners * @since 1.4 */ - public synchronized PropertyChangeListener[] getPropertyChangeListeners( + public PropertyChangeListener[] getPropertyChangeListeners( String propertyName) { - if (changeSupport == null) { - return new PropertyChangeListener[0]; + synchronized (getChangeSupportLock()) { + if (changeSupport == null) { + return new PropertyChangeListener[0]; + } + return changeSupport.getPropertyChangeListeners(propertyName); } - return changeSupport.getPropertyChangeListeners(propertyName); } /** @@ -7991,7 +8007,10 @@ public abstract class Component implements ImageObserver, MenuContainer, */ protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { - PropertyChangeSupport changeSupport = this.changeSupport; + PropertyChangeSupport changeSupport; + synchronized (getChangeSupportLock()) { + changeSupport = this.changeSupport; + } if (changeSupport == null || (oldValue != null && newValue != null && oldValue.equals(newValue))) { return; @@ -8491,8 +8510,6 @@ public abstract class Component implements ImageObserver, MenuContainer, setComponentOrientation(orientation); } - transient NativeInLightFixer nativeInLightFixer; - /** * Checks that this component meets the prerequesites to be focus owner: * - it is enabled, visible, focusable @@ -8518,188 +8535,25 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * This odd class is to help out a native component that has been - * embedded in a lightweight component. Moving lightweight - * components around and changing their visibility is not seen - * by the native window system. This is a feature for lightweights, - * but a problem for native components that depend upon the - * lightweights. An instance of this class listens to the lightweight - * parents of an associated native component (the outer class). - * - * @author Timothy Prinzing + * Fix the location of the HW component in a LW container hierarchy. */ - final class NativeInLightFixer implements ComponentListener, ContainerListener { - - NativeInLightFixer() { - lightParents = new Vector(); - install(parent); - } - - void install(Container parent) { - lightParents.clear(); - Container p = parent; - boolean isLwParentsVisible = true; - // stash a reference to the components that are being observed so that - // we can reliably remove ourself as a listener later. - for (; p.peer instanceof LightweightPeer; p = p.parent) { - - // register listeners and stash a reference - p.addComponentListener(this); - p.addContainerListener(this); - lightParents.addElement(p); - isLwParentsVisible &= p.isVisible(); - } - // register with the native host (native parent of associated native) - // to get notified if the top-level lightweight is removed. - nativeHost = p; - p.addContainerListener(this); - - // kick start the fixup. Since the event isn't looked at - // we can simulate movement notification. - componentMoved(null); - if (!isLwParentsVisible) { - synchronized (getTreeLock()) { - if (peer != null) { - peer.hide(); - } - } - } - } - - void uninstall() { - if (nativeHost != null) { - removeReferences(); - } - } - - // --- ComponentListener ------------------------------------------- - - /** - * Invoked when one of the lightweight parents has been resized. - * This doesn't change the position of the native child so it - * is ignored. - */ - public void componentResized(ComponentEvent e) { - } - - /** - * Invoked when one of the lightweight parents has been moved. - * The native peer must be told of the new position which is - * relative to the native container that is hosting the - * lightweight components. - */ - public void componentMoved(ComponentEvent e) { - synchronized (getTreeLock()) { - int nativeX = x; - int nativeY = y; - for(Component c = parent; (c != null) && - (c.peer instanceof LightweightPeer); - c = c.parent) { - - nativeX += c.x; - nativeY += c.y; - } - if (peer != null) { - peer.setBounds(nativeX, nativeY, width, height, - ComponentPeer.SET_LOCATION); - } - } - } - - /** - * Invoked when a lightweight parent component has been - * shown. The associated native component must also be - * shown if it hasn't had an overriding hide done on it. - */ - public void componentShown(ComponentEvent e) { - if (shouldShow()) { - synchronized (getTreeLock()) { - if (peer != null) { - peer.show(); - } - } + final void relocateComponent() { + synchronized (getTreeLock()) { + if (peer == null) { + return; } - } - - /** - * Invoked when one of the lightweight parents become visible. - * Returns true if component and all its lightweight - * parents are visible. - */ - private boolean shouldShow() { - boolean isLwParentsVisible = visible; - for (int i = lightParents.size() - 1; - i >= 0 && isLwParentsVisible; - i--) + int nativeX = x; + int nativeY = y; + for (Component cont = getContainer(); + cont != null && cont.isLightweight(); + cont = cont.getContainer()) { - isLwParentsVisible &= - ((Container) lightParents.elementAt(i)).isVisible(); - } - return isLwParentsVisible; - } - - /** - * Invoked when component has been hidden. - */ - public void componentHidden(ComponentEvent e) { - if (visible) { - synchronized (getTreeLock()) { - if (peer != null) { - peer.hide(); - } - } + nativeX += cont.x; + nativeY += cont.y; } + peer.setBounds(nativeX, nativeY, width, height, + ComponentPeer.SET_LOCATION); } - - // --- ContainerListener ------------------------------------ - - /** - * Invoked when a component has been added to a lightweight - * parent. This doesn't effect the native component. - */ - public void componentAdded(ContainerEvent e) { - } - - /** - * Invoked when a lightweight parent has been removed. - * This means the services of this listener are no longer - * required and it should remove all references (ie - * registered listeners). - */ - public void componentRemoved(ContainerEvent e) { - Component c = e.getChild(); - if (c == Component.this) { - removeReferences(); - } else { - int n = lightParents.size(); - for (int i = 0; i < n; i++) { - Container p = (Container) lightParents.elementAt(i); - if (p == c) { - removeReferences(); - break; - } - } - } - } - - /** - * Removes references to this object so it can be - * garbage collected. - */ - void removeReferences() { - int n = lightParents.size(); - for (int i = 0; i < n; i++) { - Container c = (Container) lightParents.elementAt(i); - c.removeComponentListener(this); - c.removeContainerListener(this); - } - nativeHost.removeContainerListener(this); - lightParents.clear(); - nativeHost = null; - } - - Vector lightParents; - Container nativeHost; } /** @@ -9452,6 +9306,19 @@ public abstract class Component implements ImageObserver, MenuContainer, // ************************** MIXING CODE ******************************* + /** + * Check whether we can trust the current bounds of the component. + * The return value of false indicates that the container of the + * component is invalid, and therefore needs to be layed out, which would + * probably mean changing the bounds of its children. + * Null-layout of the container or absence of the container mean + * the bounds of the component are final and can be trusted. + */ + private boolean areBoundsValid() { + Container cont = getContainer(); + return cont == null || cont.isValid() || cont.getLayout() == null; + } + /** * Applies the shape to the component * @param shape Shape to be applied to the component @@ -9475,7 +9342,7 @@ public abstract class Component implements ImageObserver, MenuContainer, // to modify the object outside of the mixing code. this.compoundShape = shape; - if (isValid()) { + if (areBoundsValid()) { Point compAbsolute = getLocationOnWindow(); if (mixingLog.isLoggable(Level.FINER)) { @@ -9602,7 +9469,7 @@ public abstract class Component implements ImageObserver, MenuContainer, void applyCurrentShape() { checkTreeLock(); - if (!isValid()) { + if (!areBoundsValid()) { return; // Because applyCompoundShape() ignores such components anyway } if (mixingLog.isLoggable(Level.FINE)) { diff --git a/src/share/classes/java/awt/Container.java b/src/share/classes/java/awt/Container.java index 46164c410c6ccb934818b8f30a0dbf50aabe97f5..7eba36a11688fbb69da69205a3cead333813e0e8 100644 --- a/src/share/classes/java/awt/Container.java +++ b/src/share/classes/java/awt/Container.java @@ -832,16 +832,8 @@ public class Container extends Component { } if (!comp.isLightweight() && isLightweight()) { // If component is heavyweight and one of the containers is lightweight - // some NativeInLightFixer activity should be performed - if (!curParent.isLightweight()) { - // Moving from heavyweight container to lightweight container - should create NativeInLightFixer - // since addNotify does this - comp.nativeInLightFixer = new NativeInLightFixer(); - } else { - // Component already has NativeInLightFixer - just reinstall it - // because hierarchy changed and he needs to rebuild list of parents to listen. - comp.nativeInLightFixer.install(this); - } + // the location of the component should be fixed. + comp.relocateComponent(); } } } @@ -2267,53 +2259,56 @@ public class Container extends Component { EventTargetFilter filter, boolean searchHeavyweightChildren, boolean searchHeavyweightDescendants) { - int ncomponents = this.ncomponents; - Component component[] = this.component; + synchronized (getTreeLock()) { + int ncomponents = this.ncomponents; + Component component[] = this.component; - for (int i = 0 ; i < ncomponents ; i++) { - Component comp = component[i]; - if (comp != null && comp.visible && - ((!searchHeavyweightChildren && - comp.peer instanceof LightweightPeer) || - (searchHeavyweightChildren && - !(comp.peer instanceof LightweightPeer))) && - comp.contains(x - comp.x, y - comp.y)) { - - // found a component that intersects the point, see if there is - // a deeper possibility. - if (comp instanceof Container) { - Container child = (Container) comp; - Component deeper = child.getMouseEventTarget(x - child.x, - y - child.y, - includeSelf, - filter, - searchHeavyweightDescendants); - if (deeper != null) { - return deeper; - } - } else { - if (filter.accept(comp)) { - // there isn't a deeper target, but this component is a - // target - return comp; + for (int i = 0 ; i < ncomponents ; i++) { + Component comp = component[i]; + if (comp != null && comp.visible && + ((!searchHeavyweightChildren && + comp.peer instanceof LightweightPeer) || + (searchHeavyweightChildren && + !(comp.peer instanceof LightweightPeer))) && + comp.contains(x - comp.x, y - comp.y)) { + + // found a component that intersects the point, see if there + // is a deeper possibility. + if (comp instanceof Container) { + Container child = (Container) comp; + Component deeper = child.getMouseEventTarget( + x - child.x, + y - child.y, + includeSelf, + filter, + searchHeavyweightDescendants); + if (deeper != null) { + return deeper; + } + } else { + if (filter.accept(comp)) { + // there isn't a deeper target, but this component + // is a target + return comp; + } } } } - } - boolean isPeerOK; - boolean isMouseOverMe; + boolean isPeerOK; + boolean isMouseOverMe; - isPeerOK = (peer instanceof LightweightPeer) || includeSelf; - isMouseOverMe = contains(x,y); + isPeerOK = (peer instanceof LightweightPeer) || includeSelf; + isMouseOverMe = contains(x,y); - // didn't find a child target, return this component if it's a possible - // target - if (isMouseOverMe && isPeerOK && filter.accept(this)) { - return this; + // didn't find a child target, return this component if it's + // a possible target + if (isMouseOverMe && isPeerOK && filter.accept(this)) { + return this; + } + // no possible target + return null; } - // no possible target - return null; } static interface EventTargetFilter { @@ -3950,6 +3945,83 @@ public class Container extends Component { } } + private void recursiveShowHeavyweightChildren() { + if (!hasHeavyweightDescendants() || !isVisible()) { + return; + } + for (int index = 0; index < getComponentCount(); index++) { + Component comp = getComponent(index); + if (comp.isLightweight()) { + if (comp instanceof Container) { + ((Container)comp).recursiveShowHeavyweightChildren(); + } + } else { + if (comp.isVisible()) { + ComponentPeer peer = comp.getPeer(); + if (peer != null) { + peer.show(); + } + } + } + } + } + + private void recursiveHideHeavyweightChildren() { + if (!hasHeavyweightDescendants()) { + return; + } + for (int index = 0; index < getComponentCount(); index++) { + Component comp = getComponent(index); + if (comp.isLightweight()) { + if (comp instanceof Container) { + ((Container)comp).recursiveHideHeavyweightChildren(); + } + } else { + if (comp.isVisible()) { + ComponentPeer peer = comp.getPeer(); + if (peer != null) { + peer.hide(); + } + } + } + } + } + + private void recursiveRelocateHeavyweightChildren(Point origin) { + for (int index = 0; index < getComponentCount(); index++) { + Component comp = getComponent(index); + if (comp.isLightweight()) { + if (comp instanceof Container && + ((Container)comp).hasHeavyweightDescendants()) + { + final Point newOrigin = new Point(origin); + newOrigin.translate(comp.getX(), comp.getY()); + ((Container)comp).recursiveRelocateHeavyweightChildren(newOrigin); + } + } else { + ComponentPeer peer = comp.getPeer(); + if (peer != null) { + peer.setBounds(origin.x + comp.getX(), origin.y + comp.getY(), + comp.getWidth(), comp.getHeight(), + ComponentPeer.SET_LOCATION); + } + } + } + } + + /* + * Consider the heavyweight container hides or shows the HW descendants + * automatically. Therefore we care of LW containers' visibility only. + */ + private boolean isRecursivelyVisibleUpToHeavyweightContainer() { + if (!isLightweight()) { + return true; + } + return isVisible() && (getContainer() == null || + getContainer().isRecursivelyVisibleUpToHeavyweightContainer()); + } + + @Override void mixOnShowing() { synchronized (getTreeLock()) { if (mixingLog.isLoggable(Level.FINE)) { @@ -3958,6 +4030,10 @@ public class Container extends Component { boolean isLightweight = isLightweight(); + if (isLightweight && isRecursivelyVisibleUpToHeavyweightContainer()) { + recursiveShowHeavyweightChildren(); + } + if (!isLightweight || (isLightweight && hasHeavyweightDescendants())) { recursiveApplyCurrentShape(); } @@ -3966,6 +4042,42 @@ public class Container extends Component { } } + @Override + void mixOnHiding(boolean isLightweight) { + synchronized (getTreeLock()) { + if (mixingLog.isLoggable(Level.FINE)) { + mixingLog.fine("this = " + this + + "; isLightweight=" + isLightweight); + } + if (isLightweight) { + recursiveHideHeavyweightChildren(); + } + super.mixOnHiding(isLightweight); + } + } + + @Override + void mixOnReshaping() { + synchronized (getTreeLock()) { + if (mixingLog.isLoggable(Level.FINE)) { + mixingLog.fine("this = " + this); + } + if (isLightweight() && hasHeavyweightDescendants()) { + final Point origin = new Point(getX(), getY()); + for (Container cont = getContainer(); + cont != null && cont.isLightweight(); + cont = cont.getContainer()) + { + origin.translate(cont.getX(), cont.getY()); + } + + recursiveRelocateHeavyweightChildren(origin); + } + super.mixOnReshaping(); + } + } + + @Override void mixOnZOrderChanging(int oldZorder, int newZorder) { synchronized (getTreeLock()) { if (mixingLog.isLoggable(Level.FINE)) { @@ -4431,7 +4543,8 @@ class LightweightDispatcher implements java.io.Serializable, AWTEventListener { e.isPopupTrigger(), ((MouseWheelEvent)e).getScrollType(), ((MouseWheelEvent)e).getScrollAmount(), - ((MouseWheelEvent)e).getWheelRotation()); + ((MouseWheelEvent)e).getWheelRotation(), + ((MouseWheelEvent)e).getPreciseWheelRotation()); } else { retargeted = new MouseEvent(target, diff --git a/src/share/classes/java/awt/DefaultKeyboardFocusManager.java b/src/share/classes/java/awt/DefaultKeyboardFocusManager.java index 2587b7ee670057063dcf6fcefa565d6bb4e2d238..1874d8bb3e386c8b13e821f8435840332c5c3f03 100644 --- a/src/share/classes/java/awt/DefaultKeyboardFocusManager.java +++ b/src/share/classes/java/awt/DefaultKeyboardFocusManager.java @@ -154,7 +154,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager { private boolean doRestoreFocus(Component toFocus, Component vetoedComponent, boolean clearOnFailure) { - if (toFocus.isShowing() && toFocus.isFocusable() && + if (toFocus != vetoedComponent && toFocus.isShowing() && toFocus.isFocusable() && toFocus.requestFocus(false, CausedFocusEvent.Cause.ROLLBACK)) { return true; } else { diff --git a/src/share/classes/java/awt/Window.java b/src/share/classes/java/awt/Window.java index 440a65ddec3f8b2aaa51341631f40aafcbf9873e..3ebeee0063971a045aa1293e61d90704b1eff155 100644 --- a/src/share/classes/java/awt/Window.java +++ b/src/share/classes/java/awt/Window.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. 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 @@ -24,7 +24,6 @@ */ package java.awt; -import java.applet.Applet; import java.awt.event.*; import java.awt.im.InputContext; import java.awt.image.BufferStrategy; @@ -355,18 +354,21 @@ public class Window extends Container implements Accessible { static class WindowDisposerRecord implements sun.java2d.DisposerRecord { final WeakReference owner; final WeakReference weakThis; - final AppContext context; + final WeakReference context; WindowDisposerRecord(AppContext context, Window victim) { owner = new WeakReference(victim.getOwner()); weakThis = victim.weakThis; - this.context = context; + this.context = new WeakReference(context); } public void dispose() { Window parent = owner.get(); if (parent != null) { parent.removeOwnedWindow(weakThis); } - Window.removeFromWindowList(context, weakThis); + AppContext ac = context.get(); + if (null != ac) { + Window.removeFromWindowList(ac, weakThis); + } } } @@ -824,7 +826,10 @@ public class Window extends Container implements Accessible { static private final AtomicBoolean beforeFirstWindowShown = new AtomicBoolean(true); - static final void closeSplashScreen() { + final void closeSplashScreen() { + if (isTrayIconWindow) { + return; + } if (beforeFirstWindowShown.getAndSet(false)) { SunToolkit.closeSplashScreen(); } diff --git a/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java b/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java index c84e838403aa651ad629f2a6ee8ee2cf48e39b3a..77eb2bcec614641c532fde86b048ec84e12ef127 100644 --- a/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java +++ b/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. 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 @@ -49,7 +49,6 @@ import java.util.WeakHashMap; import sun.awt.datatransfer.DataTransferer; - /** * The SystemFlavorMap is a configurable map between "natives" (Strings), which * correspond to platform-specific data formats, and "flavors" (DataFlavors), @@ -117,15 +116,50 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { /** * Maps native Strings to Lists of DataFlavors (or base type Strings for * text DataFlavors). + * Do not use the field directly, use getNativeToFlavor() instead. */ private Map nativeToFlavor = new HashMap(); + /** + * Accessor to nativeToFlavor map. Since we use lazy initialization we must + * use this accessor instead of direct access to the field which may not be + * initialized yet. This method will initialize the field if needed. + * + * @return nativeToFlavor + */ + private Map getNativeToFlavor() { + if (!isMapInitialized) { + initSystemFlavorMap(); + } + return nativeToFlavor; + } + /** * Maps DataFlavors (or base type Strings for text DataFlavors) to Lists of * native Strings. + * Do not use the field directly, use getFlavorToNative() instead. */ private Map flavorToNative = new HashMap(); + /** + * Accessor to flavorToNative map. Since we use lazy initialization we must + * use this accessor instead of direct access to the field which may not be + * initialized yet. This method will initialize the field if needed. + * + * @return flavorToNative + */ + private synchronized Map getFlavorToNative() { + if (!isMapInitialized) { + initSystemFlavorMap(); + } + return flavorToNative; + } + + /** + * Shows if the object has been initialized. + */ + private boolean isMapInitialized = false; + /** * Caches the result of getNativesForFlavor(). Maps DataFlavors to * SoftReferences which reference Lists of String natives. @@ -169,15 +203,24 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { return fm; } + private SystemFlavorMap() { + } + /** - * Constructs a SystemFlavorMap by reading flavormap.properties and + * Initializes a SystemFlavorMap by reading flavormap.properties and * AWT.DnD.flavorMapFileURL. + * For thread-safety must be called under lock on this. */ - private SystemFlavorMap() { - BufferedReader flavormapDotProperties = (BufferedReader) + private void initSystemFlavorMap() { + if (isMapInitialized) { + return; + } + + isMapInitialized = true; + BufferedReader flavormapDotProperties = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public BufferedReader run() { String fileName = System.getProperty("java.home") + File.separator + @@ -197,12 +240,11 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { } }); - BufferedReader flavormapURL = (BufferedReader) + BufferedReader flavormapURL = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - String url = Toolkit.getDefaultToolkit().getProperty - ("AWT.DnD.flavorMapFileURL", null); + new java.security.PrivilegedAction() { + public BufferedReader run() { + String url = Toolkit.getProperty("AWT.DnD.flavorMapFileURL", null); if (url == null) { return null; @@ -237,7 +279,6 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { } } } - /** * Copied code from java.util.Properties. Parsing the data ourselves is the * only way to handle duplicate keys and values. @@ -388,11 +429,11 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { // For text/* flavors, store mappings in separate maps to // enable dynamic mapping generation at a run-time. if ("text".equals(flavor.getPrimaryType())) { - store(value, key, flavorToNative); - store(key, value, nativeToFlavor); + store(value, key, getFlavorToNative()); + store(key, value, getNativeToFlavor()); } else { - store(flavor, key, flavorToNative); - store(key, flavor, nativeToFlavor); + store(flavor, key, getFlavorToNative()); + store(key, flavor, getNativeToFlavor()); } } } @@ -494,7 +535,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { * only if the specified native is encoded as a Java MIME type. */ private List nativeToFlavorLookup(String nat) { - List flavors = (List)nativeToFlavor.get(nat); + List flavors = (List)getNativeToFlavor().get(nat); if (nat != null && !disabledMappingGenerationKeys.contains(nat)) { DataTransferer transferer = DataTransferer.getInstance(); @@ -530,15 +571,15 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { if (flavor != null) { flavors = new ArrayList(1); - nativeToFlavor.put(nat, flavors); + getNativeToFlavor().put(nat, flavors); flavors.add(flavor); getFlavorsForNativeCache.remove(nat); getFlavorsForNativeCache.remove(null); - List natives = (List)flavorToNative.get(flavor); + List natives = (List)getFlavorToNative().get(flavor); if (natives == null) { natives = new ArrayList(1); - flavorToNative.put(flavor, natives); + getFlavorToNative().put(flavor, natives); } natives.add(nat); getNativesForFlavorCache.remove(flavor); @@ -559,7 +600,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { */ private List flavorToNativeLookup(final DataFlavor flav, final boolean synthesize) { - List natives = (List)flavorToNative.get(flav); + List natives = (List)getFlavorToNative().get(flav); if (flav != null && !disabledMappingGenerationKeys.contains(flav)) { DataTransferer transferer = DataTransferer.getInstance(); @@ -584,15 +625,15 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { if (synthesize) { String encoded = encodeDataFlavor(flav); natives = new ArrayList(1); - flavorToNative.put(flav, natives); + getFlavorToNative().put(flav, natives); natives.add(encoded); getNativesForFlavorCache.remove(flav); getNativesForFlavorCache.remove(null); - List flavors = (List)nativeToFlavor.get(encoded); + List flavors = (List)getNativeToFlavor().get(encoded); if (flavors == null) { flavors = new ArrayList(1); - nativeToFlavor.put(encoded, flavors); + getNativeToFlavor().put(encoded, flavors); } flavors.add(flav); getFlavorsForNativeCache.remove(encoded); @@ -645,7 +686,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { } if (flav == null) { - retval = new ArrayList(nativeToFlavor.keySet()); + retval = new ArrayList(getNativeToFlavor().keySet()); } else if (disabledMappingGenerationKeys.contains(flav)) { // In this case we shouldn't synthesize a native for this flavor, // since its mappings were explicitly specified. @@ -655,7 +696,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { // For text/* flavors, flavor-to-native mappings specified in // flavormap.properties are stored per flavor's base type. if ("text".equals(flav.getPrimaryType())) { - retval = (List)flavorToNative.get(flav.mimeType.getBaseType()); + retval = (List)getFlavorToNative().get(flav.mimeType.getBaseType()); if (retval != null) { // To prevent the List stored in the map from modification. retval = new ArrayList(retval); @@ -663,7 +704,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { } // Also include text/plain natives, but don't duplicate Strings - List textPlainList = (List)flavorToNative.get(TEXT_PLAIN_BASE_TYPE); + List textPlainList = (List)getFlavorToNative().get(TEXT_PLAIN_BASE_TYPE); if (textPlainList != null && !textPlainList.isEmpty()) { // To prevent the List stored in the map from modification. @@ -699,7 +740,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { } } } else if (DataTransferer.isFlavorNoncharsetTextType(flav)) { - retval = (List)flavorToNative.get(flav.mimeType.getBaseType()); + retval = (List)getFlavorToNative().get(flav.mimeType.getBaseType()); if (retval == null || retval.isEmpty()) { retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND); @@ -1025,10 +1066,10 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { throw new NullPointerException("null arguments not permitted"); } - List natives = (List)flavorToNative.get(flav); + List natives = (List)getFlavorToNative().get(flav); if (natives == null) { natives = new ArrayList(1); - flavorToNative.put(flav, natives); + getFlavorToNative().put(flav, natives); } else if (natives.contains(nat)) { return; } @@ -1071,7 +1112,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { throw new NullPointerException("null arguments not permitted"); } - flavorToNative.remove(flav); + getFlavorToNative().remove(flav); for (int i = 0; i < natives.length; i++) { addUnencodedNativeForFlavor(flav, natives[i]); } @@ -1105,10 +1146,10 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { throw new NullPointerException("null arguments not permitted"); } - List flavors = (List)nativeToFlavor.get(nat); + List flavors = (List)getNativeToFlavor().get(nat); if (flavors == null) { flavors = new ArrayList(1); - nativeToFlavor.put(nat, flavors); + getNativeToFlavor().put(nat, flavors); } else if (flavors.contains(flav)) { return; } @@ -1150,7 +1191,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { throw new NullPointerException("null arguments not permitted"); } - nativeToFlavor.remove(nat); + getNativeToFlavor().remove(nat); for (int i = 0; i < flavors.length; i++) { addFlavorForUnencodedNative(nat, flavors[i]); } diff --git a/src/share/classes/java/awt/dnd/DropTarget.java b/src/share/classes/java/awt/dnd/DropTarget.java index 5995c885b2f51843cef762fdd50368bdc3efc356..aa75ec71541ca07a1d83f8b4edfa299536138de4 100644 --- a/src/share/classes/java/awt/dnd/DropTarget.java +++ b/src/share/classes/java/awt/dnd/DropTarget.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. 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 @@ -110,7 +110,11 @@ public class DropTarget implements DropTargetListener, Serializable { setActive(act); } - if (fm != null) flavorMap = fm; + if (fm != null) { + flavorMap = fm; + } else { + flavorMap = SystemFlavorMap.getDefaultFlavorMap(); + } } /** @@ -850,5 +854,5 @@ public class DropTarget implements DropTargetListener, Serializable { * The FlavorMap */ - private transient FlavorMap flavorMap = SystemFlavorMap.getDefaultFlavorMap(); + private transient FlavorMap flavorMap; } diff --git a/src/share/classes/java/awt/event/MouseWheelEvent.java b/src/share/classes/java/awt/event/MouseWheelEvent.java index 40af56c44396759633e2c23769e4326e1e329d88..a1c5b2ebb9111eb755c8914f9a42672b12ceef87 100644 --- a/src/share/classes/java/awt/event/MouseWheelEvent.java +++ b/src/share/classes/java/awt/event/MouseWheelEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2007 Sun Microsystems, Inc. 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 @@ -74,6 +74,19 @@ import java.awt.Component; * methods for conforming to the underlying platform settings. These * platform settings can be changed at any time by the user. MouseWheelEvents * reflect the most recent settings. + *

+ * The MouseWheelEvent class includes methods for + * getting the number of "clicks" by which the mouse wheel is rotated. + * The {@link #getWheelRotation} method returns the integer number + * of "clicks" corresponding to the number of notches by which the wheel was + * rotated. In addition to this method, the MouseWheelEvent + * class provides the {@link #getPreciseWheelRotation} method which returns + * a double number of "clicks" in case a partial rotation occurred. + * The {@link #getPreciseWheelRotation} method is useful if a mouse supports + * a high-resolution wheel, such as a freely rotating wheel with no + * notches. Applications can benefit by using this method to process + * mouse wheel events more precisely, and thus, making visual perception + * smoother. * * @author Brent Christian * @see MouseWheelListener @@ -131,6 +144,13 @@ public class MouseWheelEvent extends MouseEvent { */ int wheelRotation; + /** + * Indicates how far the mouse wheel was rotated. + * + * @see #getPreciseWheelRotation + */ + double preciseWheelRotation; + /* * serialVersionUID */ @@ -165,8 +185,8 @@ public class MouseWheelEvent extends MouseEvent { * WHEEL_BLOCK_SCROLL * @param scrollAmount for scrollType WHEEL_UNIT_SCROLL, * the number of units to be scrolled - * @param wheelRotation the amount that the mouse wheel was rotated (the - * number of "clicks") + * @param wheelRotation the integer number of "clicks" by which the mouse + * wheel was rotated * * @throws IllegalArgumentException if source is null * @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean) @@ -211,8 +231,8 @@ public class MouseWheelEvent extends MouseEvent { * WHEEL_BLOCK_SCROLL * @param scrollAmount for scrollType WHEEL_UNIT_SCROLL, * the number of units to be scrolled - * @param wheelRotation the amount that the mouse wheel was rotated (the - * number of "clicks") + * @param wheelRotation the integer number of "clicks" by which the mouse + * wheel was rotated * * @throws IllegalArgumentException if source is null * @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean) @@ -223,12 +243,68 @@ public class MouseWheelEvent extends MouseEvent { int x, int y, int xAbs, int yAbs, int clickCount, boolean popupTrigger, int scrollType, int scrollAmount, int wheelRotation) { + this(source, id, when, modifiers, x, y, xAbs, yAbs, clickCount, popupTrigger, + scrollType, scrollAmount, wheelRotation, wheelRotation); + + } + + + /** + * Constructs a MouseWheelEvent object with the specified + * source component, type, modifiers, coordinates, absolute coordinates, + * scroll type, scroll amount, and wheel rotation. + *

Note that passing in an invalid id parameter results + * in unspecified behavior. This method throws an + * IllegalArgumentException if source equals + * null. + *

Even if inconsistent values for relative and absolute coordinates + * are passed to the constructor, a MouseWheelEvent instance + * is still created and no exception is thrown. + * + * @param source the Component that originated the event + * @param id the integer value that identifies the event + * @param when a long value that gives the time when the event occurred + * @param modifiers the modifier keys down during event + * (shift, ctrl, alt, meta) + * @param x the horizontal x coordinate for the + * mouse location + * @param y the vertical y coordinate for the + * mouse location + * @param xAbs the absolute horizontal x coordinate for + * the mouse location + * @param yAbs the absolute vertical y coordinate for + * the mouse location + * @param clickCount the number of mouse clicks associated with the event + * @param popupTrigger a boolean value, true if this event is a trigger + * for a popup-menu + * @param scrollType the type of scrolling which should take place in + * response to this event; valid values are + * WHEEL_UNIT_SCROLL and + * WHEEL_BLOCK_SCROLL + * @param scrollAmount for scrollType WHEEL_UNIT_SCROLL, + * the number of units to be scrolled + * @param wheelRotation the integer number of "clicks" by which the mouse wheel + * was rotated + * @param preciseWheelRotation the double number of "clicks" by which the mouse wheel + * was rotated + * + * @throws IllegalArgumentException if source is null + * @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean) + * @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, int, int, boolean, int) + * @since 1.7 + */ + public MouseWheelEvent (Component source, int id, long when, int modifiers, + int x, int y, int xAbs, int yAbs, int clickCount, boolean popupTrigger, + int scrollType, int scrollAmount, int wheelRotation, double preciseWheelRotation) { + super(source, id, when, modifiers, x, y, xAbs, yAbs, clickCount, popupTrigger, MouseEvent.NOBUTTON); this.scrollType = scrollType; this.scrollAmount = scrollAmount; this.wheelRotation = wheelRotation; + this.preciseWheelRotation = preciseWheelRotation; + } /** @@ -267,16 +343,34 @@ public class MouseWheelEvent extends MouseEvent { } /** - * Returns the number of "clicks" the mouse wheel was rotated. + * Returns the number of "clicks" the mouse wheel was rotated, as an integer. + * A partial rotation may occur if the mouse supports a high-resolution wheel. + * In this case, the method returns zero until a full "click" has been accumulated. * * @return negative values if the mouse wheel was rotated up/away from * the user, and positive values if the mouse wheel was rotated down/ * towards the user + * @see #getPreciseWheelRotation */ public int getWheelRotation() { return wheelRotation; } + /** + * Returns the number of "clicks" the mouse wheel was rotated, as a double. + * A partial rotation may occur if the mouse supports a high-resolution wheel. + * In this case, the return value will include a fractional "click". + * + * @return negative values if the mouse wheel was rotated up or away from + * the user, and positive values if the mouse wheel was rotated down or + * towards the user + * @see #getWheelRotation + * @since 1.7 + */ + public double getPreciseWheelRotation() { + return preciseWheelRotation; + } + /** * This is a convenience method to aid in the implementation of * the common-case MouseWheelListener - to scroll a ScrollPane or @@ -348,6 +442,6 @@ public class MouseWheelEvent extends MouseEvent { } return super.paramString()+",scrollType="+scrollTypeStr+ ",scrollAmount="+getScrollAmount()+",wheelRotation="+ - getWheelRotation(); + getWheelRotation()+",preciseWheelRotation="+getPreciseWheelRotation(); } } diff --git a/src/share/classes/java/io/FileInputStream.java b/src/share/classes/java/io/FileInputStream.java index 8575e6d9397cc497714085daacc4150cb0da297b..a37c69c6239890ad13eea9c92a79dcc115bbc000 100644 --- a/src/share/classes/java/io/FileInputStream.java +++ b/src/share/classes/java/io/FileInputStream.java @@ -48,15 +48,15 @@ public class FileInputStream extends InputStream { /* File Descriptor - handle to the open file */ - private FileDescriptor fd; + private final FileDescriptor fd; private FileChannel channel = null; - private Object closeLock = new Object(); + private final Object closeLock = new Object(); private volatile boolean closed = false; - private static ThreadLocal runningFinalize = - new ThreadLocal(); + private static final ThreadLocal runningFinalize = + new ThreadLocal(); private static boolean isRunningFinalize() { Boolean val; @@ -151,7 +151,7 @@ class FileInputStream extends InputStream * is thrown. *

* This constructor does not throw an exception if fdObj - * is {link java.io.FileDescriptor#valid() invalid}. + * is {@link java.io.FileDescriptor#valid() invalid}. * However, if the methods are invoked on the resulting stream to attempt * I/O on the stream, an IOException is thrown. * @@ -389,7 +389,7 @@ class FileInputStream extends InputStream * @see java.io.FileInputStream#close() */ protected void finalize() throws IOException { - if ((fd != null) && (fd != fd.in)) { + if ((fd != null) && (fd != FileDescriptor.in)) { /* * Finalizer should not release the FileDescriptor if another diff --git a/src/share/classes/java/io/FileOutputStream.java b/src/share/classes/java/io/FileOutputStream.java index 695f43150fe2eaa182074755574209f66d8b29fa..f252237d89f85bb6d6025470fc21e008fec88dba 100644 --- a/src/share/classes/java/io/FileOutputStream.java +++ b/src/share/classes/java/io/FileOutputStream.java @@ -52,20 +52,16 @@ public class FileOutputStream extends OutputStream { /** - * The system dependent file descriptor. The value is - * 1 more than actual file descriptor. This means that - * the default value 0 indicates that the file is not open. + * The system dependent file descriptor. */ - private FileDescriptor fd; + private final FileDescriptor fd; private FileChannel channel= null; - private boolean append = false; - - private Object closeLock = new Object(); + private final Object closeLock = new Object(); private volatile boolean closed = false; - private static ThreadLocal runningFinalize = - new ThreadLocal(); + private static final ThreadLocal runningFinalize = + new ThreadLocal(); private static boolean isRunningFinalize() { Boolean val; @@ -75,7 +71,7 @@ class FileOutputStream extends OutputStream } /** - * Creates an output file stream to write to the file with the + * Creates a file output stream to write to the file with the * specified name. A new FileDescriptor object is * created to represent this file connection. *

@@ -100,8 +96,8 @@ class FileOutputStream extends OutputStream } /** - * Creates an output file stream to write to the file with the specified - * name. If the second argument is true, then + * Creates a file output stream to write to the file with the specified + * name. If the second argument is true, then * bytes will be written to the end of the file rather than the beginning. * A new FileDescriptor object is created to represent this * file connection. @@ -202,16 +198,11 @@ class FileOutputStream extends OutputStream } fd = new FileDescriptor(); fd.incrementAndGetUseCount(); - this.append = append; - if (append) { - openAppend(name); - } else { - open(name); - } + open(name, append); } /** - * Creates an output file stream to write to the specified file + * Creates a file output stream to write to the specified file * descriptor, which represents an existing connection to an actual * file in the file system. *

@@ -223,7 +214,7 @@ class FileOutputStream extends OutputStream * is thrown. *

* This constructor does not throw an exception if fdObj - * is {link java.io.FileDescriptor#valid() invalid}. + * is {@link java.io.FileDescriptor#valid() invalid}. * However, if the methods are invoked on the resulting stream to attempt * I/O on the stream, an IOException is thrown. * @@ -252,16 +243,12 @@ class FileOutputStream extends OutputStream } /** - * Opens a file, with the specified name, for writing. - * @param name name of file to be opened - */ - private native void open(String name) throws FileNotFoundException; - - /** - * Opens a file, with the specified name, for appending. + * Opens a file, with the specified name, for overwriting or appending. * @param name name of file to be opened + * @param append whether the file is to be opened in append mode */ - private native void openAppend(String name) throws FileNotFoundException; + private native void open(String name, boolean append) + throws FileNotFoundException; /** * Writes the specified byte to this file output stream. Implements @@ -385,7 +372,7 @@ class FileOutputStream extends OutputStream public FileChannel getChannel() { synchronized (this) { if (channel == null) { - channel = FileChannelImpl.open(fd, false, true, this, append); + channel = FileChannelImpl.open(fd, false, true, this); /* * Increment fd's use count. Invoking the channel's close() @@ -408,7 +395,7 @@ class FileOutputStream extends OutputStream */ protected void finalize() throws IOException { if (fd != null) { - if (fd == fd.out || fd == fd.err) { + if (fd == FileDescriptor.out || fd == FileDescriptor.err) { flush(); } else { diff --git a/src/share/classes/java/io/ObjectInputStream.java b/src/share/classes/java/io/ObjectInputStream.java index 9acc30cf7c19e1315b84caacbc730baa05f6f5cd..d4dd289a3b3e136e41dcf0e2d11d38125a8d9c6a 100644 --- a/src/share/classes/java/io/ObjectInputStream.java +++ b/src/share/classes/java/io/ObjectInputStream.java @@ -212,7 +212,8 @@ public class ObjectInputStream private static final Object unsharedMarker = new Object(); /** table mapping primitive type names to corresponding class objects */ - private static final HashMap primClasses = new HashMap(8, 1.0F); + private static final HashMap> primClasses + = new HashMap>(8, 1.0F); static { primClasses.put("boolean", boolean.class); primClasses.put("byte", byte.class); @@ -620,7 +621,7 @@ public class ObjectInputStream try { return Class.forName(name, false, latestUserDefinedLoader()); } catch (ClassNotFoundException ex) { - Class cl = (Class) primClasses.get(name); + Class cl = primClasses.get(name); if (cl != null) { return cl; } else { @@ -1254,11 +1255,11 @@ public class ObjectInputStream * override security-sensitive non-final methods. Returns true if subclass * is "safe", false otherwise. */ - private static boolean auditSubclass(final Class subcl) { + private static boolean auditSubclass(final Class subcl) { Boolean result = AccessController.doPrivileged( new PrivilegedAction() { public Boolean run() { - for (Class cl = subcl; + for (Class cl = subcl; cl != ObjectInputStream.class; cl = cl.getSuperclass()) { @@ -2217,9 +2218,9 @@ public class ObjectInputStream try { while (list != null) { AccessController.doPrivileged( - new PrivilegedExceptionAction() + new PrivilegedExceptionAction() { - public Object run() throws InvalidObjectException { + public Void run() throws InvalidObjectException { list.obj.validateObject(); return null; } diff --git a/src/share/classes/java/io/ObjectStreamClass.java b/src/share/classes/java/io/ObjectStreamClass.java index 2a4553b11e96486af7068072d896de134993f5bc..af6da35458b23ff3cccb6173dc6fc612820eba0c 100644 --- a/src/share/classes/java/io/ObjectStreamClass.java +++ b/src/share/classes/java/io/ObjectStreamClass.java @@ -77,7 +77,7 @@ public class ObjectStreamClass implements Serializable { NO_FIELDS; /** reflection factory for obtaining serialization constructors */ - private static final ReflectionFactory reflFactory = (ReflectionFactory) + private static final ReflectionFactory reflFactory = AccessController.doPrivileged( new ReflectionFactory.GetReflectionFactoryAction()); @@ -216,10 +216,10 @@ public class ObjectStreamClass implements Serializable { public long getSerialVersionUID() { // REMIND: synchronize instead of relying on volatile? if (suid == null) { - suid = (Long) AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - return Long.valueOf(computeDefaultSUID(cl)); + suid = AccessController.doPrivileged( + new PrivilegedAction() { + public Long run() { + return computeDefaultSUID(cl); } } ); @@ -392,8 +392,8 @@ public class ObjectStreamClass implements Serializable { } if (interrupted) { AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { + new PrivilegedAction() { + public Void run() { Thread.currentThread().interrupt(); return null; } @@ -427,8 +427,8 @@ public class ObjectStreamClass implements Serializable { localDesc = this; if (serializable) { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { if (isEnum) { suid = Long.valueOf(0); fields = NO_FIELDS; @@ -802,7 +802,7 @@ public class ObjectStreamClass implements Serializable { * non-primitive types, and any other non-null type matches assignable * types only. Returns matching field, or null if no match found. */ - ObjectStreamField getField(String name, Class type) { + ObjectStreamField getField(String name, Class type) { for (int i = 0; i < fields.length; i++) { ObjectStreamField f = fields[i]; if (f.getName().equals(name)) { @@ -811,7 +811,7 @@ public class ObjectStreamClass implements Serializable { { return f; } - Class ftype = f.getType(); + Class ftype = f.getType(); if (ftype != null && type.isAssignableFrom(ftype)) { return f; } @@ -1130,7 +1130,7 @@ public class ObjectStreamClass implements Serializable { private ClassDataSlot[] getClassDataLayout0() throws InvalidClassException { - ArrayList slots = new ArrayList(); + ArrayList slots = new ArrayList(); Class start = cl, end = cl; // locate closest non-serializable superclass @@ -1171,8 +1171,7 @@ public class ObjectStreamClass implements Serializable { // order slots from superclass -> subclass Collections.reverse(slots); - return (ClassDataSlot[]) - slots.toArray(new ClassDataSlot[slots.size()]); + return slots.toArray(new ClassDataSlot[slots.size()]); } /** @@ -1309,9 +1308,9 @@ public class ObjectStreamClass implements Serializable { * Access checks are disabled on the returned constructor (if any), since * the defining class may still be non-public. */ - private static Constructor getExternalizableConstructor(Class cl) { + private static Constructor getExternalizableConstructor(Class cl) { try { - Constructor cons = cl.getDeclaredConstructor((Class[]) null); + Constructor cons = cl.getDeclaredConstructor((Class[]) null); cons.setAccessible(true); return ((cons.getModifiers() & Modifier.PUBLIC) != 0) ? cons : null; @@ -1325,15 +1324,15 @@ public class ObjectStreamClass implements Serializable { * superclass, or null if none found. Access checks are disabled on the * returned constructor (if any). */ - private static Constructor getSerializableConstructor(Class cl) { - Class initCl = cl; + private static Constructor getSerializableConstructor(Class cl) { + Class initCl = cl; while (Serializable.class.isAssignableFrom(initCl)) { if ((initCl = initCl.getSuperclass()) == null) { return null; } } try { - Constructor cons = initCl.getDeclaredConstructor((Class[]) null); + Constructor cons = initCl.getDeclaredConstructor((Class[]) null); int mods = cons.getModifiers(); if ((mods & Modifier.PRIVATE) != 0 || ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 && @@ -1355,12 +1354,12 @@ public class ObjectStreamClass implements Serializable { * null if no match found. Access checks are disabled on the returned * method (if any). */ - private static Method getInheritableMethod(Class cl, String name, + private static Method getInheritableMethod(Class cl, String name, Class[] argTypes, Class returnType) { Method meth = null; - Class defCl = cl; + Class defCl = cl; while (defCl != null) { try { meth = defCl.getDeclaredMethod(name, argTypes); @@ -1391,9 +1390,9 @@ public class ObjectStreamClass implements Serializable { * class, or null if none found. Access checks are disabled on the * returned method (if any). */ - private static Method getPrivateMethod(Class cl, String name, - Class[] argTypes, - Class returnType) + private static Method getPrivateMethod(Class cl, String name, + Class[] argTypes, + Class returnType) { try { Method meth = cl.getDeclaredMethod(name, argTypes); @@ -1567,7 +1566,7 @@ public class ObjectStreamClass implements Serializable { ObjectStreamField[] boundFields = new ObjectStreamField[serialPersistentFields.length]; - Set fieldNames = new HashSet(serialPersistentFields.length); + Set fieldNames = new HashSet(serialPersistentFields.length); for (int i = 0; i < serialPersistentFields.length; i++) { ObjectStreamField spf = serialPersistentFields[i]; @@ -1605,7 +1604,7 @@ public class ObjectStreamClass implements Serializable { */ private static ObjectStreamField[] getDefaultSerialFields(Class cl) { Field[] clFields = cl.getDeclaredFields(); - ArrayList list = new ArrayList(); + ArrayList list = new ArrayList(); int mask = Modifier.STATIC | Modifier.TRANSIENT; for (int i = 0; i < clFields.length; i++) { @@ -1615,7 +1614,7 @@ public class ObjectStreamClass implements Serializable { } int size = list.size(); return (size == 0) ? NO_FIELDS : - (ObjectStreamField[]) list.toArray(new ObjectStreamField[size]); + list.toArray(new ObjectStreamField[size]); } /** @@ -1688,11 +1687,9 @@ public class ObjectStreamClass implements Serializable { for (int i = 0; i < fields.length; i++) { fieldSigs[i] = new MemberSignature(fields[i]); } - Arrays.sort(fieldSigs, new Comparator() { - public int compare(Object o1, Object o2) { - String name1 = ((MemberSignature) o1).name; - String name2 = ((MemberSignature) o2).name; - return name1.compareTo(name2); + Arrays.sort(fieldSigs, new Comparator() { + public int compare(MemberSignature ms1, MemberSignature ms2) { + return ms1.name.compareTo(ms2.name); } }); for (int i = 0; i < fieldSigs.length; i++) { @@ -1721,11 +1718,9 @@ public class ObjectStreamClass implements Serializable { for (int i = 0; i < cons.length; i++) { consSigs[i] = new MemberSignature(cons[i]); } - Arrays.sort(consSigs, new Comparator() { - public int compare(Object o1, Object o2) { - String sig1 = ((MemberSignature) o1).signature; - String sig2 = ((MemberSignature) o2).signature; - return sig1.compareTo(sig2); + Arrays.sort(consSigs, new Comparator() { + public int compare(MemberSignature ms1, MemberSignature ms2) { + return ms1.signature.compareTo(ms2.signature); } }); for (int i = 0; i < consSigs.length; i++) { @@ -1746,10 +1741,8 @@ public class ObjectStreamClass implements Serializable { for (int i = 0; i < methods.length; i++) { methSigs[i] = new MemberSignature(methods[i]); } - Arrays.sort(methSigs, new Comparator() { - public int compare(Object o1, Object o2) { - MemberSignature ms1 = (MemberSignature) o1; - MemberSignature ms2 = (MemberSignature) o2; + Arrays.sort(methSigs, new Comparator() { + public int compare(MemberSignature ms1, MemberSignature ms2) { int comp = ms1.name.compareTo(ms2.name); if (comp == 0) { comp = ms1.signature.compareTo(ms2.signature); @@ -1859,7 +1852,7 @@ public class ObjectStreamClass implements Serializable { keys = new long[nfields]; offsets = new int[nfields]; typeCodes = new char[nfields]; - ArrayList typeList = new ArrayList(); + ArrayList> typeList = new ArrayList>(); for (int i = 0; i < nfields; i++) { ObjectStreamField f = fields[i]; @@ -1873,7 +1866,7 @@ public class ObjectStreamClass implements Serializable { } } - types = (Class[]) typeList.toArray(new Class[typeList.size()]); + types = typeList.toArray(new Class[typeList.size()]); numPrimFields = nfields - types.length; } diff --git a/src/share/classes/java/lang/Class.java b/src/share/classes/java/lang/Class.java index 6d878c56e7862e96521b9a7dfa40d005ec50274d..632ddb6ed0e3bb72de10ffe608ad8f3a3e447eca 100644 --- a/src/share/classes/java/lang/Class.java +++ b/src/share/classes/java/lang/Class.java @@ -345,9 +345,9 @@ public final // since we have to do the security check here anyway // (the stack depth is wrong for the Constructor's // security check to work) - java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction() { - public Object run() { + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { c.setAccessible(true); return null; } @@ -1302,10 +1302,10 @@ public final // out anything other than public members and (2) public member access // has already been ok'd by the SecurityManager. - Class[] result = (Class[]) java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction() { - public Object run() { - java.util.List list = new java.util.ArrayList(); + return java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Class[] run() { + List list = new ArrayList(); Class currentClass = Class.this; while (currentClass != null) { Class[] members = currentClass.getDeclaredClasses(); @@ -1316,12 +1316,9 @@ public final } currentClass = currentClass.getSuperclass(); } - Class[] empty = {}; - return list.toArray(empty); + return list.toArray(new Class[0]); } }); - - return result; } @@ -2215,15 +2212,15 @@ public final // Caches for certain reflective results private static boolean useCaches = true; - private volatile transient SoftReference declaredFields; - private volatile transient SoftReference publicFields; - private volatile transient SoftReference declaredMethods; - private volatile transient SoftReference publicMethods; - private volatile transient SoftReference declaredConstructors; - private volatile transient SoftReference publicConstructors; + private volatile transient SoftReference declaredFields; + private volatile transient SoftReference publicFields; + private volatile transient SoftReference declaredMethods; + private volatile transient SoftReference publicMethods; + private volatile transient SoftReference[]> declaredConstructors; + private volatile transient SoftReference[]> publicConstructors; // Intermediate results for getFields and getMethods - private volatile transient SoftReference declaredPublicFields; - private volatile transient SoftReference declaredPublicMethods; + private volatile transient SoftReference declaredPublicFields; + private volatile transient SoftReference declaredPublicMethods; // Incremented by the VM on each call to JVM TI RedefineClasses() // that redefines this class or a superclass. @@ -2295,11 +2292,11 @@ public final clearCachesOnClassRedefinition(); if (publicOnly) { if (declaredPublicFields != null) { - res = (Field[]) declaredPublicFields.get(); + res = declaredPublicFields.get(); } } else { if (declaredFields != null) { - res = (Field[]) declaredFields.get(); + res = declaredFields.get(); } } if (res != null) return res; @@ -2308,9 +2305,9 @@ public final res = Reflection.filterFields(this, getDeclaredFields0(publicOnly)); if (useCaches) { if (publicOnly) { - declaredPublicFields = new SoftReference(res); + declaredPublicFields = new SoftReference(res); } else { - declaredFields = new SoftReference(res); + declaredFields = new SoftReference(res); } } return res; @@ -2319,22 +2316,22 @@ public final // Returns an array of "root" fields. These Field objects must NOT // be propagated to the outside world, but must instead be copied // via ReflectionFactory.copyField. - private Field[] privateGetPublicFields(Set traversedInterfaces) { + private Field[] privateGetPublicFields(Set> traversedInterfaces) { checkInitted(); Field[] res = null; if (useCaches) { clearCachesOnClassRedefinition(); if (publicFields != null) { - res = (Field[]) publicFields.get(); + res = publicFields.get(); } if (res != null) return res; } // No cached value available; compute value recursively. // Traverse in correct order for getField(). - List fields = new ArrayList(); + List fields = new ArrayList(); if (traversedInterfaces == null) { - traversedInterfaces = new HashSet(); + traversedInterfaces = new HashSet>(); } // Local fields @@ -2342,9 +2339,7 @@ public final addAll(fields, tmp); // Direct superinterfaces, recursively - Class[] interfaces = getInterfaces(); - for (int i = 0; i < interfaces.length; i++) { - Class c = interfaces[i]; + for (Class c : getInterfaces()) { if (!traversedInterfaces.contains(c)) { traversedInterfaces.add(c); addAll(fields, c.privateGetPublicFields(traversedInterfaces)); @@ -2353,7 +2348,7 @@ public final // Direct superclass, recursively if (!isInterface()) { - Class c = getSuperclass(); + Class c = getSuperclass(); if (c != null) { addAll(fields, c.privateGetPublicFields(traversedInterfaces)); } @@ -2362,12 +2357,12 @@ public final res = new Field[fields.size()]; fields.toArray(res); if (useCaches) { - publicFields = new SoftReference(res); + publicFields = new SoftReference(res); } return res; } - private static void addAll(Collection c, Field[] o) { + private static void addAll(Collection c, Field[] o) { for (int i = 0; i < o.length; i++) { c.add(o[i]); } @@ -2383,18 +2378,18 @@ public final // Returns an array of "root" constructors. These Constructor // objects must NOT be propagated to the outside world, but must // instead be copied via ReflectionFactory.copyConstructor. - private Constructor[] privateGetDeclaredConstructors(boolean publicOnly) { + private Constructor[] privateGetDeclaredConstructors(boolean publicOnly) { checkInitted(); - Constructor[] res = null; + Constructor[] res = null; if (useCaches) { clearCachesOnClassRedefinition(); if (publicOnly) { if (publicConstructors != null) { - res = (Constructor[]) publicConstructors.get(); + res = publicConstructors.get(); } } else { if (declaredConstructors != null) { - res = (Constructor[]) declaredConstructors.get(); + res = declaredConstructors.get(); } } if (res != null) return res; @@ -2407,9 +2402,9 @@ public final } if (useCaches) { if (publicOnly) { - publicConstructors = new SoftReference(res); + publicConstructors = new SoftReference[]>(res); } else { - declaredConstructors = new SoftReference(res); + declaredConstructors = new SoftReference[]>(res); } } return res; @@ -2431,11 +2426,11 @@ public final clearCachesOnClassRedefinition(); if (publicOnly) { if (declaredPublicMethods != null) { - res = (Method[]) declaredPublicMethods.get(); + res = declaredPublicMethods.get(); } } else { if (declaredMethods != null) { - res = (Method[]) declaredMethods.get(); + res = declaredMethods.get(); } } if (res != null) return res; @@ -2444,9 +2439,9 @@ public final res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly)); if (useCaches) { if (publicOnly) { - declaredPublicMethods = new SoftReference(res); + declaredPublicMethods = new SoftReference(res); } else { - declaredMethods = new SoftReference(res); + declaredMethods = new SoftReference(res); } } return res; @@ -2552,7 +2547,7 @@ public final if (useCaches) { clearCachesOnClassRedefinition(); if (publicMethods != null) { - res = (Method[]) publicMethods.get(); + res = publicMethods.get(); } if (res != null) return res; } @@ -2602,7 +2597,7 @@ public final methods.compactAndTrim(); res = methods.getArray(); if (useCaches) { - publicMethods = new SoftReference(res); + publicMethods = new SoftReference(res); } return res; } @@ -2713,11 +2708,11 @@ public final private Constructor getConstructor0(Class[] parameterTypes, int which) throws NoSuchMethodException { - Constructor[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC)); - for (int i = 0; i < constructors.length; i++) { + Constructor[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC)); + for (Constructor constructor : constructors) { if (arrayContentsEq(parameterTypes, - constructors[i].getParameterTypes())) { - return getReflectionFactory().copyConstructor(constructors[i]); + constructor.getParameterTypes())) { + return getReflectionFactory().copyConstructor(constructor); } } throw new NoSuchMethodException(getName() + "." + argumentTypesToString(parameterTypes)); @@ -2767,18 +2762,18 @@ public final return out; } - private static Constructor[] copyConstructors(Constructor[] arg) { - Constructor[] out = new Constructor[arg.length]; + private static Constructor[] copyConstructors(Constructor[] arg) { + Constructor[] out = arg.clone(); ReflectionFactory fact = getReflectionFactory(); - for (int i = 0; i < arg.length; i++) { - out[i] = fact.copyConstructor(arg[i]); + for (int i = 0; i < out.length; i++) { + out[i] = fact.copyConstructor(out[i]); } return out; } private native Field[] getDeclaredFields0(boolean publicOnly); private native Method[] getDeclaredMethods0(boolean publicOnly); - private native Constructor[] getDeclaredConstructors0(boolean publicOnly); + private native Constructor[] getDeclaredConstructors0(boolean publicOnly); private native Class[] getDeclaredClasses0(); private static String argumentTypesToString(Class[] argTypes) { @@ -2883,7 +2878,7 @@ public final // Fetches the factory for reflective objects private static ReflectionFactory getReflectionFactory() { if (reflectionFactory == null) { - reflectionFactory = (ReflectionFactory) + reflectionFactory = java.security.AccessController.doPrivileged (new sun.reflect.ReflectionFactory.GetReflectionFactoryAction()); } @@ -2895,8 +2890,8 @@ public final private static boolean initted = false; private static void checkInitted() { if (initted) return; - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { // Tests to ensure the system properties table is fully // initialized. This is needed because reflection code is // called very early in the initialization process (before @@ -2941,17 +2936,17 @@ public final /** * Returns the elements of this enum class or null if this * Class object does not represent an enum type; - * identical to getEnumConstantsShared except that - * the result is uncloned, cached, and shared by all callers. + * identical to getEnumConstants except that the result is + * uncloned, cached, and shared by all callers. */ T[] getEnumConstantsShared() { if (enumConstants == null) { if (!isEnum()) return null; try { final Method values = getMethod("values"); - java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction() { - public Object run() { + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { values.setAccessible(true); return null; } diff --git a/src/share/classes/java/lang/ClassLoader.java b/src/share/classes/java/lang/ClassLoader.java index 391354ec38b568655f9f9c7c1a04b6cdbc0b5ee7..1b188e23f7cd0abc09a12e3bc0ab3418d45c760d 100644 --- a/src/share/classes/java/lang/ClassLoader.java +++ b/src/share/classes/java/lang/ClassLoader.java @@ -39,6 +39,7 @@ import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.security.ProtectionDomain; +import java.security.cert.Certificate; import java.util.Enumeration; import java.util.Hashtable; import java.util.HashMap; @@ -172,17 +173,18 @@ public abstract class ClassLoader { private ClassLoader parent; // Hashtable that maps packages to certs - private Hashtable package2certs = new Hashtable(11); + private Hashtable package2certs + = new Hashtable(11); // Shared among all packages with unsigned classes - java.security.cert.Certificate[] nocerts; + Certificate[] nocerts; // The classes loaded by this class loader. The only purpose of this table // is to keep the classes from being GC'ed until the loader is GC'ed. - private Vector classes = new Vector(); + private Vector> classes = new Vector>(); // The initiating protection domains for all classes loaded by this loader - private Set domains = new HashSet(); + private Set domains = new HashSet(); // Invoked by the VM to record every loaded class with this loader. void addClass(Class c) { @@ -191,7 +193,7 @@ public abstract class ClassLoader { // The packages defined in this class loader. Each package name is mapped // to its corresponding Package object. - private HashMap packages = new HashMap(); + private HashMap packages = new HashMap(); /** * Creates a new class loader using the specified parent class loader for @@ -342,8 +344,8 @@ public abstract class ClassLoader { final String name = cls.getName(); final int i = name.lastIndexOf('.'); if (i != -1) { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { sm.checkPackageAccess(name.substring(0, i)); return null; } @@ -524,17 +526,20 @@ public abstract class ClassLoader { // Class format error - try to transform the bytecode and // define the class again // - Object[] transformers = ClassFileTransformer.getTransformers(); + ClassFileTransformer[] transformers = ClassFileTransformer.getTransformers(); Class c = null; - for (int i = 0; transformers != null && i < transformers.length; i++) { - try { - // Transform byte code using transformer - byte[] tb = ((ClassFileTransformer) transformers[i]).transform(b, off, len); - c = defineClass1(name, tb, 0, tb.length, protectionDomain, source); - break; - } catch (ClassFormatError cfe2) { - // If ClassFormatError occurs, try next transformer + if (transformers != null) { + for (ClassFileTransformer transformer : transformers) { + try { + // Transform byte code using transformer + byte[] tb = transformer.transform(b, off, len); + c = defineClass1(name, tb, 0, tb.length, + protectionDomain, source); + break; + } catch (ClassFormatError cfe2) { + // If ClassFormatError occurs, try next transformer + } } } @@ -550,7 +555,7 @@ public abstract class ClassLoader { private void postDefineClass(Class c, ProtectionDomain protectionDomain) { if (protectionDomain.getCodeSource() != null) { - java.security.cert.Certificate certs[] = + Certificate certs[] = protectionDomain.getCodeSource().getCertificates(); if (certs != null) setSigners(c, certs); @@ -767,8 +772,7 @@ public abstract class ClassLoader { private synchronized void checkCerts(String name, CodeSource cs) { int i = name.lastIndexOf('.'); String pname = (i == -1) ? "" : name.substring(0, i); - java.security.cert.Certificate[] pcerts = - (java.security.cert.Certificate[]) package2certs.get(pname); + Certificate[] pcerts = package2certs.get(pname); if (pcerts == null) { // first class in this package gets to define which // certificates must be the same for all other classes @@ -778,12 +782,12 @@ public abstract class ClassLoader { } if (pcerts == null) { if (nocerts == null) - nocerts = new java.security.cert.Certificate[0]; + nocerts = new Certificate[0]; pcerts = nocerts; } package2certs.put(pname, pcerts); } else { - java.security.cert.Certificate[] certs = null; + Certificate[] certs = null; if (cs != null) { certs = cs.getCertificates(); } @@ -799,8 +803,8 @@ public abstract class ClassLoader { * check to make sure the certs for the new class (certs) are the same as * the certs for the first class inserted in the package (pcerts) */ - private boolean compareCerts(java.security.cert.Certificate[] pcerts, - java.security.cert.Certificate[] certs) + private boolean compareCerts(Certificate[] pcerts, + Certificate[] certs) { // certs can be null, indicating no certs. if ((certs == null) || (certs.length == 0)) { @@ -1031,7 +1035,7 @@ public abstract class ClassLoader { } tmp[1] = findResources(name); - return new CompoundEnumeration(tmp); + return new CompoundEnumeration(tmp); } /** @@ -1068,7 +1072,7 @@ public abstract class ClassLoader { * @since 1.2 */ protected Enumeration findResources(String name) throws IOException { - return new CompoundEnumeration(new Enumeration[0]); + return java.util.Collections.emptyEnumeration(); } /** @@ -1134,13 +1138,13 @@ public abstract class ClassLoader { /** * Find resources from the VM's built-in classloader. */ - private static Enumeration getBootstrapResources(String name) + private static Enumeration getBootstrapResources(String name) throws IOException { - final Enumeration e = getBootstrapClassPath().getResources(name); - return new Enumeration () { - public Object nextElement() { - return ((Resource)e.nextElement()).getURL(); + final Enumeration e = getBootstrapClassPath().getResources(name); + return new Enumeration () { + public URL nextElement() { + return e.nextElement().getURL(); } public boolean hasMoreElements() { return e.hasMoreElements(); @@ -1323,9 +1327,8 @@ public abstract class ClassLoader { Throwable oops = null; scl = l.getClassLoader(); try { - PrivilegedExceptionAction a; - a = new SystemClassLoaderAction(scl); - scl = (ClassLoader) AccessController.doPrivileged(a); + scl = AccessController.doPrivileged( + new SystemClassLoaderAction(scl)); } catch (PrivilegedActionException pae) { oops = pae.getCause(); if (oops instanceof InvocationTargetException) { @@ -1456,7 +1459,7 @@ public abstract class ClassLoader { */ protected Package getPackage(String name) { synchronized (packages) { - Package pkg = (Package)packages.get(name); + Package pkg = packages.get(name); if (pkg == null) { if (parent != null) { pkg = parent.getPackage(name); @@ -1481,9 +1484,9 @@ public abstract class ClassLoader { * @since 1.2 */ protected Package[] getPackages() { - Map map; + Map map; synchronized (packages) { - map = (Map)packages.clone(); + map = new HashMap(packages); } Package[] pkgs; if (parent != null) { @@ -1499,7 +1502,7 @@ public abstract class ClassLoader { } } } - return (Package[])map.values().toArray(new Package[map.size()]); + return map.values().toArray(new Package[map.size()]); } @@ -1585,8 +1588,7 @@ public abstract class ClassLoader { // Invoked in the VM to determine the context class in // JNI_Load/JNI_Unload static Class getFromClass() { - return ((NativeLibrary) - (ClassLoader.nativeLibraryContext.peek())).fromClass; + return ClassLoader.nativeLibraryContext.peek().fromClass; } } @@ -1597,22 +1599,27 @@ public abstract class ClassLoader { // Returns (and initializes) the default domain. private synchronized ProtectionDomain getDefaultDomain() { if (defaultDomain == null) { - CodeSource cs = - new CodeSource(null, (java.security.cert.Certificate[]) null); + CodeSource cs = new CodeSource(null, (Certificate[]) null); defaultDomain = new ProtectionDomain(cs, null, this, null); } return defaultDomain; } // All native library names we've loaded. - private static Vector loadedLibraryNames = new Vector(); + private static Vector loadedLibraryNames + = new Vector(); + // Native libraries belonging to system classes. - private static Vector systemNativeLibraries = new Vector(); + private static Vector systemNativeLibraries + = new Vector(); + // Native libraries associated with the class loader. - private Vector nativeLibraries = new Vector(); + private Vector nativeLibraries + = new Vector(); // native libraries being loaded/unloaded. - private static Stack nativeLibraryContext = new Stack(); + private static Stack nativeLibraryContext + = new Stack(); // The paths searched for libraries static private String usr_paths[]; @@ -1699,13 +1706,13 @@ public abstract class ClassLoader { } private static boolean loadLibrary0(Class fromClass, final File file) { - Boolean exists = (Boolean) - AccessController.doPrivileged(new PrivilegedAction() { + boolean exists = AccessController.doPrivileged( + new PrivilegedAction() { public Object run() { - return new Boolean(file.exists()); - } - }); - if (!exists.booleanValue()) { + return file.exists() ? Boolean.TRUE : null; + }}) + != null; + if (!exists) { return false; } String name; @@ -1716,12 +1723,12 @@ public abstract class ClassLoader { } ClassLoader loader = (fromClass == null) ? null : fromClass.getClassLoader(); - Vector libs = + Vector libs = loader != null ? loader.nativeLibraries : systemNativeLibraries; synchronized (libs) { int size = libs.size(); for (int i = 0; i < size; i++) { - NativeLibrary lib = (NativeLibrary)libs.elementAt(i); + NativeLibrary lib = libs.elementAt(i); if (name.equals(lib.name)) { return true; } @@ -1748,8 +1755,7 @@ public abstract class ClassLoader { */ int n = nativeLibraryContext.size(); for (int i = 0; i < n; i++) { - NativeLibrary lib = (NativeLibrary) - nativeLibraryContext.elementAt(i); + NativeLibrary lib = nativeLibraryContext.elementAt(i); if (name.equals(lib.name)) { if (loader == lib.fromClass.getClassLoader()) { return true; @@ -1780,12 +1786,12 @@ public abstract class ClassLoader { // Invoked in the VM class linking code. static long findNative(ClassLoader loader, String name) { - Vector libs = + Vector libs = loader != null ? loader.nativeLibraries : systemNativeLibraries; synchronized (libs) { int size = libs.size(); for (int i = 0; i < size; i++) { - NativeLibrary lib = (NativeLibrary)libs.elementAt(i); + NativeLibrary lib = libs.elementAt(i); long entry = lib.find(name); if (entry != 0) return entry; @@ -1805,13 +1811,13 @@ public abstract class ClassLoader { // is null then we are delegating assertion status queries to the VM, i.e., // none of this ClassLoader's assertion status modification methods have // been invoked. - private Map packageAssertionStatus = null; + private Map packageAssertionStatus = null; // Maps String fullyQualifiedClassName to Boolean assertionStatus If this // field is null then we are delegating assertion status queries to the VM, // i.e., none of this ClassLoader's assertion status modification methods // have been invoked. - Map classAssertionStatus = null; + Map classAssertionStatus = null; /** * Sets the default assertion status for this class loader. This setting @@ -1878,7 +1884,7 @@ public abstract class ClassLoader { if (packageAssertionStatus == null) initializeJavaAssertionMaps(); - packageAssertionStatus.put(packageName, Boolean.valueOf(enabled)); + packageAssertionStatus.put(packageName, enabled); } /** @@ -1909,7 +1915,7 @@ public abstract class ClassLoader { if (classAssertionStatus == null) initializeJavaAssertionMaps(); - classAssertionStatus.put(className, Boolean.valueOf(enabled)); + classAssertionStatus.put(className, enabled); } /** @@ -1927,8 +1933,8 @@ public abstract class ClassLoader { * Whether or not "Java assertion maps" are initialized, set * them to empty maps, effectively ignoring any present settings. */ - classAssertionStatus = new HashMap(); - packageAssertionStatus = new HashMap(); + classAssertionStatus = new HashMap(); + packageAssertionStatus = new HashMap(); defaultAssertionStatus = false; } @@ -1962,20 +1968,20 @@ public abstract class ClassLoader { // assert packageAssertionStatus != null; // Check for a class entry - result = (Boolean)classAssertionStatus.get(className); + result = classAssertionStatus.get(className); if (result != null) return result.booleanValue(); // Check for most specific package entry int dotIndex = className.lastIndexOf("."); if (dotIndex < 0) { // default package - result = (Boolean)packageAssertionStatus.get(null); + result = packageAssertionStatus.get(null); if (result != null) return result.booleanValue(); } while(dotIndex > 0) { className = className.substring(0, dotIndex); - result = (Boolean)packageAssertionStatus.get(className); + result = packageAssertionStatus.get(className); if (result != null) return result.booleanValue(); dotIndex = className.lastIndexOf(".", dotIndex-1); @@ -1989,17 +1995,17 @@ public abstract class ClassLoader { private void initializeJavaAssertionMaps() { // assert Thread.holdsLock(this); - classAssertionStatus = new HashMap(); - packageAssertionStatus = new HashMap(); + classAssertionStatus = new HashMap(); + packageAssertionStatus = new HashMap(); AssertionStatusDirectives directives = retrieveDirectives(); for(int i = 0; i < directives.classes.length; i++) classAssertionStatus.put(directives.classes[i], - Boolean.valueOf(directives.classEnabled[i])); + directives.classEnabled[i]); for(int i = 0; i < directives.packages.length; i++) packageAssertionStatus.put(directives.packages[i], - Boolean.valueOf(directives.packageEnabled[i])); + directives.packageEnabled[i]); defaultAssertionStatus = directives.deflt; } @@ -2009,28 +2015,24 @@ public abstract class ClassLoader { } -class SystemClassLoaderAction implements PrivilegedExceptionAction { +class SystemClassLoaderAction + implements PrivilegedExceptionAction { private ClassLoader parent; SystemClassLoaderAction(ClassLoader parent) { this.parent = parent; } - public Object run() throws Exception { - ClassLoader sys; - Constructor ctor; - Class c; - Class cp[] = { ClassLoader.class }; - Object params[] = { parent }; - + public ClassLoader run() throws Exception { String cls = System.getProperty("java.system.class.loader"); if (cls == null) { return parent; } - c = Class.forName(cls, true, parent); - ctor = c.getDeclaredConstructor(cp); - sys = (ClassLoader) ctor.newInstance(params); + Constructor ctor = Class.forName(cls, true, parent) + .getDeclaredConstructor(new Class[] { ClassLoader.class }); + ClassLoader sys = (ClassLoader) ctor.newInstance( + new Object[] { parent }); Thread.currentThread().setContextClassLoader(sys); return sys; } diff --git a/src/share/classes/java/lang/Compiler.java b/src/share/classes/java/lang/Compiler.java index 5c2ab73db28f1c621a23de94053840d5cf2d1f74..85219174d7ff68855dfeb90c4ddd831cd657acaa 100644 --- a/src/share/classes/java/lang/Compiler.java +++ b/src/share/classes/java/lang/Compiler.java @@ -53,9 +53,9 @@ public final class Compiler { static { registerNatives(); - java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction() { - public Object run() { + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { boolean loaded = false; String jit = System.getProperty("java.compiler"); if ((jit != null) && (!jit.equals("NONE")) && diff --git a/src/share/classes/java/lang/Long.java b/src/share/classes/java/lang/Long.java index 271fd1c02c8d5914717b823d2d144f132986bc99..2f0f172698efce051cc0ecd74dab0321cb358ed0 100644 --- a/src/share/classes/java/lang/Long.java +++ b/src/share/classes/java/lang/Long.java @@ -650,7 +650,7 @@ public final class Long extends Number implements Comparable { try { result = Long.valueOf(nm.substring(index), radix); - result = negative ? new Long((long)-result.longValue()) : result; + result = negative ? new Long(-result.longValue()) : result; } catch (NumberFormatException e) { // If number is Long.MIN_VALUE, we'll end up here. The next line // handles this case, and causes any genuine format error to be diff --git a/src/share/classes/java/lang/Package.java b/src/share/classes/java/lang/Package.java index 80af5d9bc46fe6d85268c2cd6d18f7781ed6bec2..0d8779b61470ebab927e31480a11e0557ffda4c3 100644 --- a/src/share/classes/java/lang/Package.java +++ b/src/share/classes/java/lang/Package.java @@ -507,7 +507,7 @@ public class Package implements java.lang.reflect.AnnotatedElement { */ static Package getSystemPackage(String name) { synchronized (pkgs) { - Package pkg = (Package)pkgs.get(name); + Package pkg = pkgs.get(name); if (pkg == null) { name = name.replace('.', '/').concat("/"); String fn = getSystemPackage0(name); @@ -529,18 +529,18 @@ public class Package implements java.lang.reflect.AnnotatedElement { for (int i = 0; i < names.length; i++) { defineSystemPackage(names[i], getSystemPackage0(names[i])); } - return (Package[])pkgs.values().toArray(new Package[pkgs.size()]); + return pkgs.values().toArray(new Package[pkgs.size()]); } } private static Package defineSystemPackage(final String iname, final String fn) { - return (Package) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + return AccessController.doPrivileged(new PrivilegedAction() { + public Package run() { String name = iname; // Get the cached code source url for the file name - URL url = (URL)urls.get(fn); + URL url = urls.get(fn); if (url == null) { // URL not found, so create one File file = new File(fn); @@ -559,7 +559,7 @@ public class Package implements java.lang.reflect.AnnotatedElement { // Convert to "."-separated package name name = name.substring(0, name.length() - 1).replace('/', '.'); Package pkg; - Manifest man = (Manifest)mans.get(fn); + Manifest man = mans.get(fn); if (man != null) { pkg = new Package(name, man, url, null); } else { @@ -588,13 +588,16 @@ public class Package implements java.lang.reflect.AnnotatedElement { } // The map of loaded system packages - private static Map pkgs = new HashMap(31); + private static Map pkgs + = new HashMap(31); // Maps each directory or zip file name to its corresponding url - private static Map urls = new HashMap(10); + private static Map urls + = new HashMap(10); // Maps each code source url for a jar file to its manifest - private static Map mans = new HashMap(10); + private static Map mans + = new HashMap(10); private static native String getSystemPackage0(String name); private static native String[] getSystemPackages0(); diff --git a/src/share/classes/java/lang/Process.java b/src/share/classes/java/lang/Process.java index fe4045ab25f7020e67559db2524178544aaf74f6..88010fd555ddbb2878f91341903bb9d777b36afa 100644 --- a/src/share/classes/java/lang/Process.java +++ b/src/share/classes/java/lang/Process.java @@ -41,18 +41,24 @@ import java.io.*; *

The methods that create processes may not work well for special * processes on certain native platforms, such as native windowing * processes, daemon processes, Win16/DOS processes on Microsoft - * Windows, or shell scripts. The created subprocess does not have - * its own terminal or console. All its standard I/O (i.e. stdin, - * stdout, stderr) operations will be redirected to the parent process - * through three streams - * ({@link #getOutputStream()}, - * {@link #getInputStream()}, - * {@link #getErrorStream()}). + * Windows, or shell scripts. + * + *

By default, the created subprocess does not have its own terminal + * or console. All its standard I/O (i.e. stdin, stdout, stderr) + * operations will be redirected to the parent process, where they can + * be accessed via the streams obtained using the methods + * {@link #getOutputStream()}, + * {@link #getInputStream()}, and + * {@link #getErrorStream()}. * The parent process uses these streams to feed input to and get output * from the subprocess. Because some native platforms only provide * limited buffer size for standard input and output streams, failure * to promptly write the input stream or read the output stream of - * the subprocess may cause the subprocess to block, and even deadlock. + * the subprocess may cause the subprocess to block, or even deadlock. + * + *

Where desired, + * subprocess I/O can also be redirected + * using methods of the {@link ProcessBuilder} class. * *

The subprocess is not killed when there are no more references to * the {@code Process} object, but rather the subprocess @@ -62,16 +68,22 @@ import java.io.*; * Process} object execute asynchronously or concurrently with respect * to the Java process that owns the {@code Process} object. * - * @author unascribed - * @see ProcessBuilder + *

As of 1.5, {@link ProcessBuilder#start()} is the preferred way + * to create a {@code Process}. + * * @since JDK1.0 */ public abstract class Process { /** * Returns the output stream connected to the normal input of the * subprocess. Output to the stream is piped into the standard - * input stream of the process represented by this {@code Process} - * object. + * input of the process represented by this {@code Process} object. + * + *

If the standard input of the subprocess has been redirected using + * {@link ProcessBuilder#redirectInput(Redirect) + * ProcessBuilder.redirectInput} + * then this method will return a + * null output stream. * *

Implementation note: It is a good idea for the returned * output stream to be buffered. @@ -84,30 +96,47 @@ public abstract class Process { /** * Returns the input stream connected to the normal output of the * subprocess. The stream obtains data piped from the standard - * output stream of the process represented by this {@code - * Process} object. + * output of the process represented by this {@code Process} object. + * + *

If the standard output of the subprocess has been redirected using + * {@link ProcessBuilder#redirectOutput(Redirect) + * ProcessBuilder.redirectOutput} + * then this method will return a + * null input stream. + * + *

Otherwise, if the standard error of the subprocess has been + * redirected using + * {@link ProcessBuilder#redirectErrorStream(boolean) + * ProcessBuilder.redirectErrorStream} + * then the input stream returned by this method will receive the + * merged standard output and the standard error of the subprocess. * *

Implementation note: It is a good idea for the returned * input stream to be buffered. * * @return the input stream connected to the normal output of the * subprocess - * @see ProcessBuilder#redirectErrorStream() */ abstract public InputStream getInputStream(); /** - * Returns the input stream connected to the error output stream of - * the subprocess. The stream obtains data piped from the error - * output stream of the process represented by this {@code Process} - * object. + * Returns the input stream connected to the error output of the + * subprocess. The stream obtains data piped from the error output + * of the process represented by this {@code Process} object. + * + *

If the standard error of the subprocess has been redirected using + * {@link ProcessBuilder#redirectError(Redirect) + * ProcessBuilder.redirectError} or + * {@link ProcessBuilder#redirectErrorStream(boolean) + * ProcessBuilder.redirectErrorStream} + * then this method will return a + * null input stream. * *

Implementation note: It is a good idea for the returned * input stream to be buffered. * - * @return the input stream connected to the error output stream of + * @return the input stream connected to the error output of * the subprocess - * @see ProcessBuilder#redirectErrorStream() */ abstract public InputStream getErrorStream(); diff --git a/src/share/classes/java/lang/ProcessBuilder.java b/src/share/classes/java/lang/ProcessBuilder.java index 32895a5baab3b86dfe99aed0a4b2fa3835c6c7ae..be24e8d8235414a8080d275810425e7f18fa767e 100644 --- a/src/share/classes/java/lang/ProcessBuilder.java +++ b/src/share/classes/java/lang/ProcessBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. 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 @@ -27,6 +27,10 @@ package java.lang; import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.FileOutputStream; +import java.util.Arrays; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -34,7 +38,7 @@ import java.util.Map; /** * This class is used to create operating system processes. * - *

Each ProcessBuilder instance manages a collection + *

Each {@code ProcessBuilder} instance manages a collection * of process attributes. The {@link #start()} method creates a new * {@link Process} instance with those attributes. The {@link * #start()} method can be invoked repeatedly from the same instance @@ -59,19 +63,64 @@ import java.util.Map; * *

  • a working directory. The default value is the current * working directory of the current process, usually the directory - * named by the system property user.dir. + * named by the system property {@code user.dir}. + * + *
  • a source of standard input. + * By default, the subprocess reads input from a pipe. Java code + * can access this pipe via the output stream returned by + * {@link Process#getOutputStream()}. However, standard input may + * be redirected to another source using + * {@link #redirectInput(Redirect) redirectInput}. + * In this case, {@link Process#getOutputStream()} will return a + * null output stream, for which: + * + *
      + *
    • the {@link OutputStream#write(int) write} methods always + * throw {@code IOException} + *
    • the {@link OutputStream#close() close} method does nothing + *
    + * + *
  • a destination for standard output + * and standard error. By default, the subprocess writes standard + * output and standard error to pipes. Java code can access these pipes + * via the input streams returned by {@link Process#getInputStream()} and + * {@link Process#getErrorStream()}. However, standard output and + * standard error may be redirected to other destinations using + * {@link #redirectOutput(Redirect) redirectOutput} and + * {@link #redirectError(Redirect) redirectError}. + * In this case, {@link Process#getInputStream()} and/or + * {@link Process#getErrorStream()} will return a null input + * stream, for which: + * + *
      + *
    • the {@link InputStream#read() read} methods always return + * {@code -1} + *
    • the {@link InputStream#available() available} method always returns + * {@code 0} + *
    • the {@link InputStream#close() close} method does nothing + *
    * *
  • a redirectErrorStream property. Initially, this property - * is false, meaning that the standard output and error + * is {@code false}, meaning that the standard output and error * output of a subprocess are sent to two separate streams, which can * be accessed using the {@link Process#getInputStream()} and {@link - * Process#getErrorStream()} methods. If the value is set to - * true, the standard error is merged with the standard - * output. This makes it easier to correlate error messages with the - * corresponding output. In this case, the merged data can be read - * from the stream returned by {@link Process#getInputStream()}, while - * reading from the stream returned by {@link - * Process#getErrorStream()} will get an immediate end of file. + * Process#getErrorStream()} methods. + * + *

    If the value is set to {@code true}, then: + * + *

    * * * @@ -87,34 +136,43 @@ import java.util.Map; * is invoked. * *

    Note that this class is not synchronized. - * If multiple threads access a ProcessBuilder instance + * If multiple threads access a {@code ProcessBuilder} instance * concurrently, and at least one of the threads modifies one of the * attributes structurally, it must be synchronized externally. * *

    Starting a new process which uses the default working directory * and environment is easy: * - *

    + * 
     {@code
      * Process p = new ProcessBuilder("myCommand", "myArg").start();
    - * 
    + * } * *

    Here is an example that starts a process with a modified working - * directory and environment: + * directory and environment, and redirects standard output and error + * to be appended to a log file: * - *

    - * ProcessBuilder pb = new ProcessBuilder("myCommand", "myArg1", "myArg2");
    - * Map<String, String> env = pb.environment();
    + * 
     {@code
    + * ProcessBuilder pb =
    + *   new ProcessBuilder("myCommand", "myArg1", "myArg2");
    + * Map env = pb.environment();
      * env.put("VAR1", "myValue");
      * env.remove("OTHERVAR");
      * env.put("VAR2", env.get("VAR1") + "suffix");
      * pb.directory(new File("myDir"));
    + * File log = new File("log");
    + * pb.redirectErrorStream(true);
    + * pb.redirectOutput(Redirect.appendTo(log));
      * Process p = pb.start();
    - * 
    + * assert pb.redirectInput() == Redirect.PIPE; + * assert pb.redirectOutput().file() == log; + * assert p.getInputStream().read() == -1; + * } * *

    To start a process with an explicit set of environment * variables, first call {@link java.util.Map#clear() Map.clear()} * before adding environment variables. * + * @author Martin Buchholz * @since 1.5 */ @@ -124,20 +182,19 @@ public final class ProcessBuilder private File directory; private Map environment; private boolean redirectErrorStream; + private Redirect[] redirects; /** * Constructs a process builder with the specified operating * system program and arguments. This constructor does not - * make a copy of the command list. Subsequent + * make a copy of the {@code command} list. Subsequent * updates to the list will be reflected in the state of the * process builder. It is not checked whether - * command corresponds to a valid operating system - * command.

    - * - * @param command The list containing the program and its arguments + * {@code command} corresponds to a valid operating system + * command. * - * @throws NullPointerException - * If the argument is null + * @param command the list containing the program and its arguments + * @throws NullPointerException if the argument is null */ public ProcessBuilder(List command) { if (command == null) @@ -149,12 +206,12 @@ public final class ProcessBuilder * Constructs a process builder with the specified operating * system program and arguments. This is a convenience * constructor that sets the process builder's command to a string - * list containing the same strings as the command + * list containing the same strings as the {@code command} * array, in the same order. It is not checked whether - * command corresponds to a valid operating system - * command.

    + * {@code command} corresponds to a valid operating system + * command. * - * @param command A string array containing the program and its arguments + * @param command a string array containing the program and its arguments */ public ProcessBuilder(String... command) { this.command = new ArrayList(command.length); @@ -165,16 +222,15 @@ public final class ProcessBuilder /** * Sets this process builder's operating system program and * arguments. This method does not make a copy of the - * command list. Subsequent updates to the list will + * {@code command} list. Subsequent updates to the list will * be reflected in the state of the process builder. It is not - * checked whether command corresponds to a valid - * operating system command.

    + * checked whether {@code command} corresponds to a valid + * operating system command. * - * @param command The list containing the program and its arguments - * @return This process builder + * @param command the list containing the program and its arguments + * @return this process builder * - * @throws NullPointerException - * If the argument is null + * @throws NullPointerException if the argument is null */ public ProcessBuilder command(List command) { if (command == null) @@ -187,12 +243,12 @@ public final class ProcessBuilder * Sets this process builder's operating system program and * arguments. This is a convenience method that sets the command * to a string list containing the same strings as the - * command array, in the same order. It is not - * checked whether command corresponds to a valid - * operating system command.

    + * {@code command} array, in the same order. It is not + * checked whether {@code command} corresponds to a valid + * operating system command. * - * @param command A string array containing the program and its arguments - * @return This process builder + * @param command a string array containing the program and its arguments + * @return this process builder */ public ProcessBuilder command(String... command) { this.command = new ArrayList(command.length); @@ -205,9 +261,9 @@ public final class ProcessBuilder * Returns this process builder's operating system program and * arguments. The returned list is not a copy. Subsequent * updates to the list will be reflected in the state of this - * process builder.

    + * process builder. * - * @return This process builder's program and its arguments + * @return this process builder's program and its arguments */ public List command() { return command; @@ -225,10 +281,10 @@ public final class ProcessBuilder *

    The returned object may be modified using ordinary {@link * java.util.Map Map} operations. These modifications will be * visible to subprocesses started via the {@link #start()} - * method. Two ProcessBuilder instances always + * method. Two {@code ProcessBuilder} instances always * contain independent process environments, so changes to the * returned map will never be reflected in any other - * ProcessBuilder instance or the values returned by + * {@code ProcessBuilder} instance or the values returned by * {@link System#getenv System.getenv}. * *

    If the system does not support environment variables, an @@ -262,25 +318,24 @@ public final class ProcessBuilder *

    The returned map is typically case-sensitive on all platforms. * *

    If a security manager exists, its - * {@link SecurityManager#checkPermission checkPermission} - * method is called with a - * {@link RuntimePermission}("getenv.*") - * permission. This may result in a {@link SecurityException} being - * thrown. + * {@link SecurityManager#checkPermission checkPermission} method + * is called with a + * {@link RuntimePermission}{@code ("getenv.*")} permission. + * This may result in a {@link SecurityException} being thrown. * *

    When passing information to a Java subprocess, * system properties - * are generally preferred over environment variables.

    + * are generally preferred over environment variables. * - * @return This process builder's environment + * @return this process builder's environment * - * @throws SecurityException - * If a security manager exists and its - * {@link SecurityManager#checkPermission checkPermission} - * method doesn't allow access to the process environment + * @throws SecurityException + * if a security manager exists and its + * {@link SecurityManager#checkPermission checkPermission} + * method doesn't allow access to the process environment * - * @see Runtime#exec(String[],String[],java.io.File) - * @see System#getenv() + * @see Runtime#exec(String[],String[],java.io.File) + * @see System#getenv() */ public Map environment() { SecurityManager security = System.getSecurityManager(); @@ -328,12 +383,12 @@ public final class ProcessBuilder * * Subprocesses subsequently started by this object's {@link * #start()} method will use this as their working directory. - * The returned value may be null -- this means to use + * The returned value may be {@code null} -- this means to use * the working directory of the current Java process, usually the - * directory named by the system property user.dir, - * as the working directory of the child process.

    + * directory named by the system property {@code user.dir}, + * as the working directory of the child process. * - * @return This process builder's working directory + * @return this process builder's working directory */ public File directory() { return directory; @@ -344,50 +399,522 @@ public final class ProcessBuilder * * Subprocesses subsequently started by this object's {@link * #start()} method will use this as their working directory. - * The argument may be null -- this means to use the + * The argument may be {@code null} -- this means to use the * working directory of the current Java process, usually the - * directory named by the system property user.dir, - * as the working directory of the child process.

    + * directory named by the system property {@code user.dir}, + * as the working directory of the child process. * - * @param directory The new working directory - * @return This process builder + * @param directory the new working directory + * @return this process builder */ public ProcessBuilder directory(File directory) { this.directory = directory; return this; } + // ---------------- I/O Redirection ---------------- + + /** + * Implements a null input stream. + */ + static class NullInputStream extends InputStream { + public int read() { return -1; } + public int available() { return 0; } + } + + /** + * Implements a null output stream. + */ + static class NullOutputStream extends OutputStream { + public void write(int b) throws IOException { + throw new IOException("Stream closed"); + } + } + + /** + * Represents a source of subprocess input or a destination of + * subprocess output. + * + * Each {@code Redirect} instance is one of the following: + * + *
      + *
    • the special value {@link #PIPE Redirect.PIPE} + *
    • the special value {@link #INHERIT Redirect.INHERIT} + *
    • a redirection to read from a file, created by an invocation of + * {@link Redirect#from Redirect.from(File)} + *
    • a redirection to write to a file, created by an invocation of + * {@link Redirect#to Redirect.to(File)} + *
    • a redirection to append to a file, created by an invocation of + * {@link Redirect#appendTo Redirect.appendTo(File)} + *
    + * + *

    Each of the above categories has an associated unique + * {@link Type Type}. + * + * @since 1.7 + */ + public static abstract class Redirect { + /** + * The type of a {@link Redirect}. + */ + public enum Type { + /** + * The type of {@link Redirect#PIPE Redirect.PIPE}. + */ + PIPE, + + /** + * The type of {@link Redirect#INHERIT Redirect.INHERIT}. + */ + INHERIT, + + /** + * The type of redirects returned from + * {@link Redirect#from Redirect.from(File)}. + */ + READ, + + /** + * The type of redirects returned from + * {@link Redirect#to Redirect.to(File)}. + */ + WRITE, + + /** + * The type of redirects returned from + * {@link Redirect#appendTo Redirect.appendTo(File)}. + */ + APPEND + }; + + /** + * Returns the type of this {@code Redirect}. + * @return the type of this {@code Redirect} + */ + public abstract Type type(); + + /** + * Indicates that subprocess I/O will be connected to the + * current Java process over a pipe. + * + * This is the default handling of subprocess standard I/O. + * + *

    It will always be true that + *

     {@code
    +         * Redirect.PIPE.file() == null &&
    +         * Redirect.PIPE.type() == Redirect.Type.PIPE
    +         * }
    + */ + public static final Redirect PIPE = new Redirect() { + public Type type() { return Type.PIPE; } + public String toString() { return type().toString(); }}; + + /** + * Indicates that subprocess I/O source or destination will be the + * same as those of the current process. This is the normal + * behavior of most operating system command interpreters (shells). + * + *

    It will always be true that + *

     {@code
    +         * Redirect.INHERIT.file() == null &&
    +         * Redirect.INHERIT.type() == Redirect.Type.INHERIT
    +         * }
    + */ + public static final Redirect INHERIT = new Redirect() { + public Type type() { return Type.INHERIT; } + public String toString() { return type().toString(); }}; + + /** + * Returns the {@link File} source or destination associated + * with this redirect, or {@code null} if there is no such file. + * + * @return the file associated with this redirect, + * or {@code null} if there is no such file + */ + public File file() { return null; } + + FileOutputStream toFileOutputStream() throws IOException { + throw new UnsupportedOperationException(); + } + + /** + * Returns a redirect to read from the specified file. + * + *

    It will always be true that + *

     {@code
    +         * Redirect.from(file).file() == file &&
    +         * Redirect.from(file).type() == Redirect.Type.READ
    +         * }
    + * + * @throws NullPointerException if the specified file is null + * @return a redirect to read from the specified file + */ + public static Redirect from(final File file) { + if (file == null) + throw new NullPointerException(); + return new Redirect() { + public Type type() { return Type.READ; } + public File file() { return file; } + public String toString() { + return "redirect to read from file \"" + file + "\""; + } + }; + } + + /** + * Returns a redirect to write to the specified file. + * If the specified file exists when the subprocess is started, + * its previous contents will be discarded. + * + *

    It will always be true that + *

     {@code
    +         * Redirect.to(file).file() == file &&
    +         * Redirect.to(file).type() == Redirect.Type.WRITE
    +         * }
    + * + * @throws NullPointerException if the specified file is null + * @return a redirect to write to the specified file + */ + public static Redirect to(final File file) { + if (file == null) + throw new NullPointerException(); + return new Redirect() { + public Type type() { return Type.WRITE; } + public File file() { return file; } + public String toString() { + return "redirect to write to file \"" + file + "\""; + } + FileOutputStream toFileOutputStream() throws IOException { + return new FileOutputStream(file, false); + } + }; + } + + /** + * Returns a redirect to append to the specified file. + * Each write operation first advances the position to the + * end of the file and then writes the requested data. + * Whether the advancement of the position and the writing + * of the data are done in a single atomic operation is + * system-dependent and therefore unspecified. + * + *

    It will always be true that + *

     {@code
    +         * Redirect.appendTo(file).file() == file &&
    +         * Redirect.appendTo(file).type() == Redirect.Type.APPEND
    +         * }
    + * + * @throws NullPointerException if the specified file is null + * @return a redirect to append to the specified file + */ + public static Redirect appendTo(final File file) { + if (file == null) + throw new NullPointerException(); + return new Redirect() { + public Type type() { return Type.APPEND; } + public File file() { return file; } + public String toString() { + return "redirect to append to file \"" + file + "\""; + } + FileOutputStream toFileOutputStream() throws IOException { + return new FileOutputStream(file, true); + } + }; + } + + /** + * Compares the specified object with this {@code Redirect} for + * equality. Returns {@code true} if and only if the two + * objects are identical or both objects are {@code Redirect} + * instances of the same type associated with non-null equal + * {@code File} instances. + */ + public boolean equals(Object obj) { + if (obj == this) + return true; + if (! (obj instanceof Redirect)) + return false; + Redirect r = (Redirect) obj; + if (r.type() != this.type()) + return false; + assert this.file() != null; + return this.file().equals(r.file()); + } + + /** + * Returns a hash code value for this {@code Redirect}. + * @return a hash code value for this {@code Redirect} + */ + public int hashCode() { + File file = file(); + if (file == null) + return super.hashCode(); + else + return file.hashCode(); + } + + /** + * No public constructors. Clients must use predefined + * static {@code Redirect} instances or factory methods. + */ + private Redirect() {} + } + + private Redirect[] redirects() { + if (redirects == null) + redirects = new Redirect[] { + Redirect.PIPE, Redirect.PIPE, Redirect.PIPE + }; + return redirects; + } + + /** + * Sets this process builder's standard input source. + * + * Subprocesses subsequently started by this object's {@link #start()} + * method obtain their standard input from this source. + * + *

    If the source is {@link Redirect#PIPE Redirect.PIPE} + * (the initial value), then the standard input of a + * subprocess can be written to using the output stream + * returned by {@link Process#getOutputStream()}. + * If the source is set to any other value, then + * {@link Process#getOutputStream()} will return a + * null output stream. + * + * @param source the new standard input source + * @return this process builder + * @throws IllegalArgumentException + * if the redirect does not correspond to a valid source + * of data, that is, has type + * {@link Redirect.Type#WRITE WRITE} or + * {@link Redirect.Type#APPEND APPEND} + * @since 1.7 + */ + public ProcessBuilder redirectInput(Redirect source) { + if (source.type() == Redirect.Type.WRITE || + source.type() == Redirect.Type.APPEND) + throw new IllegalArgumentException( + "Redirect invalid for reading: " + source); + redirects()[0] = source; + return this; + } + + /** + * Sets this process builder's standard output destination. + * + * Subprocesses subsequently started by this object's {@link #start()} + * method send their standard output to this destination. + * + *

    If the destination is {@link Redirect#PIPE Redirect.PIPE} + * (the initial value), then the standard output of a subprocess + * can be read using the input stream returned by {@link + * Process#getInputStream()}. + * If the destination is set to any other value, then + * {@link Process#getInputStream()} will return a + * null input stream. + * + * @param destination the new standard output destination + * @return this process builder + * @throws IllegalArgumentException + * if the redirect does not correspond to a valid + * destination of data, that is, has type + * {@link Redirect.Type#READ READ} + * @since 1.7 + */ + public ProcessBuilder redirectOutput(Redirect destination) { + if (destination.type() == Redirect.Type.READ) + throw new IllegalArgumentException( + "Redirect invalid for writing: " + destination); + redirects()[1] = destination; + return this; + } + + /** + * Sets this process builder's standard error destination. + * + * Subprocesses subsequently started by this object's {@link #start()} + * method send their standard error to this destination. + * + *

    If the destination is {@link Redirect#PIPE Redirect.PIPE} + * (the initial value), then the error output of a subprocess + * can be read using the input stream returned by {@link + * Process#getErrorStream()}. + * If the destination is set to any other value, then + * {@link Process#getErrorStream()} will return a + * null input stream. + * + *

    If the {@link #redirectErrorStream redirectErrorStream} + * attribute has been set {@code true}, then the redirection set + * by this method has no effect. + * + * @param destination the new standard error destination + * @return this process builder + * @throws IllegalArgumentException + * if the redirect does not correspond to a valid + * destination of data, that is, has type + * {@link Redirect.Type#READ READ} + * @since 1.7 + */ + public ProcessBuilder redirectError(Redirect destination) { + if (destination.type() == Redirect.Type.READ) + throw new IllegalArgumentException( + "Redirect invalid for writing: " + destination); + redirects()[2] = destination; + return this; + } + + /** + * Sets this process builder's standard input source to a file. + * + *

    This is a convenience method. An invocation of the form + * {@code redirectInput(file)} + * behaves in exactly the same way as the invocation + * {@link #redirectInput(Redirect) redirectInput} + * {@code (Redirect.from(file))}. + * + * @param file the new standard input source + * @return this process builder + * @since 1.7 + */ + public ProcessBuilder redirectInput(File file) { + return redirectInput(Redirect.from(file)); + } + + /** + * Sets this process builder's standard output destination to a file. + * + *

    This is a convenience method. An invocation of the form + * {@code redirectOutput(file)} + * behaves in exactly the same way as the invocation + * {@link #redirectOutput(Redirect) redirectOutput} + * {@code (Redirect.to(file))}. + * + * @param file the new standard output destination + * @return this process builder + * @since 1.7 + */ + public ProcessBuilder redirectOutput(File file) { + return redirectOutput(Redirect.to(file)); + } + + /** + * Sets this process builder's standard error destination to a file. + * + *

    This is a convenience method. An invocation of the form + * {@code redirectError(file)} + * behaves in exactly the same way as the invocation + * {@link #redirectError(Redirect) redirectError} + * {@code (Redirect.to(file))}. + * + * @param file the new standard error destination + * @return this process builder + * @since 1.7 + */ + public ProcessBuilder redirectError(File file) { + return redirectError(Redirect.to(file)); + } + + /** + * Returns this process builder's standard input source. + * + * Subprocesses subsequently started by this object's {@link #start()} + * method obtain their standard input from this source. + * The initial value is {@link Redirect#PIPE Redirect.PIPE}. + * + * @return this process builder's standard input source + * @since 1.7 + */ + public Redirect redirectInput() { + return (redirects == null) ? Redirect.PIPE : redirects[0]; + } + + /** + * Returns this process builder's standard output destination. + * + * Subprocesses subsequently started by this object's {@link #start()} + * method redirect their standard output to this destination. + * The initial value is {@link Redirect#PIPE Redirect.PIPE}. + * + * @return this process builder's standard output destination + * @since 1.7 + */ + public Redirect redirectOutput() { + return (redirects == null) ? Redirect.PIPE : redirects[1]; + } + + /** + * Returns this process builder's standard error destination. + * + * Subprocesses subsequently started by this object's {@link #start()} + * method redirect their standard error to this destination. + * The initial value is {@link Redirect#PIPE Redirect.PIPE}. + * + * @return this process builder's standard error destination + * @since 1.7 + */ + public Redirect redirectError() { + return (redirects == null) ? Redirect.PIPE : redirects[2]; + } + + /** + * Sets the source and destination for subprocess standard I/O + * to be the same as those of the current Java process. + * + *

    This is a convenience method. An invocation of the form + *

     {@code
    +     * pb.inheritIO()
    +     * }
    + * behaves in exactly the same way as the invocation + *
     {@code
    +     * pb.redirectInput(Redirect.INHERIT)
    +     *   .redirectOutput(Redirect.INHERIT)
    +     *   .redirectError(Redirect.INHERIT)
    +     * }
    + * + * This gives behavior equivalent to most operating system + * command interpreters, or the standard C library function + * {@code system()}. + * + * @return this process builder + * @since 1.7 + */ + public ProcessBuilder inheritIO() { + Arrays.fill(redirects(), Redirect.INHERIT); + return this; + } + /** * Tells whether this process builder merges standard error and * standard output. * - *

    If this property is true, then any error output + *

    If this property is {@code true}, then any error output * generated by subprocesses subsequently started by this object's * {@link #start()} method will be merged with the standard * output, so that both can be read using the * {@link Process#getInputStream()} method. This makes it easier * to correlate error messages with the corresponding output. - * The initial value is false.

    + * The initial value is {@code false}. * - * @return This process builder's redirectErrorStream property + * @return this process builder's {@code redirectErrorStream} property */ public boolean redirectErrorStream() { return redirectErrorStream; } /** - * Sets this process builder's redirectErrorStream property. + * Sets this process builder's {@code redirectErrorStream} property. * - *

    If this property is true, then any error output + *

    If this property is {@code true}, then any error output * generated by subprocesses subsequently started by this object's * {@link #start()} method will be merged with the standard * output, so that both can be read using the * {@link Process#getInputStream()} method. This makes it easier * to correlate error messages with the corresponding output. - * The initial value is false.

    + * The initial value is {@code false}. * - * @param redirectErrorStream The new property value - * @return This process builder + * @param redirectErrorStream the new property value + * @return this process builder */ public ProcessBuilder redirectErrorStream(boolean redirectErrorStream) { this.redirectErrorStream = redirectErrorStream; @@ -410,7 +937,7 @@ public final class ProcessBuilder *

    If there is a security manager, its * {@link SecurityManager#checkExec checkExec} * method is called with the first component of this object's - * command array as its argument. This may result in + * {@code command} array as its argument. This may result in * a {@link SecurityException} being thrown. * *

    Starting an operating system process is highly system-dependent. @@ -426,26 +953,42 @@ public final class ProcessBuilder * subclass of {@link IOException}. * *

    Subsequent modifications to this process builder will not - * affect the returned {@link Process}.

    + * affect the returned {@link Process}. + * + * @return a new {@link Process} object for managing the subprocess + * + * @throws NullPointerException + * if an element of the command list is null + * + * @throws IndexOutOfBoundsException + * if the command is an empty list (has size {@code 0}) + * + * @throws SecurityException + * if a security manager exists and + *
      * - * @return A new {@link Process} object for managing the subprocess + *
    • its + * {@link SecurityManager#checkExec checkExec} + * method doesn't allow creation of the subprocess, or * - * @throws NullPointerException - * If an element of the command list is null + *
    • the standard input to the subprocess was + * {@linkplain #redirectInput redirected from a file} + * and the security manager's + * {@link SecurityManager#checkRead checkRead} method + * denies read access to the file, or * - * @throws IndexOutOfBoundsException - * If the command is an empty list (has size 0) + *
    • the standard output or standard error of the + * subprocess was + * {@linkplain #redirectOutput redirected to a file} + * and the security manager's + * {@link SecurityManager#checkWrite checkWrite} method + * denies write access to the file * - * @throws SecurityException - * If a security manager exists and its - * {@link SecurityManager#checkExec checkExec} - * method doesn't allow creation of the subprocess + *
    * - * @throws IOException - * If an I/O error occurs + * @throws IOException if an I/O error occurs * - * @see Runtime#exec(String[], String[], java.io.File) - * @see SecurityManager#checkExec(String) + * @see Runtime#exec(String[], String[], java.io.File) */ public Process start() throws IOException { // Must convert to array first -- a malicious user-supplied @@ -467,6 +1010,7 @@ public final class ProcessBuilder return ProcessImpl.start(cmdarray, environment, dir, + redirects, redirectErrorStream); } catch (IOException e) { // It's much easier for us to create a high-quality error diff --git a/src/share/classes/java/lang/StringCoding.java b/src/share/classes/java/lang/StringCoding.java index 7eb302130d19b362f17ba8ba29b78a11f416a4b0..f9d8ef3e66be3f3181d4eb332179258ce343cfaf 100644 --- a/src/share/classes/java/lang/StringCoding.java +++ b/src/share/classes/java/lang/StringCoding.java @@ -53,22 +53,23 @@ class StringCoding { private StringCoding() { } - /* The cached coders for each thread - */ - private static ThreadLocal decoder = new ThreadLocal(); - private static ThreadLocal encoder = new ThreadLocal(); + /** The cached coders for each thread */ + private final static ThreadLocal> decoder = + new ThreadLocal>(); + private final static ThreadLocal> encoder = + new ThreadLocal>(); private static boolean warnUnsupportedCharset = true; - private static Object deref(ThreadLocal tl) { - SoftReference sr = (SoftReference)tl.get(); + private static T deref(ThreadLocal> tl) { + SoftReference sr = tl.get(); if (sr == null) return null; return sr.get(); } - private static void set(ThreadLocal tl, Object ob) { - tl.set(new SoftReference(ob)); + private static void set(ThreadLocal> tl, T ob) { + tl.set(new SoftReference(ob)); } // Trim the given byte array to the given length @@ -174,7 +175,7 @@ class StringCoding { static char[] decode(String charsetName, byte[] ba, int off, int len) throws UnsupportedEncodingException { - StringDecoder sd = (StringDecoder)deref(decoder); + StringDecoder sd = deref(decoder); String csn = (charsetName == null) ? "ISO-8859-1" : charsetName; if ((sd == null) || !(csn.equals(sd.requestedCharsetName()) || csn.equals(sd.charsetName()))) { @@ -193,8 +194,7 @@ class StringCoding { static char[] decode(Charset cs, byte[] ba, int off, int len) { StringDecoder sd = new StringDecoder(cs, cs.name()); - byte[] b = Arrays.copyOf(ba, ba.length); - return sd.decode(b, off, len); + return sd.decode(Arrays.copyOfRange(ba, off, off + len), 0, len); } static char[] decode(byte[] ba, int off, int len) { @@ -273,7 +273,7 @@ class StringCoding { static byte[] encode(String charsetName, char[] ca, int off, int len) throws UnsupportedEncodingException { - StringEncoder se = (StringEncoder)deref(encoder); + StringEncoder se = deref(encoder); String csn = (charsetName == null) ? "ISO-8859-1" : charsetName; if ((se == null) || !(csn.equals(se.requestedCharsetName()) || csn.equals(se.charsetName()))) { @@ -292,8 +292,7 @@ class StringCoding { static byte[] encode(Charset cs, char[] ca, int off, int len) { StringEncoder se = new StringEncoder(cs, cs.name()); - char[] c = Arrays.copyOf(ca, ca.length); - return se.encode(c, off, len); + return se.encode(Arrays.copyOfRange(ca, off, off + len), 0, len); } static byte[] encode(char[] ca, int off, int len) { diff --git a/src/share/classes/java/lang/ref/Finalizer.java b/src/share/classes/java/lang/ref/Finalizer.java index 76b5bd9454a11a24d62a04a3c35e4e838dc8ecb5..695d71d64a11efbca6bf7f657bf2a870c6e1106d 100644 --- a/src/share/classes/java/lang/ref/Finalizer.java +++ b/src/share/classes/java/lang/ref/Finalizer.java @@ -121,8 +121,9 @@ final class Finalizer extends FinalReference { /* Package-private; must be in invokers of these methods from a stalled or deadlocked finalizer thread. */ private static void forkSecondaryFinalizer(final Runnable proc) { - PrivilegedAction pa = new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged( + new PrivilegedAction() { + public Void run() { ThreadGroup tg = Thread.currentThread().getThreadGroup(); for (ThreadGroup tgn = tg; tgn != null; @@ -135,8 +136,7 @@ final class Finalizer extends FinalReference { /* Package-private; must be in /* Ignore */ } return null; - }}; - AccessController.doPrivileged(pa); + }}); } /* Called by Runtime.runFinalization() */ diff --git a/src/share/classes/java/lang/reflect/AccessibleObject.java b/src/share/classes/java/lang/reflect/AccessibleObject.java index 23f16927ae06416df3c0e0d17fecd3b3f12ded72..29889b08810dcef4e77ccd7b984c13e9ee33705a 100644 --- a/src/share/classes/java/lang/reflect/AccessibleObject.java +++ b/src/share/classes/java/lang/reflect/AccessibleObject.java @@ -165,9 +165,9 @@ public class AccessibleObject implements AnnotatedElement { // Reflection factory used by subclasses for creating field, // method, and constructor accessors. Note that this is called // very early in the bootstrapping process. - static final ReflectionFactory reflectionFactory = (ReflectionFactory) - AccessController.doPrivileged - (new sun.reflect.ReflectionFactory.GetReflectionFactoryAction()); + static final ReflectionFactory reflectionFactory = + AccessController.doPrivileged( + new sun.reflect.ReflectionFactory.GetReflectionFactoryAction()); /** * @throws NullPointerException {@inheritDoc} diff --git a/src/share/classes/java/lang/reflect/Modifier.java b/src/share/classes/java/lang/reflect/Modifier.java index e036927ef088e3a38e5595af015e284a1115d624..952fbe8011ba7be34969ac3fbb97b0a5df6e72ce 100644 --- a/src/share/classes/java/lang/reflect/Modifier.java +++ b/src/share/classes/java/lang/reflect/Modifier.java @@ -58,9 +58,8 @@ class Modifier { */ static { sun.reflect.ReflectionFactory factory = - (sun.reflect.ReflectionFactory) AccessController.doPrivileged( - new ReflectionFactory.GetReflectionFactoryAction() - ); + AccessController.doPrivileged( + new ReflectionFactory.GetReflectionFactoryAction()); factory.setLangReflectAccess(new java.lang.reflect.ReflectAccess()); } diff --git a/src/share/classes/java/lang/reflect/Proxy.java b/src/share/classes/java/lang/reflect/Proxy.java index e9a1d40f95cb4ed226d88e6ffaf0d73a5d9d7c2c..ffa6a6dcaddc864ec581f08e1c4f863a126ed642 100644 --- a/src/share/classes/java/lang/reflect/Proxy.java +++ b/src/share/classes/java/lang/reflect/Proxy.java @@ -33,6 +33,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.List; import java.util.WeakHashMap; import sun.misc.ProxyGenerator; @@ -230,7 +231,8 @@ public class Proxy implements java.io.Serializable { { InvocationHandler.class }; /** maps a class loader to the proxy class cache for that loader */ - private static Map loaderToCache = new WeakHashMap(); + private static Map, Object>> loaderToCache + = new WeakHashMap, Object>>(); /** marks that a particular proxy class is currently being generated */ private static Object pendingGenerationMarker = new Object(); @@ -240,8 +242,8 @@ public class Proxy implements java.io.Serializable { private static Object nextUniqueNumberLock = new Object(); /** set of all generated proxy classes, for isProxyClass implementation */ - private static Map proxyClasses = - Collections.synchronizedMap(new WeakHashMap()); + private static Map, Void> proxyClasses = + Collections.synchronizedMap(new WeakHashMap, Void>()); /** * the invocation handler for this proxy instance. @@ -353,7 +355,8 @@ public class Proxy implements java.io.Serializable { /* collect interface names to use as key for proxy class cache */ String[] interfaceNames = new String[interfaces.length]; - Set interfaceSet = new HashSet(); // for detecting duplicates + // for detecting duplicates + Set> interfaceSet = new HashSet>(); for (int i = 0; i < interfaces.length; i++) { /* @@ -401,16 +404,16 @@ public class Proxy implements java.io.Serializable { * representation of a class makes for an implicit weak * reference to the class. */ - Object key = Arrays.asList(interfaceNames); + List key = Arrays.asList(interfaceNames); /* * Find or create the proxy class cache for the class loader. */ - Map cache; + Map, Object> cache; synchronized (loaderToCache) { - cache = (Map) loaderToCache.get(loader); + cache = loaderToCache.get(loader); if (cache == null) { - cache = new HashMap(); + cache = new HashMap, Object>(); loaderToCache.put(loader, cache); } /* @@ -442,7 +445,7 @@ public class Proxy implements java.io.Serializable { do { Object value = cache.get(key); if (value instanceof Reference) { - proxyClass = (Class) ((Reference) value).get(); + proxyClass = (Class) ((Reference) value).get(); } if (proxyClass != null) { // proxy class already generated: return it @@ -544,7 +547,7 @@ public class Proxy implements java.io.Serializable { */ synchronized (cache) { if (proxyClass != null) { - cache.put(key, new WeakReference(proxyClass)); + cache.put(key, new WeakReference>(proxyClass)); } else { cache.remove(key); } @@ -595,14 +598,14 @@ public class Proxy implements java.io.Serializable { /* * Look up or generate the designated proxy class. */ - Class cl = getProxyClass(loader, interfaces); + Class cl = getProxyClass(loader, interfaces); /* * Invoke its constructor with the designated invocation handler. */ try { Constructor cons = cl.getConstructor(constructorParams); - return (Object) cons.newInstance(new Object[] { h }); + return cons.newInstance(new Object[] { h }); } catch (NoSuchMethodException e) { throw new InternalError(e.toString()); } catch (IllegalAccessException e) { diff --git a/src/share/classes/java/net/AbstractPlainSocketImpl.java b/src/share/classes/java/net/AbstractPlainSocketImpl.java index ffc23824b61f10c4263ae057e2208109290b5c90..41c39f0e15f403693f83ef9fa3ab5fcd690bfc48 100644 --- a/src/share/classes/java/net/AbstractPlainSocketImpl.java +++ b/src/share/classes/java/net/AbstractPlainSocketImpl.java @@ -664,7 +664,6 @@ abstract class AbstractPlainSocketImpl extends SocketImpl abstract void socketSetOption(int cmd, boolean on, Object value) throws SocketException; abstract int socketGetOption(int opt, Object iaContainerObj) throws SocketException; - abstract int socketGetOption1(int opt, Object iaContainerObj, FileDescriptor fd) throws SocketException; abstract void socketSendUrgentData(int data) throws IOException; diff --git a/src/share/classes/java/net/DatagramSocket.java b/src/share/classes/java/net/DatagramSocket.java index 4a09fa3cc571d5139864527ca9b7f80f7635e1a2..6082bcab9f22e8e0a56704e7264cd6d64e580eb2 100644 --- a/src/share/classes/java/net/DatagramSocket.java +++ b/src/share/classes/java/net/DatagramSocket.java @@ -287,8 +287,9 @@ class DatagramSocket implements java.io.Closeable { // DatagramSocketImpl.peekdata() is a protected method, therefore we need to use // getDeclaredMethod, therefore we need permission to access the member try { - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws NoSuchMethodException { + AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Void run() throws NoSuchMethodException { Class[] cl = new Class[1]; cl[0] = DatagramPacket.class; impl.getClass().getDeclaredMethod("peekData", cl); diff --git a/src/share/classes/java/net/InterfaceAddress.java b/src/share/classes/java/net/InterfaceAddress.java index e352c35f80b6d3dfe18f04f5d1e278570c252f8f..66a65358cbcc5929ab3412b8243a37cd87ef66fc 100644 --- a/src/share/classes/java/net/InterfaceAddress.java +++ b/src/share/classes/java/net/InterfaceAddress.java @@ -103,11 +103,9 @@ public class InterfaceAddress { return false; } InterfaceAddress cmp = (InterfaceAddress) obj; - if ((address != null & cmp.address == null) || - (!address.equals(cmp.address))) + if ( !(address == null ? cmp.address == null : address.equals(cmp.address)) ) return false; - if ((broadcast != null & cmp.broadcast == null) || - (!broadcast.equals(cmp.broadcast))) + if ( !(broadcast == null ? cmp.broadcast == null : broadcast.equals(cmp.broadcast)) ) return false; if (maskLength != cmp.maskLength) return false; diff --git a/src/share/classes/java/net/NetworkInterface.java b/src/share/classes/java/net/NetworkInterface.java index 8b2899c48d950df8cf5bd4602b92a6f47771b694..0ce3a8d580bb934d54c94d03f73202d9dacf08f7 100644 --- a/src/share/classes/java/net/NetworkInterface.java +++ b/src/share/classes/java/net/NetworkInterface.java @@ -425,8 +425,6 @@ public final class NetworkInterface { return virtual; } - private native static long getSubnet0(String name, int ind) throws SocketException; - private native static Inet4Address getBroadcast0(String name, int ind) throws SocketException; private native static boolean isUp0(String name, int ind) throws SocketException; private native static boolean isLoopback0(String name, int ind) throws SocketException; private native static boolean supportsMulticast0(String name, int ind) throws SocketException; diff --git a/src/share/classes/java/net/ServerSocket.java b/src/share/classes/java/net/ServerSocket.java index 8b632f665d68ab7bfec0d72ca85ab3c2c9587a41..2793b2f961e8942be76b6bdaebbdb85f314f4c89 100644 --- a/src/share/classes/java/net/ServerSocket.java +++ b/src/share/classes/java/net/ServerSocket.java @@ -247,8 +247,9 @@ class ServerSocket implements java.io.Closeable { // SocketImpl.connect() is a protected method, therefore we need to use // getDeclaredMethod, therefore we need permission to access the member try { - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws NoSuchMethodException { + AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Void run() throws NoSuchMethodException { Class[] cl = new Class[2]; cl[0] = SocketAddress.class; cl[1] = Integer.TYPE; diff --git a/src/share/classes/java/net/Socket.java b/src/share/classes/java/net/Socket.java index c02dd4e2855b19db9dbb77a24e34287bfe3c330a..5dd5f7f2e4151567edff467d2055bca5c085792e 100644 --- a/src/share/classes/java/net/Socket.java +++ b/src/share/classes/java/net/Socket.java @@ -731,7 +731,8 @@ class Socket implements java.io.Closeable { * then this method will continue to return the connected address * after the socket is closed. * - * @return a SocketAddress reprensenting the remote endpoint of this + + * @return a SocketAddress representing the remote endpoint of this * socket, or null if it is not connected yet. * @see #getInetAddress() * @see #getPort() @@ -847,9 +848,9 @@ class Socket implements java.io.Closeable { final Socket s = this; InputStream is = null; try { - is = (InputStream) - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws IOException { + is = AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public InputStream run() throws IOException { return impl.getInputStream(); } }); @@ -887,9 +888,9 @@ class Socket implements java.io.Closeable { final Socket s = this; OutputStream os = null; try { - os = (OutputStream) - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws IOException { + os = AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public OutputStream run() throws IOException { return impl.getOutputStream(); } }); diff --git a/src/share/classes/java/net/SocksSocketImpl.java b/src/share/classes/java/net/SocksSocketImpl.java index df88e645be8f21af9f8b47f185fd4a96626445af..76e11e957f7079a3fc9cc15eae2717bb755266be 100644 --- a/src/share/classes/java/net/SocksSocketImpl.java +++ b/src/share/classes/java/net/SocksSocketImpl.java @@ -78,8 +78,8 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { { try { AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { - public Object run() throws IOException { + new java.security.PrivilegedExceptionAction() { + public Void run() throws IOException { superConnectServer(host, port, timeout); cmdIn = getInputStream(); cmdOut = getOutputStream(); @@ -129,10 +129,10 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { String userName; String password = null; final InetAddress addr = InetAddress.getByName(server); - PasswordAuthentication pw = (PasswordAuthentication) + PasswordAuthentication pw = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public PasswordAuthentication run() { return Authenticator.requestPasswordAuthentication( server, addr, port, "SOCKS5", "SOCKS authentication", null); } @@ -339,10 +339,9 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { // This is the general case // server is not null only when the socket was created with a // specified proxy in which case it does bypass the ProxySelector - ProxySelector sel = (ProxySelector) - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + ProxySelector sel = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public ProxySelector run() { return ProxySelector.getDefault(); } }); @@ -652,10 +651,9 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { // This is the general case // server is not null only when the socket was created with a // specified proxy in which case it does bypass the ProxySelector - ProxySelector sel = (ProxySelector) - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + ProxySelector sel = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public ProxySelector run() { return ProxySelector.getDefault(); } }); @@ -701,8 +699,9 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { // Connects to the SOCKS server try { - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { + AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Void run() throws Exception { cmdsock = new Socket(new PlainSocketImpl()); cmdsock.connect(new InetSocketAddress(server, port)); cmdIn = cmdsock.getInputStream(); @@ -731,8 +730,9 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { } } else { try { - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { + AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Void run() throws Exception { cmdsock = new Socket(new PlainSocketImpl()); cmdsock.connect(new InetSocketAddress(server, port)); cmdIn = cmdsock.getInputStream(); diff --git a/src/share/classes/java/net/URLClassLoader.java b/src/share/classes/java/net/URLClassLoader.java index 267a005d1017a4249910116dba396f28842fc073..5a6cfefecb3067064e53aeaa0b3d2651bf29eefc 100644 --- a/src/share/classes/java/net/URLClassLoader.java +++ b/src/share/classes/java/net/URLClassLoader.java @@ -205,9 +205,9 @@ public class URLClassLoader extends SecureClassLoader { throws ClassNotFoundException { try { - return (Class) - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws ClassNotFoundException { + return AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Class run() throws ClassNotFoundException { String path = name.replace('.', '/').concat(".class"); Resource res = ucp.getResource(path, false); if (res != null) { @@ -376,9 +376,9 @@ public class URLClassLoader extends SecureClassLoader { /* * The same restriction to finding classes applies to resources */ - URL url = - (URL) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + URL url = AccessController.doPrivileged( + new PrivilegedAction() { + public URL run() { return ucp.findResource(name, true); } }, acc); @@ -397,7 +397,7 @@ public class URLClassLoader extends SecureClassLoader { public Enumeration findResources(final String name) throws IOException { - final Enumeration e = ucp.findResources(name, true); + final Enumeration e = ucp.findResources(name, true); return new Enumeration() { private URL url = null; @@ -407,9 +407,9 @@ public class URLClassLoader extends SecureClassLoader { return true; } do { - URL u = (URL) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + URL u = AccessController.doPrivileged( + new PrivilegedAction() { + public URL run() { if (!e.hasMoreElements()) return null; return e.nextElement(); @@ -515,8 +515,8 @@ public class URLClassLoader extends SecureClassLoader { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { final Permission fp = p; - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() throws SecurityException { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() throws SecurityException { sm.checkPermission(fp); return null; } @@ -544,9 +544,9 @@ public class URLClassLoader extends SecureClassLoader { // Save the caller's context AccessControlContext acc = AccessController.getContext(); // Need a privileged block to create the class loader - URLClassLoader ucl = - (URLClassLoader) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + URLClassLoader ucl = AccessController.doPrivileged( + new PrivilegedAction() { + public URLClassLoader run() { return new FactoryURLClassLoader(urls, parent); } }); @@ -571,9 +571,9 @@ public class URLClassLoader extends SecureClassLoader { // Save the caller's context AccessControlContext acc = AccessController.getContext(); // Need a privileged block to create the class loader - URLClassLoader ucl = (URLClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + URLClassLoader ucl = AccessController.doPrivileged( + new PrivilegedAction() { + public URLClassLoader run() { return new FactoryURLClassLoader(urls); } }); diff --git a/src/share/classes/java/net/URLConnection.java b/src/share/classes/java/net/URLConnection.java index c1236bd3a63df882dc1dc17bf76943bda07437e9..a78032a2fcc91d510a5fa0a5f26a1aa6243b6660 100644 --- a/src/share/classes/java/net/URLConnection.java +++ b/src/share/classes/java/net/URLConnection.java @@ -1072,7 +1072,7 @@ public abstract class URLConnection { * properties to be appended into a single property. * * @param key the keyword by which the request is known - * (e.g., "accept"). + * (e.g., "Accept"). * @param value the value associated with it. * @throws IllegalStateException if already connected * @throws NullPointerException if key is null @@ -1096,7 +1096,7 @@ public abstract class URLConnection { * existing values associated with the same key. * * @param key the keyword by which the request is known - * (e.g., "accept"). + * (e.g., "Accept"). * @param value the value associated with it. * @throws IllegalStateException if already connected * @throws NullPointerException if key is null @@ -1120,7 +1120,7 @@ public abstract class URLConnection { * Returns the value of the named general request property for this * connection. * - * @param key the keyword by which the request is known (e.g., "accept"). + * @param key the keyword by which the request is known (e.g., "Accept"). * @return the value of the named general request property for this * connection. If key is null, then null is returned. * @throws IllegalStateException if already connected @@ -1164,7 +1164,7 @@ public abstract class URLConnection { * these properties. * * @param key the keyword by which the request is known - * (e.g., "accept"). + * (e.g., "Accept"). * @param value the value associated with the key. * * @see java.net.URLConnection#setRequestProperty(java.lang.String,java.lang.String) @@ -1183,7 +1183,7 @@ public abstract class URLConnection { * Returns the value of the default request property. Default request * properties are set for every connection. * - * @param key the keyword by which the request is known (e.g., "accept"). + * @param key the keyword by which the request is known (e.g., "Accept"). * @return the value of the default request property * for the specified key. * diff --git a/src/share/classes/java/nio/StringCharBuffer.java b/src/share/classes/java/nio/StringCharBuffer.java index d5a80f26d1c5adfa89bcfcaf266014c1b547c3db..c6ef51eb0dcd9ffe574e967a247fbb0e3ac709ff 100644 --- a/src/share/classes/java/nio/StringCharBuffer.java +++ b/src/share/classes/java/nio/StringCharBuffer.java @@ -60,16 +60,9 @@ class StringCharBuffer // package-private str = s; } - private StringCharBuffer(CharSequence s, int mark, - int pos, int limit, int cap) - { - super(mark, pos, limit, cap); - str = s; - } - public CharBuffer duplicate() { return new StringCharBuffer(str, markValue(), - position(), limit(), capacity()); + position(), limit(), capacity(), offset); } public CharBuffer asReadOnlyBuffer() { @@ -77,11 +70,11 @@ class StringCharBuffer // package-private } public final char get() { - return str.charAt(nextGetIndex()); + return str.charAt(nextGetIndex() + offset); } public final char get(int index) { - return str.charAt(checkIndex(index)); + return str.charAt(checkIndex(index) + offset); } // ## Override bulk get methods for better performance @@ -103,15 +96,16 @@ class StringCharBuffer // package-private } final String toString(int start, int end) { - return str.toString().substring(start, end); + return str.toString().substring(start + offset, end + offset); } public final CharSequence subSequence(int start, int end) { try { int pos = position(); - return new StringCharBuffer(str, + return new StringCharBuffer(str, -1, pos + checkIndex(start, pos), - pos + checkIndex(end, pos)); + pos + checkIndex(end, pos), + remaining(), offset); } catch (IllegalArgumentException x) { throw new IndexOutOfBoundsException(); } diff --git a/src/share/classes/java/nio/channels/Channels.java b/src/share/classes/java/nio/channels/Channels.java index a6e8a042d571e93f0de07fb1f308d5a38765b492..a39bb382022d70b81362c4a0d71ef05033db7e17 100644 --- a/src/share/classes/java/nio/channels/Channels.java +++ b/src/share/classes/java/nio/channels/Channels.java @@ -66,7 +66,27 @@ public final class Channels { private Channels() { } // No instantiation - private static int write(WritableByteChannel ch, ByteBuffer bb) + /** + * Write all remaining bytes in buffer to the given channel. + * If the channel is selectable then it must be configured blocking. + */ + private static void writeFullyImpl(WritableByteChannel ch, ByteBuffer bb) + throws IOException + { + while (bb.remaining() > 0) { + int n = ch.write(bb); + if (n <= 0) + throw new RuntimeException("no bytes written"); + } + } + + /** + * Write all remaining bytes in buffer to the given channel. + * + * @throws IllegalBlockingException + * If the channel is selectable and configured non-blocking. + */ + private static void writeFully(WritableByteChannel ch, ByteBuffer bb) throws IOException { if (ch instanceof SelectableChannel) { @@ -74,14 +94,13 @@ public final class Channels { synchronized (sc.blockingLock()) { if (!sc.isBlocking()) throw new IllegalBlockingModeException(); - return ch.write(bb); + writeFullyImpl(ch, bb); } } else { - return ch.write(bb); + writeFullyImpl(ch, bb); } } - // -- Byte streams from channels -- /** @@ -148,7 +167,7 @@ public final class Channels { bb.position(off); this.bb = bb; this.bs = bs; - Channels.write(ch, bb); + Channels.writeFully(ch, bb); } public void close() throws IOException { diff --git a/src/share/classes/java/nio/channels/spi/SelectorProvider.java b/src/share/classes/java/nio/channels/spi/SelectorProvider.java index a227addacf26036509e38455c6dcb7a8194809b0..196359bfd91399f25b779726f5f1478d0a499d7d 100644 --- a/src/share/classes/java/nio/channels/spi/SelectorProvider.java +++ b/src/share/classes/java/nio/channels/spi/SelectorProvider.java @@ -167,9 +167,9 @@ public abstract class SelectorProvider { synchronized (lock) { if (provider != null) return provider; - return (SelectorProvider)AccessController - .doPrivileged(new PrivilegedAction() { - public Object run() { + return AccessController.doPrivileged( + new PrivilegedAction() { + public SelectorProvider run() { if (loadProviderFromProperty()) return provider; if (loadProviderAsService()) diff --git a/src/share/classes/java/nio/charset/Charset.java b/src/share/classes/java/nio/charset/Charset.java index 1372343271274fda5f35a1c31209060193ef8dff..4c166d519a2747293f36de1347d401642c3fb134 100644 --- a/src/share/classes/java/nio/charset/Charset.java +++ b/src/share/classes/java/nio/charset/Charset.java @@ -212,36 +212,47 @@ import sun.security.action.GetPropertyAction; * *

    Terminology

    * - *

    The name of this class is taken from the terms used in RFC 2278. In that - * document a charset is defined as the combination of a coded character - * set and a character-encoding scheme. + *

    The name of this class is taken from the terms used in + * RFC 2278. + * In that document a charset is defined as the combination of + * one or more coded character sets and a character-encoding scheme. + * (This definition is confusing; some other software systems define + * charset as a synonym for coded character set.) * *

    A coded character set is a mapping between a set of abstract * characters and a set of integers. US-ASCII, ISO 8859-1, - * JIS X 0201, and full Unicode, which is the same as - * ISO 10646-1, are examples of coded character sets. - * - *

    A character-encoding scheme is a mapping between a coded - * character set and a set of octet (eight-bit byte) sequences. UTF-8, UCS-2, - * UTF-16, ISO 2022, and EUC are examples of character-encoding schemes. - * Encoding schemes are often associated with a particular coded character set; - * UTF-8, for example, is used only to encode Unicode. Some schemes, however, - * are associated with multiple character sets; EUC, for example, can be used - * to encode characters in a variety of Asian character sets. + * JIS X 0201, and Unicode are examples of coded character sets. + * + *

    Some standards have defined a character set to be simply a + * set of abstract characters without an associated assigned numbering. + * An alphabet is an example of such a character set. However, the subtle + * distinction between character set and coded character set + * is rarely used in practice; the former has become a short form for the + * latter, including in the Java API specification. + * + *

    A character-encoding scheme is a mapping between one or more + * coded character sets and a set of octet (eight-bit byte) sequences. + * UTF-8, UTF-16, ISO 2022, and EUC are examples of + * character-encoding schemes. Encoding schemes are often associated with + * a particular coded character set; UTF-8, for example, is used only to + * encode Unicode. Some schemes, however, are associated with multiple + * coded character sets; EUC, for example, can be used to encode + * characters in a variety of Asian coded character sets. * *

    When a coded character set is used exclusively with a single - * character-encoding scheme then the corresponding charset is usually named - * for the character set; otherwise a charset is usually named for the encoding - * scheme and, possibly, the locale of the character sets that it supports. - * Hence US-ASCII is the name of the charset for US-ASCII while + * character-encoding scheme then the corresponding charset is usually + * named for the coded character set; otherwise a charset is usually named + * for the encoding scheme and, possibly, the locale of the coded + * character sets that it supports. Hence US-ASCII is both the + * name of a coded character set and of the charset that encodes it, while * EUC-JP is the name of the charset that encodes the * JIS X 0201, JIS X 0208, and JIS X 0212 - * character sets. + * coded character sets for the Japanese language. * *

    The native character encoding of the Java programming language is - * UTF-16. A charset in the Java platform therefore defines a mapping between - * sequences of sixteen-bit UTF-16 code units and sequences of bytes.

    + * UTF-16. A charset in the Java platform therefore defines a mapping + * between sequences of sixteen-bit UTF-16 code units (that is, sequences + * of chars) and sequences of bytes.

    * * * @author Mark Reinhold diff --git a/src/share/classes/java/rmi/activation/ActivationGroupDesc.java b/src/share/classes/java/rmi/activation/ActivationGroupDesc.java index a36274168513aecd939be0f46a47d88b5ea214c9..41a25db97f2e5721cd6d83fb0e43a8ef708a5b1c 100644 --- a/src/share/classes/java/rmi/activation/ActivationGroupDesc.java +++ b/src/share/classes/java/rmi/activation/ActivationGroupDesc.java @@ -263,7 +263,7 @@ public final class ActivationGroupDesc implements Serializable { * @since 1.2 */ public String[] getCommandOptions() { - return (String[]) options.clone(); + return options.clone(); } /** diff --git a/src/share/classes/java/rmi/dgc/VMID.java b/src/share/classes/java/rmi/dgc/VMID.java index bbfd169c011901a35b1d988e16d2ed3368426ceb..9f7801aabd4d725f650b1d326acc5ade25855b7e 100644 --- a/src/share/classes/java/rmi/dgc/VMID.java +++ b/src/share/classes/java/rmi/dgc/VMID.java @@ -136,9 +136,9 @@ public final class VMID implements java.io.Serializable { /* * Get the local host's IP address. */ - byte[] addr = (byte[]) java.security.AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { + byte[] addr = java.security.AccessController.doPrivileged( + new PrivilegedAction() { + public byte[] run() { try { return InetAddress.getLocalHost().getAddress(); } catch (Exception e) { diff --git a/src/share/classes/java/security/AccessControlContext.java b/src/share/classes/java/security/AccessControlContext.java index 601bc40ba56551756d95ae4f369eb5b6f9ba9c2e..0a9cfb85b5e408b8857c577544bde0417e38c364 100644 --- a/src/share/classes/java/security/AccessControlContext.java +++ b/src/share/classes/java/security/AccessControlContext.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. 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 @@ -322,7 +322,7 @@ public final class AccessControlContext { debug.println("access denied " + perm); } - if (Debug.isOn("failure")) { + if (Debug.isOn("failure") && debug != null) { // Want to make sure this is always displayed for failure, // but do not want to display again if already displayed // above. diff --git a/src/share/classes/java/security/KeyStore.java b/src/share/classes/java/security/KeyStore.java index f19a231bfbdc81a4f1bbaaeb3f5902585ef740db..ced20e274463073bbfe3c859a236b68d617e501b 100644 --- a/src/share/classes/java/security/KeyStore.java +++ b/src/share/classes/java/security/KeyStore.java @@ -789,7 +789,7 @@ public class KeyStore { * @param alias the alias name * * @return the certificate chain (ordered with the user's certificate first - * and the root certificate authority last), or null if the given alias + * followed by zero or more certificate authorities), or null if the given alias * does not exist or does not contain a certificate chain * * @exception KeyStoreException if the keystore has not been initialized diff --git a/src/share/classes/java/security/cert/TrustAnchor.java b/src/share/classes/java/security/cert/TrustAnchor.java index 9fdac7b2c9855a0c6bb176b0fe93f0092dc69d8e..cd4c3de7097ab6f2a623251e80e9ae2304575d14 100644 --- a/src/share/classes/java/security/cert/TrustAnchor.java +++ b/src/share/classes/java/security/cert/TrustAnchor.java @@ -275,7 +275,7 @@ public class TrustAnchor { ncBytes = null; nc = null; } else { - ncBytes = (byte []) bytes.clone(); + ncBytes = bytes.clone(); // validate DER encoding try { nc = new NameConstraintsExtension(Boolean.FALSE, bytes); @@ -309,7 +309,7 @@ public class TrustAnchor { * or null if not set. */ public final byte [] getNameConstraints() { - return (ncBytes == null ? null : (byte []) ncBytes.clone()); + return ncBytes == null ? null : ncBytes.clone(); } /** diff --git a/src/share/classes/java/security/cert/X509CertSelector.java b/src/share/classes/java/security/cert/X509CertSelector.java index dbcdf017e76012acd429451c593f32cb210e3ff2..6ec61c17d60d5d4ab5fe19ac1cac0e2ee2cb14bb 100644 --- a/src/share/classes/java/security/cert/X509CertSelector.java +++ b/src/share/classes/java/security/cert/X509CertSelector.java @@ -381,7 +381,7 @@ public class X509CertSelector implements CertSelector { if (subjectKeyID == null) { this.subjectKeyID = null; } else { - this.subjectKeyID = (byte[])subjectKeyID.clone(); + this.subjectKeyID = subjectKeyID.clone(); } } @@ -442,7 +442,7 @@ public class X509CertSelector implements CertSelector { if (authorityKeyID == null) { this.authorityKeyID = null; } else { - this.authorityKeyID = (byte[])authorityKeyID.clone(); + this.authorityKeyID = authorityKeyID.clone(); } } @@ -566,7 +566,7 @@ public class X509CertSelector implements CertSelector { subjectPublicKey = null; subjectPublicKeyBytes = null; } else { - subjectPublicKeyBytes = (byte[])key.clone(); + subjectPublicKeyBytes = key.clone(); subjectPublicKey = X509Key.parse(new DerValue(subjectPublicKeyBytes)); } } @@ -590,7 +590,7 @@ public class X509CertSelector implements CertSelector { if (keyUsage == null) { this.keyUsage = null; } else { - this.keyUsage = (boolean[])keyUsage.clone(); + this.keyUsage = keyUsage.clone(); } } @@ -1041,7 +1041,7 @@ public class X509CertSelector implements CertSelector { ncBytes = null; nc = null; } else { - ncBytes = (byte[])bytes.clone(); + ncBytes = bytes.clone(); nc = new NameConstraintsExtension(FALSE, bytes); } } @@ -1438,7 +1438,7 @@ public class X509CertSelector implements CertSelector { if (subjectKeyID == null) { return null; } - return (byte[])subjectKeyID.clone(); + return subjectKeyID.clone(); } /** @@ -1457,7 +1457,7 @@ public class X509CertSelector implements CertSelector { if (authorityKeyID == null) { return null; } - return (byte[])authorityKeyID.clone(); + return authorityKeyID.clone(); } /** @@ -1546,7 +1546,7 @@ public class X509CertSelector implements CertSelector { if (keyUsage == null) { return null; } - return (boolean[])keyUsage.clone(); + return keyUsage.clone(); } /** @@ -1736,7 +1736,7 @@ public class X509CertSelector implements CertSelector { if (ncBytes == null) { return null; } else { - return (byte[]) ncBytes.clone(); + return ncBytes.clone(); } } diff --git a/src/share/classes/java/util/ArrayList.java b/src/share/classes/java/util/ArrayList.java index 36c846e3b31d0260ae5214da40620b2c081d792f..f769822ce81ab03636488b5192157ba8b4fd8cc3 100644 --- a/src/share/classes/java/util/ArrayList.java +++ b/src/share/classes/java/util/ArrayList.java @@ -892,7 +892,7 @@ public class ArrayList extends AbstractList private final AbstractList parent; private final int parentOffset; private final int offset; - private int size; + int size; SubList(AbstractList parent, int offset, int fromIndex, int toIndex) { @@ -971,6 +971,7 @@ public class ArrayList extends AbstractList public ListIterator listIterator(final int index) { checkForComodification(); rangeCheckForAdd(index); + final int offset = this.offset; return new ListIterator() { int cursor = index; diff --git a/src/share/classes/java/util/Arrays.java b/src/share/classes/java/util/Arrays.java index 3d103ad51b006b95912968cafc4a1a8745b4b7ce..46744d2c6bea1673f1821ee9ed45c09e0f3f97a7 100644 --- a/src/share/classes/java/util/Arrays.java +++ b/src/share/classes/java/util/Arrays.java @@ -1088,7 +1088,7 @@ public class Arrays { * mutually comparable (for example, strings and integers). */ public static void sort(Object[] a) { - Object[] aux = (Object[])a.clone(); + Object[] aux = a.clone(); mergeSort(aux, a, 0, a.length, 0); } @@ -1216,7 +1216,7 @@ public class Arrays { * not mutually comparable using the specified comparator. */ public static void sort(T[] a, Comparator c) { - T[] aux = (T[])a.clone(); + T[] aux = a.clone(); if (c==null) mergeSort(aux, a, 0, a.length, 0); else @@ -1257,7 +1257,7 @@ public class Arrays { public static void sort(T[] a, int fromIndex, int toIndex, Comparator c) { rangeCheck(a.length, fromIndex, toIndex); - T[] aux = (T[])copyOfRange(a, fromIndex, toIndex); + T[] aux = copyOfRange(a, fromIndex, toIndex); if (c==null) mergeSort(aux, a, fromIndex, toIndex, -fromIndex); else @@ -4128,7 +4128,7 @@ public class Arrays { if (a.length != 0 && bufLen <= 0) bufLen = Integer.MAX_VALUE; StringBuilder buf = new StringBuilder(bufLen); - deepToString(a, buf, new HashSet()); + deepToString(a, buf, new HashSet()); return buf.toString(); } diff --git a/src/share/classes/java/util/EnumMap.java b/src/share/classes/java/util/EnumMap.java index 896e07d2833ddb84660f5b5acbccceea92dfc36b..867ccc7bc560a10379a02349993f2f136b7db114 100644 --- a/src/share/classes/java/util/EnumMap.java +++ b/src/share/classes/java/util/EnumMap.java @@ -140,7 +140,7 @@ public class EnumMap, V> extends AbstractMap public EnumMap(EnumMap m) { keyType = m.keyType; keyUniverse = m.keyUniverse; - vals = (Object[]) m.vals.clone(); + vals = m.vals.clone(); size = m.size; } @@ -161,7 +161,7 @@ public class EnumMap, V> extends AbstractMap EnumMap em = (EnumMap) m; keyType = em.keyType; keyUniverse = em.keyUniverse; - vals = (Object[]) em.vals.clone(); + vals = em.vals.clone(); size = em.size; } else { if (m.isEmpty()) @@ -257,7 +257,7 @@ public class EnumMap, V> extends AbstractMap public V put(K key, V value) { typeCheck(key); - int index = ((Enum)key).ordinal(); + int index = key.ordinal(); Object oldValue = vals[index]; vals[index] = maskNull(value); if (oldValue == null) @@ -662,7 +662,7 @@ public class EnumMap, V> extends AbstractMap } catch(CloneNotSupportedException e) { throw new AssertionError(); } - result.vals = (Object[]) result.vals.clone(); + result.vals = result.vals.clone(); return result; } diff --git a/src/share/classes/java/util/HashMap.java b/src/share/classes/java/util/HashMap.java index fbb7b730a72254fa7f9624e7797936043b990c13..daebd7867fe29f4e683920a7f2f85a6edad313fd 100644 --- a/src/share/classes/java/util/HashMap.java +++ b/src/share/classes/java/util/HashMap.java @@ -173,7 +173,7 @@ public class HashMap * rehash). This field is used to make iterators on Collection-views of * the HashMap fail-fast. (See ConcurrentModificationException). */ - transient volatile int modCount; + transient int modCount; /** * Constructs an empty HashMap with the specified initial diff --git a/src/share/classes/java/util/Hashtable.java b/src/share/classes/java/util/Hashtable.java index 46ff36b40965250a03b8b0712c664b5f36ddfaac..c19a6ad249a4f7b35e53a658c1b778e1f223671a 100644 --- a/src/share/classes/java/util/Hashtable.java +++ b/src/share/classes/java/util/Hashtable.java @@ -27,7 +27,7 @@ package java.util; import java.io.*; /** - * This class implements a hashtable, which maps keys to values. Any + * This class implements a hash table, which maps keys to values. Any * non-null object can be used as a key or as a value.

    * * To successfully store and retrieve objects from a hashtable, the @@ -100,9 +100,15 @@ import java.io.*; * *

    As of the Java 2 platform v1.2, this class was retrofitted to * implement the {@link Map} interface, making it a member of the - * Java - * Collections Framework. Unlike the new collection - * implementations, {@code Hashtable} is synchronized. + * + * + * Java Collections Framework. Unlike the new collection + * implementations, {@code Hashtable} is synchronized. If a + * thread-safe implementation is not needed, it is recommended to use + * {@link HashMap} in place of {@code Hashtable}. If a thread-safe + * highly-concurrent implementation is desired, then it is recommended + * to use {@link java.util.concurrent.ConcurrentHashMap} in place of + * {@code Hashtable}. * * @author Arthur van Hoff * @author Josh Bloch diff --git a/src/share/classes/java/util/IdentityHashMap.java b/src/share/classes/java/util/IdentityHashMap.java index 1898ccad515eef0fda6ad31c70d85604782dfd49..7e27bd76e8dc94cde2e24bf4d74cedb81304c43b 100644 --- a/src/share/classes/java/util/IdentityHashMap.java +++ b/src/share/classes/java/util/IdentityHashMap.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. 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 @@ -173,7 +173,7 @@ public class IdentityHashMap /** * The number of modifications, to support fast-fail iterators */ - private transient volatile int modCount; + private transient int modCount; /** * The next size value at which to resize (capacity * load factor). @@ -701,7 +701,7 @@ public class IdentityHashMap try { IdentityHashMap m = (IdentityHashMap) super.clone(); m.entrySet = null; - m.table = (Object[])table.clone(); + m.table = table.clone(); return m; } catch (CloneNotSupportedException e) { throw new InternalError(); @@ -749,7 +749,6 @@ public class IdentityHashMap expectedModCount = ++modCount; int deletedSlot = lastReturnedIndex; lastReturnedIndex = -1; - size--; // back up index to revisit new contents after deletion index = deletedSlot; indexValid = false; @@ -782,6 +781,8 @@ public class IdentityHashMap return; } + size--; + Object item; for (int i = nextKeyIndex(d, len); (item = tab[i]) != null; i = nextKeyIndex(i, len)) { @@ -975,7 +976,7 @@ public class IdentityHashMap */ public boolean removeAll(Collection c) { boolean modified = false; - for (Iterator i = iterator(); i.hasNext(); ) { + for (Iterator i = iterator(); i.hasNext(); ) { if (c.contains(i.next())) { i.remove(); modified = true; @@ -1033,7 +1034,7 @@ public class IdentityHashMap return containsValue(o); } public boolean remove(Object o) { - for (Iterator i = iterator(); i.hasNext(); ) { + for (Iterator i = iterator(); i.hasNext(); ) { if (i.next() == o) { i.remove(); return true; @@ -1121,7 +1122,7 @@ public class IdentityHashMap */ public boolean removeAll(Collection c) { boolean modified = false; - for (Iterator i = iterator(); i.hasNext(); ) { + for (Iterator> i = iterator(); i.hasNext(); ) { if (c.contains(i.next())) { i.remove(); modified = true; diff --git a/src/share/classes/java/util/JumboEnumSet.java b/src/share/classes/java/util/JumboEnumSet.java index 6512e2cd5c91eef066739c97adb6521e8897c713..de72c5fc5f99e8888dfd2bcff39f888eea233de4 100644 --- a/src/share/classes/java/util/JumboEnumSet.java +++ b/src/share/classes/java/util/JumboEnumSet.java @@ -364,7 +364,7 @@ class JumboEnumSet> extends EnumSet { public EnumSet clone() { JumboEnumSet result = (JumboEnumSet) super.clone(); - result.elements = (long[]) result.elements.clone(); + result.elements = result.elements.clone(); return result; } } diff --git a/src/share/classes/java/util/Random.java b/src/share/classes/java/util/Random.java index b16b48532b2eb59a7c3b8629a72885929393999a..f30feb934fe45a221d5142aa706733f7bef0cc82 100644 --- a/src/share/classes/java/util/Random.java +++ b/src/share/classes/java/util/Random.java @@ -504,7 +504,7 @@ class Random implements java.io.Serializable { // The seed is read in as {@code long} for // historical reasons, but it is converted to an AtomicLong. - long seedVal = (long) fields.get("seed", -1L); + long seedVal = fields.get("seed", -1L); if (seedVal < 0) throw new java.io.StreamCorruptedException( "Random: invalid seed"); diff --git a/src/share/classes/java/util/TreeSet.java b/src/share/classes/java/util/TreeSet.java index 81b02e3663a54d1f4e6090ef2ef8b5b6d9e392cd..c4d538e95932608808068675db4902d82db5e756 100644 --- a/src/share/classes/java/util/TreeSet.java +++ b/src/share/classes/java/util/TreeSet.java @@ -195,7 +195,7 @@ public class TreeSet extends AbstractSet * @since 1.6 */ public NavigableSet descendingSet() { - return new TreeSet(m.descendingMap()); + return new TreeSet(m.descendingMap()); } /** @@ -505,8 +505,8 @@ public class TreeSet extends AbstractSet s.writeInt(m.size()); // Write out all elements in the proper order. - for (Iterator i=m.keySet().iterator(); i.hasNext(); ) - s.writeObject(i.next()); + for (E e : m.keySet()) + s.writeObject(e); } /** diff --git a/src/share/classes/java/util/Vector.java b/src/share/classes/java/util/Vector.java index 209371c538dc42d84887d40aefbe0f3c9abb3190..ce5a2982fc210a13ce085973b8b68dca4078c4d9 100644 --- a/src/share/classes/java/util/Vector.java +++ b/src/share/classes/java/util/Vector.java @@ -64,15 +64,15 @@ package java.util; * *

    As of the Java 2 platform v1.2, this class was retrofitted to * implement the {@link List} interface, making it a member of the - * Java - * Collections Framework. Unlike the new collection - * implementations, {@code Vector} is synchronized. + * + * Java Collections Framework. Unlike the new collection + * implementations, {@code Vector} is synchronized. If a thread-safe + * implementation is not needed, it is recommended to use {@link + * ArrayList} in place of {@code Vector}. * * @author Lee Boynton * @author Jonathan Payne * @see Collection - * @see List - * @see ArrayList * @see LinkedList * @since JDK1.0 */ diff --git a/src/share/classes/java/util/WeakHashMap.java b/src/share/classes/java/util/WeakHashMap.java index 861faa9c297c5d658bd0f17347fac3696c482d2f..bdf52c579996125aaa14a4fd129ec19bc8c28ad1 100644 --- a/src/share/classes/java/util/WeakHashMap.java +++ b/src/share/classes/java/util/WeakHashMap.java @@ -29,7 +29,8 @@ import java.lang.ref.ReferenceQueue; /** - * A hashtable-based Map implementation with weak keys. + * Hash table based implementation of the Map interface, with + * weak keys. * An entry in a WeakHashMap will automatically be removed when * its key is no longer in ordinary use. More precisely, the presence of a * mapping for a given key will not prevent the key from being discarded by the @@ -181,7 +182,7 @@ public class WeakHashMap * * @see ConcurrentModificationException */ - volatile int modCount; + int modCount; @SuppressWarnings("unchecked") private Entry[] newTable(int n) { diff --git a/src/share/classes/java/util/concurrent/DelayQueue.java b/src/share/classes/java/util/concurrent/DelayQueue.java index 57350dd1c3cd788d929b2df5039fdd92c92f953c..a815bbc9bbb0127c2e7c3d4895cf4716bec4cdcf 100644 --- a/src/share/classes/java/util/concurrent/DelayQueue.java +++ b/src/share/classes/java/util/concurrent/DelayQueue.java @@ -69,9 +69,33 @@ public class DelayQueue extends AbstractQueue implements BlockingQueue { private transient final ReentrantLock lock = new ReentrantLock(); - private transient final Condition available = lock.newCondition(); private final PriorityQueue q = new PriorityQueue(); + /** + * Thread designated to wait for the element at the head of + * the queue. This variant of the Leader-Follower pattern + * (http://www.cs.wustl.edu/~schmidt/POSA/POSA2/) serves to + * minimize unnecessary timed waiting. When a thread becomes + * the leader, it waits only for the next delay to elapse, but + * other threads await indefinitely. The leader thread must + * signal some other thread before returning from take() or + * poll(...), unless some other thread becomes leader in the + * interim. Whenever the head of the queue is replaced with + * an element with an earlier expiration time, the leader + * field is invalidated by being reset to null, and some + * waiting thread, but not necessarily the current leader, is + * signalled. So waiting threads must be prepared to acquire + * and lose leadership while waiting. + */ + private Thread leader = null; + + /** + * Condition signalled when a newer element becomes available + * at the head of the queue or a new thread may need to + * become leader. + */ + private final Condition available = lock.newCondition(); + /** * Creates a new DelayQueue that is initially empty. */ @@ -111,10 +135,11 @@ public class DelayQueue extends AbstractQueue final ReentrantLock lock = this.lock; lock.lock(); try { - E first = q.peek(); q.offer(e); - if (first == null || e.compareTo(first) < 0) - available.signalAll(); + if (q.peek() == e) { + leader = null; + available.signal(); + } return true; } finally { lock.unlock(); @@ -160,13 +185,8 @@ public class DelayQueue extends AbstractQueue E first = q.peek(); if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0) return null; - else { - E x = q.poll(); - assert x != null; - if (q.size() != 0) - available.signalAll(); - return x; - } + else + return q.poll(); } finally { lock.unlock(); } @@ -185,23 +205,29 @@ public class DelayQueue extends AbstractQueue try { for (;;) { E first = q.peek(); - if (first == null) { + if (first == null) available.await(); - } else { - long delay = first.getDelay(TimeUnit.NANOSECONDS); - if (delay > 0) { - long tl = available.awaitNanos(delay); - } else { - E x = q.poll(); - assert x != null; - if (q.size() != 0) - available.signalAll(); // wake up other takers - return x; - + else { + long delay = first.getDelay(TimeUnit.NANOSECONDS); + if (delay <= 0) + return q.poll(); + else if (leader != null) + available.await(); + else { + Thread thisThread = Thread.currentThread(); + leader = thisThread; + try { + available.awaitNanos(delay); + } finally { + if (leader == thisThread) + leader = null; + } } } } } finally { + if (leader == null && q.peek() != null) + available.signal(); lock.unlock(); } } @@ -230,23 +256,28 @@ public class DelayQueue extends AbstractQueue nanos = available.awaitNanos(nanos); } else { long delay = first.getDelay(TimeUnit.NANOSECONDS); - if (delay > 0) { - if (nanos <= 0) - return null; - if (delay > nanos) - delay = nanos; - long timeLeft = available.awaitNanos(delay); - nanos -= delay - timeLeft; - } else { - E x = q.poll(); - assert x != null; - if (q.size() != 0) - available.signalAll(); - return x; + if (delay <= 0) + return q.poll(); + if (nanos <= 0) + return null; + if (nanos < delay || leader != null) + nanos = available.awaitNanos(nanos); + else { + Thread thisThread = Thread.currentThread(); + leader = thisThread; + try { + long timeLeft = available.awaitNanos(delay); + nanos -= delay - timeLeft; + } finally { + if (leader == thisThread) + leader = null; + } } } } } finally { + if (leader == null && q.peek() != null) + available.signal(); lock.unlock(); } } @@ -303,8 +334,6 @@ public class DelayQueue extends AbstractQueue c.add(q.poll()); ++n; } - if (n > 0) - available.signalAll(); return n; } finally { lock.unlock(); @@ -335,8 +364,6 @@ public class DelayQueue extends AbstractQueue c.add(q.poll()); ++n; } - if (n > 0) - available.signalAll(); return n; } finally { lock.unlock(); @@ -485,6 +512,7 @@ public class DelayQueue extends AbstractQueue return cursor < array.length; } + @SuppressWarnings("unchecked") public E next() { if (cursor >= array.length) throw new NoSuchElementException(); diff --git a/src/share/classes/java/util/concurrent/ExecutorService.java b/src/share/classes/java/util/concurrent/ExecutorService.java index 36b035c33dc524e7f58a7c5ddb2392213e23dc85..6f1f5fa85519643cd16ceef9c8b8eaea37f0972d 100644 --- a/src/share/classes/java/util/concurrent/ExecutorService.java +++ b/src/share/classes/java/util/concurrent/ExecutorService.java @@ -145,6 +145,10 @@ public interface ExecutorService extends Executor { * tasks are executed, but no new tasks will be accepted. * Invocation has no additional effect if already shut down. * + *

    This method does not wait for previously submitted tasks to + * complete execution. Use {@link #awaitTermination awaitTermination} + * to do that. + * * @throws SecurityException if a security manager exists and * shutting down this ExecutorService may manipulate * threads that the caller is not permitted to modify @@ -157,8 +161,12 @@ public interface ExecutorService extends Executor { /** * Attempts to stop all actively executing tasks, halts the - * processing of waiting tasks, and returns a list of the tasks that were - * awaiting execution. + * processing of waiting tasks, and returns a list of the tasks + * that were awaiting execution. + * + *

    This method does not wait for actively executing tasks to + * terminate. Use {@link #awaitTermination awaitTermination} to + * do that. * *

    There are no guarantees beyond best-effort attempts to stop * processing actively executing tasks. For example, typical diff --git a/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java b/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java index f0b1f42f2b174ef3ceeffa8668f22b12d853f81e..dc7fe113f2aa7a59adb6a5114da5d8ac4c86e22c 100644 --- a/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java +++ b/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java @@ -35,6 +35,7 @@ package java.util.concurrent; import java.util.concurrent.atomic.*; +import java.util.concurrent.locks.*; import java.util.*; /** @@ -45,12 +46,21 @@ import java.util.*; * flexibility or capabilities of {@link ThreadPoolExecutor} (which * this class extends) are required. * - *

    Delayed tasks execute no sooner than they are enabled, but + *

    Delayed tasks execute no sooner than they are enabled, but * without any real-time guarantees about when, after they are * enabled, they will commence. Tasks scheduled for exactly the same * execution time are enabled in first-in-first-out (FIFO) order of * submission. * + *

    When a submitted task is cancelled before it is run, execution + * is suppressed. By default, such a cancelled task is not + * automatically removed from the work queue until its delay + * elapses. While this enables further inspection and monitoring, it + * may also cause unbounded retention of cancelled tasks. To avoid + * this, set {@link #setRemoveOnCancelPolicy} to {@code true}, which + * causes tasks to be immediately removed from the work queue at + * time of cancellation. + * *

    While this class inherits from {@link ThreadPoolExecutor}, a few * of the inherited tuning methods are not useful for it. In * particular, because it acts as a fixed-sized pool using @@ -111,21 +121,11 @@ public class ScheduledThreadPoolExecutor * ScheduledExecutorService methods) which are treated as * delayed tasks with a delay of zero. * - * 2. Using a custom queue (DelayedWorkQueue) based on an + * 2. Using a custom queue (DelayedWorkQueue), a variant of * unbounded DelayQueue. The lack of capacity constraint and * the fact that corePoolSize and maximumPoolSize are * effectively identical simplifies some execution mechanics - * (see delayedExecute) compared to ThreadPoolExecutor - * version. - * - * The DelayedWorkQueue class is defined below for the sake of - * ensuring that all elements are instances of - * RunnableScheduledFuture. Since DelayQueue otherwise - * requires type be Delayed, but not necessarily Runnable, and - * the workQueue requires the opposite, we need to explicitly - * define a class that requires both to ensure that users don't - * add objects that aren't RunnableScheduledFutures via - * getQueue().add() etc. + * (see delayedExecute) compared to ThreadPoolExecutor. * * 3. Supporting optional run-after-shutdown parameters, which * leads to overrides of shutdown methods to remove and cancel @@ -149,6 +149,11 @@ public class ScheduledThreadPoolExecutor */ private volatile boolean executeExistingDelayedTasksAfterShutdown = true; + /** + * True if ScheduledFutureTask.cancel should remove from queue + */ + private volatile boolean removeOnCancel = false; + /** * Sequence number to break scheduling ties, and in turn to * guarantee FIFO order among tied entries. @@ -167,8 +172,10 @@ public class ScheduledThreadPoolExecutor /** Sequence number to break ties FIFO */ private final long sequenceNumber; + /** The time the task is enabled to execute in nanoTime units */ private long time; + /** * Period in nanoseconds for repeating tasks. A positive * value indicates fixed-rate execution. A negative value @@ -180,6 +187,11 @@ public class ScheduledThreadPoolExecutor /** The actual task to be re-enqueued by reExecutePeriodic */ RunnableScheduledFuture outerTask = this; + /** + * Index into delay queue, to support faster cancellation. + */ + int heapIndex; + /** * Creates a one-shot action with given nanoTime-based trigger time. */ @@ -255,6 +267,13 @@ public class ScheduledThreadPoolExecutor time = now() - p; } + public boolean cancel(boolean mayInterruptIfRunning) { + boolean cancelled = super.cancel(mayInterruptIfRunning); + if (cancelled && removeOnCancel && heapIndex >= 0) + remove(this); + return cancelled; + } + /** * Overrides FutureTask version so as to reset/requeue if periodic. */ @@ -654,15 +673,48 @@ public class ScheduledThreadPoolExecutor return executeExistingDelayedTasksAfterShutdown; } + /** + * Sets the policy on whether cancelled tasks should be immediately + * removed from the work queue at time of cancellation. This value is + * by default {@code false}. + * + * @param value if {@code true}, remove on cancellation, else don't + * @see #getRemoveOnCancelPolicy + * @since 1.7 + */ + public void setRemoveOnCancelPolicy(boolean value) { + removeOnCancel = value; + } + + /** + * Gets the policy on whether cancelled tasks should be immediately + * removed from the work queue at time of cancellation. This value is + * by default {@code false}. + * + * @return {@code true} if cancelled tasks are immediately removed + * from the queue + * @see #setRemoveOnCancelPolicy + * @since 1.7 + */ + public boolean getRemoveOnCancelPolicy() { + return removeOnCancel; + } + /** * Initiates an orderly shutdown in which previously submitted - * tasks are executed, but no new tasks will be accepted. If the - * {@code ExecuteExistingDelayedTasksAfterShutdownPolicy} has - * been set {@code false}, existing delayed tasks whose delays - * have not yet elapsed are cancelled. And unless the - * {@code ContinueExistingPeriodicTasksAfterShutdownPolicy} has - * been set {@code true}, future executions of existing periodic - * tasks will be cancelled. + * tasks are executed, but no new tasks will be accepted. + * Invocation has no additional effect if already shut down. + * + *

    This method does not wait for previously submitted tasks to + * complete execution. Use {@link #awaitTermination awaitTermination} + * to do that. + * + *

    If the {@code ExecuteExistingDelayedTasksAfterShutdownPolicy} + * has been set {@code false}, existing delayed tasks whose delays + * have not yet elapsed are cancelled. And unless the {@code + * ContinueExistingPeriodicTasksAfterShutdownPolicy} has been set + * {@code true}, future executions of existing periodic tasks will + * be cancelled. * * @throws SecurityException {@inheritDoc} */ @@ -675,6 +727,10 @@ public class ScheduledThreadPoolExecutor * processing of waiting tasks, and returns a list of the tasks * that were awaiting execution. * + *

    This method does not wait for actively executing tasks to + * terminate. Use {@link #awaitTermination awaitTermination} to + * do that. + * *

    There are no guarantees beyond best-effort attempts to stop * processing actively executing tasks. This implementation * cancels tasks via {@link Thread#interrupt}, so any task that @@ -707,56 +763,478 @@ public class ScheduledThreadPoolExecutor } /** - * An annoying wrapper class to convince javac to use a - * DelayQueue as a BlockingQueue + * Specialized delay queue. To mesh with TPE declarations, this + * class must be declared as a BlockingQueue even though + * it can only hold RunnableScheduledFutures. */ - private static class DelayedWorkQueue - extends AbstractCollection + static class DelayedWorkQueue extends AbstractQueue implements BlockingQueue { - private final DelayQueue dq = new DelayQueue(); - public Runnable poll() { return dq.poll(); } - public Runnable peek() { return dq.peek(); } - public Runnable take() throws InterruptedException { return dq.take(); } - public Runnable poll(long timeout, TimeUnit unit) throws InterruptedException { - return dq.poll(timeout, unit); + /* + * A DelayedWorkQueue is based on a heap-based data structure + * like those in DelayQueue and PriorityQueue, except that + * every ScheduledFutureTask also records its index into the + * heap array. This eliminates the need to find a task upon + * cancellation, greatly speeding up removal (down from O(n) + * to O(log n)), and reducing garbage retention that would + * otherwise occur by waiting for the element to rise to top + * before clearing. But because the queue may also hold + * RunnableScheduledFutures that are not ScheduledFutureTasks, + * we are not guaranteed to have such indices available, in + * which case we fall back to linear search. (We expect that + * most tasks will not be decorated, and that the faster cases + * will be much more common.) + * + * All heap operations must record index changes -- mainly + * within siftUp and siftDown. Upon removal, a task's + * heapIndex is set to -1. Note that ScheduledFutureTasks can + * appear at most once in the queue (this need not be true for + * other kinds of tasks or work queues), so are uniquely + * identified by heapIndex. + */ + + private static final int INITIAL_CAPACITY = 16; + private RunnableScheduledFuture[] queue = + new RunnableScheduledFuture[INITIAL_CAPACITY]; + private final ReentrantLock lock = new ReentrantLock(); + private int size = 0; + + /** + * Thread designated to wait for the task at the head of the + * queue. This variant of the Leader-Follower pattern + * (http://www.cs.wustl.edu/~schmidt/POSA/POSA2/) serves to + * minimize unnecessary timed waiting. When a thread becomes + * the leader, it waits only for the next delay to elapse, but + * other threads await indefinitely. The leader thread must + * signal some other thread before returning from take() or + * poll(...), unless some other thread becomes leader in the + * interim. Whenever the head of the queue is replaced with a + * task with an earlier expiration time, the leader field is + * invalidated by being reset to null, and some waiting + * thread, but not necessarily the current leader, is + * signalled. So waiting threads must be prepared to acquire + * and lose leadership while waiting. + */ + private Thread leader = null; + + /** + * Condition signalled when a newer task becomes available at the + * head of the queue or a new thread may need to become leader. + */ + private final Condition available = lock.newCondition(); + + /** + * Set f's heapIndex if it is a ScheduledFutureTask. + */ + private void setIndex(RunnableScheduledFuture f, int idx) { + if (f instanceof ScheduledFutureTask) + ((ScheduledFutureTask)f).heapIndex = idx; } - public boolean add(Runnable x) { - return dq.add((RunnableScheduledFuture)x); + /** + * Sift element added at bottom up to its heap-ordered spot. + * Call only when holding lock. + */ + private void siftUp(int k, RunnableScheduledFuture key) { + while (k > 0) { + int parent = (k - 1) >>> 1; + RunnableScheduledFuture e = queue[parent]; + if (key.compareTo(e) >= 0) + break; + queue[k] = e; + setIndex(e, k); + k = parent; + } + queue[k] = key; + setIndex(key, k); } + + /** + * Sift element added at top down to its heap-ordered spot. + * Call only when holding lock. + */ + private void siftDown(int k, RunnableScheduledFuture key) { + int half = size >>> 1; + while (k < half) { + int child = (k << 1) + 1; + RunnableScheduledFuture c = queue[child]; + int right = child + 1; + if (right < size && c.compareTo(queue[right]) > 0) + c = queue[child = right]; + if (key.compareTo(c) <= 0) + break; + queue[k] = c; + setIndex(c, k); + k = child; + } + queue[k] = key; + setIndex(key, k); + } + + /** + * Resize the heap array. Call only when holding lock. + */ + private void grow() { + int oldCapacity = queue.length; + int newCapacity = oldCapacity + (oldCapacity >> 1); // grow 50% + if (newCapacity < 0) // overflow + newCapacity = Integer.MAX_VALUE; + queue = Arrays.copyOf(queue, newCapacity); + } + + /** + * Find index of given object, or -1 if absent + */ + private int indexOf(Object x) { + if (x != null) { + if (x instanceof ScheduledFutureTask) { + int i = ((ScheduledFutureTask) x).heapIndex; + // Sanity check; x could conceivably be a + // ScheduledFutureTask from some other pool. + if (i >= 0 && i < size && queue[i] == x) + return i; + } else { + for (int i = 0; i < size; i++) + if (x.equals(queue[i])) + return i; + } + } + return -1; + } + + public boolean contains(Object x) { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return indexOf(x) != -1; + } finally { + lock.unlock(); + } + } + + public boolean remove(Object x) { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + int i = indexOf(x); + if (i < 0) + return false; + + setIndex(queue[i], -1); + int s = --size; + RunnableScheduledFuture replacement = queue[s]; + queue[s] = null; + if (s != i) { + siftDown(i, replacement); + if (queue[i] == replacement) + siftUp(i, replacement); + } + return true; + } finally { + lock.unlock(); + } + } + + public int size() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return size; + } finally { + lock.unlock(); + } + } + + public boolean isEmpty() { + return size() == 0; + } + + public int remainingCapacity() { + return Integer.MAX_VALUE; + } + + public RunnableScheduledFuture peek() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return queue[0]; + } finally { + lock.unlock(); + } + } + public boolean offer(Runnable x) { - return dq.offer((RunnableScheduledFuture)x); + if (x == null) + throw new NullPointerException(); + RunnableScheduledFuture e = (RunnableScheduledFuture)x; + final ReentrantLock lock = this.lock; + lock.lock(); + try { + int i = size; + if (i >= queue.length) + grow(); + size = i + 1; + if (i == 0) { + queue[0] = e; + setIndex(e, 0); + } else { + siftUp(i, e); + } + if (queue[0] == e) { + leader = null; + available.signal(); + } + } finally { + lock.unlock(); + } + return true; + } + + public void put(Runnable e) { + offer(e); + } + + public boolean add(Runnable e) { + return offer(e); + } + + public boolean offer(Runnable e, long timeout, TimeUnit unit) { + return offer(e); + } + + /** + * Performs common bookkeeping for poll and take: Replaces + * first element with last and sifts it down. Call only when + * holding lock. + * @param f the task to remove and return + */ + private RunnableScheduledFuture finishPoll(RunnableScheduledFuture f) { + int s = --size; + RunnableScheduledFuture x = queue[s]; + queue[s] = null; + if (s != 0) + siftDown(0, x); + setIndex(f, -1); + return f; + } + + public RunnableScheduledFuture poll() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + RunnableScheduledFuture first = queue[0]; + if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0) + return null; + else + return finishPoll(first); + } finally { + lock.unlock(); + } + } + + public RunnableScheduledFuture take() throws InterruptedException { + final ReentrantLock lock = this.lock; + lock.lockInterruptibly(); + try { + for (;;) { + RunnableScheduledFuture first = queue[0]; + if (first == null) + available.await(); + else { + long delay = first.getDelay(TimeUnit.NANOSECONDS); + if (delay <= 0) + return finishPoll(first); + else if (leader != null) + available.await(); + else { + Thread thisThread = Thread.currentThread(); + leader = thisThread; + try { + available.awaitNanos(delay); + } finally { + if (leader == thisThread) + leader = null; + } + } + } + } + } finally { + if (leader == null && queue[0] != null) + available.signal(); + lock.unlock(); + } + } + + public RunnableScheduledFuture poll(long timeout, TimeUnit unit) + throws InterruptedException { + long nanos = unit.toNanos(timeout); + final ReentrantLock lock = this.lock; + lock.lockInterruptibly(); + try { + for (;;) { + RunnableScheduledFuture first = queue[0]; + if (first == null) { + if (nanos <= 0) + return null; + else + nanos = available.awaitNanos(nanos); + } else { + long delay = first.getDelay(TimeUnit.NANOSECONDS); + if (delay <= 0) + return finishPoll(first); + if (nanos <= 0) + return null; + if (nanos < delay || leader != null) + nanos = available.awaitNanos(nanos); + else { + Thread thisThread = Thread.currentThread(); + leader = thisThread; + try { + long timeLeft = available.awaitNanos(delay); + nanos -= delay - timeLeft; + } finally { + if (leader == thisThread) + leader = null; + } + } + } + } + } finally { + if (leader == null && queue[0] != null) + available.signal(); + lock.unlock(); + } } - public void put(Runnable x) { - dq.put((RunnableScheduledFuture)x); + + public void clear() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + for (int i = 0; i < size; i++) { + RunnableScheduledFuture t = queue[i]; + if (t != null) { + queue[i] = null; + setIndex(t, -1); + } + } + size = 0; + } finally { + lock.unlock(); + } } - public boolean offer(Runnable x, long timeout, TimeUnit unit) { - return dq.offer((RunnableScheduledFuture)x, timeout, unit); + + /** + * Return and remove first element only if it is expired. + * Used only by drainTo. Call only when holding lock. + */ + private RunnableScheduledFuture pollExpired() { + RunnableScheduledFuture first = queue[0]; + if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0) + return null; + return finishPoll(first); + } + + public int drainTo(Collection c) { + if (c == null) + throw new NullPointerException(); + if (c == this) + throw new IllegalArgumentException(); + final ReentrantLock lock = this.lock; + lock.lock(); + try { + RunnableScheduledFuture first; + int n = 0; + while ((first = pollExpired()) != null) { + c.add(first); + ++n; + } + return n; + } finally { + lock.unlock(); + } } - public Runnable remove() { return dq.remove(); } - public Runnable element() { return dq.element(); } - public void clear() { dq.clear(); } - public int drainTo(Collection c) { return dq.drainTo(c); } public int drainTo(Collection c, int maxElements) { - return dq.drainTo(c, maxElements); + if (c == null) + throw new NullPointerException(); + if (c == this) + throw new IllegalArgumentException(); + if (maxElements <= 0) + return 0; + final ReentrantLock lock = this.lock; + lock.lock(); + try { + RunnableScheduledFuture first; + int n = 0; + while (n < maxElements && (first = pollExpired()) != null) { + c.add(first); + ++n; + } + return n; + } finally { + lock.unlock(); + } + } + + public Object[] toArray() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return Arrays.copyOf(queue, size, Object[].class); + } finally { + lock.unlock(); + } + } + + @SuppressWarnings("unchecked") + public T[] toArray(T[] a) { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + if (a.length < size) + return (T[]) Arrays.copyOf(queue, size, a.getClass()); + System.arraycopy(queue, 0, a, 0, size); + if (a.length > size) + a[size] = null; + return a; + } finally { + lock.unlock(); + } } - public int remainingCapacity() { return dq.remainingCapacity(); } - public boolean remove(Object x) { return dq.remove(x); } - public boolean contains(Object x) { return dq.contains(x); } - public int size() { return dq.size(); } - public boolean isEmpty() { return dq.isEmpty(); } - public Object[] toArray() { return dq.toArray(); } - public T[] toArray(T[] array) { return dq.toArray(array); } public Iterator iterator() { - return new Iterator() { - private Iterator it = dq.iterator(); - public boolean hasNext() { return it.hasNext(); } - public Runnable next() { return it.next(); } - public void remove() { it.remove(); } - }; + return new Itr(Arrays.copyOf(queue, size)); + } + + /** + * Snapshot iterator that works off copy of underlying q array. + */ + private class Itr implements Iterator { + final RunnableScheduledFuture[] array; + int cursor = 0; // index of next element to return + int lastRet = -1; // index of last element, or -1 if no such + + Itr(RunnableScheduledFuture[] array) { + this.array = array; + } + + public boolean hasNext() { + return cursor < array.length; + } + + public Runnable next() { + if (cursor >= array.length) + throw new NoSuchElementException(); + lastRet = cursor; + return array[cursor++]; + } + + public void remove() { + if (lastRet < 0) + throw new IllegalStateException(); + DelayedWorkQueue.this.remove(array[lastRet]); + lastRet = -1; + } } } } diff --git a/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java b/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java index 150ceca17477a7c36373809a7bb602ed10dc4ae7..7ea1d5ab4ba690715a596beda331f41db4fdc953 100644 --- a/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java +++ b/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java @@ -1342,6 +1342,10 @@ public class ThreadPoolExecutor extends AbstractExecutorService { * tasks are executed, but no new tasks will be accepted. * Invocation has no additional effect if already shut down. * + *

    This method does not wait for previously submitted tasks to + * complete execution. Use {@link #awaitTermination awaitTermination} + * to do that. + * * @throws SecurityException {@inheritDoc} */ public void shutdown() { @@ -1364,6 +1368,10 @@ public class ThreadPoolExecutor extends AbstractExecutorService { * that were awaiting execution. These tasks are drained (removed) * from the task queue upon return from this method. * + *

    This method does not wait for actively executing tasks to + * terminate. Use {@link #awaitTermination awaitTermination} to + * do that. + * *

    There are no guarantees beyond best-effort attempts to stop * processing actively executing tasks. This implementation * cancels tasks via {@link Thread#interrupt}, so any task that diff --git a/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java b/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java index c9280c851270c7b2a5d5603788376fed81c7b7e6..8888efb2477a57994432cdb724ba0969333a567f 100644 --- a/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java +++ b/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java @@ -222,7 +222,7 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab /** Inner class providing writelock */ private final ReentrantReadWriteLock.WriteLock writerLock; /** Performs all synchronization mechanics */ - private final Sync sync; + final Sync sync; /** * Creates a new {@code ReentrantReadWriteLock} with @@ -239,7 +239,7 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab * @param fair {@code true} if this lock should use a fair ordering policy */ public ReentrantReadWriteLock(boolean fair) { - sync = (fair)? new FairSync() : new NonfairSync(); + sync = fair ? new FairSync() : new NonfairSync(); readerLock = new ReadLock(this); writerLock = new WriteLock(this); } @@ -256,8 +256,8 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab /* * Read vs write count extraction constants and functions. - * Lock state is logically divided into two shorts: The lower - * one representing the exclusive (writer) lock hold count, + * Lock state is logically divided into two unsigned shorts: + * The lower one representing the exclusive (writer) lock hold count, * and the upper the shared (reader) hold count. */ @@ -279,13 +279,6 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab int count; // Use id, not reference, to avoid garbage retention final long tid = Thread.currentThread().getId(); - /** Decrement if positive; return previous value */ - int tryDecrement() { - int c = count; - if (c > 0) - count = c - 1; - return c; - } } /** @@ -303,7 +296,7 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab * The number of read locks held by current thread. * Initialized only in constructor and readObject. */ - transient ThreadLocalHoldCounter readHolds; + private transient ThreadLocalHoldCounter readHolds; /** * The hold count of the last thread to successfully acquire @@ -312,7 +305,17 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab * acquire. This is non-volatile since it is just used * as a heuristic, and would be great for threads to cache. */ - transient HoldCounter cachedHoldCounter; + private transient HoldCounter cachedHoldCounter; + + /** + * firstReader is the first thread to have acquired the read lock. + * firstReaderHoldCount is firstReader's hold count. + * This allows tracking of read holds for uncontended read + * locks to be very cheap. + */ + private final static long INVALID_THREAD_ID = -1; + private transient long firstReader = INVALID_THREAD_ID; + private transient int firstReaderHoldCount; Sync() { readHolds = new ThreadLocalHoldCounter(); @@ -390,12 +393,25 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab } protected final boolean tryReleaseShared(int unused) { - HoldCounter rh = cachedHoldCounter; - Thread current = Thread.currentThread(); - if (rh == null || rh.tid != current.getId()) - rh = readHolds.get(); - if (rh.tryDecrement() <= 0) - throw new IllegalMonitorStateException(); + long tid = Thread.currentThread().getId(); + if (firstReader == tid) { + // assert firstReaderHoldCount > 0; + if (firstReaderHoldCount == 1) + firstReader = INVALID_THREAD_ID; + else + firstReaderHoldCount--; + } else { + HoldCounter rh = cachedHoldCounter; + if (rh == null || rh.tid != tid) + rh = readHolds.get(); + int count = rh.count; + if (count <= 1) { + readHolds.remove(); + if (count <= 0) + throw unmatchedUnlockException(); + } + --rh.count; + } for (;;) { int c = getState(); int nextc = c - SHARED_UNIT; @@ -404,12 +420,16 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab } } + private IllegalMonitorStateException unmatchedUnlockException() { + return new IllegalMonitorStateException( + "attempt to unlock read lock, not locked by current thread"); + } + protected final int tryAcquireShared(int unused) { /* * Walkthrough: * 1. If write lock held by another thread, fail. - * 2. If count saturated, throw error. - * 3. Otherwise, this thread is eligible for + * 2. Otherwise, this thread is eligible for * lock wrt state, so ask if it should block * because of queue policy. If not, try * to grant by CASing state and updating count. @@ -417,23 +437,33 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab * acquires, which is postponed to full version * to avoid having to check hold count in * the more typical non-reentrant case. - * 4. If step 3 fails either because thread - * apparently not eligible or CAS fails, - * chain to version with full retry loop. + * 3. If step 2 fails either because thread + * apparently not eligible or CAS fails or count + * saturated, chain to version with full retry loop. */ Thread current = Thread.currentThread(); int c = getState(); if (exclusiveCount(c) != 0 && getExclusiveOwnerThread() != current) return -1; - if (sharedCount(c) == MAX_COUNT) - throw new Error("Maximum lock count exceeded"); + int r = sharedCount(c); if (!readerShouldBlock() && + r < MAX_COUNT && compareAndSetState(c, c + SHARED_UNIT)) { - HoldCounter rh = cachedHoldCounter; - if (rh == null || rh.tid != current.getId()) - cachedHoldCounter = rh = readHolds.get(); - rh.count++; + long tid = current.getId(); + if (r == 0) { + firstReader = tid; + firstReaderHoldCount = 1; + } else if (firstReader == tid) { + firstReaderHoldCount++; + } else { + HoldCounter rh = cachedHoldCounter; + if (rh == null || rh.tid != tid) + cachedHoldCounter = rh = readHolds.get(); + else if (rh.count == 0) + readHolds.set(rh); + rh.count++; + } return 1; } return fullTryAcquireShared(current); @@ -450,20 +480,56 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab * complicating tryAcquireShared with interactions between * retries and lazily reading hold counts. */ - HoldCounter rh = cachedHoldCounter; - if (rh == null || rh.tid != current.getId()) - rh = readHolds.get(); + HoldCounter rh = null; for (;;) { int c = getState(); - int w = exclusiveCount(c); - if ((w != 0 && getExclusiveOwnerThread() != current) || - ((rh.count | w) == 0 && readerShouldBlock())) - return -1; + if (exclusiveCount(c) != 0) { + if (getExclusiveOwnerThread() != current) + //if (removeNeeded) readHolds.remove(); + return -1; + // else we hold the exclusive lock; blocking here + // would cause deadlock. + } else if (readerShouldBlock()) { + // Make sure we're not acquiring read lock reentrantly + long tid = current.getId(); + if (firstReader == tid) { + // assert firstReaderHoldCount > 0; + } else { + if (rh == null) { + rh = cachedHoldCounter; + if (rh == null || rh.tid != tid) { + rh = readHolds.get(); + if (rh.count == 0) + readHolds.remove(); + } + } + if (rh.count == 0) + return -1; + } + } if (sharedCount(c) == MAX_COUNT) throw new Error("Maximum lock count exceeded"); if (compareAndSetState(c, c + SHARED_UNIT)) { - cachedHoldCounter = rh; // cache for release - rh.count++; + long tid = current.getId(); + if (sharedCount(c) == 0) { + firstReader = tid; + firstReaderHoldCount = 1; + } else if (firstReader == tid) { + firstReaderHoldCount++; + } else { + if (rh == null) { + rh = cachedHoldCounter; + if (rh != null && rh.tid == tid) { + if (rh.count == 0) + readHolds.set(rh); + } else { + rh = readHolds.get(); + } + } else if (rh.count == 0) + readHolds.set(rh); + cachedHoldCounter = rh; // cache for release + rh.count++; + } return 1; } } @@ -472,14 +538,14 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab /** * Performs tryLock for write, enabling barging in both modes. * This is identical in effect to tryAcquire except for lack - * of calls to writerShouldBlock + * of calls to writerShouldBlock. */ final boolean tryWriteLock() { Thread current = Thread.currentThread(); int c = getState(); if (c != 0) { int w = exclusiveCount(c); - if (w == 0 ||current != getExclusiveOwnerThread()) + if (w == 0 || current != getExclusiveOwnerThread()) return false; if (w == MAX_COUNT) throw new Error("Maximum lock count exceeded"); @@ -493,7 +559,7 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab /** * Performs tryLock for read, enabling barging in both modes. * This is identical in effect to tryAcquireShared except for - * lack of calls to readerShouldBlock + * lack of calls to readerShouldBlock. */ final boolean tryReadLock() { Thread current = Thread.currentThread(); @@ -502,13 +568,24 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab if (exclusiveCount(c) != 0 && getExclusiveOwnerThread() != current) return false; - if (sharedCount(c) == MAX_COUNT) + int r = sharedCount(c); + if (r == MAX_COUNT) throw new Error("Maximum lock count exceeded"); if (compareAndSetState(c, c + SHARED_UNIT)) { - HoldCounter rh = cachedHoldCounter; - if (rh == null || rh.tid != current.getId()) - cachedHoldCounter = rh = readHolds.get(); - rh.count++; + long tid = current.getId(); + if (r == 0) { + firstReader = tid; + firstReaderHoldCount = 1; + } else if (firstReader == tid) { + firstReaderHoldCount++; + } else { + HoldCounter rh = cachedHoldCounter; + if (rh == null || rh.tid != tid) + cachedHoldCounter = rh = readHolds.get(); + else if (rh.count == 0) + readHolds.set(rh); + rh.count++; + } return true; } } @@ -546,7 +623,20 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab } final int getReadHoldCount() { - return getReadLockCount() == 0? 0 : readHolds.get().count; + if (getReadLockCount() == 0) + return 0; + + long tid = Thread.currentThread().getId(); + if (firstReader == tid) + return firstReaderHoldCount; + + HoldCounter rh = cachedHoldCounter; + if (rh != null && rh.tid == tid) + return rh.count; + + int count = readHolds.get().count; + if (count == 0) readHolds.remove(); + return count; } /** @@ -557,6 +647,7 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab throws java.io.IOException, ClassNotFoundException { s.defaultReadObject(); readHolds = new ThreadLocalHoldCounter(); + firstReader = INVALID_THREAD_ID; setState(0); // reset to unlocked state } diff --git a/src/share/classes/java/util/prefs/AbstractPreferences.java b/src/share/classes/java/util/prefs/AbstractPreferences.java index 029133714ea0acfc12d1f091b9665965406da317..ebf975ccfd89e6ae88ebcf21d8f8b2c58106e7d4 100644 --- a/src/share/classes/java/util/prefs/AbstractPreferences.java +++ b/src/share/classes/java/util/prefs/AbstractPreferences.java @@ -155,7 +155,8 @@ public abstract class AbstractPreferences extends Preferences { * All known unremoved children of this node. (This "cache" is consulted * prior to calling childSpi() or getChild(). */ - private Map kidCache = new HashMap(); + private Map kidCache + = new HashMap(); /** * This field is used to keep track of whether or not this node has @@ -712,11 +713,10 @@ public abstract class AbstractPreferences extends Preferences { if (removed) throw new IllegalStateException("Node has been removed."); - Set s = new TreeSet(kidCache.keySet()); - String[] kids = childrenNamesSpi(); - for(int i=0; i s = new TreeSet(kidCache.keySet()); + for (String kid : childrenNamesSpi()) + s.add(kid); + return s.toArray(EMPTY_STRING_ARRAY); } } @@ -728,8 +728,7 @@ public abstract class AbstractPreferences extends Preferences { * @return all known unremoved children of this node. */ protected final AbstractPreferences[] cachedChildren() { - return (AbstractPreferences[]) kidCache.values(). - toArray(EMPTY_ABSTRACT_PREFS_ARRAY); + return kidCache.values().toArray(EMPTY_ABSTRACT_PREFS_ARRAY); } private static final AbstractPreferences[] EMPTY_ABSTRACT_PREFS_ARRAY @@ -825,7 +824,7 @@ public abstract class AbstractPreferences extends Preferences { if (token.equals("/")) // Check for consecutive slashes throw new IllegalArgumentException("Consecutive slashes in path"); synchronized(lock) { - AbstractPreferences child=(AbstractPreferences)kidCache.get(token); + AbstractPreferences child = kidCache.get(token); if (child == null) { if (token.length() > MAX_NAME_LENGTH) throw new IllegalArgumentException( @@ -893,7 +892,7 @@ public abstract class AbstractPreferences extends Preferences { if (token.equals("/")) // Check for consecutive slashes throw new IllegalArgumentException("Consecutive slashes in path"); synchronized(lock) { - AbstractPreferences child=(AbstractPreferences)kidCache.get(token); + AbstractPreferences child = kidCache.get(token); if (child == null) child = getChild(token); if (child==null) @@ -964,9 +963,10 @@ public abstract class AbstractPreferences extends Preferences { kidCache.put(kidNames[i], childSpi(kidNames[i])); // Recursively remove all cached children - for (Iterator i = kidCache.values().iterator(); i.hasNext();) { + for (Iterator i = kidCache.values().iterator(); + i.hasNext();) { try { - ((AbstractPreferences)i.next()).removeNode2(); + i.next().removeNode2(); i.remove(); } catch (BackingStoreException x) { } } @@ -1020,13 +1020,12 @@ public abstract class AbstractPreferences extends Preferences { * preference tree. */ public boolean isUserNode() { - Boolean result = (Boolean) - AccessController.doPrivileged( new PrivilegedAction() { - public Object run() { - return Boolean.valueOf(root == Preferences.userRoot()); + return AccessController.doPrivileged( + new PrivilegedAction() { + public Boolean run() { + return root == Preferences.userRoot(); } - }); - return result.booleanValue(); + }).booleanValue(); } public void addPreferenceChangeListener(PreferenceChangeListener pcl) { @@ -1443,7 +1442,8 @@ public abstract class AbstractPreferences extends Preferences { * event delivery from preference activity, greatly simplifying * locking and reducing opportunity for deadlock. */ - private static final List eventQueue = new LinkedList(); + private static final List eventQueue + = new LinkedList(); /** * These two classes are used to distinguish NodeChangeEvents on @@ -1476,7 +1476,7 @@ public abstract class AbstractPreferences extends Preferences { try { while (eventQueue.isEmpty()) eventQueue.wait(); - event = (EventObject) eventQueue.remove(0); + event = eventQueue.remove(0); } catch (InterruptedException e) { // XXX Log "Event dispatch thread interrupted. Exiting" return; diff --git a/src/share/classes/java/util/prefs/Preferences.java b/src/share/classes/java/util/prefs/Preferences.java index 1c25cfdbc13273b3bd21870b2f09fd924100c5f6..1aad5d9f0ef9fb529960b72bf9723035e507aa06 100644 --- a/src/share/classes/java/util/prefs/Preferences.java +++ b/src/share/classes/java/util/prefs/Preferences.java @@ -32,9 +32,8 @@ import java.security.AccessController; import java.security.Permission; import java.security.PrivilegedAction; import java.util.Iterator; -import sun.misc.Service; -import sun.misc.ServiceConfigurationError; - +import java.util.ServiceLoader; +import java.util.ServiceConfigurationError; // These imports needed only as a workaround for a JavaDoc bug import java.lang.RuntimePermission; @@ -274,12 +273,14 @@ public abstract class Preferences { private static PreferencesFactory factory1() { // 2. Try service provider interface - Iterator i = Service.providers(PreferencesFactory.class, - ClassLoader.getSystemClassLoader()); + Iterator itr = ServiceLoader + .load(PreferencesFactory.class, ClassLoader.getSystemClassLoader()) + .iterator(); + // choose first provider instance - while (i.hasNext()) { + while (itr.hasNext()) { try { - return (PreferencesFactory) i.next(); + return itr.next(); } catch (ServiceConfigurationError sce) { if (sce.getCause() instanceof SecurityException) { // Ignore the security exception, try the next provider diff --git a/src/share/classes/java/util/regex/Matcher.java b/src/share/classes/java/util/regex/Matcher.java index 5dc6caa19d2f2c422e0edf7dfe6cfe2c84bc1c0f..60dabaa279aa13fe49400f90d9dd78a570884e2f 100644 --- a/src/share/classes/java/util/regex/Matcher.java +++ b/src/share/classes/java/util/regex/Matcher.java @@ -249,7 +249,7 @@ public final class Matcher implements MatchResult { Matcher result = new Matcher(this.parentPattern, text.toString()); result.first = this.first; result.last = this.last; - result.groups = (int[])(this.groups.clone()); + result.groups = this.groups.clone(); return result; } diff --git a/src/share/classes/javax/management/AndQueryExp.java b/src/share/classes/javax/management/AndQueryExp.java index 6f61f503f1e19a1a443fe5cad113d04410bd13b5..9571c06779e7b47a4d4d372c00cb8126c76c4656 100644 --- a/src/share/classes/javax/management/AndQueryExp.java +++ b/src/share/classes/javax/management/AndQueryExp.java @@ -104,4 +104,25 @@ class AndQueryExp extends QueryEval implements QueryExp { return "(" + exp1 + ") and (" + exp2 + ")"; } - } + @Override + String toQueryString() { + // Parentheses are only added if needed to disambiguate. + return parens(exp1) + " and " + parens(exp2); + } + + // Add parens if needed to disambiguate an expression such as + // Query.and(Query.or(a, b), c). We need to return + // (a or b) and c + // in such a case, because + // a or b and c + // would mean + // a or (b and c) + private static String parens(QueryExp exp) { + String s = Query.toString(exp); + if (exp instanceof OrQueryExp) + return "(" + s + ")"; + else + return s; + } + +} diff --git a/src/share/classes/javax/management/AttributeValueExp.java b/src/share/classes/javax/management/AttributeValueExp.java index f520bbaf06ccaf39c66a01309c409df27bc0a1d5..d986aba72184d2e9bbbea910d4933ab797082eb5 100644 --- a/src/share/classes/javax/management/AttributeValueExp.java +++ b/src/share/classes/javax/management/AttributeValueExp.java @@ -26,12 +26,17 @@ package javax.management; -// RI import -import javax.management.MBeanServer; +import com.sun.jmx.mbeanserver.Introspector; +import java.io.IOException; +import java.io.ObjectInputStream; /** - * Represents attributes used as arguments to relational constraints. - * An AttributeValueExp may be used anywhere a ValueExp is required. + *

    Represents attributes used as arguments to relational constraints. + * Instances of this class are usually obtained using {@link Query#attr(String) + * Query.attr}.

    + * + *

    An AttributeValueExp may be used anywhere a + * ValueExp is required. * * @since 1.5 */ @@ -46,6 +51,8 @@ public class AttributeValueExp implements ValueExp { */ private String attr; + private transient int dotIndex; + /** * An AttributeValueExp with a null attribute. * @deprecated An instance created with this constructor cannot be @@ -64,6 +71,18 @@ public class AttributeValueExp implements ValueExp { */ public AttributeValueExp(String attr) { this.attr = attr; + setDotIndex(); + } + + private void setDotIndex() { + if (attr != null) + dotIndex = attr.indexOf('.'); + } + + private void readObject(ObjectInputStream in) + throws ClassNotFoundException, IOException { + in.defaultReadObject(); + setDotIndex(); } /** @@ -76,7 +95,13 @@ public class AttributeValueExp implements ValueExp { } /** - * Applies the AttributeValueExp on an MBean. + *

    Applies the AttributeValueExp on an MBean. + * This method calls {@link #getAttribute getAttribute(name)} and wraps + * the result as a {@code ValueExp}. The value returned by + * {@code getAttribute} must be a {@code Number}, {@code String}, + * or {@code Boolean}; otherwise this method throws a + * {@code BadAttributeValueExpException}, which will cause + * the containing query to be false for this {@code name}.

    * * @param name The name of the MBean on which the AttributeValueExp will be applied. * @@ -88,6 +113,7 @@ public class AttributeValueExp implements ValueExp { * @exception BadBinaryOpValueExpException * */ + @Override public ValueExp apply(ObjectName name) throws BadStringOperationException, BadBinaryOpValueExpException, BadAttributeValueExpException, InvalidApplicationException { Object result = getAttribute(name); @@ -106,8 +132,9 @@ public class AttributeValueExp implements ValueExp { /** * Returns the string representing its value. */ + @Override public String toString() { - return attr; + return QueryParser.quoteId(attr); } @@ -115,18 +142,38 @@ public class AttributeValueExp implements ValueExp { * Sets the MBean server on which the query is to be performed. * * @param s The MBean server on which the query is to be performed. + * + * @deprecated This method has no effect. The MBean Server used to + * obtain an attribute value is {@link QueryEval#getMBeanServer()}. */ /* There is no need for this method, because if a query is being evaluted an AttributeValueExp can only appear inside a QueryExp, and that QueryExp will itself have done setMBeanServer. */ + @Deprecated + @Override public void setMBeanServer(MBeanServer s) { } /** - * Return the value of the given attribute in the named MBean. + *

    Return the value of the given attribute in the named MBean. * If the attempt to access the attribute generates an exception, - * return null. + * return null.

    + * + *

    Let n be the {@linkplain #getAttributeName attribute + * name}. Then this method proceeds as follows. First it calls + * {@link MBeanServer#getAttribute getAttribute(name, n)}. If that + * generates an {@link AttributeNotFoundException}, and if n + * contains at least one dot ({@code .}), then the method calls {@code + * getAttribute(name, }n{@code .substring(0, }n{@code + * .indexOf('.')))}; in other words it calls {@code getAttribute} + * with the substring of n before the first dot. Then it + * extracts a component from the retrieved value, as described in the documentation for the {@code + * monitor} package.

    + * + *

    The MBean Server used is the one returned by {@link + * QueryEval#getMBeanServer()}.

    * * @param name the name of the MBean whose attribute is to be returned. * @@ -139,10 +186,34 @@ public class AttributeValueExp implements ValueExp { MBeanServer server = QueryEval.getMBeanServer(); + try { return server.getAttribute(name, attr); + } catch (AttributeNotFoundException e) { + if (dotIndex < 0) + throw e; + } + + String toGet = attr.substring(0, dotIndex); + + Object value = server.getAttribute(name, toGet); + + return extractElement(value, attr.substring(dotIndex + 1)); } catch (Exception re) { return null; } } + private Object extractElement(Object value, String elementWithDots) + throws AttributeNotFoundException { + while (true) { + int dot = elementWithDots.indexOf('.'); + String element = (dot < 0) ? + elementWithDots : elementWithDots.substring(0, dot); + value = Introspector.elementFromComplex(value, element); + if (dot < 0) + return value; + elementWithDots = elementWithDots.substring(dot + 1); + } + } + } diff --git a/src/share/classes/javax/management/BetweenQueryExp.java b/src/share/classes/javax/management/BetweenQueryExp.java index 247c6b4bab7b6821444c2ad5a167e5a4d9daa246..4079f6379618141f2cbaf81073803babdd8c717c 100644 --- a/src/share/classes/javax/management/BetweenQueryExp.java +++ b/src/share/classes/javax/management/BetweenQueryExp.java @@ -109,34 +109,25 @@ class BetweenQueryExp extends QueryEval implements QueryExp { ValueExp val1 = exp1.apply(name); ValueExp val2 = exp2.apply(name); ValueExp val3 = exp3.apply(name); - String sval1; - String sval2; - String sval3; - double dval1; - double dval2; - double dval3; - long lval1; - long lval2; - long lval3; boolean numeric = val1 instanceof NumericValueExp; if (numeric) { if (((NumericValueExp)val1).isLong()) { - lval1 = ((NumericValueExp)val1).longValue(); - lval2 = ((NumericValueExp)val2).longValue(); - lval3 = ((NumericValueExp)val3).longValue(); + long lval1 = ((NumericValueExp)val1).longValue(); + long lval2 = ((NumericValueExp)val2).longValue(); + long lval3 = ((NumericValueExp)val3).longValue(); return lval2 <= lval1 && lval1 <= lval3; } else { - dval1 = ((NumericValueExp)val1).doubleValue(); - dval2 = ((NumericValueExp)val2).doubleValue(); - dval3 = ((NumericValueExp)val3).doubleValue(); + double dval1 = ((NumericValueExp)val1).doubleValue(); + double dval2 = ((NumericValueExp)val2).doubleValue(); + double dval3 = ((NumericValueExp)val3).doubleValue(); return dval2 <= dval1 && dval1 <= dval3; } } else { - sval1 = ((StringValueExp)val1).toString(); - sval2 = ((StringValueExp)val2).toString(); - sval3 = ((StringValueExp)val3).toString(); + String sval1 = ((StringValueExp)val1).getValue(); + String sval2 = ((StringValueExp)val2).getValue(); + String sval3 = ((StringValueExp)val3).getValue(); return sval2.compareTo(sval1) <= 0 && sval1.compareTo(sval3) <= 0; } } @@ -148,4 +139,8 @@ class BetweenQueryExp extends QueryEval implements QueryExp { return "(" + exp1 + ") between (" + exp2 + ") and (" + exp3 + ")"; } - } + @Override + String toQueryString() { + return exp1 + " between " + exp2 + " and " + exp3; + } +} diff --git a/src/share/classes/javax/management/BinaryOpValueExp.java b/src/share/classes/javax/management/BinaryOpValueExp.java index 536f1f615661cfb2c09fd66ac7204d71e2607979..138258b9d2a1b42003f583a57ae2a1101b25d06b 100644 --- a/src/share/classes/javax/management/BinaryOpValueExp.java +++ b/src/share/classes/javax/management/BinaryOpValueExp.java @@ -167,12 +167,74 @@ class BinaryOpValueExp extends QueryEval implements ValueExp { */ public String toString() { try { - return exp1 + " " + opString() + " " + exp2; + return parens(exp1, true) + " " + opString() + " " + parens(exp2, false); } catch (BadBinaryOpValueExpException ex) { return "invalid expression"; } } + /* + * Add parentheses to the given subexpression if necessary to + * preserve meaning. Suppose this BinaryOpValueExp is + * Query.times(Query.plus(Query.attr("A"), Query.attr("B")), Query.attr("C")). + * Then the original toString() logic would return A + B * C. + * We check precedences in order to return (A + B) * C, which is the + * meaning of the ValueExp. + * + * We need to add parentheses if the unparenthesized expression would + * be parsed as a different ValueExp from the original. + * We cannot omit parentheses even when mathematically + * the result would be equivalent, because we do not know whether the + * numeric values will be integer or floating-point. Addition and + * multiplication are associative for integers but not always for + * floating-point. + * + * So the rule is that we omit parentheses if the ValueExp + * is (A op1 B) op2 C and the precedence of op1 is greater than or + * equal to that of op2; or if the ValueExp is A op1 (B op2 C) and + * the precedence of op2 is greater than that of op1. (There are two + * precedences: that of * and / is greater than that of + and -.) + * The case of (A op1 B) op2 (C op3 D) applies each rule in turn. + * + * The following examples show the rules in action. On the left, + * the original ValueExp. On the right, the string representation. + * + * (A + B) + C A + B + C + * (A * B) + C A * B + C + * (A + B) * C (A + B) * C + * (A * B) * C A * B * C + * A + (B + C) A + (B + C) + * A + (B * C) A + B * C + * A * (B + C) A * (B + C) + * A * (B * C) A * (B * C) + */ + private String parens(ValueExp subexp, boolean left) + throws BadBinaryOpValueExpException { + boolean omit; + if (subexp instanceof BinaryOpValueExp) { + int subop = ((BinaryOpValueExp) subexp).op; + if (left) + omit = (precedence(subop) >= precedence(op)); + else + omit = (precedence(subop) > precedence(op)); + } else + omit = true; + + if (omit) + return subexp.toString(); + else + return "(" + subexp + ")"; + } + + private int precedence(int xop) throws BadBinaryOpValueExpException { + switch (xop) { + case Query.PLUS: case Query.MINUS: return 0; + case Query.TIMES: case Query.DIV: return 1; + default: + throw new BadBinaryOpValueExpException(this); + } + } + private String opString() throws BadBinaryOpValueExpException { switch (op) { case Query.PLUS: @@ -188,4 +250,10 @@ class BinaryOpValueExp extends QueryEval implements ValueExp { throw new BadBinaryOpValueExpException(this); } + @Deprecated + public void setMBeanServer(MBeanServer s) { + super.setMBeanServer(s); + } + + } diff --git a/src/share/classes/javax/management/BinaryRelQueryExp.java b/src/share/classes/javax/management/BinaryRelQueryExp.java index 47809f35d9de1d5ae0e043f391ad440fa7be10b4..2e740aee2bde49a132ef53ae270d7765573a6452 100644 --- a/src/share/classes/javax/management/BinaryRelQueryExp.java +++ b/src/share/classes/javax/management/BinaryRelQueryExp.java @@ -108,20 +108,12 @@ class BinaryRelQueryExp extends QueryEval implements QueryExp { BadAttributeValueExpException, InvalidApplicationException { Object val1 = exp1.apply(name); Object val2 = exp2.apply(name); - String sval1; - String sval2; - double dval1; - double dval2; - long lval1; - long lval2; - boolean bval1; - boolean bval2; boolean numeric = val1 instanceof NumericValueExp; boolean bool = val1 instanceof BooleanValueExp; if (numeric) { if (((NumericValueExp)val1).isLong()) { - lval1 = ((NumericValueExp)val1).longValue(); - lval2 = ((NumericValueExp)val2).longValue(); + long lval1 = ((NumericValueExp)val1).longValue(); + long lval2 = ((NumericValueExp)val2).longValue(); switch (relOp) { case Query.GT: @@ -136,8 +128,8 @@ class BinaryRelQueryExp extends QueryEval implements QueryExp { return lval1 == lval2; } } else { - dval1 = ((NumericValueExp)val1).doubleValue(); - dval2 = ((NumericValueExp)val2).doubleValue(); + double dval1 = ((NumericValueExp)val1).doubleValue(); + double dval2 = ((NumericValueExp)val2).doubleValue(); switch (relOp) { case Query.GT: @@ -155,8 +147,8 @@ class BinaryRelQueryExp extends QueryEval implements QueryExp { } else if (bool) { - bval1 = ((BooleanValueExp)val1).getValue().booleanValue(); - bval2 = ((BooleanValueExp)val2).getValue().booleanValue(); + boolean bval1 = ((BooleanValueExp)val1).getValue().booleanValue(); + boolean bval2 = ((BooleanValueExp)val2).getValue().booleanValue(); switch (relOp) { case Query.GT: @@ -172,8 +164,8 @@ class BinaryRelQueryExp extends QueryEval implements QueryExp { } } else { - sval1 = ((StringValueExp)val1).getValue(); - sval2 = ((StringValueExp)val2).getValue(); + String sval1 = ((StringValueExp)val1).getValue(); + String sval2 = ((StringValueExp)val2).getValue(); switch (relOp) { case Query.GT: @@ -199,6 +191,11 @@ class BinaryRelQueryExp extends QueryEval implements QueryExp { return "(" + exp1 + ") " + relOpString() + " (" + exp2 + ")"; } + @Override + String toQueryString() { + return exp1 + " " + relOpString() + " " + exp2; + } + private String relOpString() { switch (relOp) { case Query.GT: diff --git a/src/share/classes/javax/management/BooleanValueExp.java b/src/share/classes/javax/management/BooleanValueExp.java index 6dc569744cf0324745bdb7728fdb252ac95d3340..7a5348fd0ab8c56cb4e824bda1811b9bad396608 100644 --- a/src/share/classes/javax/management/BooleanValueExp.java +++ b/src/share/classes/javax/management/BooleanValueExp.java @@ -84,4 +84,10 @@ class BooleanValueExp extends QueryEval implements ValueExp { return this; } + @Deprecated + public void setMBeanServer(MBeanServer s) { + super.setMBeanServer(s); + } + + } diff --git a/src/share/classes/javax/management/InQueryExp.java b/src/share/classes/javax/management/InQueryExp.java index 01f2c503a1b8d4800c135e951eb0fbea375a8ef1..103ba3b8633b37c873eaf084682b827a7ee2ec08 100644 --- a/src/share/classes/javax/management/InQueryExp.java +++ b/src/share/classes/javax/management/InQueryExp.java @@ -91,21 +91,23 @@ class InQueryExp extends QueryEval implements QueryExp { * @exception BadAttributeValueExpException * @exception InvalidApplicationException */ - public boolean apply(ObjectName name) throws BadStringOperationException, BadBinaryOpValueExpException, + public boolean apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, BadAttributeValueExpException, InvalidApplicationException { if (valueList != null) { ValueExp v = val.apply(name); boolean numeric = v instanceof NumericValueExp; - for (int i = 0; i < valueList.length; i++) { + for (ValueExp element : valueList) { + element = element.apply(name); if (numeric) { - if (((NumericValueExp)valueList[i]).doubleValue() == - ((NumericValueExp)v).doubleValue()) { + if (((NumericValueExp) element).doubleValue() == + ((NumericValueExp) v).doubleValue()) { return true; } } else { - if (((StringValueExp)valueList[i]).getValue().equals( - ((StringValueExp)v).getValue())) { + if (((StringValueExp) element).getValue().equals( + ((StringValueExp) v).getValue())) { return true; } } diff --git a/src/share/classes/javax/management/MatchQueryExp.java b/src/share/classes/javax/management/MatchQueryExp.java index 12e42769ffdf0973c026939ef83b3643c4958c75..779fac1989ff2605b4fc28a3299f16844670c951 100644 --- a/src/share/classes/javax/management/MatchQueryExp.java +++ b/src/share/classes/javax/management/MatchQueryExp.java @@ -113,7 +113,32 @@ class MatchQueryExp extends QueryEval implements QueryExp { } private static String likeTranslate(String s) { - return s.replace('?', '_').replace('*', '%'); + StringBuilder sb = new StringBuilder(); + int c; + for (int i = 0; i < s.length(); i += Character.charCount(c)) { + c = s.codePointAt(i); + switch (c) { + case '\\': + i += Character.charCount(c); + sb.append('\\'); + if (i < s.length()) { + c = s.codePointAt(i); + sb.appendCodePoint(c); + } + break; + case '*': + sb.append('%'); break; + case '?': + sb.append('_'); break; + case '%': + sb.append("\\%"); break; + case '_': + sb.append("\\_"); break; + default: + sb.appendCodePoint(c); break; + } + } + return sb.toString(); } /* diff --git a/src/share/classes/javax/management/NotQueryExp.java b/src/share/classes/javax/management/NotQueryExp.java index a099152012a9eae87aa064c595c87e28d99ca99d..ef2dc57b797e41deb45b576ee3f76008faa8dcf3 100644 --- a/src/share/classes/javax/management/NotQueryExp.java +++ b/src/share/classes/javax/management/NotQueryExp.java @@ -86,8 +86,14 @@ class NotQueryExp extends QueryEval implements QueryExp { /** * Returns the string representing the object. */ + @Override public String toString() { return "not (" + exp + ")"; } + @Override + String toQueryString() { + return "not (" + Query.toString(exp) + ")"; + } + } diff --git a/src/share/classes/javax/management/NumericValueExp.java b/src/share/classes/javax/management/NumericValueExp.java index bd8da33eaabc7a00d315792278fc32ca1823a984..c823a93deb4fc22d846dee50b963bce899983b37 100644 --- a/src/share/classes/javax/management/NumericValueExp.java +++ b/src/share/classes/javax/management/NumericValueExp.java @@ -151,11 +151,18 @@ class NumericValueExp extends QueryEval implements ValueExp { * Returns the string representing the object */ public String toString() { + if (val == null) + return "null"; if (val instanceof Long || val instanceof Integer) { - return String.valueOf(val.longValue()); + return Long.toString(val.longValue()); } - return String.valueOf(val.doubleValue()); + double d = val.doubleValue(); + if (Double.isInfinite(d)) + return (d > 0) ? "(1.0 / 0.0)" : "(-1.0 / 0.0)"; + if (Double.isNaN(d)) + return "(0.0 / 0.0)"; + return Double.toString(d); } /** @@ -244,4 +251,10 @@ class NumericValueExp extends QueryEval implements ValueExp { out.defaultWriteObject(); } } + + @Deprecated + public void setMBeanServer(MBeanServer s) { + super.setMBeanServer(s); + } + } diff --git a/src/share/classes/javax/management/ObjectName.java b/src/share/classes/javax/management/ObjectName.java index 8721bb62d18a9fdac85397a1cf6a49fec357f53c..cef869510b16f152d3744928b610d38b85879ea3 100644 --- a/src/share/classes/javax/management/ObjectName.java +++ b/src/share/classes/javax/management/ObjectName.java @@ -222,7 +222,8 @@ import javax.management.QueryExp; * @since 1.5 */ @SuppressWarnings("serial") // don't complain serialVersionUID not constant -public class ObjectName implements Comparable, QueryExp { +public class ObjectName extends ToQueryString + implements Comparable, QueryExp { /** * A structure recording property structure and @@ -1779,10 +1780,16 @@ public class ObjectName implements Comparable, QueryExp { * * @return a string representation of this object name. */ + @Override public String toString() { return getSerializedNameString(); } + @Override + String toQueryString() { + return "LIKE " + Query.value(toString()); + } + /** * Compares the current object name with another object name. Two * ObjectName instances are equal if and only if their canonical diff --git a/src/share/classes/javax/management/OrQueryExp.java b/src/share/classes/javax/management/OrQueryExp.java index 772a32385aeb8b18bb6f780f38fd148013976e3f..e1ca5122f2890de1836e870c81483aa60f44684f 100644 --- a/src/share/classes/javax/management/OrQueryExp.java +++ b/src/share/classes/javax/management/OrQueryExp.java @@ -98,9 +98,29 @@ class OrQueryExp extends QueryEval implements QueryExp { } /** - * Returns a string representation of this AndQueryExp + * Returns a string representation of this OrQueryExp */ public String toString() { return "(" + exp1 + ") or (" + exp2 + ")"; } + + @Override + String toQueryString() { + return parens(exp1) + " or " + parens(exp2); + } + + // Add parentheses to avoid possible confusion. If we have an expression + // such as Query.or(Query.and(a, b), c), then we return + // (a and b) or c + // rather than just + // a and b or c + // In fact the precedence rules are such that the parentheses are not + // strictly necessary, but omitting them would be confusing. + private static String parens(QueryExp exp) { + String s = Query.toString(exp); + if (exp instanceof AndQueryExp) + return "(" + s + ")"; + else + return s; + } } diff --git a/src/share/classes/javax/management/QualifiedAttributeValueExp.java b/src/share/classes/javax/management/QualifiedAttributeValueExp.java index fe7ce41a012920785772ae87652b3708ba572218..3934d27084f8a105e66711b26ea638c6aa149ef8 100644 --- a/src/share/classes/javax/management/QualifiedAttributeValueExp.java +++ b/src/share/classes/javax/management/QualifiedAttributeValueExp.java @@ -27,9 +27,11 @@ package javax.management; /** - * This class represents indexed attributes used as arguments to relational - * constraints. An QualifiedAttributeValueExp may be used anywhere a - * ValueExp is required. + *

    Represents attributes used as arguments to relational constraints, + * where the attribute must be in an MBean of a specified {@linkplain + * MBeanInfo#getClassName() class}. A QualifiedAttributeValueExp may be used + * anywhere a ValueExp is required. + * * @serial include * * @since 1.5 @@ -48,7 +50,9 @@ class QualifiedAttributeValueExp extends AttributeValueExp { /** * Basic Constructor. + * @deprecated see {@link AttributeValueExp#AttributeValueExp()} */ + @Deprecated public QualifiedAttributeValueExp() { } @@ -81,6 +85,7 @@ class QualifiedAttributeValueExp extends AttributeValueExp { * @exception BadAttributeValueExpException * @exception InvalidApplicationException */ + @Override public ValueExp apply(ObjectName name) throws BadStringOperationException, BadBinaryOpValueExpException, BadAttributeValueExpException, InvalidApplicationException { try { @@ -105,9 +110,11 @@ class QualifiedAttributeValueExp extends AttributeValueExp { /** * Returns the string representing its value */ + @Override public String toString() { if (className != null) { - return className + "." + super.toString(); + return QueryParser.quoteId(className) + "#" + + QueryParser.quoteId(super.toString()); } else { return super.toString(); } diff --git a/src/share/classes/javax/management/Query.java b/src/share/classes/javax/management/Query.java index 84a71da510b0570b20bf056ad9e3dbacbc4c1b2e..d3b461da75d593087d070063a654faac9e90c4a8 100644 --- a/src/share/classes/javax/management/Query.java +++ b/src/share/classes/javax/management/Query.java @@ -27,19 +27,346 @@ package javax.management; /** - *

    Constructs query object constraints. The static methods provided - * return query expressions that may be used in listing and - * enumerating MBeans. Individual constraint construction methods - * allow only appropriate types as arguments. Composition of calls can - * construct arbitrary nestings of constraints, as the following - * example illustrates:

    + *

    Constructs query object constraints.

    + * + *

    The MBean Server can be queried for MBeans that meet a particular + * condition, using its {@link MBeanServer#queryNames queryNames} or + * {@link MBeanServer#queryMBeans queryMBeans} method. The {@link QueryExp} + * parameter to the method can be any implementation of the interface + * {@code QueryExp}, but it is usually best to obtain the {@code QueryExp} + * value by calling the static methods in this class. This is particularly + * true when querying a remote MBean Server: a custom implementation of the + * {@code QueryExp} interface might not be present in the remote MBean Server, + * but the methods in this class return only standard classes that are + * part of the JMX implementation.

    + * + *

    There are two ways to create {@code QueryExp} objects using the methods + * in this class. The first is to build them by chaining together calls to + * the various methods. The second is to use the Query Language described + * below and produce the {@code QueryExp} by calling + * {@link #fromString Query.fromString}. The two ways are equivalent: + * every {@code QueryExp} returned by {@code fromString} can also be + * constructed by chaining method calls.

    + * + *

    As an example, suppose you wanted to find all MBeans where the {@code + * Enabled} attribute is {@code true} and the {@code Owner} attribute is {@code + * "Duke"}. Here is how you could construct the appropriate {@code QueryExp} by + * chaining together method calls:

    + * + *
    + * QueryExp query =
    + *     Query.and(Query.eq(Query.attr("Enabled"), Query.value(true)),
    + *               Query.eq(Query.attr("Owner"), Query.value("Duke")));
    + * 
    + * + *

    Here is how you could construct the same {@code QueryExp} using the + * Query Language:

    * *
    - * QueryExp exp = Query.and(Query.gt(Query.attr("age"),Query.value(5)),
    - *                          Query.match(Query.attr("name"),
    - *                                      Query.value("Smith")));
    + * QueryExp query = Query.fromString("Enabled = true and Owner = 'Duke'");
      * 
    * + *

    The principal advantage of the method-chaining approach is that the + * compiler will check that the query makes sense. The principal advantage + * of the Query Language approach is that it is easier to write and especially + * read.

    + * + * + *

    Query Language

    + * + *

    The query language is closely modeled on the WHERE clause of + * SQL SELECT statements. The formal specification of the language + * appears below, but it is probably easier to + * understand it with examples such as the following.

    + * + *
    + *
    {@code Message = 'OK'} + *
    Selects MBeans that have a {@code Message} attribute whose value + * is the string {@code OK}. + * + *
    {@code FreeSpacePercent < 10} + *
    Selects MBeans that have a {@code FreeSpacePercent} attribute whose + * value is a number less than 10. + * + *
    {@code FreeSpacePercent < 10 and WarningSent = false} + *
    Selects the same MBeans as the previous example, but they must + * also have a boolean attribute {@code WarningSent} whose value + * is false. + * + *
    {@code SpaceUsed > TotalSpace * (2.0 / 3.0)} + *
    Selects MBeans that have {@code SpaceUsed} and {@code TotalSpace} + * attributes where the first is more than two-thirds the second. + * + *
    {@code not (FreeSpacePercent between 10 and 90)} + *
    Selects MBeans that have a {@code FreeSpacePercent} attribute whose + * value is not between 10 and 90, inclusive. + * + *
    {@code FreeSpacePercent not between 10 and 90} + *
    Another way of writing the previous query. + * + *
    {@code Status in ('STOPPED', 'STARTING', 'STARTED')} + *
    Selects MBeans that have a {@code Status} attribute whose value + * is one of those three strings. + * + *
    {@code Message like 'OK: %'} + *
    Selects MBeans that have a {@code Message} attribute whose value + * is a string beginning with {@code "OK: "}. Notice that the + * wildcard characters are SQL's ones. In the query language, + * {@code %} means "any sequence of characters" and {@code _} + * means "any single character". In the rest of the JMX API, these + * correspond to {@code *} and {@code %} respectively. + * + *
    {@code instanceof 'javax.management.NotificationBroadcaster'} + *
    Selects MBeans that are instances of + * {@link javax.management.NotificationBroadcaster}, as reported by + * {@link javax.management.MBeanServer#isInstanceOf MBeanServer.isInstanceOf}. + * + *
    {@code like 'mydomain:*'} + *
    Selects MBeans whose {@link ObjectName}s have the domain {@code mydomain}. + * + *
    + * + *

    The last two examples do not correspond to valid SQL syntax, but all + * the others do.

    + * + *

    The remainder of this description is a formal specification of the + * query language.

    + * + * + *

    Lexical elements

    + * + *

    Keywords such as and, like, and between are not + * case sensitive. You can write between, BETWEEN, or + * BeTwEeN with the same effect.

    + * + *

    On the other hand, attribute names are case sensitive. The + * attribute {@code Name} is not the same as the attribute {@code name}.

    + * + *

    To access an attribute whose name, ignoring case, is the same as one of + * the keywords {@code not}, {@code instanceof}, {@code like}, {@code true}, + * or {@code false}, you can use double quotes, for example {@code "not"}. + * Double quotes can also be used to include non-identifier characters in + * the name of an attribute, for example {@code "attribute-name-with-hyphens"}. + * To include the double quote character in the attribute name, write it + * twice. {@code "foo""bar""baz"} represents the attribute called + * {@code foo"bar"baz}. + * + *

    String constants are written with single quotes like {@code 'this'}. A + * single quote within a string constant must be doubled, for example + * {@code 'can''t'}.

    + * + *

    Integer constants are written as a sequence of decimal digits, + * optionally preceded by a plus or minus sign. An integer constant must be + * a valid input to {@link Long#valueOf(String)}.

    + * + *

    Floating-point constants are written using the Java syntax. A + * floating-point constant must be a valid input to + * {@link Double#valueOf(String)}.

    + * + *

    A boolean constant is either {@code true} or {@code false}, ignoring + * case.

    + * + *

    Spaces cannot appear inside identifiers (unless written with double + * quotes) or keywords or multi-character tokens such as {@code <=}. Spaces can + * appear anywhere else, but are not required except to separate tokens. For + * example, the query {@code a < b and 5 = c} could also be written {@code a + * + * + *

    Grammar

    + * + *
    + *
    query: + *
    andquery [OR query] + * + *
    andquery: + *
    predicate [AND andquery] + * + *
    predicate: + *
    ( query ) |
    + * NOT predicate |
    + * INSTANCEOF stringvalue |
    + * LIKE objectnamepattern |
    + * value predrhs + * + *
    predrhs: + *
    compare value |
    + * [NOT] BETWEEN value AND + * value |
    + * [NOT] IN ( value + * commavalues ) |
    + * [NOT] LIKE stringvalue + * + *
    commavalues: + *
    [ , value commavalues ] + * + *
    compare: + *
    = | < | > | + * <= | >= | <> | != + * + *
    value: + *
    factor [plusorminus + * value] + * + *
    plusorminus: + *
    + | - + * + *
    factor: + *
    term [timesordivide + * factor] + * + *
    timesordivide: + *
    * | / + * + *
    term: + *
    attr | literal | + * ( value ) + * + *
    attr: + *
    name [# name] + * + *
    name: + *
    identifier [.name] + * + *
    identifier: + *
    Java-identifier | double-quoted-identifier + * + *
    literal: + *
    booleanlit | longlit | + * doublelit | stringlit + * + *
    booleanlit: + *
    FALSE | TRUE + * + *
    stringvalue: + *
    stringlit + * + *
    objectnamepattern: + *
    stringlit + * + *
    + * + * + *

    Semantics

    + * + *

    The meaning of the grammar is described in the table below. + * This defines a function q that maps a string to a Java object + * such as a {@link QueryExp} or a {@link ValueExp}.

    + * + * + * + * + *
    String sq(s)
    query1 OR query2 + * {@link Query#or Query.or}(q(query1), q(query2)) + * + *
    query1 AND query2 + * {@link Query#and Query.and}(q(query1), q(query2)) + * + *
    ( queryOrValue ) + * q(queryOrValue) + * + *
    NOT query + * {@link Query#not Query.not}(q(query)) + * + *
    INSTANCEOF stringLiteral + * {@link Query#isInstanceOf Query.isInstanceOf}({@link Query#value(String) Query.value}(q(stringLiteral))) + * + *
    LIKE stringLiteral + * {@link ObjectName#ObjectName(String) new ObjectName}(q(stringLiteral)) + * + *
    value1 = value2 + * {@link Query#eq Query.eq}(q(value1), q(value2)) + * + *
    value1 < value2 + * {@link Query#lt Query.lt}(q(value1), q(value2)) + * + *
    value1 > value2 + * {@link Query#gt Query.gt}(q(value1), q(value2)) + * + *
    value1 <= value2 + * {@link Query#leq Query.leq}(q(value1), q(value2)) + * + *
    value1 >= value2 + * {@link Query#geq Query.geq}(q(value1), q(value2)) + * + *
    value1 <> value2 + * {@link Query#not Query.not}({@link Query#eq Query.eq}(q(value1), q(value2))) + * + *
    value1 != value2 + * {@link Query#not Query.not}({@link Query#eq Query.eq}(q(value1), q(value2))) + * + *
    value1 BETWEEN value2 AND value3 + * {@link Query#between Query.between}(q(value1), + * q(value2), q(value3)) + * + *
    value1 NOT BETWEEN value2 AND value3 + * {@link Query#not Query.not}({@link Query#between Query.between}(q(value1), q(value2), q(value3))) + * + *
    value1 IN ( value2, value3 ) + * {@link Query#in Query.in}(q(value1), + * new ValueExp[] { + * q(value2), q(value3)}) + * + *
    value1 NOT IN ( value2, value3 ) + * {@link Query#not Query.not}({@link Query#in Query.in}(q(value1), + * new ValueExp[] { + * q(value2), q(value3)})) + * + *
    value LIKE stringLiteral + * {@link Query#match Query.match}(q(value), + * translateWildcards(q(stringLiteral))) + * + *
    value NOT LIKE stringLiteral + * {@link Query#not Query.not}({@link Query#match Query.match}(q(value), + * translateWildcards(q(stringLiteral)))) + * + *
    value1 + value2 + * {@link Query#plus Query.plus}(q(value1), q(value2)) + * + *
    value1 - value2 + * {@link Query#minus Query.minus}(q(value1), q(value2)) + * + *
    value1 * value2 + * {@link Query#times Query.times}(q(value1), q(value2)) + * + *
    value1 / value2 + * {@link Query#div Query.div}(q(value1), q(value2)) + * + *
    name + * {@link Query#attr(String) Query.attr}(q(name)) + * + *
    name1#name2 + * {@link Query#attr(String,String) Query.attr}(q(name1), + * q(name2)) + * + *
    FALSE + * {@link Query#value(boolean) Query.value}(false) + * + *
    TRUE + * {@link Query#value(boolean) Query.value}(true) + * + *
    decimalLiteral + * {@link Query#value(long) Query.value}({@link Long#valueOf(String) Long.valueOf}(decimalLiteral)) + * + *
    floatingPointLiteral + * {@link Query#value(double) Query.value}({@link Double#valueOf(String) Double.valueOf}(floatingPointLiteral)) + *
    + * + *

    Here, translateWildcards is a function + * that translates from the SQL notation for wildcards, using {@code %} and + * {@code _}, to the JMX API notation, using {@code *} and {@code ?}. If the + * LIKE string already contains {@code *} or {@code ?}, these characters + * have their literal meanings, and will be quoted in the call to + * {@link Query#match Query.match}.

    + * * @since 1.5 */ public class Query extends Object { @@ -277,16 +604,12 @@ package javax.management; } /** - *

    Returns a new attribute expression.

    - * - *

    Evaluating this expression for a given - * objectName includes performing {@link - * MBeanServer#getAttribute MBeanServer.getAttribute(objectName, - * name)}.

    + *

    Returns a new attribute expression. See {@link AttributeValueExp} + * for a detailed description of the semantics of the expression.

    * * @param name The name of the attribute. * - * @return An attribute expression for the attribute named name. + * @return An attribute expression for the attribute named {@code name}. */ public static AttributeValueExp attr(String name) { return new AttributeValueExp(name); @@ -627,6 +950,63 @@ package javax.management; return new InstanceOfQueryExp(classNameValue); } + /** + *

    Return a string representation of the given query. The string + * returned by this method can be converted back into an equivalent + * query using {@link #fromString fromString}.

    + * + *

    (Two queries are equivalent if they produce the same result in + * all cases. Equivalent queries are not necessarily identical: + * for example the queries {@code Query.lt(Query.attr("A"), Query.attr("B"))} + * and {@code Query.not(Query.ge(Query.attr("A"), Query.attr("B")))} are + * equivalent but not identical.)

    + * + *

    The string returned by this method is only guaranteed to be converted + * back into an equivalent query if {@code query} was constructed, or + * could have been constructed, using the methods of this class. + * If you make a custom query {@code myQuery} by implementing + * {@link QueryExp} yourself then the result of + * {@code Query.toString(myQuery)} is unspecified.

    + * + * @param query the query to convert. If it is null, the result will + * also be null. + * @return the string representation of the query, or null if the + * query is null. + * + * @since 1.7 + */ + public static String toString(QueryExp query) { + if (query == null) + return null; + + if (query instanceof ToQueryString) + return ((ToQueryString) query).toQueryString(); + + return query.toString(); + } + + /** + *

    Produce a query from the given string. The query returned + * by this method can be converted back into a string using + * {@link #toString(QueryExp) toString}. The resultant string will + * not necessarily be equal to {@code s}.

    + * + * @param s the string to convert. + * + * @return a {@code QueryExp} derived by parsing the string, or + * null if the string is null. + * + * @throws IllegalArgumentException if the string is not a valid + * query string. + * + * @since 1.7 + */ + public static QueryExp fromString(String s) { + if (s == null) + return null; + return new QueryParser(s).parseQuery(); + } + /** * Utility method to escape strings used with * Query.{initial|any|final}SubString() methods. diff --git a/src/share/classes/javax/management/QueryEval.java b/src/share/classes/javax/management/QueryEval.java index 05c4e38b4beca33c09a8ddb43941336cdd7ef7f9..02c651c3c4c34e138774e85264fade860a5ec88b 100644 --- a/src/share/classes/javax/management/QueryEval.java +++ b/src/share/classes/javax/management/QueryEval.java @@ -38,7 +38,7 @@ import javax.management.MBeanServer; * * @since 1.5 */ -public abstract class QueryEval implements Serializable { +public abstract class QueryEval extends ToQueryString implements Serializable { /* Serial version */ private static final long serialVersionUID = 2675899265640874796L; diff --git a/src/share/classes/javax/management/QueryExp.java b/src/share/classes/javax/management/QueryExp.java index 6ac9ef6854f5d893fca198272b0cc9296636a865..217db104249a83ba01df21b097791d6fa9851db1 100644 --- a/src/share/classes/javax/management/QueryExp.java +++ b/src/share/classes/javax/management/QueryExp.java @@ -30,9 +30,9 @@ import java.io.Serializable; /** - *

    Represents relational constraints that can be used in database - * query "where clauses". Instances of QueryExp are returned by the - * static methods of the {@link Query} class.

    + *

    Represents relational constraints similar to database query "where + * clauses". Instances of QueryExp are returned by the static methods of the + * {@link Query} class.

    * *

    It is possible, but not * recommended, to create custom queries by implementing this @@ -40,6 +40,7 @@ import java.io.Serializable; * QueryEval} class than to implement the interface directly, so that * the {@link #setMBeanServer} method works correctly. * + * @see MBeanServer#queryNames MBeanServer.queryNames * @since 1.5 */ public interface QueryExp extends Serializable { diff --git a/src/share/classes/javax/management/QueryParser.java b/src/share/classes/javax/management/QueryParser.java new file mode 100644 index 0000000000000000000000000000000000000000..5e24e3bfbd3d7dc0e7096dab5f518cc9ee73d680 --- /dev/null +++ b/src/share/classes/javax/management/QueryParser.java @@ -0,0 +1,663 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management; + +import java.util.ArrayList; +import java.util.Formatter; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +/** + *

    Parser for JMX queries represented in an SQL-like language.

    + */ +/* + * Note that if a query starts with ( then we don't know whether it is + * a predicate or just a value that is parenthesized. So, inefficiently, + * we try to parse a predicate and if that doesn't work we try to parse + * a value. + */ +class QueryParser { + // LEXER STARTS HERE + + private static class Token { + final String string; + Token(String s) { + this.string = s; + } + + @Override + public String toString() { + return string; + } + } + + private static final Token + END = new Token(""), + LPAR = new Token("("), RPAR = new Token(")"), + COMMA = new Token(","), DOT = new Token("."), SHARP = new Token("#"), + PLUS = new Token("+"), MINUS = new Token("-"), + TIMES = new Token("*"), DIVIDE = new Token("/"), + LT = new Token("<"), GT = new Token(">"), + LE = new Token("<="), GE = new Token(">="), + NE = new Token("<>"), EQ = new Token("="), + NOT = new Id("NOT"), INSTANCEOF = new Id("INSTANCEOF"), + FALSE = new Id("FALSE"), TRUE = new Id("TRUE"), + BETWEEN = new Id("BETWEEN"), AND = new Id("AND"), + OR = new Id("OR"), IN = new Id("IN"), + LIKE = new Id("LIKE"), CLASS = new Id("CLASS"); + + // Keywords that can appear where an identifier can appear. + // If an attribute is one of these, then it must be quoted when + // converting a query into a string. + // We use a TreeSet so we can look up case-insensitively. + private static final Set idKeywords = + new TreeSet(String.CASE_INSENSITIVE_ORDER); + static { + for (Token t : new Token[] {NOT, INSTANCEOF, FALSE, TRUE, LIKE, CLASS}) + idKeywords.add(t.string); + }; + + public static String quoteId(String id) { + if (id.contains("\"") || idKeywords.contains(id)) + return '"' + id.replace("\"", "\"\"") + '"'; + else + return id; + } + + private static class Id extends Token { + Id(String id) { + super(id); + } + + // All other tokens use object identity, which means e.g. that one + // occurrence of the string constant 'x' is not the same as another. + // For identifiers, we ignore case when testing for equality so that + // for a keyword such as AND you can also spell it as "And" or "and". + // But we keep the original case of the identifier, so if it's not + // a keyword we will distinguish between the attribute Foo and the + // attribute FOO. + @Override + public boolean equals(Object o) { + return (o instanceof Id && (((Id) o).toString().equalsIgnoreCase(toString()))); + } + } + + private static class QuotedId extends Token { + QuotedId(String id) { + super(id); + } + + @Override + public String toString() { + return '"' + string.replace("\"", "\"\"") + '"'; + } + } + + private static class StringLit extends Token { + StringLit(String s) { + super(s); + } + + @Override + public String toString() { + return '\'' + string.replace("'", "''") + '\''; + } + } + + private static class LongLit extends Token { + long number; + + LongLit(long number) { + super(Long.toString(number)); + this.number = number; + } + } + + private static class DoubleLit extends Token { + double number; + + DoubleLit(double number) { + super(Double.toString(number)); + this.number = number; + } + } + + private static class Tokenizer { + private final String s; + private final int len; + private int i = 0; + + Tokenizer(String s) { + this.s = s; + this.len = s.length(); + } + + private int thisChar() { + if (i == len) + return -1; + return s.codePointAt(i); + } + + private void advance() { + i += Character.charCount(thisChar()); + } + + private int thisCharAdvance() { + int c = thisChar(); + advance(); + return c; + } + + Token nextToken() { + // In this method, c is the character we're looking at, and + // thisChar() is the character after that. Everything must + // preserve these invariants. When we return we then have + // thisChar() being the start of the following token, so + // the next call to nextToken() will begin from there. + int c; + + // Skip space + do { + if (i == len) + return null; + c = thisCharAdvance(); + } while (Character.isWhitespace(c)); + + // Now c is the first character of the token, and tokenI points + // to the character after that. + switch (c) { + case '(': return LPAR; + case ')': return RPAR; + case ',': return COMMA; + case '.': return DOT; + case '#': return SHARP; + case '*': return TIMES; + case '/': return DIVIDE; + case '=': return EQ; + case '-': return MINUS; + case '+': return PLUS; + + case '>': + if (thisChar() == '=') { + advance(); + return GE; + } else + return GT; + + case '<': + c = thisChar(); + switch (c) { + case '=': advance(); return LE; + case '>': advance(); return NE; + default: return LT; + } + + case '!': + if (thisCharAdvance() != '=') + throw new IllegalArgumentException("'!' must be followed by '='"); + return NE; + + case '"': + case '\'': { + int quote = c; + StringBuilder sb = new StringBuilder(); + while (true) { + while ((c = thisChar()) != quote) { + if (c < 0) { + throw new IllegalArgumentException( + "Unterminated string constant"); + } + sb.appendCodePoint(thisCharAdvance()); + } + advance(); + if (thisChar() == quote) { + sb.appendCodePoint(quote); + advance(); + } else + break; + } + if (quote == '\'') + return new StringLit(sb.toString()); + else + return new QuotedId(sb.toString()); + } + } + + // Is it a numeric constant? + if (Character.isDigit(c) || c == '.') { + StringBuilder sb = new StringBuilder(); + int lastc = -1; + while (true) { + sb.appendCodePoint(c); + c = Character.toLowerCase(thisChar()); + if (c == '+' || c == '-') { + if (lastc != 'e') + break; + } else if (!Character.isDigit(c) && c != '.' && c != 'e') + break; + lastc = c; + advance(); + } + String s = sb.toString(); + if (s.indexOf('.') >= 0 || s.indexOf('e') >= 0) { + double d = parseDoubleCheckOverflow(s); + return new DoubleLit(d); + } else { + // Like the Java language, we allow the numeric constant + // x where -x = Long.MIN_VALUE, even though x is not + // representable as a long (it is Long.MAX_VALUE + 1). + // Code in the parser will reject this value if it is + // not the operand of unary minus. + long l = -Long.parseLong("-" + s); + return new LongLit(l); + } + } + + // It must be an identifier. + if (!Character.isJavaIdentifierStart(c)) { + StringBuilder sb = new StringBuilder(); + Formatter f = new Formatter(sb); + f.format("Bad character: %c (%04x)", c, c); + throw new IllegalArgumentException(sb.toString()); + } + + StringBuilder id = new StringBuilder(); + while (true) { // identifier + id.appendCodePoint(c); + c = thisChar(); + if (!Character.isJavaIdentifierPart(c)) + break; + advance(); + } + + return new Id(id.toString()); + } + } + + /* Parse a double as a Java compiler would do it, throwing an exception + * if the input does not fit in a double. We assume that the input + * string is not "Infinity" and does not have a leading sign. + */ + private static double parseDoubleCheckOverflow(String s) { + double d = Double.parseDouble(s); + if (Double.isInfinite(d)) + throw new NumberFormatException("Overflow: " + s); + if (d == 0.0) { // Underflow checking is hard! CR 6604864 + String ss = s; + int e = s.indexOf('e'); // we already forced E to lowercase + if (e > 0) + ss = s.substring(0, e); + ss = ss.replace("0", "").replace(".", ""); + if (!ss.isEmpty()) + throw new NumberFormatException("Underflow: " + s); + } + return d; + } + + // PARSER STARTS HERE + + private final List tokens; + private int tokenI; + // The current token is always tokens[tokenI]. + + QueryParser(String s) { + // Construct the complete list of tokens immediately and append + // a sentinel (END). + tokens = new ArrayList(); + Tokenizer tokenizer = new Tokenizer(s); + Token t; + while ((t = tokenizer.nextToken()) != null) + tokens.add(t); + tokens.add(END); + } + + private Token current() { + return tokens.get(tokenI); + } + + // If the current token is t, then skip it and return true. + // Otherwise, return false. + private boolean skip(Token t) { + if (t.equals(current())) { + tokenI++; + return true; + } + return false; + } + + // If the current token is one of the ones in 'tokens', then skip it + // and return its index in 'tokens'. Otherwise, return -1. + private int skipOne(Token... tokens) { + for (int i = 0; i < tokens.length; i++) { + if (skip(tokens[i])) + return i; + } + return -1; + } + + // If the current token is t, then skip it and return. + // Otherwise throw an exception. + private void expect(Token t) { + if (!skip(t)) + throw new IllegalArgumentException("Expected " + t + ", found " + current()); + } + + private void next() { + tokenI++; + } + + QueryExp parseQuery() { + QueryExp qe = query(); + if (current() != END) + throw new IllegalArgumentException("Junk at end of query: " + current()); + return qe; + } + + // The remainder of this class is a classical recursive-descent parser. + // We only need to violate the recursive-descent scheme in one place, + // where parentheses make the grammar not LL(1). + + private QueryExp query() { + QueryExp lhs = andquery(); + while (skip(OR)) + lhs = Query.or(lhs, andquery()); + return lhs; + } + + private QueryExp andquery() { + QueryExp lhs = predicate(); + while (skip(AND)) + lhs = Query.and(lhs, predicate()); + return lhs; + } + + private QueryExp predicate() { + // Grammar hack. If we see a paren, it might be (query) or + // it might be (value). We try to parse (query), and if that + // fails, we parse (value). For example, if the string is + // "(2+3)*4 < 5" then we will try to parse the query + // "2+3)*4 < 5", which will fail at the ), so we'll back up to + // the paren and let value() handle it. + if (skip(LPAR)) { + int parenIndex = tokenI - 1; + try { + QueryExp qe = query(); + expect(RPAR); + return qe; + } catch (IllegalArgumentException e) { + // OK: try parsing a value + } + tokenI = parenIndex; + } + + if (skip(NOT)) + return Query.not(predicate()); + + if (skip(INSTANCEOF)) + return Query.isInstanceOf(stringvalue()); + + if (skip(LIKE)) { + StringValueExp sve = stringvalue(); + String s = sve.getValue(); + try { + return new ObjectName(s); + } catch (MalformedObjectNameException e) { + throw new IllegalArgumentException( + "Bad ObjectName pattern after LIKE: '" + s + "'", e); + } + } + + ValueExp lhs = value(); + + return predrhs(lhs); + } + + // The order of elements in the following arrays is important. The code + // in predrhs depends on integer indexes. Change with caution. + private static final Token[] relations = { + EQ, LT, GT, LE, GE, NE, + // 0, 1, 2, 3, 4, 5, + }; + private static final Token[] betweenLikeIn = { + BETWEEN, LIKE, IN + // 0, 1, 2, + }; + + private QueryExp predrhs(ValueExp lhs) { + Token start = current(); // for errors + + // Look for < > = etc + int i = skipOne(relations); + if (i >= 0) { + ValueExp rhs = value(); + switch (i) { + case 0: return Query.eq(lhs, rhs); + case 1: return Query.lt(lhs, rhs); + case 2: return Query.gt(lhs, rhs); + case 3: return Query.leq(lhs, rhs); + case 4: return Query.geq(lhs, rhs); + case 5: return Query.not(Query.eq(lhs, rhs)); + // There is no Query.ne so <> is shorthand for the above. + default: + throw new AssertionError(); + } + } + + // Must be BETWEEN LIKE or IN, optionally preceded by NOT + boolean not = skip(NOT); + i = skipOne(betweenLikeIn); + if (i < 0) + throw new IllegalArgumentException("Expected relation at " + start); + + QueryExp q; + switch (i) { + case 0: { // BETWEEN + ValueExp lower = value(); + expect(AND); + ValueExp upper = value(); + q = Query.between(lhs, lower, upper); + break; + } + + case 1: { // LIKE + if (!(lhs instanceof AttributeValueExp)) { + throw new IllegalArgumentException( + "Left-hand side of LIKE must be an attribute"); + } + AttributeValueExp alhs = (AttributeValueExp) lhs; + StringValueExp sve = stringvalue(); + String s = sve.getValue(); + q = Query.match(alhs, patternValueExp(s)); + break; + } + + case 2: { // IN + expect(LPAR); + List values = new ArrayList(); + values.add(value()); + while (skip(COMMA)) + values.add(value()); + expect(RPAR); + q = Query.in(lhs, values.toArray(new ValueExp[values.size()])); + break; + } + + default: + throw new AssertionError(); + } + + if (not) + q = Query.not(q); + + return q; + } + + private ValueExp value() { + ValueExp lhs = factor(); + int i; + while ((i = skipOne(PLUS, MINUS)) >= 0) { + ValueExp rhs = factor(); + if (i == 0) + lhs = Query.plus(lhs, rhs); + else + lhs = Query.minus(lhs, rhs); + } + return lhs; + } + + private ValueExp factor() { + ValueExp lhs = term(); + int i; + while ((i = skipOne(TIMES, DIVIDE)) >= 0) { + ValueExp rhs = term(); + if (i == 0) + lhs = Query.times(lhs, rhs); + else + lhs = Query.div(lhs, rhs); + } + return lhs; + } + + private ValueExp term() { + boolean signed = false; + int sign = +1; + if (skip(PLUS)) + signed = true; + else if (skip(MINUS)) { + signed = true; sign = -1; + } + + Token t = current(); + next(); + + if (t instanceof DoubleLit) + return Query.value(sign * ((DoubleLit) t).number); + if (t instanceof LongLit) { + long n = ((LongLit) t).number; + if (n == Long.MIN_VALUE && sign != -1) + throw new IllegalArgumentException("Illegal positive integer: " + n); + return Query.value(sign * n); + } + if (signed) + throw new IllegalArgumentException("Expected number after + or -"); + + if (t == LPAR) { + ValueExp v = value(); + expect(RPAR); + return v; + } + if (t.equals(FALSE) || t.equals(TRUE)) { + return Query.value(t.equals(TRUE)); + } + if (t.equals(CLASS)) + return Query.classattr(); + + if (t instanceof StringLit) + return Query.value(t.string); // Not toString(), which would requote ' + + // At this point, all that remains is something that will call Query.attr + + if (!(t instanceof Id) && !(t instanceof QuotedId)) + throw new IllegalArgumentException("Unexpected token " + t); + + String name1 = name(t); + + if (skip(SHARP)) { + Token t2 = current(); + next(); + String name2 = name(t2); + return Query.attr(name1, name2); + } + return Query.attr(name1); + } + + // Initially, t is the first token of a supposed name and current() + // is the second. + private String name(Token t) { + StringBuilder sb = new StringBuilder(); + while (true) { + if (!(t instanceof Id) && !(t instanceof QuotedId)) + throw new IllegalArgumentException("Unexpected token " + t); + sb.append(t.string); + if (current() != DOT) + break; + sb.append('.'); + next(); + t = current(); + next(); + } + return sb.toString(); + } + + private StringValueExp stringvalue() { + // Currently the only way to get a StringValueExp when constructing + // a QueryExp is via Query.value(String), so we only recognize + // string literals here. But if we expand queries in the future + // that might no longer be true. + Token t = current(); + next(); + if (!(t instanceof StringLit)) + throw new IllegalArgumentException("Expected string: " + t); + return Query.value(t.string); + } + + // Convert the SQL pattern syntax, using % and _, to the Query.match + // syntax, using * and ?. The tricky part is recognizing \% and + // \_ as literal values, and also not replacing them inside []. + // But Query.match does not recognize \ inside [], which makes our + // job a tad easier. + private StringValueExp patternValueExp(String s) { + int c; + for (int i = 0; i < s.length(); i += Character.charCount(c)) { + c = s.codePointAt(i); + switch (c) { + case '\\': + i++; // i += Character.charCount(c), but we know it's 1! + if (i >= s.length()) + throw new IllegalArgumentException("\\ at end of pattern"); + break; + case '[': + i = s.indexOf(']', i); + if (i < 0) + throw new IllegalArgumentException("[ without ]"); + break; + case '%': + s = s.substring(0, i) + "*" + s.substring(i + 1); + break; + case '_': + s = s.substring(0, i) + "?" + s.substring(i + 1); + break; + case '*': + case '?': + s = s.substring(0, i) + '\\' + (char) c + s.substring(i + 1); + i++; + break; + } + } + return Query.value(s); + } +} diff --git a/src/share/classes/javax/management/StringValueExp.java b/src/share/classes/javax/management/StringValueExp.java index 5e5202349f5d5eeb6f0d875a9c404fd7a3902219..40a9b2364d8bf8af7ddda578370e250fd618b018 100644 --- a/src/share/classes/javax/management/StringValueExp.java +++ b/src/share/classes/javax/management/StringValueExp.java @@ -73,7 +73,7 @@ public class StringValueExp implements ValueExp { * Returns the string representing the object. */ public String toString() { - return "'" + val + "'"; + return "'" + val.replace("'", "''") + "'"; } diff --git a/src/share/classes/javax/management/ToQueryString.java b/src/share/classes/javax/management/ToQueryString.java new file mode 100644 index 0000000000000000000000000000000000000000..be73bc5f3777c3a18ca9ecdc2a875826b75be8f1 --- /dev/null +++ b/src/share/classes/javax/management/ToQueryString.java @@ -0,0 +1,38 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management; + +/* QueryExp classes can extend this to get non-default treatment for + * Query.toString(q). We're reluctant to change the public toString() + * methods of the classes because people might be parsing them, even + * though that's rather fragile. But Query.toString(q) has no such + * constraint so it can use the new toQueryString() method defined here. + */ +class ToQueryString { + String toQueryString() { + return toString(); + } +} diff --git a/src/share/classes/javax/management/monitor/Monitor.java b/src/share/classes/javax/management/monitor/Monitor.java index 528e8c7fd1a2e266a23cf96e0a16bce495d499f7..5df59a7a20e5a1afa1cb36c1ec7c155ebfebbf66 100644 --- a/src/share/classes/javax/management/monitor/Monitor.java +++ b/src/share/classes/javax/management/monitor/Monitor.java @@ -27,13 +27,8 @@ package javax.management.monitor; import static com.sun.jmx.defaults.JmxProperties.MONITOR_LOGGER; import com.sun.jmx.mbeanserver.GetPropertyAction; -import com.sun.jmx.remote.util.EnvHelp; -import java.beans.BeanInfo; -import java.beans.Introspector; -import java.beans.PropertyDescriptor; +import com.sun.jmx.mbeanserver.Introspector; import java.io.IOException; -import java.lang.reflect.Array; -import java.lang.reflect.InvocationTargetException; import java.security.AccessControlContext; import java.security.AccessController; import java.security.PrivilegedAction; @@ -64,7 +59,6 @@ import javax.management.NotificationBroadcasterSupport; import javax.management.ObjectName; import javax.management.ReflectionException; import static javax.management.monitor.MonitorNotification.*; -import javax.management.openmbean.CompositeData; /** * Defines the part common to all monitor MBeans. @@ -876,44 +870,13 @@ public abstract class Monitor if (isComplexTypeAttribute) { Object v = value; for (String attr : remainingAttributes) - v = introspect(object, attr, v); + v = Introspector.elementFromComplex(v, attr); return (Comparable) v; } else { return (Comparable) value; } } - Object introspect(ObjectName object, - String attribute, - Object value) - throws AttributeNotFoundException { - try { - if (value.getClass().isArray() && attribute.equals("length")) { - return Array.getLength(value); - } else if (value instanceof CompositeData) { - return ((CompositeData) value).get(attribute); - } else { - // Java Beans introspection - // - BeanInfo bi = Introspector.getBeanInfo(value.getClass()); - PropertyDescriptor[] pds = bi.getPropertyDescriptors(); - for (PropertyDescriptor pd : pds) - if (pd.getName().equals(attribute)) - return pd.getReadMethod().invoke(value); - throw new AttributeNotFoundException( - "Could not find the getter method for the property " + - attribute + " using the Java Beans introspector"); - } - } catch (InvocationTargetException e) { - throw new IllegalArgumentException(e); - } catch (AttributeNotFoundException e) { - throw e; - } catch (Exception e) { - throw EnvHelp.initCause( - new AttributeNotFoundException(e.getMessage()), e); - } - } - boolean isComparableTypeValid(ObjectName object, String attribute, Comparable value) { diff --git a/src/share/classes/javax/management/remote/JMXServiceURL.java b/src/share/classes/javax/management/remote/JMXServiceURL.java index 5d5c799774e5b7f4298d2133df8f6b396a9620c0..3211c902b473f164afb5fb1dcd12cea90494cf59 100644 --- a/src/share/classes/javax/management/remote/JMXServiceURL.java +++ b/src/share/classes/javax/management/remote/JMXServiceURL.java @@ -30,6 +30,7 @@ package javax.management.remote; import com.sun.jmx.remote.util.ClassLogger; import com.sun.jmx.remote.util.EnvHelp; +import java.beans.ConstructorProperties; import java.io.Serializable; import java.net.InetAddress; import java.net.MalformedURLException; @@ -274,6 +275,7 @@ public class JMXServiceURL implements Serializable { * is not possible to find the local host name, or if * port is negative. */ + @ConstructorProperties({"protocol", "host", "port", "URLPath"}) public JMXServiceURL(String protocol, String host, int port, String urlPath) throws MalformedURLException { diff --git a/src/share/classes/javax/rmi/ssl/SslRMIClientSocketFactory.java b/src/share/classes/javax/rmi/ssl/SslRMIClientSocketFactory.java index cf569ef5bdeb4386195e409c3bb4ece8a5770d83..9d266fac8612e0d41d0bdab2d83f410edd50cc90 100644 --- a/src/share/classes/javax/rmi/ssl/SslRMIClientSocketFactory.java +++ b/src/share/classes/javax/rmi/ssl/SslRMIClientSocketFactory.java @@ -121,7 +121,7 @@ public class SslRMIClientSocketFactory sslSocketFactory.createSocket(host, port); // Set the SSLSocket Enabled Cipher Suites // - final String enabledCipherSuites = (String) + final String enabledCipherSuites = System.getProperty("javax.rmi.ssl.client.enabledCipherSuites"); if (enabledCipherSuites != null) { StringTokenizer st = new StringTokenizer(enabledCipherSuites, ","); @@ -139,7 +139,7 @@ public class SslRMIClientSocketFactory } // Set the SSLSocket Enabled Protocols // - final String enabledProtocols = (String) + final String enabledProtocols = System.getProperty("javax.rmi.ssl.client.enabledProtocols"); if (enabledProtocols != null) { StringTokenizer st = new StringTokenizer(enabledProtocols, ","); diff --git a/src/share/classes/javax/rmi/ssl/SslRMIServerSocketFactory.java b/src/share/classes/javax/rmi/ssl/SslRMIServerSocketFactory.java index 27e8b2f2af9197744858c218d90891fe66386ec2..802e1668b8631007f531d98a503bf6c9cb345597 100644 --- a/src/share/classes/javax/rmi/ssl/SslRMIServerSocketFactory.java +++ b/src/share/classes/javax/rmi/ssl/SslRMIServerSocketFactory.java @@ -165,9 +165,9 @@ public class SslRMIServerSocketFactory implements RMIServerSocketFactory { // Initialize the configuration parameters. // this.enabledCipherSuites = enabledCipherSuites == null ? - null : (String[]) enabledCipherSuites.clone(); + null : enabledCipherSuites.clone(); this.enabledProtocols = enabledProtocols == null ? - null : (String[]) enabledProtocols.clone(); + null : enabledProtocols.clone(); this.needClientAuth = needClientAuth; // Force the initialization of the default at construction time, @@ -196,13 +196,11 @@ public class SslRMIServerSocketFactory implements RMIServerSocketFactory { // if (this.enabledCipherSuites != null) { sslSocket.setEnabledCipherSuites(this.enabledCipherSuites); - enabledCipherSuitesList = - Arrays.asList((String[]) this.enabledCipherSuites); + enabledCipherSuitesList = Arrays.asList(this.enabledCipherSuites); } if (this.enabledProtocols != null) { sslSocket.setEnabledProtocols(this.enabledProtocols); - enabledProtocolsList = - Arrays.asList((String[]) this.enabledProtocols); + enabledProtocolsList = Arrays.asList(this.enabledProtocols); } } @@ -218,7 +216,7 @@ public class SslRMIServerSocketFactory implements RMIServerSocketFactory { */ public final String[] getEnabledCipherSuites() { return enabledCipherSuites == null ? - null : (String[]) enabledCipherSuites.clone(); + null : enabledCipherSuites.clone(); } /** @@ -234,7 +232,7 @@ public class SslRMIServerSocketFactory implements RMIServerSocketFactory { */ public final String[] getEnabledProtocols() { return enabledProtocols == null ? - null : (String[]) enabledProtocols.clone(); + null : enabledProtocols.clone(); } /** @@ -315,8 +313,8 @@ public class SslRMIServerSocketFactory implements RMIServerSocketFactory { (enabledCipherSuites != null && that.enabledCipherSuites == null)) return false; if (enabledCipherSuites != null && that.enabledCipherSuites != null) { - List thatEnabledCipherSuitesList = - Arrays.asList((String[]) that.enabledCipherSuites); + List thatEnabledCipherSuitesList = + Arrays.asList(that.enabledCipherSuites); if (!enabledCipherSuitesList.equals(thatEnabledCipherSuitesList)) return false; } @@ -327,8 +325,8 @@ public class SslRMIServerSocketFactory implements RMIServerSocketFactory { (enabledProtocols != null && that.enabledProtocols == null)) return false; if (enabledProtocols != null && that.enabledProtocols != null) { - List thatEnabledProtocolsList = - Arrays.asList((String[]) that.enabledProtocols); + List thatEnabledProtocolsList = + Arrays.asList(that.enabledProtocols); if (!enabledProtocolsList.equals(thatEnabledProtocolsList)) return false; } @@ -374,7 +372,7 @@ public class SslRMIServerSocketFactory implements RMIServerSocketFactory { private final String[] enabledCipherSuites; private final String[] enabledProtocols; private final boolean needClientAuth; - private List enabledCipherSuitesList; - private List enabledProtocolsList; + private List enabledCipherSuitesList; + private List enabledProtocolsList; private SSLContext context; } diff --git a/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java b/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java index 1879e5c4bf230b3e7e18b28b7c79f44d3346e212..394634249843c6f97a01080fc867126ab44a54c4 100644 --- a/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java +++ b/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java @@ -276,7 +276,7 @@ public class KerberosTicket implements Destroyable, Refreshable, if (flags != null) { if (flags.length >= NUM_FLAGS) - this.flags = (boolean[]) flags.clone(); + this.flags = flags.clone(); else { this.flags = new boolean[NUM_FLAGS]; // Fill in whatever we have @@ -304,7 +304,7 @@ public class KerberosTicket implements Destroyable, Refreshable, this.endTime = endTime; if (clientAddresses != null) - this.clientAddresses = (InetAddress[]) clientAddresses.clone(); + this.clientAddresses = clientAddresses.clone(); } /** @@ -430,7 +430,7 @@ public class KerberosTicket implements Destroyable, Refreshable, * @return the flags associated with this ticket. */ public final boolean[] getFlags() { - return (flags == null? null: (boolean[]) flags.clone()); + return (flags == null? null: flags.clone()); } /** @@ -479,8 +479,7 @@ public class KerberosTicket implements Destroyable, Refreshable, * provided. */ public final java.net.InetAddress[] getClientAddresses() { - return (clientAddresses == null? - null: (InetAddress[]) clientAddresses.clone()); + return (clientAddresses == null) ? null: clientAddresses.clone(); } /** @@ -491,7 +490,7 @@ public class KerberosTicket implements Destroyable, Refreshable, public final byte[] getEncoded() { if (destroyed) throw new IllegalStateException("This ticket is no longer valid"); - return (byte[]) asn1Encoding.clone(); + return asn1Encoding.clone(); } /** Determines if this ticket is still current. */ diff --git a/src/share/classes/javax/security/auth/kerberos/KeyImpl.java b/src/share/classes/javax/security/auth/kerberos/KeyImpl.java index 5937fd53cacbcd5cbd85e2dfd5bd0167983c0536..6fcffbdeecc6bdc4b6fb950e91348eabcf1efca4 100644 --- a/src/share/classes/javax/security/auth/kerberos/KeyImpl.java +++ b/src/share/classes/javax/security/auth/kerberos/KeyImpl.java @@ -66,7 +66,7 @@ class KeyImpl implements SecretKey, Destroyable, Serializable { */ public KeyImpl(byte[] keyBytes, int keyType) { - this.keyBytes = (byte[]) keyBytes.clone(); + this.keyBytes = keyBytes.clone(); this.keyType = keyType; } @@ -151,7 +151,7 @@ class KeyImpl implements SecretKey, Destroyable, Serializable { public final byte[] getEncoded() { if (destroyed) throw new IllegalStateException("This key is no longer valid"); - return (byte[])keyBytes.clone(); + return keyBytes.clone(); } public void destroy() throws DestroyFailedException { diff --git a/src/share/classes/javax/security/cert/X509Certificate.java b/src/share/classes/javax/security/cert/X509Certificate.java index e5849e5c5206ab53d732abf959c9a5a1f4318d13..14ccaffaffd2ee42ad97af29b89204ca3ea3c8f5 100644 --- a/src/share/classes/javax/security/cert/X509Certificate.java +++ b/src/share/classes/javax/security/cert/X509Certificate.java @@ -363,7 +363,7 @@ public abstract class X509Certificate extends Certificate { * subject Name * * - *

    See getIssuerDN for Name + *

    See {@link #getIssuerDN() getIssuerDN} for Name * and other relevant definitions. * * @return a Principal whose name is the subject name. @@ -393,7 +393,7 @@ public abstract class X509Certificate extends Certificate { /** * Gets the notAfter date from the validity period of - * the certificate. See getNotBefore + * the certificate. See {@link #getNotBefore() getNotBefore} * for relevant ASN.1 definitions. * * @return the end date of the validity period. @@ -429,7 +429,7 @@ public abstract class X509Certificate extends Certificate { * For example, the string "1.2.840.10040.4.3" identifies the SHA-1 * with DSA signature algorithm, as per the PKIX part I. * - *

    See getSigAlgName for + *

    See {@link #getSigAlgName() getSigAlgName} for * relevant ASN.1 definitions. * * @return the signature algorithm OID string. @@ -442,7 +442,7 @@ public abstract class X509Certificate extends Certificate { * algorithm parameters are null; the parameters are usually * supplied with the certificate's public key. * - *

    See getSigAlgName for + *

    See {@link #getSigAlgName() getSigAlgName} for * relevant ASN.1 definitions. * * @return the DER-encoded signature algorithm parameters, or diff --git a/src/share/classes/javax/swing/plaf/synth/doc-files/synth.dtd b/src/share/classes/javax/swing/plaf/synth/doc-files/synth.dtd index 5ac5a61f100e0dc2f6929c0df69b83549ebc1c9d..9188d43e2d4e6bc4e9ba7d86663e987883b33715 100644 --- a/src/share/classes/javax/swing/plaf/synth/doc-files/synth.dtd +++ b/src/share/classes/javax/swing/plaf/synth/doc-files/synth.dtd @@ -73,7 +73,7 @@ type (idref|boolean|dimension|insets|integer|string) "idref" value CDATA #REQUIRED > - + - - + + + - - -

    - Synth is a skinnable look and feel in which all painting is - delegated. Synth does not provide a default look. In - order to use Synth you need to specify a - file, or - provide a {@link - javax.swing.plaf.synth.SynthStyleFactory}. Both - configuration options require an - understanding of the synth architecture, which is described - below, as well as an understanding of Swing's architecture. -

    -

    - Unless otherwise specified null is not a legal value to any of - the methods defined in the synth package and if passed in will - result in a NullPointerException. - - -

    Synth

    -

    - Each {@link javax.swing.plaf.ComponentUI} implementation in Synth associates - itself with one {@link - javax.swing.plaf.synth.SynthStyle} per {@link - javax.swing.plaf.synth.Region}, most - Components only have one Region and - therefor only one SynthStyle. - SynthStyle - is used to access all style related properties: fonts, colors - and other Component properties. In addition - SynthStyles are used to obtain - {@link javax.swing.plaf.synth.SynthPainter}s for painting the background, border, - focus and other portions of a Component. The ComponentUIs obtain - SynthStyles from a - {@link javax.swing.plaf.synth.SynthStyleFactory}. - A SynthStyleFactory - can be provided directly by way of - {@link javax.swing.plaf.synth.SynthLookAndFeel#setStyleFactory(javax.swing.plaf.synth.SynthStyleFactory)}, - or indirectly by way of - {@link javax.swing.plaf.synth.SynthLookAndFeel#load}. The - following example uses the SynthLookAndFeel.load() - method to configure a SynthLookAndFeel and sets it - as the current look and feel: -

    -
    -
    -  SynthLookAndFeel laf = new SynthLookAndFeel();
    +
    +
    +    

    + Synth is a skinnable look and feel in which all painting is + delegated. Synth does not provide a default look. In + order to use Synth you need to specify a + file, or + provide a {@link + javax.swing.plaf.synth.SynthStyleFactory}. Both + configuration options require an + understanding of the synth architecture, which is described + below, as well as an understanding of Swing's architecture. +

    +

    + Unless otherwise specified null is not a legal value to any of + the methods defined in the synth package and if passed in will + result in a NullPointerException. + + +

    Synth

    +

    + Each {@link javax.swing.plaf.ComponentUI} implementation in Synth associates + itself with one {@link + javax.swing.plaf.synth.SynthStyle} per {@link + javax.swing.plaf.synth.Region}, most + Components only have one Region and + therefor only one SynthStyle. + SynthStyle + is used to access all style related properties: fonts, colors + and other Component properties. In addition + SynthStyles are used to obtain + {@link javax.swing.plaf.synth.SynthPainter}s for painting the background, border, + focus and other portions of a Component. The ComponentUIs obtain + SynthStyles from a + {@link javax.swing.plaf.synth.SynthStyleFactory}. + A SynthStyleFactory + can be provided directly by way of + {@link javax.swing.plaf.synth.SynthLookAndFeel#setStyleFactory(javax.swing.plaf.synth.SynthStyleFactory)}, + or indirectly by way of + {@link javax.swing.plaf.synth.SynthLookAndFeel#load}. The + following example uses the SynthLookAndFeel.load() + method to configure a SynthLookAndFeel and sets it + as the current look and feel: +

    +
    +
    +  SynthLookAndFeel laf = new SynthLookAndFeel();
       laf.load(MyClass.class.getResourceAsStream("laf.xml"), MyClass.class);
    -  UIManager.setLookAndFeel(laf);
    -      
    -
    -

    - Many JComponents are broken down into smaller - pieces and identified by the type safe enumeration in - {@link javax.swing.plaf.synth.Region}. For example, a JTabbedPane - consists of a Region for the - JTabbedPane ({@link - javax.swing.plaf.synth.Region#TABBED_PANE}), the content - area ({@link - javax.swing.plaf.synth.Region#TABBED_PANE_CONTENT}), the - area behind the tabs ({@link - javax.swing.plaf.synth.Region#TABBED_PANE_TAB_AREA}), and the - tabs ({@link - javax.swing.plaf.synth.Region#TABBED_PANE_TAB}). Each - Region of each - JComponent will have a - SynthStyle. This allows - you to customize individual pieces of each region of each - JComponent. -

    - Many of the Synth methods take a {@link javax.swing.plaf.synth.SynthContext}. This - is used to provide information about the current - Component and includes: the - {@link javax.swing.plaf.synth.SynthStyle} associated with the current - {@link javax.swing.plaf.synth.Region}, the state of the Component - as a bitmask (refer to {@link - javax.swing.plaf.synth.SynthConstants} for the valid - states), and a {@link javax.swing.plaf.synth.Region} identifying the portion of - the Component being painted. -

    - All text rendering by non-JTextComponents is - delegated to a {@link - javax.swing.plaf.synth.SynthGraphicsUtils}, which is - obtained using the {@link javax.swing.plaf.synth.SynthStyle} method - {@link javax.swing.plaf.synth.SynthStyle#getGraphicsUtils}. You can - customize text rendering - by supplying your own {@link javax.swing.plaf.synth.SynthGraphicsUtils}. - -

    - -

    Notes on specific components

    - -

    JTree

    -

    - Synth provides a region for the cells of a tree: - Region.TREE_CELL. To specify the colors of the - renderer you'll want to provide a style for the - TREE_CELL region. The following illustrates this: -

    -  <style id="treeCellStyle">
    -    <opaque value="TRUE"/>
    -    <state>
    -      <color value="WHITE" type="TEXT_FOREGROUND"/>
    -      <color value="RED" type="TEXT_BACKGROUND"/>
    -    </state>
    -    <state value="SELECTED">
    -      <color value="RED" type="TEXT_FOREGROUND"/>
    -      <color value="WHITE" type="BACKGROUND"/>
    -    </state>
    -  </style>
    -  <bind style="treeCellStyle" type="region" key="TreeCell"/>
    -
    -

    - This specifies a color combination of red on white, when - selected, and white on red when not selected. To see the - background you need to specify that labels are not opaque. The - following XML fragment does that: -

    -  <style id="labelStyle">
    -    <opaque value="FALSE"/>
    -  </style>
    -  <bind style="labelStyle" type="region" key="Label"/>
    -
    - -

    JList and JTable

    -

    - The colors that the renderers for JList and JTable use are - specified by way of the list and table Regions. The following - XML fragment illustrates how to specify red on white, when - selected, and white on red when not selected: -

    -  <style id="style">
    -    <opaque value="TRUE"/>
    -    <state>
    -      <color value="WHITE" type="TEXT_FOREGROUND"/>
    -      <color value="RED" type="TEXT_BACKGROUND"/>
    -      <color value="RED" type="BACKGROUND"/>
    -    </state>
    -    <state value="SELECTED">
    -      <color value="RED" type="TEXT_FOREGROUND"/>
    -      <color value="WHITE" type="TEXT_BACKGROUND"/>
    -    </state>
    -  </style>
    -  <bind style="style" type="region" key="Table"/>
    -  <bind style="style" type="region" key="List"/>
    -
    - - + UIManager.setLookAndFeel(laf); +
    +
    +

    + Many JComponents are broken down into smaller + pieces and identified by the type safe enumeration in + {@link javax.swing.plaf.synth.Region}. For example, a JTabbedPane + consists of a Region for the + JTabbedPane ({@link + javax.swing.plaf.synth.Region#TABBED_PANE}), the content + area ({@link + javax.swing.plaf.synth.Region#TABBED_PANE_CONTENT}), the + area behind the tabs ({@link + javax.swing.plaf.synth.Region#TABBED_PANE_TAB_AREA}), and the + tabs ({@link + javax.swing.plaf.synth.Region#TABBED_PANE_TAB}). Each + Region of each + JComponent will have a + SynthStyle. This allows + you to customize individual pieces of each region of each + JComponent. +

    + Many of the Synth methods take a {@link javax.swing.plaf.synth.SynthContext}. This + is used to provide information about the current + Component and includes: the + {@link javax.swing.plaf.synth.SynthStyle} associated with the current + {@link javax.swing.plaf.synth.Region}, the state of the Component + as a bitmask (refer to {@link + javax.swing.plaf.synth.SynthConstants} for the valid + states), and a {@link javax.swing.plaf.synth.Region} identifying the portion of + the Component being painted. +

    + All text rendering by non-JTextComponents is + delegated to a {@link + javax.swing.plaf.synth.SynthGraphicsUtils}, which is + obtained using the {@link javax.swing.plaf.synth.SynthStyle} method + {@link javax.swing.plaf.synth.SynthStyle#getGraphicsUtils}. You can + customize text rendering + by supplying your own {@link javax.swing.plaf.synth.SynthGraphicsUtils}. + +

    + +

    Notes on specific components

    + +

    JTree

    +

    + Synth provides a region for the cells of a tree: + Region.TREE_CELL. To specify the colors of the + renderer you'll want to provide a style for the + TREE_CELL region. The following illustrates this: +

    +  <style id="treeCellStyle">
    +    <opaque value="TRUE"/>
    +    <state>
    +      <color value="WHITE" type="TEXT_FOREGROUND"/>
    +      <color value="RED" type="TEXT_BACKGROUND"/>
    +    </state>
    +    <state value="SELECTED">
    +      <color value="RED" type="TEXT_FOREGROUND"/>
    +      <color value="WHITE" type="BACKGROUND"/>
    +    </state>
    +  </style>
    +  <bind style="treeCellStyle" type="region" key="TreeCell"/>
    +
    +

    + This specifies a color combination of red on white, when + selected, and white on red when not selected. To see the + background you need to specify that labels are not opaque. The + following XML fragment does that: +

    +  <style id="labelStyle">
    +    <opaque value="FALSE"/>
    +  </style>
    +  <bind style="labelStyle" type="region" key="Label"/>
    +
    + +

    JList and JTable

    +

    + The colors that the renderers for JList and JTable use are + specified by way of the list and table Regions. The following + XML fragment illustrates how to specify red on white, when + selected, and white on red when not selected: +

    +  <style id="style">
    +    <opaque value="TRUE"/>
    +    <state>
    +      <color value="WHITE" type="TEXT_FOREGROUND"/>
    +      <color value="RED" type="TEXT_BACKGROUND"/>
    +      <color value="RED" type="BACKGROUND"/>
    +    </state>
    +    <state value="SELECTED">
    +      <color value="RED" type="TEXT_FOREGROUND"/>
    +      <color value="WHITE" type="TEXT_BACKGROUND"/>
    +    </state>
    +  </style>
    +  <bind style="style" type="region" key="Table"/>
    +  <bind style="style" type="region" key="List"/>
    +
    + + diff --git a/src/share/classes/sun/awt/AppContext.java b/src/share/classes/sun/awt/AppContext.java index 038f5936aa534152911b942e49701cdcb3e1bfc9..4bdc337970bb822b519eaac21fb74dac4930a624 100644 --- a/src/share/classes/sun/awt/AppContext.java +++ b/src/share/classes/sun/awt/AppContext.java @@ -1,5 +1,5 @@ /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2008 Sun Microsystems, Inc. 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 @@ -40,6 +40,8 @@ import java.util.IdentityHashMap; import java.util.Map; import java.util.Set; import java.util.HashSet; +import java.util.logging.Level; +import java.util.logging.Logger; import java.beans.PropertyChangeSupport; import java.beans.PropertyChangeListener; @@ -126,6 +128,7 @@ import java.beans.PropertyChangeListener; * @author Fred Ecks */ public final class AppContext { + private static final Logger log = Logger.getLogger("sun.awt.AppContext"); /* Since the contents of an AppContext are unique to each Java * session, this class should never be serialized. */ @@ -143,13 +146,15 @@ public final class AppContext { * Returns a set containing all AppContexts. */ public static Set getAppContexts() { - return new HashSet(threadGroup2appContext.values()); + synchronized (threadGroup2appContext) { + return new HashSet(threadGroup2appContext.values()); + } } /* The main "system" AppContext, used by everything not otherwise contained in another AppContext. */ - private static AppContext mainAppContext = null; + private static volatile AppContext mainAppContext = null; /* * The hash map associated with this AppContext. A private delegate @@ -174,31 +179,30 @@ public final class AppContext { public static final String DISPOSED_PROPERTY_NAME = "disposed"; public static final String GUI_DISPOSED = "guidisposed"; - private boolean isDisposed = false; // true if AppContext is disposed + private volatile boolean isDisposed = false; // true if AppContext is disposed public boolean isDisposed() { return isDisposed; } - static { // On the main Thread, we get the ThreadGroup, make a corresponding // AppContext, and instantiate the Java EventQueue. This way, legacy // code is unaffected by the move to multiple AppContext ability. AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ThreadGroup currentThreadGroup = - Thread.currentThread().getThreadGroup(); - ThreadGroup parentThreadGroup = currentThreadGroup.getParent(); - while (parentThreadGroup != null) { - // Find the root ThreadGroup to construct our main AppContext - currentThreadGroup = parentThreadGroup; - parentThreadGroup = currentThreadGroup.getParent(); + public Object run() { + ThreadGroup currentThreadGroup = + Thread.currentThread().getThreadGroup(); + ThreadGroup parentThreadGroup = currentThreadGroup.getParent(); + while (parentThreadGroup != null) { + // Find the root ThreadGroup to construct our main AppContext + currentThreadGroup = parentThreadGroup; + parentThreadGroup = currentThreadGroup.getParent(); + } + mainAppContext = new AppContext(currentThreadGroup); + numAppContexts = 1; + return mainAppContext; } - mainAppContext = new AppContext(currentThreadGroup); - numAppContexts = 1; - return mainAppContext; - } }); } @@ -209,7 +213,7 @@ public final class AppContext { * number is 1. If so, it returns the sole AppContext without * checking Thread.currentThread(). */ - private static int numAppContexts; + private static volatile int numAppContexts; /* * The context ClassLoader that was used to create this AppContext. @@ -236,14 +240,15 @@ public final class AppContext { threadGroup2appContext.put(threadGroup, this); this.contextClassLoader = - (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public ClassLoader run() { return Thread.currentThread().getContextClassLoader(); } }); } - private static MostRecentThreadAppContext mostRecentThreadAppContext = null; + private static final ThreadLocal threadAppContext = + new ThreadLocal(); /** * Returns the appropriate AppContext for the caller, @@ -260,59 +265,46 @@ public final class AppContext { if (numAppContexts == 1) // If there's only one system-wide, return mainAppContext; // return the main system AppContext. - final Thread currentThread = Thread.currentThread(); - - AppContext appContext = null; - - // Note: this most recent Thread/AppContext caching is thread-hot. - // A simple test using SwingSet found that 96.8% of lookups - // were matched using the most recent Thread/AppContext. By - // instantiating a simple MostRecentThreadAppContext object on - // cache misses, the cache hits can be processed without - // synchronization. + AppContext appContext = threadAppContext.get(); + + if (null == appContext) { + appContext = AccessController.doPrivileged(new PrivilegedAction() + { + public AppContext run() { + // Get the current ThreadGroup, and look for it and its + // parents in the hash from ThreadGroup to AppContext -- + // it should be found, because we use createNewContext() + // when new AppContext objects are created. + ThreadGroup currentThreadGroup = Thread.currentThread().getThreadGroup(); + ThreadGroup threadGroup = currentThreadGroup; + AppContext context = threadGroup2appContext.get(threadGroup); + while (context == null) { + threadGroup = threadGroup.getParent(); + if (threadGroup == null) { + // If we get here, we're running under a ThreadGroup that + // has no AppContext associated with it. This should never + // happen, because createNewContext() should be used by the + // toolkit to create the ThreadGroup that everything runs + // under. + throw new RuntimeException("Invalid ThreadGroup"); + } + context = threadGroup2appContext.get(threadGroup); + } + // In case we did anything in the above while loop, we add + // all the intermediate ThreadGroups to threadGroup2appContext + // so we won't spin again. + for (ThreadGroup tg = currentThreadGroup; tg != threadGroup; tg = tg.getParent()) { + threadGroup2appContext.put(tg, context); + } + // Now we're done, so we cache the latest key/value pair. + // (we do this before checking with any AWTSecurityManager, so if + // this Thread equates with the main AppContext in the cache, it + // still will) + threadAppContext.set(context); - MostRecentThreadAppContext recent = mostRecentThreadAppContext; - if ((recent != null) && (recent.thread == currentThread)) { - appContext = recent.appContext; // Cache hit - } else { - appContext = (AppContext)AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - // Get the current ThreadGroup, and look for it and its - // parents in the hash from ThreadGroup to AppContext -- - // it should be found, because we use createNewContext() - // when new AppContext objects are created. - ThreadGroup currentThreadGroup = currentThread.getThreadGroup(); - ThreadGroup threadGroup = currentThreadGroup; - AppContext context = threadGroup2appContext.get(threadGroup); - while (context == null) { - threadGroup = threadGroup.getParent(); - if (threadGroup == null) { - // If we get here, we're running under a ThreadGroup that - // has no AppContext associated with it. This should never - // happen, because createNewContext() should be used by the - // toolkit to create the ThreadGroup that everything runs - // under. - throw new RuntimeException("Invalid ThreadGroup"); + return context; } - context = threadGroup2appContext.get(threadGroup); - } - // In case we did anything in the above while loop, we add - // all the intermediate ThreadGroups to threadGroup2appContext - // so we won't spin again. - for (ThreadGroup tg = currentThreadGroup; tg != threadGroup; tg = tg.getParent()) { - threadGroup2appContext.put(tg, context); - } - // Now we're done, so we cache the latest key/value pair. - // (we do this before checking with any AWTSecurityManager, so if - // this Thread equates with the main AppContext in the cache, it - // still will) - mostRecentThreadAppContext = - new MostRecentThreadAppContext(currentThread, context); - - return context; - } - }); + }); } if (appContext == mainAppContext) { @@ -321,9 +313,9 @@ public final class AppContext { // allow it to choose the AppContext to return. SecurityManager securityManager = System.getSecurityManager(); if ((securityManager != null) && - (securityManager instanceof AWTSecurityManager)) { - AWTSecurityManager awtSecMgr = - (AWTSecurityManager)securityManager; + (securityManager instanceof AWTSecurityManager)) + { + AWTSecurityManager awtSecMgr = (AWTSecurityManager)securityManager; AppContext secAppContext = awtSecMgr.getAppContext(); if (secAppContext != null) { appContext = secAppContext; // Return what we're told @@ -385,7 +377,13 @@ public final class AppContext { public void run() { Window[] windowsToDispose = Window.getOwnerlessWindows(); for (Window w : windowsToDispose) { - w.dispose(); + try { + w.dispose(); + } catch (Throwable t) { + if (log.isLoggable(Level.FINER)) { + log.log(Level.FINER, "exception occured while disposing app context", t); + } + } } AccessController.doPrivileged(new PrivilegedAction() { public Object run() { @@ -444,7 +442,7 @@ public final class AppContext { // Threads in the ThreadGroup to exit. long startTime = System.currentTimeMillis(); - long endTime = startTime + (long)THREAD_INTERRUPT_TIMEOUT; + long endTime = startTime + THREAD_INTERRUPT_TIMEOUT; while ((this.threadGroup.activeCount() > 0) && (System.currentTimeMillis() < endTime)) { try { @@ -459,7 +457,7 @@ public final class AppContext { // Threads in the ThreadGroup to die. startTime = System.currentTimeMillis(); - endTime = startTime + (long)THREAD_INTERRUPT_TIMEOUT; + endTime = startTime + THREAD_INTERRUPT_TIMEOUT; while ((this.threadGroup.activeCount() > 0) && (System.currentTimeMillis() < endTime)) { try { @@ -478,10 +476,7 @@ public final class AppContext { } threadGroup2appContext.remove(this.threadGroup); - MostRecentThreadAppContext recent = mostRecentThreadAppContext; - if ((recent != null) && (recent.appContext == this)) - mostRecentThreadAppContext = null; - // If the "most recent" points to this, clear it for GC + threadAppContext.set(null); // Finally, we destroy the ThreadGroup entirely. try { @@ -664,6 +659,7 @@ public final class AppContext { * Returns a string representation of this AppContext. * @since 1.2 */ + @Override public String toString() { return getClass().getName() + "[threadGroup=" + threadGroup.getName() + "]"; } @@ -769,15 +765,6 @@ public final class AppContext { } } -final class MostRecentThreadAppContext { - final Thread thread; - final AppContext appContext; - MostRecentThreadAppContext(Thread key, AppContext value) { - thread = key; - appContext = value; - } -} - final class MostRecentKeyValue { Object key; Object value; diff --git a/src/share/classes/sun/awt/datatransfer/DataTransferer.java b/src/share/classes/sun/awt/datatransfer/DataTransferer.java index 5dd12441081fb423244e530fb064e3ea880e6e8a..d96008309fb66cbdbe2083605fc844ddd81273f7 100644 --- a/src/share/classes/sun/awt/datatransfer/DataTransferer.java +++ b/src/share/classes/sun/awt/datatransfer/DataTransferer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. 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 @@ -270,62 +270,58 @@ public abstract class DataTransferer { * instead, null will be returned. */ public static DataTransferer getInstance() { - if (transferer == null) { - synchronized (DataTransferer.class) { - if (transferer == null) { - final String name = SunToolkit. - getDataTransfererClassName(); - if (name != null) { - PrivilegedAction action = new PrivilegedAction() { - public Object run() { - Class cls = null; - Method method = null; - Object ret = null; - - try { - cls = Class.forName(name); - } catch (ClassNotFoundException e) { - ClassLoader cl = ClassLoader. - getSystemClassLoader(); - if (cl != null) { - try { - cls = cl.loadClass(name); - } catch (ClassNotFoundException ee) { - ee.printStackTrace(); - throw new AWTError("DataTransferer not found: " + name); - } - } - } - if (cls != null) { + synchronized (DataTransferer.class) { + if (transferer == null) { + final String name = SunToolkit.getDataTransfererClassName(); + if (name != null) { + PrivilegedAction action = new PrivilegedAction() + { + public DataTransferer run() { + Class cls = null; + Method method = null; + DataTransferer ret = null; + + try { + cls = Class.forName(name); + } catch (ClassNotFoundException e) { + ClassLoader cl = ClassLoader. + getSystemClassLoader(); + if (cl != null) { try { - method = cls.getDeclaredMethod - ("getInstanceImpl"); - method.setAccessible(true); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - throw new AWTError("Cannot instantiate DataTransferer: " + name); - } catch (SecurityException e) { - e.printStackTrace(); - throw new AWTError("Access is denied for DataTransferer: " + name); + cls = cl.loadClass(name); + } catch (ClassNotFoundException ee) { + ee.printStackTrace(); + throw new AWTError("DataTransferer not found: " + name); } } - if (method != null) { - try { - ret = method.invoke(null); - } catch (InvocationTargetException e) { - e.printStackTrace(); - throw new AWTError("Cannot instantiate DataTransferer: " + name); - } catch (IllegalAccessException e) { - e.printStackTrace(); - throw new AWTError("Cannot access DataTransferer: " + name); - } + } + if (cls != null) { + try { + method = cls.getDeclaredMethod("getInstanceImpl"); + method.setAccessible(true); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + throw new AWTError("Cannot instantiate DataTransferer: " + name); + } catch (SecurityException e) { + e.printStackTrace(); + throw new AWTError("Access is denied for DataTransferer: " + name); } - return ret; } - }; - transferer = (DataTransferer) - AccessController.doPrivileged(action); - } + if (method != null) { + try { + ret = (DataTransferer) method.invoke(null); + } catch (InvocationTargetException e) { + e.printStackTrace(); + throw new AWTError("Cannot instantiate DataTransferer: " + name); + } catch (IllegalAccessException e) { + e.printStackTrace(); + throw new AWTError("Cannot access DataTransferer: " + name); + } + } + return ret; + } + }; + transferer = AccessController.doPrivileged(action); } } } diff --git a/src/share/classes/sun/management/ConnectorAddressLink.java b/src/share/classes/sun/management/ConnectorAddressLink.java index 58b1b3f5a70c8f8b626fc60b8b54f25b2fc51159..093746c3164770db825e7a06feff105aff8a996a 100644 --- a/src/share/classes/sun/management/ConnectorAddressLink.java +++ b/src/share/classes/sun/management/ConnectorAddressLink.java @@ -1,5 +1,5 @@ /* - * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2008 Sun Microsystems, Inc. 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 @@ -25,12 +25,13 @@ package sun.management; +import java.io.IOException; import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; import java.util.Iterator; -import java.util.Set; -import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; import sun.misc.Perf; import sun.management.counter.Units; @@ -46,36 +47,67 @@ import sun.management.counter.perf.PerfInstrumentation; public class ConnectorAddressLink { private static final String CONNECTOR_ADDRESS_COUNTER = - "sun.management.JMXConnectorServer.address"; + "sun.management.JMXConnectorServer.address"; + + /* + * The format of the jvmstat counters representing the properties of + * a given out-of-the-box JMX remote connector will be as follows: + * + * sun.management.JMXConnectorServer..= + * + * where: + * + * counter = index computed by this class which uniquely identifies + * an out-of-the-box JMX remote connector running in this + * Java virtual machine. + * key/value = a given key/value pair in the map supplied to the + * exportRemote() method. + * + * For example, + * + * sun.management.JMXConnectorServer.0.remoteAddress=service:jmx:rmi:///jndi/rmi://myhost:5000/jmxrmi + * sun.management.JMXConnectorServer.0.authenticate=false + * sun.management.JMXConnectorServer.0.ssl=false + * sun.management.JMXConnectorServer.0.sslRegistry=false + * sun.management.JMXConnectorServer.0.sslNeedClientAuth=false + */ + private static final String REMOTE_CONNECTOR_COUNTER_PREFIX = + "sun.management.JMXConnectorServer."; + + /* + * JMX remote connector counter (it will be incremented every + * time a new out-of-the-box JMX remote connector is created). + */ + private static AtomicInteger counter = new AtomicInteger(); /** * Exports the specified connector address to the instrumentation buffer * so that it can be read by this or other Java virtual machines running * on the same system. * - * @param address The connector address. + * @param address The connector address. */ public static void export(String address) { if (address == null || address.length() == 0) { throw new IllegalArgumentException("address not specified"); } Perf perf = Perf.getPerf(); - perf.createString(CONNECTOR_ADDRESS_COUNTER, 1, Units.STRING.intValue(), address); + perf.createString( + CONNECTOR_ADDRESS_COUNTER, 1, Units.STRING.intValue(), address); } /** * Imports the connector address from the instrument buffer * of the specified Java virtual machine. * - * @param vmid an identifier that uniquely identifies a local - * Java virtual machine, or 0 to indicate - * the current Java virtual machine. + * @param vmid an identifier that uniquely identifies a local Java virtual + * machine, or 0 to indicate the current Java virtual machine. * - * @return the value of the connector address, or null - * if the target VM has not exported a connector address. + * @return the value of the connector address, or null if the + * target VM has not exported a connector address. * - * @throws IOException An I/O error occurred while trying to acquire - * the instrumentation buffer. + * @throws IOException An I/O error occurred while trying to acquire the + * instrumentation buffer. */ public static String importFrom(int vmid) throws IOException { Perf perf = Perf.getPerf(); @@ -85,14 +117,65 @@ public class ConnectorAddressLink { } catch (IllegalArgumentException iae) { throw new IOException(iae.getMessage()); } - List counters = (new PerfInstrumentation(bb)).findByPattern(CONNECTOR_ADDRESS_COUNTER); + List counters = + new PerfInstrumentation(bb).findByPattern(CONNECTOR_ADDRESS_COUNTER); Iterator i = counters.iterator(); if (i.hasNext()) { - Counter c = (Counter)i.next(); - return (String)c.getValue(); + Counter c = (Counter) i.next(); + return (String) c.getValue(); } else { return null; } } + /** + * Exports the specified remote connector address and associated + * configuration properties to the instrumentation buffer so that + * it can be read by this or other Java virtual machines running + * on the same system. + * + * @param properties The remote connector address properties. + */ + public static void exportRemote(Map properties) { + final int index = counter.getAndIncrement(); + Perf perf = Perf.getPerf(); + for (Map.Entry entry : properties.entrySet()) { + perf.createString(REMOTE_CONNECTOR_COUNTER_PREFIX + index + "." + + entry.getKey(), 1, Units.STRING.intValue(), entry.getValue()); + } + } + + /** + * Imports the remote connector address and associated + * configuration properties from the instrument buffer + * of the specified Java virtual machine. + * + * @param vmid an identifier that uniquely identifies a local Java virtual + * machine, or 0 to indicate the current Java virtual machine. + * + * @return a map containing the remote connector's properties, or an empty + * map if the target VM has not exported the remote connector's properties. + * + * @throws IOException An I/O error occurred while trying to acquire the + * instrumentation buffer. + */ + public static Map importRemoteFrom(int vmid) throws IOException { + Perf perf = Perf.getPerf(); + ByteBuffer bb; + try { + bb = perf.attach(vmid, "r"); + } catch (IllegalArgumentException iae) { + throw new IOException(iae.getMessage()); + } + List counters = new PerfInstrumentation(bb).getAllCounters(); + Map properties = new HashMap(); + for (Object c : counters) { + String name = ((Counter) c).getName(); + if (name.startsWith(REMOTE_CONNECTOR_COUNTER_PREFIX) && + !name.equals(CONNECTOR_ADDRESS_COUNTER)) { + properties.put(name, ((Counter) c).getValue().toString()); + } + } + return properties; + } } diff --git a/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java b/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java index 0463db83f89002edeb7369ab1d8e2f9dda00ad5c..43cae9144e9b1077995a854f6c2bc45c67613ec7 100644 --- a/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java +++ b/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. 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 @@ -39,6 +39,7 @@ import java.rmi.NoSuchObjectException; import java.rmi.Remote; import java.rmi.RemoteException; import java.rmi.registry.Registry; +import java.rmi.server.RemoteObject; import java.rmi.server.RMIClientSocketFactory; import java.rmi.server.RMIServerSocketFactory; import java.rmi.server.UnicastRemoteObject; @@ -70,12 +71,14 @@ import javax.rmi.ssl.SslRMIServerSocketFactory; import javax.security.auth.Subject; +import sun.rmi.server.UnicastRef; import sun.rmi.server.UnicastServerRef; import sun.rmi.server.UnicastServerRef2; import sun.management.Agent; import sun.management.AgentConfigurationError; import static sun.management.AgentConfigurationError.*; +import sun.management.ConnectorAddressLink; import sun.management.FileSystem; import sun.management.snmp.util.MibLogger; @@ -92,20 +95,22 @@ public final class ConnectorBootstrap { * Default values for JMX configuration properties. **/ public static interface DefaultValues { - public static final String PORT="0"; - public static final String CONFIG_FILE_NAME="management.properties"; - public static final String USE_SSL="true"; - public static final String USE_REGISTRY_SSL="false"; - public static final String USE_AUTHENTICATION="true"; - public static final String PASSWORD_FILE_NAME="jmxremote.password"; - public static final String ACCESS_FILE_NAME="jmxremote.access"; - public static final String SSL_NEED_CLIENT_AUTH="false"; + + public static final String PORT = "0"; + public static final String CONFIG_FILE_NAME = "management.properties"; + public static final String USE_SSL = "true"; + public static final String USE_REGISTRY_SSL = "false"; + public static final String USE_AUTHENTICATION = "true"; + public static final String PASSWORD_FILE_NAME = "jmxremote.password"; + public static final String ACCESS_FILE_NAME = "jmxremote.access"; + public static final String SSL_NEED_CLIENT_AUTH = "false"; } /** * Names of JMX configuration properties. **/ public static interface PropertyNames { + public static final String PORT = "com.sun.management.jmxremote.port"; public static final String CONFIG_FILE_NAME = @@ -132,6 +137,21 @@ public final class ConnectorBootstrap { "com.sun.management.jmxremote.ssl.config.file"; } + /** + * JMXConnectorServer associated data. + */ + private static class JMXConnectorServerData { + + public JMXConnectorServerData( + JMXConnectorServer jmxConnectorServer, + JMXServiceURL jmxRemoteURL) { + this.jmxConnectorServer = jmxConnectorServer; + this.jmxRemoteURL = jmxRemoteURL; + } + JMXConnectorServer jmxConnectorServer; + JMXServiceURL jmxRemoteURL; + } + /** *

    Prevents our RMI server objects from keeping the JVM alive.

    * @@ -151,6 +171,7 @@ public final class ConnectorBootstrap { * works). Hence the somewhat misleading name of this class.

    */ private static class PermanentExporter implements RMIExporter { + public Remote exportObject(Remote obj, int port, RMIClientSocketFactory csf, @@ -158,24 +179,25 @@ public final class ConnectorBootstrap { throws RemoteException { synchronized (this) { - if (firstExported == null) + if (firstExported == null) { firstExported = obj; + } } final UnicastServerRef ref; - if (csf == null && ssf == null) + if (csf == null && ssf == null) { ref = new UnicastServerRef(port); - else + } else { ref = new UnicastServerRef2(port, csf, ssf); + } return ref.exportObject(obj, null, true); } // Nothing special to be done for this case public boolean unexportObject(Remote obj, boolean force) - throws NoSuchObjectException { + throws NoSuchObjectException { return UnicastRemoteObject.unexportObject(obj, force); } - Remote firstExported; } @@ -202,19 +224,21 @@ public final class ConnectorBootstrap { } private void checkAccessFileEntries(Subject subject) { - if (subject == null) + if (subject == null) { throw new SecurityException( "Access denied! No matching entries found in " + "the access file [" + accessFile + "] as the " + "authenticated Subject is null"); + } final Set principals = subject.getPrincipals(); - for (Iterator i = principals.iterator(); i.hasNext(); ) { + for (Iterator i = principals.iterator(); i.hasNext();) { final Principal p = (Principal) i.next(); - if (properties.containsKey(p.getName())) + if (properties.containsKey(p.getName())) { return; + } } final Set principalsStr = new HashSet(); - for (Iterator i = principals.iterator(); i.hasNext(); ) { + for (Iterator i = principals.iterator(); i.hasNext();) { final Principal p = (Principal) i.next(); principalsStr.add(p.getName()); } @@ -225,16 +249,16 @@ public final class ConnectorBootstrap { } private static Properties propertiesFromFile(String fname) - throws IOException { + throws IOException { Properties p = new Properties(); - if (fname == null) + if (fname == null) { return p; + } FileInputStream fin = new FileInputStream(fname); p.load(fin); fin.close(); return p; } - private final Map environment; private final Properties properties; private final String accessFile; @@ -251,22 +275,23 @@ public final class ConnectorBootstrap { // Load a new management properties final Properties props = Agent.loadManagementProperties(); - if (props == null) return null; + if (props == null) { + return null; + } final String portStr = props.getProperty(PropertyNames.PORT); // System.out.println("initializing: {port=" + portStr + ", // properties="+props+"}"); - return initialize(portStr,props); + return initialize(portStr, props); } /** * Initializes and starts a JMX Connector Server for remote * monitoring and management. **/ - public static synchronized - JMXConnectorServer initialize(String portStr, Properties props) { + public static synchronized JMXConnectorServer initialize(String portStr, Properties props) { // Get port number final int port; @@ -280,21 +305,21 @@ public final class ConnectorBootstrap { } // Do we use authentication? - final String useAuthenticationStr = + final String useAuthenticationStr = props.getProperty(PropertyNames.USE_AUTHENTICATION, DefaultValues.USE_AUTHENTICATION); final boolean useAuthentication = Boolean.valueOf(useAuthenticationStr).booleanValue(); // Do we use SSL? - final String useSslStr = + final String useSslStr = props.getProperty(PropertyNames.USE_SSL, DefaultValues.USE_SSL); final boolean useSsl = Boolean.valueOf(useSslStr).booleanValue(); // Do we use RMI Registry SSL? - final String useRegistrySslStr = + final String useRegistrySslStr = props.getProperty(PropertyNames.USE_REGISTRY_SSL, DefaultValues.USE_REGISTRY_SSL); final boolean useRegistrySsl = @@ -307,7 +332,7 @@ public final class ConnectorBootstrap { StringTokenizer st = new StringTokenizer(enabledCipherSuites, ","); int tokens = st.countTokens(); enabledCipherSuitesList = new String[tokens]; - for (int i = 0 ; i < tokens; i++) { + for (int i = 0; i < tokens; i++) { enabledCipherSuitesList[i] = st.nextToken(); } } @@ -319,12 +344,12 @@ public final class ConnectorBootstrap { StringTokenizer st = new StringTokenizer(enabledProtocols, ","); int tokens = st.countTokens(); enabledProtocolsList = new String[tokens]; - for (int i = 0 ; i < tokens; i++) { + for (int i = 0; i < tokens; i++) { enabledProtocolsList[i] = st.nextToken(); } } - final String sslNeedClientAuthStr = + final String sslNeedClientAuthStr = props.getProperty(PropertyNames.SSL_NEED_CLIENT_AUTH, DefaultValues.SSL_NEED_CLIENT_AUTH); final boolean sslNeedClientAuth = @@ -374,39 +399,49 @@ public final class ConnectorBootstrap { sslNeedClientAuth + "\n\t" + PropertyNames.USE_AUTHENTICATION + "=" + useAuthentication + - (useAuthentication ? - (loginConfigName == null ? - ("\n\t" + PropertyNames.PASSWORD_FILE_NAME + "=" + - passwordFileName) : - ("\n\t" + PropertyNames.LOGIN_CONFIG_NAME + "=" + + (useAuthentication ? (loginConfigName == null ? ("\n\t" + PropertyNames.PASSWORD_FILE_NAME + "=" + + passwordFileName) : ("\n\t" + PropertyNames.LOGIN_CONFIG_NAME + "=" + loginConfigName)) : "\n\t" + Agent.getText("jmxremote.ConnectorBootstrap.initialize.noAuthentication")) + - (useAuthentication ? - ("\n\t" + PropertyNames.ACCESS_FILE_NAME + "=" + + (useAuthentication ? ("\n\t" + PropertyNames.ACCESS_FILE_NAME + "=" + accessFileName) : "") + ""); } final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); JMXConnectorServer cs = null; + JMXServiceURL url = null; try { - cs = exportMBeanServer(mbs, port, useSsl, useRegistrySsl, + final JMXConnectorServerData data = exportMBeanServer( + mbs, port, useSsl, useRegistrySsl, sslConfigFileName, enabledCipherSuitesList, enabledProtocolsList, sslNeedClientAuth, useAuthentication, loginConfigName, passwordFileName, accessFileName); - - final JMXServiceURL url = cs.getAddress(); + cs = data.jmxConnectorServer; + url = data.jmxRemoteURL; log.config("initialize", Agent.getText("jmxremote.ConnectorBootstrap.initialize.ready", - new JMXServiceURL(url.getProtocol(), - url.getHost(), - url.getPort(), - "/jndi/rmi://"+url.getHost()+":"+port+"/"+ - "jmxrmi").toString())); + url.toString())); } catch (Exception e) { throw new AgentConfigurationError(AGENT_EXCEPTION, e, e.toString()); } + try { + // Export remote connector address and associated configuration + // properties to the instrumentation buffer. + Map properties = new HashMap(); + properties.put("remoteAddress", url.toString()); + properties.put("authenticate", useAuthenticationStr); + properties.put("ssl", useSslStr); + properties.put("sslRegistry", useRegistrySslStr); + properties.put("sslNeedClientAuth", sslNeedClientAuthStr); + ConnectorAddressLink.exportRemote(properties); + } catch (Exception e) { + // Remote connector server started but unable to export remote + // connector address and associated configuration properties to + // the instrumentation buffer - non-fatal error. + log.debug("initialize", e); + } return cs; } @@ -452,7 +487,7 @@ public final class ConnectorBootstrap { } private static void checkPasswordFile(String passwordFileName) { - if (passwordFileName == null || passwordFileName.length()==0) { + if (passwordFileName == null || passwordFileName.length() == 0) { throw new AgentConfigurationError(PASSWORD_FILE_NOT_SET); } File file = new File(passwordFileName); @@ -468,9 +503,9 @@ public final class ConnectorBootstrap { try { if (fs.supportsFileSecurity(file)) { if (!fs.isAccessUserOnly(file)) { - final String msg=Agent.getText("jmxremote.ConnectorBootstrap.initialize.password.readonly", + final String msg = Agent.getText("jmxremote.ConnectorBootstrap.initialize.password.readonly", passwordFileName); - log.config("initialize",msg); + log.config("initialize", msg); throw new AgentConfigurationError(PASSWORD_FILE_ACCESS_NOT_RESTRICTED, passwordFileName); } @@ -482,7 +517,7 @@ public final class ConnectorBootstrap { } private static void checkAccessFile(String accessFileName) { - if (accessFileName == null || accessFileName.length()==0) { + if (accessFileName == null || accessFileName.length() == 0) { throw new AgentConfigurationError(ACCESS_FILE_NOT_SET); } File file = new File(accessFileName); @@ -619,7 +654,7 @@ public final class ConnectorBootstrap { } } - private static JMXConnectorServer exportMBeanServer( + private static JMXConnectorServerData exportMBeanServer( MBeanServer mbs, int port, boolean useSsl, @@ -697,24 +732,30 @@ public final class ConnectorBootstrap { } final Registry registry; - if (useRegistrySsl) + if (useRegistrySsl) { registry = new SingleEntryRegistry(port, csf, ssf, "jmxrmi", exporter.firstExported); - else + } else { registry = new SingleEntryRegistry(port, "jmxrmi", exporter.firstExported); + } + + JMXServiceURL remoteURL = new JMXServiceURL( + "service:jmx:rmi:///jndi/rmi://" + url.getHost() + ":" + + ((UnicastRef) ((RemoteObject) registry).getRef()).getLiveRef().getPort() + + "/jmxrmi"); /* Our exporter remembers the first object it was asked to - export, which will be an RMIServerImpl appropriate for - publication in our special registry. We could - alternatively have constructed the RMIServerImpl explicitly - and then constructed an RMIConnectorServer passing it as a - parameter, but that's quite a bit more verbose and pulls in - lots of knowledge of the RMI connector. */ - - return connServer; + export, which will be an RMIServerImpl appropriate for + publication in our special registry. We could + alternatively have constructed the RMIServerImpl explicitly + and then constructed an RMIConnectorServer passing it as a + parameter, but that's quite a bit more verbose and pulls in + lots of knowledge of the RMI connector. */ + + return new JMXConnectorServerData(connServer, remoteURL); } /** @@ -726,5 +767,4 @@ public final class ConnectorBootstrap { // XXX Revisit: should probably clone this MibLogger.... private static final MibLogger log = new MibLogger(ConnectorBootstrap.class); - } diff --git a/src/share/classes/sun/management/snmp/jvminstr/JvmMemPoolEntryImpl.java b/src/share/classes/sun/management/snmp/jvminstr/JvmMemPoolEntryImpl.java index 156813969f9a06ad1f910cd19505c5973dba4f37..0863148f916086ed63a7bed939509313b9b50c68 100644 --- a/src/share/classes/sun/management/snmp/jvminstr/JvmMemPoolEntryImpl.java +++ b/src/share/classes/sun/management/snmp/jvminstr/JvmMemPoolEntryImpl.java @@ -26,7 +26,6 @@ package sun.management.snmp.jvminstr; // java imports // -import java.io.Serializable; import java.util.Map; // jmx imports @@ -36,9 +35,7 @@ import com.sun.jmx.snmp.SnmpDefinitions; // jdmk imports // -import com.sun.jmx.snmp.agent.SnmpMib; -import java.lang.management.ManagementFactory; import java.lang.management.MemoryUsage; import java.lang.management.MemoryType; import java.lang.management.MemoryPoolMXBean; @@ -73,7 +70,9 @@ public class JvmMemPoolEntryImpl implements JvmMemPoolEntryMBean { "jvmMemPoolEntry.getCollectionUsage"; final static MemoryUsage ZEROS = new MemoryUsage(0,0,0,0); - + final String entryMemoryTag; + final String entryPeakMemoryTag; + final String entryCollectMemoryTag; MemoryUsage getMemoryUsage() { try { @@ -81,17 +80,17 @@ public class JvmMemPoolEntryImpl implements JvmMemPoolEntryMBean { if (m != null) { final MemoryUsage cached = (MemoryUsage) - m.get(memoryTag); + m.get(entryMemoryTag); if (cached != null) { - log.debug("getMemoryUsage", - "jvmMemPoolEntry.getUsage found in cache."); + log.debug("getMemoryUsage",entryMemoryTag+ + " found in cache."); return cached; } MemoryUsage u = pool.getUsage(); if (u == null) u = ZEROS; - m.put(memoryTag,u); + m.put(entryMemoryTag,u); return u; } // Should never come here. @@ -113,18 +112,18 @@ public class JvmMemPoolEntryImpl implements JvmMemPoolEntryMBean { if (m != null) { final MemoryUsage cached = (MemoryUsage) - m.get(peakMemoryTag); + m.get(entryPeakMemoryTag); if (cached != null) { if (log.isDebugOn()) log.debug("getPeakMemoryUsage", - peakMemoryTag + " found in cache."); + entryPeakMemoryTag + " found in cache."); return cached; } MemoryUsage u = pool.getPeakUsage(); if (u == null) u = ZEROS; - m.put(peakMemoryTag,u); + m.put(entryPeakMemoryTag,u); return u; } // Should never come here. @@ -146,18 +145,18 @@ public class JvmMemPoolEntryImpl implements JvmMemPoolEntryMBean { if (m != null) { final MemoryUsage cached = (MemoryUsage) - m.get(collectMemoryTag); + m.get(entryCollectMemoryTag); if (cached != null) { if (log.isDebugOn()) log.debug("getCollectMemoryUsage", - collectMemoryTag + " found in cache."); + entryCollectMemoryTag + " found in cache."); return cached; } MemoryUsage u = pool.getCollectionUsage(); if (u == null) u = ZEROS; - m.put(collectMemoryTag,u); + m.put(entryCollectMemoryTag,u); return u; } // Should never come here. @@ -179,9 +178,12 @@ public class JvmMemPoolEntryImpl implements JvmMemPoolEntryMBean { /** * Constructor for the "JvmMemPoolEntry" group. */ - public JvmMemPoolEntryImpl(MemoryPoolMXBean mp, int index) { + public JvmMemPoolEntryImpl(MemoryPoolMXBean mp, final int index) { this.pool=mp; this.jvmMemPoolIndex = index; + this.entryMemoryTag = memoryTag + "." + index; + this.entryPeakMemoryTag = peakMemoryTag + "." + index; + this.entryCollectMemoryTag = collectMemoryTag + "." + index; } /** diff --git a/src/share/classes/sun/misc/ClassFileTransformer.java b/src/share/classes/sun/misc/ClassFileTransformer.java index a0d2c84ed6f3d17af6c6facaa3ee60580c69d0f0..1d05f71cc8a649113d32af1f6432b8e184aee532 100644 --- a/src/share/classes/sun/misc/ClassFileTransformer.java +++ b/src/share/classes/sun/misc/ClassFileTransformer.java @@ -46,8 +46,10 @@ public abstract class ClassFileTransformer { // Singleton of ClassFileTransformer // - private static ArrayList transformerList = new ArrayList(); - private static Object[] transformers = new Object[0]; + private static ArrayList transformerList + = new ArrayList(); + private static ClassFileTransformer[] transformers + = new ClassFileTransformer[0]; /** * Add the class file transformer object. @@ -59,7 +61,7 @@ public abstract class ClassFileTransformer synchronized(transformerList) { transformerList.add(t); - transformers = transformerList.toArray(); + transformers = transformerList.toArray(new ClassFileTransformer[0]); } } @@ -68,7 +70,7 @@ public abstract class ClassFileTransformer * * @return ClassFileTransformer object array */ - public static Object[] getTransformers() + public static ClassFileTransformer[] getTransformers() { // transformers is not intended to be changed frequently, // so it is okay to not put synchronized block here diff --git a/src/share/classes/sun/misc/Cleaner.java b/src/share/classes/sun/misc/Cleaner.java index c6cd63697b41c866a9f1911aaa1b7262a464ee00..036b6c94cd0d4d24d7eafc902838edbd1eeacfef 100644 --- a/src/share/classes/sun/misc/Cleaner.java +++ b/src/share/classes/sun/misc/Cleaner.java @@ -141,8 +141,8 @@ public class Cleaner try { thunk.run(); } catch (final Throwable x) { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { if (System.err != null) new Error("Cleaner terminated abnormally", x) .printStackTrace(); diff --git a/src/share/classes/sun/misc/ExtensionDependency.java b/src/share/classes/sun/misc/ExtensionDependency.java index ce2df19f3eabc17b30c8b96eaad7e3977d6cf3da..67012641e6278f542bf377112bcebe30e5fc2cab 100644 --- a/src/share/classes/sun/misc/ExtensionDependency.java +++ b/src/share/classes/sun/misc/ExtensionDependency.java @@ -284,10 +284,9 @@ public class ExtensionDependency { // Load the jar file ... Manifest man; try { - man = (Manifest) AccessController.doPrivileged - ( - new PrivilegedExceptionAction() { - public Object run() + man = AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Manifest run() throws IOException, FileNotFoundException { if (!file.exists()) throw new FileNotFoundException(file.getName()); @@ -391,9 +390,9 @@ public class ExtensionDependency { final String extName = extensionName; final String[] fileExt = {".jar", ".zip"}; - return (File) AccessController.doPrivileged - (new PrivilegedAction() { - public Object run() { + return AccessController.doPrivileged( + new PrivilegedAction() { + public File run() { try { File fExtension; File[] dirs = getExtDirs(); @@ -460,7 +459,7 @@ public class ExtensionDependency { * @return the list of files installed in all the directories */ private static File[] getExtFiles(File[] dirs) throws IOException { - Vector urls = new Vector(); + Vector urls = new Vector(); for (int i = 0; i < dirs.length; i++) { String[] files = dirs[i].list(new JarFilter()); if (files != null) { @@ -484,16 +483,15 @@ public class ExtensionDependency { *

    */ private File[] getInstalledExtensions() throws IOException { - return (File[]) AccessController.doPrivileged - ( - new PrivilegedAction() { - public Object run() { + return AccessController.doPrivileged( + new PrivilegedAction() { + public File[] run() { try { return getExtFiles(getExtDirs()); } catch(IOException e) { debug("Cannot get list of installed extensions"); debugException(e); - return new URL[0]; + return new File[0]; } } }); diff --git a/src/share/classes/sun/misc/GC.java b/src/share/classes/sun/misc/GC.java index b3fd3f97712b4f466a8e7a478de2a66f5e2818a6..477b5ffad915c45c2d478b6a21da3a0bc881d1b7 100644 --- a/src/share/classes/sun/misc/GC.java +++ b/src/share/classes/sun/misc/GC.java @@ -128,8 +128,8 @@ public class GC { /* Create a new daemon thread in the root thread group */ public static void create() { - PrivilegedAction pa = new PrivilegedAction() { - public Object run() { + PrivilegedAction pa = new PrivilegedAction() { + public Void run() { ThreadGroup tg = Thread.currentThread().getThreadGroup(); for (ThreadGroup tgn = tg; tgn != null; @@ -170,13 +170,14 @@ public class GC { * method. Given a request, the only interesting operation is that of * cancellation. */ - public static class LatencyRequest implements Comparable { + public static class LatencyRequest + implements Comparable { /* Instance counter, used to generate unique identifers */ private static long counter = 0; /* Sorted set of active latency requests */ - private static SortedSet requests = null; + private static SortedSet requests = null; /* Examine the request set and reset the latency target if necessary. * Must be invoked while holding the lock. @@ -187,7 +188,7 @@ public class GC { setLatencyTarget(NO_TARGET); } } else { - LatencyRequest r = (LatencyRequest)requests.first(); + LatencyRequest r = requests.first(); if (r.latency != latencyTarget) { setLatencyTarget(r.latency); } @@ -211,7 +212,7 @@ public class GC { synchronized (lock) { this.id = ++counter; if (requests == null) { - requests = new TreeSet(); + requests = new TreeSet(); } requests.add(this); adjustLatencyIfNeeded(); @@ -240,8 +241,7 @@ public class GC { } } - public int compareTo(Object o) { - LatencyRequest r = (LatencyRequest)o; + public int compareTo(LatencyRequest r) { long d = this.latency - r.latency; if (d == 0) d = this.id - r.id; return (d < 0) ? -1 : ((d > 0) ? +1 : 0); diff --git a/src/share/classes/sun/misc/JavaIOFileDescriptorAccess.java b/src/share/classes/sun/misc/JavaIOFileDescriptorAccess.java index 874145c629019e32099f476b7b9f49f30fe67cdb..42f3ea1ae6627cbd815f99242bdedadfd76202e7 100644 --- a/src/share/classes/sun/misc/JavaIOFileDescriptorAccess.java +++ b/src/share/classes/sun/misc/JavaIOFileDescriptorAccess.java @@ -33,4 +33,8 @@ import java.io.FileDescriptor; public interface JavaIOFileDescriptorAccess { public void set(FileDescriptor obj, int fd); public int get(FileDescriptor fd); + + // Only valid on Windows + public void setHandle(FileDescriptor obj, long handle); + public long getHandle(FileDescriptor obj); } diff --git a/src/share/classes/sun/misc/Launcher.java b/src/share/classes/sun/misc/Launcher.java index fca6609043372757bd2648bf77cdc53bfbb6c9f3..26f84d6281973d1a4790217e7847f72127cb2b81 100644 --- a/src/share/classes/sun/misc/Launcher.java +++ b/src/share/classes/sun/misc/Launcher.java @@ -135,9 +135,9 @@ public class Launcher { // aa synthesized ACC via a call to the private method // ExtClassLoader.getContext(). - return (ExtClassLoader) AccessController.doPrivileged( - new PrivilegedExceptionAction() { - public Object run() throws IOException { + return AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public ExtClassLoader run() throws IOException { int len = dirs.length; for (int i = 0; i < len; i++) { MetaIndex.registerDirectory(dirs[i]); @@ -180,7 +180,7 @@ public class Launcher { } private static URL[] getExtURLs(File[] dirs) throws IOException { - Vector urls = new Vector(); + Vector urls = new Vector(); for (int i = 0; i < dirs.length; i++) { String[] files = dirs[i].list(); if (files != null) { @@ -261,9 +261,9 @@ public class Launcher { // when loading classes. Specifically it prevent // accessClassInPackage.sun.* grants from being honored. // - return (AppClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + return AccessController.doPrivileged( + new PrivilegedAction() { + public AppClassLoader run() { URL[] urls = (s == null) ? new URL[0] : pathToURLs(path); return new AppClassLoader(urls, extcl); @@ -348,12 +348,12 @@ public class Launcher { URL[] urls; if (prop != null) { final String path = prop; - urls = (URL[])AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { + urls = AccessController.doPrivileged( + new PrivilegedAction() { + public URL[] run() { File[] classPath = getClassPath(path); int len = classPath.length; - Set seenDirs = new HashSet(); + Set seenDirs = new HashSet(); for (int i = 0; i < len; i++) { File curEntry = classPath[i]; // Negative test used to properly handle @@ -509,8 +509,8 @@ class PathPermissions extends PermissionCollection { perms.add(new java.util.PropertyPermission("java.*", SecurityConstants.PROPERTY_READ_ACTION)); - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { for (int i=0; i < path.length; i++) { File f = path[i]; String path; @@ -553,7 +553,7 @@ class PathPermissions extends PermissionCollection { return perms.implies(permission); } - public java.util.Enumeration elements() { + public java.util.Enumeration elements() { if (perms == null) init(); synchronized (perms) { diff --git a/src/share/classes/sun/misc/PerformanceLogger.java b/src/share/classes/sun/misc/PerformanceLogger.java index 5f1218453885312f9ededf8c13147f16f7e3fb53..e23a0f1abb40a30268a4f7c05cde4eaa77718610 100644 --- a/src/share/classes/sun/misc/PerformanceLogger.java +++ b/src/share/classes/sun/misc/PerformanceLogger.java @@ -78,7 +78,7 @@ public class PerformanceLogger { private static boolean perfLoggingOn = false; private static boolean useNanoTime = false; - private static Vector times; + private static Vector times; private static String logFileName = null; private static Writer logWriter = null; @@ -104,8 +104,8 @@ public class PerformanceLogger { if (logFileName != null) { if (logWriter == null) { java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Void run() { try { File logFile = new File(logFileName); logFile.createNewFile(); @@ -124,7 +124,7 @@ public class PerformanceLogger { logWriter = new OutputStreamWriter(System.out); } } - times = new Vector(10); + times = new Vector(10); // Reserve predefined slots for (int i = 0; i <= LAST_RESERVED; ++i) { times.add(new TimeData("Time " + i + " not set", 0)); @@ -207,7 +207,7 @@ public class PerformanceLogger { */ public static long getStartTime() { if (loggingEnabled()) { - return ((TimeData)times.get(START_INDEX)).getTime(); + return times.get(START_INDEX).getTime(); } else { return 0; } @@ -253,7 +253,7 @@ public class PerformanceLogger { */ public static long getTimeAtIndex(int index) { if (loggingEnabled()) { - return ((TimeData)times.get(index)).getTime(); + return times.get(index).getTime(); } else { return 0; } @@ -264,7 +264,7 @@ public class PerformanceLogger { */ public static String getMessageAtIndex(int index) { if (loggingEnabled()) { - return ((TimeData)times.get(index)).getMessage(); + return times.get(index).getMessage(); } else { return null; } @@ -278,7 +278,7 @@ public class PerformanceLogger { try { synchronized(times) { for (int i = 0; i < times.size(); ++i) { - TimeData td = (TimeData)times.get(i); + TimeData td = times.get(i); if (td != null) { writer.write(i + " " + td.getMessage() + ": " + td.getTime() + "\n"); diff --git a/src/share/classes/sun/misc/ProxyGenerator.java b/src/share/classes/sun/misc/ProxyGenerator.java index 42350461eca7eba8383a243a7a6bb4c90304af7a..d25a87c1b4a33dc4210def1bd3a8740cfaae872d 100644 --- a/src/share/classes/sun/misc/ProxyGenerator.java +++ b/src/share/classes/sun/misc/ProxyGenerator.java @@ -324,8 +324,8 @@ public class ProxyGenerator { if (saveGeneratedFiles) { java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Void run() { try { FileOutputStream file = new FileOutputStream(dotToSlash(name) + ".class"); @@ -576,7 +576,7 @@ public class ProxyGenerator { * compatibly with the throws clauses of both * overridden methods. */ - List legalExceptions = new ArrayList(); + List> legalExceptions = new ArrayList>(); collectCompatibleTypes( exceptionTypes, pm.exceptionTypes, legalExceptions); collectCompatibleTypes( @@ -618,11 +618,11 @@ public class ProxyGenerator { * List of return types that are not yet known to be * assignable from ("covered" by) any of the others. */ - LinkedList uncoveredReturnTypes = new LinkedList(); + LinkedList> uncoveredReturnTypes = new LinkedList>(); nextNewReturnType: for (ProxyMethod pm : methods) { - Class newReturnType = pm.returnType; + Class newReturnType = pm.returnType; if (newReturnType.isPrimitive()) { throw new IllegalArgumentException( "methods with same signature " + @@ -637,9 +637,9 @@ public class ProxyGenerator { * Compare the new return type to the existing uncovered * return types. */ - ListIterator liter = uncoveredReturnTypes.listIterator(); + ListIterator> liter = uncoveredReturnTypes.listIterator(); while (liter.hasNext()) { - Class uncoveredReturnType = liter.next(); + Class uncoveredReturnType = liter.next(); /* * If an existing uncovered return type is assignable @@ -944,10 +944,10 @@ public class ProxyGenerator { tryEnd = pc = (short) minfo.code.size(); - List catchList = computeUniqueCatchList(exceptionTypes); + List> catchList = computeUniqueCatchList(exceptionTypes); if (catchList.size() > 0) { - for (Class ex : catchList) { + for (Class ex : catchList) { minfo.exceptionTable.add(new ExceptionTableEntry( tryBegin, tryEnd, pc, cp.getClass(dotToSlash(ex.getName())))); @@ -1521,8 +1521,9 @@ public class ProxyGenerator { * declared exceptions from duplicate methods inherited from * different interfaces. */ - private static void collectCompatibleTypes(Class[] from, Class[] with, - List list) + private static void collectCompatibleTypes(Class[] from, + Class[] with, + List> list) { for (int i = 0; i < from.length; i++) { if (!list.contains(from[i])) { @@ -1557,8 +1558,8 @@ public class ProxyGenerator { * given list of declared exceptions, indicating that no exceptions * need to be caught. */ - private static List computeUniqueCatchList(Class[] exceptions) { - List uniqueList = new ArrayList(); + private static List> computeUniqueCatchList(Class[] exceptions) { + List> uniqueList = new ArrayList>(); // unique exceptions to catch uniqueList.add(Error.class); // always catch/rethrow these @@ -1566,7 +1567,7 @@ public class ProxyGenerator { nextException: for (int i = 0; i < exceptions.length; i++) { - Class ex = exceptions[i]; + Class ex = exceptions[i]; if (ex.isAssignableFrom(Throwable.class)) { /* * If Throwable is declared to be thrown by the proxy method, @@ -1586,7 +1587,7 @@ public class ProxyGenerator { * exceptions that need to be caught: */ for (int j = 0; j < uniqueList.size();) { - Class ex2 = uniqueList.get(j); + Class ex2 = uniqueList.get(j); if (ex2.isAssignableFrom(ex)) { /* * if a superclass of this exception is already on diff --git a/src/share/classes/sun/misc/URLClassPath.java b/src/share/classes/sun/misc/URLClassPath.java index 3aefe401db8577d82584d462f269167d902f1d82..b3bd6d38a9e9736218a63e0a9bcbf200688f6ea3 100644 --- a/src/share/classes/sun/misc/URLClassPath.java +++ b/src/share/classes/sun/misc/URLClassPath.java @@ -86,16 +86,16 @@ public class URLClassPath { } /* The original search path of URLs. */ - private ArrayList path = new ArrayList(); + private ArrayList path = new ArrayList(); /* The stack of unopened URLs */ - Stack urls = new Stack(); + Stack urls = new Stack(); /* The resulting search path of Loaders */ - ArrayList loaders = new ArrayList(); + ArrayList loaders = new ArrayList(); /* Map of each URL opened to its corresponding Loader */ - HashMap lmap = new HashMap(); + HashMap lmap = new HashMap(); /* The jar protocol handler to use when creating new URLs */ private URLStreamHandler jarHandler; @@ -146,7 +146,7 @@ public class URLClassPath { */ public URL[] getURLs() { synchronized (urls) { - return (URL[])path.toArray(new URL[path.size()]); + return path.toArray(new URL[path.size()]); } } @@ -200,9 +200,9 @@ public class URLClassPath { * @param name the resource name * @return an Enumeration of all the urls having the specified name */ - public Enumeration findResources(final String name, + public Enumeration findResources(final String name, final boolean check) { - return new Enumeration() { + return new Enumeration() { private int index = 0; private URL url = null; @@ -225,7 +225,7 @@ public class URLClassPath { return next(); } - public Object nextElement() { + public URL nextElement() { if (!next()) { throw new NoSuchElementException(); } @@ -247,9 +247,9 @@ public class URLClassPath { * @param name the resource name * @return an Enumeration of all the resources having the specified name */ - public Enumeration getResources(final String name, + public Enumeration getResources(final String name, final boolean check) { - return new Enumeration() { + return new Enumeration() { private int index = 0; private Resource res = null; @@ -272,7 +272,7 @@ public class URLClassPath { return next(); } - public Object nextElement() { + public Resource nextElement() { if (!next()) { throw new NoSuchElementException(); } @@ -283,7 +283,7 @@ public class URLClassPath { }; } - public Enumeration getResources(final String name) { + public Enumeration getResources(final String name) { return getResources(name, true); } @@ -302,7 +302,7 @@ public class URLClassPath { if (urls.empty()) { return null; } else { - url = (URL)urls.pop(); + url = urls.pop(); } } // Skip this URL if it already has a Loader. (Loader @@ -329,7 +329,7 @@ public class URLClassPath { loaders.add(loader); lmap.put(url, loader); } - return (Loader)loaders.get(index); + return loaders.get(index); } /* @@ -337,9 +337,9 @@ public class URLClassPath { */ private Loader getLoader(final URL url) throws IOException { try { - return (Loader)java.security.AccessController.doPrivileged - (new java.security.PrivilegedExceptionAction() { - public Object run() throws IOException { + return java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction() { + public Loader run() throws IOException { String file = url.getFile(); if (file != null && file.endsWith("/")) { if ("file".equals(url.getProtocol())) { @@ -561,13 +561,14 @@ public class URLClassPath { private JarIndex index; private MetaIndex metaIndex; private URLStreamHandler handler; - private HashMap lmap; + private HashMap lmap; /* * Creates a new JarLoader for the specified URL referring to * a JAR file. */ - JarLoader(URL url, URLStreamHandler jarHandler, HashMap loaderMap) + JarLoader(URL url, URLStreamHandler jarHandler, + HashMap loaderMap) throws IOException { super(new URL("jar", "", -1, url + "!/", jarHandler)); @@ -615,8 +616,8 @@ public class URLClassPath { if (jar == null) { try { java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { - public Object run() throws IOException { + new java.security.PrivilegedExceptionAction() { + public Void run() throws IOException { if (DEBUG) { System.err.println("Opening " + csu); Thread.dumpStack(); @@ -732,9 +733,9 @@ public class URLClassPath { String entryName; ZipEntry entry; - Enumeration enum_ = jar.entries(); + Enumeration enum_ = jar.entries(); while (enum_.hasMoreElements()) { - entry = (ZipEntry)enum_.nextElement(); + entry = enum_.nextElement(); entryName = entry.getName(); if((pos = entryName.lastIndexOf("/")) != -1) entryName = entryName.substring(0, pos); @@ -778,7 +779,7 @@ public class URLClassPath { if (index == null) return null; - HashSet visited = new HashSet(); + HashSet visited = new HashSet(); return getResource(name, check, visited); } @@ -790,7 +791,7 @@ public class URLClassPath { * non-existent resource */ Resource getResource(final String name, boolean check, - Set visited) { + Set visited) { Resource res; Object[] jarFiles; @@ -819,10 +820,9 @@ public class URLClassPath { /* no loader has been set up for this jar file * before */ - newLoader = (JarLoader) - AccessController.doPrivileged( - new PrivilegedExceptionAction() { - public Object run() throws IOException { + newLoader = AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public JarLoader run() throws IOException { return new JarLoader(url, handler, lmap); } diff --git a/src/share/classes/sun/net/NetProperties.java b/src/share/classes/sun/net/NetProperties.java index c2c7eb54e2a83ee8a2212a4781624631fee61209..a94f20c2ae3fb2aeaae3d841b5c623f59694196b 100644 --- a/src/share/classes/sun/net/NetProperties.java +++ b/src/share/classes/sun/net/NetProperties.java @@ -42,8 +42,8 @@ public class NetProperties { static private Properties props = new Properties(); static { AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { + new PrivilegedAction() { + public Void run() { loadDefaultProperties(); return null; }}); diff --git a/src/share/classes/sun/net/NetworkClient.java b/src/share/classes/sun/net/NetworkClient.java index 6e49e4c30fdc3d1308f89b465e4ed65d49ae0449..321b71bf6504aeca934c7440ee3fc4fb5e8d7fbf 100644 --- a/src/share/classes/sun/net/NetworkClient.java +++ b/src/share/classes/sun/net/NetworkClient.java @@ -64,8 +64,8 @@ public class NetworkClient { final String encs[] = { null }; AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { + new PrivilegedAction() { + public Void run() { vals[0] = Integer.getInteger("sun.net.client.defaultReadTimeout", 0).intValue(); vals[1] = Integer.getInteger("sun.net.client.defaultConnectTimeout", 0).intValue(); encs[0] = System.getProperty("file.encoding", "ISO8859_1"); @@ -152,9 +152,9 @@ public class NetworkClient { Socket s; if (proxy != null) { if (proxy.type() == Proxy.Type.SOCKS) { - s = (Socket) AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { + s = AccessController.doPrivileged( + new PrivilegedAction() { + public Socket run() { return new Socket(proxy); }}); } else diff --git a/src/share/classes/sun/net/ftp/FtpClient.java b/src/share/classes/sun/net/ftp/FtpClient.java index 52458a68870adf85c58dfcf3701bea9ca52ff3c5..9a7c99d517d7f1a9749b40a04d32d58070e10210 100644 --- a/src/share/classes/sun/net/ftp/FtpClient.java +++ b/src/share/classes/sun/net/ftp/FtpClient.java @@ -117,8 +117,8 @@ public class FtpClient extends TransferProtocolClient { public static int getFtpProxyPort() { final int result[] = {80}; java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Void run() { String tmp = System.getProperty("ftp.proxyPort"); if (tmp == null) { @@ -343,9 +343,9 @@ public class FtpClient extends TransferProtocolClient { Socket s; if (proxy != null) { if (proxy.type() == Proxy.Type.SOCKS) { - s = (Socket) AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { + s = AccessController.doPrivileged( + new PrivilegedAction() { + public Socket run() { return new Socket(proxy); }}); } else diff --git a/src/share/classes/sun/net/spi/DefaultProxySelector.java b/src/share/classes/sun/net/spi/DefaultProxySelector.java index 425c884fef63ba14c8856ad05312b28cb67a5d09..6d69c49bfb6c8685d057088e2d74f4314b99c6b1 100644 --- a/src/share/classes/sun/net/spi/DefaultProxySelector.java +++ b/src/share/classes/sun/net/spi/DefaultProxySelector.java @@ -82,9 +82,9 @@ public class DefaultProxySelector extends ProxySelector { static { final String key = "java.net.useSystemProxies"; - Boolean b = (Boolean) AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { + Boolean b = AccessController.doPrivileged( + new PrivilegedAction() { + public Boolean run() { return NetProperties.getBoolean(key); }}); if (b != null && b.booleanValue()) { @@ -197,9 +197,9 @@ public class DefaultProxySelector extends ProxySelector { * System properties it does help having only 1 call to doPrivileged. * Be mindful what you do in here though! */ - Proxy p = (Proxy) AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { + Proxy p = AccessController.doPrivileged( + new PrivilegedAction() { + public Proxy run() { int i, j; String phost = null; int pport = 0; diff --git a/src/share/classes/sun/net/www/MessageHeader.java b/src/share/classes/sun/net/www/MessageHeader.java index 02fb42cd4b5cb582227e75a1b5f1de442e851821..c02374d589eee4bd432aed4b4d14eb705a0fd7e5 100644 --- a/src/share/classes/sun/net/www/MessageHeader.java +++ b/src/share/classes/sun/net/www/MessageHeader.java @@ -138,7 +138,7 @@ class MessageHeader { return null; } - class HeaderIterator implements Iterator { + class HeaderIterator implements Iterator { int index = 0; int next = -1; String key; @@ -165,7 +165,7 @@ class MessageHeader { return false; } } - public Object next() { + public String next() { synchronized (lock) { if (haveNext) { haveNext = false; @@ -187,17 +187,17 @@ class MessageHeader { * return an Iterator that returns all values of a particular * key in sequence */ - public Iterator multiValueIterator (String k) { + public Iterator multiValueIterator (String k) { return new HeaderIterator (k, this); } - public synchronized Map getHeaders() { + public synchronized Map> getHeaders() { return getHeaders(null); } - public synchronized Map getHeaders(String[] excludeList) { + public synchronized Map> getHeaders(String[] excludeList) { boolean skipIt = false; - Map m = new HashMap(); + Map> m = new HashMap>(); for (int i = nkeys; --i >= 0;) { if (excludeList != null) { // check if the key is in the excludeList. @@ -211,9 +211,9 @@ class MessageHeader { } } if (!skipIt) { - List l = (List)m.get(keys[i]); + List l = m.get(keys[i]); if (l == null) { - l = new ArrayList(); + l = new ArrayList(); m.put(keys[i], l); } l.add(values[i]); @@ -223,11 +223,8 @@ class MessageHeader { } } - Set keySet = m.keySet(); - for (Iterator i = keySet.iterator(); i.hasNext();) { - Object key = i.next(); - List l = (List)m.get(key); - m.put(key, Collections.unmodifiableList(l)); + for (String key : m.keySet()) { + m.put(key, Collections.unmodifiableList(m.get(key))); } return Collections.unmodifiableMap(m); diff --git a/src/share/classes/sun/net/www/MimeTable.java b/src/share/classes/sun/net/www/MimeTable.java index 291cf0586eb37dc9d0708c789ca50bf09efcd048..6018fbf464147051c228f652c7dbb531d747f5ac 100644 --- a/src/share/classes/sun/net/www/MimeTable.java +++ b/src/share/classes/sun/net/www/MimeTable.java @@ -37,18 +37,20 @@ import java.util.StringTokenizer; public class MimeTable implements FileNameMap { /** Keyed by content type, returns MimeEntries */ - private Hashtable entries = new Hashtable(); + private Hashtable entries + = new Hashtable(); /** Keyed by file extension (with the .), returns MimeEntries */ - private Hashtable extensionMap = new Hashtable(); + private Hashtable extensionMap + = new Hashtable(); // Will be reset if in the platform-specific data file private static String tempFileTemplate; static { java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Void run() { tempFileTemplate = System.getProperty("content.types.temp.file.template", "/tmp/%s"); @@ -60,7 +62,8 @@ public class MimeTable implements FileNameMap { "/usr/etc/mailcap", "/usr/local/etc/mailcap", System.getProperty("hotjava.home", - "/usr/local/hotjava") + "/lib/mailcap", + "/usr/local/hotjava") + + "/lib/mailcap", }; return null; } @@ -83,8 +86,8 @@ public class MimeTable implements FileNameMap { public static MimeTable getDefaultTable() { if (defaultInstance == null) { java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Void run() { defaultInstance = new MimeTable(); URLConnection.setFileNameMap(defaultInstance); return null; @@ -130,7 +133,7 @@ public class MimeTable implements FileNameMap { } public synchronized MimeEntry remove(String type) { - MimeEntry entry = (MimeEntry)entries.get(type); + MimeEntry entry = entries.get(type); return remove(entry); } @@ -142,16 +145,16 @@ public class MimeTable implements FileNameMap { } } - return (MimeEntry)entries.remove(entry.getType()); + return entries.remove(entry.getType()); } public synchronized MimeEntry find(String type) { - MimeEntry entry = (MimeEntry)entries.get(type); + MimeEntry entry = entries.get(type); if (entry == null) { // try a wildcard lookup - Enumeration e = entries.elements(); + Enumeration e = entries.elements(); while (e.hasMoreElements()) { - MimeEntry wild = (MimeEntry)e.nextElement(); + MimeEntry wild = e.nextElement(); if (wild.matches(type)) { return wild; } @@ -191,13 +194,13 @@ public class MimeTable implements FileNameMap { * with it. */ public synchronized MimeEntry findByExt(String fileExtension) { - return (MimeEntry)extensionMap.get(fileExtension); + return extensionMap.get(fileExtension); } public synchronized MimeEntry findByDescription(String description) { - Enumeration e = elements(); + Enumeration e = elements(); while (e.hasMoreElements()) { - MimeEntry entry = (MimeEntry)e.nextElement(); + MimeEntry entry = e.nextElement(); if (description.equals(entry.getDescription())) { return entry; } @@ -211,7 +214,7 @@ public class MimeTable implements FileNameMap { return tempFileTemplate; } - public synchronized Enumeration elements() { + public synchronized Enumeration elements() { return entries.elements(); } @@ -269,7 +272,7 @@ public class MimeTable implements FileNameMap { } // now, parse the mime-type spec's - Enumeration types = entries.propertyNames(); + Enumeration types = entries.propertyNames(); while (types.hasMoreElements()) { String type = (String)types.nextElement(); String attrs = entries.getProperty(type); @@ -392,9 +395,9 @@ public class MimeTable implements FileNameMap { public Properties getAsProperties() { Properties properties = new Properties(); - Enumeration e = elements(); + Enumeration e = elements(); while (e.hasMoreElements()) { - MimeEntry entry = (MimeEntry)e.nextElement(); + MimeEntry entry = e.nextElement(); properties.put(entry.getType(), entry.toProperty()); } diff --git a/src/share/classes/sun/net/www/http/ChunkedOutputStream.java b/src/share/classes/sun/net/www/http/ChunkedOutputStream.java index a06b5afe22867fc2f7c7f883a667014ec3b489e7..5f4a7902f622b51fa7747cfac62bac70318a6d6c 100644 --- a/src/share/classes/sun/net/www/http/ChunkedOutputStream.java +++ b/src/share/classes/sun/net/www/http/ChunkedOutputStream.java @@ -177,14 +177,23 @@ public class ChunkedOutputStream extends PrintStream { return; } - if (len > MAX_BUF_SIZE) { + int l = preferredChunkSize - count; + + if ((len > MAX_BUF_SIZE) && (len > l)) { + /* current chunk is empty just write the data */ + if (count == 0) { + count = len; + flush (b, false, off); + return; + } + /* first finish the current chunk */ - int l = preferredChunkSize - count; if (l > 0) { System.arraycopy(b, off, buf, count, l); count = preferredChunkSize; flush(buf, false); } + count = len - l; /* Now write the rest of the data */ flush (b, false, l+off); diff --git a/src/share/classes/sun/net/www/http/HttpClient.java b/src/share/classes/sun/net/www/http/HttpClient.java index 674a88336e460200110c26272d760a85f959b91f..7f0cf0d427329213bed55c796557aa09735b3add 100644 --- a/src/share/classes/sun/net/www/http/HttpClient.java +++ b/src/share/classes/sun/net/www/http/HttpClient.java @@ -230,9 +230,9 @@ public class HttpClient extends NetworkClient { setConnectTimeout(to); // get the cookieHandler if there is any - cookieHandler = (CookieHandler)java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + cookieHandler = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public CookieHandler run() { return CookieHandler.getDefault(); } }); @@ -297,7 +297,7 @@ public class HttpClient extends NetworkClient { HttpClient ret = null; /* see if one's already around */ if (useCache) { - ret = (HttpClient) kac.get(url, null); + ret = kac.get(url, null); if (ret != null) { if ((ret.proxy != null && ret.proxy.equals(p)) || (ret.proxy == null && p == null)) { @@ -389,7 +389,7 @@ public class HttpClient extends NetworkClient { * cache). */ public void closeIdleConnection() { - HttpClient http = (HttpClient) kac.get(url, null); + HttpClient http = kac.get(url, null); if (http != null) { http.closeServer(); } @@ -447,8 +447,8 @@ public class HttpClient extends NetworkClient { { try { java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { - public Object run() throws IOException { + new java.security.PrivilegedExceptionAction() { + public Void run() throws IOException { openServer(server.getHostString(), server.getPort()); return null; } @@ -477,9 +477,8 @@ public class HttpClient extends NetworkClient { { try { java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { - public Object run() throws IOException - { + new java.security.PrivilegedExceptionAction() { + public Void run() throws IOException { superOpenServer(proxyHost, proxyPort); return null; } @@ -686,7 +685,7 @@ public class HttpClient extends NetworkClient { // So we do put the cast in as a workaround until // it is resolved. if (uri != null) - cookieHandler.put(uri, (Map>)responses.getHeaders()); + cookieHandler.put(uri, responses.getHeaders()); } /* decide if we're keeping alive: diff --git a/src/share/classes/sun/net/www/http/KeepAliveCache.java b/src/share/classes/sun/net/www/http/KeepAliveCache.java index 1226b2510136de22b047a576fa985ed25fa3e171..93882397a112ad4619ef141758bef4470cf4a5d8 100644 --- a/src/share/classes/sun/net/www/http/KeepAliveCache.java +++ b/src/share/classes/sun/net/www/http/KeepAliveCache.java @@ -38,7 +38,9 @@ import java.util.concurrent.ConcurrentHashMap; * @author Stephen R. Pietrowicz (NCSA) * @author Dave Brown */ -public class KeepAliveCache extends ConcurrentHashMap implements Runnable { +public class KeepAliveCache + extends ConcurrentHashMap + implements Runnable { private static final long serialVersionUID = -2937172892064557949L; /* maximum # keep-alive connections to maintain at once @@ -88,12 +90,12 @@ public class KeepAliveCache extends ConcurrentHashMap implements Runnable { * back from the server. If I'm connected through a Netscape proxy * to a server that sent me a keep-alive * time of 15 sec, the proxy unilaterally terminates my connection - * The robustness to to get around this is in HttpClient.parseHTTP() + * The robustness to get around this is in HttpClient.parseHTTP() */ final KeepAliveCache cache = this; java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Void run() { // We want to create the Keep-Alive-Timer in the // system threadgroup ThreadGroup grp = Thread.currentThread().getThreadGroup(); @@ -112,7 +114,7 @@ public class KeepAliveCache extends ConcurrentHashMap implements Runnable { } KeepAliveKey key = new KeepAliveKey(url, obj); - ClientVector v = (ClientVector)super.get(key); + ClientVector v = super.get(key); if (v == null) { int keepAliveTimeout = http.getKeepAliveTimeout(); @@ -125,10 +127,10 @@ public class KeepAliveCache extends ConcurrentHashMap implements Runnable { } } - /* remove an obsolete HttpClient from it's VectorCache */ + /* remove an obsolete HttpClient from its VectorCache */ public synchronized void remove (HttpClient h, Object obj) { KeepAliveKey key = new KeepAliveKey(h.url, obj); - ClientVector v = (ClientVector)super.get(key); + ClientVector v = super.get(key); if (v != null) { v.remove(h); if (v.empty()) { @@ -137,7 +139,7 @@ public class KeepAliveCache extends ConcurrentHashMap implements Runnable { } } - /* called by a clientVector thread when all it's connections have timed out + /* called by a clientVector thread when all its connections have timed out * and that vector of connections should be removed. */ synchronized void removeVector(KeepAliveKey k) { @@ -147,10 +149,10 @@ public class KeepAliveCache extends ConcurrentHashMap implements Runnable { /** * Check to see if this URL has a cached HttpClient */ - public synchronized Object get(URL url, Object obj) { + public synchronized HttpClient get(URL url, Object obj) { KeepAliveKey key = new KeepAliveKey(url, obj); - ClientVector v = (ClientVector)super.get(key); + ClientVector v = super.get(key); if (v == null) { // nothing in cache yet return null; } @@ -180,17 +182,16 @@ public class KeepAliveCache extends ConcurrentHashMap implements Runnable { long currentTime = System.currentTimeMillis(); - Iterator itr = keySet().iterator(); - ArrayList keysToRemove = new ArrayList(); + ArrayList keysToRemove + = new ArrayList(); - while (itr.hasNext()) { - KeepAliveKey key = (KeepAliveKey)itr.next(); - ClientVector v = (ClientVector)get(key); + for (KeepAliveKey key : keySet()) { + ClientVector v = get(key); synchronized (v) { int i; for (i = 0; i < v.size(); i++) { - KeepAliveEntry e = (KeepAliveEntry)v.elementAt(i); + KeepAliveEntry e = v.elementAt(i); if ((currentTime - e.idleStartTime) > v.nap) { HttpClient h = e.hc; h.closeServer(); @@ -205,9 +206,9 @@ public class KeepAliveCache extends ConcurrentHashMap implements Runnable { } } } - itr = keysToRemove.iterator(); - while (itr.hasNext()) { - removeVector((KeepAliveKey)itr.next()); + + for (KeepAliveKey key : keysToRemove) { + removeVector(key); } } } while (size() > 0); @@ -234,7 +235,7 @@ public class KeepAliveCache extends ConcurrentHashMap implements Runnable { */ -class ClientVector extends java.util.Stack { +class ClientVector extends java.util.Stack { private static final long serialVersionUID = -8680532108106489459L; // sleep time in milliseconds, before cache clear @@ -254,7 +255,7 @@ class ClientVector extends java.util.Stack { HttpClient hc = null; long currentTime = System.currentTimeMillis(); do { - KeepAliveEntry e = (KeepAliveEntry)pop(); + KeepAliveEntry e = pop(); if ((currentTime - e.idleStartTime) > nap) { e.hc.closeServer(); } else { diff --git a/src/share/classes/sun/net/www/http/KeepAliveStream.java b/src/share/classes/sun/net/www/http/KeepAliveStream.java index 779afb5ad7ba988d2163077e02e08e878ec67453..08fc3b03b17f210cfc23852ee1596a8d6ab24181 100644 --- a/src/share/classes/sun/net/www/http/KeepAliveStream.java +++ b/src/share/classes/sun/net/www/http/KeepAliveStream.java @@ -174,8 +174,8 @@ class KeepAliveStream extends MeteredStream implements Hurryable { if (startCleanupThread) { java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Void run() { // We want to create the Keep-Alive-SocketCleaner in the // system threadgroup ThreadGroup grp = Thread.currentThread().getThreadGroup(); diff --git a/src/share/classes/sun/net/www/http/KeepAliveStreamCleaner.java b/src/share/classes/sun/net/www/http/KeepAliveStreamCleaner.java index 779e38ac9ea94cc00522c822ab35606edf278104..3ae7cff0fdf97d36b9b6bc1ef69e35ef8d753ca9 100644 --- a/src/share/classes/sun/net/www/http/KeepAliveStreamCleaner.java +++ b/src/share/classes/sun/net/www/http/KeepAliveStreamCleaner.java @@ -59,19 +59,19 @@ public class KeepAliveStreamCleaner extends LinkedBlockingQueue() { + public Integer run() { + return NetProperties.getInteger(maxDataKey, MAX_DATA_REMAINING); + }}).intValue() * 1024; MAX_DATA_REMAINING = maxData; final String maxCapacityKey = "http.KeepAlive.queuedConnections"; - int maxCapacity = ((Integer) AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - return new Integer(NetProperties.getInteger(maxCapacityKey, MAX_CAPACITY)); - }})).intValue(); + int maxCapacity = AccessController.doPrivileged( + new PrivilegedAction() { + public Integer run() { + return NetProperties.getInteger(maxCapacityKey, MAX_CAPACITY); + }}).intValue(); MAX_CAPACITY = maxCapacity; } diff --git a/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java b/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java index 44473d421d829ee580fe1d3ada25a99493be81b4..3661090f806dce4ed926f9f5da7ee125f8c96376 100644 --- a/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java +++ b/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java @@ -215,12 +215,11 @@ public class FtpURLConnection extends URLConnection { Proxy p = null; if (instProxy == null) { // no per connection proxy specified /** - * Do we have to use a proxie? + * Do we have to use a proxy? */ - ProxySelector sel = (ProxySelector) - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + ProxySelector sel = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public ProxySelector run() { return ProxySelector.getDefault(); } }); diff --git a/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index fb1f3b05ed14a9adf96fd7039fb60ad60d2351b2..ef439005318a8152e9a447124dda5c8d2ad23811 100644 --- a/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -64,11 +64,6 @@ import java.text.SimpleDateFormat; import java.util.TimeZone; import java.net.MalformedURLException; import java.nio.ByteBuffer; -import java.nio.channels.ReadableByteChannel; -import java.nio.channels.WritableByteChannel; -import java.nio.channels.Selector; -import java.nio.channels.SelectionKey; -import java.nio.channels.SelectableChannel; import java.lang.reflect.*; /** @@ -144,8 +139,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection { static { maxRedirects = java.security.AccessController.doPrivileged( - new sun.security.action.GetIntegerAction("http.maxRedirects", - defaultmaxRedirects)).intValue(); + new sun.security.action.GetIntegerAction( + "http.maxRedirects", defaultmaxRedirects)).intValue(); version = java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("java.version")); String agent = java.security.AccessController.doPrivileged( @@ -291,10 +286,9 @@ public class HttpURLConnection extends java.net.HttpURLConnection { final String scheme, final URL url, final RequestorType authType) { - return (PasswordAuthentication) - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + return java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public PasswordAuthentication run() { return Authenticator.requestPasswordAuthentication( host, addr, port, protocol, prompt, scheme, url, authType); @@ -559,15 +553,15 @@ public class HttpURLConnection extends java.net.HttpURLConnection { responses = new MessageHeader(); this.handler = handler; instProxy = p; - cookieHandler = (CookieHandler)java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + cookieHandler = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public CookieHandler run() { return CookieHandler.getDefault(); } }); - cacheHandler = (ResponseCache)java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + cacheHandler = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public ResponseCache run() { return ResponseCache.getDefault(); } }); @@ -650,8 +644,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection { final boolean result[] = {false}; java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Void run() { try { InetAddress a1 = InetAddress.getByName(h1); InetAddress a2 = InetAddress.getByName(h2); @@ -729,10 +723,10 @@ public class HttpURLConnection extends java.net.HttpURLConnection { /** * Do we have to use a proxy? */ - ProxySelector sel = (ProxySelector) + ProxySelector sel = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public ProxySelector run() { return ProxySelector.getDefault(); } }); @@ -824,6 +818,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * - get input, [read input,] get output, [write output] */ + @Override public synchronized OutputStream getOutputStream() throws IOException { try { @@ -908,30 +903,28 @@ public class HttpURLConnection extends java.net.HttpURLConnection { URI uri = ParseUtil.toURI(url); if (uri != null) { - Map cookies = cookieHandler.get(uri, requests.getHeaders(EXCLUDE_HEADERS)); + Map> cookies + = cookieHandler.get( + uri, requests.getHeaders(EXCLUDE_HEADERS)); if (!cookies.isEmpty()) { - Set s = cookies.entrySet(); - Iterator k_itr = s.iterator(); - while (k_itr.hasNext()) { - Map.Entry entry = (Map.Entry)k_itr.next(); - String key = (String)entry.getKey(); + for (Map.Entry> entry : + cookies.entrySet()) { + String key = entry.getKey(); // ignore all entries that don't have "Cookie" // or "Cookie2" as keys if (!"Cookie".equalsIgnoreCase(key) && !"Cookie2".equalsIgnoreCase(key)) { continue; } - List l = (List)entry.getValue(); + List l = entry.getValue(); if (l != null && !l.isEmpty()) { - Iterator v_itr = l.iterator(); StringBuilder cookieValue = new StringBuilder(); - while (v_itr.hasNext()) { - String value = (String)v_itr.next(); - cookieValue.append(value).append(';'); + for (String value : l) { + cookieValue.append(value).append("; "); } - // strip off the ending ;-sign + // strip off the trailing '; ' try { - requests.add(key, cookieValue.substring(0, cookieValue.length() - 1)); + requests.add(key, cookieValue.substring(0, cookieValue.length() - 2)); } catch (StringIndexOutOfBoundsException ignored) { // no-op } @@ -950,6 +943,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection { } // end of getting cookies } + @Override + @SuppressWarnings("empty-statement") public synchronized InputStream getInputStream() throws IOException { if (!doInput) { @@ -1363,29 +1358,27 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * original exception and with the same message. Right now, * there is no convenient APIs for doing so. */ - private IOException getChainedException(IOException rememberedException) { + private IOException getChainedException(final IOException rememberedException) { try { - final IOException originalException = rememberedException; - final Class[] cls = new Class[1]; - cls[0] = String.class; - final String[] args = new String[1]; - args[0] = originalException.getMessage(); - IOException chainedException = (IOException) - java.security.AccessController.doPrivileged - (new java.security.PrivilegedExceptionAction() { - public Object run() - throws Exception { - Constructor ctr = originalException.getClass().getConstructor(cls); - return (IOException)ctr.newInstance((Object[])args); + final Object[] args = { rememberedException.getMessage() }; + IOException chainedException = + java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction() { + public IOException run() throws Exception { + return (IOException) + rememberedException.getClass() + .getConstructor(new Class[] { String.class }) + .newInstance(args); } }); - chainedException.initCause(originalException); + chainedException.initCause(rememberedException); return chainedException; } catch (Exception ignored) { return rememberedException; } } + @Override public InputStream getErrorStream() { if (connected && responseCode >= 400) { // Client Error 4xx and Server Error 5xx @@ -1629,10 +1622,9 @@ public class HttpURLConnection extends java.net.HttpURLConnection { InetAddress addr = null; try { final String finalHost = host; - addr = (InetAddress) - java.security.AccessController.doPrivileged - (new java.security.PrivilegedExceptionAction() { - public Object run() + addr = java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction() { + public InetAddress run() throws java.net.UnknownHostException { return InetAddress.getByName(finalHost); } @@ -2054,6 +2046,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { */ private void disconnectInternal() { responseCode = -1; + inputStream = null; if (pi != null) { pi.finishTracking(); pi = null; @@ -2152,6 +2145,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * Gets a header field by name. Returns null if not known. * @param name the name of the header field */ + @Override public String getHeaderField(String name) { try { getInputStream(); @@ -2174,7 +2168,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * @return a Map of header fields * @since 1.4 */ - public Map getHeaderFields() { + @Override + public Map> getHeaderFields() { try { getInputStream(); } catch (IOException e) {} @@ -2190,6 +2185,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * Gets a header field by index. Returns null if not known. * @param n the index of the header field */ + @Override public String getHeaderField(int n) { try { getInputStream(); @@ -2205,6 +2201,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * Gets a header field by index. Returns null if not known. * @param n the index of the header field */ + @Override public String getHeaderFieldKey(int n) { try { getInputStream(); @@ -2222,6 +2219,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * exists, overwrite its value with the new value. * @param value the value to be set */ + @Override public void setRequestProperty(String key, String value) { if (connected) throw new IllegalStateException("Already connected"); @@ -2243,6 +2241,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * @see #getRequestProperties(java.lang.String) * @since 1.4 */ + @Override public void addRequestProperty(String key, String value) { if (connected) throw new IllegalStateException("Already connected"); @@ -2262,6 +2261,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { requests.set(key, value); } + @Override public String getRequestProperty (String key) { // don't return headers containing security sensitive information if (key != null) { @@ -2286,7 +2286,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * @throws IllegalStateException if already connected * @since 1.4 */ - public Map getRequestProperties() { + @Override + public Map> getRequestProperties() { if (connected) throw new IllegalStateException("Already connected"); @@ -2294,6 +2295,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { return requests.getHeaders(EXCLUDE_HEADERS); } + @Override public void setConnectTimeout(int timeout) { if (timeout < 0) throw new IllegalArgumentException("timeouts can't be negative"); @@ -2313,6 +2315,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * @see java.net.URLConnection#connect() * @since 1.5 */ + @Override public int getConnectTimeout() { return (connectTimeout < 0 ? 0 : connectTimeout); } @@ -2337,6 +2340,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * @see java.io.InputStream#read() * @since 1.5 */ + @Override public void setReadTimeout(int timeout) { if (timeout < 0) throw new IllegalArgumentException("timeouts can't be negative"); @@ -2354,10 +2358,12 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * @see java.io.InputStream#read() * @since 1.5 */ + @Override public int getReadTimeout() { return readTimeout < 0 ? 0 : readTimeout; } + @Override protected void finalize() { // this should do nothing. The stream finalizer will close // the fd @@ -2367,20 +2373,15 @@ public class HttpURLConnection extends java.net.HttpURLConnection { return method; } - private MessageHeader mapToMessageHeader(Map map) { + private MessageHeader mapToMessageHeader(Map> map) { MessageHeader headers = new MessageHeader(); if (map == null || map.isEmpty()) { return headers; } - Set entries = map.entrySet(); - Iterator itr1 = entries.iterator(); - while (itr1.hasNext()) { - Map.Entry entry = (Map.Entry)itr1.next(); - String key = (String)entry.getKey(); - List values = (List)entry.getValue(); - Iterator itr2 = values.iterator(); - while (itr2.hasNext()) { - String value = (String)itr2.next(); + for (Map.Entry> entry : map.entrySet()) { + String key = entry.getKey(); + List values = entry.getValue(); + for (String value : values) { if (key == null) { headers.prepend(key, value); } else { @@ -2437,6 +2438,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * @see java.io.FilterInputStream#in * @see java.io.FilterInputStream#reset() */ + @Override public synchronized void mark(int readlimit) { super.mark(readlimit); if (cacheRequest != null) { @@ -2466,6 +2468,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * @see java.io.FilterInputStream#in * @see java.io.FilterInputStream#mark(int) */ + @Override public synchronized void reset() throws IOException { super.reset(); if (cacheRequest != null) { @@ -2474,6 +2477,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { } } + @Override public int read() throws IOException { try { byte[] b = new byte[1]; @@ -2487,10 +2491,12 @@ public class HttpURLConnection extends java.net.HttpURLConnection { } } + @Override public int read(byte[] b) throws IOException { return read(b, 0, b.length); } + @Override public int read(byte[] b, int off, int len) throws IOException { try { int newLen = super.read(b, off, len); @@ -2521,6 +2527,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { } } + @Override public void close () throws IOException { try { if (outputStream != null) { @@ -2565,6 +2572,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { error = false; } + @Override public void write (int b) throws IOException { checkError(); written ++; @@ -2574,10 +2582,12 @@ public class HttpURLConnection extends java.net.HttpURLConnection { out.write (b); } + @Override public void write (byte[] b) throws IOException { write (b, 0, b.length); } + @Override public void write (byte[] b, int off, int len) throws IOException { checkError(); written += len; @@ -2608,6 +2618,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { return closed && ! error; } + @Override public void close () throws IOException { if (closed) { return; @@ -2726,6 +2737,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { } } + @Override public int available() throws IOException { if (is == null) { return buffer.remaining(); @@ -2740,10 +2752,12 @@ public class HttpURLConnection extends java.net.HttpURLConnection { return (ret == -1? ret : (b[0] & 0x00FF)); } + @Override public int read(byte[] b) throws IOException { return read(b, 0, b.length); } + @Override public int read(byte[] b, int off, int len) throws IOException { int rem = buffer.remaining(); if (rem > 0) { @@ -2759,6 +2773,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { } } + @Override public void close() throws IOException { buffer = null; if (is != null) { @@ -2775,6 +2790,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { class EmptyInputStream extends InputStream { + @Override public int available() { return 0; } diff --git a/src/share/classes/sun/net/www/protocol/https/HttpsClient.java b/src/share/classes/sun/net/www/protocol/https/HttpsClient.java index 7f82e993161999189b40b1f600d236e351086494..d21425680c810a14b4b210b6cc46212fcf3401b6 100644 --- a/src/share/classes/sun/net/www/protocol/https/HttpsClient.java +++ b/src/share/classes/sun/net/www/protocol/https/HttpsClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2001-2008 Sun Microsystems, Inc. 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 @@ -518,6 +518,16 @@ final class HttpsClient extends HttpClient kac.put(url, sslSocketFactory, this); } + /* + * Close an idle connection to this URL (if it exists in the cache). + */ + public void closeIdleConnection() { + HttpClient http = (HttpClient) kac.get(url, sslSocketFactory); + if (http != null) { + http.closeServer(); + } + } + /** * Returns the cipher suite in use on this connection. */ diff --git a/src/share/classes/sun/net/www/protocol/jar/URLJarFile.java b/src/share/classes/sun/net/www/protocol/jar/URLJarFile.java index 4388f79d8910685921e8a0ddea9b9e11cf2d3512..80b9f0f763f567c9261afc84d0abb521fdff9c6d 100644 --- a/src/share/classes/sun/net/www/protocol/jar/URLJarFile.java +++ b/src/share/classes/sun/net/www/protocol/jar/URLJarFile.java @@ -55,7 +55,7 @@ public class URLJarFile extends JarFile { private Manifest superMan; private Attributes superAttr; - private Map superEntries; + private Map superEntries; static JarFile getJarFile(URL url) throws IOException { return getJarFile(url, null); @@ -146,12 +146,10 @@ public class URLJarFile extends JarFile { // now deep copy the manifest entries if (superEntries != null) { - Map entries = man.getEntries(); - Iterator it = superEntries.keySet().iterator(); - while (it.hasNext()) { - Object key = it.next(); - Attributes at = (Attributes)superEntries.get(key); - entries.put(key, at.clone()); + Map entries = man.getEntries(); + for (String key : superEntries.keySet()) { + Attributes at = superEntries.get(key); + entries.put(key, (Attributes) at.clone()); } } @@ -213,9 +211,9 @@ public class URLJarFile extends JarFile { final InputStream in = url.openConnection().getInputStream(); try { - result = (JarFile) - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws IOException { + result = AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public JarFile run() throws IOException { OutputStream out = null; File tmpFile = null; try { @@ -273,9 +271,9 @@ public class URLJarFile extends JarFile { public Attributes getAttributes() throws IOException { if (URLJarFile.this.isSuperMan()) { - Map e = URLJarFile.this.superEntries; + Map e = URLJarFile.this.superEntries; if (e != null) { - Attributes a = (Attributes)e.get(getName()); + Attributes a = e.get(getName()); if (a != null) return (Attributes)a.clone(); } diff --git a/src/share/classes/sun/net/www/protocol/mailto/MailToURLConnection.java b/src/share/classes/sun/net/www/protocol/mailto/MailToURLConnection.java index d939ce5515b9425f8cc05fb2ab1c31cbf360d592..53367aead964b056baebb18560f63c88e14ac3f5 100644 --- a/src/share/classes/sun/net/www/protocol/mailto/MailToURLConnection.java +++ b/src/share/classes/sun/net/www/protocol/mailto/MailToURLConnection.java @@ -29,9 +29,6 @@ import java.net.URL; import java.net.InetAddress; import java.net.SocketPermission; import java.io.*; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.StringTokenizer; import java.security.Permission; import sun.net.www.*; import sun.net.smtp.SmtpClient; @@ -86,11 +83,11 @@ public class MailToURLConnection extends URLConnection { } public void connect() throws IOException { - System.err.println("connect. Timeout = " + connectTimeout); client = new SmtpClient(connectTimeout); client.setReadTimeout(readTimeout); } + @Override public synchronized OutputStream getOutputStream() throws IOException { if (os != null) { return os; @@ -107,6 +104,7 @@ public class MailToURLConnection extends URLConnection { return os; } + @Override public Permission getPermission() throws IOException { if (permission == null) { connect(); @@ -116,22 +114,26 @@ public class MailToURLConnection extends URLConnection { return permission; } + @Override public void setConnectTimeout(int timeout) { if (timeout < 0) throw new IllegalArgumentException("timeouts can't be negative"); connectTimeout = timeout; } + @Override public int getConnectTimeout() { return (connectTimeout < 0 ? 0 : connectTimeout); } + @Override public void setReadTimeout(int timeout) { if (timeout < 0) throw new IllegalArgumentException("timeouts can't be negative"); readTimeout = timeout; } + @Override public int getReadTimeout() { return readTimeout < 0 ? 0 : readTimeout; } diff --git a/src/share/classes/sun/nio/ch/FileChannelImpl.java b/src/share/classes/sun/nio/ch/FileChannelImpl.java index 4aa21dbd18ad9f28955bd6079f88d9a2703fceb7..aae23b7664b476481366a27e17dc3f6a7ea66d93 100644 --- a/src/share/classes/sun/nio/ch/FileChannelImpl.java +++ b/src/share/classes/sun/nio/ch/FileChannelImpl.java @@ -52,39 +52,37 @@ public class FileChannelImpl { // Used to make native read and write calls - private static NativeDispatcher nd; + private static final NativeDispatcher nd; // Memory allocation size for mapping buffers - private static long allocationGranularity; + private static final long allocationGranularity; // Cached field for MappedByteBuffer.isAMappedBuffer - private static Field isAMappedBufferField; + private static final Field isAMappedBufferField; // File descriptor - private FileDescriptor fd; + private final FileDescriptor fd; // File access mode (immutable) - private boolean writable; - private boolean readable; - private boolean appending; + private final boolean writable; + private final boolean readable; // Required to prevent finalization of creating stream (immutable) - private Object parent; + private final Object parent; // Thread-safe set of IDs of native threads, for signalling - private NativeThreadSet threads = new NativeThreadSet(2); + private final NativeThreadSet threads = new NativeThreadSet(2); // Lock for operations involving position and size - private Object positionLock = new Object(); + private final Object positionLock = new Object(); private FileChannelImpl(FileDescriptor fd, boolean readable, - boolean writable, Object parent, boolean append) + boolean writable, Object parent) { this.fd = fd; this.readable = readable; this.writable = writable; this.parent = parent; - this.appending = append; } // Invoked by getChannel() methods @@ -94,14 +92,7 @@ public class FileChannelImpl boolean readable, boolean writable, Object parent) { - return new FileChannelImpl(fd, readable, writable, parent, false); - } - - public static FileChannel open(FileDescriptor fd, - boolean readable, boolean writable, - Object parent, boolean append) - { - return new FileChannelImpl(fd, readable, writable, parent, append); + return new FileChannelImpl(fd, readable, writable, parent); } private void ensureOpen() throws IOException { @@ -134,15 +125,7 @@ public class FileChannelImpl // superclass AbstractInterruptibleChannel, but the isOpen logic in // that method will prevent this method from being reinvoked. // - if (parent instanceof FileInputStream) - ((FileInputStream)parent).close(); - else if (parent instanceof FileOutputStream) - ((FileOutputStream)parent).close(); - else if (parent instanceof RandomAccessFile) - ((RandomAccessFile)parent).close(); - else - assert false; - + ((java.io.Closeable)parent).close(); } else { nd.close(fd); } @@ -218,8 +201,6 @@ public class FileChannelImpl if (!isOpen()) return 0; ti = threads.add(); - if (appending) - position(size()); do { n = IOUtil.write(fd, src, -1, nd, positionLock); } while ((n == IOStatus.INTERRUPTED) && isOpen()); @@ -244,8 +225,6 @@ public class FileChannelImpl if (!isOpen()) return 0; ti = threads.add(); - if (appending) - position(size()); do { n = IOUtil.write(fd, srcs, nd); } while ((n == IOStatus.INTERRUPTED) && isOpen()); @@ -1051,7 +1030,7 @@ public class FileChannelImpl private FileKey fileKey; FileLockReference(FileLock referent, - ReferenceQueue queue, + ReferenceQueue queue, FileKey key) { super(referent, queue); this.fileKey = key; @@ -1073,7 +1052,7 @@ public class FileChannelImpl new ConcurrentHashMap>(); // reference queue for cleared refs - private static ReferenceQueue queue = new ReferenceQueue(); + private static ReferenceQueue queue = new ReferenceQueue(); // the enclosing file channel private FileChannelImpl fci; diff --git a/src/share/classes/sun/nio/ch/Reflect.java b/src/share/classes/sun/nio/ch/Reflect.java index b50c600e3145152f972ec4f02c2b523f7350465f..cd98bf8dfad5fb1197326cc01458b293ef164ac7 100644 --- a/src/share/classes/sun/nio/ch/Reflect.java +++ b/src/share/classes/sun/nio/ch/Reflect.java @@ -43,8 +43,8 @@ class Reflect { // package-private } private static void setAccessible(final AccessibleObject ao) { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { ao.setAccessible(true); return null; }}); @@ -54,7 +54,7 @@ class Reflect { // package-private Class[] paramTypes) { try { - Class cl = Class.forName(className); + Class cl = Class.forName(className); Constructor c = cl.getDeclaredConstructor(paramTypes); setAccessible(c); return c; @@ -82,7 +82,7 @@ class Reflect { // package-private Class[] paramTypes) { try { - Class cl = Class.forName(className); + Class cl = Class.forName(className); Method m = cl.getDeclaredMethod(methodName, paramTypes); setAccessible(m); return m; diff --git a/src/share/classes/sun/nio/ch/SocketAdaptor.java b/src/share/classes/sun/nio/ch/SocketAdaptor.java index e852204d803381f658bac8e352c885845fdfed38..d8c26a2d13bb41a1336210f442bab22ba918aac9 100644 --- a/src/share/classes/sun/nio/ch/SocketAdaptor.java +++ b/src/share/classes/sun/nio/ch/SocketAdaptor.java @@ -242,9 +242,9 @@ public class SocketAdaptor throw new SocketException("Socket input is shutdown"); if (socketInputStream == null) { try { - socketInputStream = (InputStream)AccessController.doPrivileged( - new PrivilegedExceptionAction() { - public Object run() throws IOException { + socketInputStream = AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public InputStream run() throws IOException { return new SocketInputStream(); } }); @@ -264,9 +264,9 @@ public class SocketAdaptor throw new SocketException("Socket output is shutdown"); OutputStream os = null; try { - os = (OutputStream) - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws IOException { + os = AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public OutputStream run() throws IOException { return Channels.newOutputStream(sc); } }); diff --git a/src/share/classes/sun/nio/ch/Util.java b/src/share/classes/sun/nio/ch/Util.java index bacaa59f85f9e29aaff9aa066faceb4d6fa48178..73b66e072962775da72610b95a2f134c51c79055 100644 --- a/src/share/classes/sun/nio/ch/Util.java +++ b/src/share/classes/sun/nio/ch/Util.java @@ -49,20 +49,21 @@ class Util { private static final int TEMP_BUF_POOL_SIZE = 3; // Per-thread soft cache of the last temporary direct buffer - private static ThreadLocal[] bufferPool; + private static ThreadLocal>[] bufferPool; static { - bufferPool = new ThreadLocal[TEMP_BUF_POOL_SIZE]; + bufferPool = (ThreadLocal>[]) + new ThreadLocal[TEMP_BUF_POOL_SIZE]; for (int i=0; i>(); } static ByteBuffer getTemporaryDirectBuffer(int size) { ByteBuffer buf = null; // Grab a buffer if available for (int i=0; i ref = bufferPool[i].get(); + if ((ref != null) && ((buf = ref.get()) != null) && (buf.capacity() >= size)) { buf.rewind(); buf.limit(size); @@ -80,18 +81,18 @@ class Util { return; // Put it in an empty slot if such exists for (int i=0; i ref = bufferPool[i].get(); if ((ref == null) || (ref.get() == null)) { - bufferPool[i].set(new SoftReference(buf)); + bufferPool[i].set(new SoftReference(buf)); return; } } // Otherwise replace a smaller one in the cache if such exists for (int i=0; i ref = bufferPool[i].get(); + ByteBuffer inCacheBuf = ref.get(); if ((inCacheBuf == null) || (buf.capacity() > inCacheBuf.capacity())) { - bufferPool[i].set(new SoftReference(buf)); + bufferPool[i].set(new SoftReference(buf)); return; } } @@ -120,10 +121,12 @@ class Util { } // Per-thread cached selector - private static ThreadLocal localSelector = new ThreadLocal(); + private static ThreadLocal> localSelector + = new ThreadLocal>(); // Hold a reference to the selWrapper object to prevent it from // being cleaned when the temporary selector wrapped is on lease. - private static ThreadLocal localSelectorWrapper = new ThreadLocal(); + private static ThreadLocal localSelectorWrapper + = new ThreadLocal(); // When finished, invoker must ensure that selector is empty // by cancelling any related keys and explicitly releasing @@ -131,15 +134,16 @@ class Util { static Selector getTemporarySelector(SelectableChannel sc) throws IOException { - SoftReference ref = (SoftReference)localSelector.get(); + SoftReference ref = localSelector.get(); SelectorWrapper selWrapper = null; Selector sel = null; if (ref == null - || ((selWrapper = (SelectorWrapper) ref.get()) == null) + || ((selWrapper = ref.get()) == null) || ((sel = selWrapper.get()) == null) || (sel.provider() != sc.provider())) { sel = sc.provider().openSelector(); - localSelector.set(new SoftReference(new SelectorWrapper(sel))); + localSelector.set(new SoftReference( + new SelectorWrapper(sel))); } else { localSelectorWrapper.set(selWrapper); } @@ -235,10 +239,10 @@ class Util { private static volatile Constructor directByteBufferConstructor = null; private static void initDBBConstructor() { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { try { - Class cl = Class.forName("java.nio.DirectByteBuffer"); + Class cl = Class.forName("java.nio.DirectByteBuffer"); Constructor ctor = cl.getDeclaredConstructor( new Class[] { int.class, long.class, @@ -282,10 +286,10 @@ class Util { private static volatile Constructor directByteBufferRConstructor = null; private static void initDBBRConstructor() { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { try { - Class cl = Class.forName("java.nio.DirectByteBufferR"); + Class cl = Class.forName("java.nio.DirectByteBufferR"); Constructor ctor = cl.getDeclaredConstructor( new Class[] { int.class, long.class, diff --git a/src/share/classes/sun/reflect/ClassDefiner.java b/src/share/classes/sun/reflect/ClassDefiner.java index 63a4e2af44d77830851d6af6c337152722353cc2..91efcfffedff9ba0bfcb7536d8d2b46ff241a523 100644 --- a/src/share/classes/sun/reflect/ClassDefiner.java +++ b/src/share/classes/sun/reflect/ClassDefiner.java @@ -54,9 +54,9 @@ class ClassDefiner { static Class defineClass(String name, byte[] bytes, int off, int len, final ClassLoader parentClassLoader) { - ClassLoader newLoader = (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + ClassLoader newLoader = AccessController.doPrivileged( + new PrivilegedAction() { + public ClassLoader run() { return new DelegatingClassLoader(parentClassLoader); } }); diff --git a/src/share/classes/sun/reflect/MethodAccessorGenerator.java b/src/share/classes/sun/reflect/MethodAccessorGenerator.java index 3b62e2df8190ba5a4f30d81dd5d1afbca207c756..fd72a6e1c87cc900b988b031cc0b80dc016a339a 100644 --- a/src/share/classes/sun/reflect/MethodAccessorGenerator.java +++ b/src/share/classes/sun/reflect/MethodAccessorGenerator.java @@ -392,11 +392,12 @@ class MethodAccessorGenerator extends AccessorGenerator { // same namespace as the target class. Since the generated code // is privileged anyway, the protection domain probably doesn't // matter. - return (MagicAccessorImpl) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + return AccessController.doPrivileged( + new PrivilegedAction() { + public MagicAccessorImpl run() { try { - return ClassDefiner.defineClass + return (MagicAccessorImpl) + ClassDefiner.defineClass (generatedName, bytes, 0, diff --git a/src/share/classes/sun/reflect/ReflectionFactory.java b/src/share/classes/sun/reflect/ReflectionFactory.java index 30a1ac47c20c6a944843476ff796d0c1a443a21b..54dc717f62f3ffa8fdcbcccfb1c8cd7439fad5b1 100644 --- a/src/share/classes/sun/reflect/ReflectionFactory.java +++ b/src/share/classes/sun/reflect/ReflectionFactory.java @@ -84,8 +84,8 @@ public class ReflectionFactory { * AccessController.doPrivileged. */ public static final class GetReflectionFactoryAction - implements PrivilegedAction { - public Object run() { + implements PrivilegedAction { + public ReflectionFactory run() { return getReflectionFactory(); } } @@ -164,7 +164,7 @@ public class ReflectionFactory { public ConstructorAccessor newConstructorAccessor(Constructor c) { checkInitted(); - Class declaringClass = c.getDeclaringClass(); + Class declaringClass = c.getDeclaringClass(); if (Modifier.isAbstract(declaringClass.getModifiers())) { return new InstantiationExceptionConstructorAccessorImpl(null); } @@ -204,9 +204,9 @@ public class ReflectionFactory { /** Creates a new java.lang.reflect.Field. Access checks as per java.lang.reflect.AccessibleObject are not overridden. */ - public Field newField(Class declaringClass, + public Field newField(Class declaringClass, String name, - Class type, + Class type, int modifiers, int slot, String signature, @@ -223,11 +223,11 @@ public class ReflectionFactory { /** Creates a new java.lang.reflect.Method. Access checks as per java.lang.reflect.AccessibleObject are not overridden. */ - public Method newMethod(Class declaringClass, + public Method newMethod(Class declaringClass, String name, - Class[] parameterTypes, - Class returnType, - Class[] checkedExceptions, + Class[] parameterTypes, + Class returnType, + Class[] checkedExceptions, int modifiers, int slot, String signature, @@ -250,9 +250,9 @@ public class ReflectionFactory { /** Creates a new java.lang.reflect.Constructor. Access checks as per java.lang.reflect.AccessibleObject are not overridden. */ - public Constructor newConstructor(Class declaringClass, - Class[] parameterTypes, - Class[] checkedExceptions, + public Constructor newConstructor(Class declaringClass, + Class[] parameterTypes, + Class[] checkedExceptions, int modifiers, int slot, String signature, @@ -310,7 +310,7 @@ public class ReflectionFactory { /** Makes a copy of the passed constructor. The returned constructor is a "child" of the passed one; see the comments in Constructor.java for details. */ - public Constructor copyConstructor(Constructor arg) { + public Constructor copyConstructor(Constructor arg) { return langReflectAccess().copyConstructor(arg); } @@ -321,7 +321,7 @@ public class ReflectionFactory { // public Constructor newConstructorForSerialization - (Class classToInstantiate, Constructor constructorToCall) + (Class classToInstantiate, Constructor constructorToCall) { // Fast path if (constructorToCall.getDeclaringClass() == classToInstantiate) { @@ -366,8 +366,9 @@ public class ReflectionFactory { run, before the system properties are set up. */ private static void checkInitted() { if (initted) return; - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged( + new PrivilegedAction() { + public Void run() { // Tests to ensure the system properties table is fully // initialized. This is needed because reflection code is // called very early in the initialization process (before diff --git a/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java b/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java index 45147dc51cf42828046107aa48f7501e6d1a1f07..56f1bad4b04479c23f27f8a0b70affb0c56af468 100644 --- a/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java +++ b/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java @@ -273,8 +273,8 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable { private Method[] getMemberMethods() { if (memberMethods == null) { final Method[] mm = type.getDeclaredMethods(); - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { AccessibleObject.setAccessible(mm, true); return null; } diff --git a/src/share/classes/sun/reflect/misc/MethodUtil.java b/src/share/classes/sun/reflect/misc/MethodUtil.java index b36993337bb2460c89d6d43d61d9ca17dec2718c..9c1bfbea41fceaab140489762ca53d85a23f5b4b 100644 --- a/src/share/classes/sun/reflect/misc/MethodUtil.java +++ b/src/share/classes/sun/reflect/misc/MethodUtil.java @@ -67,7 +67,7 @@ public final class MethodUtil extends SecureClassLoader { super(); } - public static Method getMethod(Class cls, String name, Class[] args) + public static Method getMethod(Class cls, String name, Class[] args) throws NoSuchMethodException { ReflectUtil.checkPackageAccess(cls); return cls.getMethod(name, args); @@ -89,7 +89,7 @@ public final class MethodUtil extends SecureClassLoader { if (System.getSecurityManager() == null) { return cls.getMethods(); } - Map sigs = new HashMap(); + Map sigs = new HashMap(); while (cls != null) { boolean done = getInternalPublicMethods(cls, sigs); if (done) { @@ -98,14 +98,14 @@ public final class MethodUtil extends SecureClassLoader { getInterfaceMethods(cls, sigs); cls = cls.getSuperclass(); } - Collection c = sigs.values(); - return (Method[]) c.toArray(new Method[c.size()]); + return sigs.values().toArray(new Method[sigs.size()]); } /* * Process the immediate interfaces of this class or interface. */ - private static void getInterfaceMethods(Class cls, Map sigs) { + private static void getInterfaceMethods(Class cls, + Map sigs) { Class[] intfs = cls.getInterfaces(); for (int i=0; i < intfs.length; i++) { Class intf = intfs[i]; @@ -120,7 +120,8 @@ public final class MethodUtil extends SecureClassLoader { * * Process the methods in this class or interface */ - private static boolean getInternalPublicMethods(Class cls, Map sigs) { + private static boolean getInternalPublicMethods(Class cls, + Map sigs) { Method[] methods = null; try { /* @@ -178,7 +179,7 @@ public final class MethodUtil extends SecureClassLoader { return done; } - private static void addMethod(Map sigs, Method method) { + private static void addMethod(Map sigs, Method method) { Signature signature = new Signature(method); if (!sigs.containsKey(signature)) { sigs.put(signature, method); @@ -186,7 +187,7 @@ public final class MethodUtil extends SecureClassLoader { /* * Superclasses beat interfaces. */ - Method old = (Method)sigs.get(signature); + Method old = sigs.get(signature); if (old.getDeclaringClass().isInterface()) { sigs.put(signature, method); } @@ -280,17 +281,15 @@ public final class MethodUtil extends SecureClassLoader { } private static Method getTrampoline() { - Method tramp = null; - try { - tramp = (Method) AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { - Class[] types; - Class t = getTrampolineClass(); - Method b; - - types = new Class[] {Method.class, Object.class, Object[].class}; - b = t.getDeclaredMethod("invoke", types); + return AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Method run() throws Exception { + Class t = getTrampolineClass(); + Class[] types = { + Method.class, Object.class, Object[].class + }; + Method b = t.getDeclaredMethod("invoke", types); ((AccessibleObject)b).setAccessible(true); return b; } @@ -298,7 +297,6 @@ public final class MethodUtil extends SecureClassLoader { } catch (Exception e) { throw new InternalError("bouncer cannot be found"); } - return tramp; } diff --git a/src/share/classes/sun/rmi/log/ReliableLog.java b/src/share/classes/sun/rmi/log/ReliableLog.java index 7ac2858196a315e12624d59c0820a171ff432527..542c6d27a15a169b7a687e2232294c6fe0b969e8 100644 --- a/src/share/classes/sun/rmi/log/ReliableLog.java +++ b/src/share/classes/sun/rmi/log/ReliableLog.java @@ -140,8 +140,8 @@ public class ReliableLog { throws IOException { super(); - this.Debug = ((Boolean) AccessController.doPrivileged( - new GetBooleanAction("sun.rmi.log.debug"))).booleanValue(); + this.Debug = AccessController.doPrivileged( + new GetBooleanAction("sun.rmi.log.debug")).booleanValue(); dir = new File(dirPath); if (!(dir.exists() && dir.isDirectory())) { // create directory @@ -333,8 +333,8 @@ public class ReliableLog { private static Constructor getLogClassConstructor() { - String logClassName = ((String) AccessController.doPrivileged( - new GetPropertyAction("sun.rmi.log.class"))); + String logClassName = AccessController.doPrivileged( + new GetPropertyAction("sun.rmi.log.class")); if (logClassName != null) { try { ClassLoader loader = diff --git a/src/share/classes/sun/rmi/registry/RegistryImpl.java b/src/share/classes/sun/rmi/registry/RegistryImpl.java index 2f29cd57033517b8d277aed65ce3a481ed1c1250..7a99a014ee52666b141f5447ab1b796c0a90316b 100644 --- a/src/share/classes/sun/rmi/registry/RegistryImpl.java +++ b/src/share/classes/sun/rmi/registry/RegistryImpl.java @@ -66,8 +66,10 @@ public class RegistryImpl extends java.rmi.server.RemoteServer /* indicate compatibility with JDK 1.1.x version of class */ private static final long serialVersionUID = 4666870661827494597L; - private Hashtable bindings = new Hashtable(101); - private static Hashtable allowedAccessCache = new Hashtable(3); + private Hashtable bindings + = new Hashtable(101); + private static Hashtable allowedAccessCache + = new Hashtable(3); private static RegistryImpl registry; private static ObjID id = new ObjID(ObjID.REGISTRY_ID); @@ -119,7 +121,7 @@ public class RegistryImpl extends java.rmi.server.RemoteServer throws RemoteException, NotBoundException { synchronized (bindings) { - Remote obj = (Remote)bindings.get(name); + Remote obj = bindings.get(name); if (obj == null) throw new NotBoundException(name); return obj; @@ -136,7 +138,7 @@ public class RegistryImpl extends java.rmi.server.RemoteServer { checkAccess("Registry.bind"); synchronized (bindings) { - Remote curr = (Remote)bindings.get(name); + Remote curr = bindings.get(name); if (curr != null) throw new AlreadyBoundException(name); bindings.put(name, obj); @@ -153,7 +155,7 @@ public class RegistryImpl extends java.rmi.server.RemoteServer { checkAccess("Registry.unbind"); synchronized (bindings) { - Remote obj = (Remote)bindings.get(name); + Remote obj = bindings.get(name); if (obj == null) throw new NotBoundException(name); bindings.remove(name); @@ -203,10 +205,9 @@ public class RegistryImpl extends java.rmi.server.RemoteServer InetAddress clientHost; try { - clientHost = (InetAddress) - java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { - public Object run() + clientHost = java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction() { + public InetAddress run() throws java.net.UnknownHostException { return InetAddress.getByName(clientHostName); @@ -228,8 +229,8 @@ public class RegistryImpl extends java.rmi.server.RemoteServer final InetAddress finalClientHost = clientHost; java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { - public Object run() throws java.io.IOException { + new java.security.PrivilegedExceptionAction() { + public Void run() throws java.io.IOException { /* * if a ServerSocket can be bound to the client's * address then that address must be local diff --git a/src/share/classes/sun/rmi/rmic/RemoteClass.java b/src/share/classes/sun/rmi/rmic/RemoteClass.java index 0caa07fe0677abd2c7a0a30d1eb5c82db2c473ea..7d41be36974f2a517d804e6eb95484bc78fc475b 100644 --- a/src/share/classes/sun/rmi/rmic/RemoteClass.java +++ b/src/share/classes/sun/rmi/rmic/RemoteClass.java @@ -103,7 +103,7 @@ public class RemoteClass implements sun.rmi.rmic.RMIConstants { * in the array). */ public ClassDefinition[] getRemoteInterfaces() { - return (ClassDefinition[]) remoteInterfaces.clone(); + return remoteInterfaces.clone(); } /** @@ -118,7 +118,7 @@ public class RemoteClass implements sun.rmi.rmic.RMIConstants { * stub/skeleton protocol. */ public Method[] getRemoteMethods() { - return (Method[]) remoteMethods.clone(); + return remoteMethods.clone(); } /** @@ -204,8 +204,8 @@ public class RemoteClass implements sun.rmi.rmic.RMIConstants { * chain, add each directly-implemented interface that * somehow extends Remote to a list. */ - Vector remotesImplemented = // list of remote interfaces found - new Vector(); + Vector remotesImplemented = // list of remote interfaces found + new Vector(); for (ClassDefinition classDef = implClassDef; classDef != null;) { @@ -307,13 +307,13 @@ public class RemoteClass implements sun.rmi.rmic.RMIConstants { * Now we collect the methods from all of the remote interfaces * into a hashtable. */ - Hashtable methods = new Hashtable(); + Hashtable methods = new Hashtable(); boolean errors = false; - for (Enumeration enumeration = remotesImplemented.elements(); + for (Enumeration enumeration + = remotesImplemented.elements(); enumeration.hasMoreElements();) { - ClassDefinition interfaceDef = - (ClassDefinition) enumeration.nextElement(); + ClassDefinition interfaceDef = enumeration.nextElement(); if (!collectRemoteMethods(interfaceDef, methods)) errors = true; } @@ -336,10 +336,10 @@ public class RemoteClass implements sun.rmi.rmic.RMIConstants { */ String[] orderedKeys = new String[methods.size()]; int count = 0; - for (Enumeration enumeration = methods.elements(); + for (Enumeration enumeration = methods.elements(); enumeration.hasMoreElements();) { - Method m = (Method) enumeration.nextElement(); + Method m = enumeration.nextElement(); String key = m.getNameAndDescriptor(); int i; for (i = count; i > 0; --i) { @@ -353,7 +353,7 @@ public class RemoteClass implements sun.rmi.rmic.RMIConstants { } remoteMethods = new Method[methods.size()]; for (int i = 0; i < remoteMethods.length; i++) { - remoteMethods[i] = (Method) methods.get(orderedKeys[i]); + remoteMethods[i] = methods.get(orderedKeys[i]); /***** */ if (env.verbose()) { System.out.print("[found remote method <" + i + ">: " + @@ -388,7 +388,7 @@ public class RemoteClass implements sun.rmi.rmic.RMIConstants { * or false if an error occurred. */ private boolean collectRemoteMethods(ClassDefinition interfaceDef, - Hashtable table) + Hashtable table) { if (!interfaceDef.isInterface()) { throw new Error( @@ -529,7 +529,7 @@ public class RemoteClass implements sun.rmi.rmic.RMIConstants { * the new method (see bugid 4070653). */ String key = newMethod.getNameAndDescriptor(); - Method oldMethod = (Method) table.get(key); + Method oldMethod = table.get(key); if (oldMethod != null) { newMethod = newMethod.mergeWith(oldMethod); if (newMethod == null) { @@ -684,7 +684,7 @@ public class RemoteClass implements sun.rmi.rmic.RMIConstants { * methods that can be legally thrown in each of them. */ public ClassDeclaration[] getExceptions() { - return (ClassDeclaration[]) exceptions.clone(); + return exceptions.clone(); } /** @@ -789,7 +789,8 @@ public class RemoteClass implements sun.rmi.rmic.RMIConstants { getNameAndDescriptor()); } - Vector legalExceptions = new Vector(); + Vector legalExceptions + = new Vector(); try { collectCompatibleExceptions( other.exceptions, exceptions, legalExceptions); @@ -814,7 +815,7 @@ public class RemoteClass implements sun.rmi.rmic.RMIConstants { */ private void collectCompatibleExceptions(ClassDeclaration[] from, ClassDeclaration[] with, - Vector list) + Vector list) throws ClassNotFound { for (int i = 0; i < from.length; i++) { diff --git a/src/share/classes/sun/rmi/rmic/newrmic/jrmp/RemoteClass.java b/src/share/classes/sun/rmi/rmic/newrmic/jrmp/RemoteClass.java index f22a652dfdb5c7390b6dc9bd23efd66cd2191767..064d2d0cc7a2c1825f3e52dd10b9c75dedc0e0ae 100644 --- a/src/share/classes/sun/rmi/rmic/newrmic/jrmp/RemoteClass.java +++ b/src/share/classes/sun/rmi/rmic/newrmic/jrmp/RemoteClass.java @@ -121,7 +121,7 @@ final class RemoteClass { * in the array). **/ ClassDoc[] remoteInterfaces() { - return (ClassDoc[]) remoteInterfaces.clone(); + return remoteInterfaces.clone(); } /** @@ -136,7 +136,7 @@ final class RemoteClass { * stub/skeleton protocol. **/ Method[] remoteMethods() { - return (Method[]) remoteMethods.clone(); + return remoteMethods.clone(); } /** @@ -559,7 +559,7 @@ final class RemoteClass { * methods that can be legally thrown by all of them. **/ ClassDoc[] exceptionTypes() { - return (ClassDoc[]) exceptionTypes.clone(); + return exceptionTypes.clone(); } /** diff --git a/src/share/classes/sun/rmi/runtime/Log.java b/src/share/classes/sun/rmi/runtime/Log.java index 3eb8ce9cf9f72d92971936bba509302ab61ed9a9..8017ee0a10f08855aec561a9d4e1a6b31d5be460 100644 --- a/src/share/classes/sun/rmi/runtime/Log.java +++ b/src/share/classes/sun/rmi/runtime/Log.java @@ -71,7 +71,7 @@ public abstract class Log { private static final LogFactory logFactory; static { boolean useOld = - Boolean.valueOf((String) java.security.AccessController. + Boolean.valueOf(java.security.AccessController. doPrivileged(new sun.security.action.GetPropertyAction( "sun.rmi.log.useOld"))).booleanValue(); @@ -179,17 +179,16 @@ public abstract class Log { private static class LoggerLog extends Log { /* alternate console handler for RMI loggers */ - private static final Handler alternateConsole = (Handler) + private static final Handler alternateConsole = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Handler run() { InternalStreamHandler alternate = new InternalStreamHandler(System.err); alternate.setLevel(Level.ALL); return alternate; } - } - ); + }); /** handler to which messages are copied */ private InternalStreamHandler copyHandler = null; @@ -206,8 +205,8 @@ public abstract class Log { if (level != null){ java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Void run() { if (!logger.isLoggable(level)) { logger.setLevel(level); } diff --git a/src/share/classes/sun/rmi/server/LoaderHandler.java b/src/share/classes/sun/rmi/server/LoaderHandler.java index d4a9183e4a368bd8002b3a86bee9058dde58fdb3..dcdecb0cc43c74f804529dad7722ab1d2a301aa5 100644 --- a/src/share/classes/sun/rmi/server/LoaderHandler.java +++ b/src/share/classes/sun/rmi/server/LoaderHandler.java @@ -70,7 +70,7 @@ public final class LoaderHandler { /** RMI class loader log level */ static final int logLevel = LogStream.parseLevel( - (String) java.security.AccessController.doPrivileged( + java.security.AccessController.doPrivileged( new GetPropertyAction("sun.rmi.loader.logLevel"))); /* loader system log */ @@ -83,7 +83,7 @@ public final class LoaderHandler { */ private static String codebaseProperty = null; static { - String prop = (String) java.security.AccessController.doPrivileged( + String prop = java.security.AccessController.doPrivileged( new GetPropertyAction("java.rmi.server.codebase")); if (prop != null && prop.trim().length() > 0) { codebaseProperty = prop; @@ -94,8 +94,8 @@ public final class LoaderHandler { private static URL[] codebaseURLs = null; /** table of class loaders that use codebase property for annotation */ - private static final Map codebaseLoaders = - Collections.synchronizedMap(new IdentityHashMap(5)); + private static final Map codebaseLoaders = + Collections.synchronizedMap(new IdentityHashMap(5)); static { for (ClassLoader codebaseLoader = ClassLoader.getSystemClassLoader(); codebaseLoader != null; @@ -111,10 +111,12 @@ public final class LoaderHandler { * references, so this table does not prevent loaders from being * garbage collected. */ - private static final HashMap loaderTable = new HashMap(5); + private static final HashMap loaderTable + = new HashMap(5); /** reference queue for cleared class loader entries */ - private static final ReferenceQueue refQueue = new ReferenceQueue(); + private static final ReferenceQueue refQueue + = new ReferenceQueue(); /* * Disallow anyone from creating one of these. @@ -757,7 +759,7 @@ public final class LoaderHandler { throws MalformedURLException { synchronized (pathToURLsCache) { - Object[] v = (Object[]) pathToURLsCache.get(path); + Object[] v = pathToURLsCache.get(path); if (v != null) { return ((URL[])v[0]); } @@ -769,13 +771,14 @@ public final class LoaderHandler { } synchronized (pathToURLsCache) { pathToURLsCache.put(path, - new Object[] {urls, new SoftReference(path)}); + new Object[] {urls, new SoftReference(path)}); } return urls; } /** map from weak(key=string) to [URL[], soft(key)] */ - private static final Map pathToURLsCache = new WeakHashMap(5); + private static final Map pathToURLsCache + = new WeakHashMap(5); /** * Convert an array of URL objects into a corresponding string @@ -853,9 +856,9 @@ public final class LoaderHandler { * in the table of RMI class loaders. */ LoaderKey key = new LoaderKey(urls, parent); - entry = (LoaderEntry) loaderTable.get(key); + entry = loaderTable.get(key); - if (entry == null || (loader = (Loader) entry.get()) == null) { + if (entry == null || (loader = entry.get()) == null) { /* * If entry was in table but it's weak reference was cleared, * remove it from the table and mark it as explicitly cleared, @@ -876,9 +879,9 @@ public final class LoaderHandler { * necessary to load classes from its codebase URL path. */ AccessControlContext acc = getLoaderAccessControlContext(urls); - loader = (Loader) java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + loader = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Loader run() { return new Loader(urls, parent); } }, acc); @@ -954,7 +957,7 @@ public final class LoaderHandler { * loader key for the loader so that the mapping can be removed from * the table efficiently when the weak reference is cleared. */ - private static class LoaderEntry extends WeakReference { + private static class LoaderEntry extends WeakReference { public LoaderKey key; @@ -983,10 +986,10 @@ public final class LoaderHandler { * getAccessControlContext() in the sun.applet.AppletPanel class. */ // begin with permissions granted to all code in current policy - PermissionCollection perms = (PermissionCollection) + PermissionCollection perms = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public PermissionCollection run() { CodeSource codesource = new CodeSource(null, (java.security.cert.Certificate[]) null); Policy p = java.security.Policy.getPolicy(); diff --git a/src/share/classes/sun/rmi/server/MarshalInputStream.java b/src/share/classes/sun/rmi/server/MarshalInputStream.java index a75b8051a5cece710332e519dc5035637138aa66..cf4e345d786c4b5c1d0a69603545036765a25a45 100644 --- a/src/share/classes/sun/rmi/server/MarshalInputStream.java +++ b/src/share/classes/sun/rmi/server/MarshalInputStream.java @@ -59,18 +59,20 @@ public class MarshalInputStream extends ObjectInputStream { * as cached at class initialization time. */ private static final boolean useCodebaseOnlyProperty = - ((Boolean) java.security.AccessController.doPrivileged( + java.security.AccessController.doPrivileged( new sun.security.action.GetBooleanAction( - "java.rmi.server.useCodebaseOnly"))).booleanValue(); + "java.rmi.server.useCodebaseOnly")).booleanValue(); /** table to hold sun classes to which access is explicitly permitted */ - protected static Map permittedSunClasses = new HashMap(3); + protected static Map> permittedSunClasses + = new HashMap>(3); /** if true, don't try superclass first in resolveClass() */ private boolean skipDefaultResolveClass = false; /** callbacks to make when done() called: maps Object to Runnable */ - private final Map doneCallbacks = new HashMap(3); + private final Map doneCallbacks + = new HashMap(3); /** * if true, load classes (if not available locally) only from the @@ -130,7 +132,7 @@ public class MarshalInputStream extends ObjectInputStream { * with that key. */ public Runnable getDoneCallback(Object key) { - return (Runnable) doneCallbacks.get(key); // not thread-safe + return doneCallbacks.get(key); // not thread-safe } /** @@ -153,9 +155,9 @@ public class MarshalInputStream extends ObjectInputStream { * the superclass's close method. */ public void done() { - Iterator iter = doneCallbacks.values().iterator(); + Iterator iter = doneCallbacks.values().iterator(); while (iter.hasNext()) { // not thread-safe - Runnable callback = (Runnable) iter.next(); + Runnable callback = iter.next(); callback.run(); } doneCallbacks.clear(); @@ -276,8 +278,7 @@ public class MarshalInputStream extends ObjectInputStream { name = perm.getName(); } - Class resolvedClass = - (Class) permittedSunClasses.get(className); + Class resolvedClass = permittedSunClasses.get(className); // if class not permitted, throw the SecurityException if ((name == null) || diff --git a/src/share/classes/sun/rmi/server/MarshalOutputStream.java b/src/share/classes/sun/rmi/server/MarshalOutputStream.java index 63aed2bee5324eb5057d958b2062701e22492d81..067a5f2ec702ce0e215e0ea60ca2608145d0d37f 100644 --- a/src/share/classes/sun/rmi/server/MarshalOutputStream.java +++ b/src/share/classes/sun/rmi/server/MarshalOutputStream.java @@ -64,8 +64,8 @@ public class MarshalOutputStream extends ObjectOutputStream super(out); this.useProtocolVersion(protocolVersion); java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Void run() { enableReplaceObject(true); return null; } diff --git a/src/share/classes/sun/rmi/server/Util.java b/src/share/classes/sun/rmi/server/Util.java index f103319ce89cc244542670d0d9288736aa1ec908..f757874416bba4afe927e910f964a001fefcfb6e 100644 --- a/src/share/classes/sun/rmi/server/Util.java +++ b/src/share/classes/sun/rmi/server/Util.java @@ -67,7 +67,7 @@ public final class Util { /** "server" package log level */ static final int logLevel = LogStream.parseLevel( - (String) AccessController.doPrivileged( + AccessController.doPrivileged( new GetPropertyAction("sun.rmi.server.logLevel"))); /** server reference log */ @@ -76,13 +76,13 @@ public final class Util { /** cached value of property java.rmi.server.ignoreStubClasses */ private static final boolean ignoreStubClasses = - ((Boolean) AccessController.doPrivileged( - new GetBooleanAction("java.rmi.server.ignoreStubClasses"))). + AccessController.doPrivileged( + new GetBooleanAction("java.rmi.server.ignoreStubClasses")). booleanValue(); /** cache of impl classes that have no corresponding stub class */ - private static final Map withoutStubs = - Collections.synchronizedMap(new WeakHashMap(11)); + private static final Map, Void> withoutStubs = + Collections.synchronizedMap(new WeakHashMap, Void>(11)); /** parameter types for stub constructor */ private static final Class[] stubConsParamTypes = { RemoteRef.class }; @@ -207,9 +207,9 @@ public final class Util { * @throws NullPointerException if remoteClass is null */ private static Class[] getRemoteInterfaces(Class remoteClass) { - ArrayList list = new ArrayList(); + ArrayList> list = new ArrayList>(); getRemoteInterfaces(list, remoteClass); - return (Class []) list.toArray(new Class[list.size()]); + return list.toArray(new Class[list.size()]); } /** @@ -220,7 +220,7 @@ public final class Util { * any illegal remote interfaces * @throws NullPointerException if the specified class or list is null */ - private static void getRemoteInterfaces(ArrayList list, Class cl) { + private static void getRemoteInterfaces(ArrayList> list, Class cl) { Class superclass = cl.getSuperclass(); if (superclass != null) { getRemoteInterfaces(list, superclass); @@ -254,7 +254,7 @@ public final class Util { * @throws IllegalArgumentException if m is an illegal remote method */ private static void checkMethod(Method m) { - Class[] ex = m.getExceptionTypes(); + Class[] ex = m.getExceptionTypes(); for (int i = 0; i < ex.length; i++) { if (ex[i].isAssignableFrom(RemoteException.class)) return; @@ -283,7 +283,7 @@ public final class Util { * pickle methods */ try { - Class stubcl = + Class stubcl = Class.forName(stubname, false, remoteClass.getClassLoader()); Constructor cons = stubcl.getConstructor(stubConsParamTypes); return (RemoteStub) cons.newInstance(new Object[] { ref }); diff --git a/src/share/classes/sun/rmi/server/WeakClassHashMap.java b/src/share/classes/sun/rmi/server/WeakClassHashMap.java index e822c26551b734eb95707f447c4d51decb46c327..331930c368034b0d7aaebe38af14f433920a962c 100644 --- a/src/share/classes/sun/rmi/server/WeakClassHashMap.java +++ b/src/share/classes/sun/rmi/server/WeakClassHashMap.java @@ -69,7 +69,7 @@ public abstract class WeakClassHashMap { synchronized (valueCell) { V value = null; if (valueCell.ref != null) { - value = (V) valueCell.ref.get(); + value = valueCell.ref.get(); } if (value == null) { value = computeValue(remoteClass); diff --git a/src/share/classes/sun/rmi/transport/DGCClient.java b/src/share/classes/sun/rmi/transport/DGCClient.java index 31784b3574a7c7e596564ea056e9bd4afb33b105..585901bbce7c5ac61e1fbf862eb53c4abe93f564 100644 --- a/src/share/classes/sun/rmi/transport/DGCClient.java +++ b/src/share/classes/sun/rmi/transport/DGCClient.java @@ -85,21 +85,21 @@ final class DGCClient { /** lease duration to request (usually ignored by server) */ private static final long leaseValue = // default 10 minutes - ((Long) AccessController.doPrivileged( + AccessController.doPrivileged( new GetLongAction("java.rmi.dgc.leaseValue", - 600000))).longValue(); + 600000)).longValue(); /** maximum interval between retries of failed clean calls */ private static final long cleanInterval = // default 3 minutes - ((Long) AccessController.doPrivileged( + AccessController.doPrivileged( new GetLongAction("sun.rmi.dgc.cleanInterval", - 180000))).longValue(); + 180000)).longValue(); /** maximum interval between complete garbage collections of local heap */ private static final long gcInterval = // default 1 hour - ((Long) AccessController.doPrivileged( + AccessController.doPrivileged( new GetLongAction("sun.rmi.dgc.client.gcInterval", - 3600000))).longValue(); + 3600000)).longValue(); /** minimum retry count for dirty calls that fail */ private static final int dirtyFailureRetries = 5; @@ -243,7 +243,7 @@ final class DGCClient { } catch (RemoteException e) { throw new Error("internal error creating DGC stub"); } - renewCleanThread = (Thread) AccessController.doPrivileged( + renewCleanThread = AccessController.doPrivileged( new NewThreadAction(new RenewCleanThread(), "RenewClean-" + endpoint, true)); renewCleanThread.start(); @@ -473,8 +473,9 @@ final class DGCClient { if (newRenewTime < renewTime) { renewTime = newRenewTime; if (interruptible) { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged( + new PrivilegedAction() { + public Void run() { renewCleanThread.interrupt(); return null; } diff --git a/src/share/classes/sun/rmi/transport/Target.java b/src/share/classes/sun/rmi/transport/Target.java index 01df43800938e4c877ec4860cfbdbefb2b75adbe..6abf092d725d0a65623edc92ff5df42a3a24695d 100644 --- a/src/share/classes/sun/rmi/transport/Target.java +++ b/src/share/classes/sun/rmi/transport/Target.java @@ -321,7 +321,7 @@ public final class Target { Remote obj = getImpl(); if (obj instanceof Unreferenced) { final Unreferenced unrefObj = (Unreferenced) obj; - final Thread t = (Thread) + final Thread t = java.security.AccessController.doPrivileged( new NewThreadAction(new Runnable() { public void run() { @@ -334,8 +334,8 @@ public final class Target { * for threads that may invoke user code (see bugid 4171278). */ java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Void run() { t.setContextClassLoader(ccl); return null; } diff --git a/src/share/classes/sun/rmi/transport/Transport.java b/src/share/classes/sun/rmi/transport/Transport.java index 572a55b2bea1551303b6a9aff2b16a936ded0f5b..67e6058d95a91191c3036efd12830e8e05260125 100644 --- a/src/share/classes/sun/rmi/transport/Transport.java +++ b/src/share/classes/sun/rmi/transport/Transport.java @@ -53,7 +53,7 @@ public abstract class Transport { static final int logLevel = LogStream.parseLevel(getLogLevel()); private static String getLogLevel() { - return (String) java.security.AccessController.doPrivileged( + return java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("sun.rmi.transport.logLevel")); } @@ -171,8 +171,8 @@ public abstract class Transport { currentTransport.set(this); try { java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { - public Object run() throws IOException { + new java.security.PrivilegedExceptionAction() { + public Void run() throws IOException { checkAcceptPermission(acc); disp.dispatch(impl, call); return null; diff --git a/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java b/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java index 3d91ab0d179a4bbe90a3cc015612eadd34fc3c56..cb4a88e562c6677fca20a068538c80fb81b95ef6 100644 --- a/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java +++ b/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java @@ -89,8 +89,8 @@ public final class CGIHandler { static { java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Void run() { ContentLength = Integer.getInteger("CONTENT_LENGTH", 0).intValue(); QueryString = System.getProperty("QUERY_STRING", ""); diff --git a/src/share/classes/sun/rmi/transport/proxy/HttpSendSocket.java b/src/share/classes/sun/rmi/transport/proxy/HttpSendSocket.java index 7498c9bfd8b03449d44a52b00ce48513eea195cb..2c972d8760f6c6116b0d802b8cff101d4fd59094 100644 --- a/src/share/classes/sun/rmi/transport/proxy/HttpSendSocket.java +++ b/src/share/classes/sun/rmi/transport/proxy/HttpSendSocket.java @@ -78,7 +78,7 @@ class HttpSendSocket extends Socket implements RMISocketInfo { * property at the moment that the socket was created. */ private String lineSeparator = - (String) java.security.AccessController.doPrivileged( + java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("line.separator")); /** diff --git a/src/share/classes/sun/rmi/transport/proxy/RMIMasterSocketFactory.java b/src/share/classes/sun/rmi/transport/proxy/RMIMasterSocketFactory.java index 16735959e2f594dd5ed80b4b01c77974097f29b0..92d0dd77cb3a955f66a29745c836feb38ac88eb8 100644 --- a/src/share/classes/sun/rmi/transport/proxy/RMIMasterSocketFactory.java +++ b/src/share/classes/sun/rmi/transport/proxy/RMIMasterSocketFactory.java @@ -50,7 +50,7 @@ public class RMIMasterSocketFactory extends RMISocketFactory { static int logLevel = LogStream.parseLevel(getLogLevel()); private static String getLogLevel() { - return (String) java.security.AccessController.doPrivileged( + return java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("sun.rmi.transport.proxy.logLevel")); } @@ -63,15 +63,15 @@ public class RMIMasterSocketFactory extends RMISocketFactory { private static long connectTimeout = getConnectTimeout(); private static long getConnectTimeout() { - return ((Long) java.security.AccessController.doPrivileged( + return java.security.AccessController.doPrivileged( new GetLongAction("sun.rmi.transport.proxy.connectTimeout", - 15000))).longValue(); // default: 15 seconds + 15000)).longValue(); // default: 15 seconds } /** whether to fallback to HTTP on general connect failures */ - private static final boolean eagerHttpFallback = ((Boolean) + private static final boolean eagerHttpFallback = java.security.AccessController.doPrivileged(new GetBooleanAction( - "sun.rmi.transport.proxy.eagerHttpFallback"))).booleanValue(); + "sun.rmi.transport.proxy.eagerHttpFallback")).booleanValue(); /** table of hosts successfully connected to and the factory used */ private Hashtable successTable = new Hashtable(); @@ -100,14 +100,14 @@ public class RMIMasterSocketFactory extends RMISocketFactory { try { String proxyHost; - proxyHost = (String) java.security.AccessController.doPrivileged( + proxyHost = java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("http.proxyHost")); if (proxyHost == null) - proxyHost=(String)java.security.AccessController.doPrivileged( + proxyHost = java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("proxyHost")); - Boolean tmp = (Boolean)java.security.AccessController.doPrivileged( + Boolean tmp = java.security.AccessController.doPrivileged( new sun.security.action.GetBooleanAction("java.rmi.server.disableHttp")); if (!tmp.booleanValue() && @@ -178,10 +178,8 @@ public class RMIMasterSocketFactory extends RMISocketFactory { try { synchronized (connector) { - Thread t = (Thread) - java.security.AccessController.doPrivileged( - new NewThreadAction(connector, "AsyncConnector", - true)); + Thread t = java.security.AccessController.doPrivileged( + new NewThreadAction(connector, "AsyncConnector", true)); t.start(); try { diff --git a/src/share/classes/sun/rmi/transport/tcp/ConnectionMultiplexer.java b/src/share/classes/sun/rmi/transport/tcp/ConnectionMultiplexer.java index f756cd34f74fa4759df1be8e08389613b482bc4e..ac26ac6d832a759457bc00aad073d6f4e4546b95 100644 --- a/src/share/classes/sun/rmi/transport/tcp/ConnectionMultiplexer.java +++ b/src/share/classes/sun/rmi/transport/tcp/ConnectionMultiplexer.java @@ -49,7 +49,7 @@ final class ConnectionMultiplexer { static int logLevel = LogStream.parseLevel(getLogLevel()); private static String getLogLevel() { - return (String) java.security.AccessController.doPrivileged( + return java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("sun.rmi.transport.tcp.multiplex.logLevel")); } diff --git a/src/share/classes/sun/security/jgss/GSSManagerImpl.java b/src/share/classes/sun/security/jgss/GSSManagerImpl.java index 7bf0f9be2302edb2974fd99f482345a488820416..7aa401b03800a8ecd669427edb74f022d4dfe8bd 100644 --- a/src/share/classes/sun/security/jgss/GSSManagerImpl.java +++ b/src/share/classes/sun/security/jgss/GSSManagerImpl.java @@ -83,7 +83,7 @@ public class GSSManagerImpl extends GSSManager { public Oid[] getNamesForMech(Oid mech) throws GSSException { MechanismFactory factory = list.getMechFactory(mech); - return (Oid[])factory.getNameTypes().clone(); + return factory.getNameTypes().clone(); } public Oid[] getMechsForName(Oid nameType){ diff --git a/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java b/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java index 0fcbe12ff25e74b78a8edba1ddcb15b9b2a54a8a..838f6f8df1e373da5e5f8fbe18594e8166a86dc3 100644 --- a/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java +++ b/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java @@ -103,8 +103,7 @@ class InitSecContextToken extends InitialToken { apReq = new KrbApReq(apReqBytes, keys, addr); //debug("\nReceived AP-REQ and authenticated it.\n"); - EncryptionKey sessionKey - = (EncryptionKey) apReq.getCreds().getSessionKey(); + EncryptionKey sessionKey = apReq.getCreds().getSessionKey(); /* System.out.println("\n\nSession key from service ticket is: " + diff --git a/src/share/classes/sun/security/krb5/Config.java b/src/share/classes/sun/security/krb5/Config.java index 013fd1da1365c4f092e54417ac4fe367f1e607ab..a65ec8687497622681cbd304d55db431274812e6 100644 --- a/src/share/classes/sun/security/krb5/Config.java +++ b/src/share/classes/sun/security/krb5/Config.java @@ -1040,11 +1040,12 @@ public class Config { * Check if need to use DNS to locate Kerberos services */ public boolean useDNS(String name) { - boolean value = getDefaultBooleanValue(name, "libdefaults"); - if (value == false) { - value = getDefaultBooleanValue("dns_fallback", "libdefaults"); + String value = getDefault(name, "libdefaults"); + if (value == null) { + return getDefaultBooleanValue("dns_fallback", "libdefaults"); + } else { + return value.equalsIgnoreCase("true"); } - return value; } /** diff --git a/src/share/classes/sun/security/krb5/KrbTgsReq.java b/src/share/classes/sun/security/krb5/KrbTgsReq.java index 328e255e0d64ec25d566b86583bc722c25d13136..0cc54e17c454ffdc77ba4ab7f9ba2ae1639fb24c 100644 --- a/src/share/classes/sun/security/krb5/KrbTgsReq.java +++ b/src/share/classes/sun/security/krb5/KrbTgsReq.java @@ -75,108 +75,108 @@ public class KrbTgsReq extends KrbKdcReq { null); // EncryptionKey subSessionKey } - // Called by Credentials, KrbCred - KrbTgsReq( - KDCOptions options, - Credentials asCreds, - PrincipalName sname, - KerberosTime from, - KerberosTime till, - KerberosTime rtime, - int[] eTypes, - HostAddresses addresses, - AuthorizationData authorizationData, - Ticket[] additionalTickets, - EncryptionKey subKey) throws KrbException, IOException { - - princName = asCreds.client; - servName = sname; - ctime = new KerberosTime(KerberosTime.NOW); - - - // check if they are valid arguments. The optional fields - // should be consistent with settings in KDCOptions. - if (options.get(KDCOptions.FORWARDABLE) && - (!(asCreds.flags.get(Krb5.TKT_OPTS_FORWARDABLE)))) { - throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); - } - if (options.get(KDCOptions.FORWARDED)) { - if (!(asCreds.flags.get(KDCOptions.FORWARDABLE))) - throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); - } - if (options.get(KDCOptions.PROXIABLE) && - (!(asCreds.flags.get(Krb5.TKT_OPTS_PROXIABLE)))) { - throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); - } - if (options.get(KDCOptions.PROXY)) { - if (!(asCreds.flags.get(KDCOptions.PROXIABLE))) - throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); - } - if (options.get(KDCOptions.ALLOW_POSTDATE) && - (!(asCreds.flags.get(Krb5.TKT_OPTS_MAY_POSTDATE)))) { - throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); - } - if (options.get(KDCOptions.RENEWABLE) && - (!(asCreds.flags.get(Krb5.TKT_OPTS_RENEWABLE)))) { - throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); - } - - if (options.get(KDCOptions.POSTDATED)) { - if (!(asCreds.flags.get(KDCOptions.POSTDATED))) - throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); - } else { - if (from != null) from = null; - } - if (options.get(KDCOptions.RENEWABLE)) { - if (!(asCreds.flags.get(KDCOptions.RENEWABLE))) - throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); - } else { - if (rtime != null) rtime = null; - } - if (options.get(KDCOptions.ENC_TKT_IN_SKEY)) { - if (additionalTickets == null) - throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); - // in TGS_REQ there could be more than one additional - // tickets, but in file-based credential cache, - // there is only one additional ticket field. - secondTicket = additionalTickets[0]; - } else { - if (additionalTickets != null) - additionalTickets = null; - } - - tgsReqMessg = createRequest( - options, - asCreds.ticket, - asCreds.key, - ctime, - princName, - princName.getRealm(), - servName, - from, - till, - rtime, - eTypes, - addresses, - authorizationData, - additionalTickets, - subKey); - obuf = tgsReqMessg.asn1Encode(); - - // XXX We need to revisit this to see if can't move it - // up such that FORWARDED flag set in the options - // is included in the marshaled request. - /* - * If this is based on a forwarded ticket, record that in the - * options, because the returned TgsRep will contain the - * FORWARDED flag set. - */ - if (asCreds.flags.get(KDCOptions.FORWARDED)) - options.set(KDCOptions.FORWARDED, true); - + // Called by Credentials, KrbCred + KrbTgsReq( + KDCOptions options, + Credentials asCreds, + PrincipalName sname, + KerberosTime from, + KerberosTime till, + KerberosTime rtime, + int[] eTypes, + HostAddresses addresses, + AuthorizationData authorizationData, + Ticket[] additionalTickets, + EncryptionKey subKey) throws KrbException, IOException { + + princName = asCreds.client; + servName = sname; + ctime = new KerberosTime(KerberosTime.NOW); + + + // check if they are valid arguments. The optional fields + // should be consistent with settings in KDCOptions. + if (options.get(KDCOptions.FORWARDABLE) && + (!(asCreds.flags.get(Krb5.TKT_OPTS_FORWARDABLE)))) { + throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); + } + if (options.get(KDCOptions.FORWARDED)) { + if (!(asCreds.flags.get(KDCOptions.FORWARDABLE))) + throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); + } + if (options.get(KDCOptions.PROXIABLE) && + (!(asCreds.flags.get(Krb5.TKT_OPTS_PROXIABLE)))) { + throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); + } + if (options.get(KDCOptions.PROXY)) { + if (!(asCreds.flags.get(KDCOptions.PROXIABLE))) + throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); + } + if (options.get(KDCOptions.ALLOW_POSTDATE) && + (!(asCreds.flags.get(Krb5.TKT_OPTS_MAY_POSTDATE)))) { + throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); + } + if (options.get(KDCOptions.RENEWABLE) && + (!(asCreds.flags.get(Krb5.TKT_OPTS_RENEWABLE)))) { + throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); + } + if (options.get(KDCOptions.POSTDATED)) { + if (!(asCreds.flags.get(KDCOptions.POSTDATED))) + throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); + } else { + if (from != null) from = null; + } + if (options.get(KDCOptions.RENEWABLE)) { + if (!(asCreds.flags.get(KDCOptions.RENEWABLE))) + throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); + } else { + if (rtime != null) rtime = null; + } + if (options.get(KDCOptions.ENC_TKT_IN_SKEY)) { + if (additionalTickets == null) + throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); + // in TGS_REQ there could be more than one additional + // tickets, but in file-based credential cache, + // there is only one additional ticket field. + secondTicket = additionalTickets[0]; + } else { + if (additionalTickets != null) + additionalTickets = null; } + tgsReqMessg = createRequest( + options, + asCreds.ticket, + asCreds.key, + ctime, + princName, + princName.getRealm(), + servName, + from, + till, + rtime, + eTypes, + addresses, + authorizationData, + additionalTickets, + subKey); + obuf = tgsReqMessg.asn1Encode(); + + // XXX We need to revisit this to see if can't move it + // up such that FORWARDED flag set in the options + // is included in the marshaled request. + /* + * If this is based on a forwarded ticket, record that in the + * options, because the returned TgsRep will contain the + * FORWARDED flag set. + */ + if (asCreds.flags.get(KDCOptions.FORWARDED)) + options.set(KDCOptions.FORWARDED, true); + + + } + /** * Sends a TGS request to the realm of the target. * @throws KrbException diff --git a/src/share/classes/sun/security/krb5/internal/APRep.java b/src/share/classes/sun/security/krb5/internal/APRep.java index 17aeb89797c9ff57636bc6c6b7f26ec1c19bd890..53c3b58eaac2c419d7a45dc5b11b1914d39f1f48 100644 --- a/src/share/classes/sun/security/krb5/internal/APRep.java +++ b/src/share/classes/sun/security/krb5/internal/APRep.java @@ -54,81 +54,88 @@ import java.math.BigInteger; * http://www.ietf.org/rfc/rfc4120.txt. */ public class APRep { - public int pvno; - public int msgType; - public EncryptedData encPart; - public APRep(EncryptedData new_encPart) { - pvno = Krb5.PVNO; - msgType = Krb5.KRB_AP_REP; - encPart = new_encPart; - } + public int pvno; + public int msgType; + public EncryptedData encPart; - public APRep(byte[] data) throws Asn1Exception, - KrbApErrException, IOException { - init(new DerValue(data)); - } + public APRep(EncryptedData new_encPart) { + pvno = Krb5.PVNO; + msgType = Krb5.KRB_AP_REP; + encPart = new_encPart; + } + + public APRep(byte[] data) throws Asn1Exception, + KrbApErrException, IOException { + init(new DerValue(data)); + } public APRep(DerValue encoding) throws Asn1Exception, - KrbApErrException, IOException { - init(encoding); - } + KrbApErrException, IOException { + init(encoding); + } - /** - * Initializes an APRep object. - * @param encoding a single DER-encoded value. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * @exception KrbApErrException if the value read from the DER-encoded data - * stream does not match the pre-defined value. - */ + /** + * Initializes an APRep object. + * @param encoding a single DER-encoded value. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * @exception KrbApErrException if the value read from the DER-encoded data + * stream does not match the pre-defined value. + */ private void init(DerValue encoding) throws Asn1Exception, - KrbApErrException, IOException { + KrbApErrException, IOException { - if (((encoding.getTag() & (byte)(0x1F)) != Krb5.KRB_AP_REP) - || (encoding.isApplication() != true) - || (encoding.isConstructed() != true)) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - DerValue der = encoding.getData().getDerValue(); - if (der.getTag() != DerValue.tag_Sequence) + if (((encoding.getTag() & (byte) (0x1F)) != Krb5.KRB_AP_REP) + || (encoding.isApplication() != true) + || (encoding.isConstructed() != true)) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); - DerValue subDer = der.getData().getDerValue(); - if ((subDer.getTag() & (byte)0x1F) != (byte)0x00) + } + DerValue der = encoding.getData().getDerValue(); + if (der.getTag() != DerValue.tag_Sequence) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + DerValue subDer = der.getData().getDerValue(); + if ((subDer.getTag() & (byte) 0x1F) != (byte) 0x00) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } pvno = subDer.getData().getBigInteger().intValue(); - if (pvno != Krb5.PVNO) - throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION); - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & (byte)0x1F) != (byte)0x01) + if (pvno != Krb5.PVNO) { + throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION); + } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & (byte) 0x1F) != (byte) 0x01) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); - msgType = subDer.getData().getBigInteger().intValue(); - if (msgType != Krb5.KRB_AP_REP) - throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE); - encPart = EncryptedData.parse(der.getData(), (byte)0x02, false); - if (der.getData().available() > 0) + } + msgType = subDer.getData().getBigInteger().intValue(); + if (msgType != Krb5.KRB_AP_REP) { + throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE); + } + encPart = EncryptedData.parse(der.getData(), (byte) 0x02, false); + if (der.getData().available() > 0) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); } + } - /** - * Encodes an APRep object. - * @return byte array of encoded APRep object. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ - public byte[] asn1Encode() throws Asn1Exception, IOException { + /** + * Encodes an APRep object. + * @return byte array of encoded APRep object. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + public byte[] asn1Encode() throws Asn1Exception, IOException { DerOutputStream bytes = new DerOutputStream(); - DerOutputStream temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(pvno)); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp); - temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(msgType)); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), encPart.asn1Encode()); - temp = new DerOutputStream(); - temp.write(DerValue.tag_Sequence, bytes); - DerOutputStream aprep = new DerOutputStream(); - aprep.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x0F), temp); - return aprep.toByteArray(); - } - + DerOutputStream temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(pvno)); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x00), temp); + temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(msgType)); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x01), temp); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x02), encPart.asn1Encode()); + temp = new DerOutputStream(); + temp.write(DerValue.tag_Sequence, bytes); + DerOutputStream aprep = new DerOutputStream(); + aprep.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte) 0x0F), temp); + return aprep.toByteArray(); + } } diff --git a/src/share/classes/sun/security/krb5/internal/APReq.java b/src/share/classes/sun/security/krb5/internal/APReq.java index 328f833df6291b390ce57e427712494b2b565b21..3a1dc7c2222eeb9a69d9e2bbc7576fe63a2cee11 100644 --- a/src/share/classes/sun/security/krb5/internal/APReq.java +++ b/src/share/classes/sun/security/krb5/internal/APReq.java @@ -54,94 +54,98 @@ import java.math.BigInteger; * * http://www.ietf.org/rfc/rfc4120.txt. */ - public class APReq { - public int pvno; - public int msgType; - public APOptions apOptions; - public Ticket ticket; - public EncryptedData authenticator; - public APReq( - APOptions new_apOptions, - Ticket new_ticket, - EncryptedData new_authenticator - ) { - pvno = Krb5.PVNO; - msgType = Krb5.KRB_AP_REQ; - apOptions = new_apOptions; - ticket = new_ticket; - authenticator = new_authenticator; - } + public int pvno; + public int msgType; + public APOptions apOptions; + public Ticket ticket; + public EncryptedData authenticator; + + public APReq( + APOptions new_apOptions, + Ticket new_ticket, + EncryptedData new_authenticator) { + pvno = Krb5.PVNO; + msgType = Krb5.KRB_AP_REQ; + apOptions = new_apOptions; + ticket = new_ticket; + authenticator = new_authenticator; + } - public APReq(byte[] data) throws Asn1Exception,IOException, KrbApErrException, RealmException { + public APReq(byte[] data) throws Asn1Exception, IOException, KrbApErrException, RealmException { init(new DerValue(data)); - } + } public APReq(DerValue encoding) throws Asn1Exception, IOException, KrbApErrException, RealmException { - init(encoding); - } + init(encoding); + } - /** - * Initializes an APReq object. - * @param encoding a single DER-encoded value. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * @exception KrbApErrException if the value read from the DER-encoded data stream does not match the pre-defined value. - * @exception RealmException if an error occurs while parsing a Realm object. - */ - private void init(DerValue encoding) throws Asn1Exception, - IOException, KrbApErrException, RealmException { - DerValue der, subDer; - if (((encoding.getTag() & (byte)0x1F) != Krb5.KRB_AP_REQ) - || (encoding.isApplication() != true) - || (encoding.isConstructed() != true)) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - der = encoding.getData().getDerValue(); - if (der.getTag() != DerValue.tag_Sequence) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & (byte)0x1F) != (byte)0x00) + /** + * Initializes an APReq object. + * @param encoding a single DER-encoded value. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * @exception KrbApErrException if the value read from the DER-encoded data stream does not match the pre-defined value. + * @exception RealmException if an error occurs while parsing a Realm object. + */ + private void init(DerValue encoding) throws Asn1Exception, + IOException, KrbApErrException, RealmException { + DerValue der, subDer; + if (((encoding.getTag() & (byte) 0x1F) != Krb5.KRB_AP_REQ) + || (encoding.isApplication() != true) + || (encoding.isConstructed() != true)) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + der = encoding.getData().getDerValue(); + if (der.getTag() != DerValue.tag_Sequence) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & (byte) 0x1F) != (byte) 0x00) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } pvno = subDer.getData().getBigInteger().intValue(); - if (pvno != Krb5.PVNO) - throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION); - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & (byte)0x1F) != (byte)0x01) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - msgType = subDer.getData().getBigInteger().intValue(); - if (msgType != Krb5.KRB_AP_REQ) - throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE); - apOptions = APOptions.parse(der.getData(), (byte)0x02, false); - ticket = Ticket.parse(der.getData(), (byte)0x03, false); - authenticator = EncryptedData.parse(der.getData(), (byte)0x04, false); - if (der.getData().available() > 0) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); + if (pvno != Krb5.PVNO) { + throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION); } - - /** - * Encodes an APReq object. - * @return byte array of encoded APReq object. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ - public byte[] asn1Encode() throws Asn1Exception, IOException { - DerOutputStream bytes = new DerOutputStream(); - DerOutputStream temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(pvno)); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp); - temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(msgType)); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), apOptions.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), ticket.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), authenticator.asn1Encode()); - temp = new DerOutputStream(); - temp.write(DerValue.tag_Sequence, bytes); - DerOutputStream apreq = new DerOutputStream(); - apreq.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x0E), temp); - return apreq.toByteArray(); - + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & (byte) 0x1F) != (byte) 0x01) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); } + msgType = subDer.getData().getBigInteger().intValue(); + if (msgType != Krb5.KRB_AP_REQ) { + throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE); + } + apOptions = APOptions.parse(der.getData(), (byte) 0x02, false); + ticket = Ticket.parse(der.getData(), (byte) 0x03, false); + authenticator = EncryptedData.parse(der.getData(), (byte) 0x04, false); + if (der.getData().available() > 0) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + } + /** + * Encodes an APReq object. + * @return byte array of encoded APReq object. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + public byte[] asn1Encode() throws Asn1Exception, IOException { + DerOutputStream bytes = new DerOutputStream(); + DerOutputStream temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(pvno)); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x00), temp); + temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(msgType)); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x01), temp); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x02), apOptions.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x03), ticket.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x04), authenticator.asn1Encode()); + temp = new DerOutputStream(); + temp.write(DerValue.tag_Sequence, bytes); + DerOutputStream apreq = new DerOutputStream(); + apreq.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte) 0x0E), temp); + return apreq.toByteArray(); + } } diff --git a/src/share/classes/sun/security/krb5/internal/ASRep.java b/src/share/classes/sun/security/krb5/internal/ASRep.java index df0ebac655062ee4828eeae58880de2a7bb0fa92..a59811d97f9a88467fe736bc4ae03758ca77805a 100644 --- a/src/share/classes/sun/security/krb5/internal/ASRep.java +++ b/src/share/classes/sun/security/krb5/internal/ASRep.java @@ -40,30 +40,28 @@ import java.io.IOException; public class ASRep extends KDCRep { - public ASRep( - PAData[] new_pAData, - Realm new_crealm, - PrincipalName new_cname, - Ticket new_ticket, - EncryptedData new_encPart - ) throws IOException { - super(new_pAData, new_crealm, new_cname, new_ticket, - new_encPart, Krb5.KRB_AS_REP); - } + public ASRep( + PAData[] new_pAData, + Realm new_crealm, + PrincipalName new_cname, + Ticket new_ticket, + EncryptedData new_encPart) throws IOException { + super(new_pAData, new_crealm, new_cname, new_ticket, + new_encPart, Krb5.KRB_AS_REP); + } - public ASRep(byte[] data) throws Asn1Exception, - RealmException, KrbApErrException, IOException { - init(new DerValue(data)); - } + public ASRep(byte[] data) throws Asn1Exception, + RealmException, KrbApErrException, IOException { + init(new DerValue(data)); + } - public ASRep(DerValue encoding) throws Asn1Exception, - RealmException, KrbApErrException, IOException { - init(encoding); - } - - private void init(DerValue encoding) throws Asn1Exception, - RealmException, KrbApErrException, IOException { - init(encoding, Krb5.KRB_AS_REP); - } + public ASRep(DerValue encoding) throws Asn1Exception, + RealmException, KrbApErrException, IOException { + init(encoding); + } + private void init(DerValue encoding) throws Asn1Exception, + RealmException, KrbApErrException, IOException { + init(encoding, Krb5.KRB_AS_REP); + } } diff --git a/src/share/classes/sun/security/krb5/internal/ASReq.java b/src/share/classes/sun/security/krb5/internal/ASReq.java index 743316c6c0c9109d794165952944a0b69bb028d6..b5907398bf71a2e6804ac998ca8a6cb96080bbe5 100644 --- a/src/share/classes/sun/security/krb5/internal/ASReq.java +++ b/src/share/classes/sun/security/krb5/internal/ASReq.java @@ -36,20 +36,19 @@ import java.io.IOException; public class ASReq extends KDCReq { - public ASReq(PAData[] new_pAData, KDCReqBody new_reqBody) throws IOException { - super(new_pAData, new_reqBody, Krb5.KRB_AS_REQ); - } + public ASReq(PAData[] new_pAData, KDCReqBody new_reqBody) throws IOException { + super(new_pAData, new_reqBody, Krb5.KRB_AS_REQ); + } - public ASReq(byte[] data) throws Asn1Exception, KrbException, IOException { - init(new DerValue(data)); - } + public ASReq(byte[] data) throws Asn1Exception, KrbException, IOException { + init(new DerValue(data)); + } public ASReq(DerValue encoding) throws Asn1Exception, KrbException, IOException { - init(encoding); - } - - private void init(DerValue encoding) throws Asn1Exception, IOException, KrbException { - super.init(encoding, Krb5.KRB_AS_REQ); - } + init(encoding); + } + private void init(DerValue encoding) throws Asn1Exception, IOException, KrbException { + super.init(encoding, Krb5.KRB_AS_REQ); + } } diff --git a/src/share/classes/sun/security/krb5/internal/Authenticator.java b/src/share/classes/sun/security/krb5/internal/Authenticator.java index 57b6156c0e5e2342d09eee273dcc6baa94c7ed3e..49cf1709ee2c3bca33acc9c7a81d0c63a9a1236d 100644 --- a/src/share/classes/sun/security/krb5/internal/Authenticator.java +++ b/src/share/classes/sun/security/krb5/internal/Authenticator.java @@ -34,6 +34,7 @@ import sun.security.util.*; import java.util.Vector; import java.io.IOException; import java.math.BigInteger; + /** * Implements the ASN.1 Authenticator type. * @@ -58,6 +59,7 @@ import java.math.BigInteger; * http://www.ietf.org/rfc/rfc4120.txt. */ public class Authenticator { + public int authenticator_vno; public Realm crealm; public PrincipalName cname; @@ -68,137 +70,145 @@ public class Authenticator { Integer seqNumber; //optional public AuthorizationData authorizationData; //optional - public Authenticator ( - Realm new_crealm, - PrincipalName new_cname, - Checksum new_cksum, - int new_cusec, - KerberosTime new_ctime, - EncryptionKey new_subKey, - Integer new_seqNumber, - AuthorizationData new_authorizationData - ) { - authenticator_vno = Krb5.AUTHNETICATOR_VNO; - crealm = new_crealm; - cname = new_cname; - cksum = new_cksum; - cusec = new_cusec; - ctime = new_ctime; - subKey = new_subKey; - seqNumber = new_seqNumber; - authorizationData = new_authorizationData; - } + public Authenticator( + Realm new_crealm, + PrincipalName new_cname, + Checksum new_cksum, + int new_cusec, + KerberosTime new_ctime, + EncryptionKey new_subKey, + Integer new_seqNumber, + AuthorizationData new_authorizationData) { + authenticator_vno = Krb5.AUTHNETICATOR_VNO; + crealm = new_crealm; + cname = new_cname; + cksum = new_cksum; + cusec = new_cusec; + ctime = new_ctime; + subKey = new_subKey; + seqNumber = new_seqNumber; + authorizationData = new_authorizationData; + } - public Authenticator(byte[] data) - throws Asn1Exception, IOException, KrbApErrException, RealmException { - init(new DerValue(data)); - } + public Authenticator(byte[] data) + throws Asn1Exception, IOException, KrbApErrException, RealmException { + init(new DerValue(data)); + } - public Authenticator(DerValue encoding) - throws Asn1Exception,IOException, KrbApErrException, RealmException { - init(encoding); - } + public Authenticator(DerValue encoding) + throws Asn1Exception, IOException, KrbApErrException, RealmException { + init(encoding); + } - /** - * Initializes an Authenticator object. - * @param encoding a single DER-encoded value. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * @exception KrbApErrException if the value read from the DER-encoded data - * stream does not match the pre-defined value. - * @exception RealmException if an error occurs while parsing a Realm object. - */ - private void init(DerValue encoding) - throws Asn1Exception, IOException, KrbApErrException, RealmException { - DerValue der, subDer; - //may not be the correct error code for a tag - //mismatch on an encrypted structure - if (((encoding.getTag() & (byte)0x1F) != (byte)0x02) - || (encoding.isApplication() != true) - || (encoding.isConstructed() != true)) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - der = encoding.getData().getDerValue(); - if (der.getTag() != DerValue.tag_Sequence) + /** + * Initializes an Authenticator object. + * @param encoding a single DER-encoded value. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * @exception KrbApErrException if the value read from the DER-encoded data + * stream does not match the pre-defined value. + * @exception RealmException if an error occurs while parsing a Realm object. + */ + private void init(DerValue encoding) + throws Asn1Exception, IOException, KrbApErrException, RealmException { + DerValue der, subDer; + //may not be the correct error code for a tag + //mismatch on an encrypted structure + if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x02) + || (encoding.isApplication() != true) + || (encoding.isConstructed() != true)) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & (byte)0x1F) != (byte)0x00) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + der = encoding.getData().getDerValue(); + if (der.getTag() != DerValue.tag_Sequence) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & (byte) 0x1F) != (byte) 0x00) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } authenticator_vno = subDer.getData().getBigInteger().intValue(); - if (authenticator_vno != 5) + if (authenticator_vno != 5) { throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION); - crealm = Realm.parse(der.getData(), (byte)0x01, false); - cname = PrincipalName.parse(der.getData(), (byte)0x02, false); - cksum = Checksum.parse(der.getData(), (byte)0x03, true); + } + crealm = Realm.parse(der.getData(), (byte) 0x01, false); + cname = PrincipalName.parse(der.getData(), (byte) 0x02, false); + cksum = Checksum.parse(der.getData(), (byte) 0x03, true); + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & (byte) 0x1F) == 0x04) { + cusec = subDer.getData().getBigInteger().intValue(); + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + ctime = KerberosTime.parse(der.getData(), (byte) 0x05, false); + if (der.getData().available() > 0) { + subKey = EncryptionKey.parse(der.getData(), (byte) 0x06, true); + } else { + subKey = null; + seqNumber = null; + authorizationData = null; + } + if (der.getData().available() > 0) { + if ((der.getData().peekByte() & 0x1F) == 0x07) { subDer = der.getData().getDerValue(); - if ((subDer.getTag() & (byte)0x1F) == 0x04) { - cusec = subDer.getData().getBigInteger().intValue(); - } - else throw new Asn1Exception(Krb5.ASN1_BAD_ID); - ctime = KerberosTime.parse(der.getData(), (byte)0x05, false); - if (der.getData().available() > 0) { - subKey = EncryptionKey.parse(der.getData(), (byte)0x06, true); - } - else { - subKey = null; - seqNumber = null; - authorizationData = null; - } - if (der.getData().available() > 0) { - if ((der.getData().peekByte() & 0x1F) == 0x07) { - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & (byte)0x1F) == (byte)0x07) - seqNumber = new Integer(subDer.getData().getBigInteger().intValue()); - } + if ((subDer.getTag() & (byte) 0x1F) == (byte) 0x07) { + seqNumber = new Integer(subDer.getData().getBigInteger().intValue()); } - else { - seqNumber = null; - authorizationData = null; - } - if (der.getData().available() > 0) { - authorizationData = AuthorizationData.parse(der.getData(), (byte)0x08, true); - } - else authorizationData = null; - if (der.getData().available() > 0) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + } else { + seqNumber = null; + authorizationData = null; + } + if (der.getData().available() > 0) { + authorizationData = AuthorizationData.parse(der.getData(), (byte) 0x08, true); + } else { + authorizationData = null; + } + if (der.getData().available() > 0) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); } + } - /** - * Encodes an Authenticator object. - * @return byte array of encoded Authenticator object. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ - public byte[] asn1Encode() throws Asn1Exception, IOException { - Vector v = new Vector (); - DerOutputStream temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(authenticator_vno)); - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp.toByteArray())); - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), crealm.asn1Encode())); - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), cname.asn1Encode())); - if (cksum != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), cksum.asn1Encode())); - temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(cusec)); - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), temp.toByteArray())); - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), ctime.asn1Encode())); - if (subKey != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), subKey.asn1Encode())); - if (seqNumber != null) { - temp = new DerOutputStream(); - // encode as an unsigned integer (UInt32) - temp.putInteger(BigInteger.valueOf(seqNumber.longValue())); - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x07), temp.toByteArray())); - } - if (authorizationData != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x08), authorizationData.asn1Encode())); - DerValue der[] = new DerValue[v.size()]; - v.copyInto(der); - temp = new DerOutputStream(); - temp.putSequence(der); - DerOutputStream out = new DerOutputStream(); - out.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x02), temp); - return out.toByteArray(); + /** + * Encodes an Authenticator object. + * @return byte array of encoded Authenticator object. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + public byte[] asn1Encode() throws Asn1Exception, IOException { + Vector v = new Vector(); + DerOutputStream temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(authenticator_vno)); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x00), temp.toByteArray())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x01), crealm.asn1Encode())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x02), cname.asn1Encode())); + if (cksum != null) { + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x03), cksum.asn1Encode())); + } + temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(cusec)); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x04), temp.toByteArray())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x05), ctime.asn1Encode())); + if (subKey != null) { + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x06), subKey.asn1Encode())); } + if (seqNumber != null) { + temp = new DerOutputStream(); + // encode as an unsigned integer (UInt32) + temp.putInteger(BigInteger.valueOf(seqNumber.longValue())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x07), temp.toByteArray())); + } + if (authorizationData != null) { + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x08), authorizationData.asn1Encode())); + } + DerValue der[] = new DerValue[v.size()]; + v.copyInto(der); + temp = new DerOutputStream(); + temp.putSequence(der); + DerOutputStream out = new DerOutputStream(); + out.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte) 0x02), temp); + return out.toByteArray(); + } public final Checksum getChecksum() { return cksum; @@ -211,5 +221,4 @@ public class Authenticator { public final EncryptionKey getSubKey() { return subKey; } - } diff --git a/src/share/classes/sun/security/krb5/internal/AuthorizationData.java b/src/share/classes/sun/security/krb5/internal/AuthorizationData.java index d6f04d748b521c1a3e0ca14cd5fb7830721eec28..269edec71a1500d9843a2f3186253227fd404312 100644 --- a/src/share/classes/sun/security/krb5/internal/AuthorizationData.java +++ b/src/share/classes/sun/security/krb5/internal/AuthorizationData.java @@ -53,82 +53,81 @@ import sun.security.krb5.internal.ccache.CCacheOutputStream; * } */ public class AuthorizationData implements Cloneable { - private AuthorizationDataEntry[] entry = null; - private AuthorizationData() { - } + private AuthorizationDataEntry[] entry = null; + + private AuthorizationData() { + } - public AuthorizationData( - AuthorizationDataEntry[] new_entries - ) throws IOException { - if (new_entries != null) { - entry = new AuthorizationDataEntry[new_entries.length]; - for (int i = 0; i < new_entries.length; i++) { - if (new_entries[i] == null) { - throw new IOException("Cannot create an AuthorizationData"); - } else { - entry[i] = (AuthorizationDataEntry)new_entries[i].clone(); - } - } + public AuthorizationData(AuthorizationDataEntry[] new_entries) + throws IOException { + if (new_entries != null) { + entry = new AuthorizationDataEntry[new_entries.length]; + for (int i = 0; i < new_entries.length; i++) { + if (new_entries[i] == null) { + throw new IOException("Cannot create an AuthorizationData"); + } else { + entry[i] = (AuthorizationDataEntry) new_entries[i].clone(); } + } } + } - public AuthorizationData( - AuthorizationDataEntry new_entry - ) { - entry = new AuthorizationDataEntry[1]; - entry[0] = new_entry; - } + public AuthorizationData(AuthorizationDataEntry new_entry) { + entry = new AuthorizationDataEntry[1]; + entry[0] = new_entry; + } - public Object clone() { - AuthorizationData new_authorizationData = - new AuthorizationData(); - if (entry != null) { - new_authorizationData.entry = - new AuthorizationDataEntry[entry.length]; - for (int i = 0; i < entry.length; i++) - new_authorizationData.entry[i] = - (AuthorizationDataEntry)entry[i].clone(); - } - return new_authorizationData; + public Object clone() { + AuthorizationData new_authorizationData = + new AuthorizationData(); + if (entry != null) { + new_authorizationData.entry = + new AuthorizationDataEntry[entry.length]; + for (int i = 0; i < entry.length; i++) { + new_authorizationData.entry[i] = + (AuthorizationDataEntry) entry[i].clone(); + } } + return new_authorizationData; + } - /** - * Constructs a new AuthorizationData, instance. - * @param der a single DER-encoded value. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ - public AuthorizationData(DerValue der) throws Asn1Exception, IOException { - Vector v = - new Vector (); - if (der.getTag() != DerValue.tag_Sequence) { - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - } - while (der.getData().available() > 0) { - v.addElement(new AuthorizationDataEntry(der.getData().getDerValue())); - } - if (v.size() > 0) { - entry = new AuthorizationDataEntry[v.size()]; - v.copyInto(entry); - } + /** + * Constructs a new AuthorizationData, instance. + * @param der a single DER-encoded value. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + public AuthorizationData(DerValue der) throws Asn1Exception, IOException { + Vector v = + new Vector(); + if (der.getTag() != DerValue.tag_Sequence) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + while (der.getData().available() > 0) { + v.addElement(new AuthorizationDataEntry(der.getData().getDerValue())); } + if (v.size() > 0) { + entry = new AuthorizationDataEntry[v.size()]; + v.copyInto(entry); + } + } - /** - * Encodes an AuthorizationData object. - * @return byte array of encoded AuthorizationData object. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ - public byte[] asn1Encode() throws Asn1Exception, IOException { - DerOutputStream bytes = new DerOutputStream(); - DerValue der[] = new DerValue[entry.length]; - for (int i = 0; i < entry.length; i++) { - der[i] = new DerValue(entry[i].asn1Encode()); - } - bytes.putSequence(der); - return bytes.toByteArray(); + /** + * Encodes an AuthorizationData object. + * @return byte array of encoded AuthorizationData object. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + public byte[] asn1Encode() throws Asn1Exception, IOException { + DerOutputStream bytes = new DerOutputStream(); + DerValue der[] = new DerValue[entry.length]; + for (int i = 0; i < entry.length; i++) { + der[i] = new DerValue(entry[i].asn1Encode()); } + bytes.putSequence(der); + return bytes.toByteArray(); + } /** * Parse (unmarshal) an AuthorizationData object from a DER input stream. @@ -143,31 +142,30 @@ public class AuthorizationData implements Cloneable { * @return an instance of AuthorizationData. * */ - public static AuthorizationData parse(DerInputStream data, byte explicitTag, boolean optional) throws Asn1Exception, IOException{ - if ((optional) && (((byte)data.peekByte() & (byte)0x1F) != explicitTag)) { - return null; - } - DerValue der = data.getDerValue(); - if (explicitTag != (der.getTag() & (byte)0x1F)) { - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - } - else { - DerValue subDer = der.getData().getDerValue(); - return new AuthorizationData(subDer); - } + public static AuthorizationData parse(DerInputStream data, byte explicitTag, boolean optional) throws Asn1Exception, IOException { + if ((optional) && (((byte) data.peekByte() & (byte) 0x1F) != explicitTag)) { + return null; + } + DerValue der = data.getDerValue(); + if (explicitTag != (der.getTag() & (byte) 0x1F)) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } else { + DerValue subDer = der.getData().getDerValue(); + return new AuthorizationData(subDer); } + } - /** - * Writes AuthorizationData data fields to a output stream. - * - * @param cos a CCacheOutputStream to be written to. - * @exception IOException if an I/O exception occurs. - */ - public void writeAuth(CCacheOutputStream cos) throws IOException { - for (int i = 0; i < entry.length; i++) { - entry[i].writeEntry(cos); - } + /** + * Writes AuthorizationData data fields to a output stream. + * + * @param cos a CCacheOutputStream to be written to. + * @exception IOException if an I/O exception occurs. + */ + public void writeAuth(CCacheOutputStream cos) throws IOException { + for (int i = 0; i < entry.length; i++) { + entry[i].writeEntry(cos); } + } public String toString() { String retVal = "AuthorizationData:\n"; diff --git a/src/share/classes/sun/security/krb5/internal/AuthorizationDataEntry.java b/src/share/classes/sun/security/krb5/internal/AuthorizationDataEntry.java index 3ad64576175750ed08dbb0ca8f6b94bbdd6e4465..e159c85fc00947bec63608e1b5aaaa3bcccf6a30 100644 --- a/src/share/classes/sun/security/krb5/internal/AuthorizationDataEntry.java +++ b/src/share/classes/sun/security/krb5/internal/AuthorizationDataEntry.java @@ -35,90 +35,90 @@ import sun.security.krb5.Asn1Exception; import sun.security.krb5.internal.ccache.CCacheOutputStream; public class AuthorizationDataEntry implements Cloneable { - public int adType; - public byte[] adData; - private AuthorizationDataEntry() { - } + public int adType; + public byte[] adData; - public AuthorizationDataEntry( - int new_adType, - byte[] new_adData - ) { - adType = new_adType; - adData = new_adData; - } + private AuthorizationDataEntry() { + } + + public AuthorizationDataEntry( + int new_adType, + byte[] new_adData) { + adType = new_adType; + adData = new_adData; + } - public Object clone() { - AuthorizationDataEntry new_authorizationDataEntry = - new AuthorizationDataEntry(); - new_authorizationDataEntry.adType = adType; - if (adData != null) { - new_authorizationDataEntry.adData = new byte[adData.length]; - System.arraycopy(adData, 0, - new_authorizationDataEntry.adData, 0, adData.length); - } - return new_authorizationDataEntry; + public Object clone() { + AuthorizationDataEntry new_authorizationDataEntry = + new AuthorizationDataEntry(); + new_authorizationDataEntry.adType = adType; + if (adData != null) { + new_authorizationDataEntry.adData = new byte[adData.length]; + System.arraycopy(adData, 0, + new_authorizationDataEntry.adData, 0, adData.length); } + return new_authorizationDataEntry; + } - /** - * Constructs an instance of AuthorizationDataEntry. - * @param encoding a single DER-encoded value. - */ - public AuthorizationDataEntry(DerValue encoding) throws Asn1Exception, IOException { - DerValue der; + /** + * Constructs an instance of AuthorizationDataEntry. + * @param encoding a single DER-encoded value. + */ + public AuthorizationDataEntry(DerValue encoding) throws Asn1Exception, IOException { + DerValue der; if (encoding.getTag() != DerValue.tag_Sequence) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); - } - der = encoding.getData().getDerValue(); - if ((der.getTag() & (byte)0x1F) == (byte)0x00) { - adType = der.getData().getBigInteger().intValue(); - } - else - throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } der = encoding.getData().getDerValue(); - if ((der.getTag() & (byte)0x1F) == (byte)0x01) { - adData = der.getData().getOctetString(); - } - else - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - if (encoding.getData().available() > 0) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); + if ((der.getTag() & (byte) 0x1F) == (byte) 0x00) { + adType = der.getData().getBigInteger().intValue(); + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); } + der = encoding.getData().getDerValue(); + if ((der.getTag() & (byte) 0x1F) == (byte) 0x01) { + adData = der.getData().getOctetString(); + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + if (encoding.getData().available() > 0) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + } - /** - * Encodes an AuthorizationDataEntry object. - * @return byte array of encoded AuthorizationDataEntry object. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ - public byte[] asn1Encode() throws Asn1Exception, IOException { + /** + * Encodes an AuthorizationDataEntry object. + * @return byte array of encoded AuthorizationDataEntry object. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + public byte[] asn1Encode() throws Asn1Exception, IOException { DerOutputStream bytes = new DerOutputStream(); - DerOutputStream temp = new DerOutputStream(); - temp.putInteger(adType); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp); - temp = new DerOutputStream(); - temp.putOctetString(adData); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp); - temp = new DerOutputStream(); - temp.write(DerValue.tag_Sequence, bytes); - return temp.toByteArray(); - } + DerOutputStream temp = new DerOutputStream(); + temp.putInteger(adType); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x00), temp); + temp = new DerOutputStream(); + temp.putOctetString(adData); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x01), temp); + temp = new DerOutputStream(); + temp.write(DerValue.tag_Sequence, bytes); + return temp.toByteArray(); + } - /** - * Writes the entry's data fields in FCC format to an output stream. - * - * @param cos a CCacheOutputStream. - * @exception IOException if an I/O exception occurs. - */ - public void writeEntry(CCacheOutputStream cos) throws IOException { - cos.write16(adType); - cos.write32(adData.length); - cos.write(adData, 0, adData.length); - } + /** + * Writes the entry's data fields in FCC format to an output stream. + * + * @param cos a CCacheOutputStream. + * @exception IOException if an I/O exception occurs. + */ + public void writeEntry(CCacheOutputStream cos) throws IOException { + cos.write16(adType); + cos.write32(adData.length); + cos.write(adData, 0, adData.length); + } public String toString() { return ("adType=" + adType + " adData.length=" + adData.length); } - } diff --git a/src/share/classes/sun/security/krb5/internal/ETypeInfo2.java b/src/share/classes/sun/security/krb5/internal/ETypeInfo2.java index 110e38b080667545709f475ec453f6a331eb6d8d..30bf4dfb3c9ee49a9853408a555e64e301944280 100644 --- a/src/share/classes/sun/security/krb5/internal/ETypeInfo2.java +++ b/src/share/classes/sun/security/krb5/internal/ETypeInfo2.java @@ -100,16 +100,16 @@ public class ETypeInfo2 { // salt if (encoding.getData().available() > 0) { - der = encoding.getData().getDerValue(); - if ((der.getTag() & 0x1F) == 0x01) { + if ((encoding.getData().peekByte() & 0x1F) == 0x01) { + der = encoding.getData().getDerValue(); this.saltStr = der.getData().getGeneralString(); } } // s2kparams if (encoding.getData().available() > 0) { - der = encoding.getData().getDerValue(); - if ((der.getTag() & 0x1F) == 0x02) { + if ((encoding.getData().peekByte() & 0x1F) == 0x02) { + der = encoding.getData().getDerValue(); this.s2kparams = der.getData().getOctetString(); } } diff --git a/src/share/classes/sun/security/krb5/internal/EncAPRepPart.java b/src/share/classes/sun/security/krb5/internal/EncAPRepPart.java index 1d3381797e04bbaf89fe93690ceb182dc5463e77..b3dcf144159854736fa264c9aad8036f46c45758 100644 --- a/src/share/classes/sun/security/krb5/internal/EncAPRepPart.java +++ b/src/share/classes/sun/security/krb5/internal/EncAPRepPart.java @@ -55,102 +55,111 @@ import java.math.BigInteger; * http://www.ietf.org/rfc/rfc4120.txt. */ public class EncAPRepPart { - public KerberosTime ctime; - public int cusec; + + public KerberosTime ctime; + public int cusec; EncryptionKey subKey; //optional Integer seqNumber; //optional - public EncAPRepPart( - KerberosTime new_ctime, - int new_cusec, - EncryptionKey new_subKey, - Integer new_seqNumber - ) { - ctime = new_ctime; - cusec = new_cusec; - subKey = new_subKey; - seqNumber = new_seqNumber; - } + public EncAPRepPart( + KerberosTime new_ctime, + int new_cusec, + EncryptionKey new_subKey, + Integer new_seqNumber) { + ctime = new_ctime; + cusec = new_cusec; + subKey = new_subKey; + seqNumber = new_seqNumber; + } - public EncAPRepPart(byte[] data) - throws Asn1Exception, IOException { - init(new DerValue(data)); - } + public EncAPRepPart(byte[] data) + throws Asn1Exception, IOException { + init(new DerValue(data)); + } - public EncAPRepPart(DerValue encoding) - throws Asn1Exception, IOException { - init(encoding); - } + public EncAPRepPart(DerValue encoding) + throws Asn1Exception, IOException { + init(encoding); + } - /** - * Initializes an EncaPRepPart object. - * @param encoding a single DER-encoded value. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ - private void init(DerValue encoding) throws Asn1Exception, IOException { - DerValue der, subDer; - if (((encoding.getTag() & (byte)0x1F) != (byte)0x1B) - || (encoding.isApplication() != true) - || (encoding.isConstructed() != true)) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); + /** + * Initializes an EncaPRepPart object. + * @param encoding a single DER-encoded value. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + private void init(DerValue encoding) throws Asn1Exception, IOException { + DerValue der, subDer; + if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x1B) + || (encoding.isApplication() != true) + || (encoding.isConstructed() != true)) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } der = encoding.getData().getDerValue(); - if (der.getTag() != DerValue.tag_Sequence) + if (der.getTag() != DerValue.tag_Sequence) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + ctime = KerberosTime.parse(der.getData(), (byte) 0x00, true); + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & (byte) 0x1F) == (byte) 0x01) { + cusec = subDer.getData().getBigInteger().intValue(); + } else { throw new Asn1Exception(Krb5.ASN1_BAD_ID); - ctime = KerberosTime.parse(der.getData(), (byte)0x00, true); - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & (byte)0x1F) == (byte)0x01) { - cusec = subDer.getData().getBigInteger().intValue(); - } - else - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - if (der.getData().available() > 0) { - subKey = EncryptionKey.parse(der.getData(), (byte)0x02, true); - } - else { - subKey = null; - seqNumber = null; - } - if (der.getData().available() > 0) { - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & 0x1F) != 0x03) { - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - } - seqNumber = new Integer(subDer.getData().getBigInteger().intValue()); - } - else seqNumber = null; - if (der.getData().available() > 0) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); } + if (der.getData().available() > 0) { + subKey = EncryptionKey.parse(der.getData(), (byte) 0x02, true); + } else { + subKey = null; + seqNumber = null; + } + if (der.getData().available() > 0) { + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & 0x1F) != 0x03) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + seqNumber = new Integer(subDer.getData().getBigInteger().intValue()); + } else { + seqNumber = null; + } + if (der.getData().available() > 0) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + } - /** - * Encodes an EncAPRepPart object. - * @return byte array of encoded EncAPRepPart object. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ - public byte[] asn1Encode() throws Asn1Exception, IOException{ - Vector v = new Vector (); + /** + * Encodes an EncAPRepPart object. + * @return byte array of encoded EncAPRepPart object. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + public byte[] asn1Encode() throws Asn1Exception, IOException { + Vector v = new Vector(); DerOutputStream temp = new DerOutputStream(); - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), ctime.asn1Encode())); - temp.putInteger(BigInteger.valueOf(cusec)); - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp.toByteArray())); - if (subKey != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), subKey.asn1Encode())); - if (seqNumber != null) { - temp = new DerOutputStream(); - // encode as an unsigned integer (UInt32) - temp.putInteger(BigInteger.valueOf(seqNumber.longValue())); - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), temp.toByteArray())); - } - DerValue der[] = new DerValue[v.size()]; - v.copyInto(der); - temp = new DerOutputStream(); - temp.putSequence(der); - DerOutputStream out = new DerOutputStream(); - out.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x1B), temp); - return out.toByteArray(); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x00), ctime.asn1Encode())); + temp.putInteger(BigInteger.valueOf(cusec)); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x01), temp.toByteArray())); + if (subKey != null) { + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x02), subKey.asn1Encode())); + } + if (seqNumber != null) { + temp = new DerOutputStream(); + // encode as an unsigned integer (UInt32) + temp.putInteger(BigInteger.valueOf(seqNumber.longValue())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x03), temp.toByteArray())); } + DerValue der[] = new DerValue[v.size()]; + v.copyInto(der); + temp = new DerOutputStream(); + temp.putSequence(der); + DerOutputStream out = new DerOutputStream(); + out.write(DerValue.createTag(DerValue.TAG_APPLICATION, + true, (byte) 0x1B), temp); + return out.toByteArray(); + } public final EncryptionKey getSubKey() { return subKey; @@ -159,5 +168,4 @@ public class EncAPRepPart { public final Integer getSeqNumber() { return seqNumber; } - } diff --git a/src/share/classes/sun/security/krb5/internal/EncASRepPart.java b/src/share/classes/sun/security/krb5/internal/EncASRepPart.java index b5526e8014d5260c55c8a4ca69626cd9b919b25e..b71238fef5110bd30e5a19eb328a3f4cf23aa042 100644 --- a/src/share/classes/sun/security/krb5/internal/EncASRepPart.java +++ b/src/share/classes/sun/security/krb5/internal/EncASRepPart.java @@ -36,57 +36,55 @@ import java.io.IOException; public class EncASRepPart extends EncKDCRepPart { - public EncASRepPart( - EncryptionKey new_key, - LastReq new_lastReq, - int new_nonce, - KerberosTime new_keyExpiration, - TicketFlags new_flags, - KerberosTime new_authtime, - KerberosTime new_starttime, - KerberosTime new_endtime, - KerberosTime new_renewTill, - Realm new_srealm, - PrincipalName new_sname, - HostAddresses new_caddr - ) { - super( - new_key, - new_lastReq, - new_nonce, - new_keyExpiration, - new_flags, - new_authtime, - new_starttime, - new_endtime, - new_renewTill, - new_srealm, - new_sname, - new_caddr, - Krb5.KRB_ENC_AS_REP_PART - //may need to use Krb5.KRB_ENC_TGS_REP_PART to mimic - //behavior of other implementaions, instead of above + public EncASRepPart( + EncryptionKey new_key, + LastReq new_lastReq, + int new_nonce, + KerberosTime new_keyExpiration, + TicketFlags new_flags, + KerberosTime new_authtime, + KerberosTime new_starttime, + KerberosTime new_endtime, + KerberosTime new_renewTill, + Realm new_srealm, + PrincipalName new_sname, + HostAddresses new_caddr) { + super( + new_key, + new_lastReq, + new_nonce, + new_keyExpiration, + new_flags, + new_authtime, + new_starttime, + new_endtime, + new_renewTill, + new_srealm, + new_sname, + new_caddr, + Krb5.KRB_ENC_AS_REP_PART ); - } + //may need to use Krb5.KRB_ENC_TGS_REP_PART to mimic + //behavior of other implementaions, instead of above + } - public EncASRepPart(byte[] data) throws Asn1Exception, - IOException, KrbException { - init(new DerValue(data)); - } + public EncASRepPart(byte[] data) throws Asn1Exception, + IOException, KrbException { + init(new DerValue(data)); + } - public EncASRepPart(DerValue encoding) throws Asn1Exception, - IOException, KrbException { - init(encoding); - } + public EncASRepPart(DerValue encoding) throws Asn1Exception, + IOException, KrbException { + init(encoding); + } - private void init(DerValue encoding) throws Asn1Exception, - IOException, KrbException { - init(encoding, Krb5.KRB_ENC_AS_REP_PART); - } - - public byte[] asn1Encode() throws Asn1Exception, - IOException { - return asn1Encode(Krb5.KRB_ENC_AS_REP_PART); - } + private void init(DerValue encoding) throws Asn1Exception, + IOException, KrbException { + init(encoding, Krb5.KRB_ENC_AS_REP_PART); + } + public byte[] asn1Encode() throws Asn1Exception, + IOException { + return asn1Encode(Krb5.KRB_ENC_AS_REP_PART); + } } diff --git a/src/share/classes/sun/security/krb5/internal/EncKDCRepPart.java b/src/share/classes/sun/security/krb5/internal/EncKDCRepPart.java index 35081a0051cd8459bffec558fdf9a8922001b359..e7723a41c4236dce939871a8b41ab5a0bdae739e 100644 --- a/src/share/classes/sun/security/krb5/internal/EncKDCRepPart.java +++ b/src/share/classes/sun/security/krb5/internal/EncKDCRepPart.java @@ -36,6 +36,7 @@ import sun.security.util.*; import java.util.Vector; import java.io.IOException; import java.math.BigInteger; + /** * Implements the ASN.1 EncKDCRepPart type. * @@ -63,143 +64,163 @@ import java.math.BigInteger; * http://www.ietf.org/rfc/rfc4120.txt. */ public class EncKDCRepPart { - public EncryptionKey key; - public LastReq lastReq; - public int nonce; - public KerberosTime keyExpiration; //optional - public TicketFlags flags; - public KerberosTime authtime; - public KerberosTime starttime; //optional - public KerberosTime endtime; - public KerberosTime renewTill; //optional - public Realm srealm; - public PrincipalName sname; - public HostAddresses caddr; //optional - public int msgType; //not included in sequence - public EncKDCRepPart( - EncryptionKey new_key, - LastReq new_lastReq, - int new_nonce, - KerberosTime new_keyExpiration, - TicketFlags new_flags, - KerberosTime new_authtime, - KerberosTime new_starttime, - KerberosTime new_endtime, - KerberosTime new_renewTill, - Realm new_srealm, - PrincipalName new_sname, - HostAddresses new_caddr, - int new_msgType - ) { - key = new_key; - lastReq = new_lastReq; - nonce = new_nonce; - keyExpiration = new_keyExpiration; - flags = new_flags; - authtime = new_authtime; - starttime = new_starttime; - endtime = new_endtime; - renewTill = new_renewTill; - srealm = new_srealm; - sname = new_sname; - caddr = new_caddr; - msgType = new_msgType; - } + public EncryptionKey key; + public LastReq lastReq; + public int nonce; + public KerberosTime keyExpiration; //optional + public TicketFlags flags; + public KerberosTime authtime; + public KerberosTime starttime; //optional + public KerberosTime endtime; + public KerberosTime renewTill; //optional + public Realm srealm; + public PrincipalName sname; + public HostAddresses caddr; //optional + public int msgType; //not included in sequence - public EncKDCRepPart() { - } + public EncKDCRepPart( + EncryptionKey new_key, + LastReq new_lastReq, + int new_nonce, + KerberosTime new_keyExpiration, + TicketFlags new_flags, + KerberosTime new_authtime, + KerberosTime new_starttime, + KerberosTime new_endtime, + KerberosTime new_renewTill, + Realm new_srealm, + PrincipalName new_sname, + HostAddresses new_caddr, + int new_msgType) { + key = new_key; + lastReq = new_lastReq; + nonce = new_nonce; + keyExpiration = new_keyExpiration; + flags = new_flags; + authtime = new_authtime; + starttime = new_starttime; + endtime = new_endtime; + renewTill = new_renewTill; + srealm = new_srealm; + sname = new_sname; + caddr = new_caddr; + msgType = new_msgType; + } - public EncKDCRepPart(byte[] data, int rep_type) - throws Asn1Exception, IOException, RealmException{ - init(new DerValue(data), rep_type); - } + public EncKDCRepPart() { + } - public EncKDCRepPart(DerValue encoding, int rep_type) - throws Asn1Exception, IOException, RealmException - { - init(encoding, rep_type); - } + public EncKDCRepPart(byte[] data, int rep_type) + throws Asn1Exception, IOException, RealmException { + init(new DerValue(data), rep_type); + } + + public EncKDCRepPart(DerValue encoding, int rep_type) + throws Asn1Exception, IOException, RealmException { + init(encoding, rep_type); + } - /** - * Initializes an EncKDCRepPart object. - * - * @param encoding a single DER-encoded value. - * @param rep_type type of the encrypted reply message. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * @exception RealmException if an error occurs while decoding an Realm object. - */ - protected void init(DerValue encoding, int rep_type) - throws Asn1Exception, IOException, RealmException - { - DerValue der, subDer; - //implementations return the incorrect tag value, so - //we don't use the above line; instead we use the following - msgType = (encoding.getTag() & (byte)0x1F); + /** + * Initializes an EncKDCRepPart object. + * + * @param encoding a single DER-encoded value. + * @param rep_type type of the encrypted reply message. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * @exception RealmException if an error occurs while decoding an Realm object. + */ + protected void init(DerValue encoding, int rep_type) + throws Asn1Exception, IOException, RealmException { + DerValue der, subDer; + //implementations return the incorrect tag value, so + //we don't use the above line; instead we use the following + msgType = (encoding.getTag() & (byte) 0x1F); if (msgType != Krb5.KRB_ENC_AS_REP_PART && - msgType != Krb5.KRB_ENC_TGS_REP_PART) + msgType != Krb5.KRB_ENC_TGS_REP_PART) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + der = encoding.getData().getDerValue(); + if (der.getTag() != DerValue.tag_Sequence) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); - der = encoding.getData().getDerValue(); - if (der.getTag() != DerValue.tag_Sequence) + } + key = EncryptionKey.parse(der.getData(), (byte) 0x00, false); + lastReq = LastReq.parse(der.getData(), (byte) 0x01, false); + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & (byte) 0x1F) == (byte) 0x02) { + nonce = subDer.getData().getBigInteger().intValue(); + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + keyExpiration = KerberosTime.parse(der.getData(), (byte) 0x03, true); + flags = TicketFlags.parse(der.getData(), (byte) 0x04, false); + authtime = KerberosTime.parse(der.getData(), (byte) 0x05, false); + starttime = KerberosTime.parse(der.getData(), (byte) 0x06, true); + endtime = KerberosTime.parse(der.getData(), (byte) 0x07, false); + renewTill = KerberosTime.parse(der.getData(), (byte) 0x08, true); + srealm = Realm.parse(der.getData(), (byte) 0x09, false); + sname = PrincipalName.parse(der.getData(), (byte) 0x0A, false); + if (der.getData().available() > 0) { + caddr = HostAddresses.parse(der.getData(), (byte) 0x0B, true); + } + if (der.getData().available() > 0) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); - key = EncryptionKey.parse(der.getData(), (byte)0x00, false); - lastReq = LastReq.parse(der.getData(), (byte)0x01, false); - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & (byte)0x1F) == (byte)0x02) - nonce = subDer.getData().getBigInteger().intValue(); - else throw new Asn1Exception(Krb5.ASN1_BAD_ID); - keyExpiration = KerberosTime.parse(der.getData(), (byte)0x03, true); - flags = TicketFlags.parse(der.getData(), (byte)0x04, false); - authtime = KerberosTime.parse(der.getData(), (byte)0x05, false); - starttime = KerberosTime.parse(der.getData(), (byte)0x06, true); - endtime = KerberosTime.parse(der.getData(), (byte)0x07, false); - renewTill = KerberosTime.parse(der.getData(), (byte)0x08, true); - srealm = Realm.parse(der.getData(), (byte)0x09, false); - sname = PrincipalName.parse(der.getData(), (byte)0x0A, false); - if (der.getData().available() > 0) - caddr = HostAddresses.parse(der.getData(), (byte)0x0B, true); - if (der.getData().available() > 0) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); } + } - /** - * Encodes an EncKDCRepPart object. - * @param rep_type type of encrypted reply message. - * @return byte array of encoded EncKDCRepPart object. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ - public byte[] asn1Encode(int rep_type) throws Asn1Exception, - IOException { + /** + * Encodes an EncKDCRepPart object. + * @param rep_type type of encrypted reply message. + * @return byte array of encoded EncKDCRepPart object. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + public byte[] asn1Encode(int rep_type) throws Asn1Exception, + IOException { DerOutputStream temp = new DerOutputStream(); DerOutputStream bytes = new DerOutputStream(); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), key.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), lastReq.asn1Encode()); - temp.putInteger(BigInteger.valueOf(nonce)); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), temp); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x00), key.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x01), lastReq.asn1Encode()); + temp.putInteger(BigInteger.valueOf(nonce)); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x02), temp); - if (keyExpiration != null) - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), keyExpiration.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), flags.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), authtime.asn1Encode()); - if (starttime != null) - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), starttime.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x07), endtime.asn1Encode()); - if (renewTill != null) - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x08), renewTill.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x09), srealm.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x0A), sname.asn1Encode()); - if (caddr != null) - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x0B), caddr.asn1Encode()); - //should use the rep_type to build the encoding - //but other implementations do not; it is ignored and - //the cached msgType is used instead - temp = new DerOutputStream(); - temp.write(DerValue.tag_Sequence, bytes); - bytes = new DerOutputStream(); - bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)msgType), temp); - return bytes.toByteArray(); + if (keyExpiration != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x03), keyExpiration.asn1Encode()); } - + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x04), flags.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x05), authtime.asn1Encode()); + if (starttime != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x06), starttime.asn1Encode()); + } + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x07), endtime.asn1Encode()); + if (renewTill != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x08), renewTill.asn1Encode()); + } + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x09), srealm.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x0A), sname.asn1Encode()); + if (caddr != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x0B), caddr.asn1Encode()); + } + //should use the rep_type to build the encoding + //but other implementations do not; it is ignored and + //the cached msgType is used instead + temp = new DerOutputStream(); + temp.write(DerValue.tag_Sequence, bytes); + bytes = new DerOutputStream(); + bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, + true, (byte) msgType), temp); + return bytes.toByteArray(); + } } diff --git a/src/share/classes/sun/security/krb5/internal/EncKrbCredPart.java b/src/share/classes/sun/security/krb5/internal/EncKrbCredPart.java index f37f252bbaa1d3ac8556b484ebb67795a8a3a3bd..c5acf6d2b1c8ef02c538a1b39301521f37745efe 100644 --- a/src/share/classes/sun/security/krb5/internal/EncKrbCredPart.java +++ b/src/share/classes/sun/security/krb5/internal/EncKrbCredPart.java @@ -36,6 +36,7 @@ import sun.security.krb5.RealmException; import java.util.Vector; import java.io.IOException; import java.math.BigInteger; + /** * Implements the ASN.1 EncKrbCredPart type. * @@ -57,148 +58,158 @@ import java.math.BigInteger; * http://www.ietf.org/rfc/rfc4120.txt. */ public class EncKrbCredPart { - public KrbCredInfo[] ticketInfo = null; - public KerberosTime timeStamp; //optional - private Integer nonce; //optional - private Integer usec; //optional - private HostAddress sAddress; //optional - private HostAddresses rAddress; //optional + public KrbCredInfo[] ticketInfo = null; + public KerberosTime timeStamp; //optional + private Integer nonce; //optional + private Integer usec; //optional + private HostAddress sAddress; //optional + private HostAddresses rAddress; //optional - public EncKrbCredPart( - KrbCredInfo[] new_ticketInfo, - KerberosTime new_timeStamp, - Integer new_usec, - Integer new_nonce, - HostAddress new_sAddress, - HostAddresses new_rAddress - ) throws IOException { - if (new_ticketInfo != null) { - ticketInfo = new KrbCredInfo[new_ticketInfo.length]; - for (int i = 0; i < new_ticketInfo.length; i++) { - if (new_ticketInfo[i] == null) { - throw new IOException("Cannot create a EncKrbCredPart"); - } else { - ticketInfo[i] = (KrbCredInfo)new_ticketInfo[i].clone(); - } - } + public EncKrbCredPart( + KrbCredInfo[] new_ticketInfo, + KerberosTime new_timeStamp, + Integer new_usec, + Integer new_nonce, + HostAddress new_sAddress, + HostAddresses new_rAddress) throws IOException { + if (new_ticketInfo != null) { + ticketInfo = new KrbCredInfo[new_ticketInfo.length]; + for (int i = 0; i < new_ticketInfo.length; i++) { + if (new_ticketInfo[i] == null) { + throw new IOException("Cannot create a EncKrbCredPart"); + } else { + ticketInfo[i] = (KrbCredInfo) new_ticketInfo[i].clone(); } - timeStamp = new_timeStamp; - usec = new_usec; - nonce = new_nonce; - sAddress = new_sAddress; - rAddress = new_rAddress; + } } + timeStamp = new_timeStamp; + usec = new_usec; + nonce = new_nonce; + sAddress = new_sAddress; + rAddress = new_rAddress; + } - public EncKrbCredPart(byte[] data) throws Asn1Exception, - IOException, RealmException { - init(new DerValue(data)); - } + public EncKrbCredPart(byte[] data) throws Asn1Exception, + IOException, RealmException { + init(new DerValue(data)); + } - public EncKrbCredPart(DerValue encoding) throws Asn1Exception, - IOException, RealmException { - init(encoding); - } + public EncKrbCredPart(DerValue encoding) throws Asn1Exception, + IOException, RealmException { + init(encoding); + } - /** - * Initializes an EncKrbCredPart object. - * @param encoding a single DER-encoded value. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * @exception RealmException if an error occurs while parsing a Realm object. - */ - private void init(DerValue encoding) throws Asn1Exception, - IOException, RealmException { - DerValue der, subDer; - //may not be the correct error code for a tag - //mismatch on an encrypted structure - nonce = null; - timeStamp = null; - usec= null; + /** + * Initializes an EncKrbCredPart object. + * @param encoding a single DER-encoded value. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * @exception RealmException if an error occurs while parsing a Realm object. + */ + private void init(DerValue encoding) throws Asn1Exception, + IOException, RealmException { + DerValue der, subDer; + //may not be the correct error code for a tag + //mismatch on an encrypted structure + nonce = null; + timeStamp = null; + usec = null; sAddress = null; rAddress = null; - if (((encoding.getTag() & (byte)0x1F) != (byte)0x1D) - || (encoding.isApplication() != true) - || (encoding.isConstructed() != true)) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); + if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x1D) + || (encoding.isApplication() != true) + || (encoding.isConstructed() != true)) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } der = encoding.getData().getDerValue(); - if (der.getTag() != DerValue.tag_Sequence) + if (der.getTag() != DerValue.tag_Sequence) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & (byte) 0x1F) == (byte) 0x00) { + DerValue derValues[] = subDer.getData().getSequence(1); + ticketInfo = new KrbCredInfo[derValues.length]; + for (int i = 0; i < derValues.length; i++) { + ticketInfo[i] = new KrbCredInfo(derValues[i]); + } + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + if (der.getData().available() > 0) { + if (((byte) (der.getData().peekByte()) & (byte) 0x1F) == (byte) 0x01) { subDer = der.getData().getDerValue(); - if ((subDer.getTag() & (byte)0x1F) == (byte)0x00) { - DerValue derValues[] = subDer.getData().getSequence(1); - ticketInfo = new KrbCredInfo[derValues.length]; - for (int i = 0; i < derValues.length; i++) { - ticketInfo[i] = new KrbCredInfo(derValues[i]); - } - } - else - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - if (der.getData().available() > 0) { - if (((byte)(der.getData().peekByte()) & (byte)0x1F) == (byte)0x01) { - subDer = der.getData().getDerValue(); - nonce = new Integer(subDer.getData().getBigInteger().intValue()); - } - } - if (der.getData().available() >0) { - timeStamp = KerberosTime.parse(der.getData(), (byte)0x02, true); - } - if (der.getData().available() >0) { - if (((byte)(der.getData().peekByte()) & (byte)0x1F) == (byte)0x03) { - subDer = der.getData().getDerValue(); - usec = new Integer(subDer.getData().getBigInteger().intValue()); - } - } - if (der.getData().available() >0) { - sAddress = HostAddress.parse(der.getData(), (byte)0x04, true); - } - if (der.getData().available() >0) { - rAddress = HostAddresses.parse(der.getData(), (byte)0x05, true); - } - if (der.getData().available() >0) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); + nonce = new Integer(subDer.getData().getBigInteger().intValue()); + } + } + if (der.getData().available() > 0) { + timeStamp = KerberosTime.parse(der.getData(), (byte) 0x02, true); + } + if (der.getData().available() > 0) { + if (((byte) (der.getData().peekByte()) & (byte) 0x1F) == (byte) 0x03) { + subDer = der.getData().getDerValue(); + usec = new Integer(subDer.getData().getBigInteger().intValue()); + } + } + if (der.getData().available() > 0) { + sAddress = HostAddress.parse(der.getData(), (byte) 0x04, true); + } + if (der.getData().available() > 0) { + rAddress = HostAddresses.parse(der.getData(), (byte) 0x05, true); + } + if (der.getData().available() > 0) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); } + } - /** - * Encodes an EncKrbCredPart object. - * @return byte array of encoded EncKrbCredPart object. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * - */ - public byte[] asn1Encode() throws Asn1Exception, IOException{ + /** + * Encodes an EncKrbCredPart object. + * @return byte array of encoded EncKrbCredPart object. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * + */ + public byte[] asn1Encode() throws Asn1Exception, IOException { DerOutputStream bytes = new DerOutputStream(); - DerOutputStream temp = new DerOutputStream(); - DerValue[] tickets = new DerValue[ticketInfo.length]; - for (int i = 0; i < ticketInfo.length; i++) - tickets[i] = new DerValue(ticketInfo[i].asn1Encode()); - temp.putSequence(tickets); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp); + DerOutputStream temp = new DerOutputStream(); + DerValue[] tickets = new DerValue[ticketInfo.length]; + for (int i = 0; i < ticketInfo.length; i++) { + tickets[i] = new DerValue(ticketInfo[i].asn1Encode()); + } + temp.putSequence(tickets); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x00), temp); - if (nonce != null) { + if (nonce != null) { temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(nonce.intValue())); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp); - } + temp.putInteger(BigInteger.valueOf(nonce.intValue())); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x01), temp); + } if (timeStamp != null) { - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), timeStamp.asn1Encode()); - } - if (usec != null) { - temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(usec.intValue())); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), temp); - } - if (sAddress != null) { - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), sAddress.asn1Encode()); - } - if (rAddress != null) { - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), rAddress.asn1Encode()); - } - temp = new DerOutputStream(); - temp.write(DerValue.tag_Sequence, bytes); - bytes = new DerOutputStream(); - bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x1D), temp); - return bytes.toByteArray(); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x02), timeStamp.asn1Encode()); + } + if (usec != null) { + temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(usec.intValue())); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x03), temp); + } + if (sAddress != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x04), sAddress.asn1Encode()); + } + if (rAddress != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x05), rAddress.asn1Encode()); } + temp = new DerOutputStream(); + temp.write(DerValue.tag_Sequence, bytes); + bytes = new DerOutputStream(); + bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, + true, (byte) 0x1D), temp); + return bytes.toByteArray(); + } } diff --git a/src/share/classes/sun/security/krb5/internal/EncKrbPrivPart.java b/src/share/classes/sun/security/krb5/internal/EncKrbPrivPart.java index e4ed50b4ba1cf382d960f2f64f06c173ea098a0f..292dd58be3b442acbf177c5192365cf42adb254c 100644 --- a/src/share/classes/sun/security/krb5/internal/EncKrbPrivPart.java +++ b/src/share/classes/sun/security/krb5/internal/EncKrbPrivPart.java @@ -55,114 +55,119 @@ import java.math.BigInteger; * * http://www.ietf.org/rfc/rfc4120.txt. */ - public class EncKrbPrivPart { - public byte[] userData = null; - public KerberosTime timestamp; //optional - public Integer usec; //optional - public Integer seqNumber; //optional - public HostAddress sAddress; //optional - public HostAddress rAddress; //optional - public EncKrbPrivPart( - byte[] new_userData, - KerberosTime new_timestamp, - Integer new_usec, - Integer new_seqNumber, - HostAddress new_sAddress, - HostAddress new_rAddress - ) { - if (new_userData != null) { - userData = new_userData.clone(); - } - timestamp = new_timestamp; - usec = new_usec; - seqNumber = new_seqNumber; - sAddress = new_sAddress; - rAddress = new_rAddress; - } + public byte[] userData = null; + public KerberosTime timestamp; //optional + public Integer usec; //optional + public Integer seqNumber; //optional + public HostAddress sAddress; //optional + public HostAddress rAddress; //optional - public EncKrbPrivPart(byte[] data) throws Asn1Exception, IOException { - init(new DerValue(data)); + public EncKrbPrivPart( + byte[] new_userData, + KerberosTime new_timestamp, + Integer new_usec, + Integer new_seqNumber, + HostAddress new_sAddress, + HostAddress new_rAddress) { + if (new_userData != null) { + userData = new_userData.clone(); } + timestamp = new_timestamp; + usec = new_usec; + seqNumber = new_seqNumber; + sAddress = new_sAddress; + rAddress = new_rAddress; + } - public EncKrbPrivPart(DerValue encoding) throws Asn1Exception, IOException { - init(encoding); - } + public EncKrbPrivPart(byte[] data) throws Asn1Exception, IOException { + init(new DerValue(data)); + } + + public EncKrbPrivPart(DerValue encoding) throws Asn1Exception, IOException { + init(encoding); + } - /** - * Initializes an EncKrbPrivPart object. - * @param encoding a single DER-encoded value. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ - private void init(DerValue encoding) throws Asn1Exception, IOException { + /** + * Initializes an EncKrbPrivPart object. + * @param encoding a single DER-encoded value. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + private void init(DerValue encoding) throws Asn1Exception, IOException { DerValue der, subDer; - if (((encoding.getTag() & (byte)0x1F) != (byte)0x1C) - || (encoding.isApplication() != true) - || (encoding.isConstructed() != true)) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - der = encoding.getData().getDerValue(); - if (der.getTag() != DerValue.tag_Sequence) + if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x1C) + || (encoding.isApplication() != true) + || (encoding.isConstructed() != true)) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + der = encoding.getData().getDerValue(); + if (der.getTag() != DerValue.tag_Sequence) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & (byte) 0x1F) == (byte) 0x00) { + userData = subDer.getData().getOctetString(); + } else { throw new Asn1Exception(Krb5.ASN1_BAD_ID); - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & (byte)0x1F) == (byte)0x00) { - userData = subDer.getData().getOctetString(); - } - else - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - timestamp = KerberosTime.parse(der.getData(), (byte)0x01, true); - if ((der.getData().peekByte() & 0x1F) == 0x02) { - subDer = der.getData().getDerValue(); - usec = new Integer(subDer.getData().getBigInteger().intValue()); - } - else usec = null; - if ((der.getData().peekByte() & 0x1F) == 0x03 ) { - subDer = der.getData().getDerValue(); - seqNumber = new Integer(subDer.getData().getBigInteger().intValue()); - } - else seqNumber = null; - sAddress = HostAddress.parse(der.getData(), (byte)0x04, false); - if (der.getData().available() > 0) { - rAddress = HostAddress.parse(der.getData(), (byte)0x05, true); - } - if (der.getData().available() > 0) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); } + timestamp = KerberosTime.parse(der.getData(), (byte) 0x01, true); + if ((der.getData().peekByte() & 0x1F) == 0x02) { + subDer = der.getData().getDerValue(); + usec = new Integer(subDer.getData().getBigInteger().intValue()); + } else { + usec = null; + } + if ((der.getData().peekByte() & 0x1F) == 0x03) { + subDer = der.getData().getDerValue(); + seqNumber = new Integer(subDer.getData().getBigInteger().intValue()); + } else { + seqNumber = null; + } + sAddress = HostAddress.parse(der.getData(), (byte) 0x04, false); + if (der.getData().available() > 0) { + rAddress = HostAddress.parse(der.getData(), (byte) 0x05, true); + } + if (der.getData().available() > 0) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + } - /** - * Encodes an EncKrbPrivPart object. - * @return byte array of encoded EncKrbPrivPart object. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ - public byte[] asn1Encode() throws Asn1Exception, IOException { + /** + * Encodes an EncKrbPrivPart object. + * @return byte array of encoded EncKrbPrivPart object. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + public byte[] asn1Encode() throws Asn1Exception, IOException { DerOutputStream temp = new DerOutputStream(); DerOutputStream bytes = new DerOutputStream(); - temp.putOctetString(userData); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp); - if (timestamp != null) - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), timestamp.asn1Encode()); - if (usec != null) { - temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(usec.intValue())); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), temp); - } - if (seqNumber != null) { - temp = new DerOutputStream(); - // encode as an unsigned integer (UInt32) - temp.putInteger(BigInteger.valueOf(seqNumber.longValue())); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), temp); - } - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), sAddress.asn1Encode()); - if (rAddress != null) { - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), rAddress.asn1Encode()); - } - temp = new DerOutputStream(); - temp.write(DerValue.tag_Sequence, bytes); - bytes = new DerOutputStream(); - bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x1C), temp); - return bytes.toByteArray(); + temp.putOctetString(userData); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x00), temp); + if (timestamp != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x01), timestamp.asn1Encode()); + } + if (usec != null) { + temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(usec.intValue())); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x02), temp); + } + if (seqNumber != null) { + temp = new DerOutputStream(); + // encode as an unsigned integer (UInt32) + temp.putInteger(BigInteger.valueOf(seqNumber.longValue())); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x03), temp); + } + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x04), sAddress.asn1Encode()); + if (rAddress != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x05), rAddress.asn1Encode()); } + temp = new DerOutputStream(); + temp.write(DerValue.tag_Sequence, bytes); + bytes = new DerOutputStream(); + bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte) 0x1C), temp); + return bytes.toByteArray(); + } } diff --git a/src/share/classes/sun/security/krb5/internal/EncTGSRepPart.java b/src/share/classes/sun/security/krb5/internal/EncTGSRepPart.java index 95c100a020aca76197012d16966dc295e7b8172d..864115e52e98fc51cb06bc2a2f15d12e8155550d 100644 --- a/src/share/classes/sun/security/krb5/internal/EncTGSRepPart.java +++ b/src/share/classes/sun/security/krb5/internal/EncTGSRepPart.java @@ -35,55 +35,52 @@ import java.io.IOException; public class EncTGSRepPart extends EncKDCRepPart { - public EncTGSRepPart( - EncryptionKey new_key, - LastReq new_lastReq, - int new_nonce, - KerberosTime new_keyExpiration, - TicketFlags new_flags, - KerberosTime new_authtime, - KerberosTime new_starttime, - KerberosTime new_endtime, - KerberosTime new_renewTill, - Realm new_srealm, - PrincipalName new_sname, - HostAddresses new_caddr - ) { - super( - new_key, - new_lastReq, - new_nonce, - new_keyExpiration, - new_flags, - new_authtime, - new_starttime, - new_endtime, - new_renewTill, - new_srealm, - new_sname, - new_caddr, - Krb5.KRB_ENC_TGS_REP_PART - ); - } + public EncTGSRepPart( + EncryptionKey new_key, + LastReq new_lastReq, + int new_nonce, + KerberosTime new_keyExpiration, + TicketFlags new_flags, + KerberosTime new_authtime, + KerberosTime new_starttime, + KerberosTime new_endtime, + KerberosTime new_renewTill, + Realm new_srealm, + PrincipalName new_sname, + HostAddresses new_caddr) { + super( + new_key, + new_lastReq, + new_nonce, + new_keyExpiration, + new_flags, + new_authtime, + new_starttime, + new_endtime, + new_renewTill, + new_srealm, + new_sname, + new_caddr, + Krb5.KRB_ENC_TGS_REP_PART); + } - public EncTGSRepPart(byte[] data) throws Asn1Exception, - IOException, KrbException { - init(new DerValue(data)); - } + public EncTGSRepPart(byte[] data) throws Asn1Exception, + IOException, KrbException { + init(new DerValue(data)); + } - public EncTGSRepPart(DerValue encoding) throws Asn1Exception, - IOException, KrbException { - init(encoding); - } + public EncTGSRepPart(DerValue encoding) throws Asn1Exception, + IOException, KrbException { + init(encoding); + } - private void init(DerValue encoding) throws Asn1Exception, - IOException, KrbException { - init(encoding, Krb5.KRB_ENC_TGS_REP_PART); - } - - public byte[] asn1Encode() throws Asn1Exception, - IOException { - return asn1Encode(Krb5.KRB_ENC_TGS_REP_PART); - } + private void init(DerValue encoding) throws Asn1Exception, + IOException, KrbException { + init(encoding, Krb5.KRB_ENC_TGS_REP_PART); + } + public byte[] asn1Encode() throws Asn1Exception, + IOException { + return asn1Encode(Krb5.KRB_ENC_TGS_REP_PART); + } } diff --git a/src/share/classes/sun/security/krb5/internal/EncTicketPart.java b/src/share/classes/sun/security/krb5/internal/EncTicketPart.java index 5f315095825832d0759518f877403558e3556ed1..73eb814445baff9933da195a84aa99aab0225ab7 100644 --- a/src/share/classes/sun/security/krb5/internal/EncTicketPart.java +++ b/src/share/classes/sun/security/krb5/internal/EncTicketPart.java @@ -62,69 +62,68 @@ import java.io.*; * http://www.ietf.org/rfc/rfc4120.txt. */ public class EncTicketPart { - public TicketFlags flags; - public EncryptionKey key; - public Realm crealm; - public PrincipalName cname; - public TransitedEncoding transited; - public KerberosTime authtime; - public KerberosTime starttime; //optional - public KerberosTime endtime; - public KerberosTime renewTill; //optional - public HostAddresses caddr; //optional - public AuthorizationData authorizationData; //optional - - public EncTicketPart( - TicketFlags new_flags, - EncryptionKey new_key, - Realm new_crealm, - PrincipalName new_cname, - TransitedEncoding new_transited, - KerberosTime new_authtime, - KerberosTime new_starttime, - KerberosTime new_endtime, - KerberosTime new_renewTill, - HostAddresses new_caddr, - AuthorizationData new_authorizationData - ) { - flags = new_flags; - key = new_key; - crealm = new_crealm; - cname = new_cname; - transited = new_transited; - authtime = new_authtime; - starttime = new_starttime; - endtime = new_endtime; - renewTill = new_renewTill; - caddr = new_caddr; - authorizationData = new_authorizationData; - } - public EncTicketPart(byte[] data) - throws Asn1Exception, KrbException, IOException { - init(new DerValue(data)); - } + public TicketFlags flags; + public EncryptionKey key; + public Realm crealm; + public PrincipalName cname; + public TransitedEncoding transited; + public KerberosTime authtime; + public KerberosTime starttime; //optional + public KerberosTime endtime; + public KerberosTime renewTill; //optional + public HostAddresses caddr; //optional + public AuthorizationData authorizationData; //optional + + public EncTicketPart( + TicketFlags new_flags, + EncryptionKey new_key, + Realm new_crealm, + PrincipalName new_cname, + TransitedEncoding new_transited, + KerberosTime new_authtime, + KerberosTime new_starttime, + KerberosTime new_endtime, + KerberosTime new_renewTill, + HostAddresses new_caddr, + AuthorizationData new_authorizationData) { + flags = new_flags; + key = new_key; + crealm = new_crealm; + cname = new_cname; + transited = new_transited; + authtime = new_authtime; + starttime = new_starttime; + endtime = new_endtime; + renewTill = new_renewTill; + caddr = new_caddr; + authorizationData = new_authorizationData; + } - public EncTicketPart(DerValue encoding) - throws Asn1Exception, KrbException, IOException { - init(encoding); - } + public EncTicketPart(byte[] data) + throws Asn1Exception, KrbException, IOException { + init(new DerValue(data)); + } - /** - * Initializes an EncTicketPart object. - * @param encoding a single DER-encoded value. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * @exception RealmException if an error occurs while parsing a Realm object. - */ + public EncTicketPart(DerValue encoding) + throws Asn1Exception, KrbException, IOException { + init(encoding); + } + /** + * Initializes an EncTicketPart object. + * @param encoding a single DER-encoded value. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * @exception RealmException if an error occurs while parsing a Realm object. + */ private static String getHexBytes(byte[] bytes, int len) - throws IOException { + throws IOException { StringBuffer sb = new StringBuffer(); for (int i = 0; i < len; i++) { - int b1 = (bytes[i]>>4) & 0x0f; + int b1 = (bytes[i] >> 4) & 0x0f; int b2 = bytes[i] & 0x0f; sb.append(Integer.toHexString(b1)); @@ -134,73 +133,91 @@ public class EncTicketPart { return sb.toString(); } - private void init(DerValue encoding) - throws Asn1Exception, IOException, RealmException { - DerValue der, subDer; + private void init(DerValue encoding) + throws Asn1Exception, IOException, RealmException { + DerValue der, subDer; - renewTill = null; - caddr = null; - authorizationData = null; - if (((encoding.getTag() & (byte)0x1F) != (byte)0x03) + renewTill = null; + caddr = null; + authorizationData = null; + if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x03) || (encoding.isApplication() != true) - || (encoding.isConstructed() != true)) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - der = encoding.getData().getDerValue(); - if (der.getTag() != DerValue.tag_Sequence) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - flags = TicketFlags.parse(der.getData(), (byte)0x00, false); - key = EncryptionKey.parse(der.getData(), (byte)0x01, false); - crealm = Realm.parse(der.getData(), (byte)0x02, false); - cname = PrincipalName.parse(der.getData(), (byte)0x03, false); - transited = TransitedEncoding.parse(der.getData(), (byte)0x04, false); - authtime = KerberosTime.parse(der.getData(), (byte)0x05, false); - starttime = KerberosTime.parse(der.getData(), (byte)0x06, true); - endtime = KerberosTime.parse(der.getData(), (byte)0x07, false); - if (der.getData().available() > 0) { - renewTill = KerberosTime.parse(der.getData(), (byte)0x08, true); - } - if (der.getData().available() > 0) { - caddr = HostAddresses.parse(der.getData(), (byte)0x09, true); - } - if (der.getData().available() > 0) { - authorizationData = AuthorizationData.parse(der.getData(), (byte)0x0A, true); - } - if (der.getData().available() > 0) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - + || (encoding.isConstructed() != true)) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + der = encoding.getData().getDerValue(); + if (der.getTag() != DerValue.tag_Sequence) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + flags = TicketFlags.parse(der.getData(), (byte) 0x00, false); + key = EncryptionKey.parse(der.getData(), (byte) 0x01, false); + crealm = Realm.parse(der.getData(), (byte) 0x02, false); + cname = PrincipalName.parse(der.getData(), (byte) 0x03, false); + transited = TransitedEncoding.parse(der.getData(), (byte) 0x04, false); + authtime = KerberosTime.parse(der.getData(), (byte) 0x05, false); + starttime = KerberosTime.parse(der.getData(), (byte) 0x06, true); + endtime = KerberosTime.parse(der.getData(), (byte) 0x07, false); + if (der.getData().available() > 0) { + renewTill = KerberosTime.parse(der.getData(), (byte) 0x08, true); + } + if (der.getData().available() > 0) { + caddr = HostAddresses.parse(der.getData(), (byte) 0x09, true); + } + if (der.getData().available() > 0) { + authorizationData = AuthorizationData.parse(der.getData(), (byte) 0x0A, true); + } + if (der.getData().available() > 0) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); } - /** - * Encodes an EncTicketPart object. - * @return byte array of encoded EncTicketPart object. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ + } - public byte[] asn1Encode() throws Asn1Exception, IOException { + /** + * Encodes an EncTicketPart object. + * @return byte array of encoded EncTicketPart object. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + public byte[] asn1Encode() throws Asn1Exception, IOException { DerOutputStream bytes = new DerOutputStream(); - DerOutputStream temp = new DerOutputStream(); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), flags.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), key.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), crealm.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), cname.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), transited.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), authtime.asn1Encode()); - if (starttime != null) - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), starttime.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x07), endtime.asn1Encode()); - - if (renewTill != null) - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x08), renewTill.asn1Encode()); - - if (caddr != null) - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x09), caddr.asn1Encode()); - - if (authorizationData != null) - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x0A), authorizationData.asn1Encode()); - temp.write(DerValue.tag_Sequence, bytes); - bytes = new DerOutputStream(); - bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x03), temp); - return bytes.toByteArray(); + DerOutputStream temp = new DerOutputStream(); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x00), flags.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x01), key.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x02), crealm.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x03), cname.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x04), transited.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x05), authtime.asn1Encode()); + if (starttime != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x06), starttime.asn1Encode()); + } + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x07), endtime.asn1Encode()); + + if (renewTill != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x08), renewTill.asn1Encode()); } + + if (caddr != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x09), caddr.asn1Encode()); + } + + if (authorizationData != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x0A), authorizationData.asn1Encode()); + } + temp.write(DerValue.tag_Sequence, bytes); + bytes = new DerOutputStream(); + bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, + true, (byte) 0x03), temp); + return bytes.toByteArray(); + } } diff --git a/src/share/classes/sun/security/krb5/internal/KDCRep.java b/src/share/classes/sun/security/krb5/internal/KDCRep.java index ca1d777ed231ee9c84f128dd03bb236ab8f89f7f..f7cc7180082be06e1d78b249b0cfbcc4e6d4b74d 100644 --- a/src/share/classes/sun/security/krb5/internal/KDCRep.java +++ b/src/share/classes/sun/security/krb5/internal/KDCRep.java @@ -35,6 +35,7 @@ import sun.security.util.*; import java.util.Vector; import java.io.IOException; import java.math.BigInteger; + /** * Implements the ASN.1 KDC-REP type. * @@ -59,163 +60,168 @@ import java.math.BigInteger; * * http://www.ietf.org/rfc/rfc4120.txt. */ - public class KDCRep { - public Realm crealm; - public PrincipalName cname; - public Ticket ticket; - public EncryptedData encPart; - public EncKDCRepPart encKDCRepPart; //not part of ASN.1 encoding - private int pvno; - private int msgType; - private PAData[] pAData = null; //optional - private boolean DEBUG = Krb5.DEBUG; + public Realm crealm; + public PrincipalName cname; + public Ticket ticket; + public EncryptedData encPart; + public EncKDCRepPart encKDCRepPart; //not part of ASN.1 encoding + private int pvno; + private int msgType; + private PAData[] pAData = null; //optional + private boolean DEBUG = Krb5.DEBUG; - public KDCRep( - PAData[] new_pAData, - Realm new_crealm, - PrincipalName new_cname, - Ticket new_ticket, - EncryptedData new_encPart, - int req_type - ) throws IOException { - pvno = Krb5.PVNO; - msgType = req_type; - if (new_pAData != null) { - pAData = new PAData[new_pAData.length]; - for (int i = 0; i < new_pAData.length; i++) { - if (new_pAData[i] == null) { - throw new IOException("Cannot create a KDCRep"); - } else { - pAData[i] = (PAData)new_pAData[i].clone(); - } - } + public KDCRep( + PAData[] new_pAData, + Realm new_crealm, + PrincipalName new_cname, + Ticket new_ticket, + EncryptedData new_encPart, + int req_type) throws IOException { + pvno = Krb5.PVNO; + msgType = req_type; + if (new_pAData != null) { + pAData = new PAData[new_pAData.length]; + for (int i = 0; i < new_pAData.length; i++) { + if (new_pAData[i] == null) { + throw new IOException("Cannot create a KDCRep"); + } else { + pAData[i] = (PAData) new_pAData[i].clone(); } - crealm = new_crealm; - cname = new_cname; - ticket = new_ticket; - encPart = new_encPart; + } } + crealm = new_crealm; + cname = new_cname; + ticket = new_ticket; + encPart = new_encPart; + } - public KDCRep() { - } + public KDCRep() { + } - public KDCRep(byte[] data, int req_type) throws Asn1Exception, KrbApErrException, RealmException, IOException { - init(new DerValue(data), req_type); - } + public KDCRep(byte[] data, int req_type) throws Asn1Exception, + KrbApErrException, RealmException, IOException { + init(new DerValue(data), req_type); + } - public KDCRep(DerValue encoding, int req_type) throws Asn1Exception, - RealmException, KrbApErrException, IOException { - init(encoding, req_type); - } + public KDCRep(DerValue encoding, int req_type) throws Asn1Exception, + RealmException, KrbApErrException, IOException { + init(encoding, req_type); + } /* // Not used? Don't know what keyusage to use here %%% - - public void decrypt(EncryptionKey key) throws Asn1Exception, - IOException, KrbException, RealmException { - encKDCRepPart = new EncKDCRepPart(encPart.decrypt(key), - msgType); - } -*/ - - /** - * Initializes an KDCRep object. - * - * @param encoding a single DER-encoded value. - * @param req_type reply message type. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * @exception RealmException if an error occurs while constructing a Realm object from DER-encoded data. - * @exception KrbApErrException if the value read from the DER-encoded data stream does not match the pre-defined value. - * - */ - protected void init(DerValue encoding, int req_type) + public void decrypt(EncryptionKey key) throws Asn1Exception, + IOException, KrbException, RealmException { + encKDCRepPart = new EncKDCRepPart(encPart.decrypt(key), msgType); + } + */ + /** + * Initializes an KDCRep object. + * + * @param encoding a single DER-encoded value. + * @param req_type reply message type. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * @exception RealmException if an error occurs while constructing + * a Realm object from DER-encoded data. + * @exception KrbApErrException if the value read from the DER-encoded + * data stream does not match the pre-defined value. + * + */ + protected void init(DerValue encoding, int req_type) throws Asn1Exception, RealmException, IOException, - KrbApErrException { - DerValue der, subDer; - if ((encoding.getTag() & 0x1F) != req_type) { - if (DEBUG) { - System.out.println(">>> KDCRep: init() " + - "encoding tag is " + - encoding.getTag() + - " req type is " + req_type); - } - throw new Asn1Exception(Krb5.ASN1_BAD_ID); + KrbApErrException { + DerValue der, subDer; + if ((encoding.getTag() & 0x1F) != req_type) { + if (DEBUG) { + System.out.println(">>> KDCRep: init() " + + "encoding tag is " + + encoding.getTag() + + " req type is " + req_type); } - der = encoding.getData().getDerValue(); - if (der.getTag() != DerValue.tag_Sequence) { - throw new Asn1Exception(Krb5.ASN1_BAD_ID); + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + der = encoding.getData().getDerValue(); + if (der.getTag() != DerValue.tag_Sequence) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & 0x1F) == 0x00) { + pvno = subDer.getData().getBigInteger().intValue(); + if (pvno != Krb5.PVNO) { + throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION); } - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & 0x1F) == 0x00) { - pvno = subDer.getData().getBigInteger().intValue(); - if (pvno != Krb5.PVNO) - throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION); - } else { - throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & 0x1F) == 0x01) { + msgType = subDer.getData().getBigInteger().intValue(); + if (msgType != req_type) { + throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE); } + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + if ((der.getData().peekByte() & 0x1F) == 0x02) { subDer = der.getData().getDerValue(); - if ((subDer.getTag() & 0x1F) == 0x01) { - msgType = subDer.getData().getBigInteger().intValue(); - if (msgType != req_type) { - throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE); - } - } else { - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - } - if ((der.getData().peekByte() & 0x1F) == 0x02) { - subDer = der.getData().getDerValue(); - DerValue[] padata = subDer.getData().getSequence(1); - pAData = new PAData[padata.length]; - for (int i = 0; i < padata.length; i++) { - pAData[i] = new PAData(padata[i]); - } - } else { - pAData = null; - } - crealm = Realm.parse(der.getData(), (byte)0x03, false); - cname = PrincipalName.parse(der.getData(), (byte)0x04, false); - ticket = Ticket.parse(der.getData(), (byte)0x05, false); - encPart = EncryptedData.parse(der.getData(), (byte)0x06, false); - if (der.getData().available() > 0) { - throw new Asn1Exception(Krb5.ASN1_BAD_ID); + DerValue[] padata = subDer.getData().getSequence(1); + pAData = new PAData[padata.length]; + for (int i = 0; i < padata.length; i++) { + pAData[i] = new PAData(padata[i]); } + } else { + pAData = null; } + crealm = Realm.parse(der.getData(), (byte) 0x03, false); + cname = PrincipalName.parse(der.getData(), (byte) 0x04, false); + ticket = Ticket.parse(der.getData(), (byte) 0x05, false); + encPart = EncryptedData.parse(der.getData(), (byte) 0x06, false); + if (der.getData().available() > 0) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + } + /** + * Encodes this object to a byte array. + * @return byte array of encoded APReq object. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * + */ + public byte[] asn1Encode() throws Asn1Exception, IOException { - /** - * Encodes this object to a byte array. - * @return byte array of encoded APReq object. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * - */ - public byte[] asn1Encode() throws Asn1Exception, IOException { - - DerOutputStream bytes = new DerOutputStream(); - DerOutputStream temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(pvno)); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp); - temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(msgType)); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp); - if (pAData != null && pAData.length > 0) { - DerOutputStream padata_stream = new DerOutputStream(); - for (int i = 0; i < pAData.length; i++) { - padata_stream.write(pAData[i].asn1Encode()); - } - temp = new DerOutputStream(); - temp.write(DerValue.tag_SequenceOf, padata_stream); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), temp); + DerOutputStream bytes = new DerOutputStream(); + DerOutputStream temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(pvno)); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x00), temp); + temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(msgType)); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x01), temp); + if (pAData != null && pAData.length > 0) { + DerOutputStream padata_stream = new DerOutputStream(); + for (int i = 0; i < pAData.length; i++) { + padata_stream.write(pAData[i].asn1Encode()); } - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), crealm.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), cname.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), ticket.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), encPart.asn1Encode()); temp = new DerOutputStream(); - temp.write(DerValue.tag_Sequence, bytes); - return temp.toByteArray(); + temp.write(DerValue.tag_SequenceOf, padata_stream); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x02), temp); } + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x03), crealm.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x04), cname.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x05), ticket.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x06), encPart.asn1Encode()); + temp = new DerOutputStream(); + temp.write(DerValue.tag_Sequence, bytes); + return temp.toByteArray(); + } } diff --git a/src/share/classes/sun/security/krb5/internal/KDCReq.java b/src/share/classes/sun/security/krb5/internal/KDCReq.java index 2f0498956958977aab6d1dbf1788b84a83469657..a46f6436cd82d450df53c573e37c4f69f4bda321 100644 --- a/src/share/classes/sun/security/krb5/internal/KDCReq.java +++ b/src/share/classes/sun/security/krb5/internal/KDCReq.java @@ -56,155 +56,160 @@ import java.math.BigInteger; * * http://www.ietf.org/rfc/rfc4120.txt. */ - public class KDCReq { - public KDCReqBody reqBody; - private int pvno; - private int msgType; - private PAData[] pAData = null; //optional + public KDCReqBody reqBody; + private int pvno; + private int msgType; + private PAData[] pAData = null; //optional - public KDCReq(PAData[] new_pAData, KDCReqBody new_reqBody, - int req_type) throws IOException { - pvno = Krb5.PVNO; - msgType = req_type; - if (new_pAData != null) { - pAData = new PAData[new_pAData.length]; - for (int i = 0; i < new_pAData.length; i++) { - if (new_pAData[i] == null) { - throw new IOException("Cannot create a KDCRep"); - } else { - pAData[i] = (PAData)new_pAData[i].clone(); - } - } + public KDCReq(PAData[] new_pAData, KDCReqBody new_reqBody, + int req_type) throws IOException { + pvno = Krb5.PVNO; + msgType = req_type; + if (new_pAData != null) { + pAData = new PAData[new_pAData.length]; + for (int i = 0; i < new_pAData.length; i++) { + if (new_pAData[i] == null) { + throw new IOException("Cannot create a KDCRep"); + } else { + pAData[i] = (PAData) new_pAData[i].clone(); } - reqBody = new_reqBody; + } } + reqBody = new_reqBody; + } - public KDCReq() { - } + public KDCReq() { + } - public KDCReq(byte[] data, int req_type) throws Asn1Exception, - IOException, KrbException { + public KDCReq(byte[] data, int req_type) throws Asn1Exception, + IOException, KrbException { init(new DerValue(data), req_type); - } + } /** - * Creates an KDCReq object from a DerValue object and asn1 type. - * - * @param der a DER value of an KDCReq object. - * @param req_type a encoded asn1 type value. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * @exceptoin KrbErrException - */ + * Creates an KDCReq object from a DerValue object and asn1 type. + * + * @param der a DER value of an KDCReq object. + * @param req_type a encoded asn1 type value. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * @exceptoin KrbErrException + */ public KDCReq(DerValue der, int req_type) throws Asn1Exception, - IOException, KrbException { - init(der, req_type); - } + IOException, KrbException { + init(der, req_type); + } - /** - * Initializes a KDCReq object from a DerValue. The DER encoding - * must be in the format specified by the KRB_KDC_REQ ASN.1 notation. - * - * @param encoding a DER-encoded KDCReq object. - * @param req_type an int indicating whether it's KRB_AS_REQ or KRB_TGS_REQ type - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * @exception KrbException if an error occurs while constructing a Realm object, - * or a Krb object from DER-encoded data. - */ + /** + * Initializes a KDCReq object from a DerValue. The DER encoding + * must be in the format specified by the KRB_KDC_REQ ASN.1 notation. + * + * @param encoding a DER-encoded KDCReq object. + * @param req_type an int indicating whether it's KRB_AS_REQ or KRB_TGS_REQ type + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * @exception KrbException if an error occurs while constructing a Realm object, + * or a Krb object from DER-encoded data. + */ protected void init(DerValue encoding, int req_type) throws Asn1Exception, - IOException, KrbException { - DerValue der, subDer; - BigInteger bint; - if ((encoding.getTag() & 0x1F) != req_type) { - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - } - der = encoding.getData().getDerValue(); - if (der.getTag() != DerValue.tag_Sequence) { + IOException, KrbException { + DerValue der, subDer; + BigInteger bint; + if ((encoding.getTag() & 0x1F) != req_type) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); - } - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & 0x01F) == 0x01) { - bint = subDer.getData().getBigInteger(); - this.pvno = bint.intValue(); - if (this.pvno != Krb5.PVNO) - throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION); - } - else - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & 0x01F) == 0x02) { - bint = subDer.getData().getBigInteger(); - this.msgType = bint.intValue(); - if (this.msgType != req_type) - throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE); - } - else - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & 0x01F) == 0x03) { - DerValue subsubDer = subDer.getData().getDerValue(); - if (subsubDer.getTag() != DerValue.tag_SequenceOf) { - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - } - Vector v = new Vector (); - while (subsubDer.getData().available() > 0) { - v.addElement(new PAData(subsubDer.getData().getDerValue())); - } - if (v.size() > 0) { - pAData = new PAData[v.size()]; - v.copyInto(pAData); - } - } - else pAData = null; - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & 0x01F) == 0x04) { - DerValue subsubDer = subDer.getData().getDerValue(); - reqBody = new KDCReqBody(subsubDer, msgType); - } - else - throw new Asn1Exception(Krb5.ASN1_BAD_ID); } + der = encoding.getData().getDerValue(); + if (der.getTag() != DerValue.tag_Sequence) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & 0x01F) == 0x01) { + bint = subDer.getData().getBigInteger(); + this.pvno = bint.intValue(); + if (this.pvno != Krb5.PVNO) { + throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION); + } + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & 0x01F) == 0x02) { + bint = subDer.getData().getBigInteger(); + this.msgType = bint.intValue(); + if (this.msgType != req_type) { + throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE); + } + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + if ((der.getData().peekByte() & 0x1F) == 0x03) { + subDer = der.getData().getDerValue(); + DerValue subsubDer = subDer.getData().getDerValue(); + if (subsubDer.getTag() != DerValue.tag_SequenceOf) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + Vector v = new Vector(); + while (subsubDer.getData().available() > 0) { + v.addElement(new PAData(subsubDer.getData().getDerValue())); + } + if (v.size() > 0) { + pAData = new PAData[v.size()]; + v.copyInto(pAData); + } + } else { + pAData = null; + } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & 0x01F) == 0x04) { + DerValue subsubDer = subDer.getData().getDerValue(); + reqBody = new KDCReqBody(subsubDer, msgType); + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + } - /** - * Encodes this object to a byte array. - * - * @return an byte array of encoded data. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * - */ + /** + * Encodes this object to a byte array. + * + * @return an byte array of encoded data. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * + */ public byte[] asn1Encode() throws Asn1Exception, IOException { - DerOutputStream temp, bytes, out; - temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(pvno)); - out = new DerOutputStream(); - out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp); - temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(msgType)); - out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), temp); + DerOutputStream temp, bytes, out; + temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(pvno)); + out = new DerOutputStream(); + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x01), temp); + temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(msgType)); + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x02), temp); if (pAData != null && pAData.length > 0) { - temp = new DerOutputStream(); - for (int i = 0; i < pAData.length; i++) { - temp.write(pAData[i].asn1Encode()); - } - bytes = new DerOutputStream(); - bytes.write(DerValue.tag_SequenceOf, temp); - out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), bytes); - } - out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), reqBody.asn1Encode(msgType)); - bytes = new DerOutputStream(); - bytes.write(DerValue.tag_Sequence, out); - out = new DerOutputStream(); - out.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)msgType), bytes); - return out.toByteArray(); - } - - public byte[] asn1EncodeReqBody() throws Asn1Exception, IOException - { - return reqBody.asn1Encode(msgType); + temp = new DerOutputStream(); + for (int i = 0; i < pAData.length; i++) { + temp.write(pAData[i].asn1Encode()); + } + bytes = new DerOutputStream(); + bytes.write(DerValue.tag_SequenceOf, temp); + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x03), bytes); } + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x04), reqBody.asn1Encode(msgType)); + bytes = new DerOutputStream(); + bytes.write(DerValue.tag_Sequence, out); + out = new DerOutputStream(); + out.write(DerValue.createTag(DerValue.TAG_APPLICATION, + true, (byte) msgType), bytes); + return out.toByteArray(); + } + public byte[] asn1EncodeReqBody() throws Asn1Exception, IOException { + return reqBody.asn1Encode(msgType); + } } diff --git a/src/share/classes/sun/security/krb5/internal/KRBCred.java b/src/share/classes/sun/security/krb5/internal/KRBCred.java index 2c364e834b01ba5ac268fe9b672783885bf7c9f7..a30ca6d2929379acb29b8c1fced208eb0b7095fc 100644 --- a/src/share/classes/sun/security/krb5/internal/KRBCred.java +++ b/src/share/classes/sun/security/krb5/internal/KRBCred.java @@ -56,128 +56,134 @@ import java.math.BigInteger; * * http://www.ietf.org/rfc/rfc4120.txt. */ - public class KRBCred { - public Ticket[] tickets = null; - public EncryptedData encPart; - private int pvno; - private int msgType; + public Ticket[] tickets = null; + public EncryptedData encPart; + private int pvno; + private int msgType; - public KRBCred(Ticket[] new_tickets, EncryptedData new_encPart) throws IOException { - pvno = Krb5.PVNO; - msgType = Krb5.KRB_CRED; - if (new_tickets != null) { - tickets = new Ticket[new_tickets.length]; - for (int i = 0; i < new_tickets.length; i++) { - if (new_tickets[i] == null) { - throw new IOException("Cannot create a KRBCred"); - } else { - tickets[i] = (Ticket)new_tickets[i].clone(); - } - } + public KRBCred(Ticket[] new_tickets, EncryptedData new_encPart) throws IOException { + pvno = Krb5.PVNO; + msgType = Krb5.KRB_CRED; + if (new_tickets != null) { + tickets = new Ticket[new_tickets.length]; + for (int i = 0; i < new_tickets.length; i++) { + if (new_tickets[i] == null) { + throw new IOException("Cannot create a KRBCred"); + } else { + tickets[i] = (Ticket) new_tickets[i].clone(); } - encPart = new_encPart; + } } + encPart = new_encPart; + } - public KRBCred(byte[] data) throws Asn1Exception, - RealmException, KrbApErrException, IOException { - init(new DerValue(data)); - } + public KRBCred(byte[] data) throws Asn1Exception, + RealmException, KrbApErrException, IOException { + init(new DerValue(data)); + } - public KRBCred(DerValue encoding) throws Asn1Exception, - RealmException, KrbApErrException, IOException { - init(encoding); - } + public KRBCred(DerValue encoding) throws Asn1Exception, + RealmException, KrbApErrException, IOException { + init(encoding); + } - /** - * Initializes an KRBCred object. - * @param encoding a single DER-encoded value. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * @exception KrbApErrException if the value read from the DER-encoded data - * stream does not match the pre-defined value. - * @exception RealmException if an error occurs while parsing a Realm object. - */ - private void init(DerValue encoding) throws Asn1Exception, - RealmException, KrbApErrException, IOException { - if (((encoding.getTag() & (byte)0x1F) != (byte)0x16) - || (encoding.isApplication() != true) - || (encoding.isConstructed() != true)) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); + /** + * Initializes an KRBCred object. + * @param encoding a single DER-encoded value. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * @exception KrbApErrException if the value read from the DER-encoded data + * stream does not match the pre-defined value. + * @exception RealmException if an error occurs while parsing a Realm object. + */ + private void init(DerValue encoding) throws Asn1Exception, + RealmException, KrbApErrException, IOException { + if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x16) + || (encoding.isApplication() != true) + || (encoding.isConstructed() != true)) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } DerValue der, subDer; - der = encoding.getData().getDerValue(); - if (der.getTag() != DerValue.tag_Sequence) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & 0x1F) == 0x00) { - pvno = subDer.getData().getBigInteger().intValue(); - if (pvno != Krb5.PVNO) { + der = encoding.getData().getDerValue(); + if (der.getTag() != DerValue.tag_Sequence) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & 0x1F) == 0x00) { + pvno = subDer.getData().getBigInteger().intValue(); + if (pvno != Krb5.PVNO) { throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION); - } - } - else - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & 0x1F) == 0x01) { - msgType = subDer.getData().getBigInteger().intValue(); - if (msgType != Krb5.KRB_CRED) + } + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & 0x1F) == 0x01) { + msgType = subDer.getData().getBigInteger().intValue(); + if (msgType != Krb5.KRB_CRED) { throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE); - } - else - throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } subDer = der.getData().getDerValue(); - if ((subDer.getTag() & 0x1F) == 0x02) { - DerValue subsubDer = subDer.getData().getDerValue(); + if ((subDer.getTag() & 0x1F) == 0x02) { + DerValue subsubDer = subDer.getData().getDerValue(); if (subsubDer.getTag() != DerValue.tag_SequenceOf) { - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - } - Vector v = new Vector (); + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + Vector v = new Vector(); while (subsubDer.getData().available() > 0) { - v.addElement(new Ticket(subsubDer.getData().getDerValue())); - } + v.addElement(new Ticket(subsubDer.getData().getDerValue())); + } if (v.size() > 0) { - tickets = new Ticket[v.size()]; - v.copyInto(tickets); - } - } - else - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - encPart = EncryptedData.parse(der.getData(), (byte)0x03, false); - - if (der.getData().available() > 0) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); + tickets = new Ticket[v.size()]; + v.copyInto(tickets); + } + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); } + encPart = EncryptedData.parse(der.getData(), (byte) 0x03, false); + if (der.getData().available() > 0) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + } - /** - * Encodes an KRBCred object. - * @return the data of encoded EncAPRepPart object. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ - public byte[] asn1Encode() throws Asn1Exception, IOException { + /** + * Encodes an KRBCred object. + * @return the data of encoded EncAPRepPart object. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + public byte[] asn1Encode() throws Asn1Exception, IOException { DerOutputStream temp, bytes, out; temp = new DerOutputStream(); temp.putInteger(BigInteger.valueOf(pvno)); out = new DerOutputStream(); - out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp); - temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(msgType)); - out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp); + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x00), temp); temp = new DerOutputStream(); - for (int i = 0; i < tickets.length; i++) { - temp.write(tickets[i].asn1Encode()); - } + temp.putInteger(BigInteger.valueOf(msgType)); + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x01), temp); + temp = new DerOutputStream(); + for (int i = 0; i < tickets.length; i++) { + temp.write(tickets[i].asn1Encode()); + } bytes = new DerOutputStream(); bytes.write(DerValue.tag_SequenceOf, temp); - out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), bytes); - out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), encPart.asn1Encode()); + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x02), bytes); + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x03), encPart.asn1Encode()); bytes = new DerOutputStream(); bytes.write(DerValue.tag_Sequence, out); - out = new DerOutputStream(); - out.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x16), bytes); - return out.toByteArray(); - } - + out = new DerOutputStream(); + out.write(DerValue.createTag(DerValue.TAG_APPLICATION, + true, (byte) 0x16), bytes); + return out.toByteArray(); + } } diff --git a/src/share/classes/sun/security/krb5/internal/KrbCredInfo.java b/src/share/classes/sun/security/krb5/internal/KrbCredInfo.java index 3853ab579cce0d195743b2fe3a5d9a872956b7cc..08a21b6658993d19ed6a7d700e5ed43c53ffe954 100644 --- a/src/share/classes/sun/security/krb5/internal/KrbCredInfo.java +++ b/src/share/classes/sun/security/krb5/internal/KrbCredInfo.java @@ -111,7 +111,7 @@ public class KrbCredInfo { * @exception RealmException if an error occurs while parsing a Realm object. */ public KrbCredInfo(DerValue encoding) - throws Asn1Exception, IOException, RealmException{ + throws Asn1Exception, IOException, RealmException{ if (encoding.getTag() != DerValue.tag_Sequence) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); } @@ -160,25 +160,25 @@ public class KrbCredInfo { Vector v = new Vector (); v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), key.asn1Encode())); if (prealm != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), prealm.asn1Encode())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), prealm.asn1Encode())); if (pname != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), pname.asn1Encode())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), pname.asn1Encode())); if (flags != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), flags.asn1Encode())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), flags.asn1Encode())); if (authtime != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), authtime.asn1Encode())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), authtime.asn1Encode())); if (starttime != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), starttime.asn1Encode())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), starttime.asn1Encode())); if (endtime != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), endtime.asn1Encode())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), endtime.asn1Encode())); if (renewTill != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x07), renewTill.asn1Encode())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x07), renewTill.asn1Encode())); if (srealm != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x08), srealm.asn1Encode())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x08), srealm.asn1Encode())); if (sname != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x09), sname.asn1Encode())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x09), sname.asn1Encode())); if (caddr != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x0A), caddr.asn1Encode())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x0A), caddr.asn1Encode())); DerValue der[] = new DerValue[v.size()]; v.copyInto(der); DerOutputStream out = new DerOutputStream(); diff --git a/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java b/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java index 5a62d6d2508fed4cf281066e0f6d72d965398735..64c3f8cd85bae7029baa796ea58a3d1462a1db86 100644 --- a/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java +++ b/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java @@ -215,7 +215,9 @@ public class CCacheInputStream extends KrbDataInputStream implements FileCCacheC addrType = read(2); addrLength = read(4); if (!(addrLength == 4 || addrLength == 16)) { - System.out.println("Incorrect address format."); + if (DEBUG) { + System.out.println("Incorrect address format."); + } return null; } byte[] result = new byte[addrLength]; @@ -338,15 +340,19 @@ public class CCacheInputStream extends KrbDataInputStream implements FileCCacheC System.out.println(">>>DEBUG key type: " + key.getEType()); long times[] = readTimes(); KerberosTime authtime = new KerberosTime(times[0]); - KerberosTime starttime = new KerberosTime(times[1]); + KerberosTime starttime = + (times[1]==0) ? null : new KerberosTime(times[1]); KerberosTime endtime = new KerberosTime(times[2]); - KerberosTime renewTill = new KerberosTime(times[3]); + KerberosTime renewTill = + (times[3]==0) ? null : new KerberosTime(times[3]); if (DEBUG) { System.out.println(">>>DEBUG auth time: " + authtime.toDate().toString()); - System.out.println(">>>DEBUG start time: " + starttime.toDate().toString()); + System.out.println(">>>DEBUG start time: " + + ((starttime==null)?"null":starttime.toDate().toString())); System.out.println(">>>DEBUG end time: " + endtime.toDate().toString()); - System.out.println(">>>DEBUG renew_till time: " + renewTill.toDate().toString()); + System.out.println(">>>DEBUG renew_till time: " + + ((renewTill==null)?"null":renewTill.toDate().toString())); } boolean skey = readskey(); boolean flags[] = readFlags(); diff --git a/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java b/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java index 4665d9f63dcc32ca5efa413e7336dec123975d9b..ff45cb73d37de7cbcce98169677440ca95185743 100644 --- a/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java +++ b/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java @@ -34,169 +34,185 @@ import sun.security.krb5.*; import sun.security.krb5.internal.*; public class Credentials { - PrincipalName cname; - Realm crealm; + + PrincipalName cname; + Realm crealm; PrincipalName sname; - Realm srealm; - EncryptionKey key; - KerberosTime authtime; - KerberosTime starttime;//optional - KerberosTime endtime; - KerberosTime renewTill; //optional - HostAddresses caddr; //optional; for proxied tickets only + Realm srealm; + EncryptionKey key; + KerberosTime authtime; + KerberosTime starttime;//optional + KerberosTime endtime; + KerberosTime renewTill; //optional + HostAddresses caddr; //optional; for proxied tickets only AuthorizationData authorizationData; //optional, not being actually used public boolean isEncInSKey; // true if ticket is encrypted in another ticket's skey - TicketFlags flags; + TicketFlags flags; Ticket ticket; - Ticket secondTicket; //optional - private boolean DEBUG = Krb5.DEBUG; - - public Credentials( - PrincipalName new_cname, - PrincipalName new_sname, - EncryptionKey new_key, - KerberosTime new_authtime, - KerberosTime new_starttime, - KerberosTime new_endtime, - KerberosTime new_renewTill, - boolean new_isEncInSKey, - TicketFlags new_flags, - HostAddresses new_caddr, - AuthorizationData new_authData, - Ticket new_ticket, - Ticket new_secondTicket) { - cname = (PrincipalName)new_cname.clone(); - if (new_cname.getRealm() != null) - crealm = (Realm)new_cname.getRealm().clone(); - - sname = (PrincipalName)new_sname.clone(); - if (new_sname.getRealm() != null) - srealm = (Realm)new_sname.getRealm().clone(); - - key = (EncryptionKey)new_key.clone(); - - authtime = (KerberosTime)new_authtime.clone(); - starttime = (KerberosTime)new_starttime.clone(); - endtime = (KerberosTime)new_endtime.clone(); - renewTill = (KerberosTime)new_renewTill.clone(); - if (new_caddr != null) - caddr = (HostAddresses)new_caddr.clone(); - if (new_authData != null) { - authorizationData - = (AuthorizationData)new_authData.clone(); - } - - isEncInSKey = new_isEncInSKey; - flags = (TicketFlags)new_flags.clone(); - ticket = (Ticket)(new_ticket.clone()); - if (new_secondTicket != null) - secondTicket = (Ticket)new_secondTicket.clone(); - } - - - - public Credentials( - KDCRep kdcRep, - Ticket new_secondTicket, - AuthorizationData new_authorizationData, - boolean new_isEncInSKey - ) { - if (kdcRep.encKDCRepPart == null) //can't store while encrypted - return; - crealm = (Realm)kdcRep.crealm.clone(); - cname = (PrincipalName)kdcRep.cname.clone(); - ticket = (Ticket)kdcRep.ticket.clone(); - key = (EncryptionKey)kdcRep.encKDCRepPart.key.clone(); - flags = (TicketFlags)kdcRep.encKDCRepPart.flags.clone(); - authtime = (KerberosTime)kdcRep.encKDCRepPart.authtime.clone(); - starttime = (KerberosTime)kdcRep.encKDCRepPart.starttime.clone(); - endtime = (KerberosTime)kdcRep.encKDCRepPart.endtime.clone(); - renewTill = (KerberosTime)kdcRep.encKDCRepPart.renewTill.clone(); - srealm = (Realm)kdcRep.encKDCRepPart.srealm.clone(); - sname = (PrincipalName)kdcRep.encKDCRepPart.sname.clone(); - caddr = (HostAddresses)kdcRep.encKDCRepPart.caddr.clone(); - secondTicket = (Ticket)new_secondTicket.clone(); - authorizationData = - (AuthorizationData)new_authorizationData.clone(); - isEncInSKey = new_isEncInSKey; - } - - public Credentials(KDCRep kdcRep) { - this(kdcRep, null); - } - - public Credentials(KDCRep kdcRep, Ticket new_ticket) { - sname = (PrincipalName)kdcRep.encKDCRepPart.sname.clone(); - srealm = (Realm)kdcRep.encKDCRepPart.srealm.clone(); - try { - sname.setRealm(srealm); - } - catch (RealmException e) { - } - cname = (PrincipalName)kdcRep.cname.clone(); - crealm = (Realm)kdcRep.crealm.clone(); - try { - cname.setRealm(crealm); - } - catch (RealmException e) { - } - key = (EncryptionKey)kdcRep.encKDCRepPart.key.clone(); - authtime = (KerberosTime)kdcRep.encKDCRepPart.authtime.clone(); - if (kdcRep.encKDCRepPart.starttime != null) { - starttime = (KerberosTime)kdcRep.encKDCRepPart.starttime.clone(); - } - else starttime = null; - endtime = (KerberosTime)kdcRep.encKDCRepPart.endtime.clone(); - if (kdcRep.encKDCRepPart.renewTill != null) { - renewTill = (KerberosTime)kdcRep.encKDCRepPart.renewTill.clone(); - } - else renewTill = null; - // if (kdcRep.msgType == Krb5.KRB_AS_REP) { - // isEncInSKey = false; - // secondTicket = null; - // } - flags = kdcRep.encKDCRepPart.flags; - if (kdcRep.encKDCRepPart.caddr != null) - caddr = (HostAddresses)kdcRep.encKDCRepPart.caddr.clone(); - else caddr = null; - ticket = (Ticket)kdcRep.ticket.clone(); - if (new_ticket != null) { - secondTicket = (Ticket)new_ticket.clone(); - isEncInSKey = true; - } else { - secondTicket = null; - isEncInSKey = false; - } - } - - /** - * Checks if this credential is expired - */ - public boolean isValid() { - boolean valid = true; - if (endtime.getTime() < System.currentTimeMillis()) { - valid = false; - } - else if ((starttime.getTime() > System.currentTimeMillis()) - || ((starttime == null) && (authtime.getTime() > System.currentTimeMillis()))) - { - valid = false; - } - return valid; - } - - public PrincipalName getServicePrincipal() throws RealmException{ - if (sname.getRealm() == null) { - sname.setRealm(srealm); - } - return sname; - } - - public sun.security.krb5.Credentials setKrbCreds() { - return new sun.security.krb5.Credentials(ticket, - cname, sname, key, flags, authtime, starttime, endtime, renewTill, caddr); + Ticket secondTicket; //optional + private boolean DEBUG = Krb5.DEBUG; + + public Credentials( + PrincipalName new_cname, + PrincipalName new_sname, + EncryptionKey new_key, + KerberosTime new_authtime, + KerberosTime new_starttime, + KerberosTime new_endtime, + KerberosTime new_renewTill, + boolean new_isEncInSKey, + TicketFlags new_flags, + HostAddresses new_caddr, + AuthorizationData new_authData, + Ticket new_ticket, + Ticket new_secondTicket) { + cname = (PrincipalName) new_cname.clone(); + if (new_cname.getRealm() != null) { + crealm = (Realm) new_cname.getRealm().clone(); + } + + sname = (PrincipalName) new_sname.clone(); + if (new_sname.getRealm() != null) { + srealm = (Realm) new_sname.getRealm().clone(); + } + + key = (EncryptionKey) new_key.clone(); + + authtime = (KerberosTime) new_authtime.clone(); + if (new_starttime != null) { + starttime = (KerberosTime) new_starttime.clone(); + } + endtime = (KerberosTime) new_endtime.clone(); + if (new_renewTill != null) { + renewTill = (KerberosTime) new_renewTill.clone(); + } + if (new_caddr != null) { + caddr = (HostAddresses) new_caddr.clone(); + } + if (new_authData != null) { + authorizationData = (AuthorizationData) new_authData.clone(); } + isEncInSKey = new_isEncInSKey; + flags = (TicketFlags) new_flags.clone(); + ticket = (Ticket) (new_ticket.clone()); + if (new_secondTicket != null) { + secondTicket = (Ticket) new_secondTicket.clone(); + } + } + + public Credentials( + KDCRep kdcRep, + Ticket new_secondTicket, + AuthorizationData new_authorizationData, + boolean new_isEncInSKey) { + if (kdcRep.encKDCRepPart == null) //can't store while encrypted + { + return; + } + crealm = (Realm) kdcRep.crealm.clone(); + cname = (PrincipalName) kdcRep.cname.clone(); + ticket = (Ticket) kdcRep.ticket.clone(); + key = (EncryptionKey) kdcRep.encKDCRepPart.key.clone(); + flags = (TicketFlags) kdcRep.encKDCRepPart.flags.clone(); + authtime = (KerberosTime) kdcRep.encKDCRepPart.authtime.clone(); + if (kdcRep.encKDCRepPart.starttime != null) { + starttime = (KerberosTime) kdcRep.encKDCRepPart.starttime.clone(); + } + endtime = (KerberosTime) kdcRep.encKDCRepPart.endtime.clone(); + if (kdcRep.encKDCRepPart.renewTill != null) { + renewTill = (KerberosTime) kdcRep.encKDCRepPart.renewTill.clone(); + } + srealm = (Realm) kdcRep.encKDCRepPart.srealm.clone(); + sname = (PrincipalName) kdcRep.encKDCRepPart.sname.clone(); + caddr = (HostAddresses) kdcRep.encKDCRepPart.caddr.clone(); + secondTicket = (Ticket) new_secondTicket.clone(); + authorizationData = + (AuthorizationData) new_authorizationData.clone(); + isEncInSKey = new_isEncInSKey; + } + + public Credentials(KDCRep kdcRep) { + this(kdcRep, null); + } + + public Credentials(KDCRep kdcRep, Ticket new_ticket) { + sname = (PrincipalName) kdcRep.encKDCRepPart.sname.clone(); + srealm = (Realm) kdcRep.encKDCRepPart.srealm.clone(); + try { + sname.setRealm(srealm); + } catch (RealmException e) { + } + cname = (PrincipalName) kdcRep.cname.clone(); + crealm = (Realm) kdcRep.crealm.clone(); + try { + cname.setRealm(crealm); + } catch (RealmException e) { + } + key = (EncryptionKey) kdcRep.encKDCRepPart.key.clone(); + authtime = (KerberosTime) kdcRep.encKDCRepPart.authtime.clone(); + if (kdcRep.encKDCRepPart.starttime != null) { + starttime = (KerberosTime) kdcRep.encKDCRepPart.starttime.clone(); + } else { + starttime = null; + } + endtime = (KerberosTime) kdcRep.encKDCRepPart.endtime.clone(); + if (kdcRep.encKDCRepPart.renewTill != null) { + renewTill = (KerberosTime) kdcRep.encKDCRepPart.renewTill.clone(); + } else { + renewTill = null; + } + // if (kdcRep.msgType == Krb5.KRB_AS_REP) { + // isEncInSKey = false; + // secondTicket = null; + // } + flags = kdcRep.encKDCRepPart.flags; + if (kdcRep.encKDCRepPart.caddr != null) { + caddr = (HostAddresses) kdcRep.encKDCRepPart.caddr.clone(); + } else { + caddr = null; + } + ticket = (Ticket) kdcRep.ticket.clone(); + if (new_ticket != null) { + secondTicket = (Ticket) new_ticket.clone(); + isEncInSKey = true; + } else { + secondTicket = null; + isEncInSKey = false; + } + } + + /** + * Checks if this credential is expired + */ + public boolean isValid() { + boolean valid = true; + if (endtime.getTime() < System.currentTimeMillis()) { + valid = false; + } else if (starttime != null) { + if (starttime.getTime() > System.currentTimeMillis()) { + valid = false; + } + } else { + if (authtime.getTime() > System.currentTimeMillis()) { + valid = false; + } + } + return valid; + } + + public PrincipalName getServicePrincipal() throws RealmException { + if (sname.getRealm() == null) { + sname.setRealm(srealm); + } + return sname; + } + + public sun.security.krb5.Credentials setKrbCreds() { + return new sun.security.krb5.Credentials(ticket, + cname, sname, key, flags, authtime, starttime, endtime, renewTill, caddr); + } + public KerberosTime getAuthTime() { return authtime; } diff --git a/src/share/classes/sun/security/krb5/internal/crypto/dk/AesDkCrypto.java b/src/share/classes/sun/security/krb5/internal/crypto/dk/AesDkCrypto.java index 31919fc51f5b6e83d2181fd41b942ba6ce95b169..ea6e2d3eb241722543106fc7c155eecd0922b07d 100644 --- a/src/share/classes/sun/security/krb5/internal/crypto/dk/AesDkCrypto.java +++ b/src/share/classes/sun/security/krb5/internal/crypto/dk/AesDkCrypto.java @@ -440,7 +440,9 @@ public class AesDkCrypto extends DkCrypto { for (int i = 0; i < hashSize; i++) { if (calculatedHmac[i] != ciphertext[hmacOffset+i]) { cksumFailed = true; - System.err.println("Checksum failed !"); + if (debug) { + System.err.println("Checksum failed !"); + } break; } } diff --git a/src/share/classes/sun/security/krb5/internal/crypto/dk/ArcFourCrypto.java b/src/share/classes/sun/security/krb5/internal/crypto/dk/ArcFourCrypto.java index 57a0c091721199eb5718eeb0fc8050442b2eed2c..8d4c89d60b3e956c6cf7a6bd08a18743c863ae54 100644 --- a/src/share/classes/sun/security/krb5/internal/crypto/dk/ArcFourCrypto.java +++ b/src/share/classes/sun/security/krb5/internal/crypto/dk/ArcFourCrypto.java @@ -397,7 +397,9 @@ public class ArcFourCrypto extends DkCrypto { for (int i = 0; i < hashSize; i++) { if (calculatedHmac[i] != ciphertext[i]) { cksumFailed = true; - System.err.println("Checksum failed !"); + if (debug) { + System.err.println("Checksum failed !"); + } break; } } diff --git a/src/share/classes/sun/security/ssl/CipherSuite.java b/src/share/classes/sun/security/ssl/CipherSuite.java index 794f7179f2061f5a073335b4bd00ffc76c6ab98b..81a3696f7afcddb875c5dea7f9377bdb8812c392 100644 --- a/src/share/classes/sun/security/ssl/CipherSuite.java +++ b/src/share/classes/sun/security/ssl/CipherSuite.java @@ -191,7 +191,7 @@ final class CipherSuite implements Comparable { if (s == null) { throw new IllegalArgumentException("Name must not be null"); } - CipherSuite c = (CipherSuite)nameMap.get(s); + CipherSuite c = nameMap.get(s); if ((c == null) || (c.allowed == false)) { throw new IllegalArgumentException("Unsupported ciphersuite " + s); } @@ -395,7 +395,7 @@ final class CipherSuite implements Comparable { } private static synchronized boolean isAvailable(BulkCipher cipher) { - Boolean b = (Boolean)availableCache.get(cipher); + Boolean b = availableCache.get(cipher); if (b == null) { try { SecretKey key = new SecretKeySpec diff --git a/src/share/classes/sun/security/ssl/DHCrypt.java b/src/share/classes/sun/security/ssl/DHCrypt.java index baf784cde2bc3cdb14d18959c1b9e7bd5a7248de..5c9dc14aac207baf989e76c56e05628bc8874d25 100644 --- a/src/share/classes/sun/security/ssl/DHCrypt.java +++ b/src/share/classes/sun/security/ssl/DHCrypt.java @@ -132,8 +132,7 @@ final class DHCrypt { } try { KeyFactory factory = JsseJce.getKeyFactory("DH"); - return (DHPublicKeySpec)factory.getKeySpec - (key, DHPublicKeySpec.class); + return factory.getKeySpec(key, DHPublicKeySpec.class); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/src/share/classes/sun/security/ssl/Handshaker.java b/src/share/classes/sun/security/ssl/Handshaker.java index b8395665d5a3373bb7f16de9f8d08f7533b2b9ac..5b9dae6c59084f5dc9a3ce97cd7cd18f3e34f2f4 100644 --- a/src/share/classes/sun/security/ssl/Handshaker.java +++ b/src/share/classes/sun/security/ssl/Handshaker.java @@ -617,7 +617,8 @@ abstract class Handshaker { r.write(1); // single byte of data if (conn != null) { - synchronized (conn.writeLock) { + conn.writeLock.lock(); + try { conn.writeRecord(r); conn.changeWriteCiphers(); if (debug != null && Debug.isOn("handshake")) { @@ -625,6 +626,8 @@ abstract class Handshaker { } mesg.write(output); output.flush(); + } finally { + conn.writeLock.unlock(); } } else { synchronized (engine.writeLock) { diff --git a/src/share/classes/sun/security/ssl/InputRecord.java b/src/share/classes/sun/security/ssl/InputRecord.java index 56ea2b0483e4fea9c15e0e34fc72aefab7096201..c0e3e4aa526ab29a58eda28573ff5371daa03947 100644 --- a/src/share/classes/sun/security/ssl/InputRecord.java +++ b/src/share/classes/sun/security/ssl/InputRecord.java @@ -426,12 +426,12 @@ class InputRecord extends ByteArrayInputStream implements Record { if (really < 0) { throw new SSLException("SSL peer shut down incorrectly"); } - - // now we've got a complete record. - count = contentLen + headerSize; - exlen = 0; } + // now we've got a complete record. + count = contentLen + headerSize; + exlen = 0; + if (debug != null && Debug.isOn("record")) { if (count < 0 || count > (maxRecordSize - headerSize)) { System.out.println(Thread.currentThread().getName() @@ -502,10 +502,11 @@ class InputRecord extends ByteArrayInputStream implements Record { if (really < 0) { throw new EOFException("SSL peer shut down incorrectly"); } - - // now we've got a complete record. - exlen = 0; } + + // now we've got a complete record. + exlen = 0; + hashInternal(buf, 2, 3); hashInternal(v2Buf, 0, len); V2toV3ClientHello(v2Buf); diff --git a/src/share/classes/sun/security/ssl/JsseJce.java b/src/share/classes/sun/security/ssl/JsseJce.java index 5fb6972874f644d2d981d2894397eff32df9461d..d9a40fb2b8474f068470d3cb9844e18a459d8abc 100644 --- a/src/share/classes/sun/security/ssl/JsseJce.java +++ b/src/share/classes/sun/security/ssl/JsseJce.java @@ -343,8 +343,7 @@ final class JsseJce { } try { KeyFactory factory = JsseJce.getKeyFactory("RSA"); - return (RSAPublicKeySpec)factory.getKeySpec - (key, RSAPublicKeySpec.class); + return factory.getKeySpec(key, RSAPublicKeySpec.class); } catch (Exception e) { throw (RuntimeException)new RuntimeException().initCause(e); } diff --git a/src/share/classes/sun/security/ssl/OutputRecord.java b/src/share/classes/sun/security/ssl/OutputRecord.java index 3153b07f1acced0d51b3d8470ce07dda81897fe3..3d580e5cd5b6cde93b3f73192f2d8e353b52ce51 100644 --- a/src/share/classes/sun/security/ssl/OutputRecord.java +++ b/src/share/classes/sun/security/ssl/OutputRecord.java @@ -174,6 +174,18 @@ class OutputRecord extends ByteArrayOutputStream implements Record { return count == headerSize; } + /* + * Return true if the record is of a given alert. + */ + boolean isAlert(byte description) { + // An alert is defined with a two bytes struct, + // {byte level, byte description}, following after the header bytes. + if (count > (headerSize + 1) && contentType == ct_alert) { + return buf[headerSize + 1] == description; + } + + return false; + } /* * Compute the MAC and append it to this record. In case we diff --git a/src/share/classes/sun/security/ssl/ProtocolList.java b/src/share/classes/sun/security/ssl/ProtocolList.java index 9898d244a2005b05a21c939028796af496ba99ee..197cfa4adbb31a4a674c5707bab5f71391fa794e 100644 --- a/src/share/classes/sun/security/ssl/ProtocolList.java +++ b/src/share/classes/sun/security/ssl/ProtocolList.java @@ -98,7 +98,7 @@ final class ProtocolList { protocolNames[i++] = version.name; } } - return (String[])protocolNames.clone(); + return protocolNames.clone(); } public String toString() { diff --git a/src/share/classes/sun/security/ssl/SSLSessionImpl.java b/src/share/classes/sun/security/ssl/SSLSessionImpl.java index 38d666ac337959c63ec10c1182e8fd967fe6183a..a37954ea22e4153d6915690c3cece837a1664f11 100644 --- a/src/share/classes/sun/security/ssl/SSLSessionImpl.java +++ b/src/share/classes/sun/security/ssl/SSLSessionImpl.java @@ -458,7 +458,7 @@ final class SSLSessionImpl implements SSLSession { + " for Kerberos cipher suites"); } if (peerCerts != null) { - return (X509Certificate [])peerCerts.clone(); + return peerCerts.clone(); } else { throw new SSLPeerUnverifiedException("peer not authenticated"); } @@ -489,7 +489,7 @@ final class SSLSessionImpl implements SSLSession { if (peerCerts == null) { throw new SSLPeerUnverifiedException("peer not authenticated"); } - return ((X500Principal)peerCerts[0].getSubjectX500Principal()); + return peerCerts[0].getSubjectX500Principal(); } /** @@ -508,7 +508,7 @@ final class SSLSessionImpl implements SSLSession { (KerberosPrincipal)localPrincipal); } return (localCerts == null ? null : - (X500Principal)localCerts[0].getSubjectX500Principal()); + localCerts[0].getSubjectX500Principal()); } /** diff --git a/src/share/classes/sun/security/ssl/SSLSocketImpl.java b/src/share/classes/sun/security/ssl/SSLSocketImpl.java index 0b8a16c0958954b0f8df80bc29ff1c30465ce272..66b6e6d112c0b7cf5856457bb37d17a951cbcc37 100644 --- a/src/share/classes/sun/security/ssl/SSLSocketImpl.java +++ b/src/share/classes/sun/security/ssl/SSLSocketImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. 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 @@ -33,6 +33,8 @@ import java.security.AccessController; import java.security.AccessControlContext; import java.security.PrivilegedAction; import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; import javax.crypto.BadPaddingException; @@ -274,7 +276,7 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { * from the peer are handled properly. */ private Object handshakeLock; - Object writeLock; + ReentrantLock writeLock; private Object readLock; private InputRecord inrec; @@ -314,7 +316,6 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { private HashMap handshakeListeners; - /* * Reuse the same internal input/output streams. */ @@ -526,7 +527,7 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { enabledCipherSuites = CipherSuiteList.getDefault(); enabledProtocols = ProtocolList.getDefault(); handshakeLock = new Object(); - writeLock = new Object(); + writeLock = new ReentrantLock(); readLock = new Object(); inrec = null; @@ -677,16 +678,81 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { // implementations are fragile and don't like to see empty // records, so this also increases robustness. // - synchronized (writeLock) { - if (!r.isEmpty()) { - // r.compress(c); - r.addMAC(writeMAC); - r.encrypt(writeCipher); - r.write(sockOutput); + if (!r.isEmpty()) { + + // If the record is a close notify alert, we need to honor + // socket option SO_LINGER. Note that we will try to send + // the close notify even if the SO_LINGER set to zero. + if (r.isAlert(Alerts.alert_close_notify) && getSoLinger() >= 0) { + + // keep and clear the current thread interruption status. + boolean interrupted = Thread.interrupted(); + try { + if (writeLock.tryLock(getSoLinger(), TimeUnit.SECONDS)) { + try { + writeRecordInternal(r); + } finally { + writeLock.unlock(); + } + } else { + SSLException ssle = new SSLException( + "SO_LINGER timeout," + + " close_notify message cannot be sent."); + + + // For layered, non-autoclose sockets, we are not + // able to bring them into a usable state, so we + // treat it as fatal error. + if (self != this && !autoClose) { + // Note that the alert description is + // specified as -1, so no message will be send + // to peer anymore. + fatal((byte)(-1), ssle); + } else if ((debug != null) && Debug.isOn("ssl")) { + System.out.println(threadName() + + ", received Exception: " + ssle); + } + + // RFC2246 requires that the session becomes + // unresumable if any connection is terminated + // without proper close_notify messages with + // level equal to warning. + // + // RFC4346 no longer requires that a session not be + // resumed if failure to properly close a connection. + // + // We choose to make the session unresumable if + // failed to send the close_notify message. + // + sess.invalidate(); + } + } catch (InterruptedException ie) { + // keep interrupted status + interrupted = true; + } + + // restore the interrupted status + if (interrupted) { + Thread.currentThread().interrupt(); + } + } else { + writeLock.lock(); + try { + writeRecordInternal(r); + } finally { + writeLock.unlock(); + } } } } + private void writeRecordInternal(OutputRecord r) throws IOException { + // r.compress(c); + r.addMAC(writeMAC); + r.encrypt(writeCipher); + r.write(sockOutput); + } + /* * Read an application data record. Alerts and handshake @@ -1533,7 +1599,11 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { if (oldState == cs_HANDSHAKE) { sockInput.skip(sockInput.available()); } - sendAlert(Alerts.alert_fatal, description); + + // If the description equals -1, the alert won't be sent to peer. + if (description != -1) { + sendAlert(Alerts.alert_fatal, description); + } if (cause instanceof SSLException) { // only true if != null closeReason = (SSLException)cause; } else { @@ -1614,7 +1684,7 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { * Emit alerts. Caller must have synchronized with "this". */ private void sendAlert(byte level, byte description) { - if (connectionState >= cs_CLOSED) { + if (connectionState >= cs_SENT_CLOSE) { return; } diff --git a/src/share/classes/sun/security/ssl/SessionId.java b/src/share/classes/sun/security/ssl/SessionId.java index 557fbff30c842d87e35c9b778f6c5735deab28f1..c9b900f743ad685940167443a319a8d8768886a4 100644 --- a/src/share/classes/sun/security/ssl/SessionId.java +++ b/src/share/classes/sun/security/ssl/SessionId.java @@ -64,7 +64,7 @@ class SessionId /** Returns the bytes in the ID. May be an empty array. */ byte [] getId () { - return (byte []) sessionId.clone (); + return sessionId.clone (); } /** Returns the ID as a string */ diff --git a/src/share/classes/sun/security/ssl/SunX509KeyManagerImpl.java b/src/share/classes/sun/security/ssl/SunX509KeyManagerImpl.java index a111f79b42761bacf3a8672da6ef41f50da4da06..2cd825def268f4d6b21dfe502f00111066572a06 100644 --- a/src/share/classes/sun/security/ssl/SunX509KeyManagerImpl.java +++ b/src/share/classes/sun/security/ssl/SunX509KeyManagerImpl.java @@ -172,7 +172,7 @@ final class SunX509KeyManagerImpl extends X509ExtendedKeyManager { if (cred == null) { return null; } else { - return (X509Certificate[])cred.certificates.clone(); + return cred.certificates.clone(); } } @@ -255,7 +255,7 @@ final class SunX509KeyManagerImpl extends X509ExtendedKeyManager { String[] aliases; if (issuers == null || issuers.length == 0) { - aliases = (String[])serverAliasCache.get(keyType); + aliases = serverAliasCache.get(keyType); if (aliases == null) { aliases = getServerAliases(keyType, issuers); // Cache the result (positive and negative lookups) @@ -388,7 +388,7 @@ final class SunX509KeyManagerImpl extends X509ExtendedKeyManager { } } - String[] aliasStrings = (String[])aliases.toArray(STRING0); + String[] aliasStrings = aliases.toArray(STRING0); return ((aliasStrings.length == 0) ? null : aliasStrings); } diff --git a/src/share/classes/sun/security/x509/AVA.java b/src/share/classes/sun/security/x509/AVA.java index 9a6b7a59d1a41c58d958e0e6bf0fc00dd08ff6ae..43d914cba13ea7b58734b7ac25732bc8665972ac 100644 --- a/src/share/classes/sun/security/x509/AVA.java +++ b/src/share/classes/sun/security/x509/AVA.java @@ -780,7 +780,8 @@ public class AVA implements DerEncoder { * Implementations MAY escape other characters. * * NOTE: this implementation also recognizes "=" and "#" as - * characters which need escaping. + * characters which need escaping, and null which is escaped as + * '\00' (see RFC 4514). * * If a character to be escaped is one of the list shown above, then * it is prefixed by a backslash ('\' ASCII 92). @@ -805,6 +806,10 @@ public class AVA implements DerEncoder { // append printable/escaped char sbuffer.append(c); + } else if (c == '\u0000') { + // escape null character + sbuffer.append("\\00"); + } else if (debug != null && Debug.isOn("ava")) { // embed non-printable/non-escaped char diff --git a/src/share/classes/sun/security/x509/CertificatePolicySet.java b/src/share/classes/sun/security/x509/CertificatePolicySet.java index 32e5121c76a3b89cd8a3d0c79b6c7e7164ba7202..514a3576cc47a964a99abf62aa722476f0ca98c6 100644 --- a/src/share/classes/sun/security/x509/CertificatePolicySet.java +++ b/src/share/classes/sun/security/x509/CertificatePolicySet.java @@ -87,7 +87,7 @@ public class CertificatePolicySet { DerOutputStream tmp = new DerOutputStream(); for (int i = 0; i < ids.size(); i++) { - ((CertificatePolicyId)ids.elementAt(i)).encode(tmp); + ids.elementAt(i).encode(tmp); } out.write(DerValue.tag_Sequence,tmp); } diff --git a/src/share/classes/sun/security/x509/X509Cert.java b/src/share/classes/sun/security/x509/X509Cert.java index 6777d4b4a2ff08ef906b6a28a0360f1c519c94ad..af68511129412f6c7ebf94b6aab704146691b316 100644 --- a/src/share/classes/sun/security/x509/X509Cert.java +++ b/src/share/classes/sun/security/x509/X509Cert.java @@ -516,7 +516,7 @@ public class X509Cert implements Certificate, Serializable { * Null is returned in the case of a partially constructed cert. */ public byte [] getSignedCert () - { return (byte[])signedCert.clone(); } + { return signedCert.clone(); } /** diff --git a/src/share/classes/sun/tools/jar/JarVerifierStream.java b/src/share/classes/sun/tools/jar/JarVerifierStream.java index 5485bfaded9969b082171ba8d0c0ec34a6272ed8..c39b35eaa172e3b5e1907c4155f5c3ae5b085e19 100644 --- a/src/share/classes/sun/tools/jar/JarVerifierStream.java +++ b/src/share/classes/sun/tools/jar/JarVerifierStream.java @@ -32,7 +32,6 @@ import java.util.jar.*; import java.security.cert.Certificate; import java.security.AccessController; import java.security.cert.X509Certificate; -import java.security.Identity; import java.security.PublicKey; import java.security.Principal; import sun.security.provider.SystemIdentity; @@ -49,7 +48,8 @@ import sun.security.provider.SystemIdentity; public class JarVerifierStream extends ZipInputStream { private JarEntry current; - private Hashtable verified = new Hashtable(); + private Hashtable> verified + = new Hashtable>(); private JarInputStream jis; private sun.tools.jar.Manifest man = null; @@ -120,7 +120,7 @@ public class JarVerifierStream extends ZipInputStream { if (current != null) { Certificate[] certs = current.getCertificates(); if (certs != null) { - Vector ids = getIds(certs); + Vector ids = getIds(certs); if (ids != null) { verified.put(current.getName(), ids); } @@ -189,7 +189,7 @@ public class JarVerifierStream extends ZipInputStream { static class CertCache { Certificate [] certs; - Vector ids; + Vector ids; boolean equals(Certificate[] certs) { if (this.certs == null) { @@ -229,21 +229,21 @@ public class JarVerifierStream extends ZipInputStream { } } - private ArrayList certCache = null; + private ArrayList certCache = null; /** * Returns the Identity vector for the given array of Certificates */ - protected Vector getIds(Certificate[] certs) { + protected Vector getIds(Certificate[] certs) { if (certs == null) return null; if (certCache == null) - certCache = new ArrayList(); + certCache = new ArrayList(); CertCache cc; for (int i = 0; i < certCache.size(); i++) { - cc = (CertCache) certCache.get(i); + cc = certCache.get(i); if (cc.equals(certs)) { return cc.ids; } @@ -265,8 +265,8 @@ public class JarVerifierStream extends ZipInputStream { new sun.security.x509.X509Cert(encoded); try { AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { - public Object run() + new java.security.PrivilegedExceptionAction() { + public Void run() throws java.security.KeyManagementException { id.addCertificate(oldC); @@ -278,7 +278,7 @@ public class JarVerifierStream extends ZipInputStream { pae.getException(); } if (cc.ids == null) - cc.ids = new Vector(); + cc.ids = new Vector(); cc.ids.addElement(id); } catch (java.security.KeyManagementException kme) { // ignore if we can't create Identity diff --git a/src/share/classes/sun/tools/jconsole/MBeansTab.java b/src/share/classes/sun/tools/jconsole/MBeansTab.java index c2055d0916c9910307bbed85e9caf6feb47787c8..53260144e6353545f258aa0e02551accfb1f8885 100644 --- a/src/share/classes/sun/tools/jconsole/MBeansTab.java +++ b/src/share/classes/sun/tools/jconsole/MBeansTab.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2007 Sun Microsystems, Inc. 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 @@ -26,6 +26,7 @@ package sun.tools.jconsole; import java.awt.BorderLayout; +import java.awt.EventQueue; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; @@ -42,7 +43,8 @@ import com.sun.tools.jconsole.JConsoleContext; @SuppressWarnings("serial") public class MBeansTab extends Tab implements - NotificationListener, PropertyChangeListener, TreeSelectionListener { + NotificationListener, PropertyChangeListener, + TreeSelectionListener, TreeWillExpandListener { private XTree tree; private XSheet sheet; @@ -70,6 +72,7 @@ public class MBeansTab extends Tab implements return sheet; } + @Override public void dispose() { super.dispose(); sheet.dispose(); @@ -79,61 +82,79 @@ public class MBeansTab extends Tab implements return vmPanel.getUpdateInterval(); } - void synchroniseMBeanServerView() { - // Register listener for MBean registration/unregistration - // - try { - getMBeanServerConnection().addNotificationListener( - MBeanServerDelegate.DELEGATE_NAME, - this, - null, - null); - } catch (InstanceNotFoundException e) { - // Should never happen because the MBeanServerDelegate - // is always present in any standard MBeanServer - // - if (JConsole.isDebug()) { - e.printStackTrace(); - } - } catch (IOException e) { - if (JConsole.isDebug()) { - e.printStackTrace(); + private void buildMBeanServerView() { + new SwingWorker, Void>() { + @Override + public Set doInBackground() { + // Register listener for MBean registration/unregistration + // + try { + getMBeanServerConnection().addNotificationListener( + MBeanServerDelegate.DELEGATE_NAME, + MBeansTab.this, + null, + null); + } catch (InstanceNotFoundException e) { + // Should never happen because the MBeanServerDelegate + // is always present in any standard MBeanServer + // + if (JConsole.isDebug()) { + e.printStackTrace(); + } + } catch (IOException e) { + if (JConsole.isDebug()) { + e.printStackTrace(); + } + vmPanel.getProxyClient().markAsDead(); + return null; + } + // Retrieve MBeans from MBeanServer + // + Set mbeans = null; + try { + mbeans = getMBeanServerConnection().queryNames(null, null); + } catch (IOException e) { + if (JConsole.isDebug()) { + e.printStackTrace(); + } + vmPanel.getProxyClient().markAsDead(); + return null; + } + return mbeans; } - vmPanel.getProxyClient().markAsDead(); - return; - } - // Retrieve MBeans from MBeanServer - // - Set newSet = null; - try { - newSet = getMBeanServerConnection().queryNames(null,null); - } catch (IOException e) { - if (JConsole.isDebug()) { - e.printStackTrace(); + @Override + protected void done() { + try { + // Wait for mbsc.queryNames() result + Set mbeans = get(); + // Do not display anything until the new tree has been built + // + tree.setVisible(false); + // Cleanup current tree + // + tree.removeAll(); + // Add MBeans to tree + // + tree.addMBeansToView(mbeans); + // Display the new tree + // + tree.setVisible(true); + } catch (Exception e) { + Throwable t = Utils.getActualException(e); + if (JConsole.isDebug()) { + System.err.println("Problem at MBean tree construction"); + t.printStackTrace(); + } + } } - vmPanel.getProxyClient().markAsDead(); - return; - } - // Cleanup current tree - // - tree.removeAll(); - // Do not display anything until the new tree has been built - // - tree.setVisible(false); - // Add MBeans to tree - // - for (ObjectName mbean : newSet) { - tree.addMBeanToView(mbean); - } - // Display the new tree - // - tree.setVisible(true); + }.execute(); } public MBeanServerConnection getMBeanServerConnection() { return vmPanel.getProxyClient().getMBeanServerConnection(); } + @Override public void update() { // Ping the connection to see if it is still alive. At // some point the ProxyClient class should centralize @@ -160,6 +181,7 @@ public class MBeansTab extends Tab implements tree.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION); tree.addTreeSelectionListener(this); + tree.addTreeWillExpandListener(this); tree.addMouseListener(ml); JScrollPane theScrollPane = new JScrollPane( tree, @@ -177,55 +199,55 @@ public class MBeansTab extends Tab implements add(mainSplit); } - /* notification listener */ - public void handleNotification(Notification notification, Object handback) { - if (notification instanceof MBeanServerNotification) { - ObjectName mbean = - ((MBeanServerNotification) notification).getMBeanName(); - if (notification.getType().equals( - MBeanServerNotification.REGISTRATION_NOTIFICATION)) { - tree.addMBeanToView(mbean); - } else if (notification.getType().equals( - MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) { - tree.delMBeanFromView(mbean); + /* notification listener: handleNotification */ + public void handleNotification( + final Notification notification, Object handback) { + EventQueue.invokeLater(new Runnable() { + public void run() { + if (notification instanceof MBeanServerNotification) { + ObjectName mbean = + ((MBeanServerNotification) notification).getMBeanName(); + if (notification.getType().equals( + MBeanServerNotification.REGISTRATION_NOTIFICATION)) { + tree.addMBeanToView(mbean); + } else if (notification.getType().equals( + MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) { + tree.removeMBeanFromView(mbean); + } + } } - } + }); } - /* property change listener */ + /* property change listener: propertyChange */ public void propertyChange(PropertyChangeEvent evt) { - if (evt.getPropertyName() == JConsoleContext.CONNECTION_STATE_PROPERTY) { + if (JConsoleContext.CONNECTION_STATE_PROPERTY.equals(evt.getPropertyName())) { boolean connected = (Boolean) evt.getNewValue(); if (connected) { - workerAdd(new Runnable() { - public void run() { - synchroniseMBeanServerView(); - } - }); + buildMBeanServerView(); } else { sheet.dispose(); } } - } - /* tree selection listener */ + /* tree selection listener: valueChanged */ public void valueChanged(TreeSelectionEvent e) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); sheet.displayNode(node); } - - /* tree mouse listener */ + /* tree mouse listener: mousePressed */ private MouseListener ml = new MouseAdapter() { + @Override public void mousePressed(MouseEvent e) { if (e.getClickCount() == 1) { int selRow = tree.getRowForLocation(e.getX(), e.getY()); if (selRow != -1) { TreePath selPath = tree.getPathForLocation(e.getX(), e.getY()); - DefaultMutableTreeNode node = (DefaultMutableTreeNode) - selPath.getLastPathComponent(); + DefaultMutableTreeNode node = + (DefaultMutableTreeNode) selPath.getLastPathComponent(); if (sheet.isMBeanNode(node)) { tree.expandPath(selPath); } @@ -233,4 +255,22 @@ public class MBeansTab extends Tab implements } } }; + + /* tree will expand listener: treeWillExpand */ + public void treeWillExpand(TreeExpansionEvent e) + throws ExpandVetoException { + TreePath path = e.getPath(); + if (!tree.hasBeenExpanded(path)) { + DefaultMutableTreeNode node = + (DefaultMutableTreeNode) path.getLastPathComponent(); + if (sheet.isMBeanNode(node) && !tree.hasMetadataNodes(node)) { + tree.addMetadataNodes(node); + } + } + } + + /* tree will expand listener: treeWillCollapse */ + public void treeWillCollapse(TreeExpansionEvent e) + throws ExpandVetoException { + } } diff --git a/src/share/classes/sun/tools/jconsole/MemoryPoolStat.java b/src/share/classes/sun/tools/jconsole/MemoryPoolStat.java index f1d75147b6212a4cfb4ba7d63822e545d5b48d3e..c8c27e91ac44db4bd48d307111c52bab1a2f91b1 100644 --- a/src/share/classes/sun/tools/jconsole/MemoryPoolStat.java +++ b/src/share/classes/sun/tools/jconsole/MemoryPoolStat.java @@ -22,6 +22,7 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ + package sun.tools.jconsole; import java.lang.management.MemoryUsage; diff --git a/src/share/classes/sun/tools/jconsole/VMPanel.java b/src/share/classes/sun/tools/jconsole/VMPanel.java index e57c91a5e359ebd82eb6673e4893a8e717296b97..8215a7a8ed5a99fe6b08ddce0ebda99878cbcc8f 100644 --- a/src/share/classes/sun/tools/jconsole/VMPanel.java +++ b/src/share/classes/sun/tools/jconsole/VMPanel.java @@ -45,6 +45,7 @@ import static sun.tools.jconsole.ProxyClient.*; @SuppressWarnings("serial") public class VMPanel extends JTabbedPane implements PropertyChangeListener { + private ProxyClient proxyClient; private Timer timer; private int updateInterval; @@ -55,12 +56,9 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { private String password; private String url; private VMInternalFrame vmIF = null; - private static final String windowsLaF = - "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"; - + "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"; private static ArrayList tabInfos = new ArrayList(); - private boolean wasConnected = false; // The everConnected flag keeps track of whether the window can be @@ -76,7 +74,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { // Each VMPanel has its own instance of the JConsolePlugin // A map of JConsolePlugin to the previous SwingWorker - private Map> plugins = null; + private Map> plugins = null; private boolean pluginTabsAdded = false; // Update these only on the EDT @@ -86,11 +84,11 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { static { tabInfos.add(new TabInfo(OverviewTab.class, OverviewTab.getTabName(), true)); - tabInfos.add(new TabInfo(MemoryTab.class, MemoryTab.getTabName(), true)); - tabInfos.add(new TabInfo(ThreadTab.class, ThreadTab.getTabName(), true)); - tabInfos.add(new TabInfo(ClassTab.class, ClassTab.getTabName(), true)); + tabInfos.add(new TabInfo(MemoryTab.class, MemoryTab.getTabName(), true)); + tabInfos.add(new TabInfo(ThreadTab.class, ThreadTab.getTabName(), true)); + tabInfos.add(new TabInfo(ClassTab.class, ClassTab.getTabName(), true)); tabInfos.add(new TabInfo(SummaryTab.class, SummaryTab.getTabName(), true)); - tabInfos.add(new TabInfo(MBeansTab.class, MBeansTab.getTabName(), true)); + tabInfos.add(new TabInfo(MBeansTab.class, MBeansTab.getTabName(), true)); } public static TabInfo[] getTabInfos() { @@ -101,8 +99,8 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { this.proxyClient = proxyClient; this.updateInterval = updateInterval; this.hostName = proxyClient.getHostName(); - this.port = proxyClient.getPort(); - this.vmid = proxyClient.getVmid(); + this.port = proxyClient.getPort(); + this.vmid = proxyClient.getVmid(); this.userName = proxyClient.getUserName(); this.password = proxyClient.getPassword(); this.url = proxyClient.getUrl(); @@ -113,7 +111,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { } } - plugins = new LinkedHashMap>(); + plugins = new LinkedHashMap>(); for (JConsolePlugin p : JConsole.getPlugins()) { p.setContext(proxyClient); plugins.put(p, null); @@ -128,10 +126,9 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { proxyClient.addPropertyChangeListener(this); addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { - if (connectedIconBounds != null - && (e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0 - && connectedIconBounds.contains(e.getPoint())) { + if (connectedIconBounds != null && (e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0 && connectedIconBounds.contains(e.getPoint())) { if (isConnected()) { disconnect(); @@ -145,23 +142,21 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { }); } - private static Icon connectedIcon16 = - new ImageIcon(VMPanel.class.getResource("resources/connected16.png")); + new ImageIcon(VMPanel.class.getResource("resources/connected16.png")); private static Icon connectedIcon24 = - new ImageIcon(VMPanel.class.getResource("resources/connected24.png")); + new ImageIcon(VMPanel.class.getResource("resources/connected24.png")); private static Icon disconnectedIcon16 = - new ImageIcon(VMPanel.class.getResource("resources/disconnected16.png")); + new ImageIcon(VMPanel.class.getResource("resources/disconnected16.png")); private static Icon disconnectedIcon24 = - new ImageIcon(VMPanel.class.getResource("resources/disconnected24.png")); - + new ImageIcon(VMPanel.class.getResource("resources/disconnected24.png")); private Rectangle connectedIconBounds; // Override to increase right inset for tab area, // in order to reserve space for the connect toggle. public void setUI(TabbedPaneUI ui) { - Insets insets = (Insets)UIManager.getLookAndFeelDefaults().get("TabbedPane.tabAreaInsets"); - insets = (Insets)insets.clone(); + Insets insets = (Insets) UIManager.getLookAndFeelDefaults().get("TabbedPane.tabAreaInsets"); + insets = (Insets) insets.clone(); insets.right += connectedIcon24.getIconWidth() + 8; UIManager.put("TabbedPane.tabAreaInsets", insets); super.setUI(ui); @@ -225,7 +220,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { private Tab instantiate(TabInfo tabInfo) { try { Constructor con = tabInfo.tabClass.getConstructor(VMPanel.class); - return (Tab)con.newInstance(this); + return (Tab) con.newInstance(this); } catch (Exception ex) { System.err.println(ex); return null; @@ -247,10 +242,11 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { * IT IS USED TO MAKE SOME LOCAL MANIPULATIONS. */ ProxyClient getProxyClient(boolean assertThread) { - if(assertThread) + if (assertThread) { return getProxyClient(); - else + } else { return proxyClient; + } } public ProxyClient getProxyClient() { @@ -294,6 +290,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { startUpdateTimer(); } else { new Thread("VMPanel.connect") { + public void run() { proxyClient.connect(); } @@ -301,68 +298,63 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { } } - // Call on EDT public void disconnect() { proxyClient.disconnect(); updateFrameTitle(); } - - // Called on EDT public void propertyChange(PropertyChangeEvent ev) { String prop = ev.getPropertyName(); if (prop == CONNECTION_STATE_PROPERTY) { - ConnectionState oldState = (ConnectionState)ev.getOldValue(); - ConnectionState newState = (ConnectionState)ev.getNewValue(); + ConnectionState oldState = (ConnectionState) ev.getOldValue(); + ConnectionState newState = (ConnectionState) ev.getNewValue(); switch (newState) { - case CONNECTING: - onConnecting(); - break; - - case CONNECTED: - if (progressBar != null) { - progressBar.setIndeterminate(false); - progressBar.setValue(100); - } - closeOptionPane(); - updateFrameTitle(); - // create tabs if not done - createPluginTabs(); - repaint(); - // Notify tabs - fireConnectedChange(true); - // Enable/disable tabs on initial update - initialUpdate = true; - // Start/Restart update timer on connect/reconnect - startUpdateTimer(); - break; - - case DISCONNECTED: - if (progressBar != null) { - progressBar.setIndeterminate(false); - progressBar.setValue(0); + case CONNECTING: + onConnecting(); + break; + + case CONNECTED: + if (progressBar != null) { + progressBar.setIndeterminate(false); + progressBar.setValue(100); + } closeOptionPane(); - } - vmPanelDied(); - if (oldState == ConnectionState.CONNECTED) { + updateFrameTitle(); + // create tabs if not done + createPluginTabs(); + repaint(); // Notify tabs - fireConnectedChange(false); - } - break; + fireConnectedChange(true); + // Enable/disable tabs on initial update + initialUpdate = true; + // Start/Restart update timer on connect/reconnect + startUpdateTimer(); + break; + + case DISCONNECTED: + if (progressBar != null) { + progressBar.setIndeterminate(false); + progressBar.setValue(0); + closeOptionPane(); + } + vmPanelDied(); + if (oldState == ConnectionState.CONNECTED) { + // Notify tabs + fireConnectedChange(false); + } + break; } } } - - // Called on EDT private void onConnecting() { time0 = System.currentTimeMillis(); - final JConsole jc = (JConsole)SwingUtilities.getWindowAncestor(this); + final JConsole jc = (JConsole) SwingUtilities.getWindowAncestor(this); String connectionName = getConnectionName(); progressBar = new JProgressBar(); @@ -373,17 +365,16 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { Object[] message = { "

    " + getText("connectingTo1", connectionName) + "

    ", progressPanel, - "" + getText("connectingTo2", connectionName) + "" + "" + getText("connectingTo2", connectionName) + "" }; - optionPane = - SheetDialog.showOptionDialog(this, - message, - JOptionPane.DEFAULT_OPTION, - JOptionPane.INFORMATION_MESSAGE, null, - new String[] { getText("Cancel") }, - 0); + SheetDialog.showOptionDialog(this, + message, + JOptionPane.DEFAULT_OPTION, + JOptionPane.INFORMATION_MESSAGE, null, + new String[]{getText("Cancel")}, + 0); } @@ -398,10 +389,11 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { try { sleep(2000 - elapsed); } catch (InterruptedException ex) { - // Ignore + // Ignore } } SwingUtilities.invokeLater(new Runnable() { + public void run() { optionPane.setVisible(false); progressBar = null; @@ -425,8 +417,8 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { private VMInternalFrame getFrame() { if (vmIF == null) { - vmIF = (VMInternalFrame)SwingUtilities.getAncestorOfClass(VMInternalFrame.class, - this); + vmIF = (VMInternalFrame) SwingUtilities.getAncestorOfClass(VMInternalFrame.class, + this); } return vmIF; } @@ -452,27 +444,27 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { timer.cancel(); } TimerTask timerTask = new TimerTask() { + public void run() { update(); } }; - String timerName = "Timer-"+getConnectionName(); + String timerName = "Timer-" + getConnectionName(); timer = new Timer(timerName, true); timer.schedule(timerTask, 0, updateInterval); } - // Call on EDT private void vmPanelDied() { disconnect(); - final JConsole jc = (JConsole)SwingUtilities.getWindowAncestor(this); + final JConsole jc = (JConsole) SwingUtilities.getWindowAncestor(this); JOptionPane optionPane; - final String connectStr = getText("Connect"); + final String connectStr = getText("Connect"); final String reconnectStr = getText("Reconnect"); - final String cancelStr = getText("Cancel"); + final String cancelStr = getText("Cancel"); String msgTitle, msgExplanation, buttonStr; @@ -488,15 +480,16 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { } optionPane = - SheetDialog.showOptionDialog(this, - "

    " + msgTitle + "

    " + - "" + msgExplanation + "", - JOptionPane.DEFAULT_OPTION, - JOptionPane.WARNING_MESSAGE, null, - new String[] { buttonStr, cancelStr }, - 0); + SheetDialog.showOptionDialog(this, + "

    " + msgTitle + "

    " + + "" + msgExplanation + "", + JOptionPane.DEFAULT_OPTION, + JOptionPane.WARNING_MESSAGE, null, + new String[]{buttonStr, cancelStr}, + 0); optionPane.addPropertyChangeListener(new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent event) { if (event.getPropertyName().equals(JOptionPane.VALUE_PROPERTY)) { Object value = event.getNewValue(); @@ -507,7 +500,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { try { getFrame().setClosed(true); } catch (PropertyVetoException ex) { - // Should not happen, but can be ignored. + // Should not happen, but can be ignored. } } } @@ -518,11 +511,13 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { // Note: This method is called on a TimerTask thread. Any GUI manipulation // must be performed with invokeLater() or invokeAndWait(). private Object lockObject = new Object(); + private void update() { - synchronized(lockObject) { + synchronized (lockObject) { if (!isConnected()) { if (wasConnected) { EventQueue.invokeLater(new Runnable() { + public void run() { vmPanelDied(); } @@ -548,6 +543,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { // if (initialUpdate) { EventQueue.invokeLater(new Runnable() { + public void run() { setEnabledAt(index, true); } @@ -569,8 +565,8 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { // plugin GUI update for (JConsolePlugin p : plugins.keySet()) { - SwingWorker sw = p.newSwingWorker(); - SwingWorker prevSW = plugins.get(p); + SwingWorker sw = p.newSwingWorker(); + SwingWorker prevSW = plugins.get(p); // schedule SwingWorker to run only if the previous // SwingWorker has finished its task and it hasn't started. if (prevSW == null || prevSW.isDone()) { @@ -583,7 +579,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { } } - // Set the first enabled tab in the tab´s list + // Set the first enabled tab in the tab's list // as the selected tab on initial update // if (initialUpdate) { @@ -622,7 +618,6 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { return url; } - public String getPassword() { return password; } @@ -636,6 +631,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { } static class TabInfo { + Class tabClass; String name; boolean tabVisible; diff --git a/src/share/classes/sun/tools/jconsole/inspector/OperationEntry.java b/src/share/classes/sun/tools/jconsole/inspector/OperationEntry.java index 0eb3876838ab6495f6ac750b5c4d0c3d5bea05ff..c6a805ab391ebee040bdcf0fcfe7351c9bbf8101 100644 --- a/src/share/classes/sun/tools/jconsole/inspector/OperationEntry.java +++ b/src/share/classes/sun/tools/jconsole/inspector/OperationEntry.java @@ -22,8 +22,8 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ -package sun.tools.jconsole.inspector; +package sun.tools.jconsole.inspector; // java import import java.awt.*; diff --git a/src/share/classes/sun/tools/jconsole/inspector/TableSorter.java b/src/share/classes/sun/tools/jconsole/inspector/TableSorter.java index 886b11c57f0e8822d872fd9c08626824953107dd..14ac7bc2ebb96ce584f8c1cfd3d7a54ae7bfe93a 100644 --- a/src/share/classes/sun/tools/jconsole/inspector/TableSorter.java +++ b/src/share/classes/sun/tools/jconsole/inspector/TableSorter.java @@ -22,6 +22,7 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ + package sun.tools.jconsole.inspector; import java.util.*; diff --git a/src/share/classes/sun/tools/jconsole/inspector/ThreadDialog.java b/src/share/classes/sun/tools/jconsole/inspector/ThreadDialog.java index ea07d1393c10abe748225e4d3b5554aaa8bd8abe..a548fadd60f1277f899d6e3aede638fc9add04af 100644 --- a/src/share/classes/sun/tools/jconsole/inspector/ThreadDialog.java +++ b/src/share/classes/sun/tools/jconsole/inspector/ThreadDialog.java @@ -22,6 +22,7 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ + package sun.tools.jconsole.inspector; // java import diff --git a/src/share/classes/sun/tools/jconsole/inspector/Utils.java b/src/share/classes/sun/tools/jconsole/inspector/Utils.java index 7ae531eff3afddc614478735024f8d6a7c5e7f03..eee13d6709490a5e4e7ae7e104db1ffcbfba433c 100644 --- a/src/share/classes/sun/tools/jconsole/inspector/Utils.java +++ b/src/share/classes/sun/tools/jconsole/inspector/Utils.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2007 Sun Microsystems, Inc. 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 @@ -29,55 +29,51 @@ import java.awt.event.*; import java.lang.reflect.*; import java.math.BigDecimal; import java.math.BigInteger; +import java.util.*; +import java.util.concurrent.ExecutionException; import javax.management.*; import javax.management.openmbean.*; import javax.swing.*; import javax.swing.text.*; -import java.util.*; public class Utils { private Utils() { } - private static Set tableNavigationKeys = - new HashSet(Arrays.asList(new Integer[] { + new HashSet(Arrays.asList(new Integer[]{ KeyEvent.VK_TAB, KeyEvent.VK_ENTER, KeyEvent.VK_HOME, KeyEvent.VK_END, KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT, KeyEvent.VK_UP, KeyEvent.VK_DOWN, - KeyEvent.VK_PAGE_UP, KeyEvent.VK_PAGE_DOWN})); - + KeyEvent.VK_PAGE_UP, KeyEvent.VK_PAGE_DOWN + })); private static final Set> primitiveWrappers = - new HashSet>(Arrays.asList(new Class[] { + new HashSet>(Arrays.asList(new Class[]{ Byte.class, Short.class, Integer.class, Long.class, - Float.class, Double.class, Character.class, Boolean.class})); - + Float.class, Double.class, Character.class, Boolean.class + })); private static final Set> primitives = new HashSet>(); - private static final Map> primitiveMap = new HashMap>(); - private static final Map> primitiveToWrapper = new HashMap>(); - private static final Set editableTypes = new HashSet(); - private static final Set> extraEditableClasses = - new HashSet>(Arrays.asList(new Class[] { + new HashSet>(Arrays.asList(new Class[]{ BigDecimal.class, BigInteger.class, Number.class, - String.class, ObjectName.class})); - + String.class, ObjectName.class + })); private static final Set numericalTypes = new HashSet(); - private static final Set extraNumericalTypes = - new HashSet(Arrays.asList(new String[] { + new HashSet(Arrays.asList(new String[]{ BigDecimal.class.getName(), BigInteger.class.getName(), - Number.class.getName()})); - + Number.class.getName() + })); private static final Set booleanTypes = - new HashSet(Arrays.asList(new String[] { - Boolean.TYPE.getName(), Boolean.class.getName()})); + new HashSet(Arrays.asList(new String[]{ + Boolean.TYPE.getName(), Boolean.class.getName() + })); static { // compute primitives/primitiveMap/primitiveToWrapper @@ -122,10 +118,11 @@ public class Utils { * It's used to cater for the primitive types. */ public static Class getClass(String className) - throws ClassNotFoundException { + throws ClassNotFoundException { Class c; - if ((c = primitiveMap.get(className)) != null) + if ((c = primitiveMap.get(className)) != null) { return c; + } return Class.forName(className); } @@ -155,7 +152,9 @@ public class Utils { * structure, i.e. a data structure jconsole can render as an array. */ public static boolean canBeRenderedAsArray(Object elem) { - if (isSupportedArray(elem)) return true; + if (isSupportedArray(elem)) { + return true; + } if (elem instanceof Collection) { Collection c = (Collection) elem; if (c.isEmpty()) { @@ -168,7 +167,7 @@ public class Utils { // - Collections of other Java types are handled as arrays // return !isUniformCollection(c, CompositeData.class) && - !isUniformCollection(c, TabularData.class); + !isUniformCollection(c, TabularData.class); } } if (elem instanceof Map) { @@ -239,7 +238,9 @@ public class Utils { */ public static String getReadableClassName(String name) { String className = getArrayClassName(name); - if (className == null) return name; + if (className == null) { + return name; + } int index = name.lastIndexOf("["); StringBuilder brackets = new StringBuilder(className); for (int i = 0; i <= index; i++) { @@ -282,7 +283,7 @@ public class Utils { * Try to create a Java object using a one-string-param constructor. */ public static Object newStringConstructor(String type, String param) - throws Exception { + throws Exception { Constructor c = Utils.getClass(type).getConstructor(String.class); try { return c.newInstance(param); @@ -300,7 +301,7 @@ public class Utils { * Try to convert a string value into a numerical value. */ private static Number createNumberFromStringValue(String value) - throws NumberFormatException { + throws NumberFormatException { final String suffix = value.substring(value.length() - 1); if ("L".equalsIgnoreCase(suffix)) { return Long.valueOf(value.substring(0, value.length() - 1)); @@ -314,17 +315,17 @@ public class Utils { try { return Integer.valueOf(value); } catch (NumberFormatException e) { - // OK: Ignore exception... + // OK: Ignore exception... } try { return Long.valueOf(value); } catch (NumberFormatException e1) { - // OK: Ignore exception... + // OK: Ignore exception... } try { return Double.valueOf(value); } catch (NumberFormatException e2) { - // OK: Ignore exception... + // OK: Ignore exception... } throw new NumberFormatException("Cannot convert string value '" + value + "' into a numerical value"); @@ -337,7 +338,7 @@ public class Utils { * will return an Integer object initialized to 10. */ public static Object createObjectFromString(String type, String value) - throws Exception { + throws Exception { Object result; if (primitiveToWrapper.containsKey(type)) { if (type.equals(Character.TYPE.getName())) { @@ -367,7 +368,7 @@ public class Utils { * into a useful object array for passing into a parameter array. */ public static Object[] getParameters(XTextField[] inputs, String[] params) - throws Exception { + throws Exception { Object result[] = new Object[inputs.length]; Object userInput; for (int i = 0; i < inputs.length; i++) { @@ -388,12 +389,17 @@ public class Utils { * If the exception is wrapped, unwrap it. */ public static Throwable getActualException(Throwable e) { + if (e instanceof ExecutionException) { + e = e.getCause(); + } if (e instanceof MBeanException || e instanceof RuntimeMBeanException || e instanceof RuntimeOperationsException || e instanceof ReflectionException) { Throwable t = e.getCause(); - if (t != null) return t; + if (t != null) { + return t; + } } return e; } @@ -401,6 +407,7 @@ public class Utils { @SuppressWarnings("serial") public static class ReadOnlyTableCellEditor extends DefaultCellEditor { + public ReadOnlyTableCellEditor(JTextField tf) { super(tf); tf.addFocusListener(new Utils.EditFocusAdapter(this)); @@ -409,20 +416,25 @@ public class Utils { } public static class EditFocusAdapter extends FocusAdapter { + private CellEditor editor; + public EditFocusAdapter(CellEditor editor) { this.editor = editor; } + + @Override public void focusLost(FocusEvent e) { editor.stopCellEditing(); } - }; + } public static class CopyKeyAdapter extends KeyAdapter { private static final String defaultEditorKitCopyActionName = DefaultEditorKit.copyAction; private static final String transferHandlerCopyActionName = (String) TransferHandler.getCopyAction().getValue(Action.NAME); + @Override public void keyPressed(KeyEvent e) { // Accept "copy" key strokes KeyStroke ks = KeyStroke.getKeyStroke( @@ -441,6 +453,8 @@ public class Utils { e.consume(); } } + + @Override public void keyTyped(KeyEvent e) { e.consume(); } diff --git a/src/share/classes/sun/tools/jconsole/inspector/XDataViewer.java b/src/share/classes/sun/tools/jconsole/inspector/XDataViewer.java index 21b3f44189edafaf4906f05d47128c820e23e3dc..8a339f2ac4952495047516cde471679f5771fe42 100644 --- a/src/share/classes/sun/tools/jconsole/inspector/XDataViewer.java +++ b/src/share/classes/sun/tools/jconsole/inspector/XDataViewer.java @@ -22,6 +22,7 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ + package sun.tools.jconsole.inspector; import javax.swing.JTable; @@ -108,6 +109,7 @@ public class XDataViewer { public Component createOperationViewer(Object value, XMBean mbean) { if(value instanceof Number) return null; + if(value instanceof Component) return (Component) value; return createAttributeViewer(value, mbean, null, null); } diff --git a/src/share/classes/sun/tools/jconsole/inspector/XMBean.java b/src/share/classes/sun/tools/jconsole/inspector/XMBean.java index eed56044e0969b8d25d6a291ca53b2cf3675ec3e..9999d7dbda16682d14e771a059e9e831fb6400cc 100644 --- a/src/share/classes/sun/tools/jconsole/inspector/XMBean.java +++ b/src/share/classes/sun/tools/jconsole/inspector/XMBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2007 Sun Microsystems, Inc. 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 @@ -28,47 +28,56 @@ package sun.tools.jconsole.inspector; import java.io.IOException; import javax.management.*; import javax.swing.Icon; +import sun.tools.jconsole.JConsole; import sun.tools.jconsole.MBeansTab; -public class XMBean extends Object { - private ObjectName objectName; +public class XMBean { + + private final MBeansTab mbeansTab; + private final ObjectName objectName; private Icon icon; private String text; - private boolean broadcaster; + private Boolean broadcaster; + private final Object broadcasterLock = new Object(); private MBeanInfo mbeanInfo; - private MBeansTab mbeansTab; + private final Object mbeanInfoLock = new Object(); - public XMBean(ObjectName objectName, MBeansTab mbeansTab) - throws InstanceNotFoundException, IntrospectionException, - ReflectionException, IOException { + public XMBean(ObjectName objectName, MBeansTab mbeansTab) { this.mbeansTab = mbeansTab; - setObjectName(objectName); + this.objectName = objectName; + text = objectName.getKeyProperty("name"); + if (text == null) { + text = objectName.getDomain(); + } if (MBeanServerDelegate.DELEGATE_NAME.equals(objectName)) { icon = IconManager.MBEANSERVERDELEGATE; } else { icon = IconManager.MBEAN; } - this.broadcaster = isBroadcaster(objectName); - this.mbeanInfo = getMBeanInfo(objectName); } MBeanServerConnection getMBeanServerConnection() { return mbeansTab.getMBeanServerConnection(); } - public boolean isBroadcaster() { - return broadcaster; - } - - private boolean isBroadcaster(ObjectName name) { - try { - return getMBeanServerConnection().isInstanceOf( - name, "javax.management.NotificationBroadcaster"); - } catch (Exception e) { - System.out.println("Error calling isBroadcaster: " + - e.getMessage()); + public Boolean isBroadcaster() { + synchronized (broadcasterLock) { + if (broadcaster == null) { + try { + broadcaster = getMBeanServerConnection().isInstanceOf( + getObjectName(), + "javax.management.NotificationBroadcaster"); + } catch (Exception e) { + if (JConsole.isDebug()) { + System.err.println("Couldn't check if MBean [" + + objectName + "] is a notification broadcaster"); + e.printStackTrace(); + } + return false; + } + } + return broadcaster; } - return false; } public Object invoke(String operationName) throws Exception { @@ -78,35 +87,35 @@ public class XMBean extends Object { } public Object invoke(String operationName, Object params[], String sig[]) - throws Exception { + throws Exception { Object result = getMBeanServerConnection().invoke( getObjectName(), operationName, params, sig); return result; } public void setAttribute(Attribute attribute) - throws AttributeNotFoundException, InstanceNotFoundException, + throws AttributeNotFoundException, InstanceNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException, IOException { getMBeanServerConnection().setAttribute(getObjectName(), attribute); } public Object getAttribute(String attributeName) - throws AttributeNotFoundException, InstanceNotFoundException, + throws AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException, IOException { return getMBeanServerConnection().getAttribute( getObjectName(), attributeName); } public AttributeList getAttributes(String attributeNames[]) - throws AttributeNotFoundException, InstanceNotFoundException, + throws AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException, IOException { return getMBeanServerConnection().getAttributes( getObjectName(), attributeNames); } public AttributeList getAttributes(MBeanAttributeInfo attributeNames[]) - throws AttributeNotFoundException, InstanceNotFoundException, + throws AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException, IOException { String attributeString[] = new String[attributeNames.length]; for (int i = 0; i < attributeNames.length; i++) { @@ -119,32 +128,34 @@ public class XMBean extends Object { return objectName; } - private void setObjectName(ObjectName objectName) { - this.objectName = objectName; - // generate a readable name now - String name = getObjectName().getKeyProperty("name"); - if (name == null) - setText(getObjectName().getDomain()); - else - setText(name); - } - - public MBeanInfo getMBeanInfo() { - return mbeanInfo; + public MBeanInfo getMBeanInfo() throws InstanceNotFoundException, + IntrospectionException, ReflectionException, IOException { + synchronized (mbeanInfoLock) { + if (mbeanInfo == null) { + mbeanInfo = getMBeanServerConnection().getMBeanInfo(objectName); + } + return mbeanInfo; + } } - private MBeanInfo getMBeanInfo(ObjectName name) - throws InstanceNotFoundException, IntrospectionException, - ReflectionException, IOException { - return getMBeanServerConnection().getMBeanInfo(name); + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj == this) { + return true; + } + if (!(obj instanceof XMBean)) { + return false; + } + XMBean that = (XMBean) obj; + return getObjectName().equals(that.getObjectName()); } - public boolean equals(Object o) { - if (o instanceof XMBean) { - XMBean mbean = (XMBean) o; - return getObjectName().equals((mbean).getObjectName()); - } - return false; + @Override + public int hashCode() { + return (objectName == null ? 0 : objectName.hashCode()); } public String getText() { @@ -163,6 +174,7 @@ public class XMBean extends Object { this.icon = icon; } + @Override public String toString() { return getText(); } diff --git a/src/share/classes/sun/tools/jconsole/inspector/XMBeanInfo.java b/src/share/classes/sun/tools/jconsole/inspector/XMBeanInfo.java index 5a87772f87cd00cee1ad03a296ce40f1d7d72f1b..bb195cd990e27a3ed7a707e568d698f0e46035da 100644 --- a/src/share/classes/sun/tools/jconsole/inspector/XMBeanInfo.java +++ b/src/share/classes/sun/tools/jconsole/inspector/XMBeanInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2007 Sun Microsystems, Inc. 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 @@ -35,10 +35,7 @@ import javax.swing.*; import javax.swing.border.TitledBorder; import javax.swing.event.*; import javax.swing.table.*; -import javax.swing.tree.*; -import sun.tools.jconsole.JConsole; import sun.tools.jconsole.Resources; -import sun.tools.jconsole.inspector.XNodeInfo.Type; import static sun.tools.jconsole.Utilities.*; @@ -46,21 +43,20 @@ import static sun.tools.jconsole.Utilities.*; public class XMBeanInfo extends JPanel { private static final Color lightYellow = new Color(255, 255, 128); - private final int NAME_COLUMN = 0; private final int VALUE_COLUMN = 1; - private final String[] columnNames = { Resources.getText("Name"), Resources.getText("Value") }; - private JTable infoTable = new JTable(); private JTable descTable = new JTable(); private JPanel infoBorderPanel = new JPanel(new BorderLayout()); private JPanel descBorderPanel = new JPanel(new BorderLayout()); private static class ReadOnlyDefaultTableModel extends DefaultTableModel { + + @Override public void setValueAt(Object value, int row, int col) { } } @@ -73,17 +69,18 @@ public class XMBeanInfo extends JPanel { this.tableRowDividerText = tableRowDividerText; } + @Override public String toString() { return tableRowDividerText; } } - private static MBeanInfoTableCellRenderer renderer = new MBeanInfoTableCellRenderer(); private static class MBeanInfoTableCellRenderer extends DefaultTableCellRenderer { + @Override public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { @@ -92,22 +89,24 @@ public class XMBeanInfo extends JPanel { if (value instanceof TableRowDivider) { JLabel label = new JLabel(value.toString()); label.setBackground(ensureContrast(lightYellow, - label.getForeground())); + label.getForeground())); label.setOpaque(true); return label; } return comp; } } - private static TableCellEditor editor = new MBeanInfoTableCellEditor(new JTextField()); private static class MBeanInfoTableCellEditor extends Utils.ReadOnlyTableCellEditor { + public MBeanInfoTableCellEditor(JTextField tf) { super(tf); } + + @Override public Component getTableCellEditorComponent( JTable table, Object value, boolean isSelected, int row, int column) { @@ -116,7 +115,7 @@ public class XMBeanInfo extends JPanel { if (value instanceof TableRowDivider) { JLabel label = new JLabel(value.toString()); label.setBackground(ensureContrast(lightYellow, - label.getForeground())); + label.getForeground())); label.setOpaque(true); return label; } @@ -172,6 +171,7 @@ public class XMBeanInfo extends JPanel { add(descBorderPanel); } + // Call on EDT public void emptyInfoTable() { DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel(); while (tableModel.getRowCount() > 0) { @@ -179,6 +179,7 @@ public class XMBeanInfo extends JPanel { } } + // Call on EDT public void emptyDescTable() { DefaultTableModel tableModel = (DefaultTableModel) descTable.getModel(); while (tableModel.getRowCount() > 0) { @@ -186,6 +187,7 @@ public class XMBeanInfo extends JPanel { } } + // Call on EDT private void addDescriptor(Descriptor desc, String text) { if (desc != null && desc.getFieldNames().length > 0) { DefaultTableModel tableModel = (DefaultTableModel) descTable.getModel(); @@ -223,6 +225,7 @@ public class XMBeanInfo extends JPanel { } } + // Call on EDT public void addMBeanInfo(XMBean mbean, MBeanInfo mbeanInfo) { emptyInfoTable(); emptyDescTable(); @@ -263,6 +266,7 @@ public class XMBeanInfo extends JPanel { tableModel.newDataAvailable(new TableModelEvent(tableModel)); } + // Call on EDT public void addMBeanAttributeInfo(MBeanAttributeInfo mbai) { emptyInfoTable(); emptyDescTable(); @@ -296,6 +300,7 @@ public class XMBeanInfo extends JPanel { tableModel.newDataAvailable(new TableModelEvent(tableModel)); } + // Call on EDT public void addMBeanOperationInfo(MBeanOperationInfo mboi) { emptyInfoTable(); emptyDescTable(); @@ -343,6 +348,7 @@ public class XMBeanInfo extends JPanel { tableModel.newDataAvailable(new TableModelEvent(tableModel)); } + // Call on EDT public void addMBeanNotificationInfo(MBeanNotificationInfo mbni) { emptyInfoTable(); emptyDescTable(); @@ -367,6 +373,7 @@ public class XMBeanInfo extends JPanel { tableModel.newDataAvailable(new TableModelEvent(tableModel)); } + // Call on EDT private void addMBeanConstructorInfo(MBeanConstructorInfo mbci, String text) { DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel(); Object rowData[] = new Object[2]; @@ -383,6 +390,7 @@ public class XMBeanInfo extends JPanel { tableModel.newDataAvailable(new TableModelEvent(tableModel)); } + // Call on EDT private void addMBeanParameterInfo(MBeanParameterInfo mbpi, String text) { DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel(); Object rowData[] = new Object[2]; @@ -401,91 +409,4 @@ public class XMBeanInfo extends JPanel { addDescriptor(mbpi.getDescriptor(), text); tableModel.newDataAvailable(new TableModelEvent(tableModel)); } - - public static void loadInfo(DefaultMutableTreeNode root) { - // Retrieve XMBean from XNodeInfo - // - XMBean mbean = (XMBean) ((XNodeInfo) root.getUserObject()).getData(); - // Initialize MBean*Info - // - final MBeanInfo mbeanInfo; - try { - mbeanInfo = mbean.getMBeanInfo(); - } catch (Exception e) { - if (JConsole.isDebug()) { - e.printStackTrace(); - } - return; - } - MBeanAttributeInfo[] ai = mbeanInfo.getAttributes(); - MBeanOperationInfo[] oi = mbeanInfo.getOperations(); - MBeanNotificationInfo[] ni = mbeanInfo.getNotifications(); - // MBeanAttributeInfo node - // - if (ai != null && ai.length > 0) { - DefaultMutableTreeNode attributes = new DefaultMutableTreeNode(); - XNodeInfo attributesUO = new XNodeInfo(Type.ATTRIBUTES, mbean, - Resources.getText("Attributes"), null); - attributes.setUserObject(attributesUO); - root.add(attributes); - for (MBeanAttributeInfo mbai : ai) { - DefaultMutableTreeNode attribute = new DefaultMutableTreeNode(); - XNodeInfo attributeUO = new XNodeInfo(Type.ATTRIBUTE, - new Object[] {mbean, mbai}, mbai.getName(), null); - attribute.setUserObject(attributeUO); - attributes.add(attribute); - } - } - // MBeanOperationInfo node - // - if (oi != null && oi.length > 0) { - DefaultMutableTreeNode operations = new DefaultMutableTreeNode(); - XNodeInfo operationsUO = new XNodeInfo(Type.OPERATIONS, mbean, - Resources.getText("Operations"), null); - operations.setUserObject(operationsUO); - root.add(operations); - for (MBeanOperationInfo mboi : oi) { - // Compute the operation's tool tip text: - // "operationname(param1type,param2type,...)" - // - StringBuilder sb = new StringBuilder(); - for (MBeanParameterInfo mbpi : mboi.getSignature()) { - sb.append(mbpi.getType() + ","); - } - String signature = sb.toString(); - if (signature.length() > 0) { - // Remove the trailing ',' - // - signature = signature.substring(0, signature.length() - 1); - } - String toolTipText = mboi.getName() + "(" + signature + ")"; - // Create operation node - // - DefaultMutableTreeNode operation = new DefaultMutableTreeNode(); - XNodeInfo operationUO = new XNodeInfo(Type.OPERATION, - new Object[] {mbean, mboi}, mboi.getName(), toolTipText); - operation.setUserObject(operationUO); - operations.add(operation); - } - } - // MBeanNotificationInfo node - // - if (mbean.isBroadcaster()) { - DefaultMutableTreeNode notifications = new DefaultMutableTreeNode(); - XNodeInfo notificationsUO = new XNodeInfo(Type.NOTIFICATIONS, mbean, - Resources.getText("Notifications"), null); - notifications.setUserObject(notificationsUO); - root.add(notifications); - if (ni != null && ni.length > 0) { - for (MBeanNotificationInfo mbni : ni) { - DefaultMutableTreeNode notification = - new DefaultMutableTreeNode(); - XNodeInfo notificationUO = new XNodeInfo(Type.NOTIFICATION, - mbni, mbni.getName(), null); - notification.setUserObject(notificationUO); - notifications.add(notification); - } - } - } - } } diff --git a/src/share/classes/sun/tools/jconsole/inspector/XMBeanNotifications.java b/src/share/classes/sun/tools/jconsole/inspector/XMBeanNotifications.java index c3e059a4bac6596d0a02d1d8994c733e361b1f92..20c31b001d6bb545313a70607addf641837341b3 100644 --- a/src/share/classes/sun/tools/jconsole/inspector/XMBeanNotifications.java +++ b/src/share/classes/sun/tools/jconsole/inspector/XMBeanNotifications.java @@ -29,17 +29,13 @@ import javax.swing.*; import javax.swing.event.*; import javax.swing.table.*; import javax.swing.tree.*; -import java.awt.BorderLayout; -import java.awt.GridLayout; import java.awt.Font; import java.text.SimpleDateFormat; -import java.awt.FlowLayout; import java.awt.Component; import java.awt.EventQueue; import java.awt.event.*; -import java.awt.Insets; import java.awt.Dimension; import java.util.*; import java.io.*; @@ -49,45 +45,44 @@ import javax.management.*; import javax.management.openmbean.CompositeData; import javax.management.openmbean.TabularData; +import sun.tools.jconsole.JConsole; import sun.tools.jconsole.Resources; @SuppressWarnings("serial") public class XMBeanNotifications extends JTable implements NotificationListener { - private final static String[] columnNames = { + private final static String[] columnNames = { Resources.getText("TimeStamp"), Resources.getText("Type"), Resources.getText("UserData"), Resources.getText("SeqNum"), Resources.getText("Message"), Resources.getText("Event"), - Resources.getText("Source")}; - + Resources.getText("Source") + }; private HashMap listeners = - new HashMap(); - private boolean subscribed; + new HashMap(); + private volatile boolean subscribed; private XMBeanNotificationsListener currentListener; public final static String NOTIFICATION_RECEIVED_EVENT = - "jconsole.xnotification.received"; - + "jconsole.xnotification.received"; private List notificationListenersList; - private boolean enabled; - private Font normalFont, boldFont; + private volatile boolean enabled; + private Font normalFont, boldFont; private int rowMinHeight = -1; private TableCellEditor userDataEditor = new UserDataCellEditor(); private NotifMouseListener mouseListener = new NotifMouseListener(); private SimpleDateFormat timeFormater = new SimpleDateFormat("HH:mm:ss:SSS"); - private static TableCellEditor editor = new Utils.ReadOnlyTableCellEditor(new JTextField()); public XMBeanNotifications() { - super(new TableSorter(columnNames,0)); + super(new TableSorter(columnNames, 0)); setColumnSelectionAllowed(false); setRowSelectionAllowed(false); getTableHeader().setReorderingAllowed(false); ArrayList l = - new ArrayList(1); + new ArrayList(1); notificationListenersList = Collections.synchronizedList(l); addMouseListener(mouseListener); @@ -103,20 +98,24 @@ public class XMBeanNotifications extends JTable implements NotificationListener addKeyListener(new Utils.CopyKeyAdapter()); } + // Call on EDT public void cancelCellEditing() { - TableCellEditor editor = getCellEditor(); - if (editor != null) { - editor.cancelCellEditing(); + TableCellEditor tce = getCellEditor(); + if (tce != null) { + tce.cancelCellEditing(); } } + // Call on EDT public void stopCellEditing() { - TableCellEditor editor = getCellEditor(); - if (editor != null) { - editor.stopCellEditing(); + TableCellEditor tce = getCellEditor(); + if (tce != null) { + tce.stopCellEditing(); } } + // Call on EDT + @Override public boolean isCellEditable(int row, int col) { UserDataCell cell = getUserDataCell(row, col); if (cell != null) { @@ -125,16 +124,21 @@ public class XMBeanNotifications extends JTable implements NotificationListener return true; } + // Call on EDT + @Override public void setValueAt(Object value, int row, int column) { } - public synchronized Component prepareRenderer(TableCellRenderer renderer, - int row, int column) { + // Call on EDT + @Override + public synchronized Component prepareRenderer( + TableCellRenderer renderer, int row, int column) { //In case we have a repaint thread that is in the process of //repainting an obsolete table, just ignore the call. //It can happen when MBean selection is switched at a very quick rate - if(row >= getRowCount()) + if (row >= getRowCount()) { return null; + } Component comp = super.prepareRenderer(renderer, row, column); @@ -146,9 +150,10 @@ public class XMBeanNotifications extends JTable implements NotificationListener if (column == 2 && cell != null) { comp.setFont(boldFont); int size = cell.getHeight(); - if(size > 0) { - if(getRowHeight(row) != size) + if (size > 0) { + if (getRowHeight(row) != size) { setRowHeight(row, size); + } } } else { comp.setFont(normalFont); @@ -157,34 +162,35 @@ public class XMBeanNotifications extends JTable implements NotificationListener return comp; } - public synchronized TableCellRenderer getCellRenderer(int row, - int column) { + // Call on EDT + @Override + public synchronized TableCellRenderer getCellRenderer(int row, int column) { //In case we have a repaint thread that is in the process of //repainting an obsolete table, just ignore the call. //It can happen when MBean selection is switched at a very quick rate - if(row >= getRowCount()) + if (row >= getRowCount()) { return null; + } DefaultTableCellRenderer renderer; String toolTip = null; UserDataCell cell = getUserDataCell(row, column); - if(cell != null && cell.isInited()) { + if (cell != null && cell.isInited()) { renderer = (DefaultTableCellRenderer) cell.getRenderer(); - } - else { - renderer = (DefaultTableCellRenderer) - super.getCellRenderer(row, - column); + } else { + renderer = + (DefaultTableCellRenderer) super.getCellRenderer(row, column); } - if(cell != null) - toolTip = Resources.getText("Double click to expand/collapse")+". " - + cell.toString(); - else { + if (cell != null) { + toolTip = Resources.getText("Double click to expand/collapse") + + ". " + cell.toString(); + } else { Object val = - ((DefaultTableModel) getModel()).getValueAt(row,column); - if(val != null) + ((DefaultTableModel) getModel()).getValueAt(row, column); + if (val != null) { toolTip = val.toString(); + } } renderer.setToolTipText(toolTip); @@ -192,9 +198,12 @@ public class XMBeanNotifications extends JTable implements NotificationListener return renderer; } + // Call on EDT private UserDataCell getUserDataCell(int row, int column) { - Object obj = ((DefaultTableModel) getModel()).getValueAt(row,column); - if(obj instanceof UserDataCell) return (UserDataCell) obj; + Object obj = ((DefaultTableModel) getModel()).getValueAt(row, column); + if (obj instanceof UserDataCell) { + return (UserDataCell) obj; + } return null; } @@ -204,19 +213,22 @@ public class XMBeanNotifications extends JTable implements NotificationListener public long getReceivedNotifications(XMBean mbean) { XMBeanNotificationsListener listener = - listeners.get(mbean.getObjectName()); - if(listener == null) return 0; - else + listeners.get(mbean.getObjectName()); + if (listener == null) { + return 0; + } else { return listener.getReceivedNotifications(); + } } public synchronized boolean clearCurrentNotifications() { emptyTable(); - if(currentListener != null) { + if (currentListener != null) { currentListener.clear(); return true; - } else + } else { return false; + } } public synchronized boolean unregisterListener(DefaultMutableTreeNode node) { @@ -225,29 +237,25 @@ public class XMBeanNotifications extends JTable implements NotificationListener } public synchronized void registerListener(DefaultMutableTreeNode node) - throws InstanceNotFoundException, IOException { + throws InstanceNotFoundException, IOException { XMBean mbean = (XMBean) ((XNodeInfo) node.getUserObject()).getData(); - if(!subscribed) { + if (!subscribed) { try { - mbean.getMBeanServerConnection(). - addNotificationListener(new ObjectName("JMImplementation:type=MBeanServerDelegate"), - this, - null, - null); + mbean.getMBeanServerConnection().addNotificationListener( + MBeanServerDelegate.DELEGATE_NAME, this, null, null); subscribed = true; - }catch(Exception e) { - System.out.println("Error adding listener for delegate :"+ - e.getMessage()); + } catch (Exception e) { + if (JConsole.isDebug()) { + System.err.println("Error adding listener for delegate:"); + e.printStackTrace(); + } } } - XMBeanNotificationsListener listener = - listeners.get(mbean.getObjectName()); + listeners.get(mbean.getObjectName()); if (listener == null) { - listener = new XMBeanNotificationsListener(this, - mbean, - node, - columnNames); + listener = new XMBeanNotificationsListener( + this, mbean, node, columnNames); listeners.put(mbean.getObjectName(), listener); } else { if (!listener.isRegistered()) { @@ -259,19 +267,21 @@ public class XMBeanNotifications extends JTable implements NotificationListener currentListener = listener; } - public synchronized void handleNotification(Notification notif, - Object handback) { + public synchronized void handleNotification( + Notification notif, Object handback) { try { if (notif instanceof MBeanServerNotification) { ObjectName mbean = - ((MBeanServerNotification)notif).getMBeanName(); - if (notif.getType().indexOf("JMX.mbean.unregistered")>=0){ + ((MBeanServerNotification) notif).getMBeanName(); + if (notif.getType().indexOf("JMX.mbean.unregistered") >= 0) { unregister(mbean); } } - } catch(Exception e) { - System.out.println("Error unregistering notification:"+ - e.getMessage()); + } catch (Exception e) { + if (JConsole.isDebug()) { + System.err.println("Error unregistering notification:"); + e.printStackTrace(); + } } } @@ -283,75 +293,77 @@ public class XMBeanNotifications extends JTable implements NotificationListener private synchronized boolean unregister(ObjectName mbean) { XMBeanNotificationsListener listener = listeners.get(mbean); - if(listener != null && listener.isRegistered()) { + if (listener != null && listener.isRegistered()) { listener.unregister(); return true; - } else + } else { return false; + } } public void addNotificationsListener(NotificationListener nl) { - notificationListenersList.add(nl); + notificationListenersList.add(nl); } public void removeNotificationsListener(NotificationListener nl) { notificationListenersList.remove(nl); } - void fireNotificationReceived(XMBeanNotificationsListener listener, - XMBean mbean, - DefaultMutableTreeNode node, - Object[] rowData, - long received) { - if(enabled) { + // Call on EDT + void fireNotificationReceived( + XMBeanNotificationsListener listener, XMBean mbean, + DefaultMutableTreeNode node, Object[] rowData, long received) { + if (enabled) { DefaultTableModel tableModel = (DefaultTableModel) getModel(); - if(listener == currentListener) { - - //tableModel.addRow(rowData); + if (listener == currentListener) { tableModel.insertRow(0, rowData); - - //tableModel.newDataAvailable(new TableModelEvent(tableModel)); repaint(); } } - - Notification notif = new Notification(NOTIFICATION_RECEIVED_EVENT, - this, - 0); - notif.setUserData(new Long(received)); - for(NotificationListener nl : notificationListenersList) - nl.handleNotification(notif,node); + Notification notif = + new Notification(NOTIFICATION_RECEIVED_EVENT, this, 0); + notif.setUserData(received); + for (NotificationListener nl : notificationListenersList) { + nl.handleNotification(notif, node); + } } + // Call on EDT private void updateModel(List data) { emptyTable(); DefaultTableModel tableModel = (DefaultTableModel) getModel(); - for(Object[] rowData : data) + for (Object[] rowData : data) { tableModel.addRow(rowData); + } } public synchronized boolean isListenerRegistered(XMBean mbean) { XMBeanNotificationsListener listener = - listeners.get(mbean.getObjectName()); - if(listener == null) return false; + listeners.get(mbean.getObjectName()); + if (listener == null) { + return false; + } return listener.isRegistered(); } + // Call on EDT public synchronized void loadNotifications(XMBean mbean) { XMBeanNotificationsListener listener = - listeners.get(mbean.getObjectName()); + listeners.get(mbean.getObjectName()); emptyTable(); - if(listener != null ) { + if (listener != null) { enabled = true; List data = listener.getData(); updateModel(data); currentListener = listener; validate(); repaint(); - } else + } else { enabled = false; + } } + // Call on EDT private void setColumnEditors() { TableColumnModel tcm = getColumnModel(); for (int i = 0; i < columnNames.length; i++) { @@ -364,40 +376,40 @@ public class XMBeanNotifications extends JTable implements NotificationListener } } + // Call on EDT public boolean isTableEditable() { return true; } + // Call on EDT public synchronized void emptyTable() { - DefaultTableModel model = (DefaultTableModel)getModel(); + DefaultTableModel model = (DefaultTableModel) getModel(); //invalidate(); - while (model.getRowCount()>0) + while (model.getRowCount() > 0) { model.removeRow(0); + } validate(); } - synchronized void updateUserDataCell(int row, - int col) { + // Call on EDT + synchronized void updateUserDataCell(int row, int col) { Object obj = getModel().getValueAt(row, 2); - if(obj instanceof UserDataCell) { + if (obj instanceof UserDataCell) { UserDataCell cell = (UserDataCell) obj; - if(!cell.isInited()) { - if(rowMinHeight == -1) + if (!cell.isInited()) { + if (rowMinHeight == -1) { rowMinHeight = getRowHeight(row); - - cell.init(super.getCellRenderer(row, col), - rowMinHeight); + } + cell.init(super.getCellRenderer(row, col), rowMinHeight); } cell.switchState(); - setRowHeight(row, - cell.getHeight()); + setRowHeight(row, cell.getHeight()); - if(!cell.isMaximized()) { + if (!cell.isMaximized()) { cancelCellEditing(); //Back to simple editor. - editCellAt(row, - 2); + editCellAt(row, 2); } invalidate(); @@ -406,7 +418,9 @@ public class XMBeanNotifications extends JTable implements NotificationListener } class UserDataCellRenderer extends DefaultTableCellRenderer { + Component comp; + UserDataCellRenderer(Component comp) { this.comp = comp; Dimension d = comp.getPreferredSize(); @@ -415,56 +429,62 @@ public class XMBeanNotifications extends JTable implements NotificationListener } } - public Component getTableCellRendererComponent(JTable table, - Object value, - boolean isSelected, - boolean hasFocus, - int row, - int column) { + @Override + public Component getTableCellRendererComponent( + JTable table, + Object value, + boolean isSelected, + boolean hasFocus, + int row, + int column) { return comp; } public Component getComponent() { return comp; } - } class UserDataCell { + TableCellRenderer minRenderer; UserDataCellRenderer maxRenderer; int minHeight; boolean minimized = true; boolean init = false; Object userData; - UserDataCell(Object userData, Component max) { - this.userData = userData; - this.maxRenderer = new UserDataCellRenderer(max); - - } - - public String toString() { - if(userData == null) return null; - if(userData.getClass().isArray()) { - String name = - Utils.getArrayClassName(userData.getClass().getName()); - int length = Array.getLength(userData); - return name + "[" + length +"]"; - } - - if(userData instanceof CompositeData || - userData instanceof TabularData) + + UserDataCell(Object userData, Component max) { + this.userData = userData; + this.maxRenderer = new UserDataCellRenderer(max); + + } + + @Override + public String toString() { + if (userData == null) { + return null; + } + if (userData.getClass().isArray()) { + String name = + Utils.getArrayClassName(userData.getClass().getName()); + int length = Array.getLength(userData); + return name + "[" + length + "]"; + } + + if (userData instanceof CompositeData || + userData instanceof TabularData) { return userData.getClass().getName(); + } return userData.toString(); - } + } boolean isInited() { return init; } - void init(TableCellRenderer minRenderer, - int minHeight) { + void init(TableCellRenderer minRenderer, int minHeight) { this.minRenderer = minRenderer; this.minHeight = minHeight; init = true; @@ -473,9 +493,11 @@ public class XMBeanNotifications extends JTable implements NotificationListener void switchState() { minimized = !minimized; } + boolean isMaximized() { return !minimized; } + void minimize() { minimized = true; } @@ -485,30 +507,39 @@ public class XMBeanNotifications extends JTable implements NotificationListener } int getHeight() { - if(minimized) return minHeight; - else + if (minimized) { + return minHeight; + } else { return (int) maxRenderer.getComponent(). - getPreferredSize().getHeight() ; + getPreferredSize().getHeight(); + } } TableCellRenderer getRenderer() { - if(minimized) return minRenderer; - else return maxRenderer; + if (minimized) { + return minRenderer; + } else { + return maxRenderer; + } } } class NotifMouseListener extends MouseAdapter { + @Override public void mousePressed(MouseEvent e) { - if(e.getButton() == MouseEvent.BUTTON1) { - if(e.getClickCount() >= 2) { + if (e.getButton() == MouseEvent.BUTTON1) { + if (e.getClickCount() >= 2) { int row = XMBeanNotifications.this.getSelectedRow(); int col = XMBeanNotifications.this.getSelectedColumn(); - if(col != 2) return; - if(col == -1 || row == -1) return; + if (col != 2) { + return; + } + if (col == -1 || row == -1) { + return; + } - XMBeanNotifications.this.updateUserDataCell(row, - col); + XMBeanNotifications.this.updateUserDataCell(row, col); } } } @@ -516,20 +547,21 @@ public class XMBeanNotifications extends JTable implements NotificationListener class UserDataCellEditor extends XTextFieldEditor { // implements javax.swing.table.TableCellEditor - public Component getTableCellEditorComponent(JTable table, - Object value, - boolean isSelected, - int row, - int column) { + @Override + public Component getTableCellEditorComponent( + JTable table, + Object value, + boolean isSelected, + int row, + int column) { Object val = value; - if(column == 2) { - Object obj = getModel().getValueAt(row, - column); - if(obj instanceof UserDataCell) { + if (column == 2) { + Object obj = getModel().getValueAt(row, column); + if (obj instanceof UserDataCell) { UserDataCell cell = (UserDataCell) obj; - if(cell.getRenderer() instanceof UserDataCellRenderer) { + if (cell.getRenderer() instanceof UserDataCellRenderer) { UserDataCellRenderer zr = - (UserDataCellRenderer) cell.getRenderer(); + (UserDataCellRenderer) cell.getRenderer(); return zr.getComponent(); } } else { @@ -539,12 +571,14 @@ public class XMBeanNotifications extends JTable implements NotificationListener return comp; } } - return super.getTableCellEditorComponent(table, - val, - isSelected, - row, - column); + return super.getTableCellEditorComponent( + table, + val, + isSelected, + row, + column); } + @Override public boolean stopCellEditing() { int editingRow = getEditingRow(); @@ -554,7 +588,7 @@ public class XMBeanNotifications extends JTable implements NotificationListener if (obj instanceof UserDataCell) { UserDataCell cell = (UserDataCell) obj; if (cell.isMaximized()) { - this.cancelCellEditing(); + cancelCellEditing(); return true; } } @@ -564,17 +598,20 @@ public class XMBeanNotifications extends JTable implements NotificationListener } class XMBeanNotificationsListener implements NotificationListener { + private String[] columnNames; private XMBean xmbean; private DefaultMutableTreeNode node; - private long received; + private volatile long received; private XMBeanNotifications notifications; - private boolean unregistered; + private volatile boolean unregistered; private ArrayList data = new ArrayList(); - public XMBeanNotificationsListener(XMBeanNotifications notifications, - XMBean xmbean, - DefaultMutableTreeNode node, - String[] columnNames) { + + public XMBeanNotificationsListener( + XMBeanNotifications notifications, + XMBean xmbean, + DefaultMutableTreeNode node, + String[] columnNames) { this.notifications = notifications; this.xmbean = xmbean; this.node = node; @@ -591,22 +628,24 @@ public class XMBeanNotifications extends JTable implements NotificationListener received = 0; } - public boolean isRegistered() { + public synchronized boolean isRegistered() { return !unregistered; } public synchronized void unregister() { try { - xmbean.getMBeanServerConnection(). - removeNotificationListener(xmbean.getObjectName(),this,null,null); - }catch(Exception e) { - System.out.println("Error removing listener :"+ - e.getMessage()); + xmbean.getMBeanServerConnection().removeNotificationListener( + xmbean.getObjectName(), this, null, null); + } catch (Exception e) { + if (JConsole.isDebug()) { + System.err.println("Error removing listener:"); + e.printStackTrace(); + } } unregistered = true; } - public long getReceivedNotifications() { + public synchronized long getReceivedNotifications() { return received; } @@ -614,52 +653,62 @@ public class XMBeanNotifications extends JTable implements NotificationListener clear(); this.node = node; try { - xmbean.getMBeanServerConnection(). - addNotificationListener(xmbean.getObjectName(),this,null,null); + xmbean.getMBeanServerConnection().addNotificationListener( + xmbean.getObjectName(), this, null, null); unregistered = false; - }catch(Exception e) { - System.out.println("Error adding listener :"+ - e.getMessage()); + } catch (Exception e) { + if (JConsole.isDebug()) { + System.err.println("Error adding listener:"); + e.printStackTrace(); + } } } - public synchronized void handleNotification(Notification e, - Object handback) { - try { - if(unregistered) return; - Date receivedDate = new Date(e.getTimeStamp()); - String time = timeFormater.format(receivedDate); - - Object userData = e.getUserData(); - Component comp = null; - UserDataCell cell = null; - if((comp = XDataViewer.createNotificationViewer(userData)) - != null) { - XDataViewer.registerForMouseEvent(comp, mouseListener); - cell = new UserDataCell(userData, comp); + public synchronized void handleNotification( + final Notification n, Object hb) { + EventQueue.invokeLater(new Runnable() { + + public void run() { + synchronized (XMBeanNotificationsListener.this) { + try { + if (unregistered) { + return; + } + Date receivedDate = new Date(n.getTimeStamp()); + String time = timeFormater.format(receivedDate); + + Object userData = n.getUserData(); + Component comp = null; + UserDataCell cell = null; + if ((comp = XDataViewer.createNotificationViewer(userData)) != null) { + XDataViewer.registerForMouseEvent(comp, mouseListener); + cell = new UserDataCell(userData, comp); + } + + Object[] rowData = { + time, + n.getType(), + (cell == null ? userData : cell), + n.getSequenceNumber(), + n.getMessage(), + n, + n.getSource() + }; + received++; + data.add(0, rowData); + + notifications.fireNotificationReceived( + XMBeanNotificationsListener.this, + xmbean, node, rowData, received); + } catch (Exception e) { + if (JConsole.isDebug()) { + System.err.println("Error handling notification:"); + e.printStackTrace(); + } + } + } } - - Object[] rowData = {time, - e.getType(), - (cell == null ? userData : cell), - new Long(e.getSequenceNumber()), - e.getMessage(), - e, - e.getSource()}; - received++; - data.add(0, rowData); - - notifications.fireNotificationReceived(this, - xmbean, - node, - rowData, - received); - } - catch (Exception ex) { - ex.printStackTrace(); - System.out.println("Error when handling notification :"+ - ex.toString()); - } + }); } } } diff --git a/src/share/classes/sun/tools/jconsole/inspector/XMBeanOperations.java b/src/share/classes/sun/tools/jconsole/inspector/XMBeanOperations.java index c5325e14344276b02eedaaaf3ad004187b1d99c0..81f295f3215f87feb2a9a6eb1ae61ba319824d54 100644 --- a/src/share/classes/sun/tools/jconsole/inspector/XMBeanOperations.java +++ b/src/share/classes/sun/tools/jconsole/inspector/XMBeanOperations.java @@ -22,6 +22,7 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ + package sun.tools.jconsole.inspector; import javax.management.*; diff --git a/src/share/classes/sun/tools/jconsole/inspector/XObject.java b/src/share/classes/sun/tools/jconsole/inspector/XObject.java index 280607b74d2f2af471828b1c92aa6c199e9f726d..f5aa3132ca2f8ab7ab62ce7101e989cdab50de36 100644 --- a/src/share/classes/sun/tools/jconsole/inspector/XObject.java +++ b/src/share/classes/sun/tools/jconsole/inspector/XObject.java @@ -22,6 +22,7 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ + package sun.tools.jconsole.inspector; // java import diff --git a/src/share/classes/sun/tools/jconsole/inspector/XOperations.java b/src/share/classes/sun/tools/jconsole/inspector/XOperations.java index c74bb948b1b58d0d5e42c40e9f1a43e6347b0d8a..14b9a676f0032f5e8bd1e2421c5129c78d333d52 100644 --- a/src/share/classes/sun/tools/jconsole/inspector/XOperations.java +++ b/src/share/classes/sun/tools/jconsole/inspector/XOperations.java @@ -33,10 +33,7 @@ import java.awt.BorderLayout; import java.awt.GridLayout; import java.awt.FlowLayout; import java.awt.Component; -import java.awt.EventQueue; import java.awt.event.*; -import java.awt.Insets; -import java.awt.Dimension; import java.util.*; import java.io.*; @@ -49,29 +46,30 @@ import sun.tools.jconsole.JConsole; public abstract class XOperations extends JPanel implements ActionListener { public final static String OPERATION_INVOCATION_EVENT = - "jam.xoperations.invoke.result"; + "jam.xoperations.invoke.result"; private java.util.List notificationListenersList; - private Hashtable operationEntryTable; - private XMBean mbean; private MBeanInfo mbeanInfo; private MBeansTab mbeansTab; + public XOperations(MBeansTab mbeansTab) { - super(new GridLayout(1,1)); + super(new GridLayout(1, 1)); this.mbeansTab = mbeansTab; operationEntryTable = new Hashtable(); ArrayList l = - new ArrayList(1); + new ArrayList(1); notificationListenersList = - Collections.synchronizedList(l); + Collections.synchronizedList(l); } + // Call on EDT public void removeOperations() { removeAll(); } - public void loadOperations(XMBean mbean,MBeanInfo mbeanInfo) { + // Call on EDT + public void loadOperations(XMBean mbean, MBeanInfo mbeanInfo) { this.mbean = mbean; this.mbeanInfo = mbeanInfo; // add operations information @@ -80,131 +78,149 @@ public abstract class XOperations extends JPanel implements ActionListener { // remove listeners, if any Component listeners[] = getComponents(); - for (int i = 0; i < listeners.length; i++) - if (listeners[i] instanceof JButton) - ((JButton)listeners[i]).removeActionListener(this); + for (int i = 0; i < listeners.length; i++) { + if (listeners[i] instanceof JButton) { + ((JButton) listeners[i]).removeActionListener(this); + } + } removeAll(); setLayout(new BorderLayout()); JButton methodButton; JLabel methodLabel; - JPanel innerPanelLeft,innerPanelRight; - JPanel outerPanelLeft,outerPanelRight; - outerPanelLeft = new JPanel(new GridLayout(operations.length,1)); - outerPanelRight = new JPanel(new GridLayout(operations.length,1)); + JPanel innerPanelLeft, innerPanelRight; + JPanel outerPanelLeft, outerPanelRight; + outerPanelLeft = new JPanel(new GridLayout(operations.length, 1)); + outerPanelRight = new JPanel(new GridLayout(operations.length, 1)); - for (int i=0;i20) { + String returnType = operations[i].getReturnType(); + if (returnType == null) { + methodLabel = new JLabel("null", JLabel.RIGHT); + if (JConsole.isDebug()) { + System.err.println( + "WARNING: The operation's return type " + + "shouldn't be \"null\". Check how the " + + "MBeanOperationInfo for the \"" + + operations[i].getName() + "\" operation has " + + "been defined in the MBean's implementation code."); + } + } else { + methodLabel = new JLabel( + Utils.getReadableClassName(returnType), JLabel.RIGHT); + } + innerPanelLeft.add(methodLabel); + if (methodLabel.getText().length() > 20) { methodLabel.setText(methodLabel.getText(). - substring(methodLabel.getText(). - lastIndexOf(".")+1, - methodLabel.getText().length())); + substring(methodLabel.getText(). + lastIndexOf(".") + 1, + methodLabel.getText().length())); } methodButton = new JButton(operations[i].getName()); methodButton.setToolTipText(operations[i].getDescription()); boolean callable = isCallable(operations[i].getSignature()); - if(callable) + if (callable) { methodButton.addActionListener(this); - else + } else { methodButton.setEnabled(false); + } MBeanParameterInfo[] signature = operations[i].getSignature(); OperationEntry paramEntry = new OperationEntry(operations[i], - callable, - methodButton, - this); + callable, + methodButton, + this); operationEntryTable.put(methodButton, paramEntry); innerPanelRight.add(methodButton); - if(signature.length==0) - innerPanelRight.add(new JLabel("( )",JLabel.CENTER)); - else - innerPanelRight.add(paramEntry); + if (signature.length == 0) { + innerPanelRight.add(new JLabel("( )", JLabel.CENTER)); + } else { + innerPanelRight.add(paramEntry); + } - outerPanelLeft.add(innerPanelLeft,BorderLayout.WEST); - outerPanelRight.add(innerPanelRight,BorderLayout.CENTER); + outerPanelLeft.add(innerPanelLeft, BorderLayout.WEST); + outerPanelRight.add(innerPanelRight, BorderLayout.CENTER); } - add(outerPanelLeft,BorderLayout.WEST); - add(outerPanelRight,BorderLayout.CENTER); + add(outerPanelLeft, BorderLayout.WEST); + add(outerPanelRight, BorderLayout.CENTER); validate(); } private boolean isCallable(MBeanParameterInfo[] signature) { - for(int i = 0; i < signature.length; i++) { - if(!Utils.isEditableType(signature[i].getType())) + for (int i = 0; i < signature.length; i++) { + if (!Utils.isEditableType(signature[i].getType())) { return false; + } } return true; } + // Call on EDT public void actionPerformed(final ActionEvent e) { - performInvokeRequest((JButton)e.getSource()); + performInvokeRequest((JButton) e.getSource()); } void performInvokeRequest(final JButton button) { - mbeansTab.workerAdd(new Runnable() { - public void run() { + final OperationEntry entryIf = operationEntryTable.get(button); + new SwingWorker() { + @Override + public Object doInBackground() throws Exception { + return mbean.invoke(button.getText(), + entryIf.getParameters(), entryIf.getSignature()); + } + @Override + protected void done() { try { - OperationEntry entryIf = operationEntryTable.get(button); - Object result = null; - result = mbean.invoke(button.getText(), - entryIf.getParameters(), - entryIf.getSignature()); + Object result = get(); // sends result notification to upper level if // there is a return value if (entryIf.getReturnType() != null && - !entryIf.getReturnType().equals(Void.TYPE.getName()) && - !entryIf.getReturnType().equals(Void.class.getName())) - fireChangedNotification(OPERATION_INVOCATION_EVENT, - button, - result); - else - EventQueue.invokeLater(new ThreadDialog( - button, - Resources.getText("Method successfully invoked"), - Resources.getText("Info"), - JOptionPane.INFORMATION_MESSAGE)); - } catch (Throwable ex) { + !entryIf.getReturnType().equals(Void.TYPE.getName()) && + !entryIf.getReturnType().equals(Void.class.getName())) { + fireChangedNotification(OPERATION_INVOCATION_EVENT, button, result); + } else { + new ThreadDialog( + button, + Resources.getText("Method successfully invoked"), + Resources.getText("Info"), + JOptionPane.INFORMATION_MESSAGE).run(); + } + } catch (Throwable t) { + t = Utils.getActualException(t); if (JConsole.isDebug()) { - ex.printStackTrace(); + t.printStackTrace(); } - ex = Utils.getActualException(ex); - String message = ex.toString(); - EventQueue.invokeLater(new ThreadDialog( - button, - Resources.getText("Problem invoking") + " " + - button.getText() + " : " + message, - Resources.getText("Error"), - JOptionPane.ERROR_MESSAGE)); + new ThreadDialog( + button, + Resources.getText("Problem invoking") + " " + + button.getText() + " : " + t.toString(), + Resources.getText("Error"), + JOptionPane.ERROR_MESSAGE).run(); } } - }); + }.execute(); } public void addOperationsListener(NotificationListener nl) { - notificationListenersList.add(nl); - } + notificationListenersList.add(nl); + } public void removeOperationsListener(NotificationListener nl) { notificationListenersList.remove(nl); } - private void fireChangedNotification(String type, - Object source, - Object handback) { - Notification e = new Notification(type,source,0); - for(NotificationListener nl : notificationListenersList) - nl.handleNotification(e,handback); + // Call on EDT + private void fireChangedNotification( + String type, Object source, Object handback) { + Notification n = new Notification(type, source, 0); + for (NotificationListener nl : notificationListenersList) { + nl.handleNotification(n, handback); + } } - protected abstract MBeanOperationInfo[] - updateOperations(MBeanOperationInfo[] operations); + protected abstract MBeanOperationInfo[] updateOperations(MBeanOperationInfo[] operations); } diff --git a/src/share/classes/sun/tools/jconsole/inspector/XPlotter.java b/src/share/classes/sun/tools/jconsole/inspector/XPlotter.java index 292dc78adf6ef7109aa053adfab6397f1ac07e6a..9135b7a540205c0b825cf54cd05e1e0a6840ea4e 100644 --- a/src/share/classes/sun/tools/jconsole/inspector/XPlotter.java +++ b/src/share/classes/sun/tools/jconsole/inspector/XPlotter.java @@ -22,7 +22,9 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ + package sun.tools.jconsole.inspector; + import sun.tools.jconsole.Plotter; import javax.swing.JTable; import java.awt.Graphics; diff --git a/src/share/classes/sun/tools/jconsole/inspector/XPlottingViewer.java b/src/share/classes/sun/tools/jconsole/inspector/XPlottingViewer.java index 017a4a7df93d3e4c88d54bddc6ca656bf91cb629..5bcf72dd719585efcb36a0dc09fe272669819712 100644 --- a/src/share/classes/sun/tools/jconsole/inspector/XPlottingViewer.java +++ b/src/share/classes/sun/tools/jconsole/inspector/XPlottingViewer.java @@ -22,6 +22,7 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ + package sun.tools.jconsole.inspector; import java.awt.*; diff --git a/src/share/classes/sun/tools/jconsole/inspector/XSheet.java b/src/share/classes/sun/tools/jconsole/inspector/XSheet.java index 6360a082ae4030ef68508a3028337e15e8fd4560..11fce7f45bf04ac6ca2167608b42dc2069a79ac1 100644 --- a/src/share/classes/sun/tools/jconsole/inspector/XSheet.java +++ b/src/share/classes/sun/tools/jconsole/inspector/XSheet.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2007 Sun Microsystems, Inc. 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 @@ -28,7 +28,6 @@ package sun.tools.jconsole.inspector; import java.awt.*; import java.awt.event.*; import java.io.*; -import java.util.Enumeration; import javax.management.*; import javax.swing.*; import javax.swing.border.*; @@ -45,31 +44,22 @@ public class XSheet extends JPanel private JPanel mainPanel; private JPanel southPanel; - // Node being currently displayed - private DefaultMutableTreeNode node; - + private volatile DefaultMutableTreeNode currentNode; // MBean being currently displayed - private XMBean mbean; - + private volatile XMBean mbean; // XMBeanAttributes container private XMBeanAttributes mbeanAttributes; - // XMBeanOperations container private XMBeanOperations mbeanOperations; - // XMBeanNotifications container private XMBeanNotifications mbeanNotifications; - // XMBeanInfo container private XMBeanInfo mbeanInfo; - // Refresh JButton (mbean attributes case) private JButton refreshButton; - // Subscribe/Unsubscribe/Clear JButton (mbean notifications case) - private JButton clearButton, subscribeButton, unsubscribeButton; - + private JButton clearButton, subscribeButton, unsubscribeButton; // Reference to MBeans tab private MBeansTab mbeansTab; @@ -86,6 +76,7 @@ public class XSheet extends JPanel private void setupScreen() { setLayout(new BorderLayout()); + setBorder(BorderFactory.createLineBorder(Color.GRAY)); // add main panel to XSheet mainPanel = new JPanel(); mainPanel.setLayout(new BorderLayout()); @@ -129,17 +120,32 @@ public class XSheet extends JPanel mbeanInfo = new XMBeanInfo(); } + private boolean isSelectedNode(DefaultMutableTreeNode n, DefaultMutableTreeNode cn) { + return (cn == n); + } + + // Call on EDT + private void showErrorDialog(Object message, String title) { + new ThreadDialog(this, message, title, JOptionPane.ERROR_MESSAGE).run(); + } + public boolean isMBeanNode(DefaultMutableTreeNode node) { - XNodeInfo uo = (XNodeInfo) node.getUserObject(); - return uo.getType().equals(Type.MBEAN); + Object userObject = node.getUserObject(); + if (userObject instanceof XNodeInfo) { + XNodeInfo uo = (XNodeInfo) userObject; + return uo.getType().equals(Type.MBEAN); + } + return false; } - public void displayNode(DefaultMutableTreeNode node) { + // Call on EDT + public synchronized void displayNode(DefaultMutableTreeNode node) { clear(); + displayEmptyNode(); if (node == null) { - displayEmptyNode(); return; } + currentNode = node; Object userObject = node.getUserObject(); if (userObject instanceof XNodeInfo) { XNodeInfo uo = (XNodeInfo) userObject; @@ -173,27 +179,28 @@ public class XSheet extends JPanel } } + // Call on EDT private void displayMBeanNode(final DefaultMutableTreeNode node) { final XNodeInfo uo = (XNodeInfo) node.getUserObject(); if (!uo.getType().equals(Type.MBEAN)) { return; } - mbeansTab.workerAdd(new Runnable() { - public void run() { + mbean = (XMBean) uo.getData(); + SwingWorker sw = new SwingWorker() { + @Override + public MBeanInfo doInBackground() throws InstanceNotFoundException, + IntrospectionException, ReflectionException, IOException { + return mbean.getMBeanInfo(); + } + @Override + protected void done() { try { - XSheet.this.node = node; - XSheet.this.mbean = (XMBean) uo.getData(); - mbeanInfo.addMBeanInfo(mbean, mbean.getMBeanInfo()); - } catch (Throwable ex) { - EventQueue.invokeLater(new ThreadDialog( - XSheet.this, - ex.getMessage(), - Resources.getText("Problem displaying MBean"), - JOptionPane.ERROR_MESSAGE)); - return; - } - EventQueue.invokeLater(new Runnable() { - public void run() { + MBeanInfo mbi = get(); + if (mbi != null) { + if (!isSelectedNode(node, currentNode)) { + return; + } + mbeanInfo.addMBeanInfo(mbean, mbi); invalidate(); mainPanel.removeAll(); mainPanel.add(mbeanInfo, BorderLayout.CENTER); @@ -202,9 +209,19 @@ public class XSheet extends JPanel validate(); repaint(); } - }); + } catch (Exception e) { + Throwable t = Utils.getActualException(e); + if (JConsole.isDebug()) { + System.err.println("Couldn't get MBeanInfo for MBean [" + + mbean.getObjectName() + "]"); + t.printStackTrace(); + } + showErrorDialog(t.toString(), + Resources.getText("Problem displaying MBean")); + } } - }); + }; + sw.execute(); } // Call on EDT @@ -213,90 +230,90 @@ public class XSheet extends JPanel final XMBeanInfo mbi = mbeanInfo; switch (uo.getType()) { case ATTRIBUTE: - mbeansTab.workerAdd(new Runnable() { - public void run() { - Object attrData = uo.getData(); - XSheet.this.mbean = (XMBean) ((Object[]) attrData)[0]; - final MBeanAttributeInfo mbai = - (MBeanAttributeInfo) ((Object[]) attrData)[1]; - final XMBeanAttributes mba = mbeanAttributes; - try { - mba.loadAttributes(mbean, new MBeanInfo( - null, null, new MBeanAttributeInfo[] {mbai}, - null, null, null)); - } catch (Exception e) { - EventQueue.invokeLater(new ThreadDialog( - XSheet.this, - e.getMessage(), - Resources.getText("Problem displaying MBean"), - JOptionPane.ERROR_MESSAGE)); - return; - } - EventQueue.invokeLater(new Runnable() { - public void run() { - invalidate(); - mainPanel.removeAll(); - JPanel attributePanel = - new JPanel(new BorderLayout()); - JPanel attributeBorderPanel = - new JPanel(new BorderLayout()); - attributeBorderPanel.setBorder( - BorderFactory.createTitledBorder( - Resources.getText("Attribute value"))); - JPanel attributeValuePanel = - new JPanel(new BorderLayout()); - attributeValuePanel.setBorder( - LineBorder.createGrayLineBorder()); - attributeValuePanel.add(mba.getTableHeader(), - BorderLayout.PAGE_START); - attributeValuePanel.add(mba, - BorderLayout.CENTER); - attributeBorderPanel.add(attributeValuePanel, - BorderLayout.CENTER); - JPanel refreshButtonPanel = new JPanel(); - refreshButtonPanel.add(refreshButton); - attributeBorderPanel.add(refreshButtonPanel, - BorderLayout.SOUTH); - refreshButton.setEnabled(true); - attributePanel.add(attributeBorderPanel, - BorderLayout.NORTH); - mbi.addMBeanAttributeInfo(mbai); - attributePanel.add(mbi, BorderLayout.CENTER); - mainPanel.add(attributePanel, - BorderLayout.CENTER); - southPanel.setVisible(false); - southPanel.removeAll(); - validate(); - repaint(); + SwingWorker sw = + new SwingWorker() { + @Override + public MBeanAttributeInfo doInBackground() { + Object attrData = uo.getData(); + mbean = (XMBean) ((Object[]) attrData)[0]; + MBeanAttributeInfo mbai = + (MBeanAttributeInfo) ((Object[]) attrData)[1]; + mbeanAttributes.loadAttributes(mbean, new MBeanInfo( + null, null, new MBeanAttributeInfo[]{mbai}, + null, null, null)); + return mbai; } - }); - } - }); + @Override + protected void done() { + try { + MBeanAttributeInfo mbai = get(); + if (!isSelectedNode(node, currentNode)) { + return; + } + invalidate(); + mainPanel.removeAll(); + JPanel attributePanel = + new JPanel(new BorderLayout()); + JPanel attributeBorderPanel = + new JPanel(new BorderLayout()); + attributeBorderPanel.setBorder( + BorderFactory.createTitledBorder( + Resources.getText("Attribute value"))); + JPanel attributeValuePanel = + new JPanel(new BorderLayout()); + attributeValuePanel.setBorder( + LineBorder.createGrayLineBorder()); + attributeValuePanel.add(mbeanAttributes.getTableHeader(), + BorderLayout.PAGE_START); + attributeValuePanel.add(mbeanAttributes, + BorderLayout.CENTER); + attributeBorderPanel.add(attributeValuePanel, + BorderLayout.CENTER); + JPanel refreshButtonPanel = new JPanel(); + refreshButtonPanel.add(refreshButton); + attributeBorderPanel.add(refreshButtonPanel, + BorderLayout.SOUTH); + refreshButton.setEnabled(true); + attributePanel.add(attributeBorderPanel, + BorderLayout.NORTH); + mbi.addMBeanAttributeInfo(mbai); + attributePanel.add(mbi, BorderLayout.CENTER); + mainPanel.add(attributePanel, + BorderLayout.CENTER); + southPanel.setVisible(false); + southPanel.removeAll(); + validate(); + repaint(); + } catch (Exception e) { + Throwable t = Utils.getActualException(e); + if (JConsole.isDebug()) { + System.err.println("Problem displaying MBean " + + "attribute for MBean [" + + mbean.getObjectName() + "]"); + t.printStackTrace(); + } + showErrorDialog(t.toString(), + Resources.getText("Problem displaying MBean")); + } + } + }; + sw.execute(); break; case OPERATION: Object operData = uo.getData(); - XSheet.this.mbean = (XMBean) ((Object[]) operData)[0]; + mbean = (XMBean) ((Object[]) operData)[0]; MBeanOperationInfo mboi = (MBeanOperationInfo) ((Object[]) operData)[1]; - XMBeanOperations mbo = mbeanOperations; - try { - mbo.loadOperations(mbean, new MBeanInfo(null, null, null, - null, new MBeanOperationInfo[] {mboi}, null)); - } catch (Exception e) { - EventQueue.invokeLater(new ThreadDialog( - XSheet.this, - e.getMessage(), - Resources.getText("Problem displaying MBean"), - JOptionPane.ERROR_MESSAGE)); - return; - } + mbeanOperations.loadOperations(mbean, + new MBeanInfo(null, null, null, null, + new MBeanOperationInfo[]{mboi}, null)); invalidate(); mainPanel.removeAll(); JPanel operationPanel = new JPanel(new BorderLayout()); JPanel operationBorderPanel = new JPanel(new BorderLayout()); operationBorderPanel.setBorder(BorderFactory.createTitledBorder( Resources.getText("Operation invocation"))); - operationBorderPanel.add(new JScrollPane(mbo)); + operationBorderPanel.add(new JScrollPane(mbeanOperations)); operationPanel.add(operationBorderPanel, BorderLayout.NORTH); mbi.addMBeanOperationInfo(mboi); operationPanel.add(mbi, BorderLayout.CENTER); @@ -320,134 +337,134 @@ public class XSheet extends JPanel } } + // Call on EDT private void displayMBeanAttributesNode(final DefaultMutableTreeNode node) { final XNodeInfo uo = (XNodeInfo) node.getUserObject(); if (!uo.getType().equals(Type.ATTRIBUTES)) { return; } - final XMBeanAttributes mba = mbeanAttributes; - mbeansTab.workerAdd(new Runnable() { - public void run() { + mbean = (XMBean) uo.getData(); + SwingWorker sw = new SwingWorker() { + @Override + public Void doInBackground() throws InstanceNotFoundException, + IntrospectionException, ReflectionException, IOException { + mbeanAttributes.loadAttributes(mbean, mbean.getMBeanInfo()); + return null; + } + @Override + protected void done() { try { - XSheet.this.node = node; - XSheet.this.mbean = (XMBean) uo.getData(); - mba.loadAttributes(mbean, mbean.getMBeanInfo()); - } catch (Throwable ex) { - EventQueue.invokeLater(new ThreadDialog( - XSheet.this, - ex.getMessage(), - Resources.getText("Problem displaying MBean"), - JOptionPane.ERROR_MESSAGE)); - return; - } - EventQueue.invokeLater(new Runnable() { - public void run() { - invalidate(); - mainPanel.removeAll(); - JPanel borderPanel = new JPanel(new BorderLayout()); - borderPanel.setBorder(BorderFactory.createTitledBorder( - Resources.getText("Attribute values"))); - borderPanel.add(new JScrollPane(mba)); - mainPanel.add(borderPanel, BorderLayout.CENTER); - // add the refresh button to the south panel - southPanel.removeAll(); - southPanel.add(refreshButton, BorderLayout.SOUTH); - southPanel.setVisible(true); - refreshButton.setEnabled(true); - validate(); - repaint(); + get(); + if (!isSelectedNode(node, currentNode)) { + return; } - }); + invalidate(); + mainPanel.removeAll(); + JPanel borderPanel = new JPanel(new BorderLayout()); + borderPanel.setBorder(BorderFactory.createTitledBorder( + Resources.getText("Attribute values"))); + borderPanel.add(new JScrollPane(mbeanAttributes)); + mainPanel.add(borderPanel, BorderLayout.CENTER); + // add the refresh button to the south panel + southPanel.removeAll(); + southPanel.add(refreshButton, BorderLayout.SOUTH); + southPanel.setVisible(true); + refreshButton.setEnabled(true); + validate(); + repaint(); + } catch (Exception e) { + Throwable t = Utils.getActualException(e); + if (JConsole.isDebug()) { + System.err.println("Problem displaying MBean " + + "attributes for MBean [" + + mbean.getObjectName() + "]"); + t.printStackTrace(); + } + showErrorDialog(t.toString(), + Resources.getText("Problem displaying MBean")); + } } - }); + }; + sw.execute(); } + // Call on EDT private void displayMBeanOperationsNode(final DefaultMutableTreeNode node) { final XNodeInfo uo = (XNodeInfo) node.getUserObject(); if (!uo.getType().equals(Type.OPERATIONS)) { return; } - final XMBeanOperations mbo = mbeanOperations; - mbeansTab.workerAdd(new Runnable() { - public void run() { + mbean = (XMBean) uo.getData(); + SwingWorker sw = new SwingWorker() { + @Override + public MBeanInfo doInBackground() throws InstanceNotFoundException, + IntrospectionException, ReflectionException, IOException { + return mbean.getMBeanInfo(); + } + @Override + protected void done() { try { - XSheet.this.node = node; - XSheet.this.mbean = (XMBean) uo.getData(); - mbo.loadOperations(mbean, mbean.getMBeanInfo()); - } catch (Throwable ex) { - EventQueue.invokeLater(new ThreadDialog( - XSheet.this, - ex.getMessage(), - Resources.getText("Problem displaying MBean"), - JOptionPane.ERROR_MESSAGE)); - return; - } - EventQueue.invokeLater(new Runnable() { - public void run() { + MBeanInfo mbi = get(); + if (mbi != null) { + if (!isSelectedNode(node, currentNode)) { + return; + } + mbeanOperations.loadOperations(mbean, mbi); invalidate(); mainPanel.removeAll(); JPanel borderPanel = new JPanel(new BorderLayout()); borderPanel.setBorder(BorderFactory.createTitledBorder( Resources.getText("Operation invocation"))); - borderPanel.add(new JScrollPane(mbo)); + borderPanel.add(new JScrollPane(mbeanOperations)); mainPanel.add(borderPanel, BorderLayout.CENTER); southPanel.setVisible(false); southPanel.removeAll(); validate(); repaint(); } - }); + } catch (Exception e) { + Throwable t = Utils.getActualException(e); + if (JConsole.isDebug()) { + System.err.println("Problem displaying MBean " + + "operations for MBean [" + + mbean.getObjectName() + "]"); + t.printStackTrace(); + } + showErrorDialog(t.toString(), + Resources.getText("Problem displaying MBean")); + } } - }); + }; + sw.execute(); } - private void displayMBeanNotificationsNode( - final DefaultMutableTreeNode node) { + // Call on EDT + private void displayMBeanNotificationsNode(DefaultMutableTreeNode node) { final XNodeInfo uo = (XNodeInfo) node.getUserObject(); if (!uo.getType().equals(Type.NOTIFICATIONS)) { return; } - final XMBeanNotifications mbn = mbeanNotifications; - mbeansTab.workerAdd(new Runnable() { - public void run() { - try { - XSheet.this.node = node; - XSheet.this.mbean = (XMBean) uo.getData(); - mbn.loadNotifications(mbean); - updateNotifications(); - } catch (Throwable ex) { - EventQueue.invokeLater(new ThreadDialog( - XSheet.this, - ex.getMessage(), - Resources.getText("Problem displaying MBean"), - JOptionPane.ERROR_MESSAGE)); - return; - } - EventQueue.invokeLater(new Runnable() { - public void run() { - invalidate(); - mainPanel.removeAll(); - JPanel borderPanel = new JPanel(new BorderLayout()); - borderPanel.setBorder(BorderFactory.createTitledBorder( - Resources.getText("Notification buffer"))); - borderPanel.add(new JScrollPane(mbn)); - mainPanel.add(borderPanel, BorderLayout.CENTER); - // add the subscribe/unsubscribe/clear buttons to - // the south panel - southPanel.removeAll(); - southPanel.add(subscribeButton, BorderLayout.WEST); - southPanel.add(unsubscribeButton, BorderLayout.CENTER); - southPanel.add(clearButton, BorderLayout.EAST); - southPanel.setVisible(true); - subscribeButton.setEnabled(true); - unsubscribeButton.setEnabled(true); - clearButton.setEnabled(true); - validate(); - repaint(); - } - }); - } - }); + mbean = (XMBean) uo.getData(); + mbeanNotifications.loadNotifications(mbean); + updateNotifications(); + invalidate(); + mainPanel.removeAll(); + JPanel borderPanel = new JPanel(new BorderLayout()); + borderPanel.setBorder(BorderFactory.createTitledBorder( + Resources.getText("Notification buffer"))); + borderPanel.add(new JScrollPane(mbeanNotifications)); + mainPanel.add(borderPanel, BorderLayout.CENTER); + // add the subscribe/unsubscribe/clear buttons to the south panel + southPanel.removeAll(); + southPanel.add(subscribeButton, BorderLayout.WEST); + southPanel.add(unsubscribeButton, BorderLayout.CENTER); + southPanel.add(clearButton, BorderLayout.EAST); + southPanel.setVisible(true); + subscribeButton.setEnabled(true); + unsubscribeButton.setEnabled(true); + clearButton.setEnabled(true); + validate(); + repaint(); } // Call on EDT @@ -462,21 +479,60 @@ public class XSheet extends JPanel /** * Subscribe button action. */ - private void registerListener() throws InstanceNotFoundException, - IOException { - mbeanNotifications.registerListener(node); - updateNotifications(); - validate(); + private void registerListener() { + new SwingWorker() { + @Override + public Void doInBackground() + throws InstanceNotFoundException, IOException { + mbeanNotifications.registerListener(currentNode); + return null; + } + @Override + protected void done() { + try { + get(); + updateNotifications(); + validate(); + } catch (Exception e) { + Throwable t = Utils.getActualException(e); + if (JConsole.isDebug()) { + System.err.println("Problem adding listener"); + t.printStackTrace(); + } + showErrorDialog(t.getMessage(), + Resources.getText("Problem adding listener")); + } + } + }.execute(); } /** * Unsubscribe button action. */ private void unregisterListener() { - if (mbeanNotifications.unregisterListener(node)) { - clearNotifications(); - validate(); - } + new SwingWorker() { + @Override + public Boolean doInBackground() { + return mbeanNotifications.unregisterListener(currentNode); + } + @Override + protected void done() { + try { + if (get()) { + updateNotifications(); + validate(); + } + } catch (Exception e) { + Throwable t = Utils.getActualException(e); + if (JConsole.isDebug()) { + System.err.println("Problem removing listener"); + t.printStackTrace(); + } + showErrorDialog(t.getMessage(), + Resources.getText("Problem removing listener")); + } + } + }.execute(); } /** @@ -486,15 +542,11 @@ public class XSheet extends JPanel mbeanAttributes.refreshAttributes(); } + // Call on EDT private void updateNotifications() { - if (mbean.isBroadcaster()) { - if (mbeanNotifications.isListenerRegistered(mbean)) { - long received = - mbeanNotifications.getReceivedNotifications(mbean); - updateReceivedNotifications(node, received, false); - } else { - clearNotifications(); - } + if (mbeanNotifications.isListenerRegistered(mbean)) { + long received = mbeanNotifications.getReceivedNotifications(mbean); + updateReceivedNotifications(currentNode, received, false); } else { clearNotifications(); } @@ -503,11 +555,11 @@ public class XSheet extends JPanel /** * Update notification node label in MBean tree: "Notifications[received]". */ + // Call on EDT private void updateReceivedNotifications( DefaultMutableTreeNode emitter, long received, boolean bold) { String text = Resources.getText("Notifications") + "[" + received + "]"; - DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) - mbeansTab.getTree().getLastSelectedPathComponent(); + DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) mbeansTab.getTree().getLastSelectedPathComponent(); if (bold && emitter != selectedNode) { text = "" + text + ""; } @@ -517,41 +569,40 @@ public class XSheet extends JPanel /** * Update notification node label in MBean tree: "Notifications". */ + // Call on EDT private void clearNotifications() { - updateNotificationsNodeLabel(node, + updateNotificationsNodeLabel(currentNode, Resources.getText("Notifications")); } /** * Update notification node label in MBean tree: "Notifications[0]". */ + // Call on EDT private void clearNotifications0() { - updateNotificationsNodeLabel(node, + updateNotificationsNodeLabel(currentNode, Resources.getText("Notifications") + "[0]"); } /** * Update the label of the supplied MBean tree node. */ + // Call on EDT private void updateNotificationsNodeLabel( - final DefaultMutableTreeNode node, final String label) { - EventQueue.invokeLater(new Runnable() { - public void run() { - synchronized (mbeansTab.getTree()) { - invalidate(); - XNodeInfo oldUserObject = (XNodeInfo) node.getUserObject(); - XNodeInfo newUserObject = new XNodeInfo( - oldUserObject.getType(), oldUserObject.getData(), - label, oldUserObject.getToolTipText()); - node.setUserObject(newUserObject); - DefaultTreeModel model = - (DefaultTreeModel) mbeansTab.getTree().getModel(); - model.nodeChanged(node); - validate(); - repaint(); - } - } - }); + DefaultMutableTreeNode node, String label) { + synchronized (mbeansTab.getTree()) { + invalidate(); + XNodeInfo oldUserObject = (XNodeInfo) node.getUserObject(); + XNodeInfo newUserObject = new XNodeInfo( + oldUserObject.getType(), oldUserObject.getData(), + label, oldUserObject.getToolTipText()); + node.setUserObject(newUserObject); + DefaultTreeModel model = + (DefaultTreeModel) mbeansTab.getTree().getModel(); + model.nodeChanged(node); + validate(); + repaint(); + } } /** @@ -577,6 +628,7 @@ public class XSheet extends JPanel } } + // Call on EDT private void clear() { mbeanAttributes.stopCellEditing(); mbeanAttributes.emptyTable(); @@ -586,13 +638,14 @@ public class XSheet extends JPanel mbeanNotifications.emptyTable(); mbeanNotifications.disableNotifications(); mbean = null; - node = null; + currentNode = null; } /** * Notification listener: handles asynchronous reception * of MBean operation results and MBean notifications. */ + // Call on EDT public void handleNotification(Notification e, Object handback) { // Operation result if (e.getType().equals(XOperations.OPERATION_INVOCATION_EVENT)) { @@ -628,13 +681,12 @@ public class XSheet extends JPanel message = comp; } } - EventQueue.invokeLater(new ThreadDialog( + new ThreadDialog( (Component) e.getSource(), message, Resources.getText("Operation return value"), - JOptionPane.INFORMATION_MESSAGE)); - } - // Got notification + JOptionPane.INFORMATION_MESSAGE).run(); + } // Got notification else if (e.getType().equals( XMBeanNotifications.NOTIFICATION_RECEIVED_EVENT)) { DefaultMutableTreeNode emitter = (DefaultMutableTreeNode) handback; @@ -646,16 +698,19 @@ public class XSheet extends JPanel /** * Action listener: handles actions in panel buttons */ + // Call on EDT public void actionPerformed(ActionEvent e) { if (e.getSource() instanceof JButton) { JButton button = (JButton) e.getSource(); // Refresh button if (button == refreshButton) { - mbeansTab.workerAdd(new Runnable() { - public void run() { + new SwingWorker() { + @Override + public Void doInBackground() { refreshAttributes(); + return null; } - }); + }.execute(); return; } // Clear button @@ -665,38 +720,12 @@ public class XSheet extends JPanel } // Subscribe button if (button == subscribeButton) { - mbeansTab.workerAdd(new Runnable() { - public void run() { - try { - registerListener(); - } catch (Throwable ex) { - ex = Utils.getActualException(ex); - EventQueue.invokeLater(new ThreadDialog( - XSheet.this, - ex.getMessage(), - Resources.getText("Problem adding listener"), - JOptionPane.ERROR_MESSAGE)); - } - } - }); + registerListener(); return; } // Unsubscribe button if (button == unsubscribeButton) { - mbeansTab.workerAdd(new Runnable() { - public void run() { - try { - unregisterListener(); - } catch (Throwable ex) { - ex = Utils.getActualException(ex); - EventQueue.invokeLater(new ThreadDialog( - XSheet.this, - ex.getMessage(), - Resources.getText("Problem removing listener"), - JOptionPane.ERROR_MESSAGE)); - } - } - }); + unregisterListener(); return; } } diff --git a/src/share/classes/sun/tools/jconsole/inspector/XTable.java b/src/share/classes/sun/tools/jconsole/inspector/XTable.java index 5b695c81699fec6f893aacf58593c35377ee560d..c75ca66ccf5df21b38069c9e1184611f87f4a5bc 100644 --- a/src/share/classes/sun/tools/jconsole/inspector/XTable.java +++ b/src/share/classes/sun/tools/jconsole/inspector/XTable.java @@ -22,6 +22,7 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ + package sun.tools.jconsole.inspector; import javax.swing.*; diff --git a/src/share/classes/sun/tools/jconsole/inspector/XTextField.java b/src/share/classes/sun/tools/jconsole/inspector/XTextField.java index 2e7f8cb6f676d01b6b307724375f363a1521ac45..a84819d27c55df73b27b452590d4c91c83784a62 100644 --- a/src/share/classes/sun/tools/jconsole/inspector/XTextField.java +++ b/src/share/classes/sun/tools/jconsole/inspector/XTextField.java @@ -22,6 +22,7 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ + package sun.tools.jconsole.inspector; import java.awt.*; diff --git a/src/share/classes/sun/tools/jconsole/inspector/XTextFieldEditor.java b/src/share/classes/sun/tools/jconsole/inspector/XTextFieldEditor.java index 9476d5a8500b521bcf1ec2bdc3459cae48b3ba7b..237df93778875fddbb82295fb51a7344d75fc6e8 100644 --- a/src/share/classes/sun/tools/jconsole/inspector/XTextFieldEditor.java +++ b/src/share/classes/sun/tools/jconsole/inspector/XTextFieldEditor.java @@ -22,6 +22,7 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ + package sun.tools.jconsole.inspector; import java.awt.Component; diff --git a/src/share/classes/sun/tools/jconsole/inspector/XTree.java b/src/share/classes/sun/tools/jconsole/inspector/XTree.java index c6f4ce4976de1b6000cf8d1322647ed38cb0b2c9..38ee4065a359daba1d1f2c09069845e675d8767f 100644 --- a/src/share/classes/sun/tools/jconsole/inspector/XTree.java +++ b/src/share/classes/sun/tools/jconsole/inspector/XTree.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2007 Sun Microsystems, Inc. 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 @@ -25,7 +25,7 @@ package sun.tools.jconsole.inspector; -import java.awt.EventQueue; +import java.io.IOException; import java.util.*; import javax.management.*; import javax.swing.*; @@ -34,13 +34,14 @@ import sun.tools.jconsole.JConsole; import sun.tools.jconsole.MBeansTab; import sun.tools.jconsole.Resources; import sun.tools.jconsole.inspector.XNodeInfo; -import sun.tools.jconsole.inspector.XNodeInfo.Type; +import static sun.tools.jconsole.inspector.XNodeInfo.Type; @SuppressWarnings("serial") public class XTree extends JTree { private static final List orderedKeyPropertyList = new ArrayList(); + static { String keyPropertyList = System.getProperty("com.sun.tools.jconsole.mbeans.keyPropertyList"); @@ -54,9 +55,7 @@ public class XTree extends JTree { } } } - private MBeansTab mbeansTab; - private Map nodes = new HashMap(); @@ -65,7 +64,7 @@ public class XTree extends JTree { } public XTree(TreeNode root, MBeansTab mbeansTab) { - super(root); + super(root, true); this.mbeansTab = mbeansTab; setRootVisible(false); setShowsRootHandles(true); @@ -90,15 +89,8 @@ public class XTree extends JTree { DefaultMutableTreeNode parent, DefaultMutableTreeNode child, int index) { - // Tree does not show up when there is only the root node - // DefaultTreeModel model = (DefaultTreeModel) getModel(); - DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot(); - boolean rootLeaf = root.isLeaf(); model.insertNodeInto(child, parent, index); - if (rootLeaf) { - model.nodeStructureChanged(root); - } } /** @@ -114,32 +106,29 @@ public class XTree extends JTree { int childCount = parent.getChildCount(); if (childCount == 0) { addChildNode(parent, child, 0); - } else if (child instanceof ComparableDefaultMutableTreeNode) { + return; + } + if (child instanceof ComparableDefaultMutableTreeNode) { ComparableDefaultMutableTreeNode comparableChild = - (ComparableDefaultMutableTreeNode)child; - int i = 0; - for (; i < childCount; i++) { + (ComparableDefaultMutableTreeNode) child; + for (int i = childCount - 1; i >= 0; i--) { DefaultMutableTreeNode brother = (DefaultMutableTreeNode) parent.getChildAt(i); - //child < brother - if (comparableChild.compareTo(brother) < 0) { - addChildNode(parent, child, i); - break; - } - //child = brother - else if (comparableChild.compareTo(brother) == 0) { - addChildNode(parent, child, i); - break; + // expr1: child node must be inserted after metadata nodes + // - OR - + // expr2: "child >= brother" + if ((i <= 2 && isMetadataNode(brother)) || + comparableChild.compareTo(brother) >= 0) { + addChildNode(parent, child, i + 1); + return; } } - //child < all brothers - if (i == childCount) { - addChildNode(parent, child, childCount); - } - } else { - //not comparable, add at the end - addChildNode(parent, child, childCount); + // "child < all brothers", add at the beginning + addChildNode(parent, child, 0); + return; } + // "child not comparable", add at the end + addChildNode(parent, child, childCount); } /** @@ -147,6 +136,7 @@ public class XTree extends JTree { * but does not affect actual MBeanServer contents. */ // Call on EDT + @Override public synchronized void removeAll() { DefaultTreeModel model = (DefaultTreeModel) getModel(); DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot(); @@ -155,51 +145,56 @@ public class XTree extends JTree { nodes.clear(); } - public void delMBeanFromView(final ObjectName mbean) { - EventQueue.invokeLater(new Runnable() { - public void run() { - // We assume here that MBeans are removed one by one (on MBean - // unregistered notification). Deletes the tree node associated - // with the given MBean and recursively all the node parents - // which are leaves and non XMBean. - // - synchronized (XTree.this) { - DefaultMutableTreeNode node = null; - Dn dn = buildDn(mbean); - if (dn.size() > 0) { - DefaultTreeModel model = (DefaultTreeModel) getModel(); - Token token = dn.getToken(0); - String hashKey = dn.getHashKey(token); - node = nodes.get(hashKey); - if ((node != null) && (!node.isRoot())) { - if (hasMBeanChildren(node)) { - removeNonMBeanChildren(node); - String label = token.getValue().toString(); - XNodeInfo userObject = new XNodeInfo( - Type.NONMBEAN, label, - label, token.toString()); - changeNodeValue(node, userObject); - } else { - DefaultMutableTreeNode parent = - (DefaultMutableTreeNode) node.getParent(); - model.removeNodeFromParent(node); - nodes.remove(hashKey); - delParentFromView(dn, 1, parent); - } - } - } + // Call on EDT + public synchronized void removeMBeanFromView(ObjectName mbean) { + // We assume here that MBeans are removed one by one (on MBean + // unregistered notification). Deletes the tree node associated + // with the given MBean and recursively all the node parents + // which are leaves and non XMBean. + // + DefaultMutableTreeNode node = null; + Dn dn = new Dn(mbean); + if (dn.getTokenCount() > 0) { + DefaultTreeModel model = (DefaultTreeModel) getModel(); + Token token = dn.getToken(0); + String hashKey = dn.getHashKey(token); + node = nodes.get(hashKey); + if ((node != null) && (!node.isRoot())) { + if (hasNonMetadataNodes(node)) { + removeMetadataNodes(node); + String label = token.getValue(); + XNodeInfo userObject = new XNodeInfo( + Type.NONMBEAN, label, + label, token.getTokenValue()); + changeNodeValue(node, userObject); + } else { + DefaultMutableTreeNode parent = + (DefaultMutableTreeNode) node.getParent(); + model.removeNodeFromParent(node); + nodes.remove(hashKey); + removeParentFromView(dn, 1, parent); } } - }); + } } /** - * Returns true if any of the children nodes is an MBean. + * Returns true if any of the children nodes is a non MBean metadata node. */ - private boolean hasMBeanChildren(DefaultMutableTreeNode node) { - for (Enumeration e = node.children(); e.hasMoreElements(); ) { + private boolean hasNonMetadataNodes(DefaultMutableTreeNode node) { + for (Enumeration e = node.children(); e.hasMoreElements();) { DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement(); - if (((XNodeInfo) n.getUserObject()).getType().equals(Type.MBEAN)) { + Object uo = n.getUserObject(); + if (uo instanceof XNodeInfo) { + switch (((XNodeInfo) uo).getType()) { + case ATTRIBUTES: + case NOTIFICATIONS: + case OPERATIONS: + break; + default: + return true; + } + } else { return true; } } @@ -207,16 +202,68 @@ public class XTree extends JTree { } /** - * Remove all the children nodes which are not MBean. + * Returns true if any of the children nodes is an MBean metadata node. */ - private void removeNonMBeanChildren(DefaultMutableTreeNode node) { + public boolean hasMetadataNodes(DefaultMutableTreeNode node) { + for (Enumeration e = node.children(); e.hasMoreElements();) { + DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement(); + Object uo = n.getUserObject(); + if (uo instanceof XNodeInfo) { + switch (((XNodeInfo) uo).getType()) { + case ATTRIBUTES: + case NOTIFICATIONS: + case OPERATIONS: + return true; + default: + break; + } + } else { + return false; + } + } + return false; + } + + /** + * Returns true if the given node is an MBean metadata node. + */ + public boolean isMetadataNode(DefaultMutableTreeNode node) { + Object uo = node.getUserObject(); + if (uo instanceof XNodeInfo) { + switch (((XNodeInfo) uo).getType()) { + case ATTRIBUTES: + case NOTIFICATIONS: + case OPERATIONS: + return true; + default: + return false; + } + } else { + return false; + } + } + + /** + * Remove the metadata nodes associated with a given MBean node. + */ + // Call on EDT + private void removeMetadataNodes(DefaultMutableTreeNode node) { Set metadataNodes = new HashSet(); DefaultTreeModel model = (DefaultTreeModel) getModel(); - for (Enumeration e = node.children(); e.hasMoreElements(); ) { + for (Enumeration e = node.children(); e.hasMoreElements();) { DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement(); - if (!((XNodeInfo) n.getUserObject()).getType().equals(Type.MBEAN)) { - metadataNodes.add(n); + Object uo = n.getUserObject(); + if (uo instanceof XNodeInfo) { + switch (((XNodeInfo) uo).getType()) { + case ATTRIBUTES: + case NOTIFICATIONS: + case OPERATIONS: + metadataNodes.add(n); + break; + default: + break; + } } } for (DefaultMutableTreeNode n : metadataNodes) { @@ -228,7 +275,8 @@ public class XTree extends JTree { * Removes only the parent nodes which are non MBean and leaf. * This method assumes the child nodes have been removed before. */ - private DefaultMutableTreeNode delParentFromView( + // Call on EDT + private DefaultMutableTreeNode removeParentFromView( Dn dn, int index, DefaultMutableTreeNode node) { if ((!node.isRoot()) && node.isLeaf() && (!(((XNodeInfo) node.getUserObject()).getType().equals(Type.MBEAN)))) { @@ -237,115 +285,100 @@ public class XTree extends JTree { removeChildNode(node); String hashKey = dn.getHashKey(dn.getToken(index)); nodes.remove(hashKey); - delParentFromView(dn, index + 1, parent); + removeParentFromView(dn, index + 1, parent); } return node; } - public synchronized void addMBeanToView(final ObjectName mbean) { - final XMBean xmbean; - try { - xmbean = new XMBean(mbean, mbeansTab); - if (xmbean == null) { - return; - } - } catch (Exception e) { - // Got exception while trying to retrieve the - // given MBean from the underlying MBeanServer - // - if (JConsole.isDebug()) { - e.printStackTrace(); - } - return; + // Call on EDT + public synchronized void addMBeansToView(Set mbeans) { + Set dns = new TreeSet(); + for (ObjectName mbean : mbeans) { + Dn dn = new Dn(mbean); + dns.add(dn); } - EventQueue.invokeLater(new Runnable() { - public void run() { - synchronized (XTree.this) { - // Add the new nodes to the MBean tree from leaf to root + for (Dn dn : dns) { + ObjectName mbean = dn.getObjectName(); + XMBean xmbean = new XMBean(mbean, mbeansTab); + addMBeanToView(mbean, xmbean, dn); + } + } - Dn dn = buildDn(mbean); - if (dn.size() == 0) return; - Token token = dn.getToken(0); - DefaultMutableTreeNode node = null; - boolean nodeCreated = true; + // Call on EDT + public synchronized void addMBeanToView(ObjectName mbean) { + // Build XMBean for the given MBean + // + XMBean xmbean = new XMBean(mbean, mbeansTab); + // Build Dn for the given MBean + // + Dn dn = new Dn(mbean); + // Add the new nodes to the MBean tree from leaf to root + // + addMBeanToView(mbean, xmbean, dn); + } - // - // Add the node or replace its user object if already added - // + // Call on EDT + private synchronized void addMBeanToView( + ObjectName mbean, XMBean xmbean, Dn dn) { - String hashKey = dn.getHashKey(token); - if (nodes.containsKey(hashKey)) { - //already in the tree, means it has been created previously - //when adding another node - node = nodes.get(hashKey); - //sets the user object - final Object data = createNodeValue(xmbean, token); - final String label = data.toString(); - final XNodeInfo userObject = - new XNodeInfo(Type.MBEAN, data, label, mbean.toString()); - changeNodeValue(node, userObject); - nodeCreated = false; - } else { - //create a new node - node = createDnNode(dn, token, xmbean); - if (node != null) { - nodes.put(hashKey, node); - nodeCreated = true; - } else { - return; - } - } + DefaultMutableTreeNode childNode = null; + DefaultMutableTreeNode parentNode = null; - // - // Add (virtual) nodes without user object if necessary - // + // Add the node or replace its user object if already added + // + Token token = dn.getToken(0); + String hashKey = dn.getHashKey(token); + if (nodes.containsKey(hashKey)) { + // Found existing node previously created when adding another node + // + childNode = nodes.get(hashKey); + // Replace user object to reflect that this node is an MBean + // + Object data = createNodeValue(xmbean, token); + String label = data.toString(); + XNodeInfo userObject = + new XNodeInfo(Type.MBEAN, data, label, mbean.toString()); + changeNodeValue(childNode, userObject); + return; + } - for (int i = 1; i < dn.size(); i++) { - DefaultMutableTreeNode currentNode = null; - token = dn.getToken(i); - hashKey = dn.getHashKey(token); - if (nodes.containsKey(hashKey)) { - //node already present - if (nodeCreated) { - //previous node created, link to do - currentNode = nodes.get(hashKey); - addChildNode(currentNode, node); - return; - } else { - //both nodes already present - return; - } - } else { - //creates the node that can be a virtual one - if (token.getKeyDn().equals("domain")) { - //better match on keyDn that on Dn - currentNode = createDomainNode(dn, token); - if (currentNode != null) { - final DefaultMutableTreeNode root = - (DefaultMutableTreeNode) getModel().getRoot(); - addChildNode(root, currentNode); - } - } else { - currentNode = createSubDnNode(dn, token); - if (currentNode == null) { - //skip - continue; - } - } - nodes.put(hashKey, currentNode); - addChildNode(currentNode, node); - nodeCreated = true; - } - node = currentNode; - } + // Create new leaf node + // + childNode = createDnNode(dn, token, xmbean); + nodes.put(hashKey, childNode); + + // Add intermediate non MBean nodes + // + for (int i = 1; i < dn.getTokenCount(); i++) { + token = dn.getToken(i); + hashKey = dn.getHashKey(token); + if (nodes.containsKey(hashKey)) { + // Intermediate node already present, add new node as child + // + parentNode = nodes.get(hashKey); + addChildNode(parentNode, childNode); + return; + } else { + // Create new intermediate node + // + if ("domain".equals(token.getTokenType())) { + parentNode = createDomainNode(dn, token); + DefaultMutableTreeNode root = + (DefaultMutableTreeNode) getModel().getRoot(); + addChildNode(root, parentNode); + } else { + parentNode = createSubDnNode(dn, token); } + nodes.put(hashKey, parentNode); + addChildNode(parentNode, childNode); } - }); + childNode = parentNode; + } } // Call on EDT private synchronized void changeNodeValue( - final DefaultMutableTreeNode node, XNodeInfo nodeValue) { + DefaultMutableTreeNode node, XNodeInfo nodeValue) { if (node instanceof ComparableDefaultMutableTreeNode) { // should it stay at the same place? DefaultMutableTreeNode clone = @@ -373,9 +406,12 @@ public class XTree extends JTree { } // Load the MBean metadata if type is MBEAN if (nodeValue.getType().equals(Type.MBEAN)) { - XMBeanInfo.loadInfo(node); - DefaultTreeModel model = (DefaultTreeModel) getModel(); - model.nodeStructureChanged(node); + removeMetadataNodes(node); + TreeNode[] treeNodes = node.getPath(); + TreePath path = new TreePath(treeNodes); + if (isExpanded(path)) { + addMetadataNodes(node); + } } // Clear the current selection and set it // again so valueChanged() gets called @@ -386,7 +422,9 @@ public class XTree extends JTree { } } - //creates the domain node, called on a domain token + /** + * Creates the domain node. + */ private DefaultMutableTreeNode createDomainNode(Dn dn, Token token) { DefaultMutableTreeNode node = new ComparableDefaultMutableTreeNode(); String label = dn.getDomain(); @@ -396,7 +434,9 @@ public class XTree extends JTree { return node; } - //creates the node corresponding to the whole Dn + /** + * Creates the node corresponding to the whole Dn, i.e. an MBean. + */ private DefaultMutableTreeNode createDnNode( Dn dn, Token token, XMBean xmbean) { DefaultMutableTreeNode node = new ComparableDefaultMutableTreeNode(); @@ -405,38 +445,36 @@ public class XTree extends JTree { XNodeInfo userObject = new XNodeInfo(Type.MBEAN, data, label, xmbean.getObjectName().toString()); node.setUserObject(userObject); - XMBeanInfo.loadInfo(node); return node; } - //creates a node with the token value, call for each non domain sub - //dn token + /** + * Creates the node corresponding to a subDn, i.e. a non-MBean + * intermediate node. + */ private DefaultMutableTreeNode createSubDnNode(Dn dn, Token token) { DefaultMutableTreeNode node = new ComparableDefaultMutableTreeNode(); - String label = isKeyValueView() ? token.toString() : - token.getValue().toString(); + String label = isKeyValueView() ? token.getTokenValue() : token.getValue(); XNodeInfo userObject = - new XNodeInfo(Type.NONMBEAN, label, label, token.toString()); + new XNodeInfo(Type.NONMBEAN, label, label, token.getTokenValue()); node.setUserObject(userObject); return node; } private Object createNodeValue(XMBean xmbean, Token token) { - String label = isKeyValueView() ? token.toString() : - token.getValue().toString(); + String label = isKeyValueView() ? token.getTokenValue() : token.getValue(); xmbean.setText(label); return xmbean; } /** - * Parses MBean ObjectName comma-separated properties string and put the - * individual key/value pairs into the map. Key order in the properties + * Parses the MBean ObjectName comma-separated properties string and puts + * the individual key/value pairs into the map. Key order in the properties * string is preserved by the map. */ - private Map extractKeyValuePairs( - String properties, ObjectName mbean) { - String props = properties; - Map map = new LinkedHashMap(); + private static Map extractKeyValuePairs( + String props, ObjectName mbean) { + Map map = new LinkedHashMap(); int eq = props.indexOf("="); while (eq != -1) { String key = props.substring(0, eq); @@ -461,9 +499,9 @@ public class XTree extends JTree { * in the comma-separated key property list does not apply to the given * MBean then it will be discarded. */ - private String getKeyPropertyListString(ObjectName mbean) { + private static String getKeyPropertyListString(ObjectName mbean) { String props = mbean.getKeyPropertyListString(); - Map map = extractKeyValuePairs(props, mbean); + Map map = extractKeyValuePairs(props, mbean); StringBuilder sb = new StringBuilder(); // Add the key/value pairs to the buffer following the // key order defined by the "orderedKeyPropertyList" @@ -474,7 +512,7 @@ public class XTree extends JTree { } } // Add the remaining key/value pairs to the buffer - for (Map.Entry entry : map.entrySet()) { + for (Map.Entry entry : map.entrySet()) { sb.append(entry.getKey() + "=" + entry.getValue() + ","); } String orderedKeyPropertyListString = sb.toString(); @@ -483,67 +521,158 @@ public class XTree extends JTree { return orderedKeyPropertyListString; } - /** - * Builds the Dn for the given MBean. - */ - private Dn buildDn(ObjectName mbean) { - - String domain = mbean.getDomain(); - String globalDn = getKeyPropertyListString(mbean); - - Dn dn = buildDn(domain, globalDn, mbean); - - //update the Dn tokens to add the domain - dn.updateDn(); - - //reverse the Dn (from leaf to root) - dn.reverseOrder(); - - //compute the hashDn - dn.computeHashDn(); - - return dn; + // Call on EDT + public void addMetadataNodes(DefaultMutableTreeNode node) { + XMBean mbean = (XMBean) ((XNodeInfo) node.getUserObject()).getData(); + DefaultTreeModel model = (DefaultTreeModel) getModel(); + MBeanInfoNodesSwingWorker sw = + new MBeanInfoNodesSwingWorker(model, node, mbean); + if (sw != null) { + sw.execute(); + } } - /** - * Builds the Dn for the given MBean. - */ - private Dn buildDn(String domain, String globalDn, ObjectName mbean) { - Dn dn = new Dn(domain, globalDn); - String keyDn = "no_key"; - if (isTreeView()) { - String props = globalDn; - Map map = extractKeyValuePairs(props, mbean); - for (Map.Entry entry : map.entrySet()) { - dn.addToken(new Token(keyDn, - entry.getKey() + "=" + entry.getValue())); + private static class MBeanInfoNodesSwingWorker + extends SwingWorker { + + private final DefaultTreeModel model; + private final DefaultMutableTreeNode node; + private final XMBean mbean; + + public MBeanInfoNodesSwingWorker( + DefaultTreeModel model, + DefaultMutableTreeNode node, + XMBean mbean) { + this.model = model; + this.node = node; + this.mbean = mbean; + } + + @Override + public Object[] doInBackground() throws InstanceNotFoundException, + IntrospectionException, ReflectionException, IOException { + Object result[] = new Object[2]; + // Retrieve MBeanInfo for this MBean + result[0] = mbean.getMBeanInfo(); + // Check if this MBean is a notification emitter + result[1] = mbean.isBroadcaster(); + return result; + } + + @Override + protected void done() { + try { + Object result[] = get(); + MBeanInfo mbeanInfo = (MBeanInfo) result[0]; + Boolean isBroadcaster = (Boolean) result[1]; + if (mbeanInfo != null) { + addMBeanInfoNodes(model, node, mbean, mbeanInfo, isBroadcaster); + } + } catch (Exception e) { + Throwable t = Utils.getActualException(e); + if (JConsole.isDebug()) { + t.printStackTrace(); + } } - } else { - //flat view - dn.addToken(new Token(keyDn, "properties=" + globalDn)); } - return dn; - } - // - //utility objects - // + // Call on EDT + private void addMBeanInfoNodes( + DefaultTreeModel tree, DefaultMutableTreeNode node, + XMBean mbean, MBeanInfo mbeanInfo, Boolean isBroadcaster) { + MBeanAttributeInfo[] ai = mbeanInfo.getAttributes(); + MBeanOperationInfo[] oi = mbeanInfo.getOperations(); + MBeanNotificationInfo[] ni = mbeanInfo.getNotifications(); - public static class ComparableDefaultMutableTreeNode - extends DefaultMutableTreeNode - implements Comparable { - public int compareTo(DefaultMutableTreeNode node) { - return (this.toString().compareTo(node.toString())); + // Insert the Attributes/Operations/Notifications metadata nodes as + // the three first children of this MBean node. This is only useful + // when this MBean node denotes an MBean but it's not a leaf in the + // MBean tree + // + int childIndex = 0; + + // MBeanAttributeInfo node + // + if (ai != null && ai.length > 0) { + DefaultMutableTreeNode attributes = new DefaultMutableTreeNode(); + XNodeInfo attributesUO = new XNodeInfo(Type.ATTRIBUTES, mbean, + Resources.getText("Attributes"), null); + attributes.setUserObject(attributesUO); + node.insert(attributes, childIndex++); + for (MBeanAttributeInfo mbai : ai) { + DefaultMutableTreeNode attribute = new DefaultMutableTreeNode(); + XNodeInfo attributeUO = new XNodeInfo(Type.ATTRIBUTE, + new Object[]{mbean, mbai}, mbai.getName(), null); + attribute.setUserObject(attributeUO); + attribute.setAllowsChildren(false); + attributes.add(attribute); + } + } + // MBeanOperationInfo node + // + if (oi != null && oi.length > 0) { + DefaultMutableTreeNode operations = new DefaultMutableTreeNode(); + XNodeInfo operationsUO = new XNodeInfo(Type.OPERATIONS, mbean, + Resources.getText("Operations"), null); + operations.setUserObject(operationsUO); + node.insert(operations, childIndex++); + for (MBeanOperationInfo mboi : oi) { + // Compute the operation's tool tip text: + // "operationname(param1type,param2type,...)" + // + StringBuilder sb = new StringBuilder(); + for (MBeanParameterInfo mbpi : mboi.getSignature()) { + sb.append(mbpi.getType() + ","); + } + String signature = sb.toString(); + if (signature.length() > 0) { + // Remove the trailing ',' + // + signature = signature.substring(0, signature.length() - 1); + } + String toolTipText = mboi.getName() + "(" + signature + ")"; + // Create operation node + // + DefaultMutableTreeNode operation = new DefaultMutableTreeNode(); + XNodeInfo operationUO = new XNodeInfo(Type.OPERATION, + new Object[]{mbean, mboi}, mboi.getName(), toolTipText); + operation.setUserObject(operationUO); + operation.setAllowsChildren(false); + operations.add(operation); + } + } + // MBeanNotificationInfo node + // + if (isBroadcaster != null && isBroadcaster.booleanValue()) { + DefaultMutableTreeNode notifications = new DefaultMutableTreeNode(); + XNodeInfo notificationsUO = new XNodeInfo(Type.NOTIFICATIONS, mbean, + Resources.getText("Notifications"), null); + notifications.setUserObject(notificationsUO); + node.insert(notifications, childIndex++); + if (ni != null && ni.length > 0) { + for (MBeanNotificationInfo mbni : ni) { + DefaultMutableTreeNode notification = + new DefaultMutableTreeNode(); + XNodeInfo notificationUO = new XNodeInfo(Type.NOTIFICATION, + mbni, mbni.getName(), null); + notification.setUserObject(notificationUO); + notification.setAllowsChildren(false); + notifications.add(notification); + } + } + } + // Update tree model + // + model.reload(node); } } - // - //tree preferences + // Tree preferences // + private static boolean treeView; + private static boolean treeViewInit = false; - private boolean treeView; - private boolean treeViewInit = false; - public boolean isTreeView() { + private static boolean isTreeView() { if (!treeViewInit) { treeView = getTreeViewValue(); treeViewInit = true; @@ -551,170 +680,136 @@ public class XTree extends JTree { return treeView; } - private boolean getTreeViewValue() { - String treeView = System.getProperty("treeView"); - return ((treeView == null) ? true : !(treeView.equals("false"))); + private static boolean getTreeViewValue() { + String tv = System.getProperty("treeView"); + return ((tv == null) ? true : !(tv.equals("false"))); } - // - //MBean key-value preferences + // MBean key-value preferences // - private boolean keyValueView = Boolean.getBoolean("keyValueView"); - public boolean isKeyValueView() { + + private boolean isKeyValueView() { return keyValueView; } // - //utility classes + // Utility classes // + private static class ComparableDefaultMutableTreeNode + extends DefaultMutableTreeNode + implements Comparable { + + public int compareTo(DefaultMutableTreeNode node) { + return (this.toString().compareTo(node.toString())); + } + } - public static class Dn { + private static class Dn implements Comparable { + private ObjectName mbean; private String domain; - private String dn; + private String keyPropertyList; private String hashDn; - private ArrayList tokens = new ArrayList(); + private List tokens = new ArrayList(); + + public Dn(ObjectName mbean) { + this.mbean = mbean; + this.domain = mbean.getDomain(); + this.keyPropertyList = getKeyPropertyListString(mbean); + + if (isTreeView()) { + // Tree view + Map map = + extractKeyValuePairs(keyPropertyList, mbean); + for (Map.Entry entry : map.entrySet()) { + tokens.add(new Token("key", entry.getKey() + "=" + entry.getValue())); + } + } else { + // Flat view + tokens.add(new Token("key", "properties=" + keyPropertyList)); + } - public Dn(String domain, String dn) { - this.domain = domain; - this.dn = dn; - } + // Add the domain as the first token in the Dn + tokens.add(0, new Token("domain", "domain=" + domain)); - public void clearTokens() { - tokens.clear(); - } + // Reverse the Dn (from leaf to root) + Collections.reverse(tokens); - public void addToken(Token token) { - tokens.add(token); + // Compute hash for Dn + computeHashDn(); } - public void addToken(int index, Token token) { - tokens.add(index, token); + public ObjectName getObjectName() { + return mbean; } - public void setToken(int index, Token token) { - tokens.set(index, token); + public String getDomain() { + return domain; } - public void removeToken(int index) { - tokens.remove(index); + public String getKeyPropertyList() { + return keyPropertyList; } public Token getToken(int index) { return tokens.get(index); } - public void reverseOrder() { - ArrayList newOrder = new ArrayList(tokens.size()); - for (int i = tokens.size() - 1; i >= 0; i--) { - newOrder.add(tokens.get(i)); - } - tokens = newOrder; - } - - public int size() { + public int getTokenCount() { return tokens.size(); } - public String getDomain() { - return domain; - } - - public String getDn() { - return dn; - } - public String getHashDn() { return hashDn; } public String getHashKey(Token token) { - final int begin = getHashDn().indexOf(token.getHashToken()); - return getHashDn().substring(begin, getHashDn().length()); - } - - public void computeHashDn() { - final StringBuilder hashDn = new StringBuilder(); - final int tokensSize = tokens.size(); - for (int i = 0; i < tokensSize; i++) { - Token token = tokens.get(i); - String hashToken = token.getHashToken(); - if (hashToken == null) { - hashToken = token.getToken() + (tokensSize - i); - token.setHashToken(hashToken); - } - hashDn.append(hashToken); - hashDn.append(","); + final int begin = hashDn.indexOf(token.getTokenValue()); + return hashDn.substring(begin, hashDn.length()); + } + + private void computeHashDn() { + if (tokens.isEmpty()) { + return; } - if (tokensSize > 0) { - this.hashDn = hashDn.substring(0, hashDn.length() - 1); - } else { - this.hashDn = ""; + final StringBuilder hdn = new StringBuilder(); + for (int i = 0; i < tokens.size(); i++) { + hdn.append(tokens.get(i).getTokenValue()); + hdn.append(","); } + hashDn = hdn.substring(0, hdn.length() - 1); } - /** - * Adds the domain as the first token in the Dn. - */ - public void updateDn() { - addToken(0, new Token("domain", "domain=" + getDomain())); + @Override + public String toString() { + return domain + ":" + keyPropertyList; } - public String toString() { - return tokens.toString(); + public int compareTo(Dn dn) { + return this.toString().compareTo(dn.toString()); } } - public static class Token { + private static class Token { - private String keyDn; - private String token; - private String hashToken; + private String tokenType; + private String tokenValue; private String key; private String value; - public Token(String keyDn, String token) { - this.keyDn = keyDn; - this.token = token; - buildKeyValue(); - } - - public Token(String keyDn, String token, String hashToken) { - this.keyDn = keyDn; - this.token = token; - this.hashToken = hashToken; + public Token(String tokenType, String tokenValue) { + this.tokenType = tokenType; + this.tokenValue = tokenValue; buildKeyValue(); } - public String getKeyDn() { - return keyDn; - } - - public String getToken() { - return token; - } - - public void setValue(String value) { - this.value = value; - this.token = key + "=" + value; - } - - public void setKey(String key) { - this.key = key; - this.token = key + "=" + value; + public String getTokenType() { + return tokenType; } - public void setKeyDn(String keyDn) { - this.keyDn = keyDn; - } - - public void setHashToken(String hashToken) { - this.hashToken = hashToken; - } - - public String getHashToken() { - return hashToken; + public String getTokenValue() { + return tokenValue; } public String getKey() { @@ -725,26 +820,14 @@ public class XTree extends JTree { return value; } - public String toString(){ - return getToken(); - } - - public boolean equals(Object object) { - if (object instanceof Token) { - return token.equals(((Token) object)); - } else { - return false; - } - } - private void buildKeyValue() { - int index = token.indexOf("="); + int index = tokenValue.indexOf("="); if (index < 0) { - key = token; - value = token; + key = tokenValue; + value = tokenValue; } else { - key = token.substring(0, index); - value = token.substring(index + 1, token.length()); + key = tokenValue.substring(0, index); + value = tokenValue.substring(index + 1, tokenValue.length()); } } } diff --git a/src/share/classes/sun/tools/native2ascii/N2AFilter.java b/src/share/classes/sun/tools/native2ascii/N2AFilter.java index 0a5706e061c7a585de5bc2fe9c1c9d6750790f95..82c807d2e1b0f8351658f432d6bf20eedf415ba5 100644 --- a/src/share/classes/sun/tools/native2ascii/N2AFilter.java +++ b/src/share/classes/sun/tools/native2ascii/N2AFilter.java @@ -42,7 +42,7 @@ class N2AFilter extends FilterWriter { public void write(char b) throws IOException { char[] buf = new char[1]; - buf[0] = (char)b; + buf[0] = b; write(buf, 0, 1); } diff --git a/src/share/demo/jfc/Notepad/resources/Notepad.properties b/src/share/demo/jfc/Notepad/resources/Notepad.properties index 9f9ec3a75319665e3fa560544a4db1f1065c608c..fdd5c5a22468817d64b832b8cf4712f7f39c139d 100644 --- a/src/share/demo/jfc/Notepad/resources/Notepad.properties +++ b/src/share/demo/jfc/Notepad/resources/Notepad.properties @@ -1,76 +1,76 @@ -# -# Resource strings for Notepad example - -Title=Notepad -ElementTreeFrameTitle=Elements -ViewportBackingStore=false - -# menubar definition -# -# Each of the strings that follow form a key to be -# used to the actual menu definition. -menubar=file edit debug - -# file Menu definition -# -# Each of the strings that follow form a key to be -# used as the basis of a menu item definition. -# -# open -> Notepad.openAction -# new -> Notepad.newAction -# save -> Notepad.saveAction -# exit -> Notepad.exitAction -file=new open save - exit -fileLabel=File -openLabel=Open -openImage=resources/open.gif -newLabel=New -newImage=resources/new.gif -saveLabel=Save -saveImage=resources/save.gif -exitLabel=Exit - -# -# edit Menu definition -# -# cut -> JTextComponent.cutAction -# copy -> JTextComponent.copyAction -# paste -> JTextComponent.pasteAction -edit=cut copy paste - undo redo -editLabel=Edit -cutLabel=Cut -cutAction=cut-to-clipboard -cutImage=resources/cut.gif -copyLabel=Copy -copyAction=copy-to-clipboard -copyImage=resources/copy.gif -pasteLabel=Paste -pasteAction=paste-from-clipboard -pasteImage=resources/paste.gif -undoLabel=Undo -undoAction=Undo -redoLabel=Redo -redoAction=Redo - -# -# debug Menu definition -# -debug=dump showElementTree -debugLabel=Debug -dumpLabel=Dump model to System.err -dumpAction=dump-model -showElementTreeLabel=Show Elements - -# toolbar definition -# -# Each of the strings that follow form a key to be -# used as the basis of the tool definition. Actions -# are of course sharable, and in this case are shared -# with the menu items. -toolbar=new open save - cut copy paste -newTooltip=Create a new file -openTooltip=Open a file -saveTooltip=Save to a file -cutTooltip=Move selection to clipboard -copyTooltip=Copy selection to clipboard -pasteTooltip=Paste clipboard to selection +# +# Resource strings for Notepad example + +Title=Notepad +ElementTreeFrameTitle=Elements +ViewportBackingStore=false + +# menubar definition +# +# Each of the strings that follow form a key to be +# used to the actual menu definition. +menubar=file edit debug + +# file Menu definition +# +# Each of the strings that follow form a key to be +# used as the basis of a menu item definition. +# +# open -> Notepad.openAction +# new -> Notepad.newAction +# save -> Notepad.saveAction +# exit -> Notepad.exitAction +file=new open save - exit +fileLabel=File +openLabel=Open +openImage=resources/open.gif +newLabel=New +newImage=resources/new.gif +saveLabel=Save +saveImage=resources/save.gif +exitLabel=Exit + +# +# edit Menu definition +# +# cut -> JTextComponent.cutAction +# copy -> JTextComponent.copyAction +# paste -> JTextComponent.pasteAction +edit=cut copy paste - undo redo +editLabel=Edit +cutLabel=Cut +cutAction=cut-to-clipboard +cutImage=resources/cut.gif +copyLabel=Copy +copyAction=copy-to-clipboard +copyImage=resources/copy.gif +pasteLabel=Paste +pasteAction=paste-from-clipboard +pasteImage=resources/paste.gif +undoLabel=Undo +undoAction=Undo +redoLabel=Redo +redoAction=Redo + +# +# debug Menu definition +# +debug=dump showElementTree +debugLabel=Debug +dumpLabel=Dump model to System.err +dumpAction=dump-model +showElementTreeLabel=Show Elements + +# toolbar definition +# +# Each of the strings that follow form a key to be +# used as the basis of the tool definition. Actions +# are of course sharable, and in this case are shared +# with the menu items. +toolbar=new open save - cut copy paste +newTooltip=Create a new file +openTooltip=Open a file +saveTooltip=Save to a file +cutTooltip=Move selection to clipboard +copyTooltip=Copy selection to clipboard +pasteTooltip=Paste clipboard to selection diff --git a/src/share/native/java/io/io_util.c b/src/share/native/java/io/io_util.c index 4f7372babb971e85a807c8f50a8698c1736bb657..f355069cd0aa258ba11065bbdcba98b11b5349f2 100644 --- a/src/share/native/java/io/io_util.c +++ b/src/share/native/java/io/io_util.c @@ -40,7 +40,7 @@ readSingle(JNIEnv *env, jobject this, jfieldID fid) { char ret; FD fd = GET_FD(this, fid); if (fd == -1) { - JNU_ThrowIOException (env, "Stream Closed"); + JNU_ThrowIOException(env, "Stream Closed"); return -1; } nread = IO_Read(fd, &ret, 1); @@ -94,8 +94,8 @@ readBytes(JNIEnv *env, jobject this, jbyteArray bytes, fd = GET_FD(this, fid); if (fd == -1) { - JNU_ThrowIOException (env, "Stream Closed"); - return -1; + JNU_ThrowIOException(env, "Stream Closed"); + return -1; } nread = IO_Read(fd, buf, len); @@ -121,7 +121,7 @@ writeSingle(JNIEnv *env, jobject this, jint byte, jfieldID fid) { int n; FD fd = GET_FD(this, fid); if (fd == -1) { - JNU_ThrowIOException (env, "Stream Closed"); + JNU_ThrowIOException(env, "Stream Closed"); return; } n = IO_Write(fd, &c, 1); @@ -172,8 +172,8 @@ writeBytes(JNIEnv *env, jobject this, jbyteArray bytes, while (len > 0) { fd = GET_FD(this, fid); if (fd == -1) { - JNU_ThrowIOException (env, "Stream Closed"); - return; + JNU_ThrowIOException(env, "Stream Closed"); + break; } n = IO_Write(fd, buf+off, len); if (n == JVM_IO_ERR) { diff --git a/src/share/sample/vm/clr-jvm/Makefile b/src/share/sample/vm/clr-jvm/Makefile index 2515650d1d518ccf4ac1d17a43fb47c11c0d45d3..5b8e6f3b6faf4e3041933df5f853991abbb9ba3f 100644 --- a/src/share/sample/vm/clr-jvm/Makefile +++ b/src/share/sample/vm/clr-jvm/Makefile @@ -29,16 +29,16 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -all: jinvoker.dll invoked.class invoker.exe - -jinvoker.dll: jinvoker.obj Makefile - cl /LD /o jinvoker.dll jinvoker.obj - -jinvoker.obj: jinvoker.cpp jinvokerExp.h Makefile - cl /Fojinvoker.obj /DJINVOKEREEXPORT /c jinvoker.cpp - -invoked.class: invoked.java Makefile - javac invoked.java - -invoker.exe: invoker.cs Makefile - csc /unsafe invoker.cs +all: jinvoker.dll invoked.class invoker.exe + +jinvoker.dll: jinvoker.obj Makefile + cl /LD /o jinvoker.dll jinvoker.obj + +jinvoker.obj: jinvoker.cpp jinvokerExp.h Makefile + cl /Fojinvoker.obj /DJINVOKEREEXPORT /c jinvoker.cpp + +invoked.class: invoked.java Makefile + javac invoked.java + +invoker.exe: invoker.cs Makefile + csc /unsafe invoker.cs diff --git a/src/share/sample/vm/clr-jvm/README.txt b/src/share/sample/vm/clr-jvm/README.txt index a081c878c94bcdbc1fd1a54be31b7e9dc4cd4910..52ed44e6d820c8abd88a16802e7e3cb55475b47b 100644 --- a/src/share/sample/vm/clr-jvm/README.txt +++ b/src/share/sample/vm/clr-jvm/README.txt @@ -1,54 +1,54 @@ -This sample provides Java "Hello World" program that is invoked -from C# application in the same process. - -The problem of direct call of the JVM API from CLR applications -by PInvoke interface is the JVM API functions do not have static -adresses, they need to be got by JNI_CreateJavaVM() call. -The sample contains C++ libraty that wraps JVM API calls by the -static functions that are called from the C# application by -PInvoke interface. - -The sample contains the following files: - -Makefile - make file -README.txt - this readme -invoked.java - the invoked HelloWorld Java program -invoker.cs - C# invoker application -jinvoker.cpp - C++ wrapper -jinvokerExp.h - wrapper library exports - -After the success making the following files are produced: - -invoked.class - the compiled HelloWorld class -invoker.exe - the executable .NET program that invokes Java -jinvoker.dll - the wrapper library - -The following environment needs to be set for the correct sample -build and execution: - -INCLUDE must contain the paths to: - 1. MS Visual C++ standard include - 2. .NET SDK include - 3. Java includes - Example: %MSDEV%/VC98/Include;%DOTNET%/Include;%JAVA_HOME%/include;%JAVA_HOME%/include/win32 - -LIB must contain the paths to: - 1. MS Visual C++ standard libraries - 2. .NET SDK libraries - 3. jvm.dll - Example: %MSDEV%/VC98/Lib;%DOTNET%/Lib;%JAVA_HOME%/jre/bin/client - -PATH must contain the paths to: - 1. MS Visual C++ standard bin - 2. MS Dev common bin - 3. .NET SDK libraries - 4. Java bin - 5. jvm.dll - Example: %MSDEV%/VC98/Bin;%MSDEV%/Common/MSDev98/Bin;%DOTNET%/Lib;%JAVA_HOME%/bin;%JAVA_HOME%/jre/bin/client;%PATH% - -To run the sample please do: - - invoker.exe invoked - - ---Dmitry Ryashchentsev +This sample provides Java "Hello World" program that is invoked +from C# application in the same process. + +The problem of direct call of the JVM API from CLR applications +by PInvoke interface is the JVM API functions do not have static +adresses, they need to be got by JNI_CreateJavaVM() call. +The sample contains C++ libraty that wraps JVM API calls by the +static functions that are called from the C# application by +PInvoke interface. + +The sample contains the following files: + +Makefile - make file +README.txt - this readme +invoked.java - the invoked HelloWorld Java program +invoker.cs - C# invoker application +jinvoker.cpp - C++ wrapper +jinvokerExp.h - wrapper library exports + +After the success making the following files are produced: + +invoked.class - the compiled HelloWorld class +invoker.exe - the executable .NET program that invokes Java +jinvoker.dll - the wrapper library + +The following environment needs to be set for the correct sample +build and execution: + +INCLUDE must contain the paths to: + 1. MS Visual C++ standard include + 2. .NET SDK include + 3. Java includes + Example: %MSDEV%/VC98/Include;%DOTNET%/Include;%JAVA_HOME%/include;%JAVA_HOME%/include/win32 + +LIB must contain the paths to: + 1. MS Visual C++ standard libraries + 2. .NET SDK libraries + 3. jvm.dll + Example: %MSDEV%/VC98/Lib;%DOTNET%/Lib;%JAVA_HOME%/jre/bin/client + +PATH must contain the paths to: + 1. MS Visual C++ standard bin + 2. MS Dev common bin + 3. .NET SDK libraries + 4. Java bin + 5. jvm.dll + Example: %MSDEV%/VC98/Bin;%MSDEV%/Common/MSDev98/Bin;%DOTNET%/Lib;%JAVA_HOME%/bin;%JAVA_HOME%/jre/bin/client;%PATH% + +To run the sample please do: + + invoker.exe invoked + + +--Dmitry Ryashchentsev diff --git a/src/share/sample/vm/clr-jvm/invoker.cs b/src/share/sample/vm/clr-jvm/invoker.cs index 7e5646230bfa48e68b0d21f94d2098a9f90f6a58..b4ae1bb3d0ae1844636e8e1d7b857d4d38e3f3b2 100644 --- a/src/share/sample/vm/clr-jvm/invoker.cs +++ b/src/share/sample/vm/clr-jvm/invoker.cs @@ -29,30 +29,30 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* -*/ - +/* +*/ + using System; using System.Runtime.InteropServices; class jinvoker{ public static int Main(string[] aArgs){ - - // Print Hello to show we are in CLR - Console.WriteLine("Hello from C#"); - if(aArgs.Length > 0) - // invoke JVM - return InvokeMain(aArgs[0]); - else - return -1; + + // Print Hello to show we are in CLR + Console.WriteLine("Hello from C#"); + if(aArgs.Length > 0) + // invoke JVM + return InvokeMain(aArgs[0]); + else + return -1; } // Link the JVM API functions and the wrappers [DllImport("jvm.dll")] public unsafe static extern int JNI_CreateJavaVM(void** ppVm, void** ppEnv, void* pArgs); [DllImport("jinvoker.dll")] public unsafe static extern int MakeJavaVMInitArgs( void** ppArgs ); - [DllImport("jinvoker.dll")] public unsafe static extern void FreeJavaVMInitArgs( void* pArgs ); + [DllImport("jinvoker.dll")] public unsafe static extern void FreeJavaVMInitArgs( void* pArgs ); [DllImport("jinvoker.dll")] public unsafe static extern int FindClass( void* pEnv, String sClass, void** ppClass ); [DllImport("jinvoker.dll")] public unsafe static extern int GetStaticMethodID( void* pEnv, void* pClass, @@ -73,7 +73,7 @@ class jinvoker{ [DllImport("jinvoker.dll")] public unsafe static extern int DestroyJavaVM( void* pJVM ); public unsafe static int InvokeMain( String sClass ){ - + void* pJVM; // JVM struct void* pEnv; // JVM environment void* pVMArgs; // VM args @@ -81,23 +81,23 @@ class jinvoker{ void* pMethod; // The executed method struct void* pArgs; // The executed method arguments struct - // Fill the pVMArgs structs + // Fill the pVMArgs structs MakeJavaVMInitArgs( &pVMArgs ); - // Create JVM + // Create JVM int nRes = JNI_CreateJavaVM( &pJVM, &pEnv, pVMArgs ); if( nRes == 0 ){ - - // Find the executed method class + + // Find the executed method class if(FindClass( pEnv, sClass, &pClass) == 0 ) - - // Find the executed method + + // Find the executed method if( GetStaticMethodID( pEnv, pClass, "main", "([Ljava/lang/String;)V", &pMethod ) == 0 ) - - // Create empty String[] array to pass to the main() + + // Create empty String[] array to pass to the main() if( NewObjectArray( pEnv, 0, "java/lang/String", &pArgs ) == 0 ){ - - // Call main() + + // Call main() nRes = CallStaticVoidMethod( pEnv, pClass, pMethod, pArgs ); if( nRes != -1 ) Console.WriteLine("Result:"+nRes); @@ -116,16 +116,16 @@ class jinvoker{ Console.WriteLine("can not find class:"+sClass); nRes = -102; } - - // Destroy the JVM + + // Destroy the JVM DestroyJavaVM( pJVM ); }else - Console.WriteLine("Can not create Java VM"); - - // Free the JVM args structs + Console.WriteLine("Can not create Java VM"); + + // Free the JVM args structs FreeJavaVMInitArgs(pVMArgs); - + return nRes; } } diff --git a/src/share/sample/vm/jvm-clr/README.txt b/src/share/sample/vm/jvm-clr/README.txt index a8fe79db343b3ab902827229ff704377cd274539..1d1c2f4bb12575c200d15587bb00dea85bc0ab05 100644 --- a/src/share/sample/vm/jvm-clr/README.txt +++ b/src/share/sample/vm/jvm-clr/README.txt @@ -42,10 +42,10 @@ PATH must contain the paths to: 3. .NET SDK libraries 4. Java bin Example: %MSDEV%/VC98/Bin;%MSDEV%/Common/MSDev98/Bin;%DOTNET%/Lib;%JAVA_HOME%/bin;%PATH% - -To run the sample please do: - -java invoker invoked.exe - - ---Dmitry Ryashchentsev + +To run the sample please do: + +java invoker invoked.exe + + +--Dmitry Ryashchentsev diff --git a/src/share/sample/vm/jvm-clr/invoked.cs b/src/share/sample/vm/jvm-clr/invoked.cs index 1904bb7191b8b495b68c73b964119f30e0f4b6ba..e5eead480afcc7d87fa2e71e3c7452f800266f39 100644 --- a/src/share/sample/vm/jvm-clr/invoked.cs +++ b/src/share/sample/vm/jvm-clr/invoked.cs @@ -29,17 +29,17 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* -*/ - - +/* +*/ + + using System; class App{ public static int Main(){ - - // Print Hello to show we are in CLR + + // Print Hello to show we are in CLR Console.WriteLine("Hello from C#!!!"); return 0; } diff --git a/src/solaris/bin/java_md.c b/src/solaris/bin/java_md.c index 5d96c2780f009aa702428faca964fd4a0068a5d6..74dd1a3ef8ea4b07221ea5ee9bf0dbbdbe9a517e 100644 --- a/src/solaris/bin/java_md.c +++ b/src/solaris/bin/java_md.c @@ -1299,12 +1299,6 @@ void SetJavaLauncherPlatformProps() { AddOption(pid_prop_str, NULL); #endif } -void -SetJavaw() -{ - /* noop on UNIX */ - return; -} jboolean IsJavaw() @@ -1312,3 +1306,9 @@ IsJavaw() /* noop on UNIX */ return JNI_FALSE; } + +void +InitLauncher(jboolean javaw) +{ + JLI_SetTraceLauncher(); +} diff --git a/src/solaris/classes/java/io/FileDescriptor.java b/src/solaris/classes/java/io/FileDescriptor.java index fdd1d143b82c0f7765e135f792b2891a83f41468..ef8aa1c4602d64e272eef1860ba3be142c3603ba 100644 --- a/src/solaris/classes/java/io/FileDescriptor.java +++ b/src/solaris/classes/java/io/FileDescriptor.java @@ -152,11 +152,19 @@ public final class FileDescriptor { public int get(FileDescriptor obj) { return obj.fd; } + + public void setHandle(FileDescriptor obj, long handle) { + throw new UnsupportedOperationException(); + } + + public long getHandle(FileDescriptor obj) { + throw new UnsupportedOperationException(); + } } ); } - // pacakge private methods used by FIS,FOS and RAF + // package private methods used by FIS, FOS and RAF int incrementAndGetUseCount() { return useCount.incrementAndGet(); diff --git a/src/solaris/classes/java/lang/ProcessImpl.java b/src/solaris/classes/java/lang/ProcessImpl.java index d7bdbe191173916313d7dcab987d8fc458ce8632..b9074349efac8a9ac3e4cb710213d4616238e820 100644 --- a/src/solaris/classes/java/lang/ProcessImpl.java +++ b/src/solaris/classes/java/lang/ProcessImpl.java @@ -26,7 +26,10 @@ package java.lang; import java.io.IOException; -import java.lang.Process; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.lang.ProcessBuilder.Redirect; +import java.lang.ProcessBuilder.Redirect; /** * This class is for the exclusive use of ProcessBuilder.start() to @@ -36,6 +39,9 @@ import java.lang.Process; * @since 1.5 */ final class ProcessImpl { + private static final sun.misc.JavaIOFileDescriptorAccess fdAccess + = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess(); + private ProcessImpl() {} // Not instantiable private static byte[] toCString(String s) { @@ -54,6 +60,7 @@ final class ProcessImpl { static Process start(String[] cmdarray, java.util.Map environment, String dir, + ProcessBuilder.Redirect[] redirects, boolean redirectErrorStream) throws IOException { @@ -78,11 +85,61 @@ final class ProcessImpl { int[] envc = new int[1]; byte[] envBlock = ProcessEnvironment.toEnvironmentBlock(environment, envc); + int[] std_fds; + + FileInputStream f0 = null; + FileOutputStream f1 = null; + FileOutputStream f2 = null; + + try { + if (redirects == null) { + std_fds = new int[] { -1, -1, -1 }; + } else { + std_fds = new int[3]; + + if (redirects[0] == Redirect.PIPE) + std_fds[0] = -1; + else if (redirects[0] == Redirect.INHERIT) + std_fds[0] = 0; + else { + f0 = new FileInputStream(redirects[0].file()); + std_fds[0] = fdAccess.get(f0.getFD()); + } + + if (redirects[1] == Redirect.PIPE) + std_fds[1] = -1; + else if (redirects[1] == Redirect.INHERIT) + std_fds[1] = 1; + else { + f1 = redirects[1].toFileOutputStream(); + std_fds[1] = fdAccess.get(f1.getFD()); + } + + if (redirects[2] == Redirect.PIPE) + std_fds[2] = -1; + else if (redirects[2] == Redirect.INHERIT) + std_fds[2] = 2; + else { + f2 = redirects[2].toFileOutputStream(); + std_fds[2] = fdAccess.get(f2.getFD()); + } + } + return new UNIXProcess (toCString(cmdarray[0]), argBlock, args.length, envBlock, envc[0], toCString(dir), + std_fds, redirectErrorStream); + } finally { + // In theory, close() can throw IOException + // (although it is rather unlikely to happen here) + try { if (f0 != null) f0.close(); } + finally { + try { if (f1 != null) f1.close(); } + finally { if (f2 != null) f2.close(); } + } + } } } diff --git a/src/solaris/classes/java/lang/UNIXProcess.java.linux b/src/solaris/classes/java/lang/UNIXProcess.java.linux index ded83065eb781d454763ba4b82c2bd57e0a054c8..9fc9e9da6452617792155f0a8b8b229cfe6656b1 100644 --- a/src/solaris/classes/java/lang/UNIXProcess.java.linux +++ b/src/solaris/classes/java/lang/UNIXProcess.java.linux @@ -1,5 +1,5 @@ -/* - * Copyright 1995-2006 Sun Microsystems, Inc. All Rights Reserved. +/* + * Copyright 1995-2008 Sun Microsystems, Inc. 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 @@ -34,9 +34,9 @@ import java.io.*; */ final class UNIXProcess extends Process { - private FileDescriptor stdin_fd; - private FileDescriptor stdout_fd; - private FileDescriptor stderr_fd; + private static final sun.misc.JavaIOFileDescriptorAccess fdAccess + = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess(); + private int pid; private int exitcode; private boolean hasExited; @@ -48,15 +48,26 @@ final class UNIXProcess extends Process { /* this is for the reaping thread */ private native int waitForProcessExit(int pid); + /** + * Create a process using fork(2) and exec(2). + * + * @param std_fds array of file descriptors. Indexes 0, 1, and + * 2 correspond to standard input, standard output and + * standard error, respectively. On input, a value of -1 + * means to create a pipe to connect child and parent + * processes. On output, a value which is not -1 is the + * parent pipe fd corresponding to the pipe which has + * been created. An element of this array is -1 on input + * if and only if it is not -1 on output. + * @return the pid of the subprocess + */ private native int forkAndExec(byte[] prog, - byte[] argBlock, int argc, - byte[] envBlock, int envc, - byte[] dir, - boolean redirectErrorStream, - FileDescriptor stdin_fd, - FileDescriptor stdout_fd, - FileDescriptor stderr_fd) - throws IOException; + byte[] argBlock, int argc, + byte[] envBlock, int envc, + byte[] dir, + int[] std_fds, + boolean redirectErrorStream) + throws IOException; /* In the process constructor we wait on this gate until the process */ /* has been created. Then we return from the constructor. */ @@ -97,67 +108,82 @@ final class UNIXProcess extends Process { } UNIXProcess(final byte[] prog, - final byte[] argBlock, final int argc, - final byte[] envBlock, final int envc, - final byte[] dir, - final boolean redirectErrorStream) + final byte[] argBlock, final int argc, + final byte[] envBlock, final int envc, + final byte[] dir, + final int[] std_fds, + final boolean redirectErrorStream) throws IOException { - stdin_fd = new FileDescriptor(); - stdout_fd = new FileDescriptor(); - stderr_fd = new FileDescriptor(); final Gate gate = new Gate(); - /* - * For each subprocess forked a corresponding reaper thread - * is started. That thread is the only thread which waits - * for the subprocess to terminate and it doesn't hold any - * locks while doing so. This design allows waitFor() and - * exitStatus() to be safely executed in parallel (and they - * need no native code). - */ - - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - Thread t = new Thread("process reaper") { - public void run() { + /* + * For each subprocess forked a corresponding reaper thread + * is started. That thread is the only thread which waits + * for the subprocess to terminate and it doesn't hold any + * locks while doing so. This design allows waitFor() and + * exitStatus() to be safely executed in parallel (and they + * need no native code). + */ + + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + Thread t = new Thread("process reaper") { + public void run() { try { pid = forkAndExec(prog, - argBlock, argc, - envBlock, envc, - dir, - redirectErrorStream, - stdin_fd, stdout_fd, stderr_fd); + argBlock, argc, + envBlock, envc, + dir, + std_fds, + redirectErrorStream); } catch (IOException e) { gate.setException(e); /*remember to rethrow later*/ gate.exit(); return; } java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - stdin_stream = new BufferedOutputStream(new - FileOutputStream(stdin_fd)); - stdout_stream = new BufferedInputStream(new - FileInputStream(stdout_fd)); + new java.security.PrivilegedAction() { + public Void run() { + if (std_fds[0] == -1) + stdin_stream = new ProcessBuilder.NullOutputStream(); + else { + FileDescriptor stdin_fd = new FileDescriptor(); + fdAccess.set(stdin_fd, std_fds[0]); + stdin_stream = new BufferedOutputStream( + new FileOutputStream(stdin_fd)); + } + + if (std_fds[1] == -1) + stdout_stream = new ProcessBuilder.NullInputStream(); + else { + FileDescriptor stdout_fd = new FileDescriptor(); + fdAccess.set(stdout_fd, std_fds[1]); + stdout_stream = new BufferedInputStream( + new FileInputStream(stdout_fd)); + } + + if (std_fds[2] == -1) + stderr_stream = new ProcessBuilder.NullInputStream(); + else { + FileDescriptor stderr_fd = new FileDescriptor(); + fdAccess.set(stderr_fd, std_fds[2]); stderr_stream = new FileInputStream(stderr_fd); - return null; } - }); + + return null; }}); gate.exit(); /* exit from constructor */ - int res = waitForProcessExit(pid); - synchronized (UNIXProcess.this) { - hasExited = true; - exitcode = res; - UNIXProcess.this.notifyAll(); - } - } - }; + int res = waitForProcessExit(pid); + synchronized (UNIXProcess.this) { + hasExited = true; + exitcode = res; + UNIXProcess.this.notifyAll(); + } + } + }; t.setDaemon(true); t.start(); - return null; - } - }); + return null; }}); gate.waitForExit(); IOException e = gate.getException(); if (e != null) @@ -165,43 +191,43 @@ final class UNIXProcess extends Process { } public OutputStream getOutputStream() { - return stdin_stream; + return stdin_stream; } public InputStream getInputStream() { - return stdout_stream; + return stdout_stream; } public InputStream getErrorStream() { - return stderr_stream; + return stderr_stream; } public synchronized int waitFor() throws InterruptedException { while (!hasExited) { - wait(); - } - return exitcode; + wait(); + } + return exitcode; } public synchronized int exitValue() { - if (!hasExited) { - throw new IllegalThreadStateException("process hasn't exited"); - } - return exitcode; + if (!hasExited) { + throw new IllegalThreadStateException("process hasn't exited"); + } + return exitcode; } private static native void destroyProcess(int pid); public void destroy() { - // There is a risk that pid will be recycled, causing us to - // kill the wrong process! So we only terminate processes - // that appear to still be running. Even with this check, - // there is an unavoidable race condition here, but the window - // is very small, and OSes try hard to not recycle pids too - // soon, so this is quite safe. - synchronized (this) { - if (!hasExited) - destroyProcess(pid); - } + // There is a risk that pid will be recycled, causing us to + // kill the wrong process! So we only terminate processes + // that appear to still be running. Even with this check, + // there is an unavoidable race condition here, but the window + // is very small, and OSes try hard to not recycle pids too + // soon, so this is quite safe. + synchronized (this) { + if (!hasExited) + destroyProcess(pid); + } try { stdin_stream.close(); stdout_stream.close(); @@ -215,6 +241,6 @@ final class UNIXProcess extends Process { private static native void initIDs(); static { - initIDs(); + initIDs(); } } diff --git a/src/solaris/classes/java/lang/UNIXProcess.java.solaris b/src/solaris/classes/java/lang/UNIXProcess.java.solaris index ae29a09e5624f3414fbae5dc20c9b58a1c0c2ef9..f47d1043175192f8d877a1397d05f99fef185c94 100644 --- a/src/solaris/classes/java/lang/UNIXProcess.java.solaris +++ b/src/solaris/classes/java/lang/UNIXProcess.java.solaris @@ -1,5 +1,5 @@ -/* - * Copyright 1995-2006 Sun Microsystems, Inc. All Rights Reserved. +/* + * Copyright 1995-2008 Sun Microsystems, Inc. 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 @@ -33,129 +33,155 @@ import java.io.*; */ final class UNIXProcess extends Process { - private FileDescriptor stdin_fd; - private FileDescriptor stdout_fd; - private FileDescriptor stderr_fd; - private int pid; + private static final sun.misc.JavaIOFileDescriptorAccess fdAccess + = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess(); + + private final int pid; private int exitcode; private boolean hasExited; private OutputStream stdin_stream; - private BufferedInputStream stdout_stream; + private InputStream stdout_stream; private DeferredCloseInputStream stdout_inner_stream; - private DeferredCloseInputStream stderr_stream; + private InputStream stderr_stream; /* this is for the reaping thread */ private native int waitForProcessExit(int pid); + /** + * Create a process using fork(2) and exec(2). + * + * @param std_fds array of file descriptors. Indexes 0, 1, and + * 2 correspond to standard input, standard output and + * standard error, respectively. On input, a value of -1 + * means to create a pipe to connect child and parent + * processes. On output, a value which is not -1 is the + * parent pipe fd corresponding to the pipe which has + * been created. An element of this array is -1 on input + * if and only if it is not -1 on output. + * @return the pid of the subprocess + */ private native int forkAndExec(byte[] prog, - byte[] argBlock, int argc, - byte[] envBlock, int envc, - byte[] dir, - boolean redirectErrorStream, - FileDescriptor stdin_fd, - FileDescriptor stdout_fd, - FileDescriptor stderr_fd) - throws IOException; + byte[] argBlock, int argc, + byte[] envBlock, int envc, + byte[] dir, + int[] std_fds, + boolean redirectErrorStream) + throws IOException; UNIXProcess(final byte[] prog, - final byte[] argBlock, int argc, - final byte[] envBlock, int envc, - final byte[] dir, - final boolean redirectErrorStream) + final byte[] argBlock, int argc, + final byte[] envBlock, int envc, + final byte[] dir, + final int[] std_fds, + final boolean redirectErrorStream) throws IOException { - stdin_fd = new FileDescriptor(); - stdout_fd = new FileDescriptor(); - stderr_fd = new FileDescriptor(); - - pid = forkAndExec(prog, - argBlock, argc, - envBlock, envc, - dir, - redirectErrorStream, - stdin_fd, stdout_fd, stderr_fd); - - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - stdin_stream - = new BufferedOutputStream(new FileOutputStream(stdin_fd)); - stdout_inner_stream = new DeferredCloseInputStream(stdout_fd); - stdout_stream = new BufferedInputStream(stdout_inner_stream); - stderr_stream = new DeferredCloseInputStream(stderr_fd); - return null; - } - }); - - /* - * For each subprocess forked a corresponding reaper thread - * is started. That thread is the only thread which waits - * for the subprocess to terminate and it doesn't hold any - * locks while doing so. This design allows waitFor() and - * exitStatus() to be safely executed in parallel (and they - * need no native code). - */ - - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - Thread t = new Thread("process reaper") { - public void run() { - int res = waitForProcessExit(pid); - synchronized (UNIXProcess.this) { - hasExited = true; - exitcode = res; - UNIXProcess.this.notifyAll(); - } - } - }; - t.setDaemon(true); - t.start(); - return null; - } - }); + pid = forkAndExec(prog, + argBlock, argc, + envBlock, envc, + dir, + std_fds, + redirectErrorStream); + + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { public Void run() { + if (std_fds[0] == -1) + stdin_stream = new ProcessBuilder.NullOutputStream(); + else { + FileDescriptor stdin_fd = new FileDescriptor(); + fdAccess.set(stdin_fd, std_fds[0]); + stdin_stream = new BufferedOutputStream( + new FileOutputStream(stdin_fd)); + } + + if (std_fds[1] == -1) + stdout_stream = new ProcessBuilder.NullInputStream(); + else { + FileDescriptor stdout_fd = new FileDescriptor(); + fdAccess.set(stdout_fd, std_fds[1]); + stdout_inner_stream = new DeferredCloseInputStream(stdout_fd); + stdout_stream = new BufferedInputStream(stdout_inner_stream); + } + + if (std_fds[2] == -1) + stderr_stream = new ProcessBuilder.NullInputStream(); + else { + FileDescriptor stderr_fd = new FileDescriptor(); + fdAccess.set(stderr_fd, std_fds[2]); + stderr_stream = new DeferredCloseInputStream(stderr_fd); + } + + return null; }}); + + /* + * For each subprocess forked a corresponding reaper thread + * is started. That thread is the only thread which waits + * for the subprocess to terminate and it doesn't hold any + * locks while doing so. This design allows waitFor() and + * exitStatus() to be safely executed in parallel (and they + * need no native code). + */ + + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { public Void run() { + Thread t = new Thread("process reaper") { + public void run() { + int res = waitForProcessExit(pid); + synchronized (UNIXProcess.this) { + hasExited = true; + exitcode = res; + UNIXProcess.this.notifyAll(); + } + } + }; + t.setDaemon(true); + t.start(); + return null; }}); } public OutputStream getOutputStream() { - return stdin_stream; + return stdin_stream; } public InputStream getInputStream() { - return stdout_stream; + return stdout_stream; } public InputStream getErrorStream() { - return stderr_stream; + return stderr_stream; } public synchronized int waitFor() throws InterruptedException { while (!hasExited) { - wait(); - } - return exitcode; + wait(); + } + return exitcode; } public synchronized int exitValue() { - if (!hasExited) { - throw new IllegalThreadStateException("process hasn't exited"); - } - return exitcode; + if (!hasExited) { + throw new IllegalThreadStateException("process hasn't exited"); + } + return exitcode; } private static native void destroyProcess(int pid); public synchronized void destroy() { - // There is a risk that pid will be recycled, causing us to - // kill the wrong process! So we only terminate processes - // that appear to still be running. Even with this check, - // there is an unavoidable race condition here, but the window - // is very small, and OSes try hard to not recycle pids too - // soon, so this is quite safe. - if (!hasExited) - destroyProcess(pid); - try { + // There is a risk that pid will be recycled, causing us to + // kill the wrong process! So we only terminate processes + // that appear to still be running. Even with this check, + // there is an unavoidable race condition here, but the window + // is very small, and OSes try hard to not recycle pids too + // soon, so this is quite safe. + if (!hasExited) + destroyProcess(pid); + try { stdin_stream.close(); - stdout_inner_stream.closeDeferred(stdout_stream); - stderr_stream.closeDeferred(stderr_stream); + if (stdout_inner_stream != null) + stdout_inner_stream.closeDeferred(stdout_stream); + if (stderr_stream instanceof DeferredCloseInputStream) + ((DeferredCloseInputStream) stderr_stream) + .closeDeferred(stderr_stream); } catch (IOException e) { // ignore } @@ -172,99 +198,99 @@ final class UNIXProcess extends Process { // (EOF) as they did before. // private static class DeferredCloseInputStream - extends FileInputStream + extends FileInputStream { - private DeferredCloseInputStream(FileDescriptor fd) { - super(fd); - } - - private Object lock = new Object(); // For the following fields - private boolean closePending = false; - private int useCount = 0; - private InputStream streamToClose; - - private void raise() { - synchronized (lock) { - useCount++; - } - } - - private void lower() throws IOException { - synchronized (lock) { - useCount--; - if (useCount == 0 && closePending) { - streamToClose.close(); - } - } - } - - // stc is the actual stream to be closed; it might be this object, or - // it might be an upstream object for which this object is downstream. - // - private void closeDeferred(InputStream stc) throws IOException { - synchronized (lock) { - if (useCount == 0) { - stc.close(); - } else { - closePending = true; - streamToClose = stc; - } - } - } - - public void close() throws IOException { - synchronized (lock) { - useCount = 0; - closePending = false; - } - super.close(); - } - - public int read() throws IOException { - raise(); - try { - return super.read(); - } finally { - lower(); - } - } - - public int read(byte[] b) throws IOException { - raise(); - try { - return super.read(b); - } finally { - lower(); - } - } - - public int read(byte[] b, int off, int len) throws IOException { - raise(); - try { - return super.read(b, off, len); - } finally { - lower(); - } - } - - public long skip(long n) throws IOException { - raise(); - try { - return super.skip(n); - } finally { - lower(); - } - } - - public int available() throws IOException { - raise(); - try { - return super.available(); - } finally { - lower(); - } - } + private DeferredCloseInputStream(FileDescriptor fd) { + super(fd); + } + + private Object lock = new Object(); // For the following fields + private boolean closePending = false; + private int useCount = 0; + private InputStream streamToClose; + + private void raise() { + synchronized (lock) { + useCount++; + } + } + + private void lower() throws IOException { + synchronized (lock) { + useCount--; + if (useCount == 0 && closePending) { + streamToClose.close(); + } + } + } + + // stc is the actual stream to be closed; it might be this object, or + // it might be an upstream object for which this object is downstream. + // + private void closeDeferred(InputStream stc) throws IOException { + synchronized (lock) { + if (useCount == 0) { + stc.close(); + } else { + closePending = true; + streamToClose = stc; + } + } + } + + public void close() throws IOException { + synchronized (lock) { + useCount = 0; + closePending = false; + } + super.close(); + } + + public int read() throws IOException { + raise(); + try { + return super.read(); + } finally { + lower(); + } + } + + public int read(byte[] b) throws IOException { + raise(); + try { + return super.read(b); + } finally { + lower(); + } + } + + public int read(byte[] b, int off, int len) throws IOException { + raise(); + try { + return super.read(b, off, len); + } finally { + lower(); + } + } + + public long skip(long n) throws IOException { + raise(); + try { + return super.skip(n); + } finally { + lower(); + } + } + + public int available() throws IOException { + raise(); + try { + return super.available(); + } finally { + lower(); + } + } } @@ -272,6 +298,6 @@ final class UNIXProcess extends Process { private static native void initIDs(); static { - initIDs(); + initIDs(); } } diff --git a/src/solaris/classes/java/net/PlainSocketImpl.java b/src/solaris/classes/java/net/PlainSocketImpl.java index 113bcb0183e9177f9ef65b49f04528b4f8271816..25e2bab81f597fb2aac0acd68707e4dcd327a10f 100644 --- a/src/solaris/classes/java/net/PlainSocketImpl.java +++ b/src/solaris/classes/java/net/PlainSocketImpl.java @@ -76,9 +76,6 @@ class PlainSocketImpl extends AbstractPlainSocketImpl native int socketGetOption(int opt, Object iaContainerObj) throws SocketException; - native int socketGetOption1(int opt, Object iaContainerObj, FileDescriptor fd) - throws SocketException; - native void socketSendUrgentData(int data) throws IOException; } diff --git a/src/solaris/classes/java/util/prefs/FileSystemPreferences.java b/src/solaris/classes/java/util/prefs/FileSystemPreferences.java index 4b5b6d20d427e594b8b31bb643c155b95f0feb43..a48dc65fbbb296570b8c919500e9a4938753de54 100644 --- a/src/solaris/classes/java/util/prefs/FileSystemPreferences.java +++ b/src/solaris/classes/java/util/prefs/FileSystemPreferences.java @@ -52,14 +52,10 @@ class FileSystemPreferences extends AbstractPreferences { * Sync interval in seconds. */ private static final int SYNC_INTERVAL = Math.max(1, - Integer.parseInt((String) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty("java.util.prefs.syncInterval", - "30"); - } - }))); - + Integer.parseInt( + AccessController.doPrivileged( + new sun.security.action.GetPropertyAction( + "java.util.prefs.syncInterval", "30")))); /** * Returns logger for error messages. Backing store exceptions are logged at @@ -103,8 +99,8 @@ class FileSystemPreferences extends AbstractPreferences { } private static void setupUserRoot() { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { userRootDir = new File(System.getProperty("java.util.prefs.userRoot", System.getProperty("user.home")), ".java/.userPrefs"); @@ -164,9 +160,9 @@ class FileSystemPreferences extends AbstractPreferences { } private static void setupSystemRoot() { - AccessController.doPrivileged( new PrivilegedAction() { - public Object run() { - String systemPrefsDirName = (String) + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { + String systemPrefsDirName = System.getProperty("java.util.prefs.systemRoot","/etc/.java"); systemRootDir = new File(systemPrefsDirName, ".systemPrefs"); @@ -322,7 +318,7 @@ class FileSystemPreferences extends AbstractPreferences { * corresponding disk file (prefsFile) by the sync operation. The initial * value is read *without* acquiring the file-lock. */ - private Map prefsCache = null; + private Map prefsCache = null; /** * The last modification time of the file backing this node at the time @@ -358,7 +354,7 @@ class FileSystemPreferences extends AbstractPreferences { * log against that map. The resulting map is then written back * to the disk. */ - final List changeLog = new ArrayList(); + final List changeLog = new ArrayList(); /** * Represents a change to a preference. @@ -424,7 +420,7 @@ class FileSystemPreferences extends AbstractPreferences { */ private void replayChanges() { for (int i = 0, n = changeLog.size(); i() { + public Void run() { Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { syncTimer.cancel(); @@ -503,15 +499,15 @@ class FileSystemPreferences extends AbstractPreferences { dir = new File(parent.dir, dirName(name)); prefsFile = new File(dir, "prefs.xml"); tmpFile = new File(dir, "prefs.tmp"); - AccessController.doPrivileged( new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { newNode = !dir.exists(); return null; } }); if (newNode) { // These 2 things guarantee node will get wrtten at next flush/sync - prefsCache = new TreeMap(); + prefsCache = new TreeMap(); nodeCreate = new NodeCreate(); changeLog.add(nodeCreate); } @@ -529,7 +525,7 @@ class FileSystemPreferences extends AbstractPreferences { protected String getSpi(String key) { initCacheIfNecessary(); - return (String) prefsCache.get(key); + return prefsCache.get(key); } protected void removeSpi(String key) { @@ -554,7 +550,7 @@ class FileSystemPreferences extends AbstractPreferences { loadCache(); } catch(Exception e) { // assert lastSyncTime == 0; - prefsCache = new TreeMap(); + prefsCache = new TreeMap(); } } @@ -568,9 +564,10 @@ class FileSystemPreferences extends AbstractPreferences { */ private void loadCache() throws BackingStoreException { try { - AccessController.doPrivileged( new PrivilegedExceptionAction() { - public Object run() throws BackingStoreException { - Map m = new TreeMap(); + AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Void run() throws BackingStoreException { + Map m = new TreeMap(); long newLastSyncTime = 0; try { newLastSyncTime = prefsFile.lastModified(); @@ -584,7 +581,7 @@ class FileSystemPreferences extends AbstractPreferences { prefsFile.renameTo( new File( prefsFile.getParentFile(), "IncorrectFormatPrefs.xml")); - m = new TreeMap(); + m = new TreeMap(); } else if (e instanceof FileNotFoundException) { getLogger().warning("Prefs file removed in background " + prefsFile.getPath()); @@ -614,8 +611,9 @@ class FileSystemPreferences extends AbstractPreferences { */ private void writeBackCache() throws BackingStoreException { try { - AccessController.doPrivileged( new PrivilegedExceptionAction() { - public Object run() throws BackingStoreException { + AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Void run() throws BackingStoreException { try { if (!dir.exists() && !dir.mkdirs()) throw new BackingStoreException(dir + @@ -641,15 +639,14 @@ class FileSystemPreferences extends AbstractPreferences { protected String[] keysSpi() { initCacheIfNecessary(); - return (String[]) - prefsCache.keySet().toArray(new String[prefsCache.size()]); + return prefsCache.keySet().toArray(new String[prefsCache.size()]); } protected String[] childrenNamesSpi() { - return (String[]) - AccessController.doPrivileged( new PrivilegedAction() { - public Object run() { - List result = new ArrayList(); + return AccessController.doPrivileged( + new PrivilegedAction() { + public String[] run() { + List result = new ArrayList(); File[] dirContents = dir.listFiles(); if (dirContents != null) { for (int i = 0; i < dirContents.length; i++) @@ -685,8 +682,9 @@ class FileSystemPreferences extends AbstractPreferences { */ protected void removeNodeSpi() throws BackingStoreException { try { - AccessController.doPrivileged( new PrivilegedExceptionAction() { - public Object run() throws BackingStoreException { + AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Void run() throws BackingStoreException { if (changeLog.contains(nodeCreate)) { changeLog.remove(nodeCreate); nodeCreate = null; @@ -731,8 +729,9 @@ class FileSystemPreferences extends AbstractPreferences { if (!lockFile(shared)) throw(new BackingStoreException("Couldn't get file lock.")); final Long newModTime = - (Long) AccessController.doPrivileged( new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged( + new PrivilegedAction() { + public Long run() { long nmt; if (isUserNode()) { nmt = userRootModFile.lastModified(); @@ -746,8 +745,8 @@ class FileSystemPreferences extends AbstractPreferences { }); try { super.sync(); - AccessController.doPrivileged( new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { if (isUserNode()) { userRootModTime = newModTime.longValue() + 1000; userRootModFile.setLastModified(userRootModTime); @@ -766,8 +765,9 @@ class FileSystemPreferences extends AbstractPreferences { protected void syncSpi() throws BackingStoreException { try { - AccessController.doPrivileged( new PrivilegedExceptionAction() { - public Object run() throws BackingStoreException { + AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Void run() throws BackingStoreException { syncSpiPrivileged(); return null; } @@ -794,7 +794,7 @@ class FileSystemPreferences extends AbstractPreferences { } else if (lastSyncTime != 0 && !dir.exists()) { // This node was removed in the background. Playback any changes // against a virgin (empty) Map. - prefsCache = new TreeMap(); + prefsCache = new TreeMap(); replayChanges(); } if (!changeLog.isEmpty()) { diff --git a/src/solaris/classes/sun/awt/X11/MotifDnDConstants.java b/src/solaris/classes/sun/awt/X11/MotifDnDConstants.java index f9940eefb9330bd2102164c7c7df6eaf3589f4c4..9302361b04dee954a8fbf54a9e4b009fe9e7f6cf 100644 --- a/src/solaris/classes/sun/awt/X11/MotifDnDConstants.java +++ b/src/solaris/classes/sun/awt/X11/MotifDnDConstants.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. 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 @@ -39,6 +39,8 @@ import sun.misc.Unsafe; * @since 1.5 */ class MotifDnDConstants { + // utility class can not be instantiated + private MotifDnDConstants() {} // Note that offsets in all native structures below do not depend on the // architecture. private static final Unsafe unsafe = XlibWrapper.unsafe; @@ -55,8 +57,7 @@ class MotifDnDConstants { XAtom.get("XmTRANSFER_SUCCESS"); static final XAtom XA_XmTRANSFER_FAILURE = XAtom.get("XmTRANSFER_FAILURE"); - static final XSelection MotifDnDSelection = - new XSelection(XA_MOTIF_ATOM_0, null); + static final XSelection MotifDnDSelection = new XSelection(XA_MOTIF_ATOM_0); public static final byte MOTIF_DND_PROTOCOL_VERSION = 0; @@ -231,6 +232,9 @@ class MotifDnDConstants { } public static final class Swapper { + // utility class can not be instantiated + private Swapper() {} + public static short swap(short s) { return (short)(((s & 0xFF00) >>> 8) | ((s & 0xFF) << 8)); } diff --git a/src/solaris/classes/sun/awt/X11/MotifDnDDropTargetProtocol.java b/src/solaris/classes/sun/awt/X11/MotifDnDDropTargetProtocol.java index a67a2f552a05ac63e158ffb645623481c806cf4a..df348594fc560a36833f25557efa5c0f9d73c60c 100644 --- a/src/solaris/classes/sun/awt/X11/MotifDnDDropTargetProtocol.java +++ b/src/solaris/classes/sun/awt/X11/MotifDnDDropTargetProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. 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 @@ -933,7 +933,7 @@ class MotifDnDDropTargetProtocol extends XDropTargetProtocol { XSelection selection = XSelection.getSelection(selectionAtom); if (selection == null) { - selection = new XSelection(selectionAtom, null); + selection = new XSelection(selectionAtom); } return selection.getData(format, time_stamp); @@ -1056,7 +1056,7 @@ class MotifDnDDropTargetProtocol extends XDropTargetProtocol { // the original structure can be freed before this // SunDropTargetEvent is dispatched. if (xclient != null) { - int size = new XClientMessageEvent(nativeCtxt).getSize(); + int size = XClientMessageEvent.getSize(); nativeCtxt = unsafe.allocateMemory(size + 4 * Native.getLongSize()); diff --git a/src/solaris/classes/sun/awt/X11/OwnershipListener.java b/src/solaris/classes/sun/awt/X11/OwnershipListener.java new file mode 100644 index 0000000000000000000000000000000000000000..482b9cc7597893c5d251816ce636fee3f6101940 --- /dev/null +++ b/src/solaris/classes/sun/awt/X11/OwnershipListener.java @@ -0,0 +1,30 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.awt.X11; + +interface OwnershipListener { + public void ownershipChanged(final boolean isOwner); +} diff --git a/src/solaris/classes/sun/awt/X11/XAtom.java b/src/solaris/classes/sun/awt/X11/XAtom.java index b98fc9b8ee968a3d592f29e730f6ca4aabd176c4..b72e790a043e15e1e2f71d0fc4287131514af125 100644 --- a/src/solaris/classes/sun/awt/X11/XAtom.java +++ b/src/solaris/classes/sun/awt/X11/XAtom.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. 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 @@ -58,7 +58,7 @@ package sun.awt.X11; import sun.misc.Unsafe; import java.util.HashMap; -public class XAtom { +public final class XAtom { // Order of lock: XAWTLock -> XAtom.class @@ -175,7 +175,7 @@ public class XAtom { public static XAtom get(String name) { XAtom xatom = lookup(name); if (xatom == null) { - xatom = new XAtom(name); + xatom = new XAtom(XToolkit.getDisplay(), name); } return xatom; } @@ -232,10 +232,6 @@ public class XAtom { this(display, name, true); } - private XAtom(String name) { - this(XToolkit.getDisplay(), name, true); - } - public XAtom(String name, boolean autoIntern) { this(XToolkit.getDisplay(), name, autoIntern); } @@ -262,7 +258,7 @@ public class XAtom { * @since 1.5 */ - public XAtom(long display, String name, boolean autoIntern) { + private XAtom(long display, String name, boolean autoIntern) { this.name = name; this.display = display; if (autoIntern) { @@ -651,28 +647,6 @@ public class XAtom { } } - /** - * Initializes atom with name and display values - */ - public void setValues(long display, String name, boolean autoIntern) { - this.display = display; - this.name = name; - if (autoIntern) { - XToolkit.awtLock(); - try { - atom = XlibWrapper.InternAtom(display,name,0); - } finally { - XToolkit.awtUnlock(); - } - } - register(); - } - - public void setValues(long display, long atom) { - this.display = display; - this.atom = atom; - register(); - } public void setValues(long display, String name, long atom) { this.display = display; this.atom = atom; diff --git a/src/solaris/classes/sun/awt/X11/XClipboard.java b/src/solaris/classes/sun/awt/X11/XClipboard.java index 5a7faef354758f51e6c4022201370a08d1fc200f..138e11d9a8c7402b33849933187657ad9a349a50 100644 --- a/src/solaris/classes/sun/awt/X11/XClipboard.java +++ b/src/solaris/classes/sun/awt/X11/XClipboard.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. 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 @@ -26,30 +26,32 @@ package sun.awt.X11; import java.awt.datatransfer.Transferable; - import java.util.SortedMap; -import java.util.Set; -import java.util.Iterator; -import java.util.HashSet; - import java.io.IOException; - import java.security.AccessController; - +import java.util.HashMap; +import java.util.Map; +import sun.awt.UNIXToolkit; import sun.awt.datatransfer.DataTransferer; import sun.awt.datatransfer.SunClipboard; import sun.awt.datatransfer.ClipboardTransferable; - import sun.security.action.GetIntegerAction; - - /** * A class which interfaces with the X11 selection service in order to support * data transfer via Clipboard operations. */ -public class XClipboard extends SunClipboard implements Runnable { +public final class XClipboard extends SunClipboard implements OwnershipListener +{ private final XSelection selection; + // Time of calling XConvertSelection(). + private long convertSelectionTime; + // The flag used not to call XConvertSelection() if the previous SelectionNotify + // has not been processed by checkChange(). + private volatile boolean isSelectionNotifyProcessed; + // The property in which the owner should place requested targets + // when tracking changes of available data flavors (practically targets). + private volatile XAtom targetsPropertyAtom; private static final Object classLock = new Object(); @@ -57,31 +59,33 @@ public class XClipboard extends SunClipboard implements Runnable { private static int pollInterval; - private static Set listenedClipboards; - + private static Map targetsAtom2Clipboard; /** * Creates a system clipboard object. */ public XClipboard(String name, String selectionName) { super(name); - selection = new XSelection(XAtom.get(selectionName), this); + selection = new XSelection(XAtom.get(selectionName)); + selection.registerOwershipListener(this); } - /** - * The action to be run when we lose ownership + /* * NOTE: This method may be called by privileged threads. * DO NOT INVOKE CLIENT CODE ON THIS THREAD! */ - public void run() { - lostOwnershipImpl(); + public void ownershipChanged(final boolean isOwner) { + if (isOwner) { + checkChangeHere(contents); + } else { + lostOwnershipImpl(); + } } protected synchronized void setContentsNative(Transferable contents) { SortedMap formatMap = DataTransferer.getInstance().getFormatsForTransferable (contents, DataTransferer.adaptFlavorMap(flavorMap)); - long[] formats = - DataTransferer.getInstance().keysToLongArray(formatMap); + long[] formats = DataTransferer.keysToLongArray(formatMap); if (!selection.setOwner(contents, formatMap, formats, XToolkit.getCurrentServerTime())) { @@ -94,6 +98,7 @@ public class XClipboard extends SunClipboard implements Runnable { return selection.getSelectionAtom().getAtom(); } + @Override public synchronized Transferable getContents(Object requestor) { if (contents != null) { return contents; @@ -115,62 +120,163 @@ public class XClipboard extends SunClipboard implements Runnable { return selection.getData(format, XToolkit.getCurrentServerTime()); } - // Called on the toolkit thread under awtLock. - public void checkChange(long[] formats) { - if (!selection.isOwner()) { - super.checkChange(formats); - } - } - - void checkChangeHere(Transferable contents) { + private void checkChangeHere(Transferable contents) { if (areFlavorListenersRegistered()) { - super.checkChange(DataTransferer.getInstance(). + checkChange(DataTransferer.getInstance(). getFormatsForTransferableAsArray(contents, flavorMap)); } } - protected void registerClipboardViewerChecked() { - if (pollInterval <= 0) { - pollInterval = ((Integer)AccessController.doPrivileged( - new GetIntegerAction("awt.datatransfer.clipboard.poll.interval", - defaultPollInterval))).intValue(); + private static int getPollInterval() { + synchronized (XClipboard.classLock) { if (pollInterval <= 0) { - pollInterval = defaultPollInterval; + pollInterval = AccessController.doPrivileged( + new GetIntegerAction("awt.datatransfer.clipboard.poll.interval", + defaultPollInterval)); + if (pollInterval <= 0) { + pollInterval = defaultPollInterval; + } } + return pollInterval; + } + } + + private XAtom getTargetsPropertyAtom() { + if (null == targetsPropertyAtom) { + targetsPropertyAtom = + XAtom.get("XAWT_TARGETS_OF_SELECTION:" + selection.getSelectionAtom().getName()); } - selection.initializeSelectionForTrackingChanges(); + return targetsPropertyAtom; + } + + protected void registerClipboardViewerChecked() { + // for XConvertSelection() to be called for the first time in getTargetsDelayed() + isSelectionNotifyProcessed = true; + boolean mustSchedule = false; synchronized (XClipboard.classLock) { - if (listenedClipboards == null) { - listenedClipboards = new HashSet(2); + if (targetsAtom2Clipboard == null) { + targetsAtom2Clipboard = new HashMap(2); + } + mustSchedule = targetsAtom2Clipboard.isEmpty(); + targetsAtom2Clipboard.put(getTargetsPropertyAtom().getAtom(), this); + if (mustSchedule) { + XToolkit.addEventDispatcher(XWindow.getXAWTRootWindow().getWindow(), + new SelectionNotifyHandler()); } - mustSchedule = listenedClipboards.isEmpty(); - listenedClipboards.add(this); } if (mustSchedule) { - XToolkit.schedule(new CheckChangeTimerTask(), pollInterval); + XToolkit.schedule(new CheckChangeTimerTask(), XClipboard.getPollInterval()); } } private static class CheckChangeTimerTask implements Runnable { public void run() { - for (Iterator iter = listenedClipboards.iterator(); iter.hasNext();) { - XClipboard clpbrd = (XClipboard)iter.next(); - clpbrd.selection.getTargetsDelayed(); + for (XClipboard clpbrd : targetsAtom2Clipboard.values()) { + clpbrd.getTargetsDelayed(); } synchronized (XClipboard.classLock) { - if (listenedClipboards != null && !listenedClipboards.isEmpty()) { - XToolkit.schedule(this, pollInterval); + if (targetsAtom2Clipboard != null && !targetsAtom2Clipboard.isEmpty()) { + XToolkit.schedule(this, XClipboard.getPollInterval()); + } + } + } + } + + private static class SelectionNotifyHandler implements XEventDispatcher { + public void dispatchEvent(XEvent ev) { + if (ev.get_type() == XlibWrapper.SelectionNotify) { + final XSelectionEvent xse = ev.get_xselection(); + XClipboard clipboard = null; + synchronized (XClipboard.classLock) { + if (targetsAtom2Clipboard != null && !targetsAtom2Clipboard.isEmpty()) { + XToolkit.removeEventDispatcher(XWindow.getXAWTRootWindow().getWindow(), this); + return; + } + final long propertyAtom = xse.get_property(); + clipboard = targetsAtom2Clipboard.get(propertyAtom); + } + if (null != clipboard) { + clipboard.checkChange(xse); } } } } protected void unregisterClipboardViewerChecked() { - selection.deinitializeSelectionForTrackingChanges(); + isSelectionNotifyProcessed = false; synchronized (XClipboard.classLock) { - listenedClipboards.remove(this); + targetsAtom2Clipboard.remove(getTargetsPropertyAtom().getAtom()); } } + // checkChange() will be called on SelectionNotify + private void getTargetsDelayed() { + XToolkit.awtLock(); + try { + long curTime = System.currentTimeMillis(); + if (isSelectionNotifyProcessed || curTime >= (convertSelectionTime + UNIXToolkit.getDatatransferTimeout())) + { + convertSelectionTime = curTime; + XlibWrapper.XConvertSelection(XToolkit.getDisplay(), + selection.getSelectionAtom().getAtom(), + XDataTransferer.TARGETS_ATOM.getAtom(), + getTargetsPropertyAtom().getAtom(), + XWindow.getXAWTRootWindow().getWindow(), + XlibWrapper.CurrentTime); + isSelectionNotifyProcessed = false; + } + } finally { + XToolkit.awtUnlock(); + } + } + + /* + * Tracks changes of available formats. + * NOTE: This method may be called by privileged threads. + * DO NOT INVOKE CLIENT CODE ON THIS THREAD! + */ + private void checkChange(XSelectionEvent xse) { + final long propertyAtom = xse.get_property(); + if (propertyAtom != getTargetsPropertyAtom().getAtom()) { + // wrong atom + return; + } + + final XAtom selectionAtom = XAtom.get(xse.get_selection()); + final XSelection changedSelection = XSelection.getSelection(selectionAtom); + + if (null == changedSelection || changedSelection != selection) { + // unknown selection - do nothing + return; + } + + isSelectionNotifyProcessed = true; + + if (selection.isOwner()) { + // selection is owner - do not need formats + return; + } + + long[] formats = null; + + if (propertyAtom == XlibWrapper.None) { + // We treat None property atom as "empty selection". + formats = new long[0]; + } else { + WindowPropertyGetter targetsGetter = + new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(), + XAtom.get(propertyAtom), 0, + XSelection.MAX_LENGTH, true, + XlibWrapper.AnyPropertyType); + try { + targetsGetter.execute(); + formats = XSelection.getFormats(targetsGetter); + } finally { + targetsGetter.dispose(); + } + } + + checkChange(formats); + } } diff --git a/src/solaris/classes/sun/awt/X11/XComponentPeer.java b/src/solaris/classes/sun/awt/X11/XComponentPeer.java index 4657f75c49b06f9a1d52f3539cbbc05d835275ab..fb687e368307ca46a52ba619bea435498a4d9d10 100644 --- a/src/solaris/classes/sun/awt/X11/XComponentPeer.java +++ b/src/solaris/classes/sun/awt/X11/XComponentPeer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. 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 @@ -31,17 +31,13 @@ import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Cursor; -import java.awt.DefaultKeyboardFocusManager; import java.awt.Dimension; -import java.awt.Event; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Image; import java.awt.Insets; import java.awt.KeyboardFocusManager; -import java.awt.MenuBar; -import java.awt.Point; import java.awt.Rectangle; import java.awt.SystemColor; import java.awt.Toolkit; @@ -60,12 +56,9 @@ import java.awt.event.InvocationEvent; import java.awt.image.ImageObserver; import java.awt.image.ImageProducer; import java.awt.image.VolatileImage; -import java.awt.peer.CanvasPeer; import java.awt.peer.ComponentPeer; import java.awt.peer.ContainerPeer; import java.awt.peer.LightweightPeer; -import java.awt.peer.PanelPeer; -import java.awt.peer.WindowPeer; import java.lang.reflect.*; import java.security.*; import java.util.Collection; @@ -821,7 +814,7 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget public void setFont(Font f) { synchronized (getStateLock()) { if (f == null) { - f = defaultFont; + f = XWindow.getDefaultFont(); } font = f; } diff --git a/src/solaris/classes/sun/awt/X11/XContentWindow.java b/src/solaris/classes/sun/awt/X11/XContentWindow.java index 72737df0691720b6932367e8d33c733c44180f3b..268f7f5d151be251289fd87ab36d06a0947f7b60 100644 --- a/src/solaris/classes/sun/awt/X11/XContentWindow.java +++ b/src/solaris/classes/sun/awt/X11/XContentWindow.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. 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 @@ -39,16 +39,37 @@ import sun.awt.ComponentAccessor; * This class implements window which serves as content window for decorated frames. * Its purpose to provide correct events dispatching for the complex * constructs such as decorated frames. + * + * It should always be located at (- left inset, - top inset) in the associated + * decorated window. So coordinates in it would be the same as java coordinates. */ -public class XContentWindow extends XWindow implements XConstants { +public final class XContentWindow extends XWindow implements XConstants { private static Logger insLog = Logger.getLogger("sun.awt.X11.insets.XContentWindow"); - XDecoratedPeer parentFrame; + static XContentWindow createContent(XDecoratedPeer parentFrame) { + final WindowDimensions dims = parentFrame.getDimensions(); + Rectangle rec = dims.getBounds(); + // Fix for - set the location of the content window to the (-left inset, -top inset) + Insets ins = dims.getInsets(); + if (ins != null) { + rec.x = -ins.left; + rec.y = -ins.top; + } else { + rec.x = 0; + rec.y = 0; + } + final XContentWindow cw = new XContentWindow(parentFrame, rec); + cw.xSetVisible(true); + return cw; + } + + private final XDecoratedPeer parentFrame; // A list of expose events that come when the parentFrame is iconified - private java.util.List iconifiedExposeEvents = new java.util.ArrayList(); + private final java.util.List iconifiedExposeEvents = + new java.util.ArrayList(); - XContentWindow(XDecoratedPeer parentFrame, Rectangle bounds) { + private XContentWindow(XDecoratedPeer parentFrame, Rectangle bounds) { super((Component)parentFrame.getTarget(), parentFrame.getShell(), bounds); this.parentFrame = parentFrame; } @@ -63,9 +84,6 @@ public class XContentWindow extends XWindow implements XConstants { } } - void initialize() { - xSetVisible(true); - } protected String getWMName() { return "Content window"; } diff --git a/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java b/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java index a6b8c36f8f67962543f463a7bedd8eefd7494514..8aa3085282f4ca107f6ca06c7be2bbd56ad3d59f 100644 --- a/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java +++ b/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java @@ -36,7 +36,7 @@ import java.util.logging.Logger; import sun.awt.ComponentAccessor; import sun.awt.SunToolkit; -class XDecoratedPeer extends XWindowPeer { +abstract class XDecoratedPeer extends XWindowPeer { private static final Logger log = Logger.getLogger("sun.awt.X11.XDecoratedPeer"); private static final Logger insLog = Logger.getLogger("sun.awt.X11.insets.XDecoratedPeer"); private static final Logger focusLog = Logger.getLogger("sun.awt.X11.focus.XDecoratedPeer"); @@ -98,8 +98,7 @@ class XDecoratedPeer extends XWindowPeer { // happen after the X window is created. initResizability(); updateSizeHints(dimensions); - content = createContent(dimensions); - content.initialize(); + content = XContentWindow.createContent(this); if (warningWindow != null) { warningWindow.toFront(); } @@ -160,20 +159,6 @@ class XDecoratedPeer extends XWindowPeer { } } - XContentWindow createContent(WindowDimensions dims) { - Rectangle rec = dims.getBounds(); - // Fix for - set the location of the content window to the (-left inset, -top inset) - Insets ins = dims.getInsets(); - if (ins != null) { - rec.x = -ins.left; - rec.y = -ins.top; - } else { - rec.x = 0; - rec.y = 0; - } - return new XContentWindow(this, rec); - } - XFocusProxyWindow createFocusProxy() { return new XFocusProxyWindow(this); } @@ -286,7 +271,7 @@ class XDecoratedPeer extends XWindowPeer { return; } Component t = (Component)target; - if (getDecorations() == winAttr.AWT_DECOR_NONE) { + if (getDecorations() == XWindowAttributesData.AWT_DECOR_NONE) { setReparented(true); insets_corrected = true; reshape(dimensions, SET_SIZE, false); @@ -471,6 +456,15 @@ class XDecoratedPeer extends XWindowPeer { if (insLog.isLoggable(Level.FINE)) { insLog.fine("Reshaping " + this + " to " + newDimensions + " op " + op + " user reshape " + userReshape); } + if (userReshape) { + // We handle only userReshape == true cases. It means that + // if the window manager or any other part of the windowing + // system sets inappropriate size for this window, we can + // do nothing but accept it. + Rectangle reqBounds = newDimensions.getBounds(); + Rectangle newBounds = constrainBounds(reqBounds.x, reqBounds.y, reqBounds.width, reqBounds.height); + newDimensions = new WindowDimensions(newBounds, newDimensions.getInsets(), newDimensions.isClientSizeSet()); + } XToolkit.awtLock(); try { if (!isReparented() || !isVisible()) { @@ -586,6 +580,49 @@ class XDecoratedPeer extends XWindowPeer { reshape(dims, operation, userReshape); } + // This method gets overriden in XFramePeer & XDialogPeer. + abstract boolean isTargetUndecorated(); + + @Override + Rectangle constrainBounds(int x, int y, int width, int height) { + // We don't restrict the setBounds() operation if the code is trusted. + if (!hasWarningWindow()) { + return new Rectangle(x, y, width, height); + } + + // If it's undecorated or is not currently visible, + // apply the same constraints as for the Window. + if (!isVisible() || isTargetUndecorated()) { + return super.constrainBounds(x, y, width, height); + } + + // If it's visible & decorated, constraint the size only + int newX = x; + int newY = y; + int newW = width; + int newH = height; + + GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration(); + Rectangle sB = gc.getBounds(); + Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc); + + Rectangle curBounds = getBounds(); + + int maxW = Math.max(sB.width - sIn.left - sIn.right, curBounds.width); + int maxH = Math.max(sB.height - sIn.top - sIn.bottom, curBounds.height); + + // First make sure the size is withing the visible part of the screen + if (newW > maxW) { + newW = maxW; + } + + if (newH > maxH) { + newH = maxH; + } + + return new Rectangle(newX, newY, newW, newH); + } + /** * @see java.awt.peer.ComponentPeer#setBounds */ @@ -651,12 +688,12 @@ class XDecoratedPeer extends XWindowPeer { } if (!isReparented() && isVisible() && runningWM != XWM.NO_WM && !XWM.isNonReparentingWM() - && getDecorations() != winAttr.AWT_DECOR_NONE) { + && getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) { insLog.fine("- visible but not reparented, skipping"); return; } //Last chance to correct insets - if (!insets_corrected && getDecorations() != winAttr.AWT_DECOR_NONE) { + if (!insets_corrected && getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) { long parent = XlibUtil.getParentWindow(window); Insets correctWM = (parent != -1) ? XWM.getWM().getInsets(this, window, parent) : null; if (insLog.isLoggable(Level.FINER)) { @@ -824,7 +861,7 @@ class XDecoratedPeer extends XWindowPeer { fs &= ~(MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE); } winAttr.functions = fs; - XWM.setShellNotResizable(this, dimensions, dimensions.getScreenBounds(), false); + XWM.setShellNotResizable(this, dimensions, dimensions.getBounds(), false); } } @@ -870,7 +907,7 @@ class XDecoratedPeer extends XWindowPeer { return getSize().height; } - public WindowDimensions getDimensions() { + final public WindowDimensions getDimensions() { return dimensions; } diff --git a/src/solaris/classes/sun/awt/X11/XDialogPeer.java b/src/solaris/classes/sun/awt/X11/XDialogPeer.java index 248e6f8e60ceb21b2689b7c0de9ec3b4f349c417..40822e2c27da2e31e3fb2dcc31116ae8fcfed389 100644 --- a/src/solaris/classes/sun/awt/X11/XDialogPeer.java +++ b/src/solaris/classes/sun/awt/X11/XDialogPeer.java @@ -88,7 +88,8 @@ class XDialogPeer extends XDecoratedPeer implements DialogPeer { } } - private boolean isTargetUndecorated() { + @Override + boolean isTargetUndecorated() { if (undecorated != null) { return undecorated.booleanValue(); } else { diff --git a/src/solaris/classes/sun/awt/X11/XDnDConstants.java b/src/solaris/classes/sun/awt/X11/XDnDConstants.java index 7974d12960d8284ce0d7ebdf719f4376a0d3c785..26967f76995e545059aa993cb0a0d2cdb6d14ce4 100644 --- a/src/solaris/classes/sun/awt/X11/XDnDConstants.java +++ b/src/solaris/classes/sun/awt/X11/XDnDConstants.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. 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 @@ -48,8 +48,7 @@ class XDnDConstants { static final XAtom XA_XdndStatus = XAtom.get("XdndStatus"); static final XAtom XA_XdndFinished = XAtom.get("XdndFinished"); - static final XSelection XDnDSelection = - new XSelection(XA_XdndSelection, null); + static final XSelection XDnDSelection = new XSelection(XA_XdndSelection); public static final int XDND_MIN_PROTOCOL_VERSION = 3; public static final int XDND_PROTOCOL_VERSION = 5; diff --git a/src/solaris/classes/sun/awt/X11/XEmbedCanvasPeer.java b/src/solaris/classes/sun/awt/X11/XEmbedCanvasPeer.java index 14cedf1fffa87bcd5119b6c63bf3e14c33ade963..10b71a453b4605e79c406ab0e6ba990569d1cac2 100644 --- a/src/solaris/classes/sun/awt/X11/XEmbedCanvasPeer.java +++ b/src/solaris/classes/sun/awt/X11/XEmbedCanvasPeer.java @@ -647,12 +647,6 @@ public class XEmbedCanvasPeer extends XCanvasPeer implements WindowFocusListener } if (isXEmbedActive()) { switch ((int)msg.get_data(1)) { - case _SUN_XEMBED_START: - // Child has finished initialization and waits for notify - xembed.processXEmbedInfo(); - - notifyChildEmbedded(); - break; case XEMBED_REQUEST_FOCUS: requestXEmbedFocus(); break; diff --git a/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java b/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java index 582c2f05578fd9e4a4e87be1e0e8050e17182600..c56883e46af958977832e9687761274ad7f2a8f8 100644 --- a/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java +++ b/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java @@ -74,7 +74,6 @@ public class XEmbedClientHelper extends XEmbedHelper implements XEventDispatcher XToolkit.awtUnlock(); } } - notifyReady(); } void handleClientMessage(XEvent xev) { @@ -84,7 +83,6 @@ public class XEmbedClientHelper extends XEmbedHelper implements XEventDispatcher if (xembedLog.isLoggable(Level.FINE)) xembedLog.fine("Embedded message: " + msgidToString((int)msg.get_data(1))); switch ((int)msg.get_data(1)) { case XEMBED_EMBEDDED_NOTIFY: // Notification about embedding protocol start - // NOTE: May be called two times because we send _SUN_XEMBED_START active = true; server = getEmbedder(embedded, msg); // Check if window is reparented. If not - it was created with @@ -223,13 +221,4 @@ public class XEmbedClientHelper extends XEmbedHelper implements XEventDispatcher long getX11Mods(AWTKeyStroke stroke) { return XWindow.getXModifiers(stroke); } - - void notifyReady() { - long wnd = server; - if (wnd == 0) { - // Server is still 0, get the parent - wnd = embedded.getParentWindowHandle(); - } - sendMessage(wnd, _SUN_XEMBED_START); - } } diff --git a/src/solaris/classes/sun/awt/X11/XEmbedHelper.java b/src/solaris/classes/sun/awt/X11/XEmbedHelper.java index ae2fc8507a64992f603bc7432c5eafaffbd9050f..aab7855200736d3af21095d3a620a9d2ce94e9c4 100644 --- a/src/solaris/classes/sun/awt/X11/XEmbedHelper.java +++ b/src/solaris/classes/sun/awt/X11/XEmbedHelper.java @@ -58,7 +58,6 @@ public class XEmbedHelper { final static int XEMBED_REGISTER_ACCELERATOR = 12; final static int XEMBED_UNREGISTER_ACCELERATOR= 13; final static int XEMBED_ACTIVATE_ACCELERATOR = 14; - final static int _SUN_XEMBED_START = 1119; final static int NON_STANDARD_XEMBED_GTK_GRAB_KEY = 108; final static int NON_STANDARD_XEMBED_GTK_UNGRAB_KEY = 109; @@ -151,8 +150,6 @@ public class XEmbedHelper { return "NON_STANDARD_XEMBED_GTK_UNGRAB_KEY"; case NON_STANDARD_XEMBED_GTK_GRAB_KEY: return "NON_STANDARD_XEMBED_GTK_GRAB_KEY"; - case _SUN_XEMBED_START: - return "XEMBED_START"; case XConstants.KeyPress | XEmbedServerTester.SYSTEM_EVENT_MASK: return "KeyPress"; case XConstants.MapNotify | XEmbedServerTester.SYSTEM_EVENT_MASK: diff --git a/src/solaris/classes/sun/awt/X11/XEmbedServerTester.java b/src/solaris/classes/sun/awt/X11/XEmbedServerTester.java index 5fab6876a5e5774569eb85c1d0c988084e96cf06..a5ce2df74049862b3bcb21b9cda47808edd721b8 100644 --- a/src/solaris/classes/sun/awt/X11/XEmbedServerTester.java +++ b/src/solaris/classes/sun/awt/X11/XEmbedServerTester.java @@ -177,13 +177,6 @@ public class XEmbedServerTester implements XEventDispatcher { embedCompletely(); } - public void test3_2() { - embedCompletely(); - int res = getEventPos(); - sendMessage(XEmbedHelper._SUN_XEMBED_START); - waitEmbeddedNotify(res); - } - public void test3_3() { reparent = true; embedCompletely(); diff --git a/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java b/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java index d33e545e27920c3b9f2e50971da9f1afd9e5e16c..b0cb3aa6d074fb25b2f64a5284ca50a419ca9122 100644 --- a/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java +++ b/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java @@ -184,6 +184,12 @@ public class XEmbeddedFramePeer extends XFramePeer { } } + @Override + Rectangle constrainBounds(int x, int y, int width, int height) { + // We don't constrain the bounds of the EmbeddedFrames + return new Rectangle(x, y, width, height); + } + // don't use getBounds() inherited from XDecoratedPeer public Rectangle getBounds() { return new Rectangle(x, y, width, height); diff --git a/src/solaris/classes/sun/awt/X11/XFramePeer.java b/src/solaris/classes/sun/awt/X11/XFramePeer.java index 84469bd649fc32aac2070b775f289d0b816ffd8a..28989acc60937a83ab3e3f01f31b303c1a48caa0 100644 --- a/src/solaris/classes/sun/awt/X11/XFramePeer.java +++ b/src/solaris/classes/sun/awt/X11/XFramePeer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. 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 @@ -24,15 +24,18 @@ */ package sun.awt.X11; -import java.util.Vector; -import java.awt.*; -import java.awt.peer.*; -import java.awt.event.*; -import sun.awt.im.*; -import sun.awt.*; -import java.util.logging.*; -import java.lang.reflect.Field; -import java.util.*; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.MenuBar; +import java.awt.Rectangle; +import java.awt.peer.FramePeer; +import java.util.logging.Level; +import java.util.logging.Logger; class XFramePeer extends XDecoratedPeer implements FramePeer, XConstants { private static Logger log = Logger.getLogger("sun.awt.X11.XFramePeer"); @@ -92,7 +95,8 @@ class XFramePeer extends XDecoratedPeer implements FramePeer, XConstants { } } - private boolean isTargetUndecorated() { + @Override + boolean isTargetUndecorated() { if (undecorated != null) { return undecorated.booleanValue(); } else { @@ -285,19 +289,20 @@ class XFramePeer extends XDecoratedPeer implements FramePeer, XConstants { * Let's see if this is a window state protocol message, and * if it is - decode a new state in terms of java constants. */ - Integer newState = XWM.getWM().isStateChange(this, ev); - if (newState == null) { + if (!XWM.getWM().isStateChange(this, ev)) { + stateLog.finer("either not a state atom or state has not been changed"); return; } - int changed = state ^ newState.intValue(); + final int newState = XWM.getWM().getState(this); + int changed = state ^ newState; if (changed == 0) { stateLog.finer("State is the same: " + state); return; } int old_state = state; - state = newState.intValue(); + state = newState; if ((changed & Frame.ICONIFIED) != 0) { if ((state & Frame.ICONIFIED) != 0) { diff --git a/src/solaris/classes/sun/awt/X11/XMenuItemPeer.java b/src/solaris/classes/sun/awt/X11/XMenuItemPeer.java index c679dbecd5d2b395fd1b66b9f2adbf1cb0d4d438..ec80cebcec1b171f7ab7e5ae976b16531a23f7c6 100644 --- a/src/solaris/classes/sun/awt/X11/XMenuItemPeer.java +++ b/src/solaris/classes/sun/awt/X11/XMenuItemPeer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. 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 @@ -218,7 +218,7 @@ public class XMenuItemPeer implements MenuItemPeer { Font getTargetFont() { if (target == null) { - return XWindow.defaultFont; + return XWindow.getDefaultFont(); } try { return (Font)m_getFont.invoke(target, new Object[0]); @@ -227,7 +227,7 @@ public class XMenuItemPeer implements MenuItemPeer { } catch (InvocationTargetException e) { e.printStackTrace(); } - return XWindow.defaultFont; + return XWindow.getDefaultFont(); } String getTargetLabel() { diff --git a/src/solaris/classes/sun/awt/X11/XNETProtocol.java b/src/solaris/classes/sun/awt/X11/XNETProtocol.java index 8ae5334cba3b0295aa7a763c19a55d6dcec5e740..f61c476e57eceb013bb4f4e028f99be15c5976e9 100644 --- a/src/solaris/classes/sun/awt/X11/XNETProtocol.java +++ b/src/solaris/classes/sun/awt/X11/XNETProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. 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 @@ -26,17 +26,15 @@ package sun.awt.X11; -import java.awt.*; +import java.awt.Frame; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.logging.LogManager; -import java.awt.*; -import java.awt.image.*; -import java.util.*; -class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProtocol { - final static Logger log = Logger.getLogger("sun.awt.X11.XNETProtocol"); +final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProtocol +{ + private final static Logger log = Logger.getLogger("sun.awt.X11.XNETProtocol"); private final static Logger iconLog = Logger.getLogger("sun.awt.X11.icon.XNETProtocol"); + private static Logger stateLog = Logger.getLogger("sun.awt.X11.states.XNETProtocol"); /** * XStateProtocol @@ -276,6 +274,7 @@ class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProtocol { boolean doStateProtocol() { boolean res = active() && checkProtocol(XA_NET_SUPPORTED, XA_NET_WM_STATE); + stateLog.finer("doStateProtocol() returns " + res); return res; } diff --git a/src/solaris/classes/sun/awt/X11/XPopupMenuPeer.java b/src/solaris/classes/sun/awt/X11/XPopupMenuPeer.java index 8523bd7fffad72e235017f47c6e90acead152741..55fcfb5743f13256e102a14ea101fe618e172c01 100644 --- a/src/solaris/classes/sun/awt/X11/XPopupMenuPeer.java +++ b/src/solaris/classes/sun/awt/X11/XPopupMenuPeer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. 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 @@ -187,7 +187,7 @@ public class XPopupMenuPeer extends XMenuWindow implements PopupMenuPeer { //Fix for 6267144: PIT: Popup menu label is not shown, XToolkit Font getTargetFont() { if (popupMenuTarget == null) { - return XWindow.defaultFont; + return XWindow.getDefaultFont(); } try { return (Font)m_getFont.invoke(popupMenuTarget, new Object[0]); @@ -196,7 +196,7 @@ public class XPopupMenuPeer extends XMenuWindow implements PopupMenuPeer { } catch (InvocationTargetException e) { e.printStackTrace(); } - return XWindow.defaultFont; + return XWindow.getDefaultFont(); } String getTargetLabel() { diff --git a/src/solaris/classes/sun/awt/X11/XSelection.java b/src/solaris/classes/sun/awt/X11/XSelection.java index 9759a8175ca49c79ff6dcd6853ef9b5fee53aa08..b472bec7646ff2ae1506c60a30eefa8d0d0e9865 100644 --- a/src/solaris/classes/sun/awt/X11/XSelection.java +++ b/src/solaris/classes/sun/awt/X11/XSelection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. 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 @@ -32,9 +32,6 @@ import java.io.IOException; import java.util.Hashtable; import java.util.Map; -import java.util.Set; -import java.util.HashSet; -import java.util.Collections; import sun.awt.AppContext; import sun.awt.SunToolkit; @@ -45,7 +42,7 @@ import sun.awt.datatransfer.DataTransferer; /** * A class which interfaces with the X11 selection service. */ -public class XSelection { +public final class XSelection { /* Maps atoms to XSelection instances. */ private static final Hashtable table = new Hashtable(); @@ -69,8 +66,6 @@ public class XSelection { XToolkit.awtUnlock(); } } - /* The selection timeout. */ - private static long SELECTION_TIMEOUT = UNIXToolkit.getDatatransferTimeout(); /* The PropertyNotify event handler for incremental data transfer. */ private static final XEventDispatcher incrementalTransferHandler = @@ -84,11 +79,6 @@ public class XSelection { /* The X atom for the underlying selection. */ private final XAtom selectionAtom; - /* - * XClipboard.run() is to be called when we lose ownership. - * XClipbioard.checkChange() is to be called when tracking changes of flavors. - */ - private final XClipboard clipboard; /* * Owner-related variables - protected with synchronized (this). @@ -109,17 +99,8 @@ public class XSelection { private long ownershipTime = 0; // True if we are the owner of this selection. private boolean isOwner; - // The property in which the owner should place requested targets - // when tracking changes of available data flavors (practically targets). - private volatile XAtom targetsPropertyAtom; - // A set of these property atoms. - private static volatile Set targetsPropertyAtoms; - // The flag used not to call XConvertSelection() if the previous SelectionNotify - // has not been processed by checkChange(). - private volatile boolean isSelectionNotifyProcessed; - // Time of calling XConvertSelection(). - private long convertSelectionTime; - + private OwnershipListener ownershipListener = null; + private final Object stateLock = new Object(); static { XToolkit.addEventDispatcher(XWindow.getXAWTRootWindow().getWindow(), @@ -141,12 +122,11 @@ public class XSelection { * @param clpbrd the corresponding clipoboard * @exception NullPointerException if atom is null. */ - public XSelection(XAtom atom, XClipboard clpbrd) { + public XSelection(XAtom atom) { if (atom == null) { throw new NullPointerException("Null atom"); } selectionAtom = atom; - clipboard = clpbrd; table.put(selectionAtom, this); } @@ -154,25 +134,9 @@ public class XSelection { return selectionAtom; } - void initializeSelectionForTrackingChanges() { - targetsPropertyAtom = XAtom.get("XAWT_TARGETS_OF_SELECTION:" + selectionAtom.getName()); - if (targetsPropertyAtoms == null) { - targetsPropertyAtoms = Collections.synchronizedSet(new HashSet(2)); - } - targetsPropertyAtoms.add(Long.valueOf(targetsPropertyAtom.getAtom())); - // for XConvertSelection() to be called for the first time in getTargetsDelayed() - isSelectionNotifyProcessed = true; - } - - void deinitializeSelectionForTrackingChanges() { - if (targetsPropertyAtoms != null && targetsPropertyAtom != null) { - targetsPropertyAtoms.remove(Long.valueOf(targetsPropertyAtom.getAtom())); - } - isSelectionNotifyProcessed = false; - } - public synchronized boolean setOwner(Transferable contents, Map formatMap, - long[] formats, long time) { + long[] formats, long time) + { long owner = XWindow.getXAWTRootWindow().getWindow(); long selection = selectionAtom.getAtom(); @@ -192,15 +156,12 @@ public class XSelection { XlibWrapper.XSetSelectionOwner(XToolkit.getDisplay(), selection, owner, time); if (XlibWrapper.XGetSelectionOwner(XToolkit.getDisplay(), - selection) != owner) { - + selection) != owner) + { reset(); return false; } - isOwner = true; - if (clipboard != null) { - clipboard.checkChangeHere(contents); - } + setOwnerProp(true); return true; } finally { XToolkit.awtUnlock(); @@ -217,7 +178,7 @@ public class XSelection { do { DataTransferer.getInstance().processDataConversionRequests(); XToolkit.awtLockWait(250); - } while (propertyGetter == dataGetter && System.currentTimeMillis() < startTime + SELECTION_TIMEOUT); + } while (propertyGetter == dataGetter && System.currentTimeMillis() < startTime + UNIXToolkit.getDatatransferTimeout()); } finally { XToolkit.awtUnlock(); } @@ -232,11 +193,9 @@ public class XSelection { throw new Error("UNIMPLEMENTED"); } - long[] formats = null; + long[] targets = null; synchronized (lock) { - SELECTION_TIMEOUT = UNIXToolkit.getDatatransferTimeout(); - WindowPropertyGetter targetsGetter = new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(), selectionPropertyAtom, 0, MAX_LENGTH, @@ -267,23 +226,25 @@ public class XSelection { } finally { XToolkit.awtUnlock(); } - formats = getFormats(targetsGetter); + targets = getFormats(targetsGetter); } finally { targetsGetter.dispose(); } } - return formats; + return targets; } - private static long[] getFormats(WindowPropertyGetter targetsGetter) { + static long[] getFormats(WindowPropertyGetter targetsGetter) { long[] formats = null; if (targetsGetter.isExecuted() && !targetsGetter.isDisposed() && (targetsGetter.getActualType() == XAtom.XA_ATOM || targetsGetter.getActualType() == XDataTransferer.TARGETS_ATOM.getAtom()) && - targetsGetter.getActualFormat() == 32) { - - int count = (int)targetsGetter.getNumberOfItems(); + targetsGetter.getActualFormat() == 32) + { + // we accept property with TARGETS type to be compatible with old jdks + // see 6607163 + int count = targetsGetter.getNumberOfItems(); if (count > 0) { long atoms = targetsGetter.getData(); formats = new long[count]; @@ -297,26 +258,6 @@ public class XSelection { return formats != null ? formats : new long[0]; } - // checkChange() will be called on SelectionNotify - void getTargetsDelayed() { - XToolkit.awtLock(); - try { - long curTime = System.currentTimeMillis(); - if (isSelectionNotifyProcessed || curTime >= convertSelectionTime + SELECTION_TIMEOUT) { - convertSelectionTime = curTime; - XlibWrapper.XConvertSelection(XToolkit.getDisplay(), - getSelectionAtom().getAtom(), - XDataTransferer.TARGETS_ATOM.getAtom(), - targetsPropertyAtom.getAtom(), - XWindow.getXAWTRootWindow().getWindow(), - XlibWrapper.CurrentTime); - isSelectionNotifyProcessed = false; - } - } finally { - XToolkit.awtUnlock(); - } - } - /* * Requests the selection data in the specified format and returns * the data provided by the owner. @@ -329,8 +270,6 @@ public class XSelection { byte[] data = null; synchronized (lock) { - SELECTION_TIMEOUT = UNIXToolkit.getDatatransferTimeout(); - WindowPropertyGetter dataGetter = new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(), selectionPropertyAtom, 0, MAX_LENGTH, @@ -379,7 +318,7 @@ public class XSelection { dataGetter.getActualFormat()); } - int count = (int)dataGetter.getNumberOfItems(); + int count = dataGetter.getNumberOfItems(); if (count <= 0) { throw new IOException("INCR data is missed."); @@ -455,7 +394,7 @@ public class XSelection { incrDataGetter.getActualFormat()); } - count = (int)incrDataGetter.getNumberOfItems(); + count = incrDataGetter.getNumberOfItems(); if (count == 0) { break; @@ -489,7 +428,7 @@ public class XSelection { dataGetter.getActualFormat()); } - int count = (int)dataGetter.getNumberOfItems(); + int count = dataGetter.getNumberOfItems(); if (count > 0) { data = new byte[count]; long ptr = dataGetter.getData(); @@ -511,11 +450,14 @@ public class XSelection { return isOwner; } - public void lostOwnership() { - isOwner = false; - if (clipboard != null) { - clipboard.run(); - } + // To be MT-safe this method should be called under awtLock. + private void setOwnerProp(boolean f) { + isOwner = f; + fireOwnershipChanges(isOwner); + } + + private void lostOwnership() { + setOwnerProp(false); } public synchronized void reset() { @@ -595,125 +537,39 @@ public class XSelection { private void handleSelectionRequest(XSelectionRequestEvent xsre) { long property = xsre.get_property(); - long requestor = xsre.get_requestor(); - long requestTime = xsre.get_time(); - long format = xsre.get_target(); - int dataFormat = 0; + final long requestor = xsre.get_requestor(); + final long requestTime = xsre.get_time(); + final long format = xsre.get_target(); boolean conversionSucceeded = false; if (ownershipTime != 0 && - (requestTime == XlibWrapper.CurrentTime || - requestTime >= ownershipTime)) { - - property = xsre.get_property(); - + (requestTime == XlibWrapper.CurrentTime || requestTime >= ownershipTime)) + { // Handle MULTIPLE requests as per ICCCM. if (format == XDataTransferer.MULTIPLE_ATOM.getAtom()) { - // The property cannot be 0 for a MULTIPLE request. - if (property != 0) { - // First retrieve the list of requested targets. - WindowPropertyGetter wpg = - new WindowPropertyGetter(requestor, XAtom.get(property), 0, - MAX_LENGTH, false, - XlibWrapper.AnyPropertyType); - try { - wpg.execute(); - - if (wpg.getActualFormat() == 32 && - (wpg.getNumberOfItems() % 2) == 0) { - long count = wpg.getNumberOfItems() / 2; - long pairsPtr = wpg.getData(); - boolean writeBack = false; - for (int i = 0; i < count; i++) { - long target = Native.getLong(pairsPtr, 2*i); - long prop = Native.getLong(pairsPtr, 2*i + 1); - - if (!convertAndStore(requestor, target, prop)) { - // To report failure, we should replace the - // target atom with 0 in the MULTIPLE property. - Native.putLong(pairsPtr, 2*i, 0); - writeBack = true; - } - } - if (writeBack) { - XToolkit.awtLock(); - try { - XlibWrapper.XChangeProperty(XToolkit.getDisplay(), requestor, - property, - wpg.getActualType(), - wpg.getActualFormat(), - XlibWrapper.PropModeReplace, - wpg.getData(), - wpg.getNumberOfItems()); - } finally { - XToolkit.awtUnlock(); - } - } - conversionSucceeded = true; - } - } finally { - wpg.dispose(); - } - } + conversionSucceeded = handleMultipleRequest(requestor, property); } else { - // Support for obsolete clients as per ICCCM. - if (property == 0) { + if (property == XlibWrapper.None) { property = format; } if (format == XDataTransferer.TARGETS_ATOM.getAtom()) { - long nativeDataPtr = 0; - int count = 0; - dataFormat = 32; - - // Use a local copy to avoid synchronization. - long[] formatsLocal = formats; - - if (formatsLocal == null) { - throw new IllegalStateException("Not an owner."); - } - - count = formatsLocal.length; - - try { - if (count > 0) { - nativeDataPtr = Native.allocateLongArray(count); - Native.put(nativeDataPtr, formatsLocal); - } - - conversionSucceeded = true; - - XToolkit.awtLock(); - try { - XlibWrapper.XChangeProperty(XToolkit.getDisplay(), requestor, - property, format, dataFormat, - XlibWrapper.PropModeReplace, - nativeDataPtr, count); - } finally { - XToolkit.awtUnlock(); - } - } finally { - if (nativeDataPtr != 0) { - XlibWrapper.unsafe.freeMemory(nativeDataPtr); - nativeDataPtr = 0; - } - } + conversionSucceeded = handleTargetsRequest(property, requestor); } else { - conversionSucceeded = convertAndStore(requestor, format, - property); + conversionSucceeded = convertAndStore(requestor, format, property); } } } if (!conversionSucceeded) { - // Zero property indicates conversion failure. - property = 0; + // None property indicates conversion failure. + property = XlibWrapper.None; } XSelectionEvent xse = new XSelectionEvent(); try { - xse.set_type((int)XlibWrapper.SelectionNotify); + xse.set_type(XlibWrapper.SelectionNotify); xse.set_send_event(true); xse.set_requestor(requestor); xse.set_selection(selectionAtom.getAtom()); @@ -733,40 +589,123 @@ public class XSelection { } } - private static void checkChange(XSelectionEvent xse) { - if (targetsPropertyAtoms == null || targetsPropertyAtoms.isEmpty()) { - // We are not tracking changes. - return; + private boolean handleMultipleRequest(final long requestor, long property) { + if (XlibWrapper.None == property) { + // The property cannot be None for a MULTIPLE request. + return false; } - long propertyAtom = xse.get_property(); - long[] formats = null; + boolean conversionSucceeded = false; - if (propertyAtom == XlibWrapper.None) { - // We threat None property atom as "empty selection". - formats = new long[0]; - } else if (!targetsPropertyAtoms.contains(Long.valueOf(propertyAtom))) { - return; - } else { - WindowPropertyGetter targetsGetter = - new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(), - XAtom.get(propertyAtom), 0, MAX_LENGTH, - true, XlibWrapper.AnyPropertyType); + // First retrieve the list of requested targets. + WindowPropertyGetter wpg = + new WindowPropertyGetter(requestor, XAtom.get(property), + 0, MAX_LENGTH, false, + XlibWrapper.AnyPropertyType); + try { + wpg.execute(); + + if (wpg.getActualFormat() == 32 && (wpg.getNumberOfItems() % 2) == 0) { + final long count = wpg.getNumberOfItems() / 2; + final long pairsPtr = wpg.getData(); + boolean writeBack = false; + + for (int i = 0; i < count; i++) { + long target = Native.getLong(pairsPtr, 2 * i); + long prop = Native.getLong(pairsPtr, 2 * i + 1); + + if (!convertAndStore(requestor, target, prop)) { + // To report failure, we should replace the + // target atom with 0 in the MULTIPLE property. + Native.putLong(pairsPtr, 2 * i, 0); + writeBack = true; + } + } + if (writeBack) { + XToolkit.awtLock(); + try { + XlibWrapper.XChangeProperty(XToolkit.getDisplay(), + requestor, + property, + wpg.getActualType(), + wpg.getActualFormat(), + XlibWrapper.PropModeReplace, + wpg.getData(), + wpg.getNumberOfItems()); + } finally { + XToolkit.awtUnlock(); + } + } + conversionSucceeded = true; + } + } finally { + wpg.dispose(); + } + + return conversionSucceeded; + } + + private boolean handleTargetsRequest(long property, long requestor) + throws IllegalStateException + { + boolean conversionSucceeded = false; + // Use a local copy to avoid synchronization. + long[] formatsLocal = formats; + + if (formatsLocal == null) { + throw new IllegalStateException("Not an owner."); + } + + long nativeDataPtr = 0; + + try { + final int count = formatsLocal.length; + final int dataFormat = 32; + + if (count > 0) { + nativeDataPtr = Native.allocateLongArray(count); + Native.put(nativeDataPtr, formatsLocal); + } + + conversionSucceeded = true; + + XToolkit.awtLock(); try { - targetsGetter.execute(); - formats = getFormats(targetsGetter); + XlibWrapper.XChangeProperty(XToolkit.getDisplay(), requestor, + property, XAtom.XA_ATOM, dataFormat, + XlibWrapper.PropModeReplace, + nativeDataPtr, count); } finally { - targetsGetter.dispose(); + XToolkit.awtUnlock(); + } + } finally { + if (nativeDataPtr != 0) { + XlibWrapper.unsafe.freeMemory(nativeDataPtr); + nativeDataPtr = 0; } } + return conversionSucceeded; + } - XAtom selectionAtom = XAtom.get(xse.get_selection()); - XSelection selection = getSelection(selectionAtom); - if (selection != null) { - selection.isSelectionNotifyProcessed = true; - if (selection.clipboard != null) { - selection.clipboard.checkChange(formats); - } + private void fireOwnershipChanges(final boolean isOwner) { + OwnershipListener l = null; + synchronized (stateLock) { + l = ownershipListener; + } + if (null != l) { + l.ownershipChanged(isOwner); + } + } + + void registerOwershipListener(OwnershipListener l) { + synchronized (stateLock) { + ownershipListener = l; + } + } + + void unregisterOwnershipListener() { + synchronized (stateLock) { + ownershipListener = null; } } @@ -774,10 +713,9 @@ public class XSelection { public void dispatchEvent(XEvent ev) { switch (ev.get_type()) { case XlibWrapper.SelectionNotify: { - XSelectionEvent xse = ev.get_xselection(); - checkChange(xse); XToolkit.awtLock(); try { + XSelectionEvent xse = ev.get_xselection(); // Ignore the SelectionNotify event if it is not the response to our last request. if (propertyGetter != null && xse.get_time() == lastRequestServerTime) { // The property will be None in case of convertion failure. diff --git a/src/solaris/classes/sun/awt/X11/XToolkit.java b/src/solaris/classes/sun/awt/X11/XToolkit.java index b94d01f2257a6a3d626f6aecb2ed185d68675756..069568519d8b62ecaaf025764b1971138fe72b69 100644 --- a/src/solaris/classes/sun/awt/X11/XToolkit.java +++ b/src/solaris/classes/sun/awt/X11/XToolkit.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. 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 @@ -25,11 +25,9 @@ package sun.awt.X11; import java.awt.*; -import java.awt.event.*; -import java.awt.peer.*; -import java.beans.PropertyChangeListener; -import sun.awt.*; -import java.util.*; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; +import java.awt.datatransfer.Clipboard; import java.awt.dnd.DragSource; import java.awt.dnd.DragGestureListener; import java.awt.dnd.DragGestureEvent; @@ -37,20 +35,27 @@ import java.awt.dnd.DragGestureRecognizer; import java.awt.dnd.MouseDragGestureRecognizer; import java.awt.dnd.InvalidDnDOperationException; import java.awt.dnd.peer.DragSourceContextPeer; -import java.awt.image.*; -import java.security.*; import java.awt.im.InputMethodHighlight; import java.awt.im.spi.InputMethodDescriptor; -import java.awt.datatransfer.Clipboard; +import java.awt.image.ColorModel; +import java.awt.peer.*; +import java.beans.PropertyChangeListener; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.swing.LookAndFeel; import javax.swing.UIDefaults; -import java.util.logging.*; +import sun.awt.*; import sun.font.FontManager; import sun.misc.PerformanceLogger; import sun.print.PrintJob2D; -import java.lang.reflect.*; -public class XToolkit extends UNIXToolkit implements Runnable, XConstants { +public final class XToolkit extends UNIXToolkit implements Runnable, XConstants +{ private static Logger log = Logger.getLogger("sun.awt.X11.XToolkit"); private static Logger eventLog = Logger.getLogger("sun.awt.X11.event.XToolkit"); private static final Logger timeoutTaskLog = Logger.getLogger("sun.awt.X11.timeoutTask.XToolkit"); @@ -1871,9 +1876,7 @@ public class XToolkit extends UNIXToolkit implements Runnable, XConstants { } public boolean isAlwaysOnTopSupported() { - Iterator iter = XWM.getWM().getProtocols(XLayerProtocol.class).iterator(); - while (iter.hasNext()) { - XLayerProtocol proto = (XLayerProtocol)iter.next(); + for (XLayerProtocol proto : XWM.getWM().getProtocols(XLayerProtocol.class)) { if (proto.supportsLayer(XLayerProtocol.LAYER_ALWAYS_ON_TOP)) { return true; } diff --git a/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java b/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java index c9b9a1abfd3a231ea1bb8cda304d67620d071826..5c8ccd02913ce41569e9d5768777193d8488c497 100644 --- a/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java +++ b/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 Sun Microsystems, Inc. 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 @@ -31,11 +31,8 @@ import java.awt.peer.TrayIconPeer; import sun.awt.*; import java.awt.image.*; import java.text.BreakIterator; -import java.util.Vector; -import java.lang.reflect.Field; import java.util.logging.Logger; import java.util.logging.Level; -import java.util.AbstractQueue; import java.util.concurrent.ArrayBlockingQueue; import java.security.AccessController; import java.security.PrivilegedAction; @@ -629,7 +626,7 @@ public class XTrayIconPeer implements TrayIconPeer { final static int TOOLTIP_MAX_LENGTH = 64; final static int TOOLTIP_MOUSE_CURSOR_INDENT = 5; final static Color TOOLTIP_BACKGROUND_COLOR = new Color(255, 255, 220); - final static Font TOOLTIP_TEXT_FONT = XWindow.defaultFont; + final static Font TOOLTIP_TEXT_FONT = XWindow.getDefaultFont(); Tooltip(XTrayIconPeer xtiPeer, Frame parent) { super(parent, Color.black); diff --git a/src/solaris/classes/sun/awt/X11/XWM.java b/src/solaris/classes/sun/awt/X11/XWM.java index 68d1ff73e5f2e3c14c67772c4a8631763f093537..d8e0d6b031dacfc21b39350d9b7be4720139a46e 100644 --- a/src/solaris/classes/sun/awt/X11/XWM.java +++ b/src/solaris/classes/sun/awt/X11/XWM.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. 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 @@ -31,20 +31,23 @@ package sun.awt.X11; import sun.misc.Unsafe; -import java.util.regex.*; +import java.awt.Insets; import java.awt.Frame; import java.awt.Rectangle; -import java.util.*; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; import java.util.logging.Level; -import java.util.logging.LogManager; import java.util.logging.Logger; -import java.awt.Insets; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Class incapsulating knowledge about window managers in general * Descendants should provide some information about specific window manager. */ -class XWM implements MWMConstants, XUtilConstants { +final class XWM implements MWMConstants, XUtilConstants +{ private final static Logger log = Logger.getLogger("sun.awt.X11.XWM"); private final static Logger insLog = Logger.getLogger("sun.awt.X11.insets.XWM"); @@ -1026,21 +1029,21 @@ class XWM implements MWMConstants, XUtilConstants { /*****************************************************************************\ * Protocols support */ - HashMap, Collection> protocolsMap = new HashMap, Collection>(); + private HashMap, Collection> protocolsMap = new HashMap, Collection>(); /** * Returns all protocols supporting given protocol interface */ - Collection getProtocols(Class protocolInterface) { - Collection res = protocolsMap.get(protocolInterface); + Collection getProtocols(Class protocolInterface) { + Collection res = (Collection) protocolsMap.get(protocolInterface); if (res != null) { - return (Collection)res; + return res; } else { - return new LinkedList(); + return new LinkedList(); } } - void addProtocol(Class protocolInterface, XProtocol protocol) { - Collection protocols = getProtocols(protocolInterface); + private void addProtocol(Class protocolInterface, T protocol) { + Collection protocols = getProtocols(protocolInterface); protocols.add(protocol); protocolsMap.put(protocolInterface, protocols); } @@ -1085,9 +1088,7 @@ class XWM implements MWMConstants, XUtilConstants { } /* FALLTROUGH */ case Frame.MAXIMIZED_BOTH: - Iterator iter = getProtocols(XStateProtocol.class).iterator(); - while (iter.hasNext()) { - XStateProtocol proto = (XStateProtocol)iter.next(); + for (XStateProtocol proto : getProtocols(XStateProtocol.class)) { if (proto.supportsState(state)) { return true; } @@ -1105,10 +1106,8 @@ class XWM implements MWMConstants, XUtilConstants { int getExtendedState(XWindowPeer window) { - Iterator iter = getProtocols(XStateProtocol.class).iterator(); int state = 0; - while (iter.hasNext()) { - XStateProtocol proto = (XStateProtocol)iter.next(); + for (XStateProtocol proto : getProtocols(XStateProtocol.class)) { state |= proto.getState(window); } if (state != 0) { @@ -1127,18 +1126,17 @@ class XWM implements MWMConstants, XUtilConstants { /* * Check if property change is a window state protocol message. - * If it is - return the new state as Integer, otherwise return null */ - Integer isStateChange(XDecoratedPeer window, XPropertyEvent e) { + boolean isStateChange(XDecoratedPeer window, XPropertyEvent e) { if (!window.isShowing()) { stateLog.finer("Window is not showing"); - return null; + return false; } int wm_state = window.getWMState(); if (wm_state == XlibWrapper.WithdrawnState) { stateLog.finer("WithdrawnState"); - return null; + return false; } else { stateLog.finer("Window WM_STATE is " + wm_state); } @@ -1147,26 +1145,26 @@ class XWM implements MWMConstants, XUtilConstants { is_state_change = true; } - Iterator iter = getProtocols(XStateProtocol.class).iterator(); - while (iter.hasNext()) { - XStateProtocol proto = (XStateProtocol)iter.next(); + for (XStateProtocol proto : getProtocols(XStateProtocol.class)) { is_state_change |= proto.isStateChange(e); + stateLog.finest(proto + ": is state changed = " + is_state_change); } - int res = 0; + return is_state_change; + } - if (is_state_change) { - if (wm_state == XlibWrapper.IconicState) { - res = Frame.ICONIFIED; - } else { - res = Frame.NORMAL; - } - res |= getExtendedState(window); - } - if (is_state_change) { - return Integer.valueOf(res); + /* + * Returns current state (including extended) of a given window. + */ + int getState(XDecoratedPeer window) { + int res = 0; + final int wm_state = window.getWMState(); + if (wm_state == XlibWrapper.IconicState) { + res = Frame.ICONIFIED; } else { - return null; + res = Frame.NORMAL; } + res |= getExtendedState(window); + return res; } /*****************************************************************************\ @@ -1180,9 +1178,7 @@ class XWM implements MWMConstants, XUtilConstants { * in XLayerProtocol */ void setLayer(XWindowPeer window, int layer) { - Iterator iter = getProtocols(XLayerProtocol.class).iterator(); - while (iter.hasNext()) { - XLayerProtocol proto = (XLayerProtocol)iter.next(); + for (XLayerProtocol proto : getProtocols(XLayerProtocol.class)) { if (proto.supportsLayer(layer)) { proto.setLayer(window, layer); } @@ -1191,9 +1187,7 @@ class XWM implements MWMConstants, XUtilConstants { } void setExtendedState(XWindowPeer window, int state) { - Iterator iter = getProtocols(XStateProtocol.class).iterator(); - while (iter.hasNext()) { - XStateProtocol proto = (XStateProtocol)iter.next(); + for (XStateProtocol proto : getProtocols(XStateProtocol.class)) { if (proto.supportsState(state)) { proto.setState(window, state); break; @@ -1239,9 +1233,7 @@ class XWM implements MWMConstants, XUtilConstants { void unshadeKludge(XDecoratedPeer window) { assert(window.isShowing()); - Iterator iter = getProtocols(XStateProtocol.class).iterator(); - while (iter.hasNext()) { - XStateProtocol proto = (XStateProtocol)iter.next(); + for (XStateProtocol proto : getProtocols(XStateProtocol.class)) { proto.unshadeKludge(window); } XToolkit.XSync(); diff --git a/src/solaris/classes/sun/awt/X11/XWindow.java b/src/solaris/classes/sun/awt/X11/XWindow.java index 9e3c877fa11af0ca30466c05fc2c4a5c75d33a0b..2d55ef889fbdec8cb8d923d79e3322a4198c89f3 100644 --- a/src/solaris/classes/sun/awt/X11/XWindow.java +++ b/src/solaris/classes/sun/awt/X11/XWindow.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. 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 @@ -92,8 +92,16 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { SurfaceData surfaceData; XRepaintArea paintArea; + // fallback default font object - final static Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12); + private static Font defaultFont; + + static synchronized Font getDefaultFont() { + if (null == defaultFont) { + defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12); + } + return defaultFont; + } /* * Keeps all buttons which were pressed at the time of the last mouse @@ -333,7 +341,7 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { } Font font = afont; if (font == null) { - font = defaultFont; + font = XWindow.getDefaultFont(); } return new SunGraphics2D(surfData, fgColor, bgColor, font); } @@ -902,13 +910,11 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { super.handleConfigureNotifyEvent(xev); insLog.log(Level.FINER, "Configure, {0}, event disabled: {1}", - new Object[] {xev, isEventDisabled(xev)}); + new Object[] {xev.get_xconfigure(), isEventDisabled(xev)}); if (isEventDisabled(xev)) { return; } - long eventWindow = xev.get_xany().get_window(); - // if ( Check if it's a resize, a move, or a stacking order change ) // { Rectangle bounds = getBounds(); @@ -982,7 +988,6 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { // called directly from this package, unlike handleKeyRelease. // un-final it if you need to override it in a subclass. final void handleKeyPress(XKeyEvent ev) { - int keycode = java.awt.event.KeyEvent.VK_UNDEFINED; long keysym[] = new long[2]; char unicodeKey = 0; keysym[0] = NoSymbol; @@ -1066,7 +1071,6 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { } // un-private it if you need to call it from elsewhere private void handleKeyRelease(XKeyEvent ev) { - int keycode = java.awt.event.KeyEvent.VK_UNDEFINED; long keysym[] = new long[2]; char unicodeKey = 0; keysym[0] = NoSymbol; diff --git a/src/solaris/classes/sun/awt/X11/XWindowPeer.java b/src/solaris/classes/sun/awt/X11/XWindowPeer.java index 18ccbcba8dadae1c14d7ce6bec3a2d43735e053f..be6792089745ce5c6e4635c8728bbd735fbde224 100644 --- a/src/solaris/classes/sun/awt/X11/XWindowPeer.java +++ b/src/solaris/classes/sun/awt/X11/XWindowPeer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. 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 @@ -112,9 +112,6 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, PARENT_WINDOW, Long.valueOf(0)})); } - // fallback default font object - static Font defaultFont; - /* * This constant defines icon size recommended for using. * Apparently, we should use XGetIconSizes which should @@ -162,10 +159,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, Font f = target.getFont(); if (f == null) { - if (defaultFont == null) { - defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12); - } - f = defaultFont; + f = XWindow.getDefaultFont(); target.setFont(f); // we should not call setFont because it will call a repaint // which the peer may not be ready to do yet. @@ -188,6 +182,9 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, GraphicsConfiguration gc = getGraphicsConfiguration(); ((X11GraphicsDevice)gc.getDevice()).addDisplayChangedListener(this); + + Rectangle bounds = (Rectangle)(params.get(BOUNDS)); + params.put(BOUNDS, constrainBounds(bounds.x, bounds.y, bounds.width, bounds.height)); } private void initWMProtocols() { @@ -437,6 +434,56 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, return ownerPeer; } + // This method is overriden at the XDecoratedPeer to handle + // decorated windows a bit differently. + Rectangle constrainBounds(int x, int y, int width, int height) { + // We don't restrict the setBounds() operation if the code is trusted. + if (!hasWarningWindow()) { + return new Rectangle(x, y, width, height); + } + + // The window bounds should be within the visible part of the screen + int newX = x; + int newY = y; + int newW = width; + int newH = height; + + // Now check each point is within the visible part of the screen + GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration(); + Rectangle sB = gc.getBounds(); + Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc); + + int screenX = sB.x + sIn.left; + int screenY = sB.y + sIn.top; + int screenW = sB.width - sIn.left - sIn.right; + int screenH = sB.height - sIn.top - sIn.bottom; + + + // First make sure the size is withing the visible part of the screen + if (newW > screenW) { + newW = screenW; + } + + if (newH > screenH) { + newH = screenH; + } + + // Tweak the location if needed + if (newX < screenX) { + newX = screenX; + } else if (newX + newW > screenX + screenW) { + newX = screenX + screenW - newW; + } + + if (newY < screenY) { + newY = screenY; + } else if (newY + newH > screenY + screenH) { + newY = screenY + screenH - newH; + } + + return new Rectangle(newX, newY, newW, newH); + } + //Fix for 6318144: PIT:Setting Min Size bigger than current size enlarges //the window but fails to revalidate, Sol-CDE //This bug is regression for @@ -445,10 +492,14 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, //Note that this function is overriden in XDecoratedPeer so event //posting is not changing for decorated peers public void setBounds(int x, int y, int width, int height, int op) { + Rectangle newBounds = constrainBounds(x, y, width, height); + XToolkit.awtLock(); try { Rectangle oldBounds = getBounds(); - super.setBounds(x, y, width, height, op); + + super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op); + Rectangle bounds = getBounds(); XSizeHints hints = getHints(); @@ -1035,7 +1086,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, return !(target instanceof Frame || target instanceof Dialog); } boolean hasWarningWindow() { - return warningWindow != null; + return ((Window)target).getWarningString() != null; } // The height of menu bar window diff --git a/src/solaris/classes/sun/awt/motif/MDialogPeer.java b/src/solaris/classes/sun/awt/motif/MDialogPeer.java index 16ccab54ca6f9d6b6e8809b8aa792b9d92564351..5e22931aa600f8f6efbcf5fe73248c5570208377 100644 --- a/src/solaris/classes/sun/awt/motif/MDialogPeer.java +++ b/src/solaris/classes/sun/awt/motif/MDialogPeer.java @@ -102,4 +102,9 @@ class MDialogPeer extends MWindowPeer implements DialogPeer, MInputMethodControl public void blockWindows(java.util.List toBlock) { // do nothing } + + @Override + final boolean isTargetUndecorated() { + return ((Dialog)target).isUndecorated(); + } } diff --git a/src/solaris/classes/sun/awt/motif/MEmbeddedFramePeer.java b/src/solaris/classes/sun/awt/motif/MEmbeddedFramePeer.java index d608721d97dd4553e7e1fabbcb51da3c2fe0ed43..60de1a245f6192ad002a54f69a3e2d4e851f7f8b 100644 --- a/src/solaris/classes/sun/awt/motif/MEmbeddedFramePeer.java +++ b/src/solaris/classes/sun/awt/motif/MEmbeddedFramePeer.java @@ -204,4 +204,10 @@ public class MEmbeddedFramePeer extends MFramePeer { } public native Rectangle getBoundsPrivate(); + + @Override + Rectangle constrainBounds(int x, int y, int width, int height) { + // We don't constrain the bounds of the EmbeddedFrames + return new Rectangle(x, y, width, height); + } } diff --git a/src/solaris/classes/sun/awt/motif/MFramePeer.java b/src/solaris/classes/sun/awt/motif/MFramePeer.java index 99516d5a98b520c65e39aaf299f9dee073391e7a..d772b99c4c2fceb2b39e5d13c97d20c6caa3ae4d 100644 --- a/src/solaris/classes/sun/awt/motif/MFramePeer.java +++ b/src/solaris/classes/sun/awt/motif/MFramePeer.java @@ -503,4 +503,9 @@ class MFramePeer extends MWindowPeer implements FramePeer, MInputMethodControl { public Rectangle getBoundsPrivate() { return getBounds(); } + + @Override + final boolean isTargetUndecorated() { + return ((Frame)target).isUndecorated(); + } } diff --git a/src/solaris/classes/sun/awt/motif/MWindowPeer.java b/src/solaris/classes/sun/awt/motif/MWindowPeer.java index c59750aec5120b878f57591f523ffdc036760b40..15c5c80de3b3c8720aa635c348c329ad24649f0f 100644 --- a/src/solaris/classes/sun/awt/motif/MWindowPeer.java +++ b/src/solaris/classes/sun/awt/motif/MWindowPeer.java @@ -113,6 +113,12 @@ DisplayChangedListener { insets.right = getInset("awt.frame.rightInset", -1); } + Rectangle bounds = target.getBounds(); + sysX = bounds.x; + sysY = bounds.y; + sysW = bounds.width; + sysH = bounds.height; + super.init(target); InputMethodManager imm = InputMethodManager.getInstance(); String menuString = imm.getTriggerMenuString(); @@ -150,6 +156,7 @@ DisplayChangedListener { GraphicsConfiguration gc = getGraphicsConfiguration(); ((X11GraphicsDevice)gc.getDevice()).addDisplayChangedListener(this); + } /* Support for multiple icons is not implemented in MAWT */ @@ -246,6 +253,8 @@ DisplayChangedListener { // NOTE: This method may be called by privileged threads. // DO NOT INVOKE CLIENT CODE ON THIS THREAD! public void handleResize(int width, int height) { + sysW = width; + sysH = height; // REMIND: Is this secure? Can client code subclass input method? if (!tcList.isEmpty() && @@ -268,6 +277,8 @@ DisplayChangedListener { } public void handleMoved(int x, int y) { + sysX = x; + sysY = y; postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_MOVED)); } @@ -505,4 +516,87 @@ DisplayChangedListener { } return false; } + + private final boolean hasWarningWindow() { + return ((Window)target).getWarningString() != null; + } + + // This method is overriden at Dialog and Frame peers. + boolean isTargetUndecorated() { + return true; + } + + private volatile int sysX = 0; + private volatile int sysY = 0; + private volatile int sysW = 0; + private volatile int sysH = 0; + + Rectangle constrainBounds(int x, int y, int width, int height) { + // We don't restrict the setBounds() operation if the code is trusted. + if (!hasWarningWindow()) { + return new Rectangle(x, y, width, height); + } + + int newX = x; + int newY = y; + int newW = width; + int newH = height; + + GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration(); + Rectangle sB = gc.getBounds(); + Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc); + + int screenW = sB.width - sIn.left - sIn.right; + int screenH = sB.height - sIn.top - sIn.bottom; + + // If it's undecorated or is not currently visible, + // then check each point is within the visible part of the screen + if (!target.isVisible() || isTargetUndecorated()) { + int screenX = sB.x + sIn.left; + int screenY = sB.y + sIn.top; + + // First make sure the size is withing the visible part of the screen + if (newW > screenW) { + newW = screenW; + } + + if (newH > screenH) { + newH = screenH; + } + + // Tweak the location if needed + if (newX < screenX) { + newX = screenX; + } else if (newX + newW > screenX + screenW) { + newX = screenX + screenW - newW; + } + + if (newY < screenY) { + newY = screenY; + } else if (newY + newH > screenY + screenH) { + newY = screenY + screenH - newH; + } + } else { + int maxW = Math.max(screenW, sysW); + int maxH = Math.max(screenH, sysH); + + // Make sure the size is withing the visible part of the screen + // OR is less that the current size of the window. + if (newW > maxW) { + newW = maxW; + } + + if (newH > maxH) { + newH = maxH; + } + } + + return new Rectangle(newX, newY, newW, newH); + } + + public void setBounds(int x, int y, int width, int height, int op) { + Rectangle newBounds = constrainBounds(x, y, width, height); + super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op); + } + } diff --git a/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java b/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java index 2514a2fffc013ef07a0be89a34e97ceaaeec8793..f56a159294e24a0747d15ebc1ad87b9fff3c7147 100644 --- a/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java +++ b/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java @@ -217,8 +217,7 @@ class DevPollArrayWrapper { Updator u = null; while ((u = updateList.poll()) != null) { // First add pollfd struct to clear out this fd - putPollFD(updatePollArray, index, u.fd, - (short)POLLREMOVE); + putPollFD(updatePollArray, index, u.fd, POLLREMOVE); index++; // Now add pollfd to update this fd, if necessary if (u.mask != POLLREMOVE) { diff --git a/src/solaris/classes/sun/security/provider/NativePRNG.java b/src/solaris/classes/sun/security/provider/NativePRNG.java index 8e25f2560683db09cb049d73ac2ed837e7d90a11..cfa19f8f47895167e924a347e1526384cf2cc47f 100644 --- a/src/solaris/classes/sun/security/provider/NativePRNG.java +++ b/src/solaris/classes/sun/security/provider/NativePRNG.java @@ -71,8 +71,9 @@ public final class NativePRNG extends SecureRandomSpi { private static final RandomIO INSTANCE = initIO(); private static RandomIO initIO() { - Object o = AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + return AccessController.doPrivileged( + new PrivilegedAction() { + public RandomIO run() { File randomFile = new File(NAME_RANDOM); if (randomFile.exists() == false) { return null; @@ -88,7 +89,6 @@ public final class NativePRNG extends SecureRandomSpi { } } }); - return (RandomIO)o; } // return whether the NativePRNG is available diff --git a/src/solaris/hpi/native_threads/src/sys_api_td.c b/src/solaris/hpi/native_threads/src/sys_api_td.c index 37b098aae4390f9fe514fd64c075f470f5bae4aa..c61324a4d0fef03eec65baa6a8b41d4e6b1ce759 100644 --- a/src/solaris/hpi/native_threads/src/sys_api_td.c +++ b/src/solaris/hpi/native_threads/src/sys_api_td.c @@ -63,15 +63,8 @@ #define CLOSEIO #endif /* NO_INTERRUPTIBLE_IO */ -/* - * Linux does not define rlim_t (solaris - * does). THIS IS PROBABLY NOT THE RIGHT THING TO DO, so - * somebody please fix this. - */ -#ifdef __linux__ -typedef int rlim_t ; -#endif - +/* Get typedef for rlim_t */ +#include #ifdef CLOSEIO diff --git a/src/solaris/native/java/io/FileOutputStream_md.c b/src/solaris/native/java/io/FileOutputStream_md.c index 3bee404589cdefd6b2c9258a4d883c865973cd14..4fc5904660be2862d5f5524172edbbf22a724825 100644 --- a/src/solaris/native/java/io/FileOutputStream_md.c +++ b/src/solaris/native/java/io/FileOutputStream_md.c @@ -53,13 +53,10 @@ Java_java_io_FileOutputStream_initIDs(JNIEnv *env, jclass fdClass) { */ JNIEXPORT void JNICALL -Java_java_io_FileOutputStream_open(JNIEnv *env, jobject this, jstring path) { - fileOpen(env, this, path, fos_fd, O_WRONLY | O_CREAT | O_TRUNC); -} - -JNIEXPORT void JNICALL -Java_java_io_FileOutputStream_openAppend(JNIEnv *env, jobject this, jstring path) { - fileOpen(env, this, path, fos_fd, O_WRONLY | O_CREAT | O_APPEND); +Java_java_io_FileOutputStream_open(JNIEnv *env, jobject this, + jstring path, jboolean append) { + fileOpen(env, this, path, fos_fd, + O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC)); } JNIEXPORT void JNICALL diff --git a/src/solaris/native/java/lang/UNIXProcess_md.c b/src/solaris/native/java/lang/UNIXProcess_md.c index a14496e7456d1ea05c623d86e81f88a0d2cb4b56..8390a2baad58eb67980c471fcaae15a5ebe328d3 100644 --- a/src/solaris/native/java/lang/UNIXProcess_md.c +++ b/src/solaris/native/java/lang/UNIXProcess_md.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. 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 @@ -479,6 +479,37 @@ closeSafely(int fd) close(fd); } +/* + * Reads nbyte bytes from file descriptor fd into buf, + * The read operation is retried in case of EINTR or partial reads. + * + * Returns number of bytes read (normally nbyte, but may be less in + * case of EOF). In case of read errors, returns -1 and sets errno. + */ +static ssize_t +readFully(int fd, void *buf, size_t nbyte) +{ + ssize_t remaining = nbyte; + for (;;) { + ssize_t n = read(fd, buf, remaining); + if (n == 0) { + return nbyte - remaining; + } else if (n > 0) { + remaining -= n; + if (remaining <= 0) + return nbyte; + /* We were interrupted in the middle of reading the bytes. + * Unlikely, but possible. */ + buf = (void *) (((char *)buf) + n); + } else if (errno == EINTR) { + /* Strange signals like SIGJVM1 are possible at any time. + * See http://www.dreamsongs.com/WorseIsBetter.html */ + } else { + return -1; + } + } +} + #ifndef __solaris__ #undef fork1 #define fork1() fork() @@ -491,10 +522,8 @@ Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env, jbyteArray argBlock, jint argc, jbyteArray envBlock, jint envc, jbyteArray dir, - jboolean redirectErrorStream, - jobject stdin_fd, - jobject stdout_fd, - jobject stderr_fd) + jintArray std_fds, + jboolean redirectErrorStream) { int errnum; int resultPid = -1; @@ -505,6 +534,7 @@ Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env, const char *pargBlock = getBytes(env, argBlock); const char *penvBlock = getBytes(env, envBlock); const char *pdir = getBytes(env, dir); + jint *fds = NULL; in[0] = in[1] = out[0] = out[1] = err[0] = err[1] = fail[0] = fail[1] = -1; @@ -527,9 +557,13 @@ Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env, initVectorFromBlock(envv, penvBlock, envc); } - if ((pipe(in) < 0) || - (pipe(out) < 0) || - (pipe(err) < 0) || + assert(std_fds != NULL); + fds = (*env)->GetIntArrayElements(env, std_fds, NULL); + if (fds == NULL) goto Catch; + + if ((fds[0] == -1 && pipe(in) < 0) || + (fds[1] == -1 && pipe(out) < 0) || + (fds[2] == -1 && pipe(err) < 0) || (pipe(fail) < 0)) { throwIOException(env, errno, "Bad file descriptor"); goto Catch; @@ -544,23 +578,26 @@ Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env, if (resultPid == 0) { /* Child process */ - /* Close the parent sides of the pipe. - Give the child sides of the pipes the right fileno's. + /* Close the parent sides of the pipes. Closing pipe fds here is redundant, since closeDescriptors() would do it anyways, but a little paranoia is a good thing. */ + closeSafely(in[1]); + closeSafely(out[0]); + closeSafely(err[0]); + closeSafely(fail[0]); + + /* Give the child sides of the pipes the right fileno's. */ /* Note: it is possible for in[0] == 0 */ - close(in[1]); - moveDescriptor(in[0], STDIN_FILENO); - close(out[0]); - moveDescriptor(out[1], STDOUT_FILENO); - close(err[0]); + moveDescriptor(in[0] != -1 ? in[0] : fds[0], STDIN_FILENO); + moveDescriptor(out[1]!= -1 ? out[1] : fds[1], STDOUT_FILENO); + if (redirectErrorStream) { - close(err[1]); + closeSafely(err[1]); dup2(STDOUT_FILENO, STDERR_FILENO); } else { - moveDescriptor(err[1], STDERR_FILENO); + moveDescriptor(err[1] != -1 ? err[1] : fds[2], STDERR_FILENO); } - close(fail[0]); + moveDescriptor(fail[1], FAIL_FILENO); /* close everything */ @@ -600,15 +637,21 @@ Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env, /* parent process */ close(fail[1]); fail[1] = -1; /* See: WhyCantJohnnyExec */ - if (read(fail[0], &errnum, sizeof(errnum)) != 0) { + + switch (readFully(fail[0], &errnum, sizeof(errnum))) { + case 0: break; /* Exec succeeded */ + case sizeof(errnum): waitpid(resultPid, NULL, 0); throwIOException(env, errnum, "Exec failed"); goto Catch; + default: + throwIOException(env, errno, "Read failed"); + goto Catch; } - (*env)->SetIntField(env, stdin_fd, IO_fd_fdID, in [1]); - (*env)->SetIntField(env, stdout_fd, IO_fd_fdID, out[0]); - (*env)->SetIntField(env, stderr_fd, IO_fd_fdID, err[0]); + fds[0] = (in [1] != -1) ? in [1] : -1; + fds[1] = (out[0] != -1) ? out[0] : -1; + fds[2] = (err[0] != -1) ? err[0] : -1; Finally: /* Always clean up the child's side of the pipes */ @@ -628,6 +671,9 @@ Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env, releaseBytes(env, envBlock, penvBlock); releaseBytes(env, dir, pdir); + if (fds != NULL) + (*env)->ReleaseIntArrayElements(env, std_fds, fds, 0); + return resultPid; Catch: diff --git a/src/solaris/native/sun/nio/ch/FileChannelImpl.c b/src/solaris/native/sun/nio/ch/FileChannelImpl.c index 897ad488e949a13f67bfec8cfd8f9f29eb7f7909..6110143de7bcf834067f9b88566e17b08cc3d899 100644 --- a/src/solaris/native/sun/nio/ch/FileChannelImpl.c +++ b/src/solaris/native/sun/nio/ch/FileChannelImpl.c @@ -31,6 +31,7 @@ #include #include "sun_nio_ch_FileChannelImpl.h" #include "java_lang_Integer.h" +#include "java_lang_Long.h" #include "nio.h" #include "nio_util.h" #include @@ -291,7 +292,11 @@ Java_sun_nio_ch_FileChannelImpl_lock0(JNIEnv *env, jobject this, jobject fdo, struct flock64 fl; fl.l_whence = SEEK_SET; - fl.l_len = (off64_t)size; + if (size == (jlong)java_lang_Long_MAX_VALUE) { + fl.l_len = (off64_t)0; + } else { + fl.l_len = (off64_t)size; + } fl.l_start = (off64_t)pos; if (shared == JNI_TRUE) { fl.l_type = F_RDLCK; @@ -325,7 +330,11 @@ Java_sun_nio_ch_FileChannelImpl_release0(JNIEnv *env, jobject this, int cmd = F_SETLK64; fl.l_whence = SEEK_SET; - fl.l_len = (off64_t)size; + if (size == (jlong)java_lang_Long_MAX_VALUE) { + fl.l_len = (off64_t)0; + } else { + fl.l_len = (off64_t)size; + } fl.l_start = (off64_t)pos; fl.l_type = F_UNLCK; lockResult = fcntl(fd, cmd, &fl); diff --git a/src/windows/bin/java_md.c b/src/windows/bin/java_md.c index 2e1c787838d1d1956fab5a8569352889fd0ee069..f252e0b1b3821815d3612a689ccb71fa5efabebe 100644 --- a/src/windows/bin/java_md.c +++ b/src/windows/bin/java_md.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include "java.h" @@ -52,11 +53,6 @@ static jboolean GetJREPath(char *path, jint pathsize); static jboolean _isjavaw = JNI_FALSE; -void -SetJavaw() -{ - _isjavaw = JNI_TRUE; -} jboolean IsJavaw() @@ -999,3 +995,20 @@ ContinueInNewThread0(int (JNICALL *continuation)(void *), jlong stack_size, void /* Linux only, empty on windows. */ void SetJavaLauncherPlatformProps() {} + +void +InitLauncher(boolean javaw) +{ + INITCOMMONCONTROLSEX icx; + + /* + * Required for javaw mode MessageBox output as well as for + * HotSpot -XX:+ShowMessageBoxOnError in java mode, an empty + * flag field is sufficient to perform the basic UI initialization. + */ + memset(&icx, 0, sizeof(INITCOMMONCONTROLSEX)); + icx.dwSize = sizeof(INITCOMMONCONTROLSEX); + InitCommonControlsEx(&icx); + _isjavaw = javaw; + JLI_SetTraceLauncher(); +} diff --git a/src/windows/classes/java/io/FileDescriptor.java b/src/windows/classes/java/io/FileDescriptor.java index c02c1619c1086e19305db9e5bb2c187fac05d7b9..f2036263e8decb16f59c095ff8b71c3b57ad4fb7 100644 --- a/src/windows/classes/java/io/FileDescriptor.java +++ b/src/windows/classes/java/io/FileDescriptor.java @@ -29,17 +29,14 @@ import java.util.concurrent.atomic.AtomicInteger; /** * Instances of the file descriptor class serve as an opaque handle - * to the underlying machine-specific structure representing an open - * file, an open socket, or another source or sink of bytes. The - * main practical use for a file descriptor is to create a - * FileInputStream or FileOutputStream to - * contain it. - *

    - * Applications should not create their own file descriptors. + * to the underlying machine-specific structure representing an + * open file, an open socket, or another source or sink of bytes. + * The main practical use for a file descriptor is to create a + * {@link FileInputStream} or {@link FileOutputStream} to contain it. + * + *

    Applications should not create their own file descriptors. * * @author Pavani Diwanji - * @see java.io.FileInputStream - * @see java.io.FileOutputStream * @since JDK1.0 */ public final class FileDescriptor { @@ -81,6 +78,14 @@ public final class FileDescriptor { public int get(FileDescriptor obj) { return obj.fd; } + + public void setHandle(FileDescriptor obj, long handle) { + obj.handle = handle; + } + + public long getHandle(FileDescriptor obj) { + return obj.handle; + } } ); } @@ -88,7 +93,7 @@ public final class FileDescriptor { /** * A handle to the standard input stream. Usually, this file * descriptor is not used directly, but rather via the input stream - * known as System.in. + * known as {@code System.in}. * * @see java.lang.System#in */ @@ -97,7 +102,7 @@ public final class FileDescriptor { /** * A handle to the standard output stream. Usually, this file * descriptor is not used directly, but rather via the output stream - * known as System.out. + * known as {@code System.out}. * @see java.lang.System#out */ public static final FileDescriptor out = standardStream(1); @@ -105,7 +110,7 @@ public final class FileDescriptor { /** * A handle to the standard error stream. Usually, this file * descriptor is not used directly, but rather via the output stream - * known as System.err. + * known as {@code System.err}. * * @see java.lang.System#err */ @@ -114,9 +119,9 @@ public final class FileDescriptor { /** * Tests if this file descriptor object is valid. * - * @return true if the file descriptor object represents a + * @return {@code true} if the file descriptor object represents a * valid, open file, socket, or other active I/O connection; - * false otherwise. + * {@code false} otherwise. */ public boolean valid() { return ((handle != -1) || (fd != -1)); diff --git a/src/windows/classes/java/lang/ProcessImpl.java b/src/windows/classes/java/lang/ProcessImpl.java index 9db29772571d90d6d27db22a7ff6868573ba8970..910575c44474ed18ed47bb9b7b8f594a5ff27044 100644 --- a/src/windows/classes/java/lang/ProcessImpl.java +++ b/src/windows/classes/java/lang/ProcessImpl.java @@ -25,7 +25,16 @@ package java.lang; -import java.io.*; +import java.io.IOException; +import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileDescriptor; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.lang.ProcessBuilder.Redirect; /* This class is for the exclusive use of ProcessBuilder.start() to * create new processes. @@ -35,30 +44,82 @@ import java.io.*; */ final class ProcessImpl extends Process { + private static final sun.misc.JavaIOFileDescriptorAccess fdAccess + = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess(); // System-dependent portion of ProcessBuilder.start() static Process start(String cmdarray[], java.util.Map environment, String dir, + ProcessBuilder.Redirect[] redirects, boolean redirectErrorStream) throws IOException { String envblock = ProcessEnvironment.toEnvironmentBlock(environment); - return new ProcessImpl(cmdarray, envblock, dir, redirectErrorStream); + + FileInputStream f0 = null; + FileOutputStream f1 = null; + FileOutputStream f2 = null; + + try { + long[] stdHandles; + if (redirects == null) { + stdHandles = new long[] { -1L, -1L, -1L }; + } else { + stdHandles = new long[3]; + + if (redirects[0] == Redirect.PIPE) + stdHandles[0] = -1L; + else if (redirects[0] == Redirect.INHERIT) + stdHandles[0] = fdAccess.getHandle(FileDescriptor.in); + else { + f0 = new FileInputStream(redirects[0].file()); + stdHandles[0] = fdAccess.getHandle(f0.getFD()); + } + + if (redirects[1] == Redirect.PIPE) + stdHandles[1] = -1L; + else if (redirects[1] == Redirect.INHERIT) + stdHandles[1] = fdAccess.getHandle(FileDescriptor.out); + else { + f1 = redirects[1].toFileOutputStream(); + stdHandles[1] = fdAccess.getHandle(f1.getFD()); + } + + if (redirects[2] == Redirect.PIPE) + stdHandles[2] = -1L; + else if (redirects[2] == Redirect.INHERIT) + stdHandles[2] = fdAccess.getHandle(FileDescriptor.err); + else { + f2 = redirects[2].toFileOutputStream(); + stdHandles[2] = fdAccess.getHandle(f2.getFD()); + } + } + + return new ProcessImpl(cmdarray, envblock, dir, + stdHandles, redirectErrorStream); + } finally { + // In theory, close() can throw IOException + // (although it is rather unlikely to happen here) + try { if (f0 != null) f0.close(); } + finally { + try { if (f1 != null) f1.close(); } + finally { if (f2 != null) f2.close(); } + } + } + } private long handle = 0; - private FileDescriptor stdin_fd; - private FileDescriptor stdout_fd; - private FileDescriptor stderr_fd; private OutputStream stdin_stream; private InputStream stdout_stream; private InputStream stderr_stream; - private ProcessImpl(String cmd[], - String envblock, - String path, - boolean redirectErrorStream) + private ProcessImpl(final String cmd[], + final String envblock, + final String path, + final long[] stdHandles, + final boolean redirectErrorStream) throws IOException { // Win32 CreateProcess requires cmd[0] to be normalized @@ -91,25 +152,39 @@ final class ProcessImpl extends Process { } String cmdstr = cmdbuf.toString(); - stdin_fd = new FileDescriptor(); - stdout_fd = new FileDescriptor(); - stderr_fd = new FileDescriptor(); - - handle = create(cmdstr, envblock, path, redirectErrorStream, - stdin_fd, stdout_fd, stderr_fd); + handle = create(cmdstr, envblock, path, + stdHandles, redirectErrorStream); java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - stdin_stream = - new BufferedOutputStream(new FileOutputStream(stdin_fd)); - stdout_stream = - new BufferedInputStream(new FileInputStream(stdout_fd)); - stderr_stream = - new FileInputStream(stderr_fd); - return null; + new java.security.PrivilegedAction() { + public Void run() { + if (stdHandles[0] == -1L) + stdin_stream = new ProcessBuilder.NullOutputStream(); + else { + FileDescriptor stdin_fd = new FileDescriptor(); + fdAccess.setHandle(stdin_fd, stdHandles[0]); + stdin_stream = new BufferedOutputStream( + new FileOutputStream(stdin_fd)); } - }); + + if (stdHandles[1] == -1L) + stdout_stream = new ProcessBuilder.NullInputStream(); + else { + FileDescriptor stdout_fd = new FileDescriptor(); + fdAccess.setHandle(stdout_fd, stdHandles[1]); + stdout_stream = new BufferedInputStream( + new FileInputStream(stdout_fd)); + } + + if (stdHandles[2] == -1L) + stderr_stream = new ProcessBuilder.NullInputStream(); + else { + FileDescriptor stderr_fd = new FileDescriptor(); + fdAccess.setHandle(stderr_fd, stdHandles[2]); + stderr_stream = new FileInputStream(stderr_fd); + } + + return null; }}); } public OutputStream getOutputStream() { @@ -150,13 +225,30 @@ final class ProcessImpl extends Process { public void destroy() { terminateProcess(handle); } private static native void terminateProcess(long handle); + /** + * Create a process using the win32 function CreateProcess. + * + * @param cmdstr the Windows commandline + * @param envblock NUL-separated, double-NUL-terminated list of + * environment strings in VAR=VALUE form + * @param dir the working directory of the process, or null if + * inheriting the current directory from the parent process + * @param stdHandles array of windows HANDLEs. Indexes 0, 1, and + * 2 correspond to standard input, standard output and + * standard error, respectively. On input, a value of -1 + * means to create a pipe to connect child and parent + * processes. On output, a value which is not -1 is the + * parent pipe handle corresponding to the pipe which has + * been created. An element of this array is -1 on input + * if and only if it is not -1 on output. + * @param redirectErrorStream redirectErrorStream attribute + * @return the native subprocess HANDLE returned by CreateProcess + */ private static native long create(String cmdstr, String envblock, String dir, - boolean redirectErrorStream, - FileDescriptor in_fd, - FileDescriptor out_fd, - FileDescriptor err_fd) + long[] stdHandles, + boolean redirectErrorStream) throws IOException; private static native boolean closeHandle(long handle); diff --git a/src/windows/classes/java/net/DualStackPlainSocketImpl.java b/src/windows/classes/java/net/DualStackPlainSocketImpl.java index 116046603f8592cdb676615b6e78a4d94c6293fd..4e92df7f687d7c6121fec182dd56e1d571c42961 100644 --- a/src/windows/classes/java/net/DualStackPlainSocketImpl.java +++ b/src/windows/classes/java/net/DualStackPlainSocketImpl.java @@ -218,9 +218,6 @@ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl return value; } - int socketGetOption1(int opt, Object iaContainerObj, FileDescriptor fd) - throws SocketException {return 0;} // un-implemented REMOVE - void socketSendUrgentData(int data) throws IOException { int nativefd = checkAndReturnNativeFD(); sendOOB(nativefd, data); diff --git a/src/windows/classes/java/net/PlainSocketImpl.java b/src/windows/classes/java/net/PlainSocketImpl.java index c65c71c670f9a192a4c9bac8dd2b8a89aab8b6e3..cde60b530878050fa00c99bca7ef6523a566271c 100644 --- a/src/windows/classes/java/net/PlainSocketImpl.java +++ b/src/windows/classes/java/net/PlainSocketImpl.java @@ -304,11 +304,6 @@ class PlainSocketImpl extends AbstractPlainSocketImpl return impl.socketGetOption(opt, iaContainerObj); } - int socketGetOption1(int opt, Object iaContainerObj, FileDescriptor fd) - throws SocketException { - return impl.socketGetOption1(opt, iaContainerObj, fd); - } - void socketSendUrgentData(int data) throws IOException { impl.socketSendUrgentData(data); } diff --git a/src/windows/classes/java/net/TwoStacksPlainSocketImpl.java b/src/windows/classes/java/net/TwoStacksPlainSocketImpl.java index 9475bd3f7a10e17ed845d2b7df49599e04344c35..13851124b32ce7723bc12a4f43d30a67d2c21961 100644 --- a/src/windows/classes/java/net/TwoStacksPlainSocketImpl.java +++ b/src/windows/classes/java/net/TwoStacksPlainSocketImpl.java @@ -199,8 +199,5 @@ class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl native int socketGetOption(int opt, Object iaContainerObj) throws SocketException; - native int socketGetOption1(int opt, Object iaContainerObj, FileDescriptor fd) - throws SocketException; - native void socketSendUrgentData(int data) throws IOException; } diff --git a/src/windows/classes/sun/awt/windows/WDialogPeer.java b/src/windows/classes/sun/awt/windows/WDialogPeer.java index 735e5f9f1356147e89b77c4c084bc28179052916..4056c4a6f65baafce0dff2bec56edd2bb6576a8b 100644 --- a/src/windows/classes/sun/awt/windows/WDialogPeer.java +++ b/src/windows/classes/sun/awt/windows/WDialogPeer.java @@ -108,11 +108,18 @@ class WDialogPeer extends WWindowPeer implements DialogPeer { } } + @Override + boolean isTargetUndecorated() { + return ((Dialog)target).isUndecorated(); + } + public void reshape(int x, int y, int width, int height) { + Rectangle newBounds = constrainBounds(x, y, width, height); + if (((Dialog)target).isUndecorated()) { - super.reshape(x,y,width,height); + super.reshape(newBounds.x, newBounds.y, newBounds.width, newBounds.height); } else { - reshapeFrame(x,y,width,height); + reshapeFrame(newBounds.x, newBounds.y, newBounds.width, newBounds.height); } } diff --git a/src/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java b/src/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java index 56513d30863c157263be126800923da24bef8956..8c446ff91842f8b23826e575f0a8d40ca466b0c3 100644 --- a/src/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java +++ b/src/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java @@ -65,4 +65,10 @@ public class WEmbeddedFramePeer extends WFramePeer { public native Rectangle getBoundsPrivate(); public native void synthesizeWmActivate(boolean doActivate); + + @Override + Rectangle constrainBounds(int x, int y, int width, int height) { + // We don't constrain the bounds of the EmbeddedFrames + return new Rectangle(x, y, width, height); + } } diff --git a/src/windows/classes/sun/awt/windows/WFramePeer.java b/src/windows/classes/sun/awt/windows/WFramePeer.java index cdf23ec7d3b7879f380bad13744e5e777f1f0d4a..2667fafe0473aedea1c8e1351ed79e0a1e53b606 100644 --- a/src/windows/classes/sun/awt/windows/WFramePeer.java +++ b/src/windows/classes/sun/awt/windows/WFramePeer.java @@ -64,11 +64,18 @@ class WFramePeer extends WWindowPeer implements FramePeer { } } + @Override + boolean isTargetUndecorated() { + return ((Frame)target).isUndecorated(); + } + public void reshape(int x, int y, int width, int height) { + Rectangle newBounds = constrainBounds(x, y, width, height); + if (((Frame)target).isUndecorated()) { - super.reshape(x,y,width,height); + super.reshape(newBounds.x, newBounds.y, newBounds.width, newBounds.height); } else { - reshapeFrame(x,y,width,height); + reshapeFrame(newBounds.x, newBounds.y, newBounds.width, newBounds.height); } } diff --git a/src/windows/classes/sun/awt/windows/WObjectPeer.java b/src/windows/classes/sun/awt/windows/WObjectPeer.java index efe00a63950d47d7dd33d9942c35fa14e9df7f99..d67329e8422cab16111554e9c0aec7caeb9eed91 100644 --- a/src/windows/classes/sun/awt/windows/WObjectPeer.java +++ b/src/windows/classes/sun/awt/windows/WObjectPeer.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. 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 @@ -30,8 +30,12 @@ abstract class WObjectPeer { initIDs(); } - long pData; // The Windows handle for the native widget. - Object target; // The associated AWT object. + // The Windows handle for the native widget. + long pData; + // if the native peer has been destroyed + boolean destroyed = false; + // The associated AWT object. + Object target; private volatile boolean disposed; diff --git a/src/windows/classes/sun/awt/windows/WWindowPeer.java b/src/windows/classes/sun/awt/windows/WWindowPeer.java index 03fb08c7c7610c69339cb5ce50ac6d79d0e34d97..070c67dd15e9d8c5f44541a93297cf155b4abf0c 100644 --- a/src/windows/classes/sun/awt/windows/WWindowPeer.java +++ b/src/windows/classes/sun/awt/windows/WWindowPeer.java @@ -434,6 +434,97 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer { private native void nativeGrab(); private native void nativeUngrab(); + private final boolean hasWarningWindow() { + return ((Window)target).getWarningString() != null; + } + + boolean isTargetUndecorated() { + return true; + } + + // These are the peer bounds. They get updated at: + // 1. the WWindowPeer.setBounds() method. + // 2. the native code (on WM_SIZE/WM_MOVE) + private volatile int sysX = 0; + private volatile int sysY = 0; + private volatile int sysW = 0; + private volatile int sysH = 0; + + Rectangle constrainBounds(int x, int y, int width, int height) { + // We don't restrict the setBounds() operation if the code is trusted. + if (!hasWarningWindow()) { + return new Rectangle(x, y, width, height); + } + + int newX = x; + int newY = y; + int newW = width; + int newH = height; + + GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration(); + Rectangle sB = gc.getBounds(); + Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc); + + int screenW = sB.width - sIn.left - sIn.right; + int screenH = sB.height - sIn.top - sIn.bottom; + + // If it's undecorated or is not currently visible + if (!((Window)target).isVisible() || isTargetUndecorated()) { + // Now check each point is within the visible part of the screen + int screenX = sB.x + sIn.left; + int screenY = sB.y + sIn.top; + + // First make sure the size is withing the visible part of the screen + if (newW > screenW) { + newW = screenW; + } + + if (newH > screenH) { + newH = screenH; + } + + // Tweak the location if needed + if (newX < screenX) { + newX = screenX; + } else if (newX + newW > screenX + screenW) { + newX = screenX + screenW - newW; + } + + if (newY < screenY) { + newY = screenY; + } else if (newY + newH > screenY + screenH) { + newY = screenY + screenH - newH; + } + } else { + int maxW = Math.max(screenW, sysW); + int maxH = Math.max(screenH, sysH); + + // Make sure the size is withing the visible part of the screen + // OR less that the current size of the window. + if (newW > maxW) { + newW = maxW; + } + + if (newH > maxH) { + newH = maxH; + } + } + + return new Rectangle(newX, newY, newW, newH); + } + + @Override + public void setBounds(int x, int y, int width, int height, int op) { + Rectangle newBounds = constrainBounds(x, y, width, height); + + sysX = newBounds.x; + sysY = newBounds.y; + sysW = newBounds.width; + sysH = newBounds.height; + + super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op); + } + /* * The method maps the list of the active windows to the window's AppContext, * then the method registers ActiveWindowListener, GuiDisposedListener listeners; diff --git a/src/windows/classes/sun/security/mscapi/SunMSCAPI.java b/src/windows/classes/sun/security/mscapi/SunMSCAPI.java index b867a76e5d969411dd9a7b081131c009676b9f83..99a5165a90db2ff213729eb95ee7abc2407e4b7d 100644 --- a/src/windows/classes/sun/security/mscapi/SunMSCAPI.java +++ b/src/windows/classes/sun/security/mscapi/SunMSCAPI.java @@ -48,8 +48,8 @@ public final class SunMSCAPI extends Provider { private static final String INFO = "Sun's Microsoft Crypto API provider"; static { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { System.loadLibrary("sunmscapi"); return null; } diff --git a/src/windows/native/java/io/FileOutputStream_md.c b/src/windows/native/java/io/FileOutputStream_md.c index b5c29abe3e520c29c8c17e9f1f6714da81100c60..97862c5d2d8d21b9993a152494105a2f6bd299e9 100644 --- a/src/windows/native/java/io/FileOutputStream_md.c +++ b/src/windows/native/java/io/FileOutputStream_md.c @@ -39,8 +39,6 @@ jfieldID fos_fd; /* id for jobject 'fd' in java.io.FileOutputStream */ -jfieldID fos_append; - /************************************************************** * static methods to store field ID's in initializers */ @@ -49,7 +47,6 @@ JNIEXPORT void JNICALL Java_java_io_FileOutputStream_initIDs(JNIEnv *env, jclass fosClass) { fos_fd = (*env)->GetFieldID(env, fosClass, "fd", "Ljava/io/FileDescriptor;"); - fos_append = (*env)->GetFieldID(env, fosClass, "append", "Z"); } /************************************************************** @@ -57,45 +54,20 @@ Java_java_io_FileOutputStream_initIDs(JNIEnv *env, jclass fosClass) { */ JNIEXPORT void JNICALL -Java_java_io_FileOutputStream_open(JNIEnv *env, jobject this, jstring path) { - fileOpen(env, this, path, fos_fd, O_WRONLY | O_CREAT | O_TRUNC); -} - -JNIEXPORT void JNICALL -Java_java_io_FileOutputStream_openAppend(JNIEnv *env, jobject this, jstring path) { - fileOpen(env, this, path, fos_fd, O_WRONLY | O_CREAT | O_APPEND); +Java_java_io_FileOutputStream_open(JNIEnv *env, jobject this, + jstring path, jboolean append) { + fileOpen(env, this, path, fos_fd, + O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC)); } JNIEXPORT void JNICALL Java_java_io_FileOutputStream_write(JNIEnv *env, jobject this, jint byte) { - jboolean append = (*env)->GetBooleanField(env, this, fos_append); - FD fd = GET_FD(this, fos_fd); - if (fd == -1) { - JNU_ThrowIOException(env, "Stream Closed"); - return; - } - if (append == JNI_TRUE) { - if (IO_Lseek(fd, 0L, SEEK_END) == -1) { - JNU_ThrowIOExceptionWithLastError(env, "Append failed"); - } - } writeSingle(env, this, byte, fos_fd); } JNIEXPORT void JNICALL Java_java_io_FileOutputStream_writeBytes(JNIEnv *env, jobject this, jbyteArray bytes, jint off, jint len) { - jboolean append = (*env)->GetBooleanField(env, this, fos_append); - FD fd = GET_FD(this, fos_fd); - if (fd == -1) { - JNU_ThrowIOException(env, "Stream Closed"); - return; - } - if (append == JNI_TRUE) { - if (IO_Lseek(fd, 0L, SEEK_END) == -1) { - JNU_ThrowIOExceptionWithLastError(env, "Append failed"); - } - } writeBytes(env, this, bytes, off, len, fos_fd); } diff --git a/src/windows/native/java/io/io_util_md.c b/src/windows/native/java/io/io_util_md.c index a18894ca885dbf74dd2f2a980ab0712a7c140d10..89290c778f744216a0a6e16147ae2637612b9226 100644 --- a/src/windows/native/java/io/io_util_md.c +++ b/src/windows/native/java/io/io_util_md.c @@ -42,7 +42,7 @@ extern jboolean onNT = JNI_FALSE; -static int MAX_INPUT_EVENTS = 2000; +static DWORD MAX_INPUT_EVENTS = 2000; void initializeWindowsVersion() { @@ -190,9 +190,16 @@ pathToNTPath(JNIEnv *env, jstring path, jboolean throwFNFE) { jlong winFileHandleOpen(JNIEnv *env, jstring path, int flags) { + /* To implement O_APPEND, we use the strategy from + http://msdn2.microsoft.com/en-us/library/aa363858.aspx + "You can get atomic append by opening a file with + FILE_APPEND_DATA access and _without_ FILE_WRITE_DATA access. + If you do this then all writes will ignore the current file + pointer and be done at the end-of file." */ const DWORD access = - (flags & O_RDWR) ? (GENERIC_WRITE | GENERIC_READ) : + (flags & O_APPEND) ? (FILE_GENERIC_WRITE & ~FILE_WRITE_DATA) : (flags & O_WRONLY) ? GENERIC_WRITE : + (flags & O_RDWR) ? (GENERIC_READ | GENERIC_WRITE) : GENERIC_READ; const DWORD sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; @@ -444,24 +451,6 @@ handleSetLength(jlong fd, jlong length) { return 0; } -int -handleFileSizeFD(jlong fd, jlong *size) -{ - DWORD sizeLow = 0; - DWORD sizeHigh = 0; - HANDLE h = (HANDLE)fd; - if (h == INVALID_HANDLE_VALUE) { - return -1; - } - sizeLow = GetFileSize(h, &sizeHigh); - if (sizeLow == ((DWORD)-1)) { - if (GetLastError() != ERROR_SUCCESS) { - return -1; - } - } - return (((jlong)sizeHigh) << 32) | sizeLow; -} - JNIEXPORT size_t handleRead(jlong fd, void *buf, jint len) @@ -513,7 +502,7 @@ handleClose(JNIEnv *env, jobject this, jfieldID fid) FD fd = GET_FD(this, fid); HANDLE h = (HANDLE)fd; - if (fd == INVALID_HANDLE_VALUE) { + if (h == INVALID_HANDLE_VALUE) { return 0; } diff --git a/src/windows/native/java/io/io_util_md.h b/src/windows/native/java/io/io_util_md.h index fdbd5bf22e299f140d347452433b408a082af47f..bf9047d7c6527fd46f3b5571b5b002042db34a5b 100644 --- a/src/windows/native/java/io/io_util_md.h +++ b/src/windows/native/java/io/io_util_md.h @@ -38,7 +38,6 @@ void fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags); int handleAvailable(jlong fd, jlong *pbytes); JNIEXPORT int handleSync(jlong fd); int handleSetLength(jlong fd, jlong length); -int handleFileSizeFD(jlong fd, jlong *size); JNIEXPORT size_t handleRead(jlong fd, void *buf, jint len); JNIEXPORT size_t handleWrite(jlong fd, const void *buf, jint len); jint handleClose(JNIEnv *env, jobject this, jfieldID fid); diff --git a/src/windows/native/java/lang/ProcessImpl_md.c b/src/windows/native/java/lang/ProcessImpl_md.c index fd9da8e41685eae0c0451635d8043a84ea2c1aac..f6a8cad4e4b83511e70fa3515f5ffce43f30bd12 100644 --- a/src/windows/native/java/lang/ProcessImpl_md.c +++ b/src/windows/native/java/lang/ProcessImpl_md.c @@ -33,7 +33,12 @@ #include #include -#define PIPE_SIZE 4096 +/* We try to make sure that we can read and write 4095 bytes (the + * fixed limit on Linux) to the pipe on all operating systems without + * deadlock. Windows 2000 inexplicably appears to need an extra 24 + * bytes of slop to avoid deadlock. + */ +#define PIPE_SIZE (4096+24) char * extractExecutablePath(JNIEnv *env, char *source) @@ -120,7 +125,7 @@ win32Error(JNIEnv *env, const char *functionName) static void closeSafely(HANDLE handle) { - if (handle) + if (handle != INVALID_HANDLE_VALUE) CloseHandle(handle); } @@ -129,23 +134,22 @@ Java_java_lang_ProcessImpl_create(JNIEnv *env, jclass ignored, jstring cmd, jstring envBlock, jstring dir, - jboolean redirectErrorStream, - jobject in_fd, - jobject out_fd, - jobject err_fd) + jlongArray stdHandles, + jboolean redirectErrorStream) { - HANDLE inRead = 0; - HANDLE inWrite = 0; - HANDLE outRead = 0; - HANDLE outWrite = 0; - HANDLE errRead = 0; - HANDLE errWrite = 0; + HANDLE inRead = INVALID_HANDLE_VALUE; + HANDLE inWrite = INVALID_HANDLE_VALUE; + HANDLE outRead = INVALID_HANDLE_VALUE; + HANDLE outWrite = INVALID_HANDLE_VALUE; + HANDLE errRead = INVALID_HANDLE_VALUE; + HANDLE errWrite = INVALID_HANDLE_VALUE; SECURITY_ATTRIBUTES sa; PROCESS_INFORMATION pi; STARTUPINFO si; LPTSTR pcmd = NULL; LPCTSTR pdir = NULL; LPVOID penvBlock = NULL; + jlong *handles = NULL; jlong ret = 0; OSVERSIONINFO ver; jboolean onNT = JNI_FALSE; @@ -156,17 +160,6 @@ Java_java_lang_ProcessImpl_create(JNIEnv *env, jclass ignored, if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT) onNT = JNI_TRUE; - sa.nLength = sizeof(sa); - sa.lpSecurityDescriptor = 0; - sa.bInheritHandle = TRUE; - - if (!(CreatePipe(&inRead, &inWrite, &sa, PIPE_SIZE) && - CreatePipe(&outRead, &outWrite, &sa, PIPE_SIZE) && - CreatePipe(&errRead, &errWrite, &sa, PIPE_SIZE))) { - win32Error(env, "CreatePipe"); - goto Catch; - } - assert(cmd != NULL); pcmd = (LPTSTR) JNU_GetStringPlatformChars(env, cmd, NULL); if (pcmd == NULL) goto Catch; @@ -184,19 +177,62 @@ Java_java_lang_ProcessImpl_create(JNIEnv *env, jclass ignored, if (penvBlock == NULL) goto Catch; } + assert(stdHandles != NULL); + handles = (*env)->GetLongArrayElements(env, stdHandles, NULL); + if (handles == NULL) goto Catch; + memset(&si, 0, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES; - si.hStdInput = inRead; - si.hStdOutput = outWrite; - si.hStdError = redirectErrorStream ? outWrite : errWrite; - SetHandleInformation(inWrite, HANDLE_FLAG_INHERIT, FALSE); - SetHandleInformation(outRead, HANDLE_FLAG_INHERIT, FALSE); - SetHandleInformation(errRead, HANDLE_FLAG_INHERIT, FALSE); + sa.nLength = sizeof(sa); + sa.lpSecurityDescriptor = 0; + sa.bInheritHandle = TRUE; - if (redirectErrorStream) - SetHandleInformation(errWrite, HANDLE_FLAG_INHERIT, FALSE); + if (handles[0] != (jlong) -1) { + si.hStdInput = (HANDLE) handles[0]; + handles[0] = (jlong) -1; + } else { + if (! CreatePipe(&inRead, &inWrite, &sa, PIPE_SIZE)) { + win32Error(env, "CreatePipe"); + goto Catch; + } + si.hStdInput = inRead; + SetHandleInformation(inWrite, HANDLE_FLAG_INHERIT, FALSE); + handles[0] = (jlong) inWrite; + } + SetHandleInformation(si.hStdInput, HANDLE_FLAG_INHERIT, TRUE); + + if (handles[1] != (jlong) -1) { + si.hStdOutput = (HANDLE) handles[1]; + handles[1] = (jlong) -1; + } else { + if (! CreatePipe(&outRead, &outWrite, &sa, PIPE_SIZE)) { + win32Error(env, "CreatePipe"); + goto Catch; + } + si.hStdOutput = outWrite; + SetHandleInformation(outRead, HANDLE_FLAG_INHERIT, FALSE); + handles[1] = (jlong) outRead; + } + SetHandleInformation(si.hStdOutput, HANDLE_FLAG_INHERIT, TRUE); + + if (redirectErrorStream) { + si.hStdError = si.hStdOutput; + handles[2] = (jlong) -1; + } else if (handles[2] != (jlong) -1) { + si.hStdError = (HANDLE) handles[2]; + handles[2] = (jlong) -1; + } else { + if (! CreatePipe(&errRead, &errWrite, &sa, PIPE_SIZE)) { + win32Error(env, "CreatePipe"); + goto Catch; + } + si.hStdError = errWrite; + SetHandleInformation(errRead, HANDLE_FLAG_INHERIT, FALSE); + handles[2] = (jlong) errRead; + } + SetHandleInformation(si.hStdError, HANDLE_FLAG_INHERIT, TRUE); if (onNT) processFlag = CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT; @@ -232,9 +268,6 @@ Java_java_lang_ProcessImpl_create(JNIEnv *env, jclass ignored, CloseHandle(pi.hThread); ret = (jlong)pi.hProcess; - (*env)->SetLongField(env, in_fd, IO_handle_fdID, (jlong)inWrite); - (*env)->SetLongField(env, out_fd, IO_handle_fdID, (jlong)outRead); - (*env)->SetLongField(env, err_fd, IO_handle_fdID, (jlong)errRead); Finally: /* Always clean up the child's side of the pipes */ @@ -252,6 +285,9 @@ Java_java_lang_ProcessImpl_create(JNIEnv *env, jclass ignored, else JNU_ReleaseStringPlatformChars(env, dir, (char *) penvBlock); } + if (handles != NULL) + (*env)->ReleaseLongArrayElements(env, stdHandles, handles, 0); + return ret; Catch: diff --git a/src/windows/native/java/lang/java_props_md.c b/src/windows/native/java/lang/java_props_md.c index ec0561c04e11db95e7ea9045306de8defe6877e8..7c758e5a9947bb9b38e72ad5e9d144d363520059 100644 --- a/src/windows/native/java/lang/java_props_md.c +++ b/src/windows/native/java/lang/java_props_md.c @@ -673,13 +673,13 @@ GetJavaProperties(JNIEnv* env) /* OS properties */ { char buf[100]; - OSVERSIONINFO ver; + OSVERSIONINFOEX ver; ver.dwOSVersionInfoSize = sizeof(ver); - GetVersionEx(&ver); + GetVersionEx((OSVERSIONINFO *) &ver); /* * From msdn page on OSVERSIONINFOEX, current as of this - * writing decoding of dwMajorVersion and dwMinorVersion. + * writing, decoding of dwMajorVersion and dwMinorVersion. * * Operating system dwMajorVersion dwMinorVersion * ================== ============== ============== @@ -692,7 +692,7 @@ GetJavaProperties(JNIEnv* env) * Windows 2000 5 0 * Windows XP 5 1 * Windows Server 2003 family 5 2 - * Windows Vista 6 0 + * Windows Vista family 6 0 * * This mapping will presumably be augmented as new Windows * versions are released. @@ -724,7 +724,20 @@ GetJavaProperties(JNIEnv* env) default: sprops.os_name = "Windows NT (unknown)"; break; } } else if (ver.dwMajorVersion == 6) { - sprops.os_name = "Windows Vista"; + /* + * From MSDN OSVERSIONINFOEX documentation: + * + * "Because the version numbers for Windows Server 2008 + * and Windows Vista are identical, you must also test + * whether the wProductType member is VER_NT_WORKSTATION. + * If wProductType is VER_NT_WORKSTATION, the operating + * system is Windows Vista; otherwise, it is Windows + * Server 2008." + */ + if (ver.wProductType == VER_NT_WORKSTATION) + sprops.os_name = "Windows Vista"; + else + sprops.os_name = "Windows Server 2008"; } else { sprops.os_name = "Windows NT (unknown)"; } diff --git a/src/windows/native/sun/net/www/protocol/http/NTLMAuthSequence.c b/src/windows/native/sun/net/www/protocol/http/NTLMAuthSequence.c index 29c0a2b3b70e31e0cf8c937df6f3a5d473efd778..580e2fabadb6a5c000069b46cf114245b24e924c 100644 --- a/src/windows/native/sun/net/www/protocol/http/NTLMAuthSequence.c +++ b/src/windows/native/sun/net/www/protocol/http/NTLMAuthSequence.c @@ -36,6 +36,8 @@ #include #include +#include "jni_util.h" + #define SECURITY_WIN32 #include "sspi.h" #include "issperr.h" @@ -52,7 +54,7 @@ static INITIALIZE_SECURITY_CONTEXT_FN pInitializeSecurityContext; static COMPLETE_AUTH_TOKEN_FN pCompleteAuthToken; static DELETE_SECURITY_CONTEXT_FN pDeleteSecurityContext; -static void endSequence (PCredHandle credHand, PCtxtHandle ctxHandle, SecBufferDesc OutBuffDesc); +static void endSequence (PCredHandle credHand, PCtxtHandle ctxHandle); static jfieldID ntlm_ctxHandleID; static jfieldID ntlm_crdHandleID; @@ -117,22 +119,36 @@ JNIEXPORT jlong JNICALL Java_sun_net_www_protocol_http_NTLMAuthSequence_getCrede { SEC_WINNT_AUTH_IDENTITY AuthId; SEC_WINNT_AUTH_IDENTITY * pAuthId; - CHAR *pUser = 0; - CHAR *pDomain = 0; - CHAR *pPassword = 0; + const CHAR *pUser = 0; + const CHAR *pDomain = 0; + const CHAR *pPassword = 0; CredHandle *pCred; TimeStamp ltime; jboolean isCopy; SECURITY_STATUS ss; if (user != 0) { - pUser = (CHAR *)(*env)->GetStringUTFChars(env, user, &isCopy); + pUser = JNU_GetStringPlatformChars(env, user, &isCopy); + if (pUser == NULL) + return 0; // pending Exception } if (domain != 0) { - pDomain = (CHAR *)(*env)->GetStringUTFChars(env, domain, &isCopy); + pDomain = JNU_GetStringPlatformChars(env, domain, &isCopy); + if (pDomain == NULL) { + if (pUser != NULL) + JNU_ReleaseStringPlatformChars(env, user, pUser); + return 0; // pending Exception + } } if (password != 0) { - pPassword = (CHAR *)(*env)->GetStringUTFChars(env, password, &isCopy); + pPassword = JNU_GetStringPlatformChars(env, password, &isCopy); + if (pPassword == NULL) { + if(pUser != NULL) + JNU_ReleaseStringPlatformChars(env, user, pUser); + if(pDomain != NULL) + JNU_ReleaseStringPlatformChars(env, domain, pDomain); + return 0; // pending Exception + } } pCred = (CredHandle *)malloc(sizeof (CredHandle)); @@ -167,6 +183,14 @@ JNIEXPORT jlong JNICALL Java_sun_net_www_protocol_http_NTLMAuthSequence_getCrede pCred, <ime ); + /* Release resources held by JNU_GetStringPlatformChars */ + if (pUser != NULL) + JNU_ReleaseStringPlatformChars(env, user, pUser); + if (pPassword != NULL) + JNU_ReleaseStringPlatformChars(env, password, pPassword); + if (pDomain != NULL) + JNU_ReleaseStringPlatformChars(env, domain, pDomain); + if (ss == 0) { return (jlong) pCred; } else { @@ -181,7 +205,6 @@ JNIEXPORT jbyteArray JNICALL Java_sun_net_www_protocol_http_NTLMAuthSequence_get VOID *pInput = 0; DWORD inputLen; CHAR buffOut[512]; - DWORD pcbBuffOut; jboolean isCopy; SECURITY_STATUS ss; SecBufferDesc OutBuffDesc; @@ -247,7 +270,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_net_www_protocol_http_NTLMAuthSequence_get } if (ss < 0) { - endSequence (pCred, pCtx, OutBuffDesc); + endSequence (pCred, pCtx); return 0; } @@ -255,7 +278,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_net_www_protocol_http_NTLMAuthSequence_get ss = pCompleteAuthToken( pCtx, &OutBuffDesc ); if (ss < 0) { - endSequence (pCred, pCtx, OutBuffDesc); + endSequence (pCred, pCtx); return 0; } } @@ -265,25 +288,23 @@ JNIEXPORT jbyteArray JNICALL Java_sun_net_www_protocol_http_NTLMAuthSequence_get (*env)->SetByteArrayRegion(env, ret, 0, OutSecBuff.cbBuffer, OutSecBuff.pvBuffer); if (lastToken != 0) // 2nd stage - endSequence (pCred, pCtx, OutBuffDesc); + endSequence (pCred, pCtx); result = ret; } if ((ss != SEC_I_CONTINUE_NEEDED) && (ss == SEC_I_COMPLETE_AND_CONTINUE)) { - endSequence (pCred, pCtx, OutBuffDesc); + endSequence (pCred, pCtx); } return result; } -static void endSequence (PCredHandle credHand, PCtxtHandle ctxHandle, SecBufferDesc OutBuffDesc) { +static void endSequence (PCredHandle credHand, PCtxtHandle ctxHandle) { if (credHand != 0) { pFreeCredentialsHandle (credHand); free (credHand); } - pFreeContextBuffer (&OutBuffDesc); - if (ctxHandle != 0) { pDeleteSecurityContext(ctxHandle); free (ctxHandle); diff --git a/src/windows/native/sun/security/krb5/NativeCreds.c b/src/windows/native/sun/security/krb5/NativeCreds.c index 879dab473880822c42438554c7a2df65bbc548bf..5d2365a415a92040471b617eb3882eab1529a2bd 100644 --- a/src/windows/native/sun/security/krb5/NativeCreds.c +++ b/src/windows/native/sun/security/krb5/NativeCreds.c @@ -88,9 +88,9 @@ VOID ShowNTError(LPSTR,NTSTATUS); VOID InitUnicodeString( - PUNICODE_STRING DestinationString, + PUNICODE_STRING DestinationString, PCWSTR SourceString OPTIONAL - ); +); jobject BuildTicket(JNIEnv *env, PUCHAR encodedTicket, ULONG encodedTicketSize); @@ -108,215 +108,215 @@ jobject BuildKerberosTime(JNIEnv *env, PLARGE_INTEGER kerbtime); */ JNIEXPORT jint JNICALL JNI_OnLoad( - JavaVM *jvm, - void *reserved) { - - jclass cls; - JNIEnv *env; - - if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2)) { - return JNI_EVERSION; /* JNI version not supported */ - } - - cls = (*env)->FindClass(env,"sun/security/krb5/internal/Ticket"); - - if (cls == NULL) { - printf("Couldn't find Ticket\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found Ticket\n"); - #endif /* DEBUG */ + JavaVM *jvm, + void *reserved) { - ticketClass = (*env)->NewWeakGlobalRef(env,cls); - if (ticketClass == NULL) { - return JNI_ERR; - } - #ifdef DEBUG - printf("Made NewWeakGlobalRef\n"); - #endif /* DEBUG */ - - cls = (*env)->FindClass(env, "sun/security/krb5/PrincipalName"); + jclass cls; + JNIEnv *env; - if (cls == NULL) { - printf("Couldn't find PrincipalName\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found PrincipalName\n"); - #endif /* DEBUG */ - - principalNameClass = (*env)->NewWeakGlobalRef(env,cls); - if (principalNameClass == NULL) { - return JNI_ERR; - } - #ifdef DEBUG - printf("Made NewWeakGlobalRef\n"); - #endif /* DEBUG */ - - cls = (*env)->FindClass(env,"sun/security/util/DerValue"); + if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2)) { + return JNI_EVERSION; /* JNI version not supported */ + } - if (cls == NULL) { - printf("Couldn't find DerValue\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found DerValue\n"); - #endif /* DEBUG */ + cls = (*env)->FindClass(env,"sun/security/krb5/internal/Ticket"); - derValueClass = (*env)->NewWeakGlobalRef(env,cls); - if (derValueClass == NULL) { - return JNI_ERR; - } - #ifdef DEBUG - printf("Made NewWeakGlobalRef\n"); - #endif /* DEBUG */ + if (cls == NULL) { + printf("Couldn't find Ticket\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found Ticket\n"); + #endif /* DEBUG */ - cls = (*env)->FindClass(env,"sun/security/krb5/EncryptionKey"); + ticketClass = (*env)->NewWeakGlobalRef(env,cls); + if (ticketClass == NULL) { + return JNI_ERR; + } + #ifdef DEBUG + printf("Made NewWeakGlobalRef\n"); + #endif /* DEBUG */ - if (cls == NULL) { - printf("Couldn't find EncryptionKey\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found EncryptionKey\n"); - #endif /* DEBUG */ + cls = (*env)->FindClass(env, "sun/security/krb5/PrincipalName"); - encryptionKeyClass = (*env)->NewWeakGlobalRef(env,cls); - if (encryptionKeyClass == NULL) { - return JNI_ERR; - } - #ifdef DEBUG - printf("Made NewWeakGlobalRef\n"); - #endif /* DEBUG */ + if (cls == NULL) { + printf("Couldn't find PrincipalName\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found PrincipalName\n"); + #endif /* DEBUG */ - cls = (*env)->FindClass(env,"sun/security/krb5/internal/TicketFlags"); + principalNameClass = (*env)->NewWeakGlobalRef(env,cls); + if (principalNameClass == NULL) { + return JNI_ERR; + } + #ifdef DEBUG + printf("Made NewWeakGlobalRef\n"); + #endif /* DEBUG */ - if (cls == NULL) { - printf("Couldn't find TicketFlags\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found TicketFlags\n"); - #endif /* DEBUG */ + cls = (*env)->FindClass(env,"sun/security/util/DerValue"); - ticketFlagsClass = (*env)->NewWeakGlobalRef(env,cls); - if (ticketFlagsClass == NULL) { - return JNI_ERR; - } - #ifdef DEBUG - printf("Made NewWeakGlobalRef\n"); - #endif /* DEBUG */ + if (cls == NULL) { + printf("Couldn't find DerValue\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found DerValue\n"); + #endif /* DEBUG */ - cls = (*env)->FindClass(env,"sun/security/krb5/internal/KerberosTime"); + derValueClass = (*env)->NewWeakGlobalRef(env,cls); + if (derValueClass == NULL) { + return JNI_ERR; + } + #ifdef DEBUG + printf("Made NewWeakGlobalRef\n"); + #endif /* DEBUG */ - if (cls == NULL) { - printf("Couldn't find KerberosTime\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found KerberosTime\n"); - #endif /* DEBUG */ + cls = (*env)->FindClass(env,"sun/security/krb5/EncryptionKey"); - kerberosTimeClass = (*env)->NewWeakGlobalRef(env,cls); - if (kerberosTimeClass == NULL) { - return JNI_ERR; - } - #ifdef DEBUG - printf("Made NewWeakGlobalRef\n"); - #endif /* DEBUG */ + if (cls == NULL) { + printf("Couldn't find EncryptionKey\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found EncryptionKey\n"); + #endif /* DEBUG */ - cls = (*env)->FindClass(env,"java/lang/String"); + encryptionKeyClass = (*env)->NewWeakGlobalRef(env,cls); + if (encryptionKeyClass == NULL) { + return JNI_ERR; + } + #ifdef DEBUG + printf("Made NewWeakGlobalRef\n"); + #endif /* DEBUG */ - if (cls == NULL) { - printf("Couldn't find String\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found String\n"); - #endif /* DEBUG */ + cls = (*env)->FindClass(env,"sun/security/krb5/internal/TicketFlags"); - javaLangStringClass = (*env)->NewWeakGlobalRef(env,cls); - if (javaLangStringClass == NULL) { - return JNI_ERR; - } - #ifdef DEBUG - printf("Made NewWeakGlobalRef\n"); - #endif /* DEBUG */ + if (cls == NULL) { + printf("Couldn't find TicketFlags\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found TicketFlags\n"); + #endif /* DEBUG */ - derValueConstructor = (*env)->GetMethodID(env, derValueClass, - "", "([B)V"); - if (derValueConstructor == 0) { - printf("Couldn't find DerValue constructor\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found DerValue constructor\n"); - #endif /* DEBUG */ + ticketFlagsClass = (*env)->NewWeakGlobalRef(env,cls); + if (ticketFlagsClass == NULL) { + return JNI_ERR; + } + #ifdef DEBUG + printf("Made NewWeakGlobalRef\n"); + #endif /* DEBUG */ - ticketConstructor = (*env)->GetMethodID(env, ticketClass, - "", "(Lsun/security/util/DerValue;)V"); - if (ticketConstructor == 0) { - printf("Couldn't find Ticket constructor\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found Ticket constructor\n"); - #endif /* DEBUG */ + cls = (*env)->FindClass(env,"sun/security/krb5/internal/KerberosTime"); - principalNameConstructor = (*env)->GetMethodID(env, principalNameClass, - "", "([Ljava/lang/String;)V"); - if (principalNameConstructor == 0) { - printf("Couldn't find PrincipalName constructor\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found PrincipalName constructor\n"); - #endif /* DEBUG */ + if (cls == NULL) { + printf("Couldn't find KerberosTime\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found KerberosTime\n"); + #endif /* DEBUG */ - encryptionKeyConstructor = (*env)->GetMethodID(env, encryptionKeyClass, - "", "(I[B)V"); - if (encryptionKeyConstructor == 0) { - printf("Couldn't find EncryptionKey constructor\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found EncryptionKey constructor\n"); - #endif /* DEBUG */ + kerberosTimeClass = (*env)->NewWeakGlobalRef(env,cls); + if (kerberosTimeClass == NULL) { + return JNI_ERR; + } + #ifdef DEBUG + printf("Made NewWeakGlobalRef\n"); + #endif /* DEBUG */ - ticketFlagsConstructor = (*env)->GetMethodID(env, ticketFlagsClass, - "", "(I[B)V"); - if (ticketFlagsConstructor == 0) { - printf("Couldn't find TicketFlags constructor\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found TicketFlags constructor\n"); - #endif /* DEBUG */ + cls = (*env)->FindClass(env,"java/lang/String"); - kerberosTimeConstructor = (*env)->GetMethodID(env, kerberosTimeClass, - "", "(Ljava/lang/String;)V"); - if (kerberosTimeConstructor == 0) { - printf("Couldn't find KerberosTime constructor\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found KerberosTime constructor\n"); - #endif /* DEBUG */ + if (cls == NULL) { + printf("Couldn't find String\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found String\n"); + #endif /* DEBUG */ - // load the setRealm method in PrincipalName - setRealmMethod = (*env)->GetMethodID(env, principalNameClass, - "setRealm", "(Ljava/lang/String;)V"); - if (setRealmMethod == 0) { - printf("Couldn't find setRealm in PrincipalName\n"); - return JNI_ERR; - } + javaLangStringClass = (*env)->NewWeakGlobalRef(env,cls); + if (javaLangStringClass == NULL) { + return JNI_ERR; + } + #ifdef DEBUG + printf("Made NewWeakGlobalRef\n"); + #endif /* DEBUG */ + + derValueConstructor = (*env)->GetMethodID(env, derValueClass, + "", "([B)V"); + if (derValueConstructor == 0) { + printf("Couldn't find DerValue constructor\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found DerValue constructor\n"); + #endif /* DEBUG */ + + ticketConstructor = (*env)->GetMethodID(env, ticketClass, + "", "(Lsun/security/util/DerValue;)V"); + if (ticketConstructor == 0) { + printf("Couldn't find Ticket constructor\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found Ticket constructor\n"); + #endif /* DEBUG */ + + principalNameConstructor = (*env)->GetMethodID(env, principalNameClass, + "", "([Ljava/lang/String;)V"); + if (principalNameConstructor == 0) { + printf("Couldn't find PrincipalName constructor\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found PrincipalName constructor\n"); + #endif /* DEBUG */ + + encryptionKeyConstructor = (*env)->GetMethodID(env, encryptionKeyClass, + "", "(I[B)V"); + if (encryptionKeyConstructor == 0) { + printf("Couldn't find EncryptionKey constructor\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found EncryptionKey constructor\n"); + #endif /* DEBUG */ + + ticketFlagsConstructor = (*env)->GetMethodID(env, ticketFlagsClass, + "", "(I[B)V"); + if (ticketFlagsConstructor == 0) { + printf("Couldn't find TicketFlags constructor\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found TicketFlags constructor\n"); + #endif /* DEBUG */ + + kerberosTimeConstructor = (*env)->GetMethodID(env, kerberosTimeClass, + "", "(Ljava/lang/String;)V"); + if (kerberosTimeConstructor == 0) { + printf("Couldn't find KerberosTime constructor\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found KerberosTime constructor\n"); + #endif /* DEBUG */ + + // load the setRealm method in PrincipalName + setRealmMethod = (*env)->GetMethodID(env, principalNameClass, + "setRealm", "(Ljava/lang/String;)V"); + if (setRealmMethod == 0) { + printf("Couldn't find setRealm in PrincipalName\n"); + return JNI_ERR; + } - #ifdef DEBUG - printf("Finished OnLoad processing\n"); - #endif /* DEBUG */ + #ifdef DEBUG + printf("Finished OnLoad processing\n"); + #endif /* DEBUG */ - return JNI_VERSION_1_2; + return JNI_VERSION_1_2; } /* @@ -325,38 +325,38 @@ JNIEXPORT jint JNICALL JNI_OnLoad( */ JNIEXPORT void JNICALL JNI_OnUnload( - JavaVM *jvm, - void *reserved) { + JavaVM *jvm, + void *reserved) { - JNIEnv *env; + JNIEnv *env; - if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2)) { - return; /* Nothing else we can do */ - } + if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2)) { + return; /* Nothing else we can do */ + } - if (ticketClass != NULL) { - (*env)->DeleteWeakGlobalRef(env,ticketClass); - } - if (derValueClass != NULL) { - (*env)->DeleteWeakGlobalRef(env,derValueClass); - } - if (principalNameClass != NULL) { - (*env)->DeleteWeakGlobalRef(env,principalNameClass); - } - if (encryptionKeyClass != NULL) { - (*env)->DeleteWeakGlobalRef(env,encryptionKeyClass); - } - if (ticketFlagsClass != NULL) { - (*env)->DeleteWeakGlobalRef(env,ticketFlagsClass); - } - if (kerberosTimeClass != NULL) { - (*env)->DeleteWeakGlobalRef(env,kerberosTimeClass); - } - if (javaLangStringClass != NULL) { - (*env)->DeleteWeakGlobalRef(env,javaLangStringClass); - } + if (ticketClass != NULL) { + (*env)->DeleteWeakGlobalRef(env,ticketClass); + } + if (derValueClass != NULL) { + (*env)->DeleteWeakGlobalRef(env,derValueClass); + } + if (principalNameClass != NULL) { + (*env)->DeleteWeakGlobalRef(env,principalNameClass); + } + if (encryptionKeyClass != NULL) { + (*env)->DeleteWeakGlobalRef(env,encryptionKeyClass); + } + if (ticketFlagsClass != NULL) { + (*env)->DeleteWeakGlobalRef(env,ticketFlagsClass); + } + if (kerberosTimeClass != NULL) { + (*env)->DeleteWeakGlobalRef(env,kerberosTimeClass); + } + if (javaLangStringClass != NULL) { + (*env)->DeleteWeakGlobalRef(env,javaLangStringClass); + } - return; + return; } /* @@ -365,31 +365,31 @@ JNIEXPORT void JNICALL JNI_OnUnload( * Signature: ()Lsun/security/krb5/Credentials; */ JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativeCreds( - JNIEnv *env, - jclass krbcredsClass) { - - KERB_QUERY_TKT_CACHE_REQUEST CacheRequest; - PKERB_RETRIEVE_TKT_RESPONSE TktCacheResponse = NULL; - PKERB_RETRIEVE_TKT_REQUEST pTicketRequest = NULL; - PKERB_RETRIEVE_TKT_RESPONSE pTicketResponse = NULL; - NTSTATUS Status, SubStatus; - ULONG requestSize = 0; - ULONG responseSize = 0; - ULONG rspSize = 0; - HANDLE LogonHandle = NULL; - ULONG PackageId; - jobject ticket, clientPrincipal, targetPrincipal, encryptionKey; - jobject ticketFlags, startTime, endTime, krbCreds = NULL; - jobject authTime, renewTillTime, hostAddresses = NULL; - KERB_EXTERNAL_TICKET *msticket; - int ignore_cache = 0; - FILETIME Now, EndTime, LocalEndTime; - - while (TRUE) { + JNIEnv *env, + jclass krbcredsClass) { + + KERB_QUERY_TKT_CACHE_REQUEST CacheRequest; + PKERB_RETRIEVE_TKT_RESPONSE TktCacheResponse = NULL; + PKERB_RETRIEVE_TKT_REQUEST pTicketRequest = NULL; + PKERB_RETRIEVE_TKT_RESPONSE pTicketResponse = NULL; + NTSTATUS Status, SubStatus; + ULONG requestSize = 0; + ULONG responseSize = 0; + ULONG rspSize = 0; + HANDLE LogonHandle = NULL; + ULONG PackageId; + jobject ticket, clientPrincipal, targetPrincipal, encryptionKey; + jobject ticketFlags, startTime, endTime, krbCreds = NULL; + jobject authTime, renewTillTime, hostAddresses = NULL; + KERB_EXTERNAL_TICKET *msticket; + int ignore_cache = 0; + FILETIME Now, EndTime, LocalEndTime; + + while (TRUE) { if (krbcredsConstructor == 0) { - krbcredsConstructor = (*env)->GetMethodID(env, krbcredsClass, "", - "(Lsun/security/krb5/internal/Ticket;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/EncryptionKey;Lsun/security/krb5/internal/TicketFlags;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/HostAddresses;)V"); + krbcredsConstructor = (*env)->GetMethodID(env, krbcredsClass, "", + "(Lsun/security/krb5/internal/Ticket;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/EncryptionKey;Lsun/security/krb5/internal/TicketFlags;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/HostAddresses;)V"); if (krbcredsConstructor == 0) { printf("Couldn't find sun.security.krb5.Credentials constructor\n"); break; @@ -510,88 +510,88 @@ JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativ msticket = &(pTicketResponse->Ticket); } -/* - -typedef struct _KERB_RETRIEVE_TKT_RESPONSE { - KERB_EXTERNAL_TICKET Ticket; -} KERB_RETRIEVE_TKT_RESPONSE, *PKERB_RETRIEVE_TKT_RESPONSE; - -typedef struct _KERB_EXTERNAL_TICKET { - PKERB_EXTERNAL_NAME ServiceName; - PKERB_EXTERNAL_NAME TargetName; - PKERB_EXTERNAL_NAME ClientName; - UNICODE_STRING DomainName; - UNICODE_STRING TargetDomainName; - UNICODE_STRING AltTargetDomainName; - KERB_CRYPTO_KEY SessionKey; - ULONG TicketFlags; - ULONG Flags; - LARGE_INTEGER KeyExpirationTime; - LARGE_INTEGER StartTime; - LARGE_INTEGER EndTime; - LARGE_INTEGER RenewUntil; - LARGE_INTEGER TimeSkew; - ULONG EncodedTicketSize; - PUCHAR EncodedTicket; <========== Here's the good stuff -} KERB_EXTERNAL_TICKET, *PKERB_EXTERNAL_TICKET; - -typedef struct _KERB_EXTERNAL_NAME { - SHORT NameType; - USHORT NameCount; - UNICODE_STRING Names[ANYSIZE_ARRAY]; -} KERB_EXTERNAL_NAME, *PKERB_EXTERNAL_NAME; - -typedef struct _LSA_UNICODE_STRING { - USHORT Length; - USHORT MaximumLength; - PWSTR Buffer; -} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING; - -typedef LSA_UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING; - -typedef struct KERB_CRYPTO_KEY { - LONG KeyType; - ULONG Length; - PUCHAR Value; -} KERB_CRYPTO_KEY, *PKERB_CRYPTO_KEY; + /* -*/ + typedef struct _KERB_RETRIEVE_TKT_RESPONSE { + KERB_EXTERNAL_TICKET Ticket; + } KERB_RETRIEVE_TKT_RESPONSE, *PKERB_RETRIEVE_TKT_RESPONSE; + + typedef struct _KERB_EXTERNAL_TICKET { + PKERB_EXTERNAL_NAME ServiceName; + PKERB_EXTERNAL_NAME TargetName; + PKERB_EXTERNAL_NAME ClientName; + UNICODE_STRING DomainName; + UNICODE_STRING TargetDomainName; + UNICODE_STRING AltTargetDomainName; + KERB_CRYPTO_KEY SessionKey; + ULONG TicketFlags; + ULONG Flags; + LARGE_INTEGER KeyExpirationTime; + LARGE_INTEGER StartTime; + LARGE_INTEGER EndTime; + LARGE_INTEGER RenewUntil; + LARGE_INTEGER TimeSkew; + ULONG EncodedTicketSize; + PUCHAR EncodedTicket; <========== Here's the good stuff + } KERB_EXTERNAL_TICKET, *PKERB_EXTERNAL_TICKET; + + typedef struct _KERB_EXTERNAL_NAME { + SHORT NameType; + USHORT NameCount; + UNICODE_STRING Names[ANYSIZE_ARRAY]; + } KERB_EXTERNAL_NAME, *PKERB_EXTERNAL_NAME; + + typedef struct _LSA_UNICODE_STRING { + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; + } LSA_UNICODE_STRING, *PLSA_UNICODE_STRING; + + typedef LSA_UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING; + + typedef struct KERB_CRYPTO_KEY { + LONG KeyType; + ULONG Length; + PUCHAR Value; + } KERB_CRYPTO_KEY, *PKERB_CRYPTO_KEY; + + */ // Build a com.sun.security.krb5.Ticket ticket = BuildTicket(env, msticket->EncodedTicket, msticket->EncodedTicketSize); if (ticket == NULL) { - break; + break; } // OK, have a Ticket, now need to get the client name clientPrincipal = BuildPrincipal(env, msticket->ClientName, msticket->TargetDomainName); // mdu if (clientPrincipal == NULL) { - break; + break; } // and the "name" of tgt targetPrincipal = BuildPrincipal(env, msticket->ServiceName, msticket->DomainName); if (targetPrincipal == NULL) { - break; + break; } // Get the encryption key encryptionKey = BuildEncryptionKey(env, &(msticket->SessionKey)); if (encryptionKey == NULL) { - break; + break; } // and the ticket flags ticketFlags = BuildTicketFlags(env, &(msticket->TicketFlags)); if (ticketFlags == NULL) { - break; + break; } // Get the start time startTime = BuildKerberosTime(env, &(msticket->StartTime)); if (startTime == NULL) { - break; + break; } /* @@ -604,13 +604,13 @@ typedef struct KERB_CRYPTO_KEY { // and the end time endTime = BuildKerberosTime(env, &(msticket->EndTime)); if (endTime == NULL) { - break; + break; } // Get the renew till time renewTillTime = BuildKerberosTime(env, &(msticket->RenewUntil)); if (renewTillTime == NULL) { - break; + break; } // and now go build a KrbCreds object @@ -630,87 +630,87 @@ typedef struct KERB_CRYPTO_KEY { hostAddresses); break; - } // end of WHILE + } // end of WHILE - // clean up resources - if (TktCacheResponse != NULL) { - LsaFreeReturnBuffer(TktCacheResponse); - } - if (pTicketRequest) { - LocalFree(pTicketRequest); - } - if (pTicketResponse != NULL) { - LsaFreeReturnBuffer(pTicketResponse); - } + // clean up resources + if (TktCacheResponse != NULL) { + LsaFreeReturnBuffer(TktCacheResponse); + } + if (pTicketRequest) { + LocalFree(pTicketRequest); + } + if (pTicketResponse != NULL) { + LsaFreeReturnBuffer(pTicketResponse); + } - return krbCreds; + return krbCreds; } static NTSTATUS ConstructTicketRequest(UNICODE_STRING DomainName, PKERB_RETRIEVE_TKT_REQUEST *outRequest, ULONG *outSize) { - NTSTATUS Status; - UNICODE_STRING TargetPrefix; - USHORT TargetSize; - ULONG RequestSize; - ULONG Length; - PKERB_RETRIEVE_TKT_REQUEST pTicketRequest = NULL; + NTSTATUS Status; + UNICODE_STRING TargetPrefix; + USHORT TargetSize; + ULONG RequestSize; + ULONG Length; + PKERB_RETRIEVE_TKT_REQUEST pTicketRequest = NULL; - *outRequest = NULL; - *outSize = 0; + *outRequest = NULL; + *outSize = 0; - // - // Set up the "krbtgt/" target prefix into a UNICODE_STRING so we - // can easily concatenate it later. - // + // + // Set up the "krbtgt/" target prefix into a UNICODE_STRING so we + // can easily concatenate it later. + // - TargetPrefix.Buffer = L"krbtgt/"; - Length = (ULONG)wcslen(TargetPrefix.Buffer) * sizeof(WCHAR); - TargetPrefix.Length = (USHORT)Length; - TargetPrefix.MaximumLength = TargetPrefix.Length; + TargetPrefix.Buffer = L"krbtgt/"; + Length = (ULONG)wcslen(TargetPrefix.Buffer) * sizeof(WCHAR); + TargetPrefix.Length = (USHORT)Length; + TargetPrefix.MaximumLength = TargetPrefix.Length; - // - // We will need to concatenate the "krbtgt/" prefix and the - // Logon Session's DnsDomainName into our request's target name. - // - // Therefore, first compute the necessary buffer size for that. - // - // Note that we might theoretically have integer overflow. - // + // + // We will need to concatenate the "krbtgt/" prefix and the + // Logon Session's DnsDomainName into our request's target name. + // + // Therefore, first compute the necessary buffer size for that. + // + // Note that we might theoretically have integer overflow. + // - TargetSize = TargetPrefix.Length + DomainName.Length; + TargetSize = TargetPrefix.Length + DomainName.Length; - // - // The ticket request buffer needs to be a single buffer. That buffer - // needs to include the buffer for the target name. - // + // + // The ticket request buffer needs to be a single buffer. That buffer + // needs to include the buffer for the target name. + // - RequestSize = sizeof (*pTicketRequest) + TargetSize; + RequestSize = sizeof (*pTicketRequest) + TargetSize; - // - // Allocate the request buffer and make sure it's zero-filled. - // + // + // Allocate the request buffer and make sure it's zero-filled. + // - pTicketRequest = (PKERB_RETRIEVE_TKT_REQUEST) - LocalAlloc(LMEM_ZEROINIT, RequestSize); - if (!pTicketRequest) - return GetLastError(); + pTicketRequest = (PKERB_RETRIEVE_TKT_REQUEST) + LocalAlloc(LMEM_ZEROINIT, RequestSize); + if (!pTicketRequest) + return GetLastError(); - // - // Concatenate the target prefix with the previous reponse's - // target domain. - // + // + // Concatenate the target prefix with the previous reponse's + // target domain. + // - pTicketRequest->TargetName.Length = 0; - pTicketRequest->TargetName.MaximumLength = TargetSize; - pTicketRequest->TargetName.Buffer = (PWSTR) (pTicketRequest + 1); - Status = ConcatenateUnicodeStrings(&(pTicketRequest->TargetName), - TargetPrefix, - DomainName); - *outRequest = pTicketRequest; - *outSize = RequestSize; - return Status; + pTicketRequest->TargetName.Length = 0; + pTicketRequest->TargetName.MaximumLength = TargetSize; + pTicketRequest->TargetName.Buffer = (PWSTR) (pTicketRequest + 1); + Status = ConcatenateUnicodeStrings(&(pTicketRequest->TargetName), + TargetPrefix, + DomainName); + *outRequest = pTicketRequest; + *outSize = RequestSize; + return Status; } DWORD @@ -720,22 +720,22 @@ ConcatenateUnicodeStrings( UNICODE_STRING Source2 ) { - // - // The buffers for Source1 and Source2 cannot overlap pTarget's - // buffer. Source1.Length + Source2.Length must be <= 0xFFFF, - // otherwise we overflow... - // + // + // The buffers for Source1 and Source2 cannot overlap pTarget's + // buffer. Source1.Length + Source2.Length must be <= 0xFFFF, + // otherwise we overflow... + // - USHORT TotalSize = Source1.Length + Source2.Length; - PBYTE buffer = (PBYTE) pTarget->Buffer; + USHORT TotalSize = Source1.Length + Source2.Length; + PBYTE buffer = (PBYTE) pTarget->Buffer; - if (TotalSize > pTarget->MaximumLength) - return ERROR_INSUFFICIENT_BUFFER; + if (TotalSize > pTarget->MaximumLength) + return ERROR_INSUFFICIENT_BUFFER; - pTarget->Length = TotalSize; - memcpy(buffer, Source1.Buffer, Source1.Length); - memcpy(buffer + Source1.Length, Source2.Buffer, Source2.Length); - return ERROR_SUCCESS; + pTarget->Length = TotalSize; + memcpy(buffer, Source1.Buffer, Source1.Length); + memcpy(buffer + Source1.Length, Source2.Buffer, Source2.Length); + return ERROR_SUCCESS; } BOOL @@ -783,27 +783,27 @@ ShowLastError( DWORD dwError ) { - #define MAX_MSG_SIZE 256 - - static WCHAR szMsgBuf[MAX_MSG_SIZE]; - DWORD dwRes; - - printf("Error calling function %s: %lu\n", szAPI, dwError); - - dwRes = FormatMessage ( - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - dwError, - 0, - szMsgBuf, - MAX_MSG_SIZE, - NULL); - if (0 == dwRes) { - printf("FormatMessage failed with %d\n", GetLastError()); - // ExitProcess(EXIT_FAILURE); - } else { - printf("%S",szMsgBuf); - } + #define MAX_MSG_SIZE 256 + + static WCHAR szMsgBuf[MAX_MSG_SIZE]; + DWORD dwRes; + + printf("Error calling function %s: %lu\n", szAPI, dwError); + + dwRes = FormatMessage ( + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + dwError, + 0, + szMsgBuf, + MAX_MSG_SIZE, + NULL); + if (0 == dwRes) { + printf("FormatMessage failed with %d\n", GetLastError()); + // ExitProcess(EXIT_FAILURE); + } else { + printf("%S",szMsgBuf); + } } VOID @@ -831,189 +831,189 @@ InitUnicodeString( Length = (ULONG)wcslen( SourceString ) * sizeof( WCHAR ); DestinationString->Length = (USHORT)Length; DestinationString->MaximumLength = (USHORT)(Length + sizeof(UNICODE_NULL)); - } + } else { DestinationString->MaximumLength = 0; DestinationString->Length = 0; - } + } } jobject BuildTicket(JNIEnv *env, PUCHAR encodedTicket, ULONG encodedTicketSize) { - /* To build a Ticket, we first need to build a DerValue out of the EncodedTicket. - * But before we can do that, we need to make a byte array out of the ET. - */ - - jobject derValue, ticket; - jbyteArray ary; + /* To build a Ticket, we first need to build a DerValue out of the EncodedTicket. + * But before we can do that, we need to make a byte array out of the ET. + */ - ary = (*env)->NewByteArray(env,encodedTicketSize); - if ((*env)->ExceptionOccurred(env)) { - return (jobject) NULL; - } + jobject derValue, ticket; + jbyteArray ary; - (*env)->SetByteArrayRegion(env, ary, (jsize) 0, encodedTicketSize, - (jbyte *)encodedTicket); - if ((*env)->ExceptionOccurred(env)) { - (*env)->DeleteLocalRef(env, ary); - return (jobject) NULL; - } + ary = (*env)->NewByteArray(env,encodedTicketSize); + if ((*env)->ExceptionOccurred(env)) { + return (jobject) NULL; + } - derValue = (*env)->NewObject(env, derValueClass, derValueConstructor, ary); - if ((*env)->ExceptionOccurred(env)) { - (*env)->DeleteLocalRef(env, ary); - return (jobject) NULL; - } + (*env)->SetByteArrayRegion(env, ary, (jsize) 0, encodedTicketSize, + (jbyte *)encodedTicket); + if ((*env)->ExceptionOccurred(env)) { + (*env)->DeleteLocalRef(env, ary); + return (jobject) NULL; + } + derValue = (*env)->NewObject(env, derValueClass, derValueConstructor, ary); + if ((*env)->ExceptionOccurred(env)) { (*env)->DeleteLocalRef(env, ary); - ticket = (*env)->NewObject(env, ticketClass, ticketConstructor, derValue); - if ((*env)->ExceptionOccurred(env)) { - (*env)->DeleteLocalRef(env, derValue); - return (jobject) NULL; - } + return (jobject) NULL; + } + + (*env)->DeleteLocalRef(env, ary); + ticket = (*env)->NewObject(env, ticketClass, ticketConstructor, derValue); + if ((*env)->ExceptionOccurred(env)) { (*env)->DeleteLocalRef(env, derValue); - return ticket; + return (jobject) NULL; + } + (*env)->DeleteLocalRef(env, derValue); + return ticket; } // mdu jobject BuildPrincipal(JNIEnv *env, PKERB_EXTERNAL_NAME principalName, UNICODE_STRING domainName) { - /* - * To build the Principal, we need to get the names out of - * this goofy MS structure - */ - jobject principal = NULL; - jobject realmStr = NULL; - jobjectArray stringArray; - jstring tempString; - int nameCount,i; - PUNICODE_STRING scanner; - WCHAR *realm; - ULONG realmLen; - - realm = (WCHAR *) LocalAlloc(LMEM_ZEROINIT, - ((domainName.Length)*sizeof(WCHAR) + sizeof(UNICODE_NULL))); - wcsncpy(realm, domainName.Buffer, domainName.Length/sizeof(WCHAR)); - - #ifdef DEBUG - printf("Principal domain is %S\n", realm); - printf("Name type is %x\n", principalName->NameType); - printf("Name count is %x\n", principalName->NameCount); - #endif - - nameCount = principalName->NameCount; - stringArray = (*env)->NewObjectArray(env, nameCount, - javaLangStringClass, NULL); - if (stringArray == NULL) { - printf("Can't allocate String array for Principal\n"); - LocalFree(realm); - return principal; - } + /* + * To build the Principal, we need to get the names out of + * this goofy MS structure + */ + jobject principal = NULL; + jobject realmStr = NULL; + jobjectArray stringArray; + jstring tempString; + int nameCount,i; + PUNICODE_STRING scanner; + WCHAR *realm; + ULONG realmLen; + + realm = (WCHAR *) LocalAlloc(LMEM_ZEROINIT, + ((domainName.Length)*sizeof(WCHAR) + sizeof(UNICODE_NULL))); + wcsncpy(realm, domainName.Buffer, domainName.Length/sizeof(WCHAR)); + + #ifdef DEBUG + printf("Principal domain is %S\n", realm); + printf("Name type is %x\n", principalName->NameType); + printf("Name count is %x\n", principalName->NameCount); + #endif + + nameCount = principalName->NameCount; + stringArray = (*env)->NewObjectArray(env, nameCount, + javaLangStringClass, NULL); + if (stringArray == NULL) { + printf("Can't allocate String array for Principal\n"); + LocalFree(realm); + return principal; + } - for (i=0; iNames[i]); + for (i=0; iNames[i]); - // OK, got a Char array, so construct a String - tempString = (*env)->NewString(env, (const jchar*)scanner->Buffer, - scanner->Length/sizeof(WCHAR)); - // Set the String into the StringArray - (*env)->SetObjectArrayElement(env, stringArray, i, tempString); + // OK, got a Char array, so construct a String + tempString = (*env)->NewString(env, (const jchar*)scanner->Buffer, + scanner->Length/sizeof(WCHAR)); + // Set the String into the StringArray + (*env)->SetObjectArrayElement(env, stringArray, i, tempString); - // Do I have to worry about storage reclamation here? - } - principal = (*env)->NewObject(env, principalNameClass, - principalNameConstructor, stringArray); + // Do I have to worry about storage reclamation here? + } + principal = (*env)->NewObject(env, principalNameClass, + principalNameConstructor, stringArray); - // now set the realm in the principal - realmLen = (ULONG)wcslen((PWCHAR)realm); - realmStr = (*env)->NewString(env, (PWCHAR)realm, (USHORT)realmLen); - (*env)->CallVoidMethod(env, principal, setRealmMethod, realmStr); + // now set the realm in the principal + realmLen = (ULONG)wcslen((PWCHAR)realm); + realmStr = (*env)->NewString(env, (PWCHAR)realm, (USHORT)realmLen); + (*env)->CallVoidMethod(env, principal, setRealmMethod, realmStr); - // free local resources - LocalFree(realm); + // free local resources + LocalFree(realm); - return principal; + return principal; } jobject BuildEncryptionKey(JNIEnv *env, PKERB_CRYPTO_KEY cryptoKey) { - // First, need to build a byte array - jbyteArray ary; - jobject encryptionKey = NULL; - - ary = (*env)->NewByteArray(env,cryptoKey->Length); - (*env)->SetByteArrayRegion(env, ary, (jsize) 0, cryptoKey->Length, - (jbyte *)cryptoKey->Value); - if ((*env)->ExceptionOccurred(env)) { - (*env)->DeleteLocalRef(env, ary); - } else { - encryptionKey = (*env)->NewObject(env, encryptionKeyClass, - encryptionKeyConstructor, cryptoKey->KeyType, ary); - } + // First, need to build a byte array + jbyteArray ary; + jobject encryptionKey = NULL; + + ary = (*env)->NewByteArray(env,cryptoKey->Length); + (*env)->SetByteArrayRegion(env, ary, (jsize) 0, cryptoKey->Length, + (jbyte *)cryptoKey->Value); + if ((*env)->ExceptionOccurred(env)) { + (*env)->DeleteLocalRef(env, ary); + } else { + encryptionKey = (*env)->NewObject(env, encryptionKeyClass, + encryptionKeyConstructor, cryptoKey->KeyType, ary); + } - return encryptionKey; + return encryptionKey; } jobject BuildTicketFlags(JNIEnv *env, PULONG flags) { - jobject ticketFlags = NULL; - jbyteArray ary; - /* - * mdu: Convert the bytes to nework byte order before copying - * them to a Java byte array. - */ - ULONG nlflags = htonl(*flags); - - ary = (*env)->NewByteArray(env, sizeof(*flags)); - (*env)->SetByteArrayRegion(env, ary, (jsize) 0, sizeof(*flags), - (jbyte *)&nlflags); - if ((*env)->ExceptionOccurred(env)) { - (*env)->DeleteLocalRef(env, ary); - } else { - ticketFlags = (*env)->NewObject(env, ticketFlagsClass, - ticketFlagsConstructor, sizeof(*flags)*8, ary); - } + jobject ticketFlags = NULL; + jbyteArray ary; + /* + * mdu: Convert the bytes to nework byte order before copying + * them to a Java byte array. + */ + ULONG nlflags = htonl(*flags); + + ary = (*env)->NewByteArray(env, sizeof(*flags)); + (*env)->SetByteArrayRegion(env, ary, (jsize) 0, sizeof(*flags), + (jbyte *)&nlflags); + if ((*env)->ExceptionOccurred(env)) { + (*env)->DeleteLocalRef(env, ary); + } else { + ticketFlags = (*env)->NewObject(env, ticketFlagsClass, + ticketFlagsConstructor, sizeof(*flags)*8, ary); + } - return ticketFlags; + return ticketFlags; } jobject BuildKerberosTime(JNIEnv *env, PLARGE_INTEGER kerbtime) { - jobject kerberosTime = NULL; - jstring stringTime = NULL; - SYSTEMTIME systemTime; - WCHAR timeString[16]; - WCHAR month[3]; - WCHAR day[3]; - WCHAR hour[3]; - WCHAR minute[3]; - WCHAR second[3]; - - if (FileTimeToSystemTime((FILETIME *)kerbtime, &systemTime)) { -// XXX Cannot use %02.2ld, because the leading 0 is ignored for integers. -// So, print them to strings, and then print them to the master string with a -// format pattern that makes it two digits and prefix with a 0 if necessary. - swprintf( (wchar_t *)month, L"%2.2d", systemTime.wMonth); - swprintf( (wchar_t *)day, L"%2.2d", systemTime.wDay); - swprintf( (wchar_t *)hour, L"%2.2d", systemTime.wHour); - swprintf( (wchar_t *)minute, L"%2.2d", systemTime.wMinute); - swprintf( (wchar_t *)second, L"%2.2d", systemTime.wSecond); - swprintf( (wchar_t *)timeString, - L"%ld%02.2s%02.2s%02.2s%02.2s%02.2sZ", + jobject kerberosTime = NULL; + jstring stringTime = NULL; + SYSTEMTIME systemTime; + WCHAR timeString[16]; + WCHAR month[3]; + WCHAR day[3]; + WCHAR hour[3]; + WCHAR minute[3]; + WCHAR second[3]; + + if (FileTimeToSystemTime((FILETIME *)kerbtime, &systemTime)) { + // XXX Cannot use %02.2ld, because the leading 0 is ignored for integers. + // So, print them to strings, and then print them to the master string with a + // format pattern that makes it two digits and prefix with a 0 if necessary. + swprintf( (wchar_t *)month, L"%2.2d", systemTime.wMonth); + swprintf( (wchar_t *)day, L"%2.2d", systemTime.wDay); + swprintf( (wchar_t *)hour, L"%2.2d", systemTime.wHour); + swprintf( (wchar_t *)minute, L"%2.2d", systemTime.wMinute); + swprintf( (wchar_t *)second, L"%2.2d", systemTime.wSecond); + swprintf( (wchar_t *)timeString, + L"%ld%02.2s%02.2s%02.2s%02.2s%02.2sZ", systemTime.wYear, month, day, hour, minute, second ); - #ifdef DEBUG - printf("%S\n", (wchar_t *)timeString); - #endif /* DEBUG */ - stringTime = (*env)->NewString(env, timeString, - (sizeof(timeString)/sizeof(WCHAR))-1); - if (stringTime != NULL) { // everything's OK so far - kerberosTime = (*env)->NewObject(env, kerberosTimeClass, - kerberosTimeConstructor, stringTime); - } + #ifdef DEBUG + printf("%S\n", (wchar_t *)timeString); + #endif /* DEBUG */ + stringTime = (*env)->NewString(env, timeString, + (sizeof(timeString)/sizeof(WCHAR))-1); + if (stringTime != NULL) { // everything's OK so far + kerberosTime = (*env)->NewObject(env, kerberosTimeClass, + kerberosTimeConstructor, stringTime); } - return kerberosTime; + } + return kerberosTime; } diff --git a/src/windows/native/sun/windows/awt.h b/src/windows/native/sun/windows/awt.h index 9043367f6794b638c14164157e2605cec840e8e4..2a1d9904c9bb0f2faf3303ac6257d2734b55c503 100644 --- a/src/windows/native/sun/windows/awt.h +++ b/src/windows/native/sun/windows/awt.h @@ -1,5 +1,5 @@ /* - * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. 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 @@ -47,7 +47,7 @@ typedef AwtObject* PDATA; JNI_CHECK_NULL_GOTO(peer, "peer", where); \ pData = JNI_GET_PDATA(peer); \ if (pData == NULL) { \ - JNU_ThrowNullPointerException(env, "null pData"); \ + THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \ goto where; \ } \ } @@ -63,7 +63,7 @@ typedef AwtObject* PDATA; JNI_CHECK_NULL_RETURN(peer, "peer"); \ pData = JNI_GET_PDATA(peer); \ if (pData == NULL) { \ - JNU_ThrowNullPointerException(env, "null pData"); \ + THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \ return; \ } \ } @@ -96,7 +96,7 @@ typedef AwtObject* PDATA; JNI_CHECK_NULL_RETURN_NULL(peer, "peer"); \ pData = JNI_GET_PDATA(peer); \ if (pData == NULL) { \ - JNU_ThrowNullPointerException(env, "null pData"); \ + THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \ return 0; \ } \ } @@ -105,16 +105,27 @@ typedef AwtObject* PDATA; JNI_CHECK_NULL_RETURN_VAL(peer, "peer", val); \ pData = JNI_GET_PDATA(peer); \ if (pData == NULL) { \ - JNU_ThrowNullPointerException(env, "null pData"); \ + THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \ return val; \ } \ } +#define THROW_NULL_PDATA_IF_NOT_DESTROYED(peer) { \ + jboolean destroyed = JNI_GET_DESTROYED(peer); \ + if (destroyed != JNI_TRUE) { \ + JNU_ThrowNullPointerException(env, "null pData"); \ + } \ +} + #define JNI_GET_PDATA(peer) (PDATA) env->GetLongField(peer, AwtObject::pDataID) +#define JNI_GET_DESTROYED(peer) env->GetBooleanField(peer, AwtObject::destroyedID) #define JNI_SET_PDATA(peer, data) env->SetLongField(peer, \ - AwtObject::pDataID, \ - (jlong)data) + AwtObject::pDataID, \ + (jlong)data) +#define JNI_SET_DESTROYED(peer) env->SetBooleanField(peer, \ + AwtObject::destroyedID, \ + JNI_TRUE) /* /NEW JNI */ /* diff --git a/src/windows/native/sun/windows/awt_Component.cpp b/src/windows/native/sun/windows/awt_Component.cpp index cba88cdf8c4f2982e792128207f2beec736fad74..f58237861109137dc09672ba5c99cfae8cda3b4f 100644 --- a/src/windows/native/sun/windows/awt_Component.cpp +++ b/src/windows/native/sun/windows/awt_Component.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. 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 @@ -226,6 +226,8 @@ BOOL AwtComponent::m_QueryNewPaletteCalled = FALSE; CriticalSection windowMoveLock; BOOL windowMoveLockHeld = FALSE; +int AwtComponent::sm_wheelRotationAmount = 0; + /************************************************************************ * AwtComponent methods */ @@ -2074,6 +2076,8 @@ MsgRouting AwtComponent::WmSetFocus(HWND hWndLostFocus) sm_realFocusOpposite = NULL; } + sm_wheelRotationAmount = 0; + SendFocusEvent(java_awt_event_FocusEvent_FOCUS_GAINED, hWndLostFocus); return mrDoDefault; @@ -2105,6 +2109,7 @@ MsgRouting AwtComponent::WmKillFocus(HWND hWndGotFocus) } sm_focusOwner = NULL; + sm_wheelRotationAmount = 0; SendFocusEvent(java_awt_event_FocusEvent_FOCUS_LOST, hWndGotFocus); return mrDoDefault; @@ -2190,8 +2195,11 @@ AwtComponent::AwtSetFocus() DWORD fgProcessID; ::GetWindowThreadProcessId(fgWindow, &fgProcessID); - if (fgProcessID != ::GetCurrentProcessId()) { - // fix for 6458497. we shouldn't request focus if it is out of our application. + if (fgProcessID != ::GetCurrentProcessId() + && !AwtToolkit::GetInstance().IsEmbedderProcessId(fgProcessID)) + { + // fix for 6458497. we shouldn't request focus if it is out of both + // our and embedder process. return FALSE; } } @@ -2619,9 +2627,13 @@ MsgRouting AwtComponent::WmMouseWheel(UINT flags, int x, int y, BOOL result; UINT platformLines; + sm_wheelRotationAmount += wheelRotation; + // AWT interprets wheel rotation differently than win32, so we need to // decode wheel amount. - jint newWheelRotation = wheelRotation / (-1 * WHEEL_DELTA); + jint roundedWheelRotation = sm_wheelRotationAmount / (-1 * WHEEL_DELTA); + jdouble preciseWheelRotation = (jdouble) wheelRotation / (-1 * WHEEL_DELTA); + MSG msg; if (IS_WIN95 && !IS_WIN98) { @@ -2654,7 +2666,9 @@ MsgRouting AwtComponent::WmMouseWheel(UINT flags, int x, int y, SendMouseWheelEvent(java_awt_event_MouseEvent_MOUSE_WHEEL, TimeHelper::getMessageTimeUTC(), eventPt.x, eventPt.y, GetJavaModifiers(), 0, 0, scrollType, - scrollLines, newWheelRotation, &msg); + scrollLines, roundedWheelRotation, preciseWheelRotation, &msg); + + sm_wheelRotationAmount %= WHEEL_DELTA; return mrConsume; } @@ -4986,8 +5000,8 @@ void AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y, jint modifiers, jint clickCount, jboolean popupTrigger, jint scrollType, - jint scrollAmount, jint wheelRotation, - MSG *pMsg) + jint scrollAmount, jint roundedWheelRotation, + jdouble preciseWheelRotation, MSG *pMsg) { /* Code based not so loosely on AwtComponent::SendMouseEvent */ JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); @@ -5015,7 +5029,7 @@ AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y, if (mouseWheelEventConst == NULL) { mouseWheelEventConst = env->GetMethodID(mouseWheelEventCls, "", - "(Ljava/awt/Component;IJIIIIZIII)V"); + "(Ljava/awt/Component;IJIIIIIIZIIID)V"); DASSERT(mouseWheelEventConst); } if (env->EnsureLocalCapacity(2) < 0) { @@ -5023,14 +5037,16 @@ AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y, } jobject target = GetTarget(env); DTRACE_PRINTLN("creating MWE in JNI"); + jobject mouseWheelEvent = env->NewObject(mouseWheelEventCls, mouseWheelEventConst, target, id, when, modifiers, x+insets.left, y+insets.top, + 0, 0, clickCount, popupTrigger, scrollType, scrollAmount, - wheelRotation); + roundedWheelRotation, preciseWheelRotation); if (safe_ExceptionOccurred(env)) { env->ExceptionDescribe(); env->ExceptionClear(); @@ -5400,6 +5416,7 @@ void AwtComponent::UnlinkObjects() if (m_peerObject) { env->SetLongField(m_peerObject, AwtComponent::hwndID, 0); JNI_SET_PDATA(m_peerObject, static_cast(NULL)); + JNI_SET_DESTROYED(m_peerObject); env->DeleteGlobalRef(m_peerObject); m_peerObject = NULL; } @@ -5408,7 +5425,13 @@ void AwtComponent::UnlinkObjects() void AwtComponent::Enable(BOOL bEnable) { sm_suppressFocusAndActivation = TRUE; + + if (bEnable && IsTopLevel()) { + // we should not enable blocked toplevels + bEnable = !::IsWindow(AwtWindow::GetModalBlocker(GetHWnd())); + } ::EnableWindow(GetHWnd(), bEnable); + sm_suppressFocusAndActivation = FALSE; CriticalSection::Lock l(GetLock()); VerifyState(); diff --git a/src/windows/native/sun/windows/awt_Component.h b/src/windows/native/sun/windows/awt_Component.h index cecab39830519dc9fec507c697e378393c17f539..ecc7ef5ea33daa9883b2a12dc725e8a001be1a77 100644 --- a/src/windows/native/sun/windows/awt_Component.h +++ b/src/windows/native/sun/windows/awt_Component.h @@ -392,7 +392,7 @@ public: jint modifiers, jint clickCount, jboolean popupTrigger, jint scrollType, jint scrollAmount, jint wheelRotation, - MSG *msg = NULL); + jdouble preciseWheelRotation, MSG *msg = NULL); /* * Allocate and initialize a new java.awt.event.FocusEvent, and @@ -785,7 +785,9 @@ private: int windowMoveLockPosCX; int windowMoveLockPosCY; -private: + // 6524352: support finer-resolution + static int sm_wheelRotationAmount; + /* * The association list of children's IDs and corresponding components. * Some components like Choice or List are required their sizes while diff --git a/src/windows/native/sun/windows/awt_Dialog.cpp b/src/windows/native/sun/windows/awt_Dialog.cpp index 072ed2ba65b3024c20c4326c9c80d408290bc621..0c98fc0d9fe8982974d2ced60ae9ee9df865ca93 100644 --- a/src/windows/native/sun/windows/awt_Dialog.cpp +++ b/src/windows/native/sun/windows/awt_Dialog.cpp @@ -273,6 +273,10 @@ LRESULT CALLBACK AwtDialog::MouseHookProc(int nCode, { HWND blocker = AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(hWnd)); HWND topMostBlocker = blocker; + HWND prevForegroundWindow = ::GetForegroundWindow(); + if (::IsWindow(blocker)) { + ::BringWindowToTop(hWnd); + } while (::IsWindow(blocker)) { topMostBlocker = blocker; ::BringWindowToTop(blocker); @@ -282,7 +286,7 @@ LRESULT CALLBACK AwtDialog::MouseHookProc(int nCode, // no beep/flash if the mouse was clicked in the taskbar menu // or the dialog is currently inactive if ((::WindowFromPoint(mhs->pt) == hWnd) && - (::GetForegroundWindow() == topMostBlocker)) + (prevForegroundWindow == topMostBlocker)) { ::MessageBeep(MB_OK); // some heuristics: 3 times x 64 milliseconds @@ -292,6 +296,7 @@ LRESULT CALLBACK AwtDialog::MouseHookProc(int nCode, ::BringWindowToTop(topMostBlocker); ::SetForegroundWindow(topMostBlocker); } + return 1; } } } diff --git a/src/windows/native/sun/windows/awt_Frame.cpp b/src/windows/native/sun/windows/awt_Frame.cpp index 0ba898419269978f557feb2fd7e974f0583fd8a6..37e8546ed49efa52a3621a2693dad6a4ee1b614b 100644 --- a/src/windows/native/sun/windows/awt_Frame.cpp +++ b/src/windows/native/sun/windows/awt_Frame.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. 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 @@ -221,8 +221,7 @@ AwtFrame* AwtFrame::Create(jobject self, jobject parent) // Update target's dimensions to reflect this embedded window. ::GetClientRect(frame->m_hwnd, &rect); - ::MapWindowPoints(frame->m_hwnd, hwndParent, (LPPOINT)&rect, - 2); + ::MapWindowPoints(frame->m_hwnd, hwndParent, (LPPOINT)&rect, 2); env->SetIntField(target, AwtComponent::xID, rect.left); env->SetIntField(target, AwtComponent::yID, rect.top); @@ -231,6 +230,7 @@ AwtFrame* AwtFrame::Create(jobject self, jobject parent) env->SetIntField(target, AwtComponent::heightID, rect.bottom-rect.top); frame->InitPeerGraphicsConfig(env, self); + AwtToolkit::GetInstance().RegisterEmbedderProcessId(hwndParent); } else { jint state = env->GetIntField(target, AwtFrame::stateID); DWORD exStyle; @@ -408,8 +408,9 @@ MsgRouting AwtFrame::WmShowWindow(BOOL show, UINT status) * message. This breaks Java focus. To workaround the problem we * set the toplevel being shown foreground programmatically. * The fix is localized to non-foreground process case only. + * (See also: 6599270) */ - if (show == TRUE && status == 0) { + if (!IsEmbeddedFrame() && show == TRUE && status == 0) { HWND fgHWnd = ::GetForegroundWindow(); if (fgHWnd != NULL) { DWORD fgProcessID; @@ -495,7 +496,7 @@ MsgRouting AwtFrame::WmMouseMove(UINT flags, int x, int y) { ::SetWindowPos(GetHWnd(), NULL, r.left, r.top, r.right-r.left, r.bottom-r.top, - SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_NOZORDER | + SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOCOPYBITS | SWP_DEFERERASE); } return mrConsume; diff --git a/src/windows/native/sun/windows/awt_Object.cpp b/src/windows/native/sun/windows/awt_Object.cpp index 96153f1600f239818e9512a0294091874044899e..aab7e98b50201d9c5fb15310ea083f4ab4a389d4 100644 --- a/src/windows/native/sun/windows/awt_Object.cpp +++ b/src/windows/native/sun/windows/awt_Object.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. 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 @@ -39,6 +39,7 @@ static BOOL reportEvents = FALSE; */ jfieldID AwtObject::pDataID; +jfieldID AwtObject::destroyedID; jfieldID AwtObject::targetID; jclass AwtObject::wObjectPeerClass; jmethodID AwtObject::getPeerForTargetMID; @@ -223,6 +224,7 @@ Java_sun_awt_windows_WObjectPeer_initIDs(JNIEnv *env, jclass cls) { AwtObject::wObjectPeerClass = (jclass)env->NewGlobalRef(cls); AwtObject::pDataID = env->GetFieldID(cls, "pData", "J"); + AwtObject::destroyedID = env->GetFieldID(cls, "destroyed", "Z"); AwtObject::targetID = env->GetFieldID(cls, "target", "Ljava/lang/Object;"); @@ -233,6 +235,7 @@ Java_sun_awt_windows_WObjectPeer_initIDs(JNIEnv *env, jclass cls) { AwtObject::createErrorID = env->GetFieldID(cls, "createError", "Ljava/lang/Error;"); DASSERT(AwtObject::pDataID != NULL); + DASSERT(AwtObject::destroyedID != NULL); DASSERT(AwtObject::targetID != NULL); DASSERT(AwtObject::getPeerForTargetMID != NULL); DASSERT(AwtObject::createErrorID != NULL); diff --git a/src/windows/native/sun/windows/awt_Object.h b/src/windows/native/sun/windows/awt_Object.h index 3e69dd89cca339cbfac380f78a0865ca17b6fa26..bcfa6b6f555308eadb8e40ea5158069a8ce61e71 100644 --- a/src/windows/native/sun/windows/awt_Object.h +++ b/src/windows/native/sun/windows/awt_Object.h @@ -1,5 +1,5 @@ /* - * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. 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 @@ -51,6 +51,7 @@ public: /* sun.awt.windows.WObjectPeer field and method ids */ static jfieldID pDataID; + static jfieldID destroyedID; static jfieldID targetID; static jmethodID getPeerForTargetMID; diff --git a/src/windows/native/sun/windows/awt_Toolkit.cpp b/src/windows/native/sun/windows/awt_Toolkit.cpp index 4a8e45177aa1db88c85993c0280434f1e470836d..958ca8d871d1fe2c17d0d40216bd9e98a111a586 100644 --- a/src/windows/native/sun/windows/awt_Toolkit.cpp +++ b/src/windows/native/sun/windows/awt_Toolkit.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. 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 @@ -354,6 +354,7 @@ AwtToolkit::AwtToolkit() { m_dllHandle = NULL; m_displayChanged = FALSE; + m_embedderProcessID = 0; // XXX: keyboard mapping should really be moved out of AwtComponent AwtComponent::InitDynamicKeyMapTable(); @@ -1442,49 +1443,17 @@ void hang_if_shutdown(void) } } -/* - * Returns a reference to the class java.awt.Component. - */ -jclass -getComponentClass(JNIEnv *env) +// for now we support only one embedder, but should be ready for future +void AwtToolkit::RegisterEmbedderProcessId(HWND embedder) { - static jclass componentCls = NULL; - - // get global reference of java/awt/Component class (run only once) - if (componentCls == NULL) { - jclass componentClsLocal = env->FindClass("java/awt/Component"); - DASSERT(componentClsLocal != NULL); - if (componentClsLocal == NULL) { - /* exception already thrown */ - return NULL; - } - componentCls = (jclass)env->NewGlobalRef(componentClsLocal); - env->DeleteLocalRef(componentClsLocal); + if (m_embedderProcessID) { + // we already set embedder process and do not expect + // two different processes to embed the same AwtToolkit + return; } - return componentCls; -} - -/* - * Returns a reference to the class java.awt.MenuComponent. - */ -jclass -getMenuComponentClass(JNIEnv *env) -{ - static jclass menuComponentCls = NULL; - - // get global reference of java/awt/MenuComponent class (run only once) - if (menuComponentCls == NULL) { - jclass menuComponentClsLocal = env->FindClass("java/awt/MenuComponent"); - DASSERT(menuComponentClsLocal != NULL); - if (menuComponentClsLocal == NULL) { - /* exception already thrown */ - return NULL; - } - menuComponentCls = (jclass)env->NewGlobalRef(menuComponentClsLocal); - env->DeleteLocalRef(menuComponentClsLocal); - } - return menuComponentCls; + embedder = ::GetAncestor(embedder, GA_ROOT); + ::GetWindowThreadProcessId(embedder, &m_embedderProcessID); } JNIEnv* AwtToolkit::m_env; diff --git a/src/windows/native/sun/windows/awt_Toolkit.h b/src/windows/native/sun/windows/awt_Toolkit.h index e7ffb1d29033d8ecb49340833e1418fcacdac7e6..fcee2d4ad5cb756e7d84d595c4b27f475a9b29cb 100644 --- a/src/windows/native/sun/windows/awt_Toolkit.h +++ b/src/windows/native/sun/windows/awt_Toolkit.h @@ -1,5 +1,5 @@ /* - * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. 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 @@ -426,10 +426,17 @@ private: */ private: BOOL m_displayChanged; /* Tracks displayChanged events */ + // 0 means we are not embedded. + DWORD m_embedderProcessID; public: BOOL HasDisplayChanged() { return m_displayChanged; } void ResetDisplayChanged() { m_displayChanged = FALSE; } + void RegisterEmbedderProcessId(HWND); + BOOL IsEmbedderProcessId(const DWORD processID) const + { + return m_embedderProcessID && (processID == m_embedderProcessID); + } private: static JNIEnv *m_env; diff --git a/src/windows/native/sun/windows/awt_Window.cpp b/src/windows/native/sun/windows/awt_Window.cpp index adc3ee6af2af118c08199a29bf294147e3f944e7..7e2f31fb13949bde6ff99344505e04e5c2ecec6d 100644 --- a/src/windows/native/sun/windows/awt_Window.cpp +++ b/src/windows/native/sun/windows/awt_Window.cpp @@ -125,6 +125,11 @@ jfieldID AwtWindow::autoRequestFocusID; jclass AwtWindow::wwindowPeerCls; jmethodID AwtWindow::getActiveWindowsMID; +jfieldID AwtWindow::sysXID; +jfieldID AwtWindow::sysYID; +jfieldID AwtWindow::sysWID; +jfieldID AwtWindow::sysHID; + int AwtWindow::ms_instanceCounter = 0; HHOOK AwtWindow::ms_hCBTFilter; AwtWindow * AwtWindow::m_grabbedWindow = NULL; @@ -180,7 +185,6 @@ void AwtWindow::Dispose() } ::RemoveProp(GetHWnd(), ModalBlockerProp); - ::RemoveProp(GetHWnd(), ModalSaveWSEXProp); if (m_grabbedWindow == this) { Ungrab(); @@ -330,8 +334,11 @@ LRESULT CALLBACK AwtWindow::CBTFilter(int nCode, WPARAM wParam, LPARAM lParam) if (nCode == HCBT_ACTIVATE || nCode == HCBT_SETFOCUS) { AwtComponent *comp = AwtComponent::GetComponent((HWND)wParam); - if (comp != NULL && comp->IsTopLevel() && !((AwtWindow*)comp)->IsFocusableWindow()) { - return 1; // Don't change focus/activation. + if (comp != NULL && comp->IsTopLevel()) { + AwtWindow* win = (AwtWindow*)comp; + if (!win->IsFocusableWindow() || win->m_filterFocusAndActivation) { + return 1; // Don't change focus/activation. + } } } return ::CallNextHookEx(AwtWindow::ms_hCBTFilter, nCode, wParam, lParam); @@ -1053,6 +1060,8 @@ MsgRouting AwtWindow::WmMove(int x, int y) (env)->SetIntField(target, AwtComponent::xID, rect.left); (env)->SetIntField(target, AwtComponent::yID, rect.top); + (env)->SetIntField(peer, AwtWindow::sysXID, rect.left); + (env)->SetIntField(peer, AwtWindow::sysYID, rect.top); SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_MOVED); env->DeleteLocalRef(target); @@ -1116,6 +1125,11 @@ MsgRouting AwtWindow::WmSize(UINT type, int w, int h) (env)->SetIntField(target, AwtComponent::widthID, newWidth); (env)->SetIntField(target, AwtComponent::heightID, newHeight); + + jobject peer = GetPeer(env); + (env)->SetIntField(peer, AwtWindow::sysWID, newWidth); + (env)->SetIntField(peer, AwtWindow::sysHID, newHeight); + if (!AwtWindow::IsResizing()) { WindowResized(); } @@ -1455,20 +1469,17 @@ void AwtWindow::SetModalBlocker(HWND window, HWND blocker) { if (!::IsWindow(window)) { return; } - DWORD exStyle = ::GetWindowLong(window, GWL_EXSTYLE); + if (::IsWindow(blocker)) { - // save WS_EX_NOACTIVATE and WS_EX_APPWINDOW styles - DWORD saveStyle = exStyle & (AWT_WS_EX_NOACTIVATE | WS_EX_APPWINDOW); - ::SetProp(window, ModalSaveWSEXProp, reinterpret_cast(saveStyle)); - ::SetWindowLong(window, GWL_EXSTYLE, (exStyle | AWT_WS_EX_NOACTIVATE) & ~WS_EX_APPWINDOW); ::SetProp(window, ModalBlockerProp, reinterpret_cast(blocker)); + ::EnableWindow(window, FALSE); } else { - // restore WS_EX_NOACTIVATE and WS_EX_APPWINDOW styles - DWORD saveStyle = reinterpret_cast(::GetProp(window, ModalSaveWSEXProp)); - ::SetWindowLong(window, GWL_EXSTYLE, - (exStyle & ~(AWT_WS_EX_NOACTIVATE | WS_EX_APPWINDOW)) | saveStyle); - ::RemoveProp(window, ModalSaveWSEXProp); ::RemoveProp(window, ModalBlockerProp); + AwtComponent *comp = AwtComponent::GetComponent(window); + // we don't expect to be called with non-java HWNDs + DASSERT(comp && comp->IsTopLevel()); + // we should not unblock disabled toplevels + ::EnableWindow(window, comp->isEnabled()); } } @@ -1754,17 +1765,22 @@ void AwtWindow::_ReshapeFrame(void *param) // Fix for 4459064 : do not enforce thresholds for embedded frames if (!p->IsEmbeddedFrame()) { + jobject peer = p->GetPeer(env); int minWidth = ::GetSystemMetrics(SM_CXMIN); int minHeight = ::GetSystemMetrics(SM_CYMIN); if (w < minWidth) { env->SetIntField(target, AwtComponent::widthID, w = minWidth); + env->SetIntField(peer, AwtWindow::sysWID, + w); } if (h < minHeight) { env->SetIntField(target, AwtComponent::heightID, h = minHeight); + env->SetIntField(peer, AwtWindow::sysHID, + h); } } env->DeleteLocalRef(target); @@ -2148,6 +2164,11 @@ Java_sun_awt_windows_WWindowPeer_initIDs(JNIEnv *env, jclass cls) env->GetStaticMethodID(cls, "getActiveWindowHandles", "()[J"); DASSERT(AwtWindow::getActiveWindowsMID != NULL); + AwtWindow::sysXID = env->GetFieldID(cls, "sysX", "I"); + AwtWindow::sysYID = env->GetFieldID(cls, "sysY", "I"); + AwtWindow::sysWID = env->GetFieldID(cls, "sysW", "I"); + AwtWindow::sysHID = env->GetFieldID(cls, "sysH", "I"); + CATCH_BAD_ALLOC; } diff --git a/src/windows/native/sun/windows/awt_Window.h b/src/windows/native/sun/windows/awt_Window.h index 1edb9b04dd73ac7f7db7e836f2f0bbd0bf681064..8e654a2d81337ef9d86512eac371a5f152be7348 100644 --- a/src/windows/native/sun/windows/awt_Window.h +++ b/src/windows/native/sun/windows/awt_Window.h @@ -33,7 +33,6 @@ // property name tagging windows disabled by modality static LPCTSTR ModalBlockerProp = TEXT("SunAwtModalBlockerProp"); -static LPCTSTR ModalSaveWSEXProp = TEXT("SunAwtModalSaveWSEXProp"); static LPCTSTR ModalDialogPeerProp = TEXT("SunAwtModalDialogPeerProp"); #ifndef WH_MOUSE_LL @@ -63,6 +62,12 @@ public: /* long[] getActiveWindowHandles() method in WWindowPeer */ static jmethodID getActiveWindowsMID; + // The coordinates at the peer. + static jfieldID sysXID; + static jfieldID sysYID; + static jfieldID sysWID; + static jfieldID sysHID; + AwtWindow(); virtual ~AwtWindow(); diff --git a/test/com/sun/crypto/provider/KeyFactory/TestProviderLeak.java b/test/com/sun/crypto/provider/KeyFactory/TestProviderLeak.java new file mode 100644 index 0000000000000000000000000000000000000000..6fe480cb6e08cd03c6db4574f3a64cba85d78c6f --- /dev/null +++ b/test/com/sun/crypto/provider/KeyFactory/TestProviderLeak.java @@ -0,0 +1,72 @@ +/* + * Copyright 2005-2007 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6578538 + * @summary com.sun.crypto.provider.SunJCE instance leak using KRB5 and + * LoginContext + * @author Brad Wetmore + * + * @run main/othervm -Xmx2m TestProviderLeak + */ + +/* + * We force the leak to become a problem by specifying the minimum + * size heap we can (above). In current runs on a server and client + * machine, it took roughly 220-240 iterations to have the memory leak + * shut down other operations. It complained about "Unable to verify + * the SunJCE provider." + */ + +import javax.crypto.*; +import javax.crypto.spec.*; + +public class TestProviderLeak { + private static void dumpMemoryStats(String s) throws Exception { + Runtime rt = Runtime.getRuntime(); + System.out.println(s + ":\t" + + rt.freeMemory() + " bytes free"); + } + + public static void main(String [] args) throws Exception { + SecretKeyFactory skf = + SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1", "SunJCE"); + PBEKeySpec pbeKS = new PBEKeySpec( + "passPhrase".toCharArray(), new byte [] { 0 }, 5, 512); + for (int i = 0; i <= 1000; i++) { + try { + skf.generateSecret(pbeKS); + if ((i % 20) == 0) { + // Calling gc() isn't dependable, but doesn't hurt. + // Gives better output in leak cases. + System.gc(); + dumpMemoryStats("Iteration " + i); + } + } catch (Exception e) { + dumpMemoryStats("\nException seen at iteration " + i); + throw e; + } + } + } +} diff --git a/test/java/awt/Focus/NonFocusableResizableTooSmall/NonFocusableResizableTooSmall.java b/test/java/awt/Focus/NonFocusableResizableTooSmall/NonFocusableResizableTooSmall.java new file mode 100644 index 0000000000000000000000000000000000000000..ef3207ffcb810292e1204570bb672f810dc03f62 --- /dev/null +++ b/test/java/awt/Focus/NonFocusableResizableTooSmall/NonFocusableResizableTooSmall.java @@ -0,0 +1,413 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + @test + @bug 6581927 + @summary Non-focusable frame should honor the size of the frame buttons/decorations when resizing + @library ../../regtesthelpers + @build Util + @author anthony.petrov@...: area=awt.toplevel + @run main NonFocusableResizableTooSmall +*/ + +/** + * NonFocusableResizableTooSmall.java + * + * summary: Non-focusable frame should honor the size of the frame buttons/decorations when resizing + */ + +import java.awt.*; +import java.awt.event.*; +import test.java.awt.regtesthelpers.Util; + +public class NonFocusableResizableTooSmall +{ + + //*** test-writer defined static variables go here *** + + + private static void init() + { + //*** Create instructions for the user here *** + + String[] instructions = + { + "This is an AUTOMATIC test, simply wait until it is done.", + "The result (passed or failed) will be shown in the", + "message window below." + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + final Frame frame = new Frame(); + frame.setFocusableWindowState(false); + frame.setSize(200, 100); + frame.setVisible(true); + + final Robot robot = Util.createRobot(); + robot.setAutoDelay(20); + + // To be sure the window is shown and packed + Util.waitForIdle(robot); + + final Insets insets = frame.getInsets(); + System.out.println("The insets of the frame: " + insets); + if (insets.right == 0 || insets.bottom == 0) { + System.out.println("The test environment must have non-zero right & bottom insets!"); + pass(); + return; + } + + // Let's move the mouse pointer to the bottom-right coner of the frame (the "size-grip") + final Rectangle bounds1 = frame.getBounds(); + System.out.println("The bounds before resizing: " + bounds1); + + robot.mouseMove(bounds1.x + bounds1.width - 1, bounds1.y + bounds1.height - 1); + + // ... and start resizing to some very small + robot.mousePress( InputEvent.BUTTON1_MASK ); + + // Now resize the frame so that the width is smaller + // than the widths of the left and the right borders. + // The sum of widths of the icon of the frame + the control-buttons + // (close, minimize, etc.) should be definitely larger! + robot.mouseMove(bounds1.x + insets.left + insets.right - 5, bounds1.y + bounds1.height - 1); + Util.waitForIdle(robot); + + robot.mouseRelease( InputEvent.BUTTON1_MASK ); + + Util.waitForIdle(robot); + + // Check the current bounds of the frame + final Rectangle bounds2 = frame.getBounds(); + System.out.println("The bounds after resizing: " + bounds2); + + if (bounds2.width <= (insets.left + insets.right)) { + fail("The frame has been resized to very small."); + } + pass(); + }//End init() + + + + /***************************************************** + * Standard Test Machinery Section + * DO NOT modify anything in this section -- it's a + * standard chunk of code which has all of the + * synchronisation necessary for the test harness. + * By keeping it the same in all tests, it is easier + * to read and understand someone else's test, as + * well as insuring that all tests behave correctly + * with the test harness. + * There is a section following this for test- + * classes + ******************************************************/ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + + private static Thread mainThread = null; + + private static int sleepTime = 300000; + + // Not sure about what happens if multiple of this test are + // instantiated in the same VM. Being static (and using + // static vars), it aint gonna work. Not worrying about + // it for now. + public static void main( String args[] ) throws InterruptedException + { + mainThread = Thread.currentThread(); + try + { + init(); + } + catch( TestPassedException e ) + { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test pass nor test fail has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try + { + Thread.sleep( sleepTime ); + //Timed out, so fail the test + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); + } + catch (InterruptedException e) + { + //The test harness may have interrupted the test. If so, rethrow the exception + // so that the harness gets it and deals with it. + if( ! testGeneratedInterrupt ) throw e; + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + + if ( theTestPassed == false ) + { + throw new RuntimeException( failureMessage ); + } + } + + }//main + + public static synchronized void setTimeoutTo( int seconds ) + { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() + { + Sysout.println( "The test passed." ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //first check if this is executing in main thread + if ( mainThread == Thread.currentThread() ) + { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + }//pass() + + public static synchronized void fail() + { + //test writer didn't specify why test failed, so give generic + fail( "it just plain failed! :-)" ); + } + + public static synchronized void fail( String whyFailed ) + { + Sysout.println( "The test failed: " + whyFailed ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //check if this called from main thread + if ( mainThread == Thread.currentThread() ) + { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException( whyFailed ); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() + +}// class NonFocusableResizableTooSmall + +//This exception is used to exit from any level of call nesting +// when it's determined that the test has passed, and immediately +// end the test. +class TestPassedException extends RuntimeException +{ +} + +//*********** End Standard Test Machinery Section ********** + + +//************ Begin classes defined for the test **************** + +// if want to make listeners, here is the recommended place for them, then instantiate +// them in init() + +/* Example of a class which may be written as part of a test +class NewClass implements anInterface + { + static int newVar = 0; + + public void eventDispatched(AWTEvent e) + { + //Counting events to see if we get enough + eventCount++; + + if( eventCount == 20 ) + { + //got enough events, so pass + + NonFocusableResizableTooSmall.pass(); + } + else if( tries == 20 ) + { + //tried too many times without getting enough events so fail + + NonFocusableResizableTooSmall.fail(); + } + + }// eventDispatched() + + }// NewClass class + +*/ + + +//************** End classes defined for the test ******************* + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout +{ + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + System.out.println(messageIn); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog +{ + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + setVisible(true); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + System.out.println(messageIn); + } + +}// TestDialog class diff --git a/test/java/awt/Focus/RestoreFocusOnDisabledComponentTest/RestoreFocusOnDisabledComponentTest.java b/test/java/awt/Focus/RestoreFocusOnDisabledComponentTest/RestoreFocusOnDisabledComponentTest.java new file mode 100644 index 0000000000000000000000000000000000000000..b813ce9599e4d574bc7c85cbc0d8fce2bc2807cf --- /dev/null +++ b/test/java/awt/Focus/RestoreFocusOnDisabledComponentTest/RestoreFocusOnDisabledComponentTest.java @@ -0,0 +1,108 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + @test %W% %E% + @bug 6598089 + @summary Tests restoring focus on a single disabled coponent + @author Anton Tarasov: area=awt-focus + @library ../../regtesthelpers + @build Util + @run main RestoreFocusOnDisabledComponentTest +*/ + +import java.awt.*; +import java.awt.event.*; +import java.applet.Applet; +import test.java.awt.regtesthelpers.Util; + +/* + * The bug is not reproducible on Windows. + */ +public class RestoreFocusOnDisabledComponentTest extends Applet { + Frame frame = new Frame("Frame") {public String toString() {return "FRAME";}}; + Button b0 = new Button("button0") {public String toString() {return "B-0";}}; + Button b1 = new Button("button1") {public String toString() {return "B-1";}}; + volatile int nFocused; + Robot robot; + + public static void main(String[] args) { + RestoreFocusOnDisabledComponentTest app = new RestoreFocusOnDisabledComponentTest(); + app.init(); + app.start(); + } + + public void init() { + robot = Util.createRobot(); + } + + public void start() { + frame.add(b0); + frame.add(b1); + frame.setLayout(new FlowLayout()); + frame.pack(); + + frame.setVisible(true); + + Util.waitForIdle(robot); + KeyboardFocusManager.setCurrentKeyboardFocusManager(new DefaultKeyboardFocusManager() { + public boolean dispatchEvent(AWTEvent e) { + if (e.getID() == FocusEvent.FOCUS_GAINED) { + // Trying to emulate timings. b1 should be disabled just by the time it gets + // FOCUS_GAINED event. The latter is a result of disabling b0 that initiates + // focus auto transfer. + if (e.getSource() == b1) { + b1.setEnabled(false); + + } else if (e.getSource() == b0) { + if (++nFocused > 10) { + nFocused = -1; + throw new TestFailedException("Focus went into busy loop!"); + } + } + } + return super.dispatchEvent(e); + } + }); + // Initiating focus auto transfer. + // Focus will be requested to b1. When FOCUS_GAINED is being dispatched to b1, it will + // be disabled. This will trigger focus restoring. Focus will be requested to b0 (the + // last opposite component). When FOCUS_GAINED is being dispatched to b0, it will + // also be disabled. However, the last opposite component (and the most recent focus owner) + // will still be b0. When DKFM initiates focus restoring it should detect restoring + // on the same component and break. + b0.setEnabled(false); + + Util.waitForIdle(robot); + if (nFocused != -1) { + System.out.println("Test passed."); + } + } +} + +class TestFailedException extends RuntimeException { + TestFailedException(String msg) { + super("Test failed: " + msg); + } +} + diff --git a/test/java/awt/Mixing/ValidBounds.java b/test/java/awt/Mixing/ValidBounds.java new file mode 100644 index 0000000000000000000000000000000000000000..dec7e6fce44e4f7e408c42b85b4890d14a1f43df --- /dev/null +++ b/test/java/awt/Mixing/ValidBounds.java @@ -0,0 +1,411 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + @test + @bug 6637796 + @summary Shape should be correctly updated on invalid components + @author anthony.petrov@...: area=awt.mixing + @library ../regtesthelpers + @build Util + @run main ValidBounds +*/ + +/** + * ValidBounds.java + * + * summary: Shape should be correctly updated on invalid components + */ + +import java.awt.*; +import java.awt.event.*; +import test.java.awt.regtesthelpers.Util; + +public class ValidBounds +{ + + static volatile boolean clickPassed = false; + + private static void init() + { + //*** Create instructions for the user here *** + + String[] instructions = + { + "This is an AUTOMATIC test, simply wait until it is done.", + "The result (passed or failed) will be shown in the", + "message window below." + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + + // Create the frame and the button + Frame f = new Frame(); + f.setBounds(100, 100, 400, 300); + + Button b = new Button("OK"); + + f.setLayout(null); + f.add(b); + b.setBounds(50, 50, 200, 50); + + b.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent e) { + clickPassed = true; + } + }); + + f.setVisible(true); + + // Let's make the button much smaller first... + Robot robot = Util.createRobot(); + robot.setAutoDelay(20); + + Util.waitForIdle(robot); + + b.setBounds(50, 50, 5, 5); + Util.waitForIdle(robot); + + // ... and now let's enlarge it. + b.setBounds(50, 50, 200, 50); + Util.waitForIdle(robot); + + // If the button doesn't receive the click, it means that the test + // failed: the shape of the button was not enlarged. + Point heavyLoc = b.getLocationOnScreen(); + robot.mouseMove(heavyLoc.x + 20, heavyLoc.y + 20); + + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + Util.waitForIdle(robot); + + if (clickPassed) { + pass(); + } else { + fail("The button cannot be clicked."); + } + }//End init() + + + + /***************************************************** + * Standard Test Machinery Section + * DO NOT modify anything in this section -- it's a + * standard chunk of code which has all of the + * synchronisation necessary for the test harness. + * By keeping it the same in all tests, it is easier + * to read and understand someone else's test, as + * well as insuring that all tests behave correctly + * with the test harness. + * There is a section following this for test- + * classes + ******************************************************/ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + + private static Thread mainThread = null; + + private static int sleepTime = 300000; + + // Not sure about what happens if multiple of this test are + // instantiated in the same VM. Being static (and using + // static vars), it aint gonna work. Not worrying about + // it for now. + public static void main( String args[] ) throws InterruptedException + { + mainThread = Thread.currentThread(); + try + { + init(); + } + catch( TestPassedException e ) + { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test pass nor test fail has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try + { + Thread.sleep( sleepTime ); + //Timed out, so fail the test + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); + } + catch (InterruptedException e) + { + //The test harness may have interrupted the test. If so, rethrow the exception + // so that the harness gets it and deals with it. + if( ! testGeneratedInterrupt ) throw e; + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + + if ( theTestPassed == false ) + { + throw new RuntimeException( failureMessage ); + } + } + + }//main + + public static synchronized void setTimeoutTo( int seconds ) + { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() + { + Sysout.println( "The test passed." ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //first check if this is executing in main thread + if ( mainThread == Thread.currentThread() ) + { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + }//pass() + + public static synchronized void fail() + { + //test writer didn't specify why test failed, so give generic + fail( "it just plain failed! :-)" ); + } + + public static synchronized void fail( String whyFailed ) + { + Sysout.println( "The test failed: " + whyFailed ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //check if this called from main thread + if ( mainThread == Thread.currentThread() ) + { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException( whyFailed ); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() + +}// class ValidBounds + +//This exception is used to exit from any level of call nesting +// when it's determined that the test has passed, and immediately +// end the test. +class TestPassedException extends RuntimeException +{ +} + +//*********** End Standard Test Machinery Section ********** + + +//************ Begin classes defined for the test **************** + +// if want to make listeners, here is the recommended place for them, then instantiate +// them in init() + +/* Example of a class which may be written as part of a test +class NewClass implements anInterface + { + static int newVar = 0; + + public void eventDispatched(AWTEvent e) + { + //Counting events to see if we get enough + eventCount++; + + if( eventCount == 20 ) + { + //got enough events, so pass + + ValidBounds.pass(); + } + else if( tries == 20 ) + { + //tried too many times without getting enough events so fail + + ValidBounds.fail(); + } + + }// eventDispatched() + + }// NewClass class + +*/ + + +//************** End classes defined for the test ******************* + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout +{ + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + System.out.println(messageIn); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog +{ + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + setVisible(true); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + System.out.println(messageIn); + } + +}// TestDialog class diff --git a/test/java/awt/Modal/WsDisabledStyle/CloseBlocker/CloseBlocker.java b/test/java/awt/Modal/WsDisabledStyle/CloseBlocker/CloseBlocker.java new file mode 100644 index 0000000000000000000000000000000000000000..ad48949b3acb9dcc6cd1ff9e8a49d6156c36aa6a --- /dev/null +++ b/test/java/awt/Modal/WsDisabledStyle/CloseBlocker/CloseBlocker.java @@ -0,0 +1,466 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + @test %I% %E% + @bug 4080029 + @summary Modal Dialog block input to all frame windows not just its parent. + @author dmitry.cherepanov: area=awt.modal + @run main/manual CloseBlocker +*/ + +/** + * ManualMainTest.java + * + * summary: The test opens and closes blocker dialog, the test verifies + * that active window is correct when the dialog is closed. + */ + +import java.awt.*; +import java.awt.event.*; + +public class CloseBlocker +{ + + private static void init() + { + //*** Create instructions for the user here *** + + String[] instructions = + { + " the test will be run 6 times, to start next test just close all ", + " windows of previous; the instructions are the same for all tests: ", + " 1) there are two frames (one the frames has 'show modal' button), ", + " 2) press the button to show a dialog, ", + " 3) close the dialog (an alternative scenario - activate another", + " native window before closing the dialog), ", + " 4) the frame with button should become next active window, ", + " if it's true, then the test passed, otherwise, it failed. ", + " Press 'pass' button only after all of the 6 tests are completed, ", + " the number of the currently executed test is displayed on the ", + " output window. " + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + test(true, true, false); + test(true, true, true); + test(false, true, false); // 3rd parameter has no affect for ownerless + + test(true, false, false); + test(true, false, true); + test(false, false, false); // 3rd parameter has no affect for ownerless + + }//End init() + + private static final Object obj = new Object(); + private static int counter = 0; + + /* + * The ownerless parameter indicates whether the blocker dialog + * has owner. The usual parameter indicates whether the blocker + * dialog is a Java dialog (non-native dialog like file dialog). + */ + private static void test(final boolean ownerless, final boolean usual, final boolean initiallyOwnerIsActive) { + + Sysout.print(" * test #" + (++counter) + " is running ... "); + + final Frame active = new Frame(); + final Frame nonactive = new Frame(); + Button button = new Button("show modal"); + button.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) { + Dialog dialog = null; + Frame parent = ownerless ? null : (initiallyOwnerIsActive? active : nonactive); + if (usual) { + dialog = new Dialog(parent, "Sample", true); + } else { + dialog = new FileDialog(parent, "Sample", FileDialog.LOAD); + } + dialog.addWindowListener(new WindowAdapter(){ + public void windowClosing(WindowEvent e){ + e.getWindow().dispose(); + } + }); + dialog.setBounds(200, 200, 200, 200); + dialog.setVisible(true); + } + }); + + active.add(button); + active.setBounds(200, 400, 200, 200); + WindowAdapter adapter = new WindowAdapter(){ + public void windowClosing(WindowEvent e){ + active.dispose(); + nonactive.dispose(); + synchronized(obj) { + obj.notify(); + } + } + }; + active.addWindowListener(adapter); + active.setVisible(true); + + nonactive.setBounds(400, 400, 200, 200); + nonactive.addWindowListener(adapter); + nonactive.setVisible(true); + + synchronized(obj) { + try{ + obj.wait(); + } catch(Exception e) { + throw new RuntimeException(e); + } + } + + Sysout.println(" completed. "); + + } + + /***************************************************** + * Standard Test Machinery Section + * DO NOT modify anything in this section -- it's a + * standard chunk of code which has all of the + * synchronisation necessary for the test harness. + * By keeping it the same in all tests, it is easier + * to read and understand someone else's test, as + * well as insuring that all tests behave correctly + * with the test harness. + * There is a section following this for test-defined + * classes + ******************************************************/ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + + private static Thread mainThread = null; + + private static int sleepTime = 300000; + + public static void main( String args[] ) throws InterruptedException + { + mainThread = Thread.currentThread(); + try + { + init(); + } + catch( TestPassedException e ) + { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test passed nor test failed has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try + { + Thread.sleep( sleepTime ); + //Timed out, so fail the test + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); + } + catch (InterruptedException e) + { + if( ! testGeneratedInterrupt ) throw e; + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + if ( theTestPassed == false ) + { + throw new RuntimeException( failureMessage ); + } + } + + }//main + + public static synchronized void setTimeoutTo( int seconds ) + { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() + { + Sysout.println( "The test passed." ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //first check if this is executing in main thread + if ( mainThread == Thread.currentThread() ) + { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + //pass was called from a different thread, so set the flag and interrupt + // the main thead. + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + }//pass() + + public static synchronized void fail() + { + //test writer didn't specify why test failed, so give generic + fail( "it just plain failed! :-)" ); + } + + public static synchronized void fail( String whyFailed ) + { + Sysout.println( "The test failed: " + whyFailed ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //check if this called from main thread + if ( mainThread == Thread.currentThread() ) + { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException( whyFailed ); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() + +}// class ManualMainTest + +//This exception is used to exit from any level of call nesting +// when it's determined that the test has passed, and immediately +// end the test. +class TestPassedException extends RuntimeException +{ +} + +//*********** End Standard Test Machinery Section ********** + + +//************ Begin classes defined for the test **************** + +// make listeners in a class defined here, and instantiate them in init() + +/* Example of a class which may be written as part of a test +class NewClass implements anInterface + { + static int newVar = 0; + + public void eventDispatched(AWTEvent e) + { + //Counting events to see if we get enough + eventCount++; + + if( eventCount == 20 ) + { + //got enough events, so pass + + ManualMainTest.pass(); + } + else if( tries == 20 ) + { + //tried too many times without getting enough events so fail + + ManualMainTest.fail(); + } + + }// eventDispatched() + + }// NewClass class + +*/ + + +//************** End classes defined for the test ******************* + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout +{ + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn, true ); + } + + public static void print( String messageIn ) + { + dialog.displayMessage( messageIn, false ); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog implements ActionListener +{ + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + Panel buttonP = new Panel(); + Button passB = new Button( "pass" ); + Button failB = new Button( "fail" ); + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + passB = new Button( "pass" ); + passB.setActionCommand( "pass" ); + passB.addActionListener( this ); + buttonP.add( "East", passB ); + + failB = new Button( "fail" ); + failB.setActionCommand( "fail" ); + failB.addActionListener( this ); + buttonP.add( "West", failB ); + + add( "South", buttonP ); + pack(); + + setVisible(true); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn, boolean nextLine ) + { + messageText.append( messageIn + (nextLine? "\n" : "") ); + System.out.println(messageIn); + } + + //catch presses of the passed and failed buttons. + //simply call the standard pass() or fail() static methods of + //ManualMainTest + public void actionPerformed( ActionEvent e ) + { + if( e.getActionCommand() == "pass" ) + { + CloseBlocker.pass(); + } + else + { + CloseBlocker.fail(); + } + } + +}// TestDialog class diff --git a/test/java/awt/Modal/WsDisabledStyle/OverBlocker/OverBlocker.java b/test/java/awt/Modal/WsDisabledStyle/OverBlocker/OverBlocker.java new file mode 100644 index 0000000000000000000000000000000000000000..15d963baa08acdc6d818495f029eef265ec34658 --- /dev/null +++ b/test/java/awt/Modal/WsDisabledStyle/OverBlocker/OverBlocker.java @@ -0,0 +1,456 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + @test %I% %E% + @bug 4080029 + @summary Modal Dialog block input to all frame windows not just its parent. + @author dmitry.cherepanov: area=awt.modal + @run main/manual OverBlocker +*/ + +/** + * OverBlocker.java + * + * summary: The test verifies that if user tries to activate the blocked dialog + * then the blocker dialog appears over the other windows + */ + +import java.awt.*; +import java.awt.event.*; + +public class OverBlocker +{ + + private static void init() + { + //*** Create instructions for the user here *** + + String[] instructions = + { + " the test will be run 4 times, to start next test just close all ", + " windows of previous; the instructions are the same for all tests: ", + " 1) there is a frame with 'show modal' button, ", + " 2) press the button to show a dialog, ", + " 3) activate any non-Java application, move the app over the dialog, ", + " 4) click on the frame by mouse, ", + " 5) make sure that the dialog comes up from the application and ", + " now the dialog overlaps the app as well as the frame, ", + " if it's true, then the test passed, otherwise, it failed. ", + " Press 'pass' button only after all of the 4 tests are completed, ", + " the number of the currently executed test is displayed on the ", + " output window. " + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + test(false, true); + test(true, true); + test(true, false); + test(false, false); + + }//End init() + + private static final Object obj = new Object(); + private static int counter = 0; + + /* + * The ownerless parameter indicates whether the blocker dialog + * has owner. The usual parameter indicates whether the blocker + * dialog is a Java dialog (non-native dialog like file dialog). + */ + private static void test(final boolean ownerless, final boolean usual) { + + Sysout.print(" * test #" + (++counter) + " is running ... "); + + final Frame frame = new Frame(); + Button button = new Button("show modal"); + button.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) { + Dialog dialog = null; + Frame parent = ownerless ? null : frame; + if (usual) { + dialog = new Dialog(parent, "Sample", true); + } else { + dialog = new FileDialog(parent, "Sample", FileDialog.LOAD); + } + dialog.addWindowListener(new WindowAdapter(){ + public void windowClosing(WindowEvent e){ + e.getWindow().dispose(); + } + }); + dialog.setBounds(200, 200, 200, 200); + dialog.setVisible(true); + } + }); + frame.add(button); + frame.setBounds(400, 400, 200, 200); + frame.addWindowListener(new WindowAdapter(){ + public void windowClosing(WindowEvent e){ + e.getWindow().dispose(); + synchronized(obj) { + obj.notify(); + } + } + }); + frame.setVisible(true); + + synchronized(obj) { + try{ + obj.wait(); + } catch(Exception e) { + throw new RuntimeException(e); + } + } + + Sysout.println(" completed. "); + + } + + /***************************************************** + * Standard Test Machinery Section + * DO NOT modify anything in this section -- it's a + * standard chunk of code which has all of the + * synchronisation necessary for the test harness. + * By keeping it the same in all tests, it is easier + * to read and understand someone else's test, as + * well as insuring that all tests behave correctly + * with the test harness. + * There is a section following this for test-defined + * classes + ******************************************************/ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + + private static Thread mainThread = null; + + private static int sleepTime = 300000; + + public static void main( String args[] ) throws InterruptedException + { + mainThread = Thread.currentThread(); + try + { + init(); + } + catch( TestPassedException e ) + { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test passed nor test failed has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try + { + Thread.sleep( sleepTime ); + //Timed out, so fail the test + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); + } + catch (InterruptedException e) + { + if( ! testGeneratedInterrupt ) throw e; + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + if ( theTestPassed == false ) + { + throw new RuntimeException( failureMessage ); + } + } + + }//main + + public static synchronized void setTimeoutTo( int seconds ) + { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() + { + Sysout.println( "The test passed." ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //first check if this is executing in main thread + if ( mainThread == Thread.currentThread() ) + { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + //pass was called from a different thread, so set the flag and interrupt + // the main thead. + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + }//pass() + + public static synchronized void fail() + { + //test writer didn't specify why test failed, so give generic + fail( "it just plain failed! :-)" ); + } + + public static synchronized void fail( String whyFailed ) + { + Sysout.println( "The test failed: " + whyFailed ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //check if this called from main thread + if ( mainThread == Thread.currentThread() ) + { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException( whyFailed ); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() + +}// class ManualMainTest + +//This exception is used to exit from any level of call nesting +// when it's determined that the test has passed, and immediately +// end the test. +class TestPassedException extends RuntimeException +{ +} + +//*********** End Standard Test Machinery Section ********** + + +//************ Begin classes defined for the test **************** + +// make listeners in a class defined here, and instantiate them in init() + +/* Example of a class which may be written as part of a test +class NewClass implements anInterface + { + static int newVar = 0; + + public void eventDispatched(AWTEvent e) + { + //Counting events to see if we get enough + eventCount++; + + if( eventCount == 20 ) + { + //got enough events, so pass + + ManualMainTest.pass(); + } + else if( tries == 20 ) + { + //tried too many times without getting enough events so fail + + ManualMainTest.fail(); + } + + }// eventDispatched() + + }// NewClass class + +*/ + + +//************** End classes defined for the test ******************* + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout +{ + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn, true ); + } + + public static void print( String messageIn ) + { + dialog.displayMessage( messageIn, false ); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog implements ActionListener +{ + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + Panel buttonP = new Panel(); + Button passB = new Button( "pass" ); + Button failB = new Button( "fail" ); + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + passB = new Button( "pass" ); + passB.setActionCommand( "pass" ); + passB.addActionListener( this ); + buttonP.add( "East", passB ); + + failB = new Button( "fail" ); + failB.setActionCommand( "fail" ); + failB.addActionListener( this ); + buttonP.add( "West", failB ); + + add( "South", buttonP ); + pack(); + + setVisible(true); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn, boolean nextLine ) + { + messageText.append( messageIn + (nextLine? "\n" : "") ); + System.out.println(messageIn); + } + + //catch presses of the passed and failed buttons. + //simply call the standard pass() or fail() static methods of + //ManualMainTest + public void actionPerformed( ActionEvent e ) + { + if( e.getActionCommand() == "pass" ) + { + OverBlocker.pass(); + } + else + { + OverBlocker.fail(); + } + } + +}// TestDialog class diff --git a/test/java/awt/Modal/WsDisabledStyle/Winkey/Winkey.java b/test/java/awt/Modal/WsDisabledStyle/Winkey/Winkey.java new file mode 100644 index 0000000000000000000000000000000000000000..59297463a2efa99861cf1ee69440060e9486501d --- /dev/null +++ b/test/java/awt/Modal/WsDisabledStyle/Winkey/Winkey.java @@ -0,0 +1,403 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + @test %I% %E% + @bug 6572263 6571808 + @summary PIT:FileDialog minimized to taskbar(through 'Show Desktop')selecting the fileDialog using windowList + @author dmitry.cherepanov: area=awt.modal + @run main/manual Winkey +*/ + +/** + * Winkey.java + * + * summary: the test verifies that pressing combination of Windows key + * and M key to minimize all windows doesn't break AWT modality + */ + +import java.awt.*; +import java.awt.event.*; + +public class Winkey +{ + + private static void init() + { + //*** Create instructions for the user here *** + + String[] instructions = + { + " 1. there is a frame with a 'show modal' button, ", + " 2. press the button to show a modal dialog, ", + " 3. the modal dialog will be shown over the frame, ", + " 4. please verify that all (5.1, 5.2.1, 5.2.2) the following tests pass: ", + " ", + " 5.1. press combination Windows Key and M key to minimize all windows, ", + " 5.2. press combination Windows Key and D key to show desktop, ", + " 5.2.1. restore the dialog by choosing this one in the ALT-TAB list, ", + " 5.2.2. restore the dialog by mouse click on taskbar (on java or any other item)", + " ", + " 6. make sure that the dialog and the frame are visible, ", + " the bounds of the windows should be the same as before, ", + " if it's true, then the test passed; otherwise, it failed. " + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + final Frame frame = new Frame(); + Button button = new Button("show modal"); + button.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) { + FileDialog dialog = new FileDialog((Frame)null, "Sample", FileDialog.LOAD); + dialog.setVisible(true); + } + }); + frame.add(button); + frame.setBounds(400, 400, 200, 200); + frame.setVisible(true); + + }//End init() + + /***************************************************** + * Standard Test Machinery Section + * DO NOT modify anything in this section -- it's a + * standard chunk of code which has all of the + * synchronisation necessary for the test harness. + * By keeping it the same in all tests, it is easier + * to read and understand someone else's test, as + * well as insuring that all tests behave correctly + * with the test harness. + * There is a section following this for test-defined + * classes + ******************************************************/ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + + private static Thread mainThread = null; + + private static int sleepTime = 300000; + + public static void main( String args[] ) throws InterruptedException + { + mainThread = Thread.currentThread(); + try + { + init(); + } + catch( TestPassedException e ) + { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test passed nor test failed has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try + { + Thread.sleep( sleepTime ); + //Timed out, so fail the test + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); + } + catch (InterruptedException e) + { + if( ! testGeneratedInterrupt ) throw e; + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + if ( theTestPassed == false ) + { + throw new RuntimeException( failureMessage ); + } + } + + }//main + + public static synchronized void setTimeoutTo( int seconds ) + { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() + { + Sysout.println( "The test passed." ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //first check if this is executing in main thread + if ( mainThread == Thread.currentThread() ) + { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + //pass was called from a different thread, so set the flag and interrupt + // the main thead. + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + }//pass() + + public static synchronized void fail() + { + //test writer didn't specify why test failed, so give generic + fail( "it just plain failed! :-)" ); + } + + public static synchronized void fail( String whyFailed ) + { + Sysout.println( "The test failed: " + whyFailed ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //check if this called from main thread + if ( mainThread == Thread.currentThread() ) + { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException( whyFailed ); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() + +}// class ManualMainTest + +//This exception is used to exit from any level of call nesting +// when it's determined that the test has passed, and immediately +// end the test. +class TestPassedException extends RuntimeException +{ +} + +//*********** End Standard Test Machinery Section ********** + + +//************ Begin classes defined for the test **************** + +// make listeners in a class defined here, and instantiate them in init() + +/* Example of a class which may be written as part of a test +class NewClass implements anInterface + { + static int newVar = 0; + + public void eventDispatched(AWTEvent e) + { + //Counting events to see if we get enough + eventCount++; + + if( eventCount == 20 ) + { + //got enough events, so pass + + ManualMainTest.pass(); + } + else if( tries == 20 ) + { + //tried too many times without getting enough events so fail + + ManualMainTest.fail(); + } + + }// eventDispatched() + + }// NewClass class + +*/ + + +//************** End classes defined for the test ******************* + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout +{ + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog implements ActionListener +{ + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + Panel buttonP = new Panel(); + Button passB = new Button( "pass" ); + Button failB = new Button( "fail" ); + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + passB = new Button( "pass" ); + passB.setActionCommand( "pass" ); + passB.addActionListener( this ); + buttonP.add( "East", passB ); + + failB = new Button( "fail" ); + failB.setActionCommand( "fail" ); + failB.addActionListener( this ); + buttonP.add( "West", failB ); + + add( "South", buttonP ); + pack(); + + setVisible(true); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + System.out.println(messageIn); + } + + //catch presses of the passed and failed buttons. + //simply call the standard pass() or fail() static methods of + //ManualMainTest + public void actionPerformed( ActionEvent e ) + { + if( e.getActionCommand() == "pass" ) + { + Winkey.pass(); + } + else + { + Winkey.fail(); + } + } + +}// TestDialog class diff --git a/test/java/awt/event/MouseEvent/SmoothWheel/SmoothWheel.java b/test/java/awt/event/MouseEvent/SmoothWheel/SmoothWheel.java new file mode 100644 index 0000000000000000000000000000000000000000..00e07c84d3c6685a1968f6863e0318a8dcf836f6 --- /dev/null +++ b/test/java/awt/event/MouseEvent/SmoothWheel/SmoothWheel.java @@ -0,0 +1,432 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + @test %W% %E% %I%, %G% + @bug 6524352 + @summary support for high-resolution mouse wheel + @author dmitry cherepanov: area=awt.event + @run main/manual SmoothWheel +*/ + +/** + * SmoothWheel.java + * + * summary: + */ + +import java.awt.*; +import java.awt.event.*; + +public class SmoothWheel +{ + + //*** test-writer defined static variables go here *** + + + private static void init() + { + String[] instructions = + { + "1. the test is for high-resolution mouse wheel only, ", + " refer to the cr# 6524352 for more info about such devices, ", + "2. you'll see a frame, the frame contains a checkbox, ", + "3. initially, the state of the checkbox is off, ", + " use mouse wheel over the frame, ", + " and the frame will change its size gradually, ", + "4. turn on the checkbox, ", + " use mouse wheel again over the frame, ", + " now the frame will change its size smoothly, ", + "5. if the frame has always the same size or", + " if the frame changes its size equally in 3,4 cases, ", + " then the test failed. Otherwise, it passed." + }; + + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + final Frame frame = new Frame(); + final Checkbox checkbox = new Checkbox("smooth wheel?"); + checkbox.setState(false); + + frame.setLayout (new FlowLayout()); + frame.add(checkbox); + + frame.addMouseWheelListener(new MouseWheelListener() { + public void mouseWheelMoved(MouseWheelEvent e) { + Sysout.println(e.toString()); + double wheelRotation = 0; + if (checkbox.getState()) { + wheelRotation = e.getPreciseWheelRotation(); + } else { + wheelRotation = e.getWheelRotation(); + } + Dimension size = frame.getSize(); + size.width += 10 * wheelRotation; + size.height += 10 * wheelRotation; + frame.setSize(size); + } + }); + + frame.setBounds(200, 200, 200, 200); + frame.setVisible(true); + + }//End init() + + + + /***************************************************** + * Standard Test Machinery Section + * DO NOT modify anything in this section -- it's a + * standard chunk of code which has all of the + * synchronisation necessary for the test harness. + * By keeping it the same in all tests, it is easier + * to read and understand someone else's test, as + * well as insuring that all tests behave correctly + * with the test harness. + * There is a section following this for test-defined + * classes + ******************************************************/ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + + private static Thread mainThread = null; + + private static int sleepTime = 300000; + + public static void main( String args[] ) throws InterruptedException + { + mainThread = Thread.currentThread(); + try + { + init(); + } + catch( TestPassedException e ) + { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test passed nor test failed has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try + { + Thread.sleep( sleepTime ); + //Timed out, so fail the test + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); + } + catch (InterruptedException e) + { + if( ! testGeneratedInterrupt ) throw e; + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + if ( theTestPassed == false ) + { + throw new RuntimeException( failureMessage ); + } + } + + }//main + + public static synchronized void setTimeoutTo( int seconds ) + { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() + { + Sysout.println( "The test passed." ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //first check if this is executing in main thread + if ( mainThread == Thread.currentThread() ) + { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + //pass was called from a different thread, so set the flag and interrupt + // the main thead. + theTestPassed = true; + testGeneratedInterrupt = true; + if (mainThread != null){ + mainThread.interrupt(); + } + }//pass() + + public static synchronized void fail() + { + //test writer didn't specify why test failed, so give generic + fail( "it just plain failed! :-)" ); + } + + public static synchronized void fail( String whyFailed ) + { + Sysout.println( "The test failed: " + whyFailed ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //check if this called from main thread + if ( mainThread == Thread.currentThread() ) + { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException( whyFailed ); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() + +}// class ManualMainTest + +//This exception is used to exit from any level of call nesting +// when it's determined that the test has passed, and immediately +// end the test. +class TestPassedException extends RuntimeException +{ +} + +//*********** End Standard Test Machinery Section ********** + + +//************ Begin classes defined for the test **************** + +// make listeners in a class defined here, and instantiate them in init() + +/* Example of a class which may be written as part of a test +class NewClass implements anInterface + { + static int newVar = 0; + + public void eventDispatched(AWTEvent e) + { + //Counting events to see if we get enough + eventCount++; + + if( eventCount == 20 ) + { + //got enough events, so pass + + ManualMainTest.pass(); + } + else if( tries == 20 ) + { + //tried too many times without getting enough events so fail + + ManualMainTest.fail(); + } + + }// eventDispatched() + + }// NewClass class + +*/ + + +//************** End classes defined for the test ******************* + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout +{ + private static TestDialog dialog; + private static boolean numbering = false; + private static int messageNumber = 0; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + + /* Enables message counting for the tester. */ + public static void enableNumbering(boolean enable){ + numbering = enable; + } + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + if (numbering) { + messageIn = "" + messageNumber + " " + messageIn; + messageNumber++; + } + dialog.displayMessage( messageIn ); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog implements ActionListener +{ + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + Panel buttonP = new Panel(); + Button passB = new Button( "pass" ); + Button failB = new Button( "fail" ); + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + passB = new Button( "pass" ); + passB.setActionCommand( "pass" ); + passB.addActionListener( this ); + buttonP.add( "East", passB ); + + failB = new Button( "fail" ); + failB.setActionCommand( "fail" ); + failB.addActionListener( this ); + buttonP.add( "West", failB ); + + add( "South", buttonP ); + pack(); + + setVisible(true); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + System.out.println(messageIn); + } + + //catch presses of the passed and failed buttons. + //simply call the standard pass() or fail() static methods of + //ManualMainTest + public void actionPerformed( ActionEvent e ) + { + if( e.getActionCommand() == "pass" ) + { + SmoothWheel.pass(); + } + else + { + SmoothWheel.fail(); + } + } + +}// TestDialog class diff --git a/test/java/io/FileOutputStream/AtomicAppend.java b/test/java/io/FileOutputStream/AtomicAppend.java new file mode 100644 index 0000000000000000000000000000000000000000..f5f0c23606c4f5e1202cc9cce1e9afa4283ad62a --- /dev/null +++ b/test/java/io/FileOutputStream/AtomicAppend.java @@ -0,0 +1,81 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6631352 + * @summary Check that appends are atomic + */ + +import java.io.File; +import java.io.FileOutputStream; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.TimeUnit; + +public class AtomicAppend { + // Before the fix for + // 6631352: Implement atomic append mode using FILE_APPEND_DATA (win) + // this would fail intermittently on windows + void test(String[] args) throws Throwable { + final int nThreads = 10; + final int writes = 1000; + final File file = new File("foo"); + file.delete(); + try { + final ExecutorService es = Executors.newFixedThreadPool(nThreads); + for (int i = 0; i < nThreads; i++) + es.execute(new Runnable() { public void run() { + try { + FileOutputStream s = new FileOutputStream(file, true); + for (int j = 0; j < 1000; j++) { + s.write((int) 'x'); + s.flush(); + } + s.close(); + } catch (Throwable t) { unexpected(t); }}}); + es.shutdown(); + es.awaitTermination(10L, TimeUnit.MINUTES); + equal(file.length(), (long) (nThreads * writes)); + } finally { + file.delete(); + } + } + + //--------------------- Infrastructure --------------------------- + volatile int passed = 0, failed = 0; + void pass() {passed++;} + void fail() {failed++; Thread.dumpStack();} + void fail(String msg) {System.err.println(msg); fail();} + void unexpected(Throwable t) {failed++; t.printStackTrace();} + void check(boolean cond) {if (cond) pass(); else fail();} + void equal(Object x, Object y) { + if (x == null ? y == null : x.equals(y)) pass(); + else fail(x + " not equal to " + y);} + public static void main(String[] args) throws Throwable { + new AtomicAppend().instanceMain(args);} + void instanceMain(String[] args) throws Throwable { + try {test(args);} catch (Throwable t) {unexpected(t);} + System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); + if (failed > 0) throw new AssertionError("Some tests failed");} +} diff --git a/test/java/lang/ProcessBuilder/Basic.java b/test/java/lang/ProcessBuilder/Basic.java index 4a57ad94ba6e897dca6979dae315ff26c7a9dce7..b0bfe12f250e06ad639a18bbc7479c7ce04a7a5d 100644 --- a/test/java/lang/ProcessBuilder/Basic.java +++ b/test/java/lang/ProcessBuilder/Basic.java @@ -25,12 +25,15 @@ * @test * @bug 4199068 4738465 4937983 4930681 4926230 4931433 4932663 4986689 * 5026830 5023243 5070673 4052517 4811767 6192449 6397034 6413313 - * 6464154 6523983 6206031 + * 6464154 6523983 6206031 4960438 6631352 6631966 * @summary Basic tests for Process and Environment Variable code * @run main/othervm Basic * @author Martin Buchholz */ +import java.lang.ProcessBuilder.Redirect; +import static java.lang.ProcessBuilder.Redirect.*; + import java.io.*; import java.util.*; import java.security.*; @@ -257,7 +260,29 @@ public class Basic { public static class JavaChild { public static void main(String args[]) throws Throwable { String action = args[0]; - if (action.equals("System.getenv(String)")) { + if (action.equals("testIO")) { + String expected = "standard input"; + char[] buf = new char[expected.length()+1]; + int n = new InputStreamReader(System.in).read(buf,0,buf.length); + if (n != expected.length()) + System.exit(5); + if (! new String(buf,0,n).equals(expected)) + System.exit(5); + System.err.print("standard error"); + System.out.print("standard output"); + } else if (action.equals("testInheritIO")) { + List childArgs = new ArrayList(javaChildArgs); + childArgs.add("testIO"); + ProcessBuilder pb = new ProcessBuilder(childArgs); + pb.inheritIO(); + ProcessResults r = run(pb); + if (! r.out().equals("")) + System.exit(7); + if (! r.err().equals("")) + System.exit(8); + if (r.exitValue() != 0) + System.exit(9); + } else if (action.equals("System.getenv(String)")) { String val = System.getenv(args[1]); printUTF8(val == null ? "null" : val); } else if (action.equals("System.getenv(\\u1234)")) { @@ -599,6 +624,333 @@ public class Basic { } catch (Throwable t) { unexpected(t); } } + static void checkRedirects(ProcessBuilder pb, + Redirect in, Redirect out, Redirect err) { + equal(pb.redirectInput(), in); + equal(pb.redirectOutput(), out); + equal(pb.redirectError(), err); + } + + static void redirectIO(ProcessBuilder pb, + Redirect in, Redirect out, Redirect err) { + pb.redirectInput(in); + pb.redirectOutput(out); + pb.redirectError(err); + } + + static void setFileContents(File file, String contents) { + try { + Writer w = new FileWriter(file); + w.write(contents); + w.close(); + } catch (Throwable t) { unexpected(t); } + } + + static String fileContents(File file) { + try { + Reader r = new FileReader(file); + StringBuilder sb = new StringBuilder(); + char[] buffer = new char[1024]; + int n; + while ((n = r.read(buffer)) != -1) + sb.append(buffer,0,n); + r.close(); + return new String(sb); + } catch (Throwable t) { unexpected(t); return ""; } + } + + static void testIORedirection() throws Throwable { + final File ifile = new File("ifile"); + final File ofile = new File("ofile"); + final File efile = new File("efile"); + ifile.delete(); + ofile.delete(); + efile.delete(); + + //---------------------------------------------------------------- + // Check mutual inequality of different types of Redirect + //---------------------------------------------------------------- + Redirect[] redirects = + { PIPE, + INHERIT, + Redirect.from(ifile), + Redirect.to(ifile), + Redirect.appendTo(ifile), + Redirect.from(ofile), + Redirect.to(ofile), + Redirect.appendTo(ofile), + }; + for (int i = 0; i < redirects.length; i++) + for (int j = 0; j < redirects.length; j++) + equal(redirects[i].equals(redirects[j]), (i == j)); + + //---------------------------------------------------------------- + // Check basic properties of different types of Redirect + //---------------------------------------------------------------- + equal(PIPE.type(), Redirect.Type.PIPE); + equal(PIPE.toString(), "PIPE"); + equal(PIPE.file(), null); + + equal(INHERIT.type(), Redirect.Type.INHERIT); + equal(INHERIT.toString(), "INHERIT"); + equal(INHERIT.file(), null); + + equal(Redirect.from(ifile).type(), Redirect.Type.READ); + equal(Redirect.from(ifile).toString(), + "redirect to read from file \"ifile\""); + equal(Redirect.from(ifile).file(), ifile); + equal(Redirect.from(ifile), + Redirect.from(ifile)); + equal(Redirect.from(ifile).hashCode(), + Redirect.from(ifile).hashCode()); + + equal(Redirect.to(ofile).type(), Redirect.Type.WRITE); + equal(Redirect.to(ofile).toString(), + "redirect to write to file \"ofile\""); + equal(Redirect.to(ofile).file(), ofile); + equal(Redirect.to(ofile), + Redirect.to(ofile)); + equal(Redirect.to(ofile).hashCode(), + Redirect.to(ofile).hashCode()); + + equal(Redirect.appendTo(ofile).type(), Redirect.Type.APPEND); + equal(Redirect.appendTo(efile).toString(), + "redirect to append to file \"efile\""); + equal(Redirect.appendTo(efile).file(), efile); + equal(Redirect.appendTo(efile), + Redirect.appendTo(efile)); + equal(Redirect.appendTo(efile).hashCode(), + Redirect.appendTo(efile).hashCode()); + + //---------------------------------------------------------------- + // Check initial values of redirects + //---------------------------------------------------------------- + List childArgs = new ArrayList(javaChildArgs); + childArgs.add("testIO"); + final ProcessBuilder pb = new ProcessBuilder(childArgs); + checkRedirects(pb, PIPE, PIPE, PIPE); + + //---------------------------------------------------------------- + // Check inheritIO + //---------------------------------------------------------------- + pb.inheritIO(); + checkRedirects(pb, INHERIT, INHERIT, INHERIT); + + //---------------------------------------------------------------- + // Check setters and getters agree + //---------------------------------------------------------------- + pb.redirectInput(ifile); + equal(pb.redirectInput().file(), ifile); + equal(pb.redirectInput(), Redirect.from(ifile)); + + pb.redirectOutput(ofile); + equal(pb.redirectOutput().file(), ofile); + equal(pb.redirectOutput(), Redirect.to(ofile)); + + pb.redirectError(efile); + equal(pb.redirectError().file(), efile); + equal(pb.redirectError(), Redirect.to(efile)); + + THROWS(IllegalArgumentException.class, + new Fun(){void f() { + pb.redirectInput(Redirect.to(ofile)); }}, + new Fun(){void f() { + pb.redirectInput(Redirect.appendTo(ofile)); }}, + new Fun(){void f() { + pb.redirectOutput(Redirect.from(ifile)); }}, + new Fun(){void f() { + pb.redirectError(Redirect.from(ifile)); }}); + + THROWS(IOException.class, + // Input file does not exist + new Fun(){void f() throws Throwable { pb.start(); }}); + setFileContents(ifile, "standard input"); + + //---------------------------------------------------------------- + // Writing to non-existent files + //---------------------------------------------------------------- + { + ProcessResults r = run(pb); + equal(r.exitValue(), 0); + equal(fileContents(ofile), "standard output"); + equal(fileContents(efile), "standard error"); + equal(r.out(), ""); + equal(r.err(), ""); + ofile.delete(); + efile.delete(); + } + + //---------------------------------------------------------------- + // Both redirectErrorStream + redirectError + //---------------------------------------------------------------- + { + pb.redirectErrorStream(true); + ProcessResults r = run(pb); + equal(r.exitValue(), 0); + equal(fileContents(ofile), + "standard error" + "standard output"); + equal(fileContents(efile), ""); + equal(r.out(), ""); + equal(r.err(), ""); + ofile.delete(); + efile.delete(); + } + + //---------------------------------------------------------------- + // Appending to existing files + //---------------------------------------------------------------- + { + setFileContents(ofile, "ofile-contents"); + setFileContents(efile, "efile-contents"); + pb.redirectOutput(Redirect.appendTo(ofile)); + pb.redirectError(Redirect.appendTo(efile)); + pb.redirectErrorStream(false); + ProcessResults r = run(pb); + equal(r.exitValue(), 0); + equal(fileContents(ofile), + "ofile-contents" + "standard output"); + equal(fileContents(efile), + "efile-contents" + "standard error"); + equal(r.out(), ""); + equal(r.err(), ""); + ofile.delete(); + efile.delete(); + } + + //---------------------------------------------------------------- + // Replacing existing files + //---------------------------------------------------------------- + { + setFileContents(ofile, "ofile-contents"); + setFileContents(efile, "efile-contents"); + pb.redirectOutput(ofile); + pb.redirectError(Redirect.to(efile)); + ProcessResults r = run(pb); + equal(r.exitValue(), 0); + equal(fileContents(ofile), "standard output"); + equal(fileContents(efile), "standard error"); + equal(r.out(), ""); + equal(r.err(), ""); + ofile.delete(); + efile.delete(); + } + + //---------------------------------------------------------------- + // Appending twice to the same file? + //---------------------------------------------------------------- + { + setFileContents(ofile, "ofile-contents"); + setFileContents(efile, "efile-contents"); + Redirect appender = Redirect.appendTo(ofile); + pb.redirectOutput(appender); + pb.redirectError(appender); + ProcessResults r = run(pb); + equal(r.exitValue(), 0); + equal(fileContents(ofile), + "ofile-contents" + + "standard error" + + "standard output"); + equal(fileContents(efile), "efile-contents"); + equal(r.out(), ""); + equal(r.err(), ""); + ifile.delete(); + ofile.delete(); + efile.delete(); + } + + //---------------------------------------------------------------- + // Testing INHERIT is harder. + // Note that this requires __FOUR__ nested JVMs involved in one test, + // if you count the harness JVM. + //---------------------------------------------------------------- + { + redirectIO(pb, PIPE, PIPE, PIPE); + List command = pb.command(); + command.set(command.size() - 1, "testInheritIO"); + Process p = pb.start(); + new PrintStream(p.getOutputStream()).print("standard input"); + p.getOutputStream().close(); + ProcessResults r = run(p); + equal(r.exitValue(), 0); + equal(r.out(), "standard output"); + equal(r.err(), "standard error"); + } + + //---------------------------------------------------------------- + // Test security implications of I/O redirection + //---------------------------------------------------------------- + + // Read access to current directory is always granted; + // So create a tmpfile for input instead. + final File tmpFile = File.createTempFile("Basic", "tmp"); + setFileContents(tmpFile, "standard input"); + + final Policy policy = new Policy(); + Policy.setPolicy(policy); + System.setSecurityManager(new SecurityManager()); + try { + final Permission xPermission + = new FilePermission("<>", "execute"); + final Permission rxPermission + = new FilePermission("<>", "read,execute"); + final Permission wxPermission + = new FilePermission("<>", "write,execute"); + final Permission rwxPermission + = new FilePermission("<>", "read,write,execute"); + + THROWS(SecurityException.class, + new Fun() { void f() throws IOException { + policy.setPermissions(xPermission); + redirectIO(pb, from(tmpFile), PIPE, PIPE); + pb.start();}}, + new Fun() { void f() throws IOException { + policy.setPermissions(rxPermission); + redirectIO(pb, PIPE, to(ofile), PIPE); + pb.start();}}, + new Fun() { void f() throws IOException { + policy.setPermissions(rxPermission); + redirectIO(pb, PIPE, PIPE, to(efile)); + pb.start();}}); + + { + policy.setPermissions(rxPermission); + redirectIO(pb, from(tmpFile), PIPE, PIPE); + ProcessResults r = run(pb); + equal(r.out(), "standard output"); + equal(r.err(), "standard error"); + } + + { + policy.setPermissions(wxPermission); + redirectIO(pb, PIPE, to(ofile), to(efile)); + Process p = pb.start(); + new PrintStream(p.getOutputStream()).print("standard input"); + p.getOutputStream().close(); + ProcessResults r = run(p); + policy.setPermissions(rwxPermission); + equal(fileContents(ofile), "standard output"); + equal(fileContents(efile), "standard error"); + } + + { + policy.setPermissions(rwxPermission); + redirectIO(pb, from(tmpFile), to(ofile), to(efile)); + ProcessResults r = run(pb); + policy.setPermissions(rwxPermission); + equal(fileContents(ofile), "standard output"); + equal(fileContents(efile), "standard error"); + } + + } finally { + policy.setPermissions(new RuntimePermission("setSecurityManager")); + System.setSecurityManager(null); + tmpFile.delete(); + ifile.delete(); + ofile.delete(); + efile.delete(); + } + } + private static void realMain(String[] args) throws Throwable { if (Windows.is()) System.out.println("This appears to be a Windows system."); @@ -607,6 +959,9 @@ public class Basic { if (UnicodeOS.is()) System.out.println("This appears to be a Unicode-based OS."); + try { testIORedirection(); } + catch (Throwable t) { unexpected(t); } + //---------------------------------------------------------------- // Basic tests for setting, replacing and deleting envvars //---------------------------------------------------------------- @@ -1354,7 +1709,8 @@ public class Basic { execPermission); ProcessBuilder pb = new ProcessBuilder("env"); pb.environment().put("foo","bar"); - pb.start(); + Process p = pb.start(); + closeStreams(p); } catch (IOException e) { // OK } catch (Throwable t) { unexpected(t); } @@ -1378,6 +1734,14 @@ public class Basic { } + static void closeStreams(Process p) { + try { + p.getOutputStream().close(); + p.getInputStream().close(); + p.getErrorStream().close(); + } catch (Throwable t) { unexpected(t); } + } + //---------------------------------------------------------------- // A Policy class designed to make permissions fiddling very easy. //---------------------------------------------------------------- @@ -1432,10 +1796,19 @@ public class Basic { } } catch (Throwable t) { throwable = t; + } finally { + try { is.close(); } + catch (Throwable t) { throwable = t; } } } } + static ProcessResults run(ProcessBuilder pb) { + try { + return run(pb.start()); + } catch (Throwable t) { unexpected(t); return null; } + } + private static ProcessResults run(Process p) { Throwable throwable = null; int exitValue = -1; diff --git a/test/java/net/CookieHandler/CookieManagerTest.java b/test/java/net/CookieHandler/CookieManagerTest.java index a2c9db3b411ea7ac4083ebbf82567630d1e78b54..b83c27fcefc7527825bedf72808b48a0d7ac22b4 100644 --- a/test/java/net/CookieHandler/CookieManagerTest.java +++ b/test/java/net/CookieHandler/CookieManagerTest.java @@ -132,17 +132,17 @@ class CookieHttpTransaction implements HttpCallback { ), new CookieTestCase("Set-Cookie", "PART_NUMBER=ROCKET_LAUNCHER_0001; path=/;" + "domain=." + localHostAddr, - "CUSTOMER=WILE:BOB;PART_NUMBER=ROCKET_LAUNCHER_0001", + "CUSTOMER=WILE:BOB; PART_NUMBER=ROCKET_LAUNCHER_0001", "/" ), new CookieTestCase("Set-Cookie", "SHIPPING=FEDEX; path=/foo;" + "domain=." + localHostAddr, - "CUSTOMER=WILE:BOB;PART_NUMBER=ROCKET_LAUNCHER_0001", + "CUSTOMER=WILE:BOB; PART_NUMBER=ROCKET_LAUNCHER_0001", "/" ), new CookieTestCase("Set-Cookie", "SHIPPING=FEDEX; path=/foo;" + "domain=." + localHostAddr, - "CUSTOMER=WILE:BOB;PART_NUMBER=ROCKET_LAUNCHER_0001;SHIPPING=FEDEX", + "CUSTOMER=WILE:BOB; PART_NUMBER=ROCKET_LAUNCHER_0001; SHIPPING=FEDEX", "/foo" ) }; @@ -157,7 +157,7 @@ class CookieHttpTransaction implements HttpCallback { ), new CookieTestCase("Set-Cookie", "PART_NUMBER=RIDING_ROCKET_0023; path=/ammo;" + "domain=." + localHostAddr, - "PART_NUMBER=RIDING_ROCKET_0023;PART_NUMBER=ROCKET_LAUNCHER_0001", + "PART_NUMBER=RIDING_ROCKET_0023; PART_NUMBER=ROCKET_LAUNCHER_0001", "/ammo" ) }; @@ -167,17 +167,17 @@ class CookieHttpTransaction implements HttpCallback { testCases[count++] = new CookieTestCase[]{ new CookieTestCase("Set-Cookie2", "Customer=\"WILE_E_COYOTE\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr, - "$Version=\"1\";Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"", + "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"", "/acme/login" ), new CookieTestCase("Set-Cookie2", "Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\";Path=\"/acme\";" + "domain=." + localHostAddr, - "$Version=\"1\";Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"" + ";Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"", + "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"", "/acme/pickitem" ), new CookieTestCase("Set-Cookie2", "Shipping=\"FedEx\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr, - "$Version=\"1\";Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"" + ";Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"" + ";Shipping=\"FedEx\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"", + "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"" + "; Shipping=\"FedEx\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"", "/acme/shipping" ) }; @@ -187,17 +187,17 @@ class CookieHttpTransaction implements HttpCallback { testCases[count++] = new CookieTestCase[]{ new CookieTestCase("Set-Cookie2", "Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr, - "$Version=\"1\";Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"", + "$Version=\"1\"; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"", "/acme/ammo" ), new CookieTestCase("Set-Cookie2", "Part_Number=\"Riding_Rocket_0023\"; Version=\"1\"; Path=\"/acme/ammo\";" + "domain=." + localHostAddr, - "$Version=\"1\";Part_Number=\"Riding_Rocket_0023\";$Path=\"/acme/ammo\";$Domain=\"." + localHostAddr + "\"" + ";Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"", + "$Version=\"1\"; Part_Number=\"Riding_Rocket_0023\";$Path=\"/acme/ammo\";$Domain=\"." + localHostAddr + "\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"", "/acme/ammo" ), new CookieTestCase("", "", - "$Version=\"1\";Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"", + "$Version=\"1\"; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"", "/acme/parts" ) }; @@ -207,12 +207,12 @@ class CookieHttpTransaction implements HttpCallback { testCases[count++] = new CookieTestCase[]{ new CookieTestCase("Set-Cookie2", "Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr, - "$Version=\"1\";Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"", + "$Version=\"1\"; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"", "/acme" ), new CookieTestCase("Set-Cookie2", "Part_Number=\"Rocket_Launcher_2000\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr, - "$Version=\"1\";Part_Number=\"Rocket_Launcher_2000\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"", + "$Version=\"1\"; Part_Number=\"Rocket_Launcher_2000\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"", "/acme" ) }; @@ -222,17 +222,17 @@ class CookieHttpTransaction implements HttpCallback { testCases[count++] = new CookieTestCase[]{ new CookieTestCase("Set-Cookie2", "Customer=\"WILE_E_COYOTE\"; Version=\"1\"; Path=\"/acme\"", - "$Version=\"1\";Customer=\"WILE_E_COYOTE\";$Path=\"/acme\"", + "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\"", "/acme/login" ), new CookieTestCase("Set-Cookie2", "Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\";Path=\"/acme\"", - "$Version=\"1\";Customer=\"WILE_E_COYOTE\";$Path=\"/acme\"" + ";Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\"", + "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\"", "/acme/pickitem" ), new CookieTestCase("Set-Cookie2", "Shipping=\"FedEx\"; Version=\"1\"; Path=\"/acme\"", - "$Version=\"1\";Customer=\"WILE_E_COYOTE\";$Path=\"/acme\"" + ";Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\"" + ";Shipping=\"FedEx\";$Path=\"/acme\"", + "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\"" + "; Shipping=\"FedEx\";$Path=\"/acme\"", "/acme/shipping" ) }; diff --git a/test/java/net/InterfaceAddress/Equals.java b/test/java/net/InterfaceAddress/Equals.java new file mode 100644 index 0000000000000000000000000000000000000000..5403bebe04c8866fd04f7fa6dba1c8c1a1cdc625 --- /dev/null +++ b/test/java/net/InterfaceAddress/Equals.java @@ -0,0 +1,119 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* @test + * @bug 6628576 + * @summary InterfaceAddress.equals() NPE when broadcast field == null + */ + +import java.net.InterfaceAddress; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; + +public class Equals +{ + public static void main(String[] args) { + InterfaceAddress ia1; + InterfaceAddress ia2; + InetAddress loopbackAddr = InetAddress.getLoopbackAddress(); + InetAddress broadcast1 = null; + InetAddress broadcast2 = null; + + try { + broadcast1 = InetAddress.getByName("255.255.255.0"); + broadcast2 = InetAddress.getByName("255.255.0.0"); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + ia1 = createInterfaceAddress(loopbackAddr, (InetAddress) null, (short)45); + ia2 = createInterfaceAddress(loopbackAddr, (InetAddress) null, (short)45); + + compare(ia1, ia2, true); + + ia2 = createInterfaceAddress(loopbackAddr, broadcast1, (short)45); + compare(ia1, ia2, false); + + ia2 = createInterfaceAddress((InetAddress)null, broadcast1, (short)45); + compare(ia1, ia2, false); + + ia1 = createInterfaceAddress(loopbackAddr, broadcast2, (short)45); + ia2 = createInterfaceAddress(loopbackAddr, broadcast2, (short)45); + compare(ia1, ia2, true); + + ia1.equals(null); + } + + static void compare(InterfaceAddress ia1, InterfaceAddress ia2, boolean equal) { + if (ia1.equals(ia2) != equal) + throw new RuntimeException("Failed: " + ia1 + " not equals to " + ia2); + + if (ia2.equals(ia1) != equal) + throw new RuntimeException("Failed: " + ia2 + " not equals to " + ia1); + } + + /** + * Returns an InterfaceAddress instance with its fields set the the values + * specificed. + */ + static InterfaceAddress createInterfaceAddress( + InetAddress address, InetAddress broadcast, short prefixlength) { + try { + Class IAClass = InterfaceAddress.class; + InterfaceAddress ia; + Constructor ctr = IAClass.getDeclaredConstructor(); + ctr.setAccessible(true); + + Field addressField = IAClass.getDeclaredField("address"); + addressField.setAccessible(true); + + Field broadcastField = IAClass.getDeclaredField("broadcast"); + broadcastField.setAccessible(true); + + Field maskLengthField = IAClass.getDeclaredField("maskLength"); + maskLengthField.setAccessible(true); + + ia = ctr.newInstance(); + addressField.set(ia, address); + broadcastField.set(ia, broadcast); + maskLengthField.setShort(ia, prefixlength); + + return ia; + } catch (NoSuchFieldException nsfe) { + nsfe.printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (InstantiationException ie) { + ie.printStackTrace(); + } catch (IllegalAccessException iae) { + iae.printStackTrace(); + } catch (InvocationTargetException ite) { + ite.printStackTrace(); + } + + return null; + } +} diff --git a/test/java/net/ResponseCache/file2.1 b/test/java/net/ResponseCache/file2.1 index 428de11adaa6bbf21e59db4908df028e401bb87f..1878bc2fe8824d743ea73c9d0fa986d15f14d440 100644 --- a/test/java/net/ResponseCache/file2.1 +++ b/test/java/net/ResponseCache/file2.1 @@ -1,4 +1,4 @@ -/* @test +/* @test @(#)file2.1 1.1 03/08/09 * @summary Unit test for java.net.ResponseCacheHandler * @bug 4837267 * @author Yingxian Wang diff --git a/test/java/nio/Buffer/StringCharBufferSliceTest.java b/test/java/nio/Buffer/StringCharBufferSliceTest.java index 56770025c32d2c8f35b8c1acc508c5e0a338699a..82d593c5d70b923b5cbd65d9194d4a6ebaca7c38 100644 --- a/test/java/nio/Buffer/StringCharBufferSliceTest.java +++ b/test/java/nio/Buffer/StringCharBufferSliceTest.java @@ -53,6 +53,57 @@ public class StringCharBufferSliceTest { buff = CharBuffer.wrap(in, 3, in.length()); test(buff, buff.slice()); + System.out.println( + ">>> StringCharBufferSliceTest-main: testing slice result with get()"); + buff.position(4); + buff.limit(7); + CharBuffer slice = buff.slice(); + for (int i = 0; i < 3; i++) { + if (slice.get() != buff.get()) { + throw new RuntimeException("Wrong characters in slice result."); + } + } + + System.out.println( + ">>> StringCharBufferSliceTest-main: testing slice result with get(int)"); + buff.position(4); + buff.limit(7); + slice = buff.slice(); + for (int i = 0; i < 3; i++) { + if (slice.get(i) != buff.get(4 + i)) { + throw new RuntimeException("Wrong characters in slice result."); + } + } + + System.out.println( + ">>> StringCharBufferSliceTest-main: testing toString."); + buff.position(4); + buff.limit(7); + slice = buff.slice(); + if (! slice.toString().equals("tes")) { + throw new RuntimeException("bad toString() after slice(): " + slice.toString()); + } + + System.out.println( + ">>> StringCharBufferSliceTest-main: testing subSequence."); + buff.position(4); + buff.limit(8); + slice = buff.slice(); + CharSequence subSeq = slice.subSequence(1, 3); + if (subSeq.charAt(0) != 'e' || subSeq.charAt(1) != 's') { + throw new RuntimeException("bad subSequence() after slice(): '" + subSeq + "'"); + } + + System.out.println( + ">>> StringCharBufferSliceTest-main: testing duplicate."); + buff.position(4); + buff.limit(8); + slice = buff.slice(); + CharBuffer dupe = slice.duplicate(); + if (dupe.charAt(0) != 't' || dupe.charAt(1) != 'e' + || dupe.charAt(2) != 's' || dupe.charAt(3) != 't') { + throw new RuntimeException("bad duplicate() after slice(): '" + dupe + "'"); + } System.out.println(">>> StringCharBufferSliceTest-main: done!"); } diff --git a/test/java/nio/channels/Channels/ShortWrite.java b/test/java/nio/channels/Channels/ShortWrite.java new file mode 100644 index 0000000000000000000000000000000000000000..0418add7359d7dfb62f2329c5d9273d532f5dcd7 --- /dev/null +++ b/test/java/nio/channels/Channels/ShortWrite.java @@ -0,0 +1,83 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* @test + * @bug 6448457 + * @summary Test Channels.newOutputStream returns OutputStream that handles + * short writes from the underlying channel + */ + +import java.io.OutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.*; +import java.util.Random; + +public class ShortWrite { + + static Random rand = new Random(); + static int bytesWritten = 0; + + public static void main(String[] args) throws IOException { + + WritableByteChannel wbc = new WritableByteChannel() { + public int write(ByteBuffer src) { + int rem = src.remaining(); + if (rem > 0) { + // short write + int n = rand.nextInt(rem) + 1; + src.position(src.position() + n); + bytesWritten += n; + return n; + } else { + return 0; + } + } + public void close() throws IOException { + throw new RuntimeException("not implemented"); + } + public boolean isOpen() { + throw new RuntimeException("not implemented"); + } + }; + + // wrap Channel with OutputStream + OutputStream out = Channels.newOutputStream(wbc); + + + // write 100, 99, 98, ... 1 + // and check that the expected number of bytes is written + int expected = 0; + byte[] buf = new byte[100]; + for (int i=0; i maps) { + Map first = maps.get(0); + for (Map map : maps) + mapsEqual(first, map); + } + + void put(List maps, Object key, Object val) { + for (Map map : maps) + map.put(key, val); + mapsEqual(maps); + } + + void removeLastTwo(List maps) { + Map first = maps.get(0); + int size = first.size(); + Iterator fit = first.keySet().iterator(); + for (int j = 0; j < size - 2; j++) + fit.next(); + Object x1 = fit.next(); + Object x2 = fit.next(); + + for (Map map : maps) { + Iterator it = map.keySet().iterator(); + while (it.hasNext()) { + Object x = it.next(); + if (x == x1 || x == x2) + it.remove(); + } + } + mapsEqual(maps); + } + + void remove(Map m, Iterator it) { + int size = m.size(); + it.remove(); + if (m.size() != size-1) + throw new Error(String.format("Incorrect size!%nmap=%s, size=%d%n", + m.toString(), m.size())); + } + + void test(String[] args) throws Throwable { + final int iterations = 100; + final Random r = new Random(); + + for (int i = 0; i < iterations; i++) { + List maps = Arrays.asList( + new Map[] { + new IdentityHashMap(11), + new HashMap(16), + new LinkedHashMap(16), + new WeakHashMap(16), + new Hashtable(16), + new TreeMap(), + new ConcurrentHashMap(16), + new ConcurrentSkipListMap() }); + + for (int j = 0; j < 10; j++) + put(maps, r.nextInt(100), r.nextInt(100)); + removeLastTwo(maps); + } + } + + //--------------------- Infrastructure --------------------------- + volatile int passed = 0, failed = 0; + void pass() {passed++;} + void fail() {failed++; Thread.dumpStack();} + void fail(String msg) {System.err.println(msg); fail();} + void unexpected(Throwable t) {failed++; t.printStackTrace();} + void check(boolean cond) {if (cond) pass(); else fail();} + void equal(Object x, Object y) { + if (x == null ? y == null : x.equals(y)) pass(); + else fail(x + " not equal to " + y);} + public static void main(String[] args) throws Throwable { + new LockStep().instanceMain(args);} + void instanceMain(String[] args) throws Throwable { + try {test(args);} catch (Throwable t) {unexpected(t);} + System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); + if (failed > 0) throw new AssertionError("Some tests failed");} +} diff --git a/test/java/util/concurrent/DelayQueue/Stress.java b/test/java/util/concurrent/DelayQueue/Stress.java new file mode 100644 index 0000000000000000000000000000000000000000..e225f542efddd420adea4f79f9c0821d3b633da2 --- /dev/null +++ b/test/java/util/concurrent/DelayQueue/Stress.java @@ -0,0 +1,61 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import java.util.concurrent.*; +import static java.util.concurrent.TimeUnit.*; + +/** + * This is not a regression test, but a stress benchmark test for + * 6609775: Reduce context switches in DelayQueue due to signalAll + * + * This runs in the same wall clock time, but much reduced cpu time, + * with the changes for 6609775. + */ +public class Stress { + + public static void main(String[] args) throws Throwable { + + final DelayQueue q = new DelayQueue(); + final long t0 = System.nanoTime(); + for (long i = 0; i < 1000; i++) { + final long expiry = t0 + i*10L*1000L*1000L; + q.add(new Delayed() { + public long getDelay(TimeUnit unit) { + return unit.convert(expiry - System.nanoTime(), + NANOSECONDS); + } + public int compareTo(Delayed x) { + long d = getDelay(NANOSECONDS) + - x.getDelay(NANOSECONDS); + return d < 0 ? -1 : d > 0 ? 1 : 0; }}); + } + + for (int i = 0; i < 300; i++) + new Thread() { public void run() { + try { + while (!q.isEmpty()) + q.poll(10L, TimeUnit.SECONDS); + } catch (Throwable t) { t.printStackTrace(); } + }}.start(); + } +} diff --git a/test/java/util/concurrent/LinkedBlockingQueue/OfferRemoveLoops.java b/test/java/util/concurrent/LinkedBlockingQueue/OfferRemoveLoops.java index bcec477ce8d9a121bdfb1526df3aef412d2de41c..baca8f1b0f1e741b589877bb0fdb2d2bbf3cbee0 100644 --- a/test/java/util/concurrent/LinkedBlockingQueue/OfferRemoveLoops.java +++ b/test/java/util/concurrent/LinkedBlockingQueue/OfferRemoveLoops.java @@ -23,7 +23,7 @@ /* * @test - * @bug 6316155 + * @bug 6316155 6595669 * @summary Test concurrent offer vs. remove * @author Martin Buchholz */ @@ -50,15 +50,18 @@ public class OfferRemoveLoops { private static void testQueue(final BlockingQueue q) throws Throwable { System.out.println(q.getClass()); final int count = 10000; + final long quittingTime = System.nanoTime() + 1L * 1000L * 1000L * 1000L; Thread t1 = new ControlledThread() { protected void realRun() { for (int i = 0, j = 0; i < count; i++) - while (! q.remove(String.valueOf(i))) + while (! q.remove(String.valueOf(i)) + && System.nanoTime() - quittingTime < 0) Thread.yield();}}; Thread t2 = new ControlledThread() { protected void realRun() { for (int i = 0, j = 0; i < count; i++) - while (! q.offer(String.valueOf(i))) + while (! q.offer(String.valueOf(i)) + && System.nanoTime() - quittingTime < 0) Thread.yield();}}; t1.setDaemon(true); t2.setDaemon(true); t1.start(); t2.start(); diff --git a/test/java/util/concurrent/ScheduledThreadPoolExecutor/BasicCancelTest.java b/test/java/util/concurrent/ScheduledThreadPoolExecutor/BasicCancelTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0e782d1d2f699abc685d0f4fd97fc6fdcb3c5ff8 --- /dev/null +++ b/test/java/util/concurrent/ScheduledThreadPoolExecutor/BasicCancelTest.java @@ -0,0 +1,113 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6602600 + * @run main/othervm -Xmx8m BasicCancelTest + * @summary Check effectiveness of RemoveOnCancelPolicy + */ + +import java.util.concurrent.*; +import java.util.Random; + +/** + * Simple timer cancellation test. Submits tasks to a scheduled executor + * service and immediately cancels them. + */ +public class BasicCancelTest { + + void checkShutdown(final ExecutorService es) { + final Runnable nop = new Runnable() {public void run() {}}; + try { + if (new Random().nextBoolean()) { + check(es.isShutdown()); + if (es instanceof ThreadPoolExecutor) + check(((ThreadPoolExecutor) es).isTerminating() + || es.isTerminated()); + THROWS(RejectedExecutionException.class, + new F(){void f(){es.execute(nop);}}); + } + } catch (Throwable t) { unexpected(t); } + } + + void checkTerminated(final ThreadPoolExecutor tpe) { + try { + checkShutdown(tpe); + check(tpe.getQueue().isEmpty()); + check(tpe.isTerminated()); + check(! tpe.isTerminating()); + equal(tpe.getActiveCount(), 0); + equal(tpe.getPoolSize(), 0); + equal(tpe.getTaskCount(), tpe.getCompletedTaskCount()); + check(tpe.awaitTermination(0, TimeUnit.SECONDS)); + } catch (Throwable t) { unexpected(t); } + } + + void test(String[] args) throws Throwable { + + final ScheduledThreadPoolExecutor pool = + new ScheduledThreadPoolExecutor(1); + + // Needed to avoid OOME + pool.setRemoveOnCancelPolicy(true); + + final long moreThanYouCanChew = Runtime.getRuntime().freeMemory() / 4; + System.out.printf("moreThanYouCanChew=%d%n", moreThanYouCanChew); + + Runnable noopTask = new Runnable() { public void run() {}}; + + for (long i = 0; i < moreThanYouCanChew; i++) + pool.schedule(noopTask, 10, TimeUnit.MINUTES).cancel(true); + + pool.shutdown(); + check(pool.awaitTermination(1L, TimeUnit.DAYS)); + checkTerminated(pool); + equal(pool.getTaskCount(), 0L); + equal(pool.getCompletedTaskCount(), 0L); + } + + //--------------------- Infrastructure --------------------------- + volatile int passed = 0, failed = 0; + void pass() {passed++;} + void fail() {failed++; Thread.dumpStack();} + void fail(String msg) {System.err.println(msg); fail();} + void unexpected(Throwable t) {failed++; t.printStackTrace();} + void check(boolean cond) {if (cond) pass(); else fail();} + void equal(Object x, Object y) { + if (x == null ? y == null : x.equals(y)) pass(); + else fail(x + " not equal to " + y);} + public static void main(String[] args) throws Throwable { + new BasicCancelTest().instanceMain(args);} + void instanceMain(String[] args) throws Throwable { + try {test(args);} catch (Throwable t) {unexpected(t);} + System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); + if (failed > 0) throw new AssertionError("Some tests failed");} + abstract class F {abstract void f() throws Throwable;} + void THROWS(Class k, F... fs) { + for (F f : fs) + try {f.f(); fail("Expected " + k.getName() + " not thrown");} + catch (Throwable t) { + if (k.isAssignableFrom(t.getClass())) pass(); + else unexpected(t);}} +} diff --git a/test/java/util/concurrent/ScheduledThreadPoolExecutor/Stress.java b/test/java/util/concurrent/ScheduledThreadPoolExecutor/Stress.java new file mode 100644 index 0000000000000000000000000000000000000000..d60953712097c5b5e354a3427406d2c2fc1a2f78 --- /dev/null +++ b/test/java/util/concurrent/ScheduledThreadPoolExecutor/Stress.java @@ -0,0 +1,54 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import java.util.concurrent.*; + +/** + * This is not a regression test, but a stress benchmark test for + * 6602600: Fast removal of cancelled scheduled thread pool tasks + * + * This runs in the same wall clock time, but much reduced cpu time, + * with the changes for 6602600. + */ +public class Stress { + + public static void main(String[] args) throws Throwable { + + final CountDownLatch count = new CountDownLatch(1000); + + final ScheduledThreadPoolExecutor pool = + new ScheduledThreadPoolExecutor(100); + pool.prestartAllCoreThreads(); + + final Runnable incTask = new Runnable() { public void run() { + count.countDown(); + }}; + + pool.scheduleAtFixedRate(incTask, 0, 10, TimeUnit.MILLISECONDS); + + count.await(); + + pool.shutdown(); + pool.awaitTermination(1L, TimeUnit.DAYS); + } +} diff --git a/test/java/util/concurrent/SynchronousQueue/Fairness.java b/test/java/util/concurrent/SynchronousQueue/Fairness.java index 2a8a35a83feca02b40c9c99bb78cec87a1f09515..5adb71d99f7735985d9a27ead064c5fc50c742df 100644 --- a/test/java/util/concurrent/SynchronousQueue/Fairness.java +++ b/test/java/util/concurrent/SynchronousQueue/Fairness.java @@ -23,36 +23,49 @@ /* * @test - * @bug 4992438 - * @compile -source 1.5 Fairness.java - * @run main Fairness + * @bug 4992438 6633113 * @summary Checks that fairness setting is respected. */ import java.util.concurrent.*; +import java.util.concurrent.locks.*; public class Fairness { private static void testFairness(boolean fair, final BlockingQueue q) - throws Exception + throws Throwable { - for (int i = 0; i < 3; i++) { - final Integer I = new Integer(i); - new Thread() { public void run() { - try { q.put(I); } catch (Exception e) {} - }}.start(); - Thread.currentThread().sleep(100); + final ReentrantLock lock = new ReentrantLock(); + final Condition ready = lock.newCondition(); + final int threadCount = 10; + final Throwable[] badness = new Throwable[1]; + lock.lock(); + for (int i = 0; i < threadCount; i++) { + final Integer I = i; + Thread t = new Thread() { public void run() { + try { + lock.lock(); + ready.signal(); + lock.unlock(); + q.put(I); + } catch (Throwable t) { badness[0] = t; }}}; + t.start(); + ready.await(); + // Probably unnecessary, but should be bullet-proof + while (t.getState() == Thread.State.RUNNABLE) + Thread.yield(); } - for (int i = 0; i < 3; i++) { - int j = q.take().intValue(); - System.err.printf("%d%n",j); + for (int i = 0; i < threadCount; i++) { + int j = q.take(); // Non-fair queues are lifo in our implementation - if (fair ? j != i : j != 2-i) - throw new Exception("No fair!"); + if (fair ? j != i : j != threadCount - 1 - i) + throw new Error(String.format("fair=%b i=%d j=%d%n", + fair, i, j)); } + if (badness[0] != null) throw new Error(badness[0]); } - public static void main(String[] args) throws Exception { + public static void main(String[] args) throws Throwable { testFairness(false, new SynchronousQueue()); testFairness(false, new SynchronousQueue(false)); testFairness(true, new SynchronousQueue(true)); diff --git a/test/java/util/concurrent/locks/ReentrantReadWriteLock/Count.java b/test/java/util/concurrent/locks/ReentrantReadWriteLock/Count.java index 0e7b9e4549dff323b796b27db9bb1a110c5fc7cb..a4d78117341a8a1ddc5bc3530b0aa8cbe2c1f5d8 100644 --- a/test/java/util/concurrent/locks/ReentrantReadWriteLock/Count.java +++ b/test/java/util/concurrent/locks/ReentrantReadWriteLock/Count.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 Sun Microsystems, Inc. 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 @@ -23,21 +23,89 @@ /* * @test - * @bug 6207928 6328220 6378321 + * @bug 6207928 6328220 6378321 6625723 * @summary Recursive lock invariant sanity checks * @author Martin Buchholz */ +import java.io.*; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.locks.*; // I am the Cownt, and I lahve to cownt. public class Count { - private static void realMain(String[] args) throws Throwable { - final ReentrantLock rl = new ReentrantLock(); - final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); + final Random rnd = new Random(); + + void lock(Lock lock) { + try { + switch (rnd.nextInt(4)) { + case 0: lock.lock(); break; + case 1: lock.lockInterruptibly(); break; + case 2: check(lock.tryLock()); break; + case 3: check(lock.tryLock(45, TimeUnit.MINUTES)); break; + } + } catch (Throwable t) { unexpected(t); } + } + + void test(String[] args) throws Throwable { + for (boolean fair : new boolean[] { true, false }) + for (boolean serialClone : new boolean[] { true, false }) { + testReentrantLocks(fair, serialClone); + testConcurrentReadLocks(fair, serialClone); + } + } + + void testConcurrentReadLocks(final boolean fair, + final boolean serialClone) throws Throwable { + final int nThreads = 10; + final CyclicBarrier barrier = new CyclicBarrier(nThreads); + final ExecutorService es = Executors.newFixedThreadPool(nThreads); + final ReentrantReadWriteLock rwl = serialClone ? + serialClone(new ReentrantReadWriteLock(fair)) : + new ReentrantReadWriteLock(fair); + for (int i = 0; i < nThreads; i++) { + es.submit(new Runnable() { public void run() { + try { + int n = 5; + for (int i = 0; i < n; i++) { + barrier.await(); + equal(rwl.getReadHoldCount(), i); + equal(rwl.getWriteHoldCount(), 0); + check(! rwl.isWriteLocked()); + equal(rwl.getReadLockCount(), nThreads * i); + barrier.await(); + lock(rwl.readLock()); + } + for (int i = 0; i < n; i++) { + rwl.readLock().unlock(); + barrier.await(); + equal(rwl.getReadHoldCount(), n-i-1); + equal(rwl.getReadLockCount(), nThreads*(n-i-1)); + equal(rwl.getWriteHoldCount(), 0); + check(! rwl.isWriteLocked()); + barrier.await(); + } + THROWS(IllegalMonitorStateException.class, + new F(){void f(){rwl.readLock().unlock();}}, + new F(){void f(){rwl.writeLock().unlock();}}); + barrier.await(); + } catch (Throwable t) { unexpected(t); }}});} + es.shutdown(); + check(es.awaitTermination(10, TimeUnit.SECONDS)); + } + + void testReentrantLocks(final boolean fair, + final boolean serialClone) throws Throwable { + final ReentrantLock rl = serialClone ? + serialClone(new ReentrantLock(fair)) : + new ReentrantLock(fair); + final ReentrantReadWriteLock rwl = serialClone ? + serialClone(new ReentrantReadWriteLock(fair)) : + new ReentrantReadWriteLock(fair); final int depth = 10; + equal(rl.isFair(), fair); + equal(rwl.isFair(), fair); check(! rl.isLocked()); check(! rwl.isWriteLocked()); check(! rl.isHeldByCurrentThread()); @@ -50,28 +118,11 @@ public class Count { equal(rwl.getReadHoldCount(), i); equal(rwl.getWriteHoldCount(), i); equal(rwl.writeLock().getHoldCount(), i); - switch (i%4) { - case 0: - rl.lock(); - rwl.writeLock().lock(); - rwl.readLock().lock(); - break; - case 1: - rl.lockInterruptibly(); - rwl.writeLock().lockInterruptibly(); - rwl.readLock().lockInterruptibly(); - break; - case 2: - check(rl.tryLock()); - check(rwl.writeLock().tryLock()); - check(rwl.readLock().tryLock()); - break; - case 3: - check(rl.tryLock(454, TimeUnit.MILLISECONDS)); - check(rwl.writeLock().tryLock(454, TimeUnit.NANOSECONDS)); - check(rwl.readLock().tryLock(454, TimeUnit.HOURS)); - break; - } + equal(rl.isLocked(), i > 0); + equal(rwl.isWriteLocked(), i > 0); + lock(rl); + lock(rwl.writeLock()); + lock(rwl.readLock()); } for (int i = depth; i > 0; i--) { @@ -95,20 +146,48 @@ public class Count { rwl.writeLock().unlock(); rl.unlock(); } + THROWS(IllegalMonitorStateException.class, + new F(){void f(){rl.unlock();}}, + new F(){void f(){rwl.readLock().unlock();}}, + new F(){void f(){rwl.writeLock().unlock();}}); } //--------------------- Infrastructure --------------------------- - static volatile int passed = 0, failed = 0; - static void pass() {passed++;} - static void fail() {failed++; Thread.dumpStack();} - static void fail(String msg) {System.out.println(msg); fail();} - static void unexpected(Throwable t) {failed++; t.printStackTrace();} - static void check(boolean cond) {if (cond) pass(); else fail();} - static void equal(Object x, Object y) { + volatile int passed = 0, failed = 0; + void pass() {passed++;} + void fail() {failed++; Thread.dumpStack();} + void fail(String msg) {System.err.println(msg); fail();} + void unexpected(Throwable t) {failed++; t.printStackTrace();} + void check(boolean cond) {if (cond) pass(); else fail();} + void equal(Object x, Object y) { if (x == null ? y == null : x.equals(y)) pass(); else fail(x + " not equal to " + y);} public static void main(String[] args) throws Throwable { - try {realMain(args);} catch (Throwable t) {unexpected(t);} + new Count().instanceMain(args);} + void instanceMain(String[] args) throws Throwable { + try {test(args);} catch (Throwable t) {unexpected(t);} System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); if (failed > 0) throw new AssertionError("Some tests failed");} + abstract class F {abstract void f() throws Throwable;} + void THROWS(Class k, F... fs) { + for (F f : fs) + try {f.f(); fail("Expected " + k.getName() + " not thrown");} + catch (Throwable t) { + if (k.isAssignableFrom(t.getClass())) pass(); + else unexpected(t);}} + + static byte[] serializedForm(Object obj) { + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + new ObjectOutputStream(baos).writeObject(obj); + return baos.toByteArray(); + } catch (IOException e) { throw new RuntimeException(e); }} + static Object readObject(byte[] bytes) + throws IOException, ClassNotFoundException { + InputStream is = new ByteArrayInputStream(bytes); + return new ObjectInputStream(is).readObject();} + @SuppressWarnings("unchecked") + static T serialClone(T obj) { + try { return (T) readObject(serializedForm(obj)); } + catch (Exception e) { throw new RuntimeException(e); }} } diff --git a/test/javax/management/mxbean/JMXServiceURLTest.java b/test/javax/management/mxbean/JMXServiceURLTest.java new file mode 100644 index 0000000000000000000000000000000000000000..dc796037c3536fe537d4c8c1f6879780883b6fab --- /dev/null +++ b/test/javax/management/mxbean/JMXServiceURLTest.java @@ -0,0 +1,103 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test JMXServiceURLTest + * @bug 6607114 6670375 + * @summary Test that JMXServiceURL works correctly in MXBeans + * @author Eamonn McManus + */ + +import java.lang.management.ManagementFactory; +import javax.management.JMX; +import javax.management.MBeanServer; +import javax.management.ObjectName; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.OpenType; +import javax.management.openmbean.SimpleType; +import javax.management.remote.JMXServiceURL; + +public class JMXServiceURLTest { + public static interface UrlMXBean { + public JMXServiceURL getUrl(); + public void setUrl(JMXServiceURL url); + } + + public static class UrlImpl implements UrlMXBean { + volatile JMXServiceURL url; + + public JMXServiceURL getUrl() { + return url; + } + + public void setUrl(JMXServiceURL url) { + this.url = url; + } + } + + public static void main(String[] args) throws Exception { + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + ObjectName name = new ObjectName("a:b=c"); + UrlImpl urlImpl = new UrlImpl(); + mbs.registerMBean(urlImpl, name); + + JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://host:8000/noddy"); + UrlMXBean proxy = JMX.newMXBeanProxy(mbs, name, UrlMXBean.class); + proxy.setUrl(url); + assertEquals(url, urlImpl.url); + JMXServiceURL url2 = proxy.getUrl(); + assertEquals(url, url2); + + CompositeData cd = (CompositeData) mbs.getAttribute(name, "Url"); + CompositeType ct = cd.getCompositeType(); + // Make sure it looks like what we expect. This will have to be + // changed if ever we add new properties to CompositeType. In that + // case this test should also check interoperability between the + // current version and the new version. + assertEquals(4, ct.keySet().size()); + Object[][] expectedItems = { + {"protocol", SimpleType.STRING, "rmi"}, + {"host", SimpleType.STRING, "host"}, + {"port", SimpleType.INTEGER, 8000}, + {"URLPath", SimpleType.STRING, "/noddy"}, + }; + for (Object[] expectedItem : expectedItems) { + String itemName = (String) expectedItem[0]; + OpenType expectedType = (OpenType) expectedItem[1]; + Object expectedValue = expectedItem[2]; + OpenType actualType = ct.getType(itemName); + assertEquals(expectedType, actualType); + Object actualValue = cd.get(itemName); + assertEquals(expectedValue, actualValue); + } + } + + private static void assertEquals(Object expect, Object actual) + throws Exception { + if (expect.equals(actual)) + System.out.println("Equal: " + expect); + else + throw new Exception("Expected " + expect + ", got " + actual); + } +} diff --git a/test/javax/management/query/QueryDottedAttrTest.java b/test/javax/management/query/QueryDottedAttrTest.java new file mode 100644 index 0000000000000000000000000000000000000000..956496db9b62883aa832c935e578a52ba57a1816 --- /dev/null +++ b/test/javax/management/query/QueryDottedAttrTest.java @@ -0,0 +1,192 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test QueryDottedAttrTest + * @bug 6602310 + * @summary Test that Query.attr can understand a.b etc. + * @author Eamonn McManus + */ + +import java.beans.ConstructorProperties; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.Collections; +import java.util.Set; +import javax.management.AttributeNotFoundException; +import javax.management.MBeanException; +import javax.management.MBeanServer; +import javax.management.MBeanServerFactory; +import javax.management.ObjectName; +import javax.management.Query; +import javax.management.QueryExp; +import javax.management.ReflectionException; +import javax.management.StandardMBean; + +public class QueryDottedAttrTest { + public static class Complex { + private final double re, im; + + @ConstructorProperties({"real", "imaginary"}) + public Complex(double re, double im) { + this.re = re; + this.im = im; + } + + public double getRe() { + return re; + } + + public double getIm() { + return im; + } + } + + public static interface Intf { + Complex getComplex(); + int[] getIntArray(); + String[] getStringArray(); + } + + public static class Impl implements Intf { + public Complex getComplex() { + return new Complex(1.0, 1.0); + } + + public int[] getIntArray() { + return new int[] {1, 2, 3}; + } + + public String[] getStringArray() { + return new String[] {"one", "two", "three"}; + } + } + + public static interface TestMBean extends Intf {} + + public static class Test extends Impl implements TestMBean {} + + public static interface TestMXBean extends Intf {} + + public static class TestMX extends Impl implements TestMXBean {} + + public static class AttrWithDot extends StandardMBean { + public AttrWithDot(Object impl, Class intf) { + super(intf.cast(impl), intf, (intf == TestMXBean.class)); + } + + public Object getAttribute(String attribute) + throws AttributeNotFoundException, MBeanException, ReflectionException { + if (attribute.equals("Complex.re")) + return 2.0; + else + return super.getAttribute(attribute); + } + } + + private static final boolean[] booleans = {false, true}; + + private static final QueryExp[] alwaysTrueQueries = { + Query.eq(Query.attr("IntArray.length"), Query.value(3)), + Query.eq(Query.attr("StringArray.length"), Query.value(3)), + Query.eq(Query.attr("Complex.im"), Query.value(1.0)), + }; + + private static final QueryExp[] alwaysFalseQueries = { + Query.eq(Query.attr("IntArray.length"), Query.value("3")), + Query.eq(Query.attr("IntArray.length"), Query.value(2)), + Query.eq(Query.attr("Complex.im"), Query.value(-1.0)), + Query.eq(Query.attr("Complex.xxx"), Query.value(0)), + }; + + private static final QueryExp[] attrWithDotTrueQueries = { + Query.eq(Query.attr("Complex.re"), Query.value(2.0)), + }; + + private static final QueryExp[] attrWithDotFalseQueries = { + Query.eq(Query.attr("Complex.re"), Query.value(1.0)), + }; + + private static String failure; + + public static void main(String[] args) throws Exception { + ObjectName name = new ObjectName("a:b=c"); + for (boolean attrWithDot : booleans) { + for (boolean mx : booleans) { + String what = + (mx ? "MXBean" : "Standard MBean") + + (attrWithDot ? " having attribute with dot in its name" : ""); + System.out.println("Testing " + what); + Class intf = mx ? TestMXBean.class : TestMBean.class; + Object impl = mx ? new TestMX() : new Test(); + if (attrWithDot) + impl = new AttrWithDot(impl, intf); + MBeanServer mbs = MBeanServerFactory.newMBeanServer(); + mbs.registerMBean(impl, name); + boolean ismx = "true".equals( + mbs.getMBeanInfo(name).getDescriptor().getFieldValue("mxbean")); + if (mx != ismx) + fail("MBean should " + (mx ? "" : "not ") + "be MXBean"); + test(mbs, name, alwaysTrueQueries, true); + test(mbs, name, alwaysFalseQueries, false); + test(mbs, name, attrWithDotTrueQueries, attrWithDot); + test(mbs, name, attrWithDotFalseQueries, !attrWithDot); + } + } + if (failure != null) + throw new Exception("TEST FAILED: " + failure); + } + + private static void test( + MBeanServer mbs, ObjectName name, QueryExp[] queries, boolean expect) + throws Exception { + for (QueryExp query : queries) { + // Serialize and deserialize the query to ensure that its + // serialization is correct + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + ObjectOutputStream oout = new ObjectOutputStream(bout); + oout.writeObject(query); + oout.close(); + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream oin = new ObjectInputStream(bin); + query = (QueryExp) oin.readObject(); + Set names = mbs.queryNames(null, query); + if (names.isEmpty()) { + if (expect) + fail("Query is false but should be true: " + query); + } else if (names.equals(Collections.singleton(name))) { + if (!expect) + fail("Query is true but should be false: " + query); + } else { + fail("Query returned unexpected set: " + names); + } + } + } + + private static void fail(String msg) { + failure = msg; + System.out.println("..." + msg); + } +} diff --git a/test/javax/management/query/QueryExpStringTest.java b/test/javax/management/query/QueryExpStringTest.java index 729a8e7ec95d46115f32f365f03e7d77b9d05fa1..be6a515b8fb1b326e3218aaf260dc6a245432049 100644 --- a/test/javax/management/query/QueryExpStringTest.java +++ b/test/javax/management/query/QueryExpStringTest.java @@ -31,6 +31,10 @@ * @run main QueryExpStringTest */ +// This test is mostly obsolete, since we now have Query.fromString. +// The test includes its own parser, from which Query.fromString was derived. +// The parsers are not identical and the one here is no longer maintained. + import java.util.*; import javax.management.*; @@ -39,6 +43,11 @@ public class QueryExpStringTest { private static final ValueExp attr = Query.attr("attr"), qattr = Query.attr("className", "attr"), + aa = Query.attr("A"), + bb = Query.attr("B"), + cc = Query.attr("C"), + dd = Query.attr("D"), + zero = Query.value(0), classattr = Query.classattr(), simpleString = Query.value("simpleString"), complexString = Query.value("a'b\\'\""), @@ -66,10 +75,14 @@ public class QueryExpStringTest { (StringValueExp) simpleString), initialStar = Query.initialSubString((AttributeValueExp) attr, Query.value("*")), + initialPercent = Query.initialSubString((AttributeValueExp) attr, + Query.value("%")), any = Query.anySubString((AttributeValueExp) attr, (StringValueExp) simpleString), anyStar = Query.anySubString((AttributeValueExp) attr, Query.value("*")), + anyPercent = Query.anySubString((AttributeValueExp) attr, + Query.value("%")), ffinal = Query.finalSubString((AttributeValueExp) attr, (StringValueExp) simpleString), finalMagic = Query.finalSubString((AttributeValueExp) attr, @@ -77,16 +90,20 @@ public class QueryExpStringTest { in = Query.in(intValue, new ValueExp[] {intValue, floatValue}), and = Query.and(gt, lt), or = Query.or(gt, lt), - not = Query.not(gt); + not = Query.not(gt), + aPlusB_PlusC = Query.gt(Query.plus(Query.plus(aa, bb), cc), zero), + aPlus_BPlusC = Query.gt(Query.plus(aa, Query.plus(bb, cc)), zero); // Commented-out tests below require change to implementation private static final Object tests[] = { attr, "attr", - qattr, "className.attr", +// qattr, "className.attr", +// Preceding form now appears as className#attr, an incompatible change +// which we don't mind much because nobody uses the two-arg Query.attr. classattr, "Class", simpleString, "'simpleString'", -// complexString, "'a\\'b\\\\\\'\"'", + complexString, "'a''b\\\''\"'", intValue, "12345678", integerValue, "12345678", longValue, "12345678", @@ -104,16 +121,20 @@ public class QueryExpStringTest { eq, "(12345678) = (2.5)", between, "(12345678) between (2.5) and (2.5)", match, "attr like 'simpleString'", -// initial, "attr like 'simpleString*'", -// initialStar, "attr like '\\\\**'", -// any, "attr like '*simpleString*'", -// anyStar, "attr like '*\\\\**'", -// ffinal, "attr like '*simpleString'", -// finalMagic, "attr like '*\\\\?\\\\*\\\\[\\\\\\\\'", + initial, "attr like 'simpleString%'", + initialStar, "attr like '\\*%'", + initialPercent, "attr like '\\%%'", + any, "attr like '%simpleString%'", + anyStar, "attr like '%\\*%'", + anyPercent, "attr like '%\\%%'", + ffinal, "attr like '%simpleString'", + finalMagic, "attr like '%\\?\\*\\[\\\\'", in, "12345678 in (12345678, 2.5)", and, "((12345678) > (2.5)) and ((12345678) < (2.5))", or, "((12345678) > (2.5)) or ((12345678) < (2.5))", not, "not ((12345678) > (2.5))", + aPlusB_PlusC, "(A + B + C) > (0)", +// aPlus_BPlusC, "(A + (B + C)) > (0)", }; public static void main(String[] args) throws Exception { @@ -185,7 +206,9 @@ public class QueryExpStringTest { throw new Exception("Expected types `attr like string': " + exp + " like " + pat); } - return Query.match((AttributeValueExp) exp, (StringValueExp) pat); + StringValueExp spat = (StringValueExp) pat; + spat = Query.value(translateMatch(spat.getValue())); + return Query.match((AttributeValueExp) exp, spat); } if (skip(ss, " in (")) { @@ -203,6 +226,28 @@ public class QueryExpStringTest { throw new Exception("Expected in or like after expression"); } + private static String translateMatch(String s) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < s.length(); i++) { // logic not correct for wide chars + char c = s.charAt(i); + switch (c) { + case '\\': + sb.append(c).append(s.charAt(++i)); break; + case '%': + sb.append('*'); break; + case '_': + sb.append('?'); break; + case '*': + sb.append("\\*"); break; + case '?': + sb.append("\\?"); break; + default: + sb.append(c); break; + } + } + return sb.toString(); + } + private static QueryExp parseQueryAfterParen(String[] ss) throws Exception { /* This is very ugly. We might have "(q1) and (q2)" here, or @@ -229,7 +274,7 @@ public class QueryExpStringTest { ss[0] = start; ValueExp lhs = parseExp(ss); if (!skip(ss, ") ")) - throw new Exception("Expected `) ' after subexpression"); + throw new Exception("Expected `) ' after subexpression: " + ss[0]); String op = scanWord(ss); if (!skip(ss, " (")) throw new Exception("Expected ` (' after `" + op + "'"); @@ -258,15 +303,16 @@ public class QueryExpStringTest { } private static ValueExp parseExp(String[] ss) throws Exception { - final ValueExp prim = parsePrimary(ss); + ValueExp lhs = parsePrimary(ss); + while (true) { /* Look ahead to see if we have an arithmetic operator. */ String back = ss[0]; if (!skip(ss, " ")) - return prim; + return lhs; if (ss[0].equals("") || "+-*/".indexOf(ss[0].charAt(0)) < 0) { ss[0] = back; - return prim; + return lhs; } final String op = scanWord(ss); @@ -276,15 +322,16 @@ public class QueryExpStringTest { throw new Exception("Unknown arithmetic operator: " + op); if (!skip(ss, " ")) throw new Exception("Expected space after arithmetic operator"); - ValueExp rhs = parseExp(ss); + ValueExp rhs = parsePrimary(ss); switch (op.charAt(0)) { - case '+': return Query.plus(prim, rhs); - case '-': return Query.minus(prim, rhs); - case '*': return Query.times(prim, rhs); - case '/': return Query.div(prim, rhs); + case '+': lhs = Query.plus(lhs, rhs); break; + case '-': lhs = Query.minus(lhs, rhs); break; + case '*': lhs = Query.times(lhs, rhs); break; + case '/': lhs = Query.div(lhs, rhs); break; default: throw new Exception("Can't happen: " + op.charAt(0)); } } + } private static ValueExp parsePrimary(String[] ss) throws Exception { String s = ss[0]; @@ -324,14 +371,19 @@ public class QueryExpStringTest { private static String scanWord(String[] ss) throws Exception { String s = ss[0]; int space = s.indexOf(' '); - if (space < 0) { + int rpar = s.indexOf(')'); + if (space < 0 && rpar < 0) { ss[0] = ""; return s; - } else { - String word = s.substring(0, space); - ss[0] = s.substring(space); - return word; } + int stop; + if (space >= 0 && rpar >= 0) // string has both space and ), stop at first + stop = Math.min(space, rpar); + else // string has only one, stop at it + stop = Math.max(space, rpar); + String word = s.substring(0, stop); + ss[0] = s.substring(stop); + return word; } private static boolean matchWord(String[] ss, String word) @@ -381,13 +433,11 @@ public class QueryExpStringTest { for (i = 0; i < len; i++) { char c = s.charAt(i); if (c == '\'') { - ss[0] = s.substring(i + 1); + ++i; + if (i >= len || s.charAt(i) != '\'') { + ss[0] = s.substring(i); return Query.value(buf.toString()); } - if (c == '\\') { - if (++i == len) - throw new Exception("\\ at end of string"); - c = s.charAt(i); } buf.append(c); } diff --git a/test/javax/management/query/QueryParseTest.java b/test/javax/management/query/QueryParseTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a6004b5c150b0967643d596c16244db253a65778 --- /dev/null +++ b/test/javax/management/query/QueryParseTest.java @@ -0,0 +1,778 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test QueryParseTest + * @bug 6602310 6604768 + * @summary Test Query.fromString and Query.toString. + * @author Eamonn McManus + */ + +import java.util.Collections; +import java.util.Set; +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.AttributeNotFoundException; +import javax.management.DynamicMBean; +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanInfo; +import javax.management.MBeanServer; +import javax.management.MBeanServerDelegate; +import javax.management.MBeanServerFactory; +import javax.management.ObjectName; +import javax.management.Query; +import javax.management.QueryExp; + +public class QueryParseTest { + // In this table, each string constant corresponds to a test case. + // The objects following the string up to the next string are MBeans. + // Each MBean must implement ExpectedValue to return true or false + // according as it should return that value for the query parsed + // from the given string. The test will parse the string into a + // a query and verify that the MBeans return the expected value + // for that query. Then it will convert the query back into a string + // and into a second query, and check that the MBeans return the + // expected value for that query too. The reason we need to do all + // this is that the spec talks about "equivalent queries", and gives + // the implementation wide scope to rearrange queries. So we cannot + // just compare string values. + // + // We could also write an implementation-dependent test that knew what + // the strings look like, and that would have to be changed if the + // implementation changed. But the approach here is cleaner. + // + // To simplify the creation of MBeans, most use the expectTrue or + // expectFalse methods. The parameters of these methods end up in + // attributes called "A", "B", "C", etc. + private static final Object[] queryTests = { + // RELATIONS + + "A < B", + expectTrue(1, 2), expectTrue(1.0, 2.0), expectTrue("one", "two"), + expectTrue(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY), + expectFalse(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY), + expectFalse(1, 1), expectFalse(1.0, 1.0), expectFalse("one", "one"), + expectFalse(2, 1), expectFalse(2.0, 1.0), expectFalse("two", "one"), + expectFalse(Double.NaN, Double.NaN), + + "One = two", + expectTrueOneTwo(1, 1), expectTrueOneTwo(1.0, 1.0), + expectFalseOneTwo(1, 2), expectFalseOneTwo(2, 1), + + "A <= B", + expectTrue(1, 1), expectTrue(1, 2), expectTrue("one", "one"), + expectTrue("one", "two"), + expectFalse(2, 1), expectFalse("two", "one"), + expectFalse(Double.NaN, Double.NaN), + + "A >= B", + expectTrue(1, 1), expectTrue(2, 1), expectTrue("two", "one"), + expectFalse(1, 2), expectFalse("one", "two"), + + "A > B", + expectTrue(2, 1), expectTrue("two", "one"), + expectFalse(2, 2), expectFalse(1, 2), expectFalse(1.0, 2.0), + expectFalse("one", "two"), + + "A <> B", + expectTrue(1, 2), expectTrue("foo", "bar"), + expectFalse(1, 1), expectFalse("foo", "foo"), + + "A != B", + expectTrue(1, 2), expectTrue("foo", "bar"), + expectFalse(1, 1), expectFalse("foo", "foo"), + + // PARENTHESES + + "(((A))) = (B)", + expectTrue(1, 1), expectFalse(1, 2), + + "(A = B)", + expectTrue(1, 1), expectFalse(1, 2), + + "(((A = (B))))", + expectTrue(1, 1), expectFalse(1, 2), + + // INTEGER LITERALS + + "A = 1234567890123456789", + expectTrue(1234567890123456789L), expectFalse(123456789L), + + "A = +1234567890123456789", + expectTrue(1234567890123456789L), expectFalse(123456789L), + + "A = -1234567890123456789", + expectTrue(-1234567890123456789L), expectFalse(-123456789L), + + + "A = + 1234567890123456789", + expectTrue(1234567890123456789L), expectFalse(123456789L), + + "A = - 1234567890123456789", + expectTrue(-1234567890123456789L), expectFalse(-123456789L), + + "A = " + Long.MAX_VALUE, + expectTrue(Long.MAX_VALUE), expectFalse(Long.MIN_VALUE), + + "A = " + Long.MIN_VALUE, + expectTrue(Long.MIN_VALUE), expectFalse(Long.MAX_VALUE), + + // DOUBLE LITERALS + + "A = 0.0", + expectTrue(0.0), expectFalse(1.0), + + "A = 0.0e23", + expectTrue(0.0), expectFalse(1.0), + + "A = 1.2e3", + expectTrue(1.2e3), expectFalse(1.2), + + "A = +1.2", + expectTrue(1.2), expectFalse(-1.2), + + "A = 1.2e+3", + expectTrue(1.2e3), expectFalse(1.2), + + "A = 1.2e-3", + expectTrue(1.2e-3), expectFalse(1.2), + + "A = 1.2E3", + expectTrue(1.2e3), expectFalse(1.2), + + "A = -1.2e3", + expectTrue(-1.2e3), expectFalse(1.2), + + "A = " + Double.MAX_VALUE, + expectTrue(Double.MAX_VALUE), expectFalse(Double.MIN_VALUE), + + "A = " + -Double.MAX_VALUE, + expectTrue(-Double.MAX_VALUE), expectFalse(-Double.MIN_VALUE), + + "A = " + Double.MIN_VALUE, + expectTrue(Double.MIN_VALUE), expectFalse(Double.MAX_VALUE), + + "A = " + -Double.MIN_VALUE, + expectTrue(-Double.MIN_VALUE), expectFalse(-Double.MAX_VALUE), + + Query.toString( // A = Infinity -> A = (1.0/0.0) + Query.eq(Query.attr("A"), Query.value(Double.POSITIVE_INFINITY))), + expectTrue(Double.POSITIVE_INFINITY), + expectFalse(0.0), expectFalse(Double.NEGATIVE_INFINITY), + + Query.toString( // A = -Infinity -> A = (-1.0/0.0) + Query.eq(Query.attr("A"), Query.value(Double.NEGATIVE_INFINITY))), + expectTrue(Double.NEGATIVE_INFINITY), + expectFalse(0.0), expectFalse(Double.POSITIVE_INFINITY), + + Query.toString( // A < NaN -> A < (0.0/0.0) + Query.lt(Query.attr("A"), Query.value(Double.NaN))), + expectFalse(0.0), expectFalse(Double.NEGATIVE_INFINITY), + expectFalse(Double.POSITIVE_INFINITY), expectFalse(Double.NaN), + + Query.toString( // A >= NaN -> A < (0.0/0.0) + Query.geq(Query.attr("A"), Query.value(Double.NaN))), + expectFalse(0.0), expectFalse(Double.NEGATIVE_INFINITY), + expectFalse(Double.POSITIVE_INFINITY), expectFalse(Double.NaN), + + // STRING LITERALS + + "A = 'blim'", + expectTrue("blim"), expectFalse("blam"), + + "A = 'can''t'", + expectTrue("can't"), expectFalse("cant"), expectFalse("can''t"), + + "A = '''blim'''", + expectTrue("'blim'"), expectFalse("'blam'"), + + "A = ''", + expectTrue(""), expectFalse((Object) null), + + // BOOLEAN LITERALS + + "A = true", + expectTrue(true), expectFalse(false), expectFalse((Object) null), + + "A = TRUE", + expectTrue(true), expectFalse(false), + + "A = TrUe", + expectTrue(true), expectFalse(false), + + "A = false", + expectTrue(false), expectFalse(true), + + "A = fAlSe", + expectTrue(false), expectFalse(true), + + "A = \"true\"", // An attribute called "true" + expectFalse(true), expectFalse(false), expectFalse("\"true\""), + newTester(new String[] {"A", "true"}, new Object[] {2.2, 2.2}, true), + newTester(new String[] {"A", "true"}, new Object[] {2.2, 2.3}, false), + + "A = \"False\"", + expectFalse(true), expectFalse(false), expectFalse("\"False\""), + newTester(new String[] {"A", "False"}, new Object[] {2.2, 2.2}, true), + newTester(new String[] {"A", "False"}, new Object[] {2.2, 2.3}, false), + + // ARITHMETIC + + "A + B = 10", + expectTrue(4, 6), expectFalse(3, 8), + + "A + B = 'blim'", + expectTrue("bl", "im"), expectFalse("bl", "am"), + + "A - B = 10", + expectTrue(16, 6), expectFalse(16, 3), + + "A * B = 10", + expectTrue(2, 5), expectFalse(3, 3), + + "A / B = 10", + expectTrue(70, 7), expectTrue(70.0, 7), expectFalse(70.01, 7), + + "A + B + C = 10", + expectTrue(2, 3, 5), expectFalse(2, 4, 8), + + "A+B+C=10", + expectTrue(2, 3, 5), expectFalse(2, 4, 8), + + "A + B + C + D = 10", + expectTrue(1, 2, 3, 4), expectFalse(2, 3, 4, 5), + + "A + (B + C) = 10", + expectTrue(2, 3, 5), expectFalse(2, 4, 8), + + // It is not correct to rearrange A + (B + C) as A + B + C + // (which means (A + B) + C), because of overflow. + // In particular Query.toString must not do this. + "A + (B + C) = " + Double.MAX_VALUE, // ensure no false associativity + expectTrue(Double.MAX_VALUE, Double.MAX_VALUE, -Double.MAX_VALUE), + expectFalse(-Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE), + + "A * (B * C) < " + Double.MAX_VALUE, // same test for multiplication + expectTrue(Double.MAX_VALUE, Double.MAX_VALUE, Double.MIN_VALUE), + expectFalse(Double.MIN_VALUE, Double.MAX_VALUE, Double.MAX_VALUE), + + "A * B + C = 10", + expectTrue(3, 3, 1), expectTrue(2, 4, 2), expectFalse(1, 2, 3), + + "A*B+C=10", + expectTrue(3, 3, 1), expectTrue(2, 4, 2), expectFalse(1, 2, 3), + + "(A * B) + C = 10", + expectTrue(3, 3, 1), expectTrue(2, 4, 2), expectFalse(1, 2, 3), + + "A + B * C = 10", + expectTrue(1, 3, 3), expectTrue(2, 2, 4), expectFalse(1, 2, 3), + + "A - B * C = 10", + expectTrue(16, 2, 3), expectFalse(15, 2, 2), + + "A + B / C = 10", + expectTrue(5, 15, 3), expectFalse(5, 16, 4), + + "A - B / C = 10", + expectTrue(16, 12, 2), expectFalse(15, 10, 3), + + "A * (B + C) = 10", + expectTrue(2, 2, 3), expectFalse(1, 2, 3), + + "A / (B + C) = 10", + expectTrue(70, 4, 3), expectFalse(70, 3, 5), + + "A * (B - C) = 10", + expectTrue(2, 8, 3), expectFalse(2, 3, 8), + + "A / (B - C) = 10", + expectTrue(70, 11, 4), expectFalse(70, 4, 11), + + "A / B / C = 10", + expectTrue(140, 2, 7), expectFalse(100, 5, 5), + + "A / (B / C) = 10", + expectTrue(70, 14, 2), expectFalse(70, 10, 7), + + // LOGIC + + "A = B or C = D", + expectTrue(1, 1, 2, 3), expectTrue(1, 2, 3, 3), expectTrue(1, 1, 2, 2), + expectFalse(1, 2, 3, 4), expectFalse("!", "!!", "?", "??"), + + "A = B and C = D", + expectTrue(1, 1, 2, 2), + expectFalse(1, 1, 2, 3), expectFalse(1, 2, 3, 3), + + "A = 1 and B = 2 and C = 3", + expectTrue(1, 2, 3), expectFalse(1, 2, 4), + + "A = 1 or B = 2 or C = 3", + expectTrue(1, 2, 3), expectTrue(1, 0, 0), expectTrue(0, 0, 3), + expectFalse(2, 3, 4), + + // grouped as (a and b) or (c and d) + "A = 1 AND B = 2 OR C = 3 AND D = 4", + expectTrue(1, 2, 3, 4), expectTrue(1, 2, 1, 2), expectTrue(3, 4, 3, 4), + expectFalse(3, 4, 1, 2), expectFalse(1, 1, 1, 1), + + "(A = 1 AND B = 2) OR (C = 3 AND D = 4)", + expectTrue(1, 2, 3, 4), expectTrue(1, 2, 1, 2), expectTrue(3, 4, 3, 4), + expectFalse(3, 4, 1, 2), expectFalse(1, 1, 1, 1), + + "(A = 1 or B = 2) AND (C = 3 or C = 4)", + expectTrue(1, 1, 3, 3), expectTrue(2, 2, 4, 4), expectTrue(1, 2, 3, 4), + expectFalse(1, 2, 1, 2), expectFalse(3, 4, 3, 4), + + // LIKE + + "A like 'b%m'", + expectTrue("blim"), expectTrue("bm"), + expectFalse(""), expectFalse("blimmo"), expectFalse("mmm"), + + "A not like 'b%m'", + expectFalse("blim"), expectFalse("bm"), + expectTrue(""), expectTrue("blimmo"), expectTrue("mmm"), + + "A like 'b_m'", + expectTrue("bim"), expectFalse("blim"), + + "A like '%can''t%'", + expectTrue("can't"), + expectTrue("I'm sorry Dave, I'm afraid I can't do that"), + expectFalse("cant"), expectFalse("can''t"), + + "A like '\\%%\\%'", + expectTrue("%blim%"), expectTrue("%%"), + expectFalse("blim"), expectFalse("%asdf"), expectFalse("asdf%"), + + "A LIKE '*%?_'", + expectTrue("*blim?!"), expectTrue("*?_"), + expectFalse("blim"), expectFalse("blim?"), + expectFalse("?*"), expectFalse("??"), expectFalse(""), expectFalse("?"), + + Query.toString( + Query.initialSubString(Query.attr("A"), Query.value("*?%_"))), + expectTrue("*?%_tiddly"), expectTrue("*?%_"), + expectFalse("?%_tiddly"), expectFalse("*!%_"), expectFalse("*??_"), + expectFalse("*?%!"), expectFalse("*?%!tiddly"), + + Query.toString( + Query.finalSubString(Query.attr("A"), Query.value("*?%_"))), + expectTrue("tiddly*?%_"), expectTrue("*?%_"), + expectFalse("tiddly?%_"), expectFalse("*!%_"), expectFalse("*??_"), + expectFalse("*?%!"), expectFalse("tiddly*?%!"), + + // BETWEEN + + "A between B and C", + expectTrue(1, 1, 2), expectTrue(2, 1, 2), expectTrue(2, 1, 3), + expectFalse(3, 1, 2), expectFalse(0, 1, 2), expectFalse(2, 3, 1), + expectTrue(1.0, 0.0, 2.0), expectFalse(2.0, 0.0, 1.0), + expectTrue(0.0, 0.0, 0.0), expectTrue(1.0, 0.0, 1.0), + expectTrue(1.0, 0.0, Double.POSITIVE_INFINITY), + expectFalse(1.0, Double.NEGATIVE_INFINITY, 0.0), + expectFalse(false, false, true), expectFalse(true, false, true), + expectTrue("jim", "fred", "sheila"), expectFalse("fred", "jim", "sheila"), + + "A between B and C and 1+2=3", + expectTrue(2, 1, 3), expectFalse(2, 3, 1), + + "A not between B and C", + expectTrue(1, 2, 3), expectFalse(2, 1, 3), + + // IN + + "A in (1, 2, 3)", + expectTrue(1), expectTrue(2), expectTrue(3), + expectFalse(0), expectFalse(4), + + "A in (1)", + expectTrue(1), expectFalse(0), + + "A in (1.2, 3.4)", + expectTrue(1.2), expectTrue(3.4), expectFalse(0.0), + + "A in ('foo', 'bar')", + expectTrue("foo"), expectTrue("bar"), expectFalse("baz"), + + "A in ('foo', 'bar') and 'bl'+'im'='blim'", + expectTrue("foo"), expectTrue("bar"), expectFalse("baz"), + + "A in (B, C, D)", // requires fix for CR 6604768 + expectTrue(1, 1, 2, 3), expectFalse(1, 2, 3, 4), + + "A not in (B, C, D)", + expectTrue(1, 2, 3, 4), expectFalse(1, 1, 2, 3), + + // QUOTING + + "\"LIKE\" = 1 and \"NOT\" = 2 and \"INSTANCEOF\" = 3 and " + + "\"TRUE\" = 4 and \"FALSE\" = 5", + newTester( + new String[] {"LIKE", "NOT", "INSTANCEOF", "TRUE", "FALSE"}, + new Object[] {1, 2, 3, 4, 5}, + true), + newTester( + new String[] {"LIKE", "NOT", "INSTANCEOF", "TRUE", "FALSE"}, + new Object[] {5, 4, 3, 2, 1}, + false), + + "\"\"\"woo\"\"\" = 5", + newTester(new String[] {"\"woo\""}, new Object[] {5}, true), + newTester(new String[] {"\"woo\""}, new Object[] {4}, false), + expectFalse(), + + // INSTANCEOF + + "instanceof '" + Tester.class.getName() + "'", + expectTrue(), + + "instanceof '" + String.class.getName() + "'", + expectFalse(), + + // LIKE OBJECTNAME + + // The test MBean is registered as a:b=c + "like 'a:b=c'", expectTrue(), + "like 'a:*'", expectTrue(), + "like '*:b=c'", expectTrue(), + "like 'a:b=*'", expectTrue(), + "like 'a:b=?'", expectTrue(), + "like 'd:b=c'", expectFalse(), + "like 'a:b=??*'", expectFalse(), + "like 'a:b=\"can''t\"'", expectFalse(), + + // QUALIFIED ATTRIBUTE + + Tester.class.getName() + "#A = 5", + expectTrue(5), expectFalse(4), + + Tester.class.getName() + " # A = 5", + expectTrue(5), expectFalse(4), + + Tester.class.getSuperclass().getName() + "#A = 5", + expectFalse(5), + + DynamicMBean.class.getName() + "#A = 5", + expectFalse(5), + + Tester.class.getName() + "#A = 5", + new Tester(new String[] {"A"}, new Object[] {5}, false) {}, + // note the little {} at the end which means this is a subclass + // and therefore QualifiedAttributeValue should return false. + + MBeanServerDelegate.class.getName() + "#SpecificationName LIKE '%'", + new Wrapped(new MBeanServerDelegate(), true), + new Tester(new String[] {"SpecificationName"}, new Object[] {"JMX"}, false), + + // DOTTED ATTRIBUTE + + "A.canonicalName = '" + + MBeanServerDelegate.DELEGATE_NAME.getCanonicalName() + "'", + expectTrue(MBeanServerDelegate.DELEGATE_NAME), + expectFalse(ObjectName.WILDCARD), + + "A.class.name = 'java.lang.String'", + expectTrue("blim"), expectFalse(95), expectFalse((Object) null), + + "A.canonicalName like 'JMImpl%:%'", + expectTrue(MBeanServerDelegate.DELEGATE_NAME), + expectFalse(ObjectName.WILDCARD), + + "A.true = 'blim'", + new Tester(new String[] {"A.true"}, new Object[] {"blim"}, true), + new Tester(new String[] {"A.true"}, new Object[] {"blam"}, false), + + "\"A.true\" = 'blim'", + new Tester(new String[] {"A.true"}, new Object[] {"blim"}, true), + new Tester(new String[] {"A.true"}, new Object[] {"blam"}, false), + + MBeanServerDelegate.class.getName() + + "#SpecificationName.class.name = 'java.lang.String'", + new Wrapped(new MBeanServerDelegate(), true), + new Tester(new String[] {"SpecificationName"}, new Object[] {"JMX"}, false), + + MBeanServerDelegate.class.getName() + + " # SpecificationName.class.name = 'java.lang.String'", + new Wrapped(new MBeanServerDelegate(), true), + new Tester(new String[] {"SpecificationName"}, new Object[] {"JMX"}, false), + + // CLASS + + "class = '" + Tester.class.getName() + "'", + expectTrue(), + new Wrapped(new MBeanServerDelegate(), false), + + "Class = '" + Tester.class.getName() + "'", + expectTrue(), + new Wrapped(new MBeanServerDelegate(), false), + }; + + private static final String[] incorrectQueries = { + "", " ", "25", "()", "(a = b", "a = b)", "a.3 = 5", + "a = " + Long.MAX_VALUE + "0", + "a = " + Double.MAX_VALUE + "0", + "a = " + Double.MIN_VALUE + "0", + "a = 12a5", "a = 12e5e5", "a = 12.23.34", + "a = 'can't'", "a = 'unterminated", "a = 'asdf''", + "a = \"oops", "a = \"oops\"\"", + "a like 5", "true or false", + "a ! b", "? = 3", "a = @", "a##b", + "a between b , c", "a between and c", + "a in b, c", "a in 23", "a in (2, 3", "a in (2, 3x)", + "a like \"foo\"", "a like b", "a like 23", + "like \"foo\"", "like b", "like 23", "like 'a:b'", + "5 like 'a'", "'a' like '%'", + "a not= b", "a not = b", "a not b", "a not b c", + "a = +b", "a = +'b'", "a = +true", "a = -b", "a = -'b'", + "a#5 = b", "a#'b' = c", + "a instanceof b", "a instanceof 17", "a instanceof", + "a like 'oops\\'", "a like '[oops'", + + // Check that -Long.MIN_VALUE is an illegal constant. This is one more + // than Long.MAX_VALUE and, like the Java language, we only allow it + // if it is the operand of unary minus. + "a = " + Long.toString(Long.MIN_VALUE).substring(1), + }; + + public static void main(String[] args) throws Exception { + int nexti; + String failed = null; + + System.out.println("TESTING CORRECT QUERY STRINGS"); + for (int i = 0; i < queryTests.length; i = nexti) { + for (nexti = i + 1; nexti < queryTests.length; nexti++) { + if (queryTests[nexti] instanceof String) + break; + } + if (!(queryTests[i] instanceof String)) + throw new Exception("Test bug: should be string: " + queryTests[i]); + + String qs = (String) queryTests[i]; + System.out.println("Test: " + qs); + + QueryExp qe = Query.fromString(qs); + String qes = Query.toString(qe); + System.out.println("...parses to: " + qes); + final QueryExp[] queries; + if (qes.equals(qs)) + queries = new QueryExp[] {qe}; + else { + QueryExp qe2 = Query.fromString(qes); + String qes2 = Query.toString(qe2); + System.out.println("...which parses to: " + qes2); + if (qes.equals(qes2)) + queries = new QueryExp[] {qe}; + else + queries = new QueryExp[] {qe, qe2}; + } + + for (int j = i + 1; j < nexti; j++) { + Object mbean; + if (queryTests[j] instanceof Wrapped) + mbean = ((Wrapped) queryTests[j]).mbean(); + else + mbean = queryTests[j]; + boolean expect = ((ExpectedValue) queryTests[j]).expectedValue(); + for (QueryExp qet : queries) { + boolean actual = runQuery(qet, mbean); + boolean ok = (expect == actual); + System.out.println( + "..." + mbean + " -> " + actual + + (ok ? " (OK)" : " ####INCORRECT####")); + if (!ok) + failed = qs; + } + } + } + + System.out.println(); + System.out.println("TESTING INCORRECT QUERY STRINGS"); + for (String s : incorrectQueries) { + try { + QueryExp qe = Query.fromString(s); + System.out.println("###DID NOT GET ERROR:### \"" + s + "\""); + failed = s; + } catch (IllegalArgumentException e) { + String es = (e.getClass() == IllegalArgumentException.class) ? + e.getMessage() : e.toString(); + System.out.println("OK: exception for \"" + s + "\": " + es); + } + } + + if (failed == null) + System.out.println("TEST PASSED"); + else + throw new Exception("TEST FAILED: Last failure: " + failed); + } + + private static boolean runQuery(QueryExp qe, Object mbean) + throws Exception { + MBeanServer mbs = MBeanServerFactory.newMBeanServer(); + ObjectName name = new ObjectName("a:b=c"); + mbs.registerMBean(mbean, name); + Set names = mbs.queryNames(new ObjectName("a:*"), qe); + if (names.isEmpty()) + return false; + if (names.equals(Collections.singleton(name))) + return true; + throw new Exception("Unexpected query result set: " + names); + } + + private static interface ExpectedValue { + public boolean expectedValue(); + } + + private static class Wrapped implements ExpectedValue { + private final Object mbean; + private final boolean expect; + + Wrapped(Object mbean, boolean expect) { + this.mbean = mbean; + this.expect = expect; + } + + Object mbean() { + return mbean; + } + + public boolean expectedValue() { + return expect; + } + } + + private static class Tester implements DynamicMBean, ExpectedValue { + private final AttributeList attributes; + private final boolean expectedValue; + + Tester(AttributeList attributes, boolean expectedValue) { + this.attributes = attributes; + this.expectedValue = expectedValue; + } + + Tester(String[] names, Object[] values, boolean expectedValue) { + this(makeAttributeList(names, values), expectedValue); + } + + private static AttributeList makeAttributeList( + String[] names, Object[] values) { + if (names.length != values.length) + throw new Error("Test bug: names and values different length"); + AttributeList list = new AttributeList(); + for (int i = 0; i < names.length; i++) + list.add(new Attribute(names[i], values[i])); + return list; + } + + public Object getAttribute(String attribute) + throws AttributeNotFoundException { + for (Attribute a : attributes.asList()) { + if (a.getName().equals(attribute)) + return a.getValue(); + } + throw new AttributeNotFoundException(attribute); + } + + public void setAttribute(Attribute attribute) { + throw new UnsupportedOperationException(); + } + + public AttributeList getAttributes(String[] attributes) { + AttributeList list = new AttributeList(); + for (String attribute : attributes) { + try { + list.add(new Attribute(attribute, getAttribute(attribute))); + } catch (AttributeNotFoundException e) { + // OK: ignore, per semantics of getAttributes + } + } + return list; + } + + public AttributeList setAttributes(AttributeList attributes) { + throw new UnsupportedOperationException(); + } + + public Object invoke(String actionName, Object[] params, String[] signature) { + throw new UnsupportedOperationException(); + } + + public MBeanInfo getMBeanInfo() { + MBeanAttributeInfo mbais[] = new MBeanAttributeInfo[attributes.size()]; + for (int i = 0; i < mbais.length; i++) { + Attribute attr = attributes.asList().get(i); + String name = attr.getName(); + Object value = attr.getValue(); + String type = + ((value == null) ? new Object() : value).getClass().getName(); + mbais[i] = new MBeanAttributeInfo( + name, type, name, true, false, false); + } + return new MBeanInfo( + getClass().getName(), "descr", mbais, null, null, null); + } + + public boolean expectedValue() { + return expectedValue; + } + + @Override + public String toString() { + return attributes.toString(); + } + } + + // Method rather than field, to avoid circular init dependencies + private static String[] abcd() { + return new String[] {"A", "B", "C", "D"}; + } + + private static String[] onetwo() { + return new String[] {"One", "two"}; + } + + private static Object expectTrue(Object... attrs) { + return newTester(abcd(), attrs, true); + } + + private static Object expectFalse(Object... attrs) { + return newTester(abcd(), attrs, false); + } + + private static Object expectTrueOneTwo(Object... attrs) { + return newTester(onetwo(), attrs, true); + } + + private static Object expectFalseOneTwo(Object... attrs) { + return newTester(onetwo(), attrs, false); + } + + private static Object newTester(String[] names, Object[] attrs, boolean expect) { + AttributeList list = new AttributeList(); + for (int i = 0; i < attrs.length; i++) + list.add(new Attribute(names[i], attrs[i])); + return new Tester(list, expect); + } +} diff --git a/test/javax/security/auth/x500/X500Principal/RFC4514.java b/test/javax/security/auth/x500/X500Principal/RFC4514.java new file mode 100644 index 0000000000000000000000000000000000000000..6169314abf047d14fa24dcc709ed1359b15a6e4a --- /dev/null +++ b/test/javax/security/auth/x500/X500Principal/RFC4514.java @@ -0,0 +1,92 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import javax.security.auth.x500.X500Principal; + +/** + * @test + * @bug 6611991 + * @summary Add support for parsing RFC 4514 DNs to X500Principal + * + * Ensure RFC 4514 Distinguished Name Strings can be parsed by X500Principal. + * RFC 4514 obsoleted RFC 2253 so we should make sure we can parse DNs of + * that form that contain subtle differences or clarifications in the grammar. + */ +public class RFC4514 { + + private int failed = 0; + + public static void main(String[] args) throws Exception { + new RFC4514().test(); + } + + private void test() throws Exception { + + /** + * RFC 4514 allows space to be escaped as '\ '. + */ + parse("CN=\\ Space\\ ,C=US"); + parse("CN=Sp\\ ace,C=US"); + /** + * RFC 4514 does not require escaping of '=' characters. + */ + parse("CN=Eq=uals,C=US"); + /** + * RFC 4514 requires the null character to be escaped. + */ + parse("CN=\\00,C=US"); + /** + * RFC 4514 does not require escaping of non-leading '#' characters. + */ + parse("CN=Num#ber,C=US"); + /** + * XMLDSig (http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/) + * allows implementations to escape trailing whitespace as '\20'. + */ + parse("CN=Trailing \\20,C=US"); + /** + * XMLDSig allows implementations to escape ASCII control characters + * (Unicode range \x00 - \x1f) by replacing them with "\" followed by + * a two digit hex number showing its Unicode number. + */ + parse("CN=Con\\09trol,C=US"); + + if (failed != 0) { + throw new Exception("Some RFC4514 tests FAILED"); + } + } + + public void parse(String dnString) throws Exception { + + System.out.println("Parsing " + dnString); + X500Principal dn = new X500Principal(dnString); + String dnString2 = dn.getName(); + X500Principal dn2 = new X500Principal(dnString2); + if (dn.equals(dn2)) { + System.out.println("PASSED"); + } else { + System.out.println("FAILED"); + failed++; + } + } +} diff --git a/test/sun/management/jmxremote/bootstrap/JvmstatCountersTest.java b/test/sun/management/jmxremote/bootstrap/JvmstatCountersTest.java new file mode 100644 index 0000000000000000000000000000000000000000..3f23b0bf7bf5339148a0ff4515beb9ecca8f97db --- /dev/null +++ b/test/sun/management/jmxremote/bootstrap/JvmstatCountersTest.java @@ -0,0 +1,183 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 4981215 + * @summary Tests that the jvmstat counters published by the out-of-the-box + * management agent for the JMX connection details are correct. + * @author Luis-Miguel Alventosa + * @run clean JvmstatCountersTest + * @run build JvmstatCountersTest + * @run main/othervm JvmstatCountersTest 1 + * @run main/othervm -Dcom.sun.management.jmxremote JvmstatCountersTest 2 + * @run main/othervm -Dcom.sun.management.jmxremote.port=0 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false JvmstatCountersTest 3 + * @run main/othervm JvmstatCountersTest 4 + */ + +import java.io.*; +import java.lang.management.*; +import java.util.*; +import javax.management.*; +import javax.management.remote.*; +import com.sun.tools.attach.*; +import sun.management.ConnectorAddressLink; + +public class JvmstatCountersTest { + + public static void checkAddress(String address) throws IOException { + System.out.println("Address = " + address); + JMXServiceURL url = new JMXServiceURL(address); + JMXConnector jmxc = JMXConnectorFactory.connect(url); + MBeanServerConnection mbsc = jmxc.getMBeanServerConnection(); + System.out.println("MBean Count = " + mbsc.getMBeanCount()); + } + + public static void checkKey(Map data, int index, + String key, String expectedValue) throws Exception { + String counter = "sun.management.JMXConnectorServer." + index + "." + key; + if (!data.containsKey(counter)) { + System.out.println("Test FAILED! Missing counter " + counter); + throw new IllegalArgumentException("Test case failed"); + } + String value = data.get(counter); + if (key.equals("remoteAddress")) { + checkAddress(value); + } else if (!expectedValue.equals(value)) { + System.out.println("Test FAILED! Invalid counter " + + counter + "=" + value); + throw new IllegalArgumentException("Test case failed"); + } + System.out.println("OK: " + counter + "=" + value); + } + + public static void main(String args[]) throws Exception { + String localAddress = ConnectorAddressLink.importFrom(0); + Map remoteData = ConnectorAddressLink.importRemoteFrom(0); + final int testCase = Integer.parseInt(args[0]); + switch (testCase) { + case 1: + if (localAddress == null && remoteData.isEmpty()) { + System.out.println("Test PASSED! The OOTB management " + + "agent didn't publish any jvmstat counter."); + } else { + System.out.println("Test FAILED! The OOTB management " + + "agent unexpectedly published jvmstat counters."); + throw new IllegalArgumentException("Test case 1 failed"); + } + break; + case 2: + if (localAddress == null) { + System.out.println("Test FAILED! The OOTB management " + + "agent didn't publish the local connector."); + throw new IllegalArgumentException("Test case 2 failed"); + } + checkAddress(localAddress); + if (!remoteData.isEmpty()) { + System.out.println("Test FAILED! The OOTB management " + + "agent shouldn't publish the remote connector."); + throw new IllegalArgumentException("Test case 2 failed"); + } + System.out.println("Test PASSED! The OOTB management " + + "agent only publishes the local connector through " + + "a jvmstat counter."); + break; + case 3: + if (localAddress == null) { + System.out.println("Test FAILED! The OOTB management " + + "agent didn't publish the local connector."); + throw new IllegalArgumentException("Test case 3 failed"); + } + checkAddress(localAddress); + if (remoteData.isEmpty()) { + System.out.println("Test FAILED! The OOTB management " + + "agent didnn't publish the remote connector."); + throw new IllegalArgumentException("Test case 3 failed"); + } + for (String key : remoteData.keySet()) { + if (!key.startsWith("sun.management.JMXConnectorServer.0.")) { + System.out.println("Test FAILED! The OOTB management " + + "agent shouldn't publish anything which isn't " + + "related to the remote connector."); + throw new IllegalArgumentException("Test case 3 failed"); + } + } + checkKey(remoteData, 0, "remoteAddress", null); + checkKey(remoteData, 0, "authenticate", "false"); + checkKey(remoteData, 0, "ssl", "false"); + checkKey(remoteData, 0, "sslRegistry", "false"); + checkKey(remoteData, 0, "sslNeedClientAuth", "false"); + System.out.println("Test PASSED! The OOTB management " + + "agent publishes both the local and remote " + + "connector info through jvmstat counters."); + break; + case 4: + if (localAddress != null || !remoteData.isEmpty()) { + System.out.println("Test FAILED! The OOTB management " + + "agent unexpectedly published jvmstat counters."); + throw new IllegalArgumentException("Test case 4 failed"); + } + RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean(); + String name = rt.getName(); + System.out.println("name = " + name); + String vmid = name.substring(0, name.indexOf("@")); + System.out.println("vmid = " + vmid); + VirtualMachine vm = VirtualMachine.attach(vmid); + String agent = vm.getSystemProperties().getProperty("java.home") + + File.separator + "lib" + File.separator + "management-agent.jar"; + vm.loadAgent(agent, "com.sun.management.jmxremote.port=0,com.sun.management.jmxremote.authenticate=false,com.sun.management.jmxremote.ssl=false"); + vm.detach(); + String localAddress2 = ConnectorAddressLink.importFrom(0); + if (localAddress2 == null) { + System.out.println("Test FAILED! The OOTB management " + + "agent didn't publish the local connector."); + throw new IllegalArgumentException("Test case 4 failed"); + } + checkAddress(localAddress2); + Map remoteData2 = ConnectorAddressLink.importRemoteFrom(0); + if (remoteData2.isEmpty()) { + System.out.println("Test FAILED! The OOTB management " + + "agent didnn't publish the remote connector."); + throw new IllegalArgumentException("Test case 4 failed"); + } + for (String key : remoteData2.keySet()) { + if (!key.startsWith("sun.management.JMXConnectorServer.0.")) { + System.out.println("Test FAILED! The OOTB management " + + "agent shouldn't publish anything which isn't " + + "related to the remote connector."); + throw new IllegalArgumentException("Test case 4 failed"); + } + } + checkKey(remoteData2, 0, "remoteAddress", null); + checkKey(remoteData2, 0, "authenticate", "false"); + checkKey(remoteData2, 0, "ssl", "false"); + checkKey(remoteData2, 0, "sslRegistry", "false"); + checkKey(remoteData2, 0, "sslNeedClientAuth", "false"); + System.out.println("Test PASSED! The OOTB management agent " + + "publishes both the local and remote connector " + + "info through jvmstat counters when the agent is " + + "loaded through the Attach API."); + } + System.out.println("Bye! Bye!"); + } +} diff --git a/test/sun/net/www/http/ChunkedOutputStream/Test.java b/test/sun/net/www/http/ChunkedOutputStream/Test.java index 89bc8b3bf854f7987da6517c2b6512c5567dccfc..3866761ade6e7203efc6283dfd2d44b4d4db4a13 100644 --- a/test/sun/net/www/http/ChunkedOutputStream/Test.java +++ b/test/sun/net/www/http/ChunkedOutputStream/Test.java @@ -23,7 +23,7 @@ /** * @test - * @bug 5026745 + * @bug 5026745 6631048 * @run main/othervm/timeout=500 Test * @summary Cannot flush output stream when writing to an HttpUrlConnection */ @@ -158,6 +158,50 @@ public class Test implements HttpHandler { exchange.sendResponseHeaders(200, 0); } break; + case 10: /* test11 */ + printRequestURI(exchange); + is = exchange.getRequestBody(); + s = read (is, str1.length()); + + error = false; + for (int i=10; i< 30 * 1024; i++) { + byte c = (byte)is.read(); + + if (c != (byte)i) { + error = true; + System.out.println ("error at position " + i); + } + } + if (!s.equals(str1) ) { + System.out.println ("received string : " + s); + exchange.sendResponseHeaders(500, 0); + } else if (error) { + System.out.println ("error"); + exchange.sendResponseHeaders(500, 0); + } else { + exchange.sendResponseHeaders(200, 0); + } + break; + case 11: /* test12 */ + printRequestURI(exchange); + is = exchange.getRequestBody(); + + error = false; + for (int i=10; i< 30 * 1024; i++) { + byte c = (byte)is.read(); + + if (c != (byte)i) { + error = true; + System.out.println ("error at position " + i); + } + } + if (error) { + System.out.println ("error"); + exchange.sendResponseHeaders(500, 0); + } else { + exchange.sendResponseHeaders(200, 0); + } + break; } exchange.close(); count ++; @@ -390,6 +434,56 @@ public class Test implements HttpHandler { } } + static void test11 (String u) throws Exception { + URL url = new URL (u); + System.out.println ("client opening connection to: " + u); + HttpURLConnection urlc = (HttpURLConnection)url.openConnection (); + urlc.setChunkedStreamingMode (36 * 1024); + urlc.setDoOutput(true); + urlc.setRequestMethod ("POST"); + OutputStream os = urlc.getOutputStream (); + byte[] buf = new byte [30 * 1024]; + for (int i=0; i< 30 * 1024; i++) { + buf[i] = (byte) i; + } + /* write a small bit first, and then the large buffer */ + os.write (str1.getBytes()); + //os.write (buf, 10, buf.length - 10); /* skip 10 bytes to test offset */ + os.write (buf, 10, (10 * 1024) - 10); + os.write (buf, (10 * 1024), (10 * 1024)); + os.write (buf, (20 * 1024), (10 * 1024)); + os.close(); + InputStream is = urlc.getInputStream(); + is.close(); + int ret = urlc.getResponseCode(); + if (ret != 200) { + throw new Exception ("Expected 200: got " + ret); + } + } + + static void test12 (String u) throws Exception { + URL url = new URL (u); + System.out.println ("client opening connection to: " + u); + HttpURLConnection urlc = (HttpURLConnection)url.openConnection (); + urlc.setChunkedStreamingMode (36 * 1024); + urlc.setDoOutput(true); + urlc.setRequestMethod ("POST"); + OutputStream os = urlc.getOutputStream (); + byte[] buf = new byte [30 * 1024]; + for (int i=0; i< 30 * 1024; i++) { + buf[i] = (byte) i; + } + os.write (buf, 10, buf.length - 10); /* skip 10 bytes to test offset */ + os.close(); + InputStream is = urlc.getInputStream(); + is.close(); + int ret = urlc.getResponseCode(); + if (ret != 200) { + throw new Exception ("Expected 200: got " + ret); + } + } + + static com.sun.net.httpserver.HttpServer httpserver; public static void main (String[] args) throws Exception { @@ -411,6 +505,8 @@ public class Test implements HttpHandler { test8("http://localhost:"+ port + "/test/test8"); test9("http://localhost:"+ port + "/test/test9"); test10("http://localhost:"+ port + "/test/test10"); + test11("http://localhost:"+ port + "/test/test11"); + test12("http://localhost:"+ port + "/test/test12"); } finally { if (httpserver != null) httpserver.stop(0); diff --git a/test/sun/net/www/protocol/http/B6641309.java b/test/sun/net/www/protocol/http/B6641309.java new file mode 100644 index 0000000000000000000000000000000000000000..15e8fdc31bc602e349ae6f2f337bf61c4dbbd011 --- /dev/null +++ b/test/sun/net/www/protocol/http/B6641309.java @@ -0,0 +1,129 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6641309 + * @summary Wrong Cookie separator used in HttpURLConnection + */ + +import java.net.*; +import java.util.*; +import java.io.*; +import com.sun.net.httpserver.*; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; + +public class B6641309 +{ + com.sun.net.httpserver.HttpServer httpServer; + ExecutorService executorService; + + public static void main(String[] args) + { + new B6641309(); + } + + public B6641309() + { + try { + startHttpServer(); + doClient(); + } catch (IOException ioe) { + System.err.println(ioe); + } + } + + void doClient() { + CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL)); + try { + InetSocketAddress address = httpServer.getAddress(); + + // GET Request + URL url = new URL("http://localhost:" + address.getPort() + "/test/"); + CookieHandler ch = CookieHandler.getDefault(); + Map> header = new HashMap>(); + List values = new LinkedList(); + values.add("Test1Cookie=TEST1; path=/test/"); + values.add("Test2Cookie=TEST2; path=/test/"); + header.put("Set-Cookie", values); + + // preload the CookieHandler with a cookie for our URL + // so that it will be sent during the first request + ch.put(url.toURI(), header); + HttpURLConnection uc = (HttpURLConnection)url.openConnection(); + int resp = uc.getResponseCode(); + if (resp != 200) + throw new RuntimeException("Failed: Response code from GET is not 200"); + + System.out.println("Response code from GET = 200 OK"); + + } catch (IOException e) { + e.printStackTrace(); + } catch (URISyntaxException e) { + e.printStackTrace(); + } finally { + httpServer.stop(1); + executorService.shutdown(); + } + } + + /** + * Http Server + */ + public void startHttpServer() throws IOException { + httpServer = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(0), 0); + + // create HttpServer context + HttpContext ctx = httpServer.createContext("/test/", new MyHandler()); + + executorService = Executors.newCachedThreadPool(); + httpServer.setExecutor(executorService); + httpServer.start(); + } + + class MyHandler implements HttpHandler { + public void handle(HttpExchange t) throws IOException { + InputStream is = t.getRequestBody(); + Headers reqHeaders = t.getRequestHeaders(); + int i = 0; + // Read till end of stream + do { + i = is.read(); + } while (i != -1); + is.close(); + + List cookies = reqHeaders.get("Cookie"); + if (cookies != null) { + for (String str : cookies) { + // The separator between the 2 cookies should be + // a semi-colon AND a space + if (str.equals("Test1Cookie=TEST1; Test2Cookie=TEST2")) + t.sendResponseHeaders(200, -1); + } + } + t.sendResponseHeaders(400, -1); + t.close(); + } + } +} diff --git a/test/sun/net/www/protocol/http/B6660405.java b/test/sun/net/www/protocol/http/B6660405.java new file mode 100644 index 0000000000000000000000000000000000000000..2309497c2fb7c575b09ad32385710aeca3b48d1c --- /dev/null +++ b/test/sun/net/www/protocol/http/B6660405.java @@ -0,0 +1,163 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6660405 + * @summary HttpURLConnection returns the wrong InputStream + */ + +import java.net.*; +import java.util.*; +import java.io.*; +import com.sun.net.httpserver.*; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; + +public class B6660405 +{ + com.sun.net.httpserver.HttpServer httpServer; + ExecutorService executorService; + + static class MyCacheResponse extends CacheResponse { + private byte[] buf = new byte[1024]; + + public MyCacheResponse() { + } + + @Override + public Map> getHeaders() throws IOException + { + Map> h = new HashMap>(); + ArrayList l = new ArrayList(); + l.add("HTTP/1.1 200 OK"); + h.put(null, l); + l = new ArrayList(); + l.add("1024"); + h.put("Content-Length", l); + return h; + } + + @Override + public InputStream getBody() throws IOException + { + return new ByteArrayInputStream(buf); + } + + } + static class MyResponseCache extends ResponseCache { + + public MyResponseCache() { + } + + @Override + public CacheResponse get(URI uri, String rqstMethod, Map> rqstHeaders) throws IOException + { + if (uri.getPath().equals("/redirect/index.html")) { + return new MyCacheResponse(); + } + return null; + } + + @Override + public CacheRequest put(URI uri, URLConnection conn) throws IOException + { + return null; + } + + } + + public static void main(String[] args) + { + new B6660405(); + } + + public B6660405() + { + try { + startHttpServer(); + doClient(); + } catch (IOException ioe) { + System.err.println(ioe); + } + } + + void doClient() { + ResponseCache.setDefault(new MyResponseCache()); + try { + InetSocketAddress address = httpServer.getAddress(); + + // GET Request + URL url = new URL("http://localhost:" + address.getPort() + "/test/index.html"); + HttpURLConnection uc = (HttpURLConnection)url.openConnection(); + int code = uc.getResponseCode(); + System.err.println("response code = " + code); + int l = uc.getContentLength(); + System.err.println("content-length = " + l); + InputStream in = uc.getInputStream(); + int i = 0; + // Read till end of stream + do { + i = in.read(); + } while (i != -1); + in.close(); + } catch (IOException e) { + throw new RuntimeException("Got the wrong InputStream after checking headers"); + } finally { + httpServer.stop(1); + executorService.shutdown(); + } + } + + /** + * Http Server + */ + public void startHttpServer() throws IOException { + httpServer = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(0), 0); + + // create HttpServer context + HttpContext ctx = httpServer.createContext("/test/", new MyHandler()); + + executorService = Executors.newCachedThreadPool(); + httpServer.setExecutor(executorService); + httpServer.start(); + } + + class MyHandler implements HttpHandler { + public void handle(HttpExchange t) throws IOException { + InputStream is = t.getRequestBody(); + Headers reqHeaders = t.getRequestHeaders(); + Headers resHeaders = t.getResponseHeaders(); + + int i = 0; + // Read till end of stream + do { + i = is.read(); + } while (i != -1); + is.close(); + resHeaders.add("Location", "http://foo.bar/redirect/index.html"); + t.sendResponseHeaders(302, -1); + t.close(); + } + } +} diff --git a/test/sun/security/krb5/DnsFallback.java b/test/sun/security/krb5/DnsFallback.java new file mode 100644 index 0000000000000000000000000000000000000000..95fbf3b165b513d73e940c75115644a883299aa7 --- /dev/null +++ b/test/sun/security/krb5/DnsFallback.java @@ -0,0 +1,64 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +/* + * @test + * @bug 6673164 + * @summary dns_fallback parse error + */ + +import sun.security.krb5.*; +import java.io.*; + +public class DnsFallback { + public static void main(String[] args) throws Exception { + check("true", "true", true); + check("false", "true", false); + check("true", "false", true); + check("false", "false", false); + check("true", null, true); + check("false", null, false); + check(null, "true", true); + check(null, "false", false); + } + + static void check(String realm, String fallback, boolean output) throws Exception { + FileOutputStream fo = new FileOutputStream("dnsfallback.conf"); + StringBuffer sb = new StringBuffer(); + sb.append("[libdefaults]\n"); + if (realm != null) { + sb.append("dns_lookup_realm=" + realm + "\n"); + } + if (fallback != null) { + sb.append("dns_fallback=" + fallback + "\n"); + } + fo.write(sb.toString().getBytes()); + fo.close(); + System.setProperty("java.security.krb5.conf", "dnsfallback.conf"); + Config.refresh(); + System.out.println("Testing " + realm + ", " + fallback + ", " + output); + if (Config.getInstance().useDNS_Realm() != output) { + throw new Exception("Fail"); + } + } +} + diff --git a/test/sun/security/krb5/OptionPADataInKDCReq.java b/test/sun/security/krb5/OptionPADataInKDCReq.java new file mode 100644 index 0000000000000000000000000000000000000000..2229b541e890668f1b2b6e29ec7a4794ab36e1b5 --- /dev/null +++ b/test/sun/security/krb5/OptionPADataInKDCReq.java @@ -0,0 +1,123 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +/* + * @test + * @bug 6648972 + * @summary KDCReq.init always read padata + */ +import sun.security.krb5.internal.ETypeInfo2; +import sun.security.krb5.internal.KDCReq; +import sun.security.util.DerValue; + +public class OptionPADataInKDCReq { + public static void main(String[] args) throws Exception { + /* + * This is a AS-REQ block without padata. The content is -- + [APPLICATION 10] SEQUENCE { + [1] INTEGER 5 + [2] INTEGER 10 + [4] SEQUENCE { + [0] BIT STRING 01000000 10000001 00000000 00010000 + [1] SEQUENCE { + [0] INTEGER 1 + [1] SEQUENCE { + STRING administrator + } + } + [2] STRING N3 + [3] SEQUENCE { + [0] INTEGER 2 + [1] SEQUENCE { + STRING krbtgt + STRING N3 + } + } + [5] TIME Sun Sep 13 10:48:05 CST 2037 + [6] TIME Sun Sep 13 10:48:05 CST 2037 + [7] INTEGER 2101281516 + [8] SEQUENCE { + INTEGER 23 + INTEGER -133 + INTEGER -128 + INTEGER 3 + INTEGER 1 + INTEGER 24 + INTEGER -135 + } + [9] SEQUENCE { + SEQUENCE { + [0] INTEGER 20 + [1] OCTET STRING + 0000: 58 50 20 20 20 20 20 20 20 20 20 20 20 20 20 20 XP + } + } + } + } + */ + byte[] b = { + (byte)0x6a, (byte)0x81, (byte)0xbf, (byte)0x30, (byte)0x81, (byte)0xbc, (byte)0xa1, (byte)0x03, + (byte)0x02, (byte)0x01, (byte)0x05, (byte)0xa2, (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x0a, + (byte)0xa4, (byte)0x81, (byte)0xaf, (byte)0x30, (byte)0x81, (byte)0xac, (byte)0xa0, (byte)0x07, + (byte)0x03, (byte)0x05, (byte)0x00, (byte)0x40, (byte)0x81, (byte)0x00, (byte)0x10, (byte)0xa1, + (byte)0x1a, (byte)0x30, (byte)0x18, (byte)0xa0, (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x01, + (byte)0xa1, (byte)0x11, (byte)0x30, (byte)0x0f, (byte)0x1b, (byte)0x0d, (byte)0x61, (byte)0x64, + (byte)0x6d, (byte)0x69, (byte)0x6e, (byte)0x69, (byte)0x73, (byte)0x74, (byte)0x72, (byte)0x61, + (byte)0x74, (byte)0x6f, (byte)0x72, (byte)0xa2, (byte)0x04, (byte)0x1b, (byte)0x02, (byte)0x4e, + (byte)0x33, (byte)0xa3, (byte)0x17, (byte)0x30, (byte)0x15, (byte)0xa0, (byte)0x03, (byte)0x02, + (byte)0x01, (byte)0x02, (byte)0xa1, (byte)0x0e, (byte)0x30, (byte)0x0c, (byte)0x1b, (byte)0x06, + (byte)0x6b, (byte)0x72, (byte)0x62, (byte)0x74, (byte)0x67, (byte)0x74, (byte)0x1b, (byte)0x02, + (byte)0x4e, (byte)0x33, (byte)0xa5, (byte)0x11, (byte)0x18, (byte)0x0f, (byte)0x32, (byte)0x30, + (byte)0x33, (byte)0x37, (byte)0x30, (byte)0x39, (byte)0x31, (byte)0x33, (byte)0x30, (byte)0x32, + (byte)0x34, (byte)0x38, (byte)0x30, (byte)0x35, (byte)0x5a, (byte)0xa6, (byte)0x11, (byte)0x18, + (byte)0x0f, (byte)0x32, (byte)0x30, (byte)0x33, (byte)0x37, (byte)0x30, (byte)0x39, (byte)0x31, + (byte)0x33, (byte)0x30, (byte)0x32, (byte)0x34, (byte)0x38, (byte)0x30, (byte)0x35, (byte)0x5a, + (byte)0xa7, (byte)0x06, (byte)0x02, (byte)0x04, (byte)0x7d, (byte)0x3f, (byte)0x02, (byte)0xec, + (byte)0xa8, (byte)0x19, (byte)0x30, (byte)0x17, (byte)0x02, (byte)0x01, (byte)0x17, (byte)0x02, + (byte)0x02, (byte)0xff, (byte)0x7b, (byte)0x02, (byte)0x01, (byte)0x80, (byte)0x02, (byte)0x01, + (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x18, (byte)0x02, + (byte)0x02, (byte)0xff, (byte)0x79, (byte)0xa9, (byte)0x1d, (byte)0x30, (byte)0x1b, (byte)0x30, + (byte)0x19, (byte)0xa0, (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x14, (byte)0xa1, (byte)0x12, + (byte)0x04, (byte)0x10, (byte)0x58, (byte)0x50, (byte)0x20, (byte)0x20, (byte)0x20, (byte)0x20, + (byte)0x20, (byte)0x20, (byte)0x20, (byte)0x20, (byte)0x20, (byte)0x20, (byte)0x20, (byte)0x20, + (byte)0x20, (byte)0x20, + }; + new KDCReq(b, 0x0a); + + /* + * This is a fake ETYPEINFO2 block with no salt + SEQUENCE { + [0] INTEGER 0 + [2] OCTET STRING 0000: 00 . + } + */ + byte[] b2 = { + (byte)0x30, (byte)0x0a, (byte)0xa0, (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x00, (byte)0xa2, + (byte)0x03, (byte)0x04, (byte)0x01, (byte)0x00, + }; + + ETypeInfo2 e2 = new ETypeInfo2(new DerValue(b2)); + if (e2.getSalt() != null || e2.getParams() == null) { + throw new Exception("ETypeInfo2 decoding error"); + } + } +} diff --git a/test/sun/security/krb5/TimeInCCache.java b/test/sun/security/krb5/TimeInCCache.java new file mode 100644 index 0000000000000000000000000000000000000000..5ef8b5370df426633f886c1f981296b229b891e4 --- /dev/null +++ b/test/sun/security/krb5/TimeInCCache.java @@ -0,0 +1,93 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +/* + * @test + * @bug 6590930 + * @summary read/write does not match for ccache + */ + +import java.io.ByteArrayInputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import sun.security.krb5.internal.ccache.CCacheInputStream; +import sun.security.krb5.internal.ccache.Credentials; + +public class TimeInCCache { + public static void main(String[] args) throws Exception { + // A trivial cache file, with startdate and renewTill being zero. + // The endtime is set to sometime in year 2022, so that isValid() + // will always check starttime. + byte[] ccache = new byte[]{ + 5, 4, 0, 12, 0, 1, 0, 8, -1, -1, -1, 19, -1, -2, 89, 51, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 10, 77, 65, 88, 73, + 46, 76, 79, 67, 65, 76, 0, 0, 0, 5, 100, 117, 109, 109, 121, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 10, 77, 65, 88, 73, 46, + 76, 79, 67, 65, 76, 0, 0, 0, 5, 100, 117, 109, 109, 121, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 10, 77, 65, 88, 73, 46, 76, + 79, 67, 65, 76, 0, 0, 0, 6, 107, 114, 98, 116, 103, 116, 0, 0, + 0, 10, 77, 65, 88, 73, 46, 76, 79, 67, 65, 76, 0, 17, 0, 0, + 0, 16, -78, -85, -90, -50, -68, 115, 68, 8, -39, -109, 91, 61, -17, -27, + -122, -120, 71, 69, 16, -121, 0, 0, 0, 0, 98, 69, 16, -121, 0, 0, + 0, 0, 0, 64, -32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 97, -127, -3, 48, -127, -6, -96, 3, 2, 1, 5, -95, 12, + 27, 10, 77, 65, 88, 73, 46, 76, 79, 67, 65, 76, -94, 31, 48, 29, + -96, 3, 2, 1, 0, -95, 22, 48, 20, 27, 6, 107, 114, 98, 116, 103, + 116, 27, 10, 77, 65, 88, 73, 46, 76, 79, 67, 65, 76, -93, -127, -61, + 48, -127, -64, -96, 3, 2, 1, 17, -95, 3, 2, 1, 1, -94, -127, -77, + 4, -127, -80, 43, 65, -66, 34, 21, -34, 37, 35, 32, 50, -14, 122, 77, + -3, -29, 37, 99, 50, 125, -43, -96, -78, 85, 23, 41, -80, 68, 2, -109, + -27, 38, -41, -72, -32, 127, 63, -76, -22, 81, 33, -114, -30, 104, 125, -81, + -29, 70, -25, 23, 100, -75, -25, 62, -120, -78, -61, -100, -74, 50, -117, -127, + -16, 79, -106, 62, -39, 91, 100, -10, 23, -88, -18, -47, 51, -19, 113, 18, + 98, -101, 31, 98, 22, -81, 11, -41, -42, 67, 87, 92, -2, 42, -54, 79, + 49, -90, 43, -37, 90, -102, 125, 62, -88, -77, 100, 102, 23, -57, -51, 38, + 68, -44, -57, -102, 103, -6, 85, -58, 74, -117, -87, 67, -103, -36, 110, -122, + 115, 12, 118, -106, -114, -51, 79, 68, 32, -91, -53, -5, -51, 89, 72, 70, + 123, -12, -95, 9, 40, -30, -117, 74, 77, 38, 91, 126, -82, 17, 98, 98, + -49, 78, 36, 36, 103, -76, -100, -23, 118, -92, -8, 80, 103, -23, -98, 56, + 21, 65, -77, 0, 0, 0, 0 + }; + System.setProperty("sun.security.krb5.debug", "true"); // test code changes in DEBUG + CCacheInputStream cis = new CCacheInputStream(new ByteArrayInputStream(ccache)); + cis.readVersion(); + cis.readTag(); + cis.readPrincipal(0x504); + Method m = CCacheInputStream.class.getDeclaredMethod("readCred", Integer.TYPE); + m.setAccessible(true); + Credentials c = (Credentials) m.invoke(cis, new Integer(0x504)); + sun.security.krb5.Credentials cc = c.setKrbCreds(); + + // 1. Make sure starttime is still null + if (cc.getStartTime() != null) { + throw new Exception("Fail, starttime should be zero here"); + } + + // 2. Make sure renewTill is still null + if (cc.getRenewTill() != null) { + throw new Exception("Fail, renewTill should be zero here"); + } + + // 3. Make sure isValid works + c.isValid(); + } +} diff --git a/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/AsyncSSLSocketClose.java b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/AsyncSSLSocketClose.java new file mode 100644 index 0000000000000000000000000000000000000000..21fe5303a6ec4eb404e58b71a097fa490d339d91 --- /dev/null +++ b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/AsyncSSLSocketClose.java @@ -0,0 +1,116 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6447412 + * @summary Issue with socket.close() for ssl sockets when poweroff on + * other system + */ + +import javax.net.ssl.*; +import java.io.*; + +public class AsyncSSLSocketClose implements Runnable +{ + SSLSocket socket; + SSLServerSocket ss; + + // Where do we find the keystores? + static String pathToStores = "../../../../../../../etc"; + static String keyStoreFile = "keystore"; + static String trustStoreFile = "truststore"; + static String passwd = "passphrase"; + + public static void main(String[] args) { + String keyFilename = + System.getProperty("test.src", "./") + "/" + pathToStores + + "/" + keyStoreFile; + String trustFilename = + System.getProperty("test.src", "./") + "/" + pathToStores + + "/" + trustStoreFile; + + System.setProperty("javax.net.ssl.keyStore", keyFilename); + System.setProperty("javax.net.ssl.keyStorePassword", passwd); + System.setProperty("javax.net.ssl.trustStore", trustFilename); + System.setProperty("javax.net.ssl.trustStorePassword", passwd); + + new AsyncSSLSocketClose(); + } + + public AsyncSSLSocketClose() { + try { + SSLServerSocketFactory sslssf = + (SSLServerSocketFactory)SSLServerSocketFactory.getDefault(); + ss = (SSLServerSocket) sslssf.createServerSocket(0); + + SSLSocketFactory sslsf = + (SSLSocketFactory)SSLSocketFactory.getDefault(); + socket = (SSLSocket)sslsf.createSocket("localhost", + ss.getLocalPort()); + SSLSocket serverSoc = (SSLSocket) ss.accept(); + ss.close(); + + (new Thread(this)).start(); + serverSoc.startHandshake(); + + try { + Thread.sleep(5000); + } catch (Exception e) { + e.printStackTrace(); + } + + socket.setSoLinger(true, 10); + System.out.println("Calling Socket.close"); + socket.close(); + System.out.println("ssl socket get closed"); + System.out.flush(); + + } catch (IOException e) { + e.printStackTrace(); + } + + } + + // block in write + public void run() { + try { + byte[] ba = new byte[1024]; + for (int i=0; i