diff --git a/.hgtags b/.hgtags index 29decea481be43e3ff80d14d035a189d881ea64e..09a0507f1d643f7002b4e2d7dddec8513f4d0891 100644 --- a/.hgtags +++ b/.hgtags @@ -50,3 +50,4 @@ b3f3240135f0c10b9f2481c174b81b7fcf0daa60 jdk7-b71 f708138c9aca4b389872838fe6773872fce3609e jdk7-b73 eacb36e30327e7ae33baa068e82ddccbd91eaae2 jdk7-b74 8885b22565077236a927e824ef450742e434a230 jdk7-b75 +8fb602395be0f7d5af4e7e93b7df2d960faf9d17 jdk7-b76 diff --git a/make/java/java/Makefile b/make/java/java/Makefile index 8755a4c3a6ecdf523c51f6a64548589e09d95f32..b0e40530f4ee70a098dba62ef0a0acc8049fdb25 100644 --- a/make/java/java/Makefile +++ b/make/java/java/Makefile @@ -390,7 +390,7 @@ clean:: LOCALES_GEN_SH = localelist.sh $(GENSRCDIR)/sun/util/CoreResourceBundleControl.java: \ - $(SHARE_SRC)/classes/sun/util/CoreResourceBundleControl-XLocales.java $(LOCALES_GEN_SH) + $(SHARE_SRC)/classes/sun/util/CoreResourceBundleControl-XLocales.java.template $(LOCALES_GEN_SH) @$(prep-target) NAWK="$(NAWK)" SED="$(SED)" $(SH) $(LOCALES_GEN_SH) "$(JRE_NONEXIST_LOCALES)" \ $< $@ diff --git a/make/java/java/genlocales.gmk b/make/java/java/genlocales.gmk index bda003b9ce16aeb0eed4822192d4d536f3a6e045..3adb769490d8ceda025d52b537e475e994a64bf5 100644 --- a/make/java/java/genlocales.gmk +++ b/make/java/java/genlocales.gmk @@ -68,7 +68,7 @@ NonEuro_Resources_properties := $(FILES_compiled_properties) FILES_java := $(FILES_java_orig) FILES_compiled_properties := $(FILES_compiled_properties_orig) -LocaleDataMetaInfo_Src=$(SHARE_SRC)/classes/sun/util/LocaleDataMetaInfo-XLocales.java +LocaleDataMetaInfo_Src=$(SHARE_SRC)/classes/sun/util/LocaleDataMetaInfo-XLocales.java.template LocaleDataMetaInfo_Dest=$(GENSRCDIR)/sun/util/LocaleDataMetaInfo.java LOCALEGEN_SH=localegen.sh RESOURCE_NAMES="FormatData CollationData TimeZoneNames LocaleNames CurrencyNames CalendarData" diff --git a/make/java/java/localegen.sh b/make/java/java/localegen.sh index 8f79eaebb88c81c356cca7026bf413d3053474bc..a21c515dc1a661eb6074f5b6f744cdd989d3a2a7 100644 --- a/make/java/java/localegen.sh +++ b/make/java/java/localegen.sh @@ -27,7 +27,7 @@ # # This script is to generate the supported locale list string and replace the -# LocaleDataMetaInfo-XLocales.java in /src/share/classes/sun/util +# LocaleDataMetaInfo-XLocales.java.template in /src/share/classes/sun/util # # SORT, NAWK & SED is passed in as environment variables. # diff --git a/make/java/jli/Makefile b/make/java/jli/Makefile index 861d5375e921dfe62f626397ee4bb609cab2c9ff..eeb64ca6e3413cc1c3d450feca0ea7a0dec084d5 100644 --- a/make/java/jli/Makefile +++ b/make/java/jli/Makefile @@ -96,6 +96,7 @@ OTHER_CPPFLAGS += $(LIBARCH_DEFINES) ifneq ($(PLATFORM), windows) # UNIX systems + LD_RUNPATH_EXTRAS += .. LIB_LOCATION = $(LIBDIR)/$(LIBARCH)/jli # Note: its important to keep this order meaning -lc is the # last library otherwise it could cause compatibility issues diff --git a/make/java/main/java/Makefile b/make/java/main/java/Makefile index ae9ce618cdd7a4f90697332a20accdcfc04f8169..37fdf2bdd0f038350b40a9aa92b3538d5dbf8240 100644 --- a/make/java/main/java/Makefile +++ b/make/java/main/java/Makefile @@ -61,8 +61,5 @@ OTHER_CPPFLAGS += -DLAUNCHER_NAME='"$(LAUNCHER_NAME)"' ifeq ($(PLATFORM), solaris) LDFLAGS += -R$(OPENWIN_LIB) -endif - -ifeq ($(PLATFORM), solaris) LDFLAGS += -M mapfile-$(ARCH) endif diff --git a/make/java/nio/Makefile b/make/java/nio/Makefile index e0cb40839e8c318fccc9964f8bb10582899bc50e..455d7529f67767282d4a71a59fb3463e97685fef 100644 --- a/make/java/nio/Makefile +++ b/make/java/nio/Makefile @@ -834,7 +834,7 @@ $(SCH_GEN)/SocketOptionRegistry.java: $(GENSOR_EXE) GENCSSRC = $(BUILDDIR)/tools/CharsetMapping CHARSETMAPPING_JARFILE = $(BUILDTOOLJARDIR)/charsetmapping.jar -$(FILES_gensbcs_out): $(GENCSSRC)/SingleByte-X.java $(GENCSSRC)/sbcs +$(FILES_gensbcs_out): $(GENCSSRC)/SingleByte-X.java.template $(GENCSSRC)/sbcs @$(prep-target) $(BOOT_JAVA_CMD) -jar $(CHARSETMAPPING_JARFILE) $(GENCSSRC) $(SCS_GEN) sbcs diff --git a/make/java/redist/Makefile b/make/java/redist/Makefile index b4ca64e5c14f80017cfe53f260cb5ed4dcc581df..69d95a605777c7f126e9be8d3a38df6788d34a63 100644 --- a/make/java/redist/Makefile +++ b/make/java/redist/Makefile @@ -194,10 +194,8 @@ endif # For backwards compatability, make a link of the 32-bit client JVM to $(LIBDIR) IMPORT_LIST += $(LIB_LOCATION)/$(JVM_NAME) -# create a link from lib/libjvm.so to client/libjvm.so $(LIB_LOCATION)/$(JVM_NAME): $(LIB_LOCATION)/$(CLIENT_LOCATION)/$(JVM_NAME) @$(prep-target) - $(LN) -s $(CLIENT_LOCATION)/$(JVM_NAME) $@ # solaris ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ solaris endif # 32bit solaris diff --git a/make/netbeans/README b/make/netbeans/README index 9c713190034be8b58e9c2b60b8d0de8bb256b0ed..8f68dce0ee5c4604466988923480c796c1191307 100644 --- a/make/netbeans/README +++ b/make/netbeans/README @@ -411,7 +411,7 @@ Creating your own NetBeans project java/util/regex/,\ java/util/spi/,\ java/util/zip/,\ - **/*-XLocales.java + **/*-XLocales.java.template jtreg.tests=\ java/util/**/*Collection/ \ java/util/**/*Map/ \ diff --git a/make/sun/javazic/tzdata/VERSION b/make/sun/javazic/tzdata/VERSION index 17a8a1b2984e5d062beb86036f1de34d2133961f..a5146914b90f544d83ddf3686aba139ce493ebed 100644 --- a/make/sun/javazic/tzdata/VERSION +++ b/make/sun/javazic/tzdata/VERSION @@ -21,4 +21,4 @@ # CA 95054 USA or visit www.sun.com if you need additional information or # have any questions. # -tzdata2009l +tzdata2009r diff --git a/make/sun/javazic/tzdata/antarctica b/make/sun/javazic/tzdata/antarctica index 31a624b0e101448d33b7c21b2b31d7ab3a78fd42..c77fc899cadfa9d1e5bf1f76c45b8d280e4a9da1 100644 --- a/make/sun/javazic/tzdata/antarctica +++ b/make/sun/javazic/tzdata/antarctica @@ -102,15 +102,38 @@ Rule ChileAQ 2000 max - Mar Sun>=9 3:00u 0 - # Davis, Vestfold Hills, -6835+07759, since 1957-01-13 # (except 1964-11 - 1969-02) # Mawson, Holme Bay, -6736+06253, since 1954-02-13 + +# From Steffen Thorsen (2009-03-11): +# Three Australian stations in Antarctica have changed their time zone: +# Casey moved from UTC+8 to UTC+11 +# Davis moved from UTC+7 to UTC+5 +# Mawson moved from UTC+6 to UTC+5 +# The changes occurred on 2009-10-18 at 02:00 (local times). +# +# Government source: (Australian Antarctic Division) +# +# http://www.aad.gov.au/default.asp?casid=37079 +# +# +# We have more background information here: +# +# http://www.timeanddate.com/news/time/antarctica-new-times.html +# + # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Antarctica/Casey 0 - zzz 1969 - 8:00 - WST # Western (Aus) Standard Time + 8:00 - WST 2009 Oct 18 2:00 + # Western (Aus) Standard Time + 11:00 - CAST # Casey Time Zone Antarctica/Davis 0 - zzz 1957 Jan 13 7:00 - DAVT 1964 Nov # Davis Time 0 - zzz 1969 Feb - 7:00 - DAVT + 7:00 - DAVT 2009 Oct 18 2:0 + 5:00 - DAVT Zone Antarctica/Mawson 0 - zzz 1954 Feb 13 - 6:00 - MAWT # Mawson Time + 6:00 - MAWT 2009 Oct 18 2:00 + # Mawson Time + 5:00 - MAWT # References: # # Casey Weather (1998-02-26) diff --git a/make/sun/javazic/tzdata/asia b/make/sun/javazic/tzdata/asia index 81534b919a44d20827ead361026d86bb7570ba96..139df5ee0e12037aab893b3228d9841810bb7c2c 100644 --- a/make/sun/javazic/tzdata/asia +++ b/make/sun/javazic/tzdata/asia @@ -21,7 +21,6 @@ # CA 95054 USA or visit www.sun.com if you need additional information or # have any questions. # -#
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
@@ -194,11 +193,30 @@ Zone	Asia/Bahrain	3:22:20 -	LMT	1920		# Al Manamah
 #
 # No DST end date has been announced yet.
 
-# From Arthur David Olson (2009-07-11):
-# Arbitrarily end DST at the end of 2009 so that a POSIX-sytle time zone string
-# can appear in the Dhaka binary file and for the benefit of old glibc
-# reimplementations of the time zone software that mishandle permanent DST.
-# A change will be required once the end date is known.
+# From Alexander Krivenyshev (2009-09-25):
+# Bangladesh won't go back to Standard Time from October 1, 2009, 
+# instead it will continue DST measure till the cabinet makes a fresh decision. 
+#
+# Following report by same newspaper-"The Daily Star Friday":
+# "DST change awaits cabinet decision-Clock won't go back by 1-hr from Oct 1"
+# 
+# http://www.thedailystar.net/newDesign/news-details.php?nid=107021
+# 
+# or
+# 
+# http://www.worldtimezone.com/dst_news/dst_news_bangladesh04.html
+# 
+
+# From Steffen Thorsen (2009-10-13):
+# IANS (Indo-Asian News Service) now reports:
+# Bangladesh has decided that the clock advanced by an hour to make 
+# maximum use of daylight hours as an energy saving measure would 
+# "continue for an indefinite period."
+#
+# One of many places where it is published:
+# 
+# http://www.thaindian.com/newsportal/business/bangladesh-to-continue-indefinitely-with-advanced-time_100259987.html
+# 
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Dhaka	6:01:40 -	LMT	1890
@@ -208,8 +226,7 @@ Zone	Asia/Dhaka	6:01:40 -	LMT	1890
 			6:30	-	BURT	1951 Sep 30
 			6:00	-	DACT	1971 Mar 26 # Dacca Time
 			6:00	-	BDT	2009 Jun 19 23:00 # Bangladesh Time
-			6:00	1:00	BDST	2010
-			6:00	-	BDT
+			6:00	1:00	BDST
 
 # Bhutan
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -373,14 +390,84 @@ Zone	Asia/Kashgar	5:03:56	-	LMT	1928 # or Kashi or Kaxgar
 			5:00	-	KAST	1980 May
 			8:00	PRC	C%sT
 
+
+# From Lee Yiu Chung (2009-10-24):
+# I found there are some mistakes for the historial DST rule for Hong
+# Kong. Accoring to the DST record from Hong Kong Observatory (actually,
+# it is not [an] observatory, but the official meteorological agency of HK,
+# and also serves as the official timing agency), there are some missing
+# and incorrect rules. Although the exact switch over time is missing, I
+# think 3:30 is correct. The official DST record for Hong Kong can be
+# obtained from
+# 
+# http://www.hko.gov.hk/gts/time/Summertime.htm
+# .
+
+# From Arthur David Olson (2009-10-28):
+# Here are the dates given at
+# 
+# http://www.hko.gov.hk/gts/time/Summertime.htm
+# 
+# as of 2009-10-28:
+# Year        Period
+# 1941        1 Apr to 30 Sep
+# 1942        Whole year 
+# 1943        Whole year
+# 1944        Whole year
+# 1945        Whole year
+# 1946        20 Apr to 1 Dec
+# 1947        13 Apr to 30 Dec
+# 1948        2 May to 31 Oct
+# 1949        3 Apr to 30 Oct
+# 1950        2 Apr to 29 Oct
+# 1951        1 Apr to 28 Oct
+# 1952        6 Apr to 25 Oct
+# 1953        5 Apr to 1 Nov
+# 1954        21 Mar to 31 Oct
+# 1955        20 Mar to 6 Nov
+# 1956        18 Mar to 4 Nov
+# 1957        24 Mar to 3 Nov
+# 1958        23 Mar to 2 Nov
+# 1959        22 Mar to 1 Nov
+# 1960        20 Mar to 6 Nov
+# 1961        19 Mar to 5 Nov
+# 1962        18 Mar to 4 Nov
+# 1963        24 Mar to 3 Nov
+# 1964        22 Mar to 1 Nov
+# 1965        18 Apr to 17 Oct
+# 1966        17 Apr to 16 Oct
+# 1967        16 Apr to 22 Oct
+# 1968        21 Apr to 20 Oct
+# 1969        20 Apr to 19 Oct
+# 1970        19 Apr to 18 Oct
+# 1971        18 Apr to 17 Oct
+# 1972        16 Apr to 22 Oct
+# 1973        22 Apr to 21 Oct
+# 1973/74     30 Dec 73 to 20 Oct 74
+# 1975        20 Apr to 19 Oct
+# 1976        18 Apr to 17 Oct
+# 1977        Nil
+# 1978        Nil
+# 1979        13 May to 21 Oct
+# 1980 to Now Nil
+# The page does not give start or end times of day.
+# The page does not give a start date for 1942.
+# The page does not givw an end date for 1945.
+# The Japanese occupation of Hong Kong began on 1941-12-25.
+# The Japanese surrender of Hong Kong was signed 1945-09-15.
+# For lack of anything better, use start of those days as the transition times.
+
 # Hong Kong (Xianggang)
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	HK	1941	only	-	Apr	1	3:30	1:00	S
+Rule	HK	1941	only	-	Sep	30	3:30	0	-
 Rule	HK	1946	only	-	Apr	20	3:30	1:00	S
 Rule	HK	1946	only	-	Dec	1	3:30	0	-
 Rule	HK	1947	only	-	Apr	13	3:30	1:00	S
 Rule	HK	1947	only	-	Dec	30	3:30	0	-
 Rule	HK	1948	only	-	May	2	3:30	1:00	S
-Rule	HK	1948	1952	-	Oct	lastSun	3:30	0	-
+Rule	HK	1948	1951	-	Oct	lastSun	3:30	0	-
+Rule	HK	1952	only	-	Oct	25	3:30	0	-
 Rule	HK	1949	1953	-	Apr	Sun>=1	3:30	1:00	S
 Rule	HK	1953	only	-	Nov	1	3:30	0	-
 Rule	HK	1954	1964	-	Mar	Sun>=18	3:30	1:00	S
@@ -388,13 +475,15 @@ Rule	HK	1954	only	-	Oct	31	3:30	0	-
 Rule	HK	1955	1964	-	Nov	Sun>=1	3:30	0	-
 Rule	HK	1965	1977	-	Apr	Sun>=16	3:30	1:00	S
 Rule	HK	1965	1977	-	Oct	Sun>=16	3:30	0	-
-Rule	HK	1979	1980	-	May	Sun>=8	3:30	1:00	S
-Rule	HK	1979	1980	-	Oct	Sun>=16	3:30	0	-
+Rule	HK	1973	only	-	Dec	30	3:30	1:00	S
+Rule	HK	1979	only	-	May	Sun>=8	3:30	1:00	S
+Rule	HK	1979	only	-	Oct	Sun>=16	3:30	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Hong_Kong	7:36:36 -	LMT	1904 Oct 30
+			8:00	HK	HK%sT	1941 Dec 25
+			9:00	-	JST	1945 Sep 15
 			8:00	HK	HK%sT
 
-
 ###############################################################################
 
 # Taiwan
@@ -1696,16 +1785,66 @@ Zone	Asia/Muscat	3:54:20 -	LMT	1920
 # advance clocks in the country by one hour from April 15 to
 # conserve energy"
 
-# From Arthur David Olson (2009-04-10):
-# Assume for now that Pakistan will end DST in 2009 as it did in 2008.
+# From Steffen Thorsen (2009-09-17):
+# "The News International," Pakistan reports that: "The Federal
+# Government has decided to restore the previous time by moving the
+# clocks backward by one hour from October 1. A formal announcement to
+# this effect will be made after the Prime Minister grants approval in
+# this regard." 
+# 
+# http://www.thenews.com.pk/updates.asp?id=87168
+# 
+
+# From Alexander Krivenyshev (2009-09-28):
+# According to Associated Press Of Pakistan, it is confirmed that
+# Pakistan clocks across the country would be turned back by an hour from October
+# 1, 2009.
+#
+# "Clocks to go back one hour from 1 Oct"
+# 
+# http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=86715&Itemid=2
+# 
+# or
+# 
+# http://www.worldtimezone.com/dst_news/dst_news_pakistan07.htm
+# 
+
+# From Steffen Thorsen (2009-09-29):
+# Alexander Krivenyshev wrote:
+# > According to Associated Press Of Pakistan, it is confirmed that
+# > Pakistan clocks across the country would be turned back by an hour from October
+# > 1, 2009.
+#
+# Now they seem to have changed their mind, November 1 is the new date:
+# 
+# http://www.thenews.com.pk/top_story_detail.asp?Id=24742
+# 
+# "The country's clocks will be reversed by one hour on November 1.
+# Officials of Federal Ministry for Interior told this to Geo News on
+# Monday."
+#
+# And more importantly, it seems that these dates will be kept every year:
+# "It has now been decided that clocks will be wound forward by one hour
+# on April 15 and reversed by an hour on November 1 every year without
+# obtaining prior approval, the officials added."
+#
+# We have confirmed this year's end date with both with the Ministry of
+# Water and Power and the Pakistan Electric Power Company:
+# 
+# http://www.timeanddate.com/news/time/pakistan-ends-dst09.html
+# 
+
+# From Christoph Goehre (2009-10-01):
+# [T]he German Consulate General in Karachi reported me today that Pakistan
+# will go back to standard time on 1st of November.
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule Pakistan	2002	only	-	Apr	Sun>=2	0:01	1:00	S
 Rule Pakistan	2002	only	-	Oct	Sun>=2	0:01	0	-
 Rule Pakistan	2008	only	-	Jun	1	0:00	1:00	S
 Rule Pakistan	2008	only	-	Nov	1	0:00	0	-
-Rule Pakistan	2009	only	-	Apr	15	0:00	1:00	S
-Rule Pakistan	2009	only	-	Nov	1	0:00	0	-
+Rule Pakistan	2009	max	-	Apr	15	0:00	1:00	S
+Rule Pakistan	2009	max	-	Nov	1	0:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Karachi	4:28:12 -	LMT	1907
 			5:30	-	IST	1942 Sep
@@ -1858,6 +1997,42 @@ Zone	Asia/Karachi	4:28:12 -	LMT	1907
 # http://www.worldtimezone.com/dst_news/dst_news_westbank01.html
 # 
 
+# From Steffen Thorsen (2009-08-31):
+# Palestine's Council of Ministers announced that they will revert back to
+# winter time on Friday, 2009-09-04.
+#
+# One news source:
+# 
+# http://www.safa.ps/ara/?action=showdetail&seid=4158
+# 
+# (Palestinian press agency, Arabic),
+# Google translate: "Decided that the Palestinian government in Ramallah
+# headed by Salam Fayyad, the start of work in time for the winter of
+# 2009, starting on Friday approved the fourth delay Sept. clock sixty
+# minutes per hour as of Friday morning."
+#
+# We are not sure if Gaza will do the same, last year they had a different
+# end date, we will keep this page updated:
+# 
+# http://www.timeanddate.com/news/time/westbank-gaza-dst-2009.html
+# 
+
+# From Alexander Krivenyshev (2009-09-02):
+# Seems that Gaza Strip will go back to Winter Time same date as West Bank.
+#
+# According to Palestinian Ministry Of Interior, West Bank and Gaza Strip plan
+# to change time back to Standard time on September 4, 2009.
+#
+# "Winter time unite the West Bank and Gaza"
+# (from Palestinian National Authority):
+# 
+# http://www.worldtimezone.com/dst_news/dst_news_gazastrip02.html
+# 
+
 # The rules for Egypt are stolen from the `africa' file.
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule EgyptAsia	1957	only	-	May	10	0:00	1:00	S
@@ -1876,7 +2051,7 @@ Rule Palestine	2006	only	-	Sep	22	0:00	0	-
 Rule Palestine	2007	only	-	Sep	Thu>=8	2:00	0	-
 Rule Palestine	2008	only	-	Aug	lastFri	2:00	0	-
 Rule Palestine	2009	max	-	Mar	lastFri	0:00	1:00	S
-Rule Palestine	2009	max	-	Sep	lastMon	2:00	0	-
+Rule Palestine	2009	max	-	Sep	Fri>=1	2:00	0	-
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Gaza	2:17:52	-	LMT	1900 Oct
@@ -2154,9 +2329,23 @@ Rule	Syria	2007	only	-	Nov	 Fri>=1	0:00	0	-
 # http://www.timeanddate.com/news/time/syria-dst-starts-march-27-2009.html
 # 
 
+# From Steffen Thorsen (2009-10-27):
+# The Syrian Arab News Network on 2009-09-29 reported that Syria will 
+# revert back to winter (standard) time on midnight between Thursday 
+# 2009-10-29 and Friday 2009-10-30:
+# 
+# http://www.sana.sy/ara/2/2009/09/29/247012.htm (Arabic)
+# 
+
+# From Arthur David Olson (2009-10-28):
+# We'll see if future DST switching times turn out to be end of the last
+# Thursday of the month or the start of the last Friday of the month or
+# something else. For now, use the start of the last Friday.
+
 Rule	Syria	2008	only	-	Apr	Fri>=1	0:00	1:00	S
-Rule	Syria	2008	max	-	Nov	1	0:00	0	-
+Rule	Syria	2008	only	-	Nov	1	0:00	0	-
 Rule	Syria	2009	max	-	Mar	lastFri	0:00	1:00	S
+Rule	Syria	2009	max	-	Oct	lastFri	0:00	0	-
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Damascus	2:25:12 -	LMT	1920	# Dimashq
diff --git a/make/sun/javazic/tzdata/australasia b/make/sun/javazic/tzdata/australasia
index 8e336dcea30fe15c7209d1a076a10041d489134d..d9150b5ffd5d1ace910ca64aadee3f25eb8b5b80 100644
--- a/make/sun/javazic/tzdata/australasia
+++ b/make/sun/javazic/tzdata/australasia
@@ -465,10 +465,56 @@ Zone Pacific/Pago_Pago	 12:37:12 -	LMT	1879 Jul  5
 # http://www.worldtimezone.com/dst_news/dst_news_samoa01.html
 # 
 
+# From Steffen Thorsen (2009-08-27):
+# Samoa's parliament passed the Daylight Saving Bill 2009, and will start 
+# daylight saving time on the first Sunday of October 2009 and end on the 
+# last Sunday of March 2010. We hope that the full text will be published 
+# soon, but we believe that the bill is only valid for 2009-2010. Samoa's 
+# Daylight Saving Act 2009 will be enforced as soon as the Head of State 
+# executes a proclamation publicizing this Act.
+#
+# Some background information here, which will be updated once we have 
+# more details:
+# 
+# http://www.timeanddate.com/news/time/samoa-dst-plan-2009.html
+# 
+
+# From Alexander Krivenyshev (2009-10-03):
+# First, my deepest condolences to people of Samoa islands and all families and
+# loved ones around the world who lost their lives in the earthquake and tsunami.
+#
+# Considering the recent devastation on Samoa by earthquake and tsunami and that
+# many government offices/ ministers are closed- not sure if "Daylight Saving
+# Bill 2009" will be implemented in next few days- on October 4, 2009.
+#
+# Here is reply from Consulate-General of Samoa in New Zealand
+# ---------------------------
+# Consul General
+# consulgeneral@samoaconsulate.org.nz
+#
+# Talofa Alexander,
+#
+# Thank you for your sympathy for our country but at this time we have not
+# been informed about the Daylight Savings Time Change.  Most Ministries in
+# Apia are closed or relocating due to weather concerns.
+#
+# When we do find out if they are still proceeding with the time change we
+# will advise you soonest.
+#
+# Kind Regards,
+# Lana
+# for: Consul General
+
+# From Steffen Thorsen (2009-10-05):
+# We have called a hotel in Samoa and asked about local time there - they 
+# are still on standard time.
+
 Zone Pacific/Apia	 12:33:04 -	LMT	1879 Jul  5
 			-11:26:56 -	LMT	1911
 			-11:30	-	SAMT	1950		# Samoa Time
-			-11:00	-	WST			# Samoa Time
+			-11:00	-	WST	2009 Oct 4
+			-11:00	1:00	WSDT	2010 Mar 28
+			-11:00	-	WST
 
 # Solomon Is
 # excludes Bougainville, for which see Papua New Guinea
diff --git a/make/sun/javazic/tzdata/europe b/make/sun/javazic/tzdata/europe
index 16dbe0ee500e089a17b578f83fd38d3710946cba..d7fffc23c7ebac8dde0d627a62e56087f9f9afa8 100644
--- a/make/sun/javazic/tzdata/europe
+++ b/make/sun/javazic/tzdata/europe
@@ -2094,9 +2094,43 @@ Zone Asia/Novosibirsk	 5:31:40 -	LMT	1919 Dec 14 6:00
 			 6:00	Russia	NOV%sT	1992 Jan 19 2:00s
 			 7:00	Russia	NOV%sT	1993 May 23 # say Shanks & P.
 			 6:00	Russia	NOV%sT
+
+# From Alexander Krivenyshev (2009-10-13):
+# Kemerovo oblast' (Kemerovo region) in Russia will change current time zone on
+# March 28, 2010:
+# from current Russia Zone 6 - Krasnoyarsk Time Zone (KRA) UTC +0700
+# to Russia Zone 5 - Novosibirsk Time Zone (NOV) UTC +0600
+#
+# This is according to Government of Russia decree # 740, on September
+# 14, 2009 "Application in the territory of the Kemerovo region the Fifth
+# time zone." ("Russia Zone 5" or old "USSR Zone 5" is GMT +0600)
+#
+# Russian Government web site (Russian language)
+# 
+# http://www.government.ru/content/governmentactivity/rfgovernmentdecisions/archive/2009/09/14/991633.htm
+# 
+# or Russian-English translation by WorldTimeZone.com with reference
+# map to local region and new Russia Time Zone map after March 28, 2010
+# 
+# http://www.worldtimezone.com/dst_news/dst_news_russia03.html
+# 
+#
+# Thus, when Russia will switch to DST on the night of March 28, 2010
+# Kemerovo region (Kemerovo oblast') will not change the clock.
+#
+# As a result, Kemerovo oblast' will be in the same time zone as
+# Novosibirsk, Omsk, Tomsk, Barnaul and Altai Republic.
+
+Zone Asia/Novokuznetsk	 5:48:48 -	NMT	1920 Jan  6
+			 6:00	-	KRAT	1930 Jun 21 # Krasnoyarsk Time
+			 7:00	Russia	KRA%sT	1991 Mar 31 2:00s
+			 6:00	Russia	KRA%sT	1992 Jan 19 2:00s
+			 7:00	Russia	KRA%sT	2010 Mar 28 2:00s
+			 6:00	Russia	NOV%sT # Novosibirsk/Novokuznetsk Time
+
 #
 # From Oscar van Vlijmen (2001-08-25): [This region consists of]
-# Kemerovskaya oblast', Krasnoyarskij kraj,
+# Krasnoyarskij kraj,
 # Tajmyrskij (Dolgano-Nenetskij) avtonomnyj okrug,
 # Respublika Tuva, Respublika Khakasiya, Evenkijskij avtonomnyj okrug.
 Zone Asia/Krasnoyarsk	 6:11:20 -	LMT	1920 Jan  6
diff --git a/make/sun/javazic/tzdata/southamerica b/make/sun/javazic/tzdata/southamerica
index c886a28b1263de0629c63c3b6674f5c044ed54ee..693fec6342321a1b76c0704e1d65e6bceea6358e 100644
--- a/make/sun/javazic/tzdata/southamerica
+++ b/make/sun/javazic/tzdata/southamerica
@@ -237,9 +237,23 @@ Rule	Arg	2000	only	-	Mar	3	0:00	0	-
 # http://www.jujuy.gov.ar/index2/partes_prensa/18_10_08/235-181008.doc
 # 
 
+# From fullinet (2009-10-18):
+# As announced in
+# 
+# http://www.argentina.gob.ar/argentina/portal/paginas.dhtml?pagina=356
+# 
+# (an official .gob.ar) under title: "Sin Cambio de Hora" (english: "No hour change")
+#
+# "Por el momento, el Gobierno Nacional resolvio no modificar la hora
+# oficial, decision que estaba en estudio para su implementacion el
+# domingo 18 de octubre. Desde el Ministerio de Planificacion se anuncio
+# que la Argentina hoy, en estas condiciones meteorologicas, no necesita
+# la modificacion del huso horario, ya que 2009 nos encuentra con
+# crecimiento en la produccion y distribucion energetica."
+
 Rule	Arg	2007	only	-	Dec	30	0:00	1:00	S
-Rule	Arg	2008	max	-	Mar	Sun>=15	0:00	0	-
-Rule	Arg	2008	max	-	Oct	Sun>=15	0:00	1:00	S
+Rule	Arg	2008	2009	-	Mar	Sun>=15	0:00	0	-
+Rule	Arg	2008	only	-	Oct	Sun>=15	0:00	1:00	S
  
 # From Mariano Absatz (2004-05-21):
 # Today it was officially published that the Province of Mendoza is changing
@@ -411,15 +425,40 @@ Rule	Arg	2008	max	-	Oct	Sun>=15	0:00	1:00	S
 # during 2009, this timezone change will run from 00:00 the third Sunday
 # in March until 24:00 of the second Saturday in October.
 
-# From Arthur David Olson (2009-03-16):
-# The unofficial claim at
-# 
-# http://www.timeanddate.com/news/time/san-luis-new-time-zone.html
+# From Mariano Absatz (2009-10-16):
+# ...the Province of San Luis is a case in itself.
+#
+# The Law at
+# 
-# is that "The province will most likely follow the next daylight saving schedule,
-# which is planned for the second Sunday in October."
-
+# is ambiguous because establishes a calendar from the 2nd Sunday in
+# October at 0:00 thru the 2nd Saturday in March at 24:00 and the
+# complement of that starting on the 2nd Sunday of March at 0:00 and
+# ending on the 2nd Saturday of March at 24:00.
+#
+# This clearly breaks every time the 1st of March or October is a Sunday.
+#
+# IMHO, the "spirit of the Law" is to make the changes at 0:00 on the 2nd
+# Sunday of October and March.
 #
+# The problem is that the changes in the rest of the Provinces that did
+# change in 2007/2008, were made according to the Federal Law and Decrees
+# that did so on the 3rd Sunday of October and March.
+#
+# In fact, San Luis actually switched from UTC-4 to UTC-3 last Sunday
+# (October 11th) at 0:00.
+#
+# So I guess a new set of rules, besides "Arg", must be made and the last
+# America/Argentina/San_Luis entries should change to use these...
+#
+# I'm enclosing a patch that does what I say... regretfully, the San Luis
+# timezone must be called "WART/WARST" even when most of the time (like,
+# right now) WARST == ART... that is, since last Sunday, all the country
+# is using UTC-3, but in my patch, San Luis calls it "WARST" and the rest
+# of the country calls it "ART".
+# ...
+
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 #
 # Buenos Aires (BA), Capital Federal (CF),
@@ -552,6 +591,10 @@ Zone America/Argentina/Mendoza -4:35:16 - LMT	1894 Oct 31
 			-3:00	-	ART
 #
 # San Luis (SL)
+
+Rule	SanLuis	2008	max	-	Mar	Sun>=8	0:00	0	-
+Rule	SanLuis	2007	max	-	Oct	Sun>=8	0:00	1:00	S
+
 Zone America/Argentina/San_Luis -4:25:24 - LMT	1894 Oct 31
 			-4:16:48 -	CMT	1920 May
 			-4:00	-	ART	1930 Dec
@@ -566,8 +609,7 @@ Zone America/Argentina/San_Luis -4:25:24 - LMT	1894 Oct 31
 			-3:00	-	ART	2004 May 31
 			-4:00	-	WART	2004 Jul 25
 			-3:00	Arg	AR%sT	2008 Jan 21
-			-3:00	-	ART	2009 Mar 15
-			-4:00	Arg	WAR%sT
+			-4:00	SanLuis	WAR%sT
 #
 # Santa Cruz (SC)
 Zone America/Argentina/Rio_Gallegos -4:36:52 - LMT 1894 Oct 31
diff --git a/make/sun/javazic/tzdata/zone.tab b/make/sun/javazic/tzdata/zone.tab
index 2a323ebb90ef172802ae7845d2333b90b55edebe..3e6f46577396962d308c32873c88aa374fbc8f27 100644
--- a/make/sun/javazic/tzdata/zone.tab
+++ b/make/sun/javazic/tzdata/zone.tab
@@ -352,6 +352,7 @@ RU	+5312+05009	Europe/Samara	Moscow+01 - Samara, Udmurtia
 RU	+5651+06036	Asia/Yekaterinburg	Moscow+02 - Urals
 RU	+5500+07324	Asia/Omsk	Moscow+03 - west Siberia
 RU	+5502+08255	Asia/Novosibirsk	Moscow+03 - Novosibirsk
+RU	+5345+08707	Asia/Novokuznetsk	Moscow+03 - Novokuznetsk
 RU	+5601+09250	Asia/Krasnoyarsk	Moscow+04 - Yenisei River
 RU	+5216+10420	Asia/Irkutsk	Moscow+05 - Lake Baikal
 RU	+6200+12940	Asia/Yakutsk	Moscow+06 - Lena River
diff --git a/make/sun/nio/Makefile b/make/sun/nio/Makefile
index e83c6f1f36d80a83c0fdde9a6dc496627baf813f..4b46a1fb76d0b82c58e2c762943ed70909ba8c77 100644
--- a/make/sun/nio/Makefile
+++ b/make/sun/nio/Makefile
@@ -82,7 +82,9 @@ $(FILES_DAT): $(FILES_MAP)
 		$(FILES_MAP) $(FILES_DAT) sjis0213
 
 
-$(FILES_genout_extcs): $(GENCSDATASRC)/SingleByte-X.java  $(GENCSDATASRC)/DoubleByte-X.java \
+$(FILES_genout_extcs): \
+                $(GENCSDATASRC)/SingleByte-X.java.template  \
+		$(GENCSDATASRC)/DoubleByte-X.java.template \
 		$(GENCSDATASRC)/extsbcs $(GENCSDATASRC)/dbcs
 	@$(prep-target)
 	$(RM) -r $(GENCSEXT)
diff --git a/make/tools/CharsetMapping/DoubleByte-X.java b/make/tools/CharsetMapping/DoubleByte-X.java.template
similarity index 100%
rename from make/tools/CharsetMapping/DoubleByte-X.java
rename to make/tools/CharsetMapping/DoubleByte-X.java.template
diff --git a/make/tools/CharsetMapping/SingleByte-X.java b/make/tools/CharsetMapping/SingleByte-X.java.template
similarity index 100%
rename from make/tools/CharsetMapping/SingleByte-X.java
rename to make/tools/CharsetMapping/SingleByte-X.java.template
diff --git a/make/tools/src/build/tools/charsetmapping/GenerateDBCS.java b/make/tools/src/build/tools/charsetmapping/GenerateDBCS.java
index f38e759c45699a2a734bcf6942a84de6e81257e9..27dc8719b950c38c996fe713b572758a390094e7 100644
--- a/make/tools/src/build/tools/charsetmapping/GenerateDBCS.java
+++ b/make/tools/src/build/tools/charsetmapping/GenerateDBCS.java
@@ -63,7 +63,7 @@ public class GenerateDBCS {
             int    b2Min    = toInteger(fields[8]);
             int    b2Max    = toInteger(fields[9]);
             System.out.printf("%s,%s,%s,%b,%s%n", clzName, csName, hisName, isASCII, pkgName);
-            genClass(args[0], args[1], "DoubleByte-X.java",
+            genClass(args[0], args[1], "DoubleByte-X.java.template",
                     clzName, csName, hisName, pkgName,
                     isASCII, type,
                     b1Min, b1Max, b2Min, b2Max);
diff --git a/make/tools/src/build/tools/charsetmapping/GenerateSBCS.java b/make/tools/src/build/tools/charsetmapping/GenerateSBCS.java
index 8a57a6521bce9a439e7ef3729fe5f01b787f2f6a..cb6496e0a9965c537203d33210a2e11ecf574fc5 100644
--- a/make/tools/src/build/tools/charsetmapping/GenerateSBCS.java
+++ b/make/tools/src/build/tools/charsetmapping/GenerateSBCS.java
@@ -55,7 +55,7 @@ public class GenerateSBCS {
             String pkgName  = fields[4];
             System.out.printf("%s,%s,%s,%b,%s%n", clzName, csName, hisName, isASCII, pkgName);
 
-            genClass(args[0], args[1], "SingleByte-X.java",
+            genClass(args[0], args[1], "SingleByte-X.java.template",
                      clzName, csName, hisName, pkgName, isASCII);
         }
     }
diff --git a/src/share/bin/java.c b/src/share/bin/java.c
index b8c0382b1d18c76ef98baaa7fac82e07c0b739b5..2494ce1ea2e5a1d4e246d296d53c1e81c585933a 100644
--- a/src/share/bin/java.c
+++ b/src/share/bin/java.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1995-2009 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
@@ -41,15 +41,13 @@
  * options are turned into "-foo" options to the vm.  This option
  * filtering is handled in a number of places in the launcher, some of
  * it in machine-dependent code.  In this file, the function
- * CheckJVMType removes vm style options and TranslateApplicationArgs
- * removes "-J" prefixes.  On unix platforms, the
- * CreateExecutionEnvironment function from the unix java_md.c file
- * processes and removes -d options.  However, in case
- * CreateExecutionEnvironment does not need to exec because
- * LD_LIBRARY_PATH is set acceptably and the data model does not need
- * to be changed, ParseArguments will screen out the redundant -d
- * options and prevent them from being passed to the vm; this is done
- * by RemovableOption.
+ * CheckJvmType removes vm style options and TranslateApplicationArgs
+ * removes "-J" prefixes.  The CreateExecutionEnvironment function processes
+ * and removes -d options. On unix, there is a possibility that the running
+ * data model may not match to the desired data model, in this case an exec is
+ * required to start the desired model. If the data models match, then
+ * ParseArguments will remove the -d flags. If the data models do not match
+ * the CreateExecutionEnviroment will remove the -d flags.
  */
 
 
@@ -1891,11 +1889,11 @@ DumpState()
  * Return JNI_TRUE for an option string that has no effect but should
  * _not_ be passed on to the vm; return JNI_FALSE otherwise.  On
  * Solaris SPARC, this screening needs to be done if:
- * 1) LD_LIBRARY_PATH does _not_ need to be reset and
- * 2) -d32 or -d64 is passed to a binary with a matching data model
- *    (the exec in SetLibraryPath removes -d options and points the
- *    exec to the proper binary).  When this exec is not done, these options
- *    would end up getting passed onto the vm.
+ *    -d32 or -d64 is passed to a binary with an unmatched data model
+ *    (the exec in CreateExecutionEnvironment removes -d options and points the
+ *    exec to the proper binary).  In the case of when the data model and the
+ *    requested version is matched, an exec would not occur, and these options
+ *    were erroneously passed to the vm.
  */
 jboolean
 RemovableOption(char * option)
diff --git a/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java b/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java
index 09b5701a95e2c86b9841421881e38a2c4d143453..a841e992b4a200dee0625d0c39cf04b4c8473f8e 100644
--- a/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java
+++ b/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java
@@ -26,6 +26,7 @@
 package com.sun.jmx.mbeanserver;
 
 import java.lang.annotation.Annotation;
+import java.lang.ref.SoftReference;
 import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
@@ -33,8 +34,13 @@ import java.lang.reflect.Modifier;
 import java.lang.reflect.Proxy;
 import java.lang.reflect.UndeclaredThrowableException;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Locale;
 import java.util.Map;
+import java.util.WeakHashMap;
 
 import javax.management.Descriptor;
 import javax.management.DescriptorKey;
@@ -506,11 +512,25 @@ public class Introspector {
             } 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);
+                Class clazz = complex.getClass();
+                Method readMethod = null;
+                if (BeansHelper.isAvailable()) {
+                    Object bi = BeansHelper.getBeanInfo(clazz);
+                    Object[] pds = BeansHelper.getPropertyDescriptors(bi);
+                    for (Object pd: pds) {
+                        if (BeansHelper.getPropertyName(pd).equals(element)) {
+                            readMethod = BeansHelper.getReadMethod(pd);
+                            break;
+                        }
+                    }
+                } else {
+                    // Java Beans not available so use simple introspection
+                    // to locate method
+                    readMethod = SimpleIntrospector.getReadMethod(clazz, element);
+                }
+                if (readMethod != null)
+                    return readMethod.invoke(complex);
+
                 throw new AttributeNotFoundException(
                     "Could not find the getter method for the property " +
                     element + " using the Java Beans introspector");
@@ -524,4 +544,235 @@ public class Introspector {
                 new AttributeNotFoundException(e.getMessage()), e);
         }
     }
+
+    /**
+     * A simple introspector that uses reflection to analyze a class and
+     * identify its "getter" methods. This class is intended for use only when
+     * Java Beans is not present (which implies that there isn't explicit
+     * information about the bean available).
+     */
+    private static class SimpleIntrospector {
+        private SimpleIntrospector() { }
+
+        private static final String GET_METHOD_PREFIX = "get";
+        private static final String IS_METHOD_PREFIX = "is";
+
+        // cache to avoid repeated lookups
+        private static final Map,SoftReference>> cache =
+            Collections.synchronizedMap(
+                new WeakHashMap,SoftReference>> ());
+
+        /**
+         * Returns the list of methods cached for the given class, or {@code null}
+         * if not cached.
+         */
+        private static List getCachedMethods(Class clazz) {
+            // return cached methods if possible
+            SoftReference> ref = cache.get(clazz);
+            if (ref != null) {
+                List cached = ref.get();
+                if (cached != null)
+                    return cached;
+            }
+            return null;
+        }
+
+        /**
+         * Returns {@code true} if the given method is a "getter" method (where
+         * "getter" method is a public method of the form getXXX or "boolean
+         * isXXX")
+         */
+        static boolean isReadMethod(Method method) {
+            // ignore static methods
+            int modifiers = method.getModifiers();
+            if (Modifier.isStatic(modifiers))
+                return false;
+
+            String name = method.getName();
+            Class[] paramTypes = method.getParameterTypes();
+            int paramCount = paramTypes.length;
+
+            if (paramCount == 0 && name.length() > 2) {
+                // boolean isXXX()
+                if (name.startsWith(IS_METHOD_PREFIX))
+                    return (method.getReturnType() == boolean.class);
+                // getXXX()
+                if (name.length() > 3 && name.startsWith(GET_METHOD_PREFIX))
+                    return (method.getReturnType() != void.class);
+            }
+            return false;
+        }
+
+        /**
+         * Returns the list of "getter" methods for the given class. The list
+         * is ordered so that isXXX methods appear before getXXX methods - this
+         * is for compatability with the JavaBeans Introspector.
+         */
+        static List getReadMethods(Class clazz) {
+            // return cached result if available
+            List cachedResult = getCachedMethods(clazz);
+            if (cachedResult != null)
+                return cachedResult;
+
+            // get list of public methods, filtering out methods that have
+            // been overridden to return a more specific type.
+            List methods =
+                StandardMBeanIntrospector.getInstance().getMethods(clazz);
+            methods = MBeanAnalyzer.eliminateCovariantMethods(methods);
+
+            // filter out the non-getter methods
+            List result = new LinkedList();
+            for (Method m: methods) {
+                if (isReadMethod(m)) {
+                    // favor isXXX over getXXX
+                    if (m.getName().startsWith(IS_METHOD_PREFIX)) {
+                        result.add(0, m);
+                    } else {
+                        result.add(m);
+                    }
+                }
+            }
+
+            // add result to cache
+            cache.put(clazz, new SoftReference>(result));
+
+            return result;
+        }
+
+        /**
+         * Returns the "getter" to read the given property from the given class or
+         * {@code null} if no method is found.
+         */
+        static Method getReadMethod(Class clazz, String property) {
+            // first character in uppercase (compatability with JavaBeans)
+            property = property.substring(0, 1).toUpperCase(Locale.ENGLISH) +
+                property.substring(1);
+            String getMethod = GET_METHOD_PREFIX + property;
+            String isMethod = IS_METHOD_PREFIX + property;
+            for (Method m: getReadMethods(clazz)) {
+                String name = m.getName();
+                if (name.equals(isMethod) || name.equals(getMethod)) {
+                    return m;
+                }
+            }
+            return null;
+        }
+    }
+
+    /**
+     * A class that provides access to the JavaBeans Introspector and
+     * PropertyDescriptors without creating a static dependency on java.beans.
+     */
+    private static class BeansHelper {
+        private static final Class introspectorClass =
+            getClass("java.beans.Introspector");
+        private static final Class beanInfoClass =
+            (introspectorClass == null) ? null : getClass("java.beans.BeanInfo");
+        private static final Class getPropertyDescriptorClass =
+            (beanInfoClass == null) ? null : getClass("java.beans.PropertyDescriptor");
+
+        private static final Method getBeanInfo =
+            getMethod(introspectorClass, "getBeanInfo", Class.class);
+        private static final Method getPropertyDescriptors =
+            getMethod(beanInfoClass, "getPropertyDescriptors");
+        private static final Method getPropertyName =
+            getMethod(getPropertyDescriptorClass, "getName");
+        private static final Method getReadMethod =
+            getMethod(getPropertyDescriptorClass, "getReadMethod");
+
+        private static Class getClass(String name) {
+            try {
+                return Class.forName(name, true, null);
+            } catch (ClassNotFoundException e) {
+                return null;
+            }
+        }
+        private static Method getMethod(Class clazz,
+                                        String name,
+                                        Class... paramTypes)
+        {
+            if (clazz != null) {
+                try {
+                    return clazz.getMethod(name, paramTypes);
+                } catch (NoSuchMethodException e) {
+                    throw new AssertionError(e);
+                }
+            } else {
+                return null;
+            }
+        }
+
+        private BeansHelper() { }
+
+        /**
+         * Returns {@code true} if java.beans is available.
+         */
+        static boolean isAvailable() {
+            return introspectorClass != null;
+        }
+
+        /**
+         * Invokes java.beans.Introspector.getBeanInfo(Class)
+         */
+        static Object getBeanInfo(Class clazz) throws Exception {
+            try {
+                return getBeanInfo.invoke(null, clazz);
+            } catch (InvocationTargetException e) {
+                Throwable cause = e.getCause();
+                if (cause instanceof Exception)
+                    throw (Exception)cause;
+                throw new AssertionError(e);
+            } catch (IllegalAccessException iae) {
+                throw new AssertionError(iae);
+            }
+        }
+
+        /**
+         * Invokes java.beans.BeanInfo.getPropertyDescriptors()
+         */
+        static Object[] getPropertyDescriptors(Object bi) {
+            try {
+                return (Object[])getPropertyDescriptors.invoke(bi);
+            } catch (InvocationTargetException e) {
+                Throwable cause = e.getCause();
+                if (cause instanceof RuntimeException)
+                    throw (RuntimeException)cause;
+                throw new AssertionError(e);
+            } catch (IllegalAccessException iae) {
+                throw new AssertionError(iae);
+            }
+        }
+
+        /**
+         * Invokes java.beans.PropertyDescriptor.getName()
+         */
+        static String getPropertyName(Object pd) {
+            try {
+                return (String)getPropertyName.invoke(pd);
+            } catch (InvocationTargetException e) {
+                Throwable cause = e.getCause();
+                if (cause instanceof RuntimeException)
+                    throw (RuntimeException)cause;
+                throw new AssertionError(e);
+            } catch (IllegalAccessException iae) {
+                throw new AssertionError(iae);
+            }
+        }
+
+        /**
+         * Invokes java.beans.PropertyDescriptor.getReadMethod()
+         */
+        static Method getReadMethod(Object pd) {
+            try {
+                return (Method)getReadMethod.invoke(pd);
+            } catch (InvocationTargetException e) {
+                Throwable cause = e.getCause();
+                if (cause instanceof RuntimeException)
+                    throw (RuntimeException)cause;
+                throw new AssertionError(e);
+            } catch (IllegalAccessException iae) {
+                throw new AssertionError(iae);
+            }
+        }
+    }
 }
diff --git a/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java b/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java
index 9edde66faf2216b0d3f6a75341a63dc1a6f8588e..17f31d16a9e80f25188e5b57e7424dc7f5fd72a9 100644
--- a/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java
+++ b/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java
@@ -175,7 +175,7 @@ abstract class MBeanIntrospector {
     /**
      * Get the methods to be analyzed to build the MBean interface.
      */
-    List getMethods(final Class mbeanType) throws Exception {
+    List getMethods(final Class mbeanType) {
         return Arrays.asList(mbeanType.getMethods());
     }
 
diff --git a/src/share/classes/com/sun/security/jgss/ExtendedGSSContext.java b/src/share/classes/com/sun/security/jgss/ExtendedGSSContext.java
index dc7a3556d7d82154a84cdaeee55cc1f0dce1cd81..1ac610d8880dd209190fdee16527470d640decf2 100644
--- a/src/share/classes/com/sun/security/jgss/ExtendedGSSContext.java
+++ b/src/share/classes/com/sun/security/jgss/ExtendedGSSContext.java
@@ -99,4 +99,58 @@ public interface ExtendedGSSContext extends GSSContext {
      */
     public Object inquireSecContext(InquireType type)
             throws GSSException;
+
+    /**
+     * Requests that the delegation policy be respected. When a true value is
+     * requested, the underlying context would use the delegation policy
+     * defined by the environment as a hint to determine whether credentials
+     * delegation should be performed. This request can only be made on the
+     * context initiator's side and it has to be done prior to the first
+     * call to initSecContext.
+     * 

+ * When this flag is false, delegation will only be tried when the + * {@link GSSContext#requestCredDeleg(boolean) credentials delegation flag} + * is true. + *

+ * When this flag is true but the + * {@link GSSContext#requestCredDeleg(boolean) credentials delegation flag} + * is false, delegation will be only tried if the delegation policy permits + * delegation. + *

+ * When both this flag and the + * {@link GSSContext#requestCredDeleg(boolean) credentials delegation flag} + * are true, delegation will be always tried. However, if the delegation + * policy does not permit delegation, the value of + * {@link #getDelegPolicyState} will be false, even + * if delegation is performed successfully. + *

+ * In any case, if the delegation is not successful, the value returned + * by {@link GSSContext#getCredDelegState()} is false, and the value + * returned by {@link #getDelegPolicyState()} is also false. + *

+ * Not all mechanisms support delegation policy. Therefore, the + * application should check to see if the request was honored with the + * {@link #getDelegPolicyState() getDelegPolicyState} method. When + * delegation policy is not supported, requestDelegPolicy + * should return silently without throwing an exception. + *

+ * Note: for the Kerberos 5 mechanism, the delegation policy is expressed + * through the OK-AS-DELEGATE flag in the service ticket. When it's true, + * the KDC permits delegation to the target server. In a cross-realm + * environment, in order for delegation be permitted, all cross-realm TGTs + * on the authentication path must also have the OK-AS-DELAGATE flags set. + * @param state true if the policy should be respected + * @throws GSSException containing the following + * major error codes: + * {@link GSSException#FAILURE GSSException.FAILURE} + */ + public void requestDelegPolicy(boolean state) throws GSSException; + + /** + * Returns the delegation policy response. Called after a security context + * is established. This method can be only called on the initiator's side. + * See {@link ExtendedGSSContext#requestDelegPolicy}. + * @return the delegation policy response + */ + public boolean getDelegPolicyState(); } diff --git a/src/share/classes/com/sun/tools/hat/internal/model/JavaStatic.java b/src/share/classes/com/sun/tools/hat/internal/model/JavaStatic.java index 36f4e0e228dd31d29097246ec14edc2760ca5442..86064914ea64d71cc295b039567ed089694bac43 100644 --- a/src/share/classes/com/sun/tools/hat/internal/model/JavaStatic.java +++ b/src/share/classes/com/sun/tools/hat/internal/model/JavaStatic.java @@ -57,7 +57,10 @@ public class JavaStatic { id = ((JavaObjectRef)value).getId(); } value = value.dereference(snapshot, field); - if (value.isHeapAllocated()) { + if (value.isHeapAllocated() && + clazz.getLoader() == snapshot.getNullThing()) { + // static fields are only roots if they are in classes + // loaded by the root classloader. JavaHeapObject ho = (JavaHeapObject) value; String s = "Static reference from " + clazz.getName() + "." + field.getName(); diff --git a/src/share/classes/com/sun/tracing/ProviderFactory.java b/src/share/classes/com/sun/tracing/ProviderFactory.java index 768a6bebb8df931f8aa34da6463f5c3336c8ea30..1a4f064ff51528f4d0ba5a14bd50f32640719d7c 100644 --- a/src/share/classes/com/sun/tracing/ProviderFactory.java +++ b/src/share/classes/com/sun/tracing/ProviderFactory.java @@ -4,7 +4,10 @@ package com.sun.tracing; import java.util.HashSet; import java.io.PrintStream; import java.lang.reflect.Field; -import java.util.logging.Logger; +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import sun.security.action.GetPropertyAction; import sun.tracing.NullProviderFactory; import sun.tracing.PrintStreamProviderFactory; @@ -52,23 +55,17 @@ public abstract class ProviderFactory { HashSet factories = new HashSet(); // Try to instantiate a DTraceProviderFactory - String prop = null; - try { prop = System.getProperty("com.sun.tracing.dtrace"); } - catch (java.security.AccessControlException e) { - Logger.getAnonymousLogger().fine( - "Cannot access property com.sun.tracing.dtrace"); - } + String prop = AccessController.doPrivileged( + new GetPropertyAction("com.sun.tracing.dtrace")); + if ( (prop == null || !prop.equals("disable")) && DTraceProviderFactory.isSupported() ) { factories.add(new DTraceProviderFactory()); } // Try to instantiate an output stream factory - try { prop = System.getProperty("sun.tracing.stream"); } - catch (java.security.AccessControlException e) { - Logger.getAnonymousLogger().fine( - "Cannot access property sun.tracing.stream"); - } + prop = AccessController.doPrivileged( + new GetPropertyAction("sun.tracing.stream")); if (prop != null) { for (String spec : prop.split(",")) { PrintStream ps = getPrintStreamFromSpec(spec); @@ -89,22 +86,29 @@ public abstract class ProviderFactory { } } - private static PrintStream getPrintStreamFromSpec(String spec) { + private static PrintStream getPrintStreamFromSpec(final String spec) { try { // spec is in the form of ., where is // a fully specified class name, and is a static member // in that class. The must be a 'PrintStream' or subtype // in order to be used. - int fieldpos = spec.lastIndexOf('.'); - Class cls = Class.forName(spec.substring(0, fieldpos)); - Field f = cls.getField(spec.substring(fieldpos + 1)); - Class fieldType = f.getType(); + final int fieldpos = spec.lastIndexOf('.'); + final Class cls = Class.forName(spec.substring(0, fieldpos)); + + Field f = AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Field run() throws NoSuchFieldException { + return cls.getField(spec.substring(fieldpos + 1)); + } + }); + return (PrintStream)f.get(null); - } catch (Exception e) { - Logger.getAnonymousLogger().warning( - "Could not parse sun.tracing.stream property: " + e); + } catch (ClassNotFoundException e) { + throw new AssertionError(e); + } catch (IllegalAccessException e) { + throw new AssertionError(e); + } catch (PrivilegedActionException e) { + throw new AssertionError(e); } - return null; } } diff --git a/src/share/classes/java/applet/Applet.java b/src/share/classes/java/applet/Applet.java index 0e2bcb87b566dd5861b1aa50e8bea736d7f08733..b12e6fb308174793c50826a3f912cd1c185b4662 100644 --- a/src/share/classes/java/applet/Applet.java +++ b/src/share/classes/java/applet/Applet.java @@ -229,6 +229,21 @@ public class Applet extends Panel { resize(d.width, d.height); } + /** + * Indicates if this container is a validate root. + *

+ * {@code Applet} objects are the validate roots, and, therefore, they + * override this method to return {@code true}. + * + * @return {@code true} + * @since 1.7 + * @see java.awt.Container#isValidateRoot + */ + @Override + public boolean isValidateRoot() { + return true; + } + /** * Requests that the argument string be displayed in the * "status window". Many browsers and applet viewers diff --git a/src/share/classes/java/awt/AWTPermission.java b/src/share/classes/java/awt/AWTPermission.java index b6eb03f62c7225c3631ee33d41c97930c7acbcb6..84b400f53d9e80386394a0cdb309ad1845747cc7 100644 --- a/src/share/classes/java/awt/AWTPermission.java +++ b/src/share/classes/java/awt/AWTPermission.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 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,7 +92,15 @@ import java.security.BasicPermission; * Enter full-screen exclusive mode * Entering full-screen exclusive mode allows direct access to * low-level graphics card memory. This could be used to spoof the - * system, since the program is in direct control of rendering. + * system, since the program is in direct control of rendering. Depending on + * the implementation, the security warning may not be shown for the windows + * used to enter the full-screen exclusive mode (assuming that the {@code + * fullScreenExclusive} permission has been granted to this application). Note + * that this behavior does not mean that the {@code + * showWindowWithoutWarningBanner} permission will be automatically granted to + * the application which has the {@code fullScreenExclusive} permission: + * non-full-screen windows will continue to be shown with the security + * warning. * * * diff --git a/src/share/classes/java/awt/Component.java b/src/share/classes/java/awt/Component.java index e9c274fcb42b72c22f7aad06a6b7e7095b7fc54c..6a942e9ec5dd8adadcd6afa202cdd7564c0b0aa4 100644 --- a/src/share/classes/java/awt/Component.java +++ b/src/share/classes/java/awt/Component.java @@ -2764,8 +2764,11 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * Ensures that this component has a valid layout. This method is - * primarily intended to operate on instances of Container. + * Validates this component. + *

+ * The meaning of the term validating is defined by the ancestors of + * this class. See {@link Container#validate} for more details. + * * @see #invalidate * @see #doLayout() * @see LayoutManager @@ -2794,12 +2797,24 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * Invalidates this component. This component and all parents - * above it are marked as needing to be laid out. This method can - * be called often, so it needs to execute quickly. + * Invalidates this component and its ancestors. + *

+ * All the ancestors of this component up to the nearest validate root are + * marked invalid also. If there is no a validate root container for this + * component, all of its ancestors up to the root of the hierarchy are + * marked invalid as well. Marking a container invalid indicates + * that the container needs to be laid out. + *

+ * This method is called automatically when any layout-related information + * changes (e.g. setting the bounds of the component, or adding the + * component to a container). + *

+ * This method might be called often, so it should work fast. + * * @see #validate * @see #doLayout * @see LayoutManager + * @see java.awt.Container#isValidateRoot * @since JDK1.0 */ public void invalidate() { @@ -2818,9 +2833,18 @@ public abstract class Component implements ImageObserver, MenuContainer, if (!isMaximumSizeSet()) { maxSize = null; } - if (parent != null) { - parent.invalidateIfValid(); - } + invalidateParent(); + } + } + + /** + * Invalidates the parent of this component if any. + * + * This method MUST BE invoked under the TreeLock. + */ + void invalidateParent() { + if (parent != null) { + parent.invalidateIfValid(); } } @@ -6727,12 +6751,13 @@ public abstract class Component implements ImageObserver, MenuContainer, } } } else { - // It's native. If the parent is lightweight it - // will need some help. - Container parent = this.parent; - if (parent != null && parent.peer instanceof LightweightPeer) { + // It's native. If the parent is lightweight it will need some + // help. + Container parent = getContainer(); + if (parent != null && parent.isLightweight()) { relocateComponent(); - if (!isRecursivelyVisible()) { + if (!parent.isRecursivelyVisibleUpToHeavyweightContainer()) + { peer.setVisible(false); } } diff --git a/src/share/classes/java/awt/Container.java b/src/share/classes/java/awt/Container.java index 010d8b08ac30cf13a12e58586bad1238a64dc14c..94273ade4cb74adbbccc24fedbac5a45ab5b3529 100644 --- a/src/share/classes/java/awt/Container.java +++ b/src/share/classes/java/awt/Container.java @@ -1492,20 +1492,59 @@ public class Container extends Component { } /** - * Invalidates the container. The container and all parents - * above it are marked as needing to be laid out. This method can - * be called often, so it needs to execute quickly. + * Indicates if this container is a validate root. + *

+ * Layout-related changes, such as bounds of the validate root descendants, + * do not affect the layout of the validate root parent. This peculiarity + * enables the {@code invalidate()} method to stop invalidating the + * component hierarchy when the method encounters a validate root. + *

+ * If a component hierarchy contains validate roots, the {@code validate()} + * method must be invoked on the validate root of a previously invalidated + * component, rather than on the top-level container (such as a {@code + * Frame} object) to restore the validity of the hierarchy later. + *

+ * The {@code Window} class and the {@code Applet} class are the validate + * roots in AWT. Swing introduces more validate roots. * - *

If the {@code LayoutManager} installed on this container is - * an instance of {@code LayoutManager2}, then - * {@link LayoutManager2#invalidateLayout(Container)} is invoked on - * it supplying this {@code Container} as the argument. + * @return whether this container is a validate root + * @see #invalidate + * @see java.awt.Component#invalidate + * @see javax.swing.JComponent#isValidateRoot + * @see javax.swing.JComponent#revalidate + * @since 1.7 + */ + public boolean isValidateRoot() { + return false; + } + + /** + * Invalidates the parent of the container unless the container + * is a validate root. + */ + @Override + void invalidateParent() { + if (!isValidateRoot()) { + super.invalidateParent(); + } + } + + /** + * Invalidates the container. + *

+ * If the {@code LayoutManager} installed on this container is an instance + * of the {@code LayoutManager2} interface, then + * the {@link LayoutManager2#invalidateLayout(Container)} method is invoked + * on it supplying this {@code Container} as the argument. + *

+ * Afterwards this method marks this container invalid, and invalidates its + * ancestors. See the {@link Component#invalidate} method for more details. * * @see #validate * @see #layout - * @see LayoutManager - * @see LayoutManager2#invalidateLayout(Container) + * @see LayoutManager2 */ + @Override public void invalidate() { LayoutManager layoutMgr = this.layoutMgr; if (layoutMgr instanceof LayoutManager2) { @@ -1518,52 +1557,90 @@ public class Container extends Component { /** * Validates this container and all of its subcomponents. *

- * The validate method is used to cause a container - * to lay out its subcomponents again. It should be invoked when - * this container's subcomponents are modified (added to or - * removed from the container, or layout-related information - * changed) after the container has been displayed. - * - *

If this {@code Container} is not valid, this method invokes + * Validating a container means laying out its subcomponents. + * Layout-related changes, such as setting the bounds of a component, or + * adding a component to the container, invalidate the container + * automatically. Note that the ancestors of the container may be + * invalidated also (see {@link Component#invalidate} for details.) + * Therefore, to restore the validity of the hierarchy, the {@code + * validate()} method should be invoked on a validate root of an + * invalidated component, or on the top-most container if the hierarchy + * does not contain validate roots. + *

+ * Validating the container may be a quite time-consuming operation. For + * performance reasons a developer may postpone the validation of the + * hierarchy till a set of layout-related operations completes, e.g. after + * adding all the children to the container. + *

+ * If this {@code Container} is not valid, this method invokes * the {@code validateTree} method and marks this {@code Container} * as valid. Otherwise, no action is performed. - *

- * Note that the {@code invalidate()} method may invalidate not only the - * component it is called upon, but also the parents of the component. - * Therefore, to restore the validity of the hierarchy, the {@code - * validate()} method must be invoked on the top-most invalid container of - * the hierarchy. For performance reasons a developer may postpone the - * validation of the hierarchy till a bunch of layout-related operations - * completes, e.g. after adding all the children to the container. * * @see #add(java.awt.Component) * @see #invalidate + * @see Container#isValidateRoot * @see javax.swing.JComponent#revalidate() * @see #validateTree */ public void validate() { - /* Avoid grabbing lock unless really necessary. */ - if (!isValid()) { - boolean updateCur = false; - synchronized (getTreeLock()) { - if (!isValid() && peer != null) { - ContainerPeer p = null; - if (peer instanceof ContainerPeer) { - p = (ContainerPeer) peer; - } - if (p != null) { - p.beginValidate(); - } - validateTree(); - if (p != null) { - p.endValidate(); + boolean updateCur = false; + synchronized (getTreeLock()) { + if ((!isValid() || descendUnconditionallyWhenValidating) + && peer != null) + { + ContainerPeer p = null; + if (peer instanceof ContainerPeer) { + p = (ContainerPeer) peer; + } + if (p != null) { + p.beginValidate(); + } + validateTree(); + if (p != null) { + p.endValidate(); + // Avoid updating cursor if this is an internal call. + // See validateUnconditionally() for details. + if (!descendUnconditionallyWhenValidating) { updateCur = isVisible(); } } } - if (updateCur) { - updateCursorImmediately(); + } + if (updateCur) { + updateCursorImmediately(); + } + } + + /** + * Indicates whether valid containers should also traverse their + * children and call the validateTree() method on them. + * + * Synchronization: TreeLock. + * + * The field is allowed to be static as long as the TreeLock itself is + * static. + * + * @see #validateUnconditionally() + */ + private static boolean descendUnconditionallyWhenValidating = false; + + /** + * Unconditionally validate the component hierarchy. + */ + final void validateUnconditionally() { + boolean updateCur = false; + synchronized (getTreeLock()) { + descendUnconditionallyWhenValidating = true; + + validate(); + if (peer instanceof ContainerPeer) { + updateCur = isVisible(); } + + descendUnconditionallyWhenValidating = false; + } + if (updateCur) { + updateCursorImmediately(); } } @@ -1578,16 +1655,20 @@ public class Container extends Component { */ protected void validateTree() { checkTreeLock(); - if (!isValid()) { + if (!isValid() || descendUnconditionallyWhenValidating) { if (peer instanceof ContainerPeer) { ((ContainerPeer)peer).beginLayout(); } - doLayout(); + if (!isValid()) { + doLayout(); + } for (int i = 0; i < component.size(); i++) { Component comp = component.get(i); if ( (comp instanceof Container) && !(comp instanceof Window) - && !comp.isValid()) { + && (!comp.isValid() || + descendUnconditionallyWhenValidating)) + { ((Container)comp).validateTree(); } else { comp.validate(); @@ -4092,16 +4173,29 @@ public class Container extends Component { } } - /* + /** + * Checks if the container and its direct lightweight containers are + * visible. + * * Consider the heavyweight container hides or shows the HW descendants * automatically. Therefore we care of LW containers' visibility only. + * + * This method MUST be invoked under the TreeLock. */ - private boolean isRecursivelyVisibleUpToHeavyweightContainer() { + final boolean isRecursivelyVisibleUpToHeavyweightContainer() { if (!isLightweight()) { return true; } - return isVisible() && (getContainer() == null || - getContainer().isRecursivelyVisibleUpToHeavyweightContainer()); + + for (Container cont = getContainer(); + cont != null && cont.isLightweight(); + cont = cont.getContainer()) + { + if (!cont.isVisible()) { + return false; + } + } + return true; } @Override diff --git a/src/share/classes/java/awt/EventQueue.java b/src/share/classes/java/awt/EventQueue.java index 3e9febf79b742b90559cf251b82ec2f6a5044e14..b5635f4a25cb1c877847275680dc408f6ddf10f3 100644 --- a/src/share/classes/java/awt/EventQueue.java +++ b/src/share/classes/java/awt/EventQueue.java @@ -1027,7 +1027,9 @@ public class EventQueue { synchronized (lock) { Toolkit.getEventQueue().postEvent(event); - lock.wait(); + while (!event.isDispatched()) { + lock.wait(); + } } Throwable eventThrowable = event.getThrowable(); diff --git a/src/share/classes/java/awt/Frame.java b/src/share/classes/java/awt/Frame.java index 761b9b8420b306ced2de70dbe0d7d0969e63fa73..ea8c6154cf1e77f5c59d1203258ea30172388aab 100644 --- a/src/share/classes/java/awt/Frame.java +++ b/src/share/classes/java/awt/Frame.java @@ -845,8 +845,11 @@ public class Frame extends Window implements MenuContainer { * others by setting those fields you want to accept from system * to Integer.MAX_VALUE. *

- * On some systems only the size portion of the bounds is taken - * into account. + * Note, the given maximized bounds are used as a hint for the native + * system, because the underlying platform may not support setting the + * location and/or size of the maximized windows. If that is the case, the + * provided values do not affect the appearance of the frame in the + * maximized state. * * @param bounds bounds for the maximized state * @see #getMaximizedBounds() diff --git a/src/share/classes/java/awt/Window.java b/src/share/classes/java/awt/Window.java index 8ea9ec821d8d5396faf3f54776edc99f79ff9d40..c039a717984842dbf5d3acc7a9f69f6b4b9a16a8 100644 --- a/src/share/classes/java/awt/Window.java +++ b/src/share/classes/java/awt/Window.java @@ -767,7 +767,7 @@ public class Window extends Container implements Accessible { isPacked = true; } - validate(); + validateUnconditionally(); } /** @@ -943,7 +943,7 @@ public class Window extends Container implements Accessible { if (peer == null) { addNotify(); } - validate(); + validateUnconditionally(); isInShow = true; if (visible) { @@ -2599,6 +2599,21 @@ public class Window extends Container implements Accessible { super.addPropertyChangeListener(propertyName, listener); } + /** + * Indicates if this container is a validate root. + *

+ * {@code Window} objects are the validate roots, and, therefore, they + * override this method to return {@code true}. + * + * @return {@code true} + * @since 1.7 + * @see java.awt.Container#isValidateRoot + */ + @Override + public boolean isValidateRoot() { + return true; + } + /** * Dispatches an event to this window or one of its sub components. * @param e the event diff --git a/src/share/classes/java/awt/datatransfer/DataFlavor.java b/src/share/classes/java/awt/datatransfer/DataFlavor.java index 0e559e5d3596fa9a3c733fb8dc2f2f3b877afbe4..36378882e1520684522d73fe41e2cf36dee79ef6 100644 --- a/src/share/classes/java/awt/datatransfer/DataFlavor.java +++ b/src/share/classes/java/awt/datatransfer/DataFlavor.java @@ -1184,7 +1184,7 @@ public class DataFlavor implements Externalizable, Cloneable { */ public boolean isRepresentationClassRemote() { - return java.rmi.Remote.class.isAssignableFrom(representationClass); + return DataTransferer.isRemote(representationClass); } /** diff --git a/src/share/classes/java/awt/event/InvocationEvent.java b/src/share/classes/java/awt/event/InvocationEvent.java index 0959a86cb3539e0999bb94ab0d8d200fc06169af..e21adf352bb9e3e6e055af81acbed394cc76b0a3 100644 --- a/src/share/classes/java/awt/event/InvocationEvent.java +++ b/src/share/classes/java/awt/event/InvocationEvent.java @@ -78,10 +78,21 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent { /** * The (potentially null) Object whose notifyAll() method will be called - * immediately after the Runnable.run() method returns. + * immediately after the Runnable.run() method has returned or thrown an exception. + * + * @see #isDispatched */ protected Object notifier; + /** + * Indicates whether the run() method of the runnable + * was executed or not. + * + * @see #isDispatched + * @since 1.7 + */ + private volatile boolean dispatched = false; + /** * Set to true if dispatch() catches Throwable and stores it in the * exception instance variable. If false, Throwables are propagated up @@ -144,7 +155,7 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent { * source which will execute the runnable's run * method when dispatched. If notifier is non-null, * notifyAll() will be called on it - * immediately after run returns. + * immediately after run has returned or thrown an exception. *

An invocation of the form InvocationEvent(source, * runnable, notifier, catchThrowables) * behaves in exactly the same way as the invocation of @@ -159,7 +170,8 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent { * executed * @param notifier The {@code Object} whose notifyAll * method will be called after - * Runnable.run has returned + * Runnable.run has returned or + * thrown an exception * @param catchThrowables Specifies whether dispatch * should catch Throwable when executing * the Runnable's run @@ -180,8 +192,8 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent { * Constructs an InvocationEvent with the specified * source and ID which will execute the runnable's run * method when dispatched. If notifier is non-null, - * notifyAll will be called on it - * immediately after run returns. + * notifyAll will be called on it immediately after + * run has returned or thrown an exception. *

This method throws an * IllegalArgumentException if source * is null. @@ -195,7 +207,8 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent { * run method will be executed * @param notifier The Object whose notifyAll * method will be called after - * Runnable.run has returned + * Runnable.run has returned or + * thrown an exception * @param catchThrowables Specifies whether dispatch * should catch Throwable when executing the * Runnable's run @@ -217,27 +230,33 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent { /** * Executes the Runnable's run() method and notifies the - * notifier (if any) when run() returns. + * notifier (if any) when run() has returned or thrown an exception. + * + * @see #isDispatched */ public void dispatch() { - if (catchExceptions) { - try { - runnable.run(); - } - catch (Throwable t) { - if (t instanceof Exception) { - exception = (Exception) t; + try { + if (catchExceptions) { + try { + runnable.run(); + } + catch (Throwable t) { + if (t instanceof Exception) { + exception = (Exception) t; + } + throwable = t; } - throwable = t; } - } - else { - runnable.run(); - } + else { + runnable.run(); + } + } finally { + dispatched = true; - if (notifier != null) { - synchronized (notifier) { - notifier.notifyAll(); + if (notifier != null) { + synchronized (notifier) { + notifier.notifyAll(); + } } } } @@ -277,6 +296,40 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent { return when; } + /** + * Returns {@code true} if the event is dispatched or any exception is + * thrown while dispatching, {@code false} otherwise. The method should + * be called by a waiting thread that calls the {@code notifier.wait()} method. + * Since spurious wakeups are possible (as explained in {@link Object#wait()}), + * this method should be used in a waiting loop to ensure that the event + * got dispatched: + *

+     *     while (!event.isDispatched()) {
+     *         notifier.wait();
+     *     }
+     * 
+ * If the waiting thread wakes up without dispatching the event, + * the {@code isDispatched()} method returns {@code false}, and + * the {@code while} loop executes once more, thus, causing + * the awakened thread to revert to the waiting mode. + *

+ * If the {@code notifier.notifyAll()} happens before the waiting thread + * enters the {@code notifier.wait()} method, the {@code while} loop ensures + * that the waiting thread will not enter the {@code notifier.wait()} method. + * Otherwise, there is no guarantee that the waiting thread will ever be woken + * from the wait. + * + * @return {@code true} if the event has been dispatched, or any exception + * has been thrown while dispatching, {@code false} otherwise + * @see #dispatch + * @see #notifier + * @see #catchExceptions + * @since 1.7 + */ + public boolean isDispatched() { + return dispatched; + } + /** * Returns a parameter string identifying this event. * This method is useful for event-logging and for debugging. diff --git a/src/share/classes/java/awt/font/NumericShaper.java b/src/share/classes/java/awt/font/NumericShaper.java index a1ffbf0b7c3a435f2f8b7066f4da9c83c92ef801..435b60213f054ac1eaeddfe1e6f2a89d79df39e2 100644 --- a/src/share/classes/java/awt/font/NumericShaper.java +++ b/src/share/classes/java/awt/font/NumericShaper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2009 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,6 +25,13 @@ package java.awt.font; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.util.Arrays; +import java.util.Comparator; +import java.util.EnumSet; +import java.util.Set; + /** * The NumericShaper class is used to convert Latin-1 (European) * digits to other Unicode decimal digits. Users of this class will @@ -64,13 +71,261 @@ package java.awt.font; * NumericShaper.getContextualShaper(NumericShaper.ARABIC | * NumericShaper.TAMIL, * NumericShaper.EUROPEAN); - * shaper.shape(text. start, count); + * shaper.shape(text, start, count); + *

+ * + *

Bit mask- and enum-based Unicode ranges

+ * + *

This class supports two different programming interfaces to + * represent Unicode ranges for script-specific digits: bit + * mask-based ones, such as {@link #ARABIC NumericShaper.ARABIC}, and + * enum-based ones, such as {@link NumericShaper.Range#ARABIC}. + * Multiple ranges can be specified by ORing bit mask-based constants, + * such as: + *

+ * NumericShaper.ARABIC | NumericShaper.TAMIL
+ * 
+ * or creating a {@code Set} with the {@link NumericShaper.Range} + * constants, such as: + *
+ * EnumSet.of(NumericShaper.Scirpt.ARABIC, NumericShaper.Range.TAMIL)
  * 
+ * The enum-based ranges are a super set of the bit mask-based ones. + * + *

If the two interfaces are mixed (including serialization), + * Unicode range values are mapped to their counterparts where such + * mapping is possible, such as {@code NumericShaper.Range.ARABIC} + * from/to {@code NumericShaper.ARABIC}. If any unmappable range + * values are specified, such as {@code NumericShaper.Range.BALINESE}, + * those ranges are ignored. * * @since 1.4 */ public final class NumericShaper implements java.io.Serializable { + /** + * A {@code NumericShaper.Range} represents a Unicode range of a + * script having its own decimal digits. For example, the {@link + * NumericShaper.Range#THAI} range has the Thai digits, THAI DIGIT + * ZERO (U+0E50) to THAI DIGIT NINE (U+0E59). + * + *

The Range enum replaces the traditional bit + * mask-based values (e.g., {@link NumericShaper#ARABIC}), and + * supports more Unicode ranges than the bit mask-based ones. For + * example, the following code using the bit mask: + *

+     * NumericShaper.getContextualShaper(NumericShaper.ARABIC |
+     *                                     NumericShaper.TAMIL,
+     *                                   NumericShaper.EUROPEAN);
+     * 
+ * can be written using this enum as: + *
+     * NumericShaper.getContextualShaper(EnumSet.of(
+     *                                     NumericShaper.Range.ARABIC,
+     *                                     NumericShaper.Range.TAMIL),
+     *                                   NumericShaper.Range.EUROPEAN);
+     * 
+ * + * @since 1.7 + */ + public static enum Range { + /** + * The Latin (European) range with the Latin (ASCII) digits. + */ + EUROPEAN ('\u0030', '\u0000', '\u0300'), + /** + * The Arabic range with the Arabic-Indic digits. + */ + ARABIC ('\u0660', '\u0600', '\u0780'), + /** + * The Arabic range with the Eastern Arabic-Indic digits. + */ + EASTERN_ARABIC ('\u06f0', '\u0600', '\u0780'), + /** + * The Devanagari range with the Devanagari digits. + */ + DEVANAGARI ('\u0966', '\u0900', '\u0980'), + /** + * The Bengali range with the Bengali digits. + */ + BENGALI ('\u09e6', '\u0980', '\u0a00'), + /** + * The Gurmukhi range with the Gurmukhi digits. + */ + GURMUKHI ('\u0a66', '\u0a00', '\u0a80'), + /** + * The Gujarati range with the Gujarati digits. + */ + GUJARATI ('\u0ae6', '\u0b00', '\u0b80'), + /** + * The Oriya range with the Oriya digits. + */ + ORIYA ('\u0b66', '\u0b00', '\u0b80'), + /** + * The Tamil range with the Tamil digits. + */ + TAMIL ('\u0be6', '\u0b80', '\u0c00'), + /** + * The Telugu range with the Telugu digits. + */ + TELUGU ('\u0c66', '\u0c00', '\u0c80'), + /** + * The Kannada range with the Kannada digits. + */ + KANNADA ('\u0ce6', '\u0c80', '\u0d00'), + /** + * The Malayalam range with the Malayalam digits. + */ + MALAYALAM ('\u0d66', '\u0d00', '\u0d80'), + /** + * The Thai range with the Thai digits. + */ + THAI ('\u0e50', '\u0e00', '\u0e80'), + /** + * The Lao range with the Lao digits. + */ + LAO ('\u0ed0', '\u0e80', '\u0f00'), + /** + * The Tibetan range with the Tibetan digits. + */ + TIBETAN ('\u0f20', '\u0f00', '\u1000'), + /** + * The Myanmar range with the Myanmar digits. + */ + MYANMAR ('\u1040', '\u1000', '\u1080'), + /** + * The Ethiopic range with the Ethiopic digits. Ethiopic + * does not have a decimal digit 0 so Latin (European) 0 is + * used. + */ + ETHIOPIC ('\u1369', '\u1200', '\u1380') { + @Override + char getNumericBase() { return 1; } + }, + /** + * The Khmer range with the Khmer digits. + */ + KHMER ('\u17e0', '\u1780', '\u1800'), + /** + * The Mongolian range with the Mongolian digits. + */ + MONGOLIAN ('\u1810', '\u1800', '\u1900'), + /** + * The N'Ko range with the N'Ko digits. + */ + NKO ('\u07c0', '\u07c0', '\u0800'), + /** + * The Myanmar range with the Myanmar Shan digits. + */ + MYANMAR_SHAN ('\u1090', '\u1000', '\u10a0'), + /** + * The Limbu range with the Limbu digits. + */ + LIMBU ('\u1946', '\u1900', '\u1950'), + /** + * The New Tai Lue range with the New Tai Lue digits. + */ + NEW_TAI_LUE ('\u19d0', '\u1980', '\u19e0'), + /** + * The Balinese range with the Balinese digits. + */ + BALINESE ('\u1b50', '\u1b00', '\u1b80'), + /** + * The Sundanese range with the Sundanese digits. + */ + SUNDANESE ('\u1bb0', '\u1b80', '\u1bc0'), + /** + * The Lepcha range with the Lepcha digits. + */ + LEPCHA ('\u1c40', '\u1c00', '\u1c50'), + /** + * The Ol Chiki range with the Ol Chiki digits. + */ + OL_CHIKI ('\u1c50', '\u1c50', '\u1c80'), + /** + * The Vai range with the Vai digits. + */ + VAI ('\ua620', '\ua500', '\ua640'), + /** + * The Saurashtra range with the Saurashtra digits. + */ + SAURASHTRA ('\ua8d0', '\ua880', '\ua8e0'), + /** + * The Kayah Li range with the Kayah Li digits. + */ + KAYAH_LI ('\ua900', '\ua900', '\ua930'), + /** + * The Cham range with the Cham digits. + */ + CHAM ('\uaa50', '\uaa00', '\uaa60'); + + private static final Range[] ranges = Range.class.getEnumConstants(); + static { + // sort ranges[] by base for binary search + Arrays.sort(ranges, + new Comparator() { + public int compare(Range s1, Range s2) { + return s1.base > s2.base ? 1 : s1.base == s2.base ? 0 : -1; + } + }); + } + + private static int toRangeIndex(Range script) { + int index = script.ordinal(); + return index < NUM_KEYS ? index : -1; + } + + private static Range indexToRange(int index) { + return index < NUM_KEYS ? Range.values()[index] : null; + } + + private static int toRangeMask(Set ranges) { + int m = 0; + for (Range range : ranges) { + int index = range.ordinal(); + if (index < NUM_KEYS) { + m |= 1 << index; + } + } + return m; + } + + private static Set maskToRangeSet(int mask) { + Set set = EnumSet.noneOf(Range.class); + Range[] a = Range.values(); + for (int i = 0; i < NUM_KEYS; i++) { + if ((mask & (1 << i)) != 0) { + set.add(a[i]); + } + } + return set; + } + + // base character of range digits + private final int base; + // Unicode range + private final int start, // inclusive + end; // exclusive + + private Range(int base, int start, int end) { + this.base = base - ('0' + getNumericBase()); + this.start = start; + this.end = end; + } + + private int getDigitBase() { + return base; + } + + char getNumericBase() { + return 0; + } + + private boolean inRange(int c) { + return start <= c && c < end; + } + } + /** index of context for contextual shaping - values range from 0 to 18 */ private int key; @@ -79,6 +334,25 @@ public final class NumericShaper implements java.io.Serializable { */ private int mask; + /** + * The context {@code Range} for contextual shaping or the {@code + * Range} for non-contextual shaping. {@code null} for the bit + * mask-based API. + * + * @since 1.7 + */ + private Range shapingRange; + + /** + * {@code Set} indicating which Unicode ranges to + * shape. {@code null} for the bit mask-based API. + * + * @since 1.7 + */ + private transient Set rangeSet; + + private static final long serialVersionUID = -8022764705923730308L; + /** Identifies the Latin-1 (European) and extended range, and * Latin-1 (European) decimal base. */ @@ -105,9 +379,8 @@ public final class NumericShaper implements java.io.Serializable { /** Identifies the ORIYA range and decimal base. */ public static final int ORIYA = 1<<7; - /** Identifies the TAMIL range and decimal base. Tamil does not have a - * decimal digit 0 so Latin-1 (European) 0 is used. - */ + /** Identifies the TAMIL range and decimal base. */ + // TAMIL DIGIT ZERO was added in Unicode 4.1 public static final int TAMIL = 1<<8; /** Identifies the TELUGU range and decimal base. */ @@ -140,7 +413,12 @@ public final class NumericShaper implements java.io.Serializable { /** Identifies the MONGOLIAN range and decimal base. */ public static final int MONGOLIAN = 1<<18; - /** Identifies all ranges, for full contextual shaping. */ + /** Identifies all ranges, for full contextual shaping. + * + *

This constant specifies all of the bit mask-based + * ranges. Use {@code EmunSet.allOf(NumericShaper.Range.class)} to + * specify all of the enum-based ranges. + */ public static final int ALL_RANGES = 0x0007ffff; private static final int EUROPEAN_KEY = 0; @@ -163,42 +441,20 @@ public final class NumericShaper implements java.io.Serializable { private static final int KHMER_KEY = 17; private static final int MONGOLIAN_KEY = 18; - private static final int NUM_KEYS = 19; - - private static final String[] keyNames = { - "EUROPEAN", - "ARABIC", - "EASTERN_ARABIC", - "DEVANAGARI", - "BENGALI", - "GURMUKHI", - "GUJARATI", - "ORIYA", - "TAMIL", - "TELUGU", - "KANNADA", - "MALAYALAM", - "THAI", - "LAO", - "TIBETAN", - "MYANMAR", - "ETHIOPIC", - "KHMER", - "MONGOLIAN" - }; + private static final int NUM_KEYS = MONGOLIAN_KEY + 1; // fixed private static final int CONTEXTUAL_MASK = 1<<31; private static final char[] bases = { '\u0030' - '\u0030', // EUROPEAN - '\u0660' - '\u0030', // ARABIC - '\u06f0' - '\u0030', // EASTERN_ARABIC + '\u0660' - '\u0030', // ARABIC-INDIC + '\u06f0' - '\u0030', // EXTENDED ARABIC-INDIC (EASTERN_ARABIC) '\u0966' - '\u0030', // DEVANAGARI '\u09e6' - '\u0030', // BENGALI '\u0a66' - '\u0030', // GURMUKHI '\u0ae6' - '\u0030', // GUJARATI '\u0b66' - '\u0030', // ORIYA - '\u0be7' - '\u0030', // TAMIL - note missing zero + '\u0be6' - '\u0030', // TAMIL - zero was added in Unicode 4.1 '\u0c66' - '\u0030', // TELUGU '\u0ce6' - '\u0030', // KANNADA '\u0d66' - '\u0030', // MALAYALAM @@ -206,7 +462,7 @@ public final class NumericShaper implements java.io.Serializable { '\u0ed0' - '\u0030', // LAO '\u0f20' - '\u0030', // TIBETAN '\u1040' - '\u0030', // MYANMAR - '\u1369' - '\u0030', // ETHIOPIC + '\u1369' - '\u0031', // ETHIOPIC - no zero '\u17e0' - '\u0030', // KHMER '\u1810' - '\u0030', // MONGOLIAN }; @@ -215,14 +471,14 @@ public final class NumericShaper implements java.io.Serializable { private static final char[] contexts = { '\u0000', '\u0300', // 'EUROPEAN' (really latin-1 and extended) - '\u0600', '\u0700', // ARABIC - '\u0600', '\u0700', // EASTERN_ARABIC -- note overlap with arabic + '\u0600', '\u0780', // ARABIC + '\u0600', '\u0780', // EASTERN_ARABIC -- note overlap with arabic '\u0900', '\u0980', // DEVANAGARI '\u0980', '\u0a00', // BENGALI '\u0a00', '\u0a80', // GURMUKHI '\u0a80', '\u0b00', // GUJARATI '\u0b00', '\u0b80', // ORIYA - '\u0b80', '\u0c00', // TAMIL - note missing zero + '\u0b80', '\u0c00', // TAMIL '\u0c00', '\u0c80', // TELUGU '\u0c80', '\u0d00', // KANNADA '\u0d00', '\u0d80', // MALAYALAM @@ -230,7 +486,7 @@ public final class NumericShaper implements java.io.Serializable { '\u0e80', '\u0f00', // LAO '\u0f00', '\u1000', // TIBETAN '\u1000', '\u1080', // MYANMAR - '\u1200', '\u1380', // ETHIOPIC + '\u1200', '\u1380', // ETHIOPIC - note missing zero '\u1780', '\u1800', // KHMER '\u1800', '\u1900', // MONGOLIAN '\uffff', @@ -254,378 +510,290 @@ public final class NumericShaper implements java.io.Serializable { return (ctCache & 0x1) == 0 ? (ctCache / 2) : EUROPEAN_KEY; } + // cache for the NumericShaper.Range version + private transient volatile Range currentRange = Range.EUROPEAN; + + private Range rangeForCodePoint(int codepoint) { + Range range = currentRange; + if (range.inRange(codepoint)) { + return range; + } + + final Range[] ranges = Range.ranges; + int lo = 0; + int hi = ranges.length - 1; + while (lo <= hi) { + int mid = (lo + hi) / 2; + range = ranges[mid]; + if (codepoint < range.start) { + hi = mid - 1; + } else if (codepoint >= range.end) { + lo = mid + 1; + } else { + currentRange = range; + return range; + } + } + return Range.EUROPEAN; + } + /* * A range table of strong directional characters (types L, R, AL). * Even (left) indexes are starts of ranges of non-strong-directional (or undefined) * characters, odd (right) indexes are starts of ranges of strong directional * characters. */ - private static char[] strongTable = { - '\u0000', '\u0041', - '\u005b', '\u0061', - '\u007b', '\u00aa', - '\u00ab', '\u00b5', - '\u00b6', '\u00ba', - '\u00bb', '\u00c0', - '\u00d7', '\u00d8', - '\u00f7', '\u00f8', - '\u0220', '\u0222', - '\u0234', '\u0250', - '\u02ae', '\u02b0', - '\u02b9', '\u02bb', - '\u02c2', '\u02d0', - '\u02d2', '\u02e0', - '\u02e5', '\u02ee', - '\u02ef', '\u037a', - '\u037b', '\u0386', - '\u0387', '\u0388', - '\u038b', '\u038c', - '\u038d', '\u038e', - '\u03a2', '\u03a3', - '\u03cf', '\u03d0', - '\u03d8', '\u03da', - '\u03f4', '\u0400', - '\u0483', '\u048c', - '\u04c5', '\u04c7', - '\u04c9', '\u04cb', - '\u04cd', '\u04d0', - '\u04f6', '\u04f8', - '\u04fa', '\u0531', - '\u0557', '\u0559', - '\u0560', '\u0561', - '\u0588', '\u0589', - '\u058a', '\u05be', - '\u05bf', '\u05c0', - '\u05c1', '\u05c3', - '\u05c4', '\u05d0', - '\u05eb', '\u05f0', - '\u05f5', '\u061b', - '\u061c', '\u061f', - '\u0620', '\u0621', - '\u063b', '\u0640', - '\u064b', '\u066d', - '\u066e', '\u0671', - '\u06d6', '\u06e5', - '\u06e7', '\u06fa', - '\u06ff', '\u0700', - '\u070e', '\u0710', - '\u0711', '\u0712', - '\u072d', '\u0780', - '\u07a6', '\u0903', - '\u0904', '\u0905', - '\u093a', '\u093d', - '\u0941', '\u0949', - '\u094d', '\u0950', - '\u0951', '\u0958', - '\u0962', '\u0964', - '\u0971', '\u0982', - '\u0984', '\u0985', - '\u098d', '\u098f', - '\u0991', '\u0993', - '\u09a9', '\u09aa', - '\u09b1', '\u09b2', - '\u09b3', '\u09b6', - '\u09ba', '\u09be', - '\u09c1', '\u09c7', - '\u09c9', '\u09cb', - '\u09cd', '\u09d7', - '\u09d8', '\u09dc', - '\u09de', '\u09df', - '\u09e2', '\u09e6', - '\u09f2', '\u09f4', - '\u09fb', '\u0a05', - '\u0a0b', '\u0a0f', - '\u0a11', '\u0a13', - '\u0a29', '\u0a2a', - '\u0a31', '\u0a32', - '\u0a34', '\u0a35', - '\u0a37', '\u0a38', - '\u0a3a', '\u0a3e', - '\u0a41', '\u0a59', - '\u0a5d', '\u0a5e', - '\u0a5f', '\u0a66', - '\u0a70', '\u0a72', - '\u0a75', '\u0a83', - '\u0a84', '\u0a85', - '\u0a8c', '\u0a8d', - '\u0a8e', '\u0a8f', - '\u0a92', '\u0a93', - '\u0aa9', '\u0aaa', - '\u0ab1', '\u0ab2', - '\u0ab4', '\u0ab5', - '\u0aba', '\u0abd', - '\u0ac1', '\u0ac9', - '\u0aca', '\u0acb', - '\u0acd', '\u0ad0', - '\u0ad1', '\u0ae0', - '\u0ae1', '\u0ae6', - '\u0af0', '\u0b02', - '\u0b04', '\u0b05', - '\u0b0d', '\u0b0f', - '\u0b11', '\u0b13', - '\u0b29', '\u0b2a', - '\u0b31', '\u0b32', - '\u0b34', '\u0b36', - '\u0b3a', '\u0b3d', - '\u0b3f', '\u0b40', - '\u0b41', '\u0b47', - '\u0b49', '\u0b4b', - '\u0b4d', '\u0b57', - '\u0b58', '\u0b5c', - '\u0b5e', '\u0b5f', - '\u0b62', '\u0b66', - '\u0b71', '\u0b83', - '\u0b84', '\u0b85', - '\u0b8b', '\u0b8e', - '\u0b91', '\u0b92', - '\u0b96', '\u0b99', - '\u0b9b', '\u0b9c', - '\u0b9d', '\u0b9e', - '\u0ba0', '\u0ba3', - '\u0ba5', '\u0ba8', - '\u0bab', '\u0bae', - '\u0bb6', '\u0bb7', - '\u0bba', '\u0bbe', - '\u0bc0', '\u0bc1', - '\u0bc3', '\u0bc6', - '\u0bc9', '\u0bca', - '\u0bcd', '\u0bd7', - '\u0bd8', '\u0be7', - '\u0bf3', '\u0c01', - '\u0c04', '\u0c05', - '\u0c0d', '\u0c0e', - '\u0c11', '\u0c12', - '\u0c29', '\u0c2a', - '\u0c34', '\u0c35', - '\u0c3a', '\u0c41', - '\u0c45', '\u0c60', - '\u0c62', '\u0c66', - '\u0c70', '\u0c82', - '\u0c84', '\u0c85', - '\u0c8d', '\u0c8e', - '\u0c91', '\u0c92', - '\u0ca9', '\u0caa', - '\u0cb4', '\u0cb5', - '\u0cba', '\u0cbe', - '\u0cbf', '\u0cc0', - '\u0cc5', '\u0cc7', - '\u0cc9', '\u0cca', - '\u0ccc', '\u0cd5', - '\u0cd7', '\u0cde', - '\u0cdf', '\u0ce0', - '\u0ce2', '\u0ce6', - '\u0cf0', '\u0d02', - '\u0d04', '\u0d05', - '\u0d0d', '\u0d0e', - '\u0d11', '\u0d12', - '\u0d29', '\u0d2a', - '\u0d3a', '\u0d3e', - '\u0d41', '\u0d46', - '\u0d49', '\u0d4a', - '\u0d4d', '\u0d57', - '\u0d58', '\u0d60', - '\u0d62', '\u0d66', - '\u0d70', '\u0d82', - '\u0d84', '\u0d85', - '\u0d97', '\u0d9a', - '\u0db2', '\u0db3', - '\u0dbc', '\u0dbd', - '\u0dbe', '\u0dc0', - '\u0dc7', '\u0dcf', - '\u0dd2', '\u0dd8', - '\u0de0', '\u0df2', - '\u0df5', '\u0e01', - '\u0e31', '\u0e32', - '\u0e34', '\u0e40', - '\u0e47', '\u0e4f', - '\u0e5c', '\u0e81', - '\u0e83', '\u0e84', - '\u0e85', '\u0e87', - '\u0e89', '\u0e8a', - '\u0e8b', '\u0e8d', - '\u0e8e', '\u0e94', - '\u0e98', '\u0e99', - '\u0ea0', '\u0ea1', - '\u0ea4', '\u0ea5', - '\u0ea6', '\u0ea7', - '\u0ea8', '\u0eaa', - '\u0eac', '\u0ead', - '\u0eb1', '\u0eb2', - '\u0eb4', '\u0ebd', - '\u0ebe', '\u0ec0', - '\u0ec5', '\u0ec6', - '\u0ec7', '\u0ed0', - '\u0eda', '\u0edc', - '\u0ede', '\u0f00', - '\u0f18', '\u0f1a', - '\u0f35', '\u0f36', - '\u0f37', '\u0f38', - '\u0f39', '\u0f3e', - '\u0f48', '\u0f49', - '\u0f6b', '\u0f7f', - '\u0f80', '\u0f85', - '\u0f86', '\u0f88', - '\u0f8c', '\u0fbe', - '\u0fc6', '\u0fc7', - '\u0fcd', '\u0fcf', - '\u0fd0', '\u1000', - '\u1022', '\u1023', - '\u1028', '\u1029', - '\u102b', '\u102c', - '\u102d', '\u1031', - '\u1032', '\u1038', - '\u1039', '\u1040', - '\u1058', '\u10a0', - '\u10c6', '\u10d0', - '\u10f7', '\u10fb', - '\u10fc', '\u1100', - '\u115a', '\u115f', - '\u11a3', '\u11a8', - '\u11fa', '\u1200', - '\u1207', '\u1208', - '\u1247', '\u1248', - '\u1249', '\u124a', - '\u124e', '\u1250', - '\u1257', '\u1258', - '\u1259', '\u125a', - '\u125e', '\u1260', - '\u1287', '\u1288', - '\u1289', '\u128a', - '\u128e', '\u1290', - '\u12af', '\u12b0', - '\u12b1', '\u12b2', - '\u12b6', '\u12b8', - '\u12bf', '\u12c0', - '\u12c1', '\u12c2', - '\u12c6', '\u12c8', - '\u12cf', '\u12d0', - '\u12d7', '\u12d8', - '\u12ef', '\u12f0', - '\u130f', '\u1310', - '\u1311', '\u1312', - '\u1316', '\u1318', - '\u131f', '\u1320', - '\u1347', '\u1348', - '\u135b', '\u1361', - '\u137d', '\u13a0', - '\u13f5', '\u1401', - '\u1677', '\u1681', - '\u169b', '\u16a0', - '\u16f1', '\u1780', - '\u17b7', '\u17be', - '\u17c6', '\u17c7', - '\u17c9', '\u17d4', - '\u17db', '\u17dc', - '\u17dd', '\u17e0', - '\u17ea', '\u1810', - '\u181a', '\u1820', - '\u1878', '\u1880', - '\u18a9', '\u1e00', - '\u1e9c', '\u1ea0', - '\u1efa', '\u1f00', - '\u1f16', '\u1f18', - '\u1f1e', '\u1f20', - '\u1f46', '\u1f48', - '\u1f4e', '\u1f50', - '\u1f58', '\u1f59', - '\u1f5a', '\u1f5b', - '\u1f5c', '\u1f5d', - '\u1f5e', '\u1f5f', - '\u1f7e', '\u1f80', - '\u1fb5', '\u1fb6', - '\u1fbd', '\u1fbe', - '\u1fbf', '\u1fc2', - '\u1fc5', '\u1fc6', - '\u1fcd', '\u1fd0', - '\u1fd4', '\u1fd6', - '\u1fdc', '\u1fe0', - '\u1fed', '\u1ff2', - '\u1ff5', '\u1ff6', - '\u1ffd', '\u200e', - '\u2010', '\u207f', - '\u2080', '\u2102', - '\u2103', '\u2107', - '\u2108', '\u210a', - '\u2114', '\u2115', - '\u2116', '\u2119', - '\u211e', '\u2124', - '\u2125', '\u2126', - '\u2127', '\u2128', - '\u2129', '\u212a', - '\u212e', '\u212f', - '\u2132', '\u2133', - '\u213a', '\u2160', - '\u2184', '\u2336', - '\u237b', '\u2395', - '\u2396', '\u249c', - '\u24ea', '\u3005', - '\u3008', '\u3021', - '\u302a', '\u3031', - '\u3036', '\u3038', - '\u303b', '\u3041', - '\u3095', '\u309d', - '\u309f', '\u30a1', - '\u30fb', '\u30fc', - '\u30ff', '\u3105', - '\u312d', '\u3131', - '\u318f', '\u3190', - '\u31b8', '\u3200', - '\u321d', '\u3220', - '\u3244', '\u3260', - '\u327c', '\u327f', - '\u32b1', '\u32c0', - '\u32cc', '\u32d0', - '\u32ff', '\u3300', - '\u3377', '\u337b', - '\u33de', '\u33e0', - '\u33ff', '\u3400', - '\u4db6', '\u4e00', - '\u9fa6', '\ua000', - '\ua48d', '\uac00', - '\ud7a4', '\uf900', - '\ufa2e', '\ufb00', - '\ufb07', '\ufb13', - '\ufb18', '\ufb1d', - '\ufb1e', '\ufb1f', - '\ufb29', '\ufb2a', - '\ufb37', '\ufb38', - '\ufb3d', '\ufb3e', - '\ufb3f', '\ufb40', - '\ufb42', '\ufb43', - '\ufb45', '\ufb46', - '\ufbb2', '\ufbd3', - '\ufd3e', '\ufd50', - '\ufd90', '\ufd92', - '\ufdc8', '\ufdf0', - '\ufdfc', '\ufe70', - '\ufe73', '\ufe74', - '\ufe75', '\ufe76', - '\ufefd', '\uff21', - '\uff3b', '\uff41', - '\uff5b', '\uff66', - '\uffbf', '\uffc2', - '\uffc8', '\uffca', - '\uffd0', '\uffd2', - '\uffd8', '\uffda', - '\uffdd', '\uffff' // last entry is sentinel, actually never checked + private static int[] strongTable = { + 0x0000, 0x0041, + 0x005b, 0x0061, + 0x007b, 0x00aa, + 0x00ab, 0x00b5, + 0x00b6, 0x00ba, + 0x00bb, 0x00c0, + 0x00d7, 0x00d8, + 0x00f7, 0x00f8, + 0x02b9, 0x02bb, + 0x02c2, 0x02d0, + 0x02d2, 0x02e0, + 0x02e5, 0x02ee, + 0x02ef, 0x0370, + 0x0374, 0x0376, + 0x037e, 0x0386, + 0x0387, 0x0388, + 0x03f6, 0x03f7, + 0x0483, 0x048a, + 0x058a, 0x05be, + 0x05bf, 0x05c0, + 0x05c1, 0x05c3, + 0x05c4, 0x05c6, + 0x05c7, 0x05d0, + 0x0600, 0x0608, + 0x0609, 0x060b, + 0x060c, 0x060d, + 0x060e, 0x061b, + 0x064b, 0x066d, + 0x0670, 0x0671, + 0x06d6, 0x06e5, + 0x06e7, 0x06ee, + 0x06f0, 0x06fa, + 0x070f, 0x0710, + 0x0711, 0x0712, + 0x0730, 0x074d, + 0x07a6, 0x07b1, + 0x07eb, 0x07f4, + 0x07f6, 0x07fa, + 0x0901, 0x0903, + 0x093c, 0x093d, + 0x0941, 0x0949, + 0x094d, 0x0950, + 0x0951, 0x0958, + 0x0962, 0x0964, + 0x0981, 0x0982, + 0x09bc, 0x09bd, + 0x09c1, 0x09c7, + 0x09cd, 0x09ce, + 0x09e2, 0x09e6, + 0x09f2, 0x09f4, + 0x0a01, 0x0a03, + 0x0a3c, 0x0a3e, + 0x0a41, 0x0a59, + 0x0a70, 0x0a72, + 0x0a75, 0x0a83, + 0x0abc, 0x0abd, + 0x0ac1, 0x0ac9, + 0x0acd, 0x0ad0, + 0x0ae2, 0x0ae6, + 0x0af1, 0x0b02, + 0x0b3c, 0x0b3d, + 0x0b3f, 0x0b40, + 0x0b41, 0x0b47, + 0x0b4d, 0x0b57, + 0x0b62, 0x0b66, + 0x0b82, 0x0b83, + 0x0bc0, 0x0bc1, + 0x0bcd, 0x0bd0, + 0x0bf3, 0x0c01, + 0x0c3e, 0x0c41, + 0x0c46, 0x0c58, + 0x0c62, 0x0c66, + 0x0c78, 0x0c7f, + 0x0cbc, 0x0cbd, + 0x0ccc, 0x0cd5, + 0x0ce2, 0x0ce6, + 0x0cf1, 0x0d02, + 0x0d41, 0x0d46, + 0x0d4d, 0x0d57, + 0x0d62, 0x0d66, + 0x0dca, 0x0dcf, + 0x0dd2, 0x0dd8, + 0x0e31, 0x0e32, + 0x0e34, 0x0e40, + 0x0e47, 0x0e4f, + 0x0eb1, 0x0eb2, + 0x0eb4, 0x0ebd, + 0x0ec8, 0x0ed0, + 0x0f18, 0x0f1a, + 0x0f35, 0x0f36, + 0x0f37, 0x0f38, + 0x0f39, 0x0f3e, + 0x0f71, 0x0f7f, + 0x0f80, 0x0f85, + 0x0f86, 0x0f88, + 0x0f90, 0x0fbe, + 0x0fc6, 0x0fc7, + 0x102d, 0x1031, + 0x1032, 0x1038, + 0x1039, 0x103b, + 0x103d, 0x103f, + 0x1058, 0x105a, + 0x105e, 0x1061, + 0x1071, 0x1075, + 0x1082, 0x1083, + 0x1085, 0x1087, + 0x108d, 0x108e, + 0x135f, 0x1360, + 0x1390, 0x13a0, + 0x1680, 0x1681, + 0x169b, 0x16a0, + 0x1712, 0x1720, + 0x1732, 0x1735, + 0x1752, 0x1760, + 0x1772, 0x1780, + 0x17b7, 0x17be, + 0x17c6, 0x17c7, + 0x17c9, 0x17d4, + 0x17db, 0x17dc, + 0x17dd, 0x17e0, + 0x17f0, 0x1810, + 0x18a9, 0x18aa, + 0x1920, 0x1923, + 0x1927, 0x1929, + 0x1932, 0x1933, + 0x1939, 0x1946, + 0x19de, 0x1a00, + 0x1a17, 0x1a19, + 0x1b00, 0x1b04, + 0x1b34, 0x1b35, + 0x1b36, 0x1b3b, + 0x1b3c, 0x1b3d, + 0x1b42, 0x1b43, + 0x1b6b, 0x1b74, + 0x1b80, 0x1b82, + 0x1ba2, 0x1ba6, + 0x1ba8, 0x1baa, + 0x1c2c, 0x1c34, + 0x1c36, 0x1c3b, + 0x1dc0, 0x1e00, + 0x1fbd, 0x1fbe, + 0x1fbf, 0x1fc2, + 0x1fcd, 0x1fd0, + 0x1fdd, 0x1fe0, + 0x1fed, 0x1ff2, + 0x1ffd, 0x200e, + 0x2010, 0x2071, + 0x2074, 0x207f, + 0x2080, 0x2090, + 0x20a0, 0x2102, + 0x2103, 0x2107, + 0x2108, 0x210a, + 0x2114, 0x2115, + 0x2116, 0x2119, + 0x211e, 0x2124, + 0x2125, 0x2126, + 0x2127, 0x2128, + 0x2129, 0x212a, + 0x212e, 0x212f, + 0x213a, 0x213c, + 0x2140, 0x2145, + 0x214a, 0x214e, + 0x2153, 0x2160, + 0x2190, 0x2336, + 0x237b, 0x2395, + 0x2396, 0x249c, + 0x24ea, 0x26ac, + 0x26ad, 0x2800, + 0x2900, 0x2c00, + 0x2ce5, 0x2d00, + 0x2de0, 0x3005, + 0x3008, 0x3021, + 0x302a, 0x3031, + 0x3036, 0x3038, + 0x303d, 0x3041, + 0x3099, 0x309d, + 0x30a0, 0x30a1, + 0x30fb, 0x30fc, + 0x31c0, 0x31f0, + 0x321d, 0x3220, + 0x3250, 0x3260, + 0x327c, 0x327f, + 0x32b1, 0x32c0, + 0x32cc, 0x32d0, + 0x3377, 0x337b, + 0x33de, 0x33e0, + 0x33ff, 0x3400, + 0x4dc0, 0x4e00, + 0xa490, 0xa500, + 0xa60d, 0xa610, + 0xa66f, 0xa680, + 0xa700, 0xa722, + 0xa788, 0xa789, + 0xa802, 0xa803, + 0xa806, 0xa807, + 0xa80b, 0xa80c, + 0xa825, 0xa827, + 0xa828, 0xa840, + 0xa874, 0xa880, + 0xa8c4, 0xa8ce, + 0xa926, 0xa92e, + 0xa947, 0xa952, + 0xaa29, 0xaa2f, + 0xaa31, 0xaa33, + 0xaa35, 0xaa40, + 0xaa43, 0xaa44, + 0xaa4c, 0xaa4d, + 0xfb1e, 0xfb1f, + 0xfb29, 0xfb2a, + 0xfd3e, 0xfd50, + 0xfdfd, 0xfe70, + 0xfeff, 0xff21, + 0xff3b, 0xff41, + 0xff5b, 0xff66, + 0xffe0, 0x10000, + 0x10101, 0x10102, + 0x10140, 0x101d0, + 0x101fd, 0x10280, + 0x1091f, 0x10920, + 0x10a01, 0x10a10, + 0x10a38, 0x10a40, + 0x1d167, 0x1d16a, + 0x1d173, 0x1d183, + 0x1d185, 0x1d18c, + 0x1d1aa, 0x1d1ae, + 0x1d200, 0x1d360, + 0x1d7ce, 0x20000, + 0xe0001, 0xf0000, + 0x10fffe, 0x10ffff // sentinel }; // use a binary search with a cache - private static int stCache = 0; + private transient volatile int stCache = 0; - // warning, synchronize access to this as it modifies state - private static boolean isStrongDirectional(char c) { - if (c < strongTable[stCache]) { - stCache = search(c, strongTable, 0, stCache); - } else if (c >= strongTable[stCache + 1]) { - stCache = search(c, strongTable, stCache + 1, strongTable.length - stCache - 1); + private boolean isStrongDirectional(char c) { + int cachedIndex = stCache; + if (c < strongTable[cachedIndex]) { + cachedIndex = search(c, strongTable, 0, cachedIndex); + } else if (c >= strongTable[cachedIndex + 1]) { + cachedIndex = search(c, strongTable, cachedIndex + 1, + strongTable.length - cachedIndex - 1); } - return (stCache & 0x1) == 1; + boolean val = (cachedIndex & 0x1) == 1; + stCache = cachedIndex; + return val; } - static private int getKeyFromMask(int mask) { + private static int getKeyFromMask(int mask) { int key = 0; while (key < NUM_KEYS && ((mask & (1<The shaper assumes EUROPEAN as the starting context, that + * is, if EUROPEAN digits are encountered before any strong + * directional text in the string, the context is presumed to be + * EUROPEAN, and so the digits will not shape. + * + * @param ranges the specified Unicode ranges + * @return a contextual shaper for the specified ranges + * @throws NullPointerException if {@code ranges} is {@code null}. + * @since 1.7 + */ + public static NumericShaper getContextualShaper(Set ranges) { + NumericShaper shaper = new NumericShaper(Range.EUROPEAN, ranges); + shaper.mask = CONTEXTUAL_MASK; + return shaper; + } + /** * Returns a contextual shaper for the provided unicode range(s). * Latin-1 (EUROPEAN) digits will be converted to the decimal digits @@ -683,12 +888,37 @@ public final class NumericShaper implements java.io.Serializable { * @throws IllegalArgumentException if the specified * defaultContext is not a single valid range. */ - static public NumericShaper getContextualShaper(int ranges, int defaultContext) { + public static NumericShaper getContextualShaper(int ranges, int defaultContext) { int key = getKeyFromMask(defaultContext); ranges |= CONTEXTUAL_MASK; return new NumericShaper(key, ranges); } + /** + * Returns a contextual shaper for the provided Unicode range(s). + * The Latin-1 (EUROPEAN) digits will be converted to the decimal + * digits corresponding to the range of the preceding text, if the + * range is one of the provided ranges. The shaper uses {@code + * defaultContext} as the starting context. + * + * @param ranges the specified Unicode ranges + * @param defaultContext the starting context, such as + * {@code NumericShaper.Range.EUROPEAN} + * @return a contextual shaper for the specified Unicode ranges. + * @throws NullPointerException + * if {@code ranges} or {@code defaultContext} is {@code null} + * @since 1.7 + */ + public static NumericShaper getContextualShaper(Set ranges, + Range defaultContext) { + if (defaultContext == null) { + throw new NullPointerException(); + } + NumericShaper shaper = new NumericShaper(defaultContext, ranges); + shaper.mask = CONTEXTUAL_MASK; + return shaper; + } + /** * Private constructor. */ @@ -697,6 +927,11 @@ public final class NumericShaper implements java.io.Serializable { this.mask = mask; } + private NumericShaper(Range defaultContext, Set ranges) { + this.shapingRange = defaultContext; + this.rangeSet = EnumSet.copyOf(ranges); // throws NPE if ranges is null. + } + /** * Converts the digits in the text that occur between start and * start + count. @@ -710,19 +945,13 @@ public final class NumericShaper implements java.io.Serializable { * @throws NullPointerException if text is null */ public void shape(char[] text, int start, int count) { - if (text == null) { - throw new NullPointerException("text is null"); - } - if ((start < 0) - || (start > text.length) - || ((start + count) < 0) - || ((start + count) > text.length)) { - throw new IndexOutOfBoundsException( - "bad start or count for text of length " + text.length); - } - + checkParams(text, start, count); if (isContextual()) { - shapeContextually(text, start, count, key); + if (rangeSet == null) { + shapeContextually(text, start, count, key); + } else { + shapeContextually(text, start, count, shapingRange); + } } else { shapeNonContextually(text, start, count); } @@ -747,6 +976,60 @@ public final class NumericShaper implements java.io.Serializable { * range. */ public void shape(char[] text, int start, int count, int context) { + checkParams(text, start, count); + if (isContextual()) { + int ctxKey = getKeyFromMask(context); + if (rangeSet == null) { + shapeContextually(text, start, count, ctxKey); + } else { + shapeContextually(text, start, count, Range.values()[ctxKey]); + } + } else { + shapeNonContextually(text, start, count); + } + } + + /** + * Converts the digits in the text that occur between {@code + * start} and {@code start + count}, using the provided {@code + * context}. {@code Context} is ignored if the shaper is not a + * contextual shaper. + * + * @param text a {@code char} array + * @param start the index into {@code text} to start converting + * @param count the number of {@code char}s in {@code text} + * to convert + * @param context the context to which to convert the characters, + * such as {@code NumericShaper.Range.EUROPEAN} + * @throws IndexOutOfBoundsException + * if {@code start} or {@code start + count} is out of bounds + * @throws NullPointerException + * if {@code text} or {@code context} is null + * @since 1.7 + */ + public void shape(char[] text, int start, int count, Range context) { + checkParams(text, start, count); + if (context == null) { + throw new NullPointerException("context is null"); + } + + if (isContextual()) { + if (rangeSet != null) { + shapeContextually(text, start, count, context); + } else { + int key = Range.toRangeIndex(context); + if (key >= 0) { + shapeContextually(text, start, count, key); + } else { + shapeContextually(text, start, count, shapingRange); + } + } + } else { + shapeNonContextually(text, start, count); + } + } + + private void checkParams(char[] text, int start, int count) { if (text == null) { throw new NullPointerException("text is null"); } @@ -757,13 +1040,6 @@ public final class NumericShaper implements java.io.Serializable { throw new IndexOutOfBoundsException( "bad start or count for text of length " + text.length); } - - if (isContextual()) { - int ctxKey = getKeyFromMask(context); - shapeContextually(text, start, count, ctxKey); - } else { - shapeNonContextually(text, start, count); - } } /** @@ -785,18 +1061,45 @@ public final class NumericShaper implements java.io.Serializable { *

* if ((shaper.getRanges() & shaper.ARABIC) != 0) { ... *
+ * + *

Note that this method supports only the bit mask-based + * ranges. Call {@link #getRangeSet()} for the enum-based ranges. + * * @return the values for all the ranges to be shaped. */ public int getRanges() { return mask & ~CONTEXTUAL_MASK; } + /** + * Returns a {@code Set} representing all the Unicode ranges in + * this {@code NumericShaper} that will be shaped. + * + * @return all the Unicode ranges to be shaped. + * @since 1.7 + */ + public Set getRangeSet() { + if (rangeSet != null) { + return EnumSet.copyOf(rangeSet); + } + return Range.maskToRangeSet(mask); + } + /** * Perform non-contextual shaping. */ private void shapeNonContextually(char[] text, int start, int count) { - int base = bases[key]; - char minDigit = key == TAMIL_KEY ? '\u0031' : '\u0030'; // Tamil doesn't use decimal zero + int base; + char minDigit = '0'; + if (shapingRange != null) { + base = shapingRange.getDigitBase(); + minDigit += shapingRange.getNumericBase(); + } else { + base = bases[key]; + if (key == ETHIOPIC_KEY) { + minDigit++; // Ethiopic doesn't use decimal zero + } + } for (int i = start, e = start + count; i < e; ++i) { char c = text[i]; if (c >= minDigit && c <= '\u0039') { @@ -807,7 +1110,7 @@ public final class NumericShaper implements java.io.Serializable { /** * Perform contextual shaping. - * Synchronized to protect caches used in getContextKey and isStrongDirectional. + * Synchronized to protect caches used in getContextKey. */ private synchronized void shapeContextually(char[] text, int start, int count, int ctxKey) { @@ -818,29 +1121,64 @@ public final class NumericShaper implements java.io.Serializable { int lastkey = ctxKey; int base = bases[ctxKey]; - char minDigit = ctxKey == TAMIL_KEY ? '\u0031' : '\u0030'; // Tamil doesn't use decimal zero + char minDigit = ctxKey == ETHIOPIC_KEY ? '1' : '0'; // Ethiopic doesn't use decimal zero - for (int i = start, e = start + count; i < e; ++i) { + synchronized (NumericShaper.class) { + for (int i = start, e = start + count; i < e; ++i) { + char c = text[i]; + if (c >= minDigit && c <= '\u0039') { + text[i] = (char)(c + base); + } + + if (isStrongDirectional(c)) { + int newkey = getContextKey(c); + if (newkey != lastkey) { + lastkey = newkey; + + ctxKey = newkey; + if (((mask & EASTERN_ARABIC) != 0) && (ctxKey == ARABIC_KEY || ctxKey == EASTERN_ARABIC_KEY)) { + ctxKey = EASTERN_ARABIC_KEY; + } else if ((mask & (1<= minDigit && c <= '\u0039') { + if (c >= minDigit && c <= '9') { text[i] = (char)(c + base); + continue; } - if (isStrongDirectional(c)) { - int newkey = getContextKey(c); - if (newkey != lastkey) { - lastkey = newkey; - - ctxKey = newkey; - if (((mask & EASTERN_ARABIC) != 0) && (ctxKey == ARABIC_KEY || ctxKey == EASTERN_ARABIC_KEY)) { - ctxKey = EASTERN_ARABIC_KEY; - } else if ((mask & (1<NumericShaper and shapes identically to this one. + * Returns {@code true} if the specified object is an instance of + * NumericShaper and shapes identically to this one, + * regardless of the range representations, the bit mask or the + * enum. For example, the following code produces {@code "true"}. + *

+     * NumericShaper ns1 = NumericShaper.getShaper(NumericShaper.ARABIC);
+     * NumericShaper ns2 = NumericShaper.getShaper(NumericShaper.Range.ARABIC);
+     * System.out.println(ns1.equals(ns2));
+     * 
+ * * @param o the specified object to compare to this * NumericShaper * @return true if o is an instance @@ -869,6 +1223,22 @@ public final class NumericShaper implements java.io.Serializable { if (o != null) { try { NumericShaper rhs = (NumericShaper)o; + if (rangeSet != null) { + if (rhs.rangeSet != null) { + return isContextual() == rhs.isContextual() + && rangeSet.equals(rhs.rangeSet) + && shapingRange == rhs.shapingRange; + } + return isContextual() == rhs.isContextual() + && rangeSet.equals(Range.maskToRangeSet(rhs.mask)) + && shapingRange == Range.indexToRange(rhs.key); + } else if (rhs.rangeSet != null) { + Set rset = Range.maskToRangeSet(mask); + Range srange = Range.indexToRange(key); + return isContextual() == rhs.isContextual() + && rset.equals(rhs.rangeSet) + && srange == rhs.shapingRange; + } return rhs.mask == mask && rhs.key == key; } catch (ClassCastException e) { @@ -885,23 +1255,29 @@ public final class NumericShaper implements java.io.Serializable { public String toString() { StringBuilder buf = new StringBuilder(super.toString()); - buf.append("[contextual:" + isContextual()); + buf.append("[contextual:").append(isContextual()); + String[] keyNames = null; if (isContextual()) { - buf.append(", context:" + keyNames[key]); + buf.append(", context:"); + buf.append(shapingRange == null ? Range.values()[key] : shapingRange); } - buf.append(", range(s): "); - boolean first = true; - for (int i = 0; i < NUM_KEYS; ++i) { - if ((mask & (1 << i)) != 0) { - if (first) { - first = false; - } else { - buf.append(", "); + if (rangeSet == null) { + buf.append(", range(s): "); + boolean first = true; + for (int i = 0; i < NUM_KEYS; ++i) { + if ((mask & (1 << i)) != 0) { + if (first) { + first = false; + } else { + buf.append(", "); + } + buf.append(Range.values()[i]); } - buf.append(keyNames[i]); } + } else { + buf.append(", range set: ").append(rangeSet); } buf.append(']'); @@ -940,7 +1316,6 @@ public final class NumericShaper implements java.io.Serializable { } if (value >= 1 << 1) { - value >>= 1; bit += 1; } @@ -950,7 +1325,7 @@ public final class NumericShaper implements java.io.Serializable { /** * fast binary search over subrange of array. */ - private static int search(char value, char[] array, int start, int length) + private static int search(int value, int[] array, int start, int length) { int power = 1 << getHighBit(length); int extra = length - power; @@ -971,4 +1346,27 @@ public final class NumericShaper implements java.io.Serializable { return index; } + + /** + * Converts the {@code NumericShaper.Range} enum-based parameters, + * if any, to the bit mask-based counterparts and writes this + * object to the {@code stream}. Any enum constants that have no + * bit mask-based counterparts are ignored in the conversion. + * + * @param stream the output stream to write to + * @throws IOException if an I/O error occurs while writing to {@code stream} + * @since 1.7 + */ + private void writeObject(ObjectOutputStream stream) throws IOException { + if (shapingRange != null) { + int index = Range.toRangeIndex(shapingRange); + if (index >= 0) { + key = index; + } + } + if (rangeSet != null) { + mask |= Range.toRangeMask(rangeSet); + } + stream.defaultWriteObject(); + } } diff --git a/src/share/classes/java/net/CookieManager.java b/src/share/classes/java/net/CookieManager.java index 57038fcdbf2b04c84fb4b82594e8ce3f5bbc4835..986daeff3378b3bbf5f24a65261b0c579662dbca 100644 --- a/src/share/classes/java/net/CookieManager.java +++ b/src/share/classes/java/net/CookieManager.java @@ -30,6 +30,7 @@ import java.util.List; import java.util.Collections; import java.util.Comparator; import java.io.IOException; +import sun.util.logging.PlatformLogger; /** * CookieManager provides a concrete implementation of {@link CookieHandler}, @@ -263,6 +264,7 @@ public class CookieManager extends CookieHandler if (cookieJar == null) return; + PlatformLogger logger = PlatformLogger.getLogger("java.net.CookieManager"); for (String headerKey : responseHeaders.keySet()) { // RFC 2965 3.2.2, key must be 'Set-Cookie2' // we also accept 'Set-Cookie' here for backward compatibility @@ -277,7 +279,16 @@ public class CookieManager extends CookieHandler for (String headerValue : responseHeaders.get(headerKey)) { try { - List cookies = HttpCookie.parse(headerValue); + List cookies; + try { + cookies = HttpCookie.parse(headerValue); + } catch (IllegalArgumentException e) { + // Bogus header, make an empty list and log the error + cookies = java.util.Collections.EMPTY_LIST; + if (logger.isLoggable(PlatformLogger.SEVERE)) { + logger.severe("Invalid cookie for " + uri + ": " + headerValue); + } + } for (HttpCookie cookie : cookies) { if (cookie.getPath() == null) { // If no path is specified, then by default diff --git a/src/share/classes/java/net/HttpCookie.java b/src/share/classes/java/net/HttpCookie.java index bd16d4f272353598f100c005fd54d7f6ee650fbe..be82cc3efbd8abe938ef22790b7c9bbf3dd9999d 100644 --- a/src/share/classes/java/net/HttpCookie.java +++ b/src/share/classes/java/net/HttpCookie.java @@ -1036,7 +1036,7 @@ public final class HttpCookie implements Cloneable { int version = Integer.parseInt(attrValue); cookie.setVersion(version); } catch (NumberFormatException ignored) { - throw new IllegalArgumentException("Illegal cookie version attribute"); + // Just ignore bogus version, it will default to 0 or 1 } } }); @@ -1147,12 +1147,15 @@ public final class HttpCookie implements Cloneable { } private static String stripOffSurroundingQuote(String str) { - if (str != null && str.length() > 0 && + if (str != null && str.length() > 2 && str.charAt(0) == '"' && str.charAt(str.length() - 1) == '"') { return str.substring(1, str.length() - 1); - } else { - return str; } + if (str != null && str.length() > 2 && + str.charAt(0) == '\'' && str.charAt(str.length() - 1) == '\'') { + return str.substring(1, str.length() - 1); + } + return str; } private static boolean equalsIgnoreCase(String s, String t) { diff --git a/src/share/classes/java/util/DualPivotQuicksort.java b/src/share/classes/java/util/DualPivotQuicksort.java index d4207838bcc1e107ef1dc304d3482875fe3bbf68..b368d0b95b1046e9f0d468a3c7b62010230d0173 100644 --- a/src/share/classes/java/util/DualPivotQuicksort.java +++ b/src/share/classes/java/util/DualPivotQuicksort.java @@ -36,15 +36,17 @@ package java.util; * @author Jon Bentley * @author Josh Bloch * - * @version 2009.11.09 m765.827.v8 + * @version 2009.11.16 m765.827.v12a */ final class DualPivotQuicksort { - // Suppresses default constructor + /** + * Suppresses default constructor. + */ private DualPivotQuicksort() {} /* - * Tuning Parameters. + * Tuning parameters. */ /** @@ -66,7 +68,7 @@ final class DualPivotQuicksort { private static final int COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR = 32768; /* - * Sorting methods for the seven primitive types. + * Sorting methods for 7 primitive types. */ /** @@ -112,7 +114,6 @@ final class DualPivotQuicksort { for (int k = left + 1; k <= right; k++) { int ak = a[k]; int j; - for (j = k - 1; j >= left && ak < a[j]; j--) { a[j + 1] = a[j]; } @@ -140,16 +141,20 @@ final class DualPivotQuicksort { int e4 = e3 + sixth; int e2 = e3 - sixth; - // Sort these elements in place using a 5-element sorting network - if (a[e1] > a[e2]) { int t = a[e1]; a[e1] = a[e2]; a[e2] = t; } - if (a[e4] > a[e5]) { int t = a[e4]; a[e4] = a[e5]; a[e5] = t; } - if (a[e1] > a[e3]) { int t = a[e1]; a[e1] = a[e3]; a[e3] = t; } - if (a[e2] > a[e3]) { int t = a[e2]; a[e2] = a[e3]; a[e3] = t; } - if (a[e1] > a[e4]) { int t = a[e1]; a[e1] = a[e4]; a[e4] = t; } - if (a[e3] > a[e4]) { int t = a[e3]; a[e3] = a[e4]; a[e4] = t; } - if (a[e2] > a[e5]) { int t = a[e2]; a[e2] = a[e5]; a[e5] = t; } - if (a[e2] > a[e3]) { int t = a[e2]; a[e2] = a[e3]; a[e3] = t; } - if (a[e4] > a[e5]) { int t = a[e4]; a[e4] = a[e5]; a[e5] = t; } + // Sort these elements using a 5-element sorting network + int ae1 = a[e1], ae2 = a[e2], ae3 = a[e3], ae4 = a[e4], ae5 = a[e5]; + + if (ae1 > ae2) { int t = ae1; ae1 = ae2; ae2 = t; } + if (ae4 > ae5) { int t = ae4; ae4 = ae5; ae5 = t; } + if (ae1 > ae3) { int t = ae1; ae1 = ae3; ae3 = t; } + if (ae2 > ae3) { int t = ae2; ae2 = ae3; ae3 = t; } + if (ae1 > ae4) { int t = ae1; ae1 = ae4; ae4 = t; } + if (ae3 > ae4) { int t = ae3; ae3 = ae4; ae4 = t; } + if (ae2 > ae5) { int t = ae2; ae2 = ae5; ae5 = t; } + if (ae2 > ae3) { int t = ae2; ae2 = ae3; ae3 = t; } + if (ae4 > ae5) { int t = ae4; ae4 = ae5; ae5 = t; } + + a[e1] = ae1; a[e3] = ae3; a[e5] = ae5; /* * Use the second and fourth of the five sorted elements as pivots. @@ -162,8 +167,8 @@ final class DualPivotQuicksort { * the pivots are swapped back into their final positions, and * excluded from subsequent sorting. */ - int pivot1 = a[e2]; a[e2] = a[left]; - int pivot2 = a[e4]; a[e4] = a[right]; + int pivot1 = ae2; a[e2] = a[left]; + int pivot2 = ae4; a[e4] = a[right]; /* * Partitioning @@ -192,21 +197,25 @@ final class DualPivotQuicksort { * * Pointer k is the first index of ?-part */ + outer: for (int k = less; k <= great; k++) { int ak = a[k]; - if (ak < pivot1) { - a[k] = a[less]; - a[less++] = ak; + if (k > less) { + a[k] = a[less]; + a[less] = ak; + } + less++; } else if (ak > pivot2) { - while (a[great] > pivot2 && k < great) { - great--; + while (a[great] > pivot2) { + if (k == great--) { + break outer; + } } a[k] = a[great]; a[great--] = ak; - ak = a[k]; - if (ak < pivot1) { + if ((ak = a[k]) < pivot1) { a[k] = a[less]; a[less++] = ak; } @@ -234,24 +243,28 @@ final class DualPivotQuicksort { * * Pointer k is the first index of ?-part */ + outer: for (int k = less; k <= great; k++) { int ak = a[k]; - if (ak == pivot1) { - continue; + continue; } if (ak < pivot1) { - a[k] = a[less]; - a[less++] = ak; - } else { + if (k > less) { + a[k] = a[less]; + a[less] = ak; + } + less++; + } else { // a[k] > pivot while (a[great] > pivot1) { - great--; + if (k == great--) { + break outer; + } } a[k] = a[great]; a[great--] = ak; - ak = a[k]; - if (ak < pivot1) { + if ((ak = a[k]) < pivot1) { a[k] = a[less]; a[less++] = ak; } @@ -283,19 +296,19 @@ final class DualPivotQuicksort { while (a[less] == pivot1) { less++; } - for (int k = less + 1; k <= great; k++) { - if (a[k] == pivot1) { - a[k] = a[less]; - a[less++] = pivot1; - } - } while (a[great] == pivot2) { great--; } - for (int k = great - 1; k >= less; k--) { - if (a[k] == pivot2) { + for (int k = less + 1; k <= great; ) { + int ak = a[k]; + if (ak == pivot1) { + a[k++] = a[less]; + a[less++] = pivot1; + } else if (ak == pivot2) { a[k] = a[great]; a[great--] = pivot2; + } else { + k++; } } } @@ -347,7 +360,6 @@ final class DualPivotQuicksort { for (int k = left + 1; k <= right; k++) { long ak = a[k]; int j; - for (j = k - 1; j >= left && ak < a[j]; j--) { a[j + 1] = a[j]; } @@ -375,16 +387,20 @@ final class DualPivotQuicksort { int e4 = e3 + sixth; int e2 = e3 - sixth; - // Sort these elements in place using a 5-element sorting network - if (a[e1] > a[e2]) { long t = a[e1]; a[e1] = a[e2]; a[e2] = t; } - if (a[e4] > a[e5]) { long t = a[e4]; a[e4] = a[e5]; a[e5] = t; } - if (a[e1] > a[e3]) { long t = a[e1]; a[e1] = a[e3]; a[e3] = t; } - if (a[e2] > a[e3]) { long t = a[e2]; a[e2] = a[e3]; a[e3] = t; } - if (a[e1] > a[e4]) { long t = a[e1]; a[e1] = a[e4]; a[e4] = t; } - if (a[e3] > a[e4]) { long t = a[e3]; a[e3] = a[e4]; a[e4] = t; } - if (a[e2] > a[e5]) { long t = a[e2]; a[e2] = a[e5]; a[e5] = t; } - if (a[e2] > a[e3]) { long t = a[e2]; a[e2] = a[e3]; a[e3] = t; } - if (a[e4] > a[e5]) { long t = a[e4]; a[e4] = a[e5]; a[e5] = t; } + // Sort these elements using a 5-element sorting network + long ae1 = a[e1], ae2 = a[e2], ae3 = a[e3], ae4 = a[e4], ae5 = a[e5]; + + if (ae1 > ae2) { long t = ae1; ae1 = ae2; ae2 = t; } + if (ae4 > ae5) { long t = ae4; ae4 = ae5; ae5 = t; } + if (ae1 > ae3) { long t = ae1; ae1 = ae3; ae3 = t; } + if (ae2 > ae3) { long t = ae2; ae2 = ae3; ae3 = t; } + if (ae1 > ae4) { long t = ae1; ae1 = ae4; ae4 = t; } + if (ae3 > ae4) { long t = ae3; ae3 = ae4; ae4 = t; } + if (ae2 > ae5) { long t = ae2; ae2 = ae5; ae5 = t; } + if (ae2 > ae3) { long t = ae2; ae2 = ae3; ae3 = t; } + if (ae4 > ae5) { long t = ae4; ae4 = ae5; ae5 = t; } + + a[e1] = ae1; a[e3] = ae3; a[e5] = ae5; /* * Use the second and fourth of the five sorted elements as pivots. @@ -397,8 +413,8 @@ final class DualPivotQuicksort { * the pivots are swapped back into their final positions, and * excluded from subsequent sorting. */ - long pivot1 = a[e2]; a[e2] = a[left]; - long pivot2 = a[e4]; a[e4] = a[right]; + long pivot1 = ae2; a[e2] = a[left]; + long pivot2 = ae4; a[e4] = a[right]; /* * Partitioning @@ -427,21 +443,25 @@ final class DualPivotQuicksort { * * Pointer k is the first index of ?-part */ + outer: for (int k = less; k <= great; k++) { long ak = a[k]; - if (ak < pivot1) { - a[k] = a[less]; - a[less++] = ak; + if (k > less) { + a[k] = a[less]; + a[less] = ak; + } + less++; } else if (ak > pivot2) { - while (a[great] > pivot2 && k < great) { - great--; + while (a[great] > pivot2) { + if (k == great--) { + break outer; + } } a[k] = a[great]; a[great--] = ak; - ak = a[k]; - if (ak < pivot1) { + if ((ak = a[k]) < pivot1) { a[k] = a[less]; a[less++] = ak; } @@ -469,24 +489,28 @@ final class DualPivotQuicksort { * * Pointer k is the first index of ?-part */ + outer: for (int k = less; k <= great; k++) { long ak = a[k]; - if (ak == pivot1) { - continue; + continue; } if (ak < pivot1) { - a[k] = a[less]; - a[less++] = ak; - } else { + if (k > less) { + a[k] = a[less]; + a[less] = ak; + } + less++; + } else { // a[k] > pivot while (a[great] > pivot1) { - great--; + if (k == great--) { + break outer; + } } a[k] = a[great]; a[great--] = ak; - ak = a[k]; - if (ak < pivot1) { + if ((ak = a[k]) < pivot1) { a[k] = a[less]; a[less++] = ak; } @@ -518,19 +542,19 @@ final class DualPivotQuicksort { while (a[less] == pivot1) { less++; } - for (int k = less + 1; k <= great; k++) { - if (a[k] == pivot1) { - a[k] = a[less]; - a[less++] = pivot1; - } - } while (a[great] == pivot2) { great--; } - for (int k = great - 1; k >= less; k--) { - if (a[k] == pivot2) { + for (int k = less + 1; k <= great; ) { + long ak = a[k]; + if (ak == pivot1) { + a[k++] = a[less]; + a[less++] = pivot1; + } else if (ak == pivot2) { a[k] = a[great]; a[great--] = pivot2; + } else { + k++; } } } @@ -585,7 +609,6 @@ final class DualPivotQuicksort { for (int k = left + 1; k <= right; k++) { short ak = a[k]; int j; - for (j = k - 1; j >= left && ak < a[j]; j--) { a[j + 1] = a[j]; } @@ -627,16 +650,20 @@ final class DualPivotQuicksort { int e4 = e3 + sixth; int e2 = e3 - sixth; - // Sort these elements in place using a 5-element sorting network - if (a[e1] > a[e2]) { short t = a[e1]; a[e1] = a[e2]; a[e2] = t; } - if (a[e4] > a[e5]) { short t = a[e4]; a[e4] = a[e5]; a[e5] = t; } - if (a[e1] > a[e3]) { short t = a[e1]; a[e1] = a[e3]; a[e3] = t; } - if (a[e2] > a[e3]) { short t = a[e2]; a[e2] = a[e3]; a[e3] = t; } - if (a[e1] > a[e4]) { short t = a[e1]; a[e1] = a[e4]; a[e4] = t; } - if (a[e3] > a[e4]) { short t = a[e3]; a[e3] = a[e4]; a[e4] = t; } - if (a[e2] > a[e5]) { short t = a[e2]; a[e2] = a[e5]; a[e5] = t; } - if (a[e2] > a[e3]) { short t = a[e2]; a[e2] = a[e3]; a[e3] = t; } - if (a[e4] > a[e5]) { short t = a[e4]; a[e4] = a[e5]; a[e5] = t; } + // Sort these elements using a 5-element sorting network + short ae1 = a[e1], ae2 = a[e2], ae3 = a[e3], ae4 = a[e4], ae5 = a[e5]; + + if (ae1 > ae2) { short t = ae1; ae1 = ae2; ae2 = t; } + if (ae4 > ae5) { short t = ae4; ae4 = ae5; ae5 = t; } + if (ae1 > ae3) { short t = ae1; ae1 = ae3; ae3 = t; } + if (ae2 > ae3) { short t = ae2; ae2 = ae3; ae3 = t; } + if (ae1 > ae4) { short t = ae1; ae1 = ae4; ae4 = t; } + if (ae3 > ae4) { short t = ae3; ae3 = ae4; ae4 = t; } + if (ae2 > ae5) { short t = ae2; ae2 = ae5; ae5 = t; } + if (ae2 > ae3) { short t = ae2; ae2 = ae3; ae3 = t; } + if (ae4 > ae5) { short t = ae4; ae4 = ae5; ae5 = t; } + + a[e1] = ae1; a[e3] = ae3; a[e5] = ae5; /* * Use the second and fourth of the five sorted elements as pivots. @@ -649,8 +676,8 @@ final class DualPivotQuicksort { * the pivots are swapped back into their final positions, and * excluded from subsequent sorting. */ - short pivot1 = a[e2]; a[e2] = a[left]; - short pivot2 = a[e4]; a[e4] = a[right]; + short pivot1 = ae2; a[e2] = a[left]; + short pivot2 = ae4; a[e4] = a[right]; /* * Partitioning @@ -679,21 +706,25 @@ final class DualPivotQuicksort { * * Pointer k is the first index of ?-part */ + outer: for (int k = less; k <= great; k++) { short ak = a[k]; - if (ak < pivot1) { - a[k] = a[less]; - a[less++] = ak; + if (k > less) { + a[k] = a[less]; + a[less] = ak; + } + less++; } else if (ak > pivot2) { - while (a[great] > pivot2 && k < great) { - great--; + while (a[great] > pivot2) { + if (k == great--) { + break outer; + } } a[k] = a[great]; a[great--] = ak; - ak = a[k]; - if (ak < pivot1) { + if ((ak = a[k]) < pivot1) { a[k] = a[less]; a[less++] = ak; } @@ -721,24 +752,28 @@ final class DualPivotQuicksort { * * Pointer k is the first index of ?-part */ + outer: for (int k = less; k <= great; k++) { short ak = a[k]; - if (ak == pivot1) { - continue; + continue; } if (ak < pivot1) { - a[k] = a[less]; - a[less++] = ak; - } else { + if (k > less) { + a[k] = a[less]; + a[less] = ak; + } + less++; + } else { // a[k] > pivot while (a[great] > pivot1) { - great--; + if (k == great--) { + break outer; + } } a[k] = a[great]; a[great--] = ak; - ak = a[k]; - if (ak < pivot1) { + if ((ak = a[k]) < pivot1) { a[k] = a[less]; a[less++] = ak; } @@ -770,19 +805,19 @@ final class DualPivotQuicksort { while (a[less] == pivot1) { less++; } - for (int k = less + 1; k <= great; k++) { - if (a[k] == pivot1) { - a[k] = a[less]; - a[less++] = pivot1; - } - } while (a[great] == pivot2) { great--; } - for (int k = great - 1; k >= less; k--) { - if (a[k] == pivot2) { + for (int k = less + 1; k <= great; ) { + short ak = a[k]; + if (ak == pivot1) { + a[k++] = a[less]; + a[less++] = pivot1; + } else if (ak == pivot2) { a[k] = a[great]; a[great--] = pivot2; + } else { + k++; } } } @@ -837,7 +872,6 @@ final class DualPivotQuicksort { for (int k = left + 1; k <= right; k++) { char ak = a[k]; int j; - for (j = k - 1; j >= left && ak < a[j]; j--) { a[j + 1] = a[j]; } @@ -877,16 +911,20 @@ final class DualPivotQuicksort { int e4 = e3 + sixth; int e2 = e3 - sixth; - // Sort these elements in place using a 5-element sorting network - if (a[e1] > a[e2]) { char t = a[e1]; a[e1] = a[e2]; a[e2] = t; } - if (a[e4] > a[e5]) { char t = a[e4]; a[e4] = a[e5]; a[e5] = t; } - if (a[e1] > a[e3]) { char t = a[e1]; a[e1] = a[e3]; a[e3] = t; } - if (a[e2] > a[e3]) { char t = a[e2]; a[e2] = a[e3]; a[e3] = t; } - if (a[e1] > a[e4]) { char t = a[e1]; a[e1] = a[e4]; a[e4] = t; } - if (a[e3] > a[e4]) { char t = a[e3]; a[e3] = a[e4]; a[e4] = t; } - if (a[e2] > a[e5]) { char t = a[e2]; a[e2] = a[e5]; a[e5] = t; } - if (a[e2] > a[e3]) { char t = a[e2]; a[e2] = a[e3]; a[e3] = t; } - if (a[e4] > a[e5]) { char t = a[e4]; a[e4] = a[e5]; a[e5] = t; } + // Sort these elements using a 5-element sorting network + char ae1 = a[e1], ae2 = a[e2], ae3 = a[e3], ae4 = a[e4], ae5 = a[e5]; + + if (ae1 > ae2) { char t = ae1; ae1 = ae2; ae2 = t; } + if (ae4 > ae5) { char t = ae4; ae4 = ae5; ae5 = t; } + if (ae1 > ae3) { char t = ae1; ae1 = ae3; ae3 = t; } + if (ae2 > ae3) { char t = ae2; ae2 = ae3; ae3 = t; } + if (ae1 > ae4) { char t = ae1; ae1 = ae4; ae4 = t; } + if (ae3 > ae4) { char t = ae3; ae3 = ae4; ae4 = t; } + if (ae2 > ae5) { char t = ae2; ae2 = ae5; ae5 = t; } + if (ae2 > ae3) { char t = ae2; ae2 = ae3; ae3 = t; } + if (ae4 > ae5) { char t = ae4; ae4 = ae5; ae5 = t; } + + a[e1] = ae1; a[e3] = ae3; a[e5] = ae5; /* * Use the second and fourth of the five sorted elements as pivots. @@ -899,8 +937,8 @@ final class DualPivotQuicksort { * the pivots are swapped back into their final positions, and * excluded from subsequent sorting. */ - char pivot1 = a[e2]; a[e2] = a[left]; - char pivot2 = a[e4]; a[e4] = a[right]; + char pivot1 = ae2; a[e2] = a[left]; + char pivot2 = ae4; a[e4] = a[right]; /* * Partitioning @@ -929,21 +967,25 @@ final class DualPivotQuicksort { * * Pointer k is the first index of ?-part */ + outer: for (int k = less; k <= great; k++) { char ak = a[k]; - if (ak < pivot1) { - a[k] = a[less]; - a[less++] = ak; + if (k > less) { + a[k] = a[less]; + a[less] = ak; + } + less++; } else if (ak > pivot2) { - while (a[great] > pivot2 && k < great) { - great--; + while (a[great] > pivot2) { + if (k == great--) { + break outer; + } } a[k] = a[great]; a[great--] = ak; - ak = a[k]; - if (ak < pivot1) { + if ((ak = a[k]) < pivot1) { a[k] = a[less]; a[less++] = ak; } @@ -971,24 +1013,28 @@ final class DualPivotQuicksort { * * Pointer k is the first index of ?-part */ + outer: for (int k = less; k <= great; k++) { char ak = a[k]; - if (ak == pivot1) { - continue; + continue; } if (ak < pivot1) { - a[k] = a[less]; - a[less++] = ak; - } else { + if (k > less) { + a[k] = a[less]; + a[less] = ak; + } + less++; + } else { // a[k] > pivot while (a[great] > pivot1) { - great--; + if (k == great--) { + break outer; + } } a[k] = a[great]; a[great--] = ak; - ak = a[k]; - if (ak < pivot1) { + if ((ak = a[k]) < pivot1) { a[k] = a[less]; a[less++] = ak; } @@ -1020,19 +1066,19 @@ final class DualPivotQuicksort { while (a[less] == pivot1) { less++; } - for (int k = less + 1; k <= great; k++) { - if (a[k] == pivot1) { - a[k] = a[less]; - a[less++] = pivot1; - } - } while (a[great] == pivot2) { great--; } - for (int k = great - 1; k >= less; k--) { - if (a[k] == pivot2) { + for (int k = less + 1; k <= great; ) { + char ak = a[k]; + if (ak == pivot1) { + a[k++] = a[less]; + a[less++] = pivot1; + } else if (ak == pivot2) { a[k] = a[great]; a[great--] = pivot2; + } else { + k++; } } } @@ -1087,7 +1133,6 @@ final class DualPivotQuicksort { for (int k = left + 1; k <= right; k++) { byte ak = a[k]; int j; - for (j = k - 1; j >= left && ak < a[j]; j--) { a[j + 1] = a[j]; } @@ -1129,16 +1174,20 @@ final class DualPivotQuicksort { int e4 = e3 + sixth; int e2 = e3 - sixth; - // Sort these elements in place using a 5-element sorting network - if (a[e1] > a[e2]) { byte t = a[e1]; a[e1] = a[e2]; a[e2] = t; } - if (a[e4] > a[e5]) { byte t = a[e4]; a[e4] = a[e5]; a[e5] = t; } - if (a[e1] > a[e3]) { byte t = a[e1]; a[e1] = a[e3]; a[e3] = t; } - if (a[e2] > a[e3]) { byte t = a[e2]; a[e2] = a[e3]; a[e3] = t; } - if (a[e1] > a[e4]) { byte t = a[e1]; a[e1] = a[e4]; a[e4] = t; } - if (a[e3] > a[e4]) { byte t = a[e3]; a[e3] = a[e4]; a[e4] = t; } - if (a[e2] > a[e5]) { byte t = a[e2]; a[e2] = a[e5]; a[e5] = t; } - if (a[e2] > a[e3]) { byte t = a[e2]; a[e2] = a[e3]; a[e3] = t; } - if (a[e4] > a[e5]) { byte t = a[e4]; a[e4] = a[e5]; a[e5] = t; } + // Sort these elements using a 5-element sorting network + byte ae1 = a[e1], ae2 = a[e2], ae3 = a[e3], ae4 = a[e4], ae5 = a[e5]; + + if (ae1 > ae2) { byte t = ae1; ae1 = ae2; ae2 = t; } + if (ae4 > ae5) { byte t = ae4; ae4 = ae5; ae5 = t; } + if (ae1 > ae3) { byte t = ae1; ae1 = ae3; ae3 = t; } + if (ae2 > ae3) { byte t = ae2; ae2 = ae3; ae3 = t; } + if (ae1 > ae4) { byte t = ae1; ae1 = ae4; ae4 = t; } + if (ae3 > ae4) { byte t = ae3; ae3 = ae4; ae4 = t; } + if (ae2 > ae5) { byte t = ae2; ae2 = ae5; ae5 = t; } + if (ae2 > ae3) { byte t = ae2; ae2 = ae3; ae3 = t; } + if (ae4 > ae5) { byte t = ae4; ae4 = ae5; ae5 = t; } + + a[e1] = ae1; a[e3] = ae3; a[e5] = ae5; /* * Use the second and fourth of the five sorted elements as pivots. @@ -1151,8 +1200,8 @@ final class DualPivotQuicksort { * the pivots are swapped back into their final positions, and * excluded from subsequent sorting. */ - byte pivot1 = a[e2]; a[e2] = a[left]; - byte pivot2 = a[e4]; a[e4] = a[right]; + byte pivot1 = ae2; a[e2] = a[left]; + byte pivot2 = ae4; a[e4] = a[right]; /* * Partitioning @@ -1181,21 +1230,25 @@ final class DualPivotQuicksort { * * Pointer k is the first index of ?-part */ + outer: for (int k = less; k <= great; k++) { byte ak = a[k]; - if (ak < pivot1) { - a[k] = a[less]; - a[less++] = ak; + if (k > less) { + a[k] = a[less]; + a[less] = ak; + } + less++; } else if (ak > pivot2) { - while (a[great] > pivot2 && k < great) { - great--; + while (a[great] > pivot2) { + if (k == great--) { + break outer; + } } a[k] = a[great]; a[great--] = ak; - ak = a[k]; - if (ak < pivot1) { + if ((ak = a[k]) < pivot1) { a[k] = a[less]; a[less++] = ak; } @@ -1223,24 +1276,28 @@ final class DualPivotQuicksort { * * Pointer k is the first index of ?-part */ + outer: for (int k = less; k <= great; k++) { byte ak = a[k]; - if (ak == pivot1) { - continue; + continue; } if (ak < pivot1) { - a[k] = a[less]; - a[less++] = ak; - } else { + if (k > less) { + a[k] = a[less]; + a[less] = ak; + } + less++; + } else { // a[k] > pivot while (a[great] > pivot1) { - great--; + if (k == great--) { + break outer; + } } a[k] = a[great]; a[great--] = ak; - ak = a[k]; - if (ak < pivot1) { + if ((ak = a[k]) < pivot1) { a[k] = a[less]; a[less++] = ak; } @@ -1272,19 +1329,19 @@ final class DualPivotQuicksort { while (a[less] == pivot1) { less++; } - for (int k = less + 1; k <= great; k++) { - if (a[k] == pivot1) { - a[k] = a[less]; - a[less++] = pivot1; - } - } while (a[great] == pivot2) { great--; } - for (int k = great - 1; k >= less; k--) { - if (a[k] == pivot2) { + for (int k = less + 1; k <= great; ) { + byte ak = a[k]; + if (ak == pivot1) { + a[k++] = a[less]; + a[less++] = pivot1; + } else if (ak == pivot2) { a[k] = a[great]; a[great--] = pivot2; + } else { + k++; } } } @@ -1356,7 +1413,6 @@ final class DualPivotQuicksort { for (int k = left; k <= n; k++) { float ak = a[k]; - if (ak == 0.0f && NEGATIVE_ZERO == Float.floatToIntBits(ak)) { a[k] = 0.0f; numNegativeZeros++; @@ -1432,7 +1488,6 @@ final class DualPivotQuicksort { for (int k = left + 1; k <= right; k++) { float ak = a[k]; int j; - for (j = k - 1; j >= left && ak < a[j]; j--) { a[j + 1] = a[j]; } @@ -1460,16 +1515,20 @@ final class DualPivotQuicksort { int e4 = e3 + sixth; int e2 = e3 - sixth; - // Sort these elements in place using a 5-element sorting network - if (a[e1] > a[e2]) { float t = a[e1]; a[e1] = a[e2]; a[e2] = t; } - if (a[e4] > a[e5]) { float t = a[e4]; a[e4] = a[e5]; a[e5] = t; } - if (a[e1] > a[e3]) { float t = a[e1]; a[e1] = a[e3]; a[e3] = t; } - if (a[e2] > a[e3]) { float t = a[e2]; a[e2] = a[e3]; a[e3] = t; } - if (a[e1] > a[e4]) { float t = a[e1]; a[e1] = a[e4]; a[e4] = t; } - if (a[e3] > a[e4]) { float t = a[e3]; a[e3] = a[e4]; a[e4] = t; } - if (a[e2] > a[e5]) { float t = a[e2]; a[e2] = a[e5]; a[e5] = t; } - if (a[e2] > a[e3]) { float t = a[e2]; a[e2] = a[e3]; a[e3] = t; } - if (a[e4] > a[e5]) { float t = a[e4]; a[e4] = a[e5]; a[e5] = t; } + // Sort these elements using a 5-element sorting network + float ae1 = a[e1], ae2 = a[e2], ae3 = a[e3], ae4 = a[e4], ae5 = a[e5]; + + if (ae1 > ae2) { float t = ae1; ae1 = ae2; ae2 = t; } + if (ae4 > ae5) { float t = ae4; ae4 = ae5; ae5 = t; } + if (ae1 > ae3) { float t = ae1; ae1 = ae3; ae3 = t; } + if (ae2 > ae3) { float t = ae2; ae2 = ae3; ae3 = t; } + if (ae1 > ae4) { float t = ae1; ae1 = ae4; ae4 = t; } + if (ae3 > ae4) { float t = ae3; ae3 = ae4; ae4 = t; } + if (ae2 > ae5) { float t = ae2; ae2 = ae5; ae5 = t; } + if (ae2 > ae3) { float t = ae2; ae2 = ae3; ae3 = t; } + if (ae4 > ae5) { float t = ae4; ae4 = ae5; ae5 = t; } + + a[e1] = ae1; a[e3] = ae3; a[e5] = ae5; /* * Use the second and fourth of the five sorted elements as pivots. @@ -1482,8 +1541,8 @@ final class DualPivotQuicksort { * the pivots are swapped back into their final positions, and * excluded from subsequent sorting. */ - float pivot1 = a[e2]; a[e2] = a[left]; - float pivot2 = a[e4]; a[e4] = a[right]; + float pivot1 = ae2; a[e2] = a[left]; + float pivot2 = ae4; a[e4] = a[right]; /* * Partitioning @@ -1512,21 +1571,25 @@ final class DualPivotQuicksort { * * Pointer k is the first index of ?-part */ + outer: for (int k = less; k <= great; k++) { float ak = a[k]; - if (ak < pivot1) { - a[k] = a[less]; - a[less++] = ak; + if (k > less) { + a[k] = a[less]; + a[less] = ak; + } + less++; } else if (ak > pivot2) { - while (a[great] > pivot2 && k < great) { - great--; + while (a[great] > pivot2) { + if (k == great--) { + break outer; + } } a[k] = a[great]; a[great--] = ak; - ak = a[k]; - if (ak < pivot1) { + if ((ak = a[k]) < pivot1) { a[k] = a[less]; a[less++] = ak; } @@ -1554,24 +1617,28 @@ final class DualPivotQuicksort { * * Pointer k is the first index of ?-part */ + outer: for (int k = less; k <= great; k++) { float ak = a[k]; - if (ak == pivot1) { - continue; + continue; } if (ak < pivot1) { - a[k] = a[less]; - a[less++] = ak; - } else { + if (k > less) { + a[k] = a[less]; + a[less] = ak; + } + less++; + } else { // a[k] > pivot while (a[great] > pivot1) { - great--; + if (k == great--) { + break outer; + } } a[k] = a[great]; a[great--] = ak; - ak = a[k]; - if (ak < pivot1) { + if ((ak = a[k]) < pivot1) { a[k] = a[less]; a[less++] = ak; } @@ -1603,19 +1670,19 @@ final class DualPivotQuicksort { while (a[less] == pivot1) { less++; } - for (int k = less + 1; k <= great; k++) { - if (a[k] == pivot1) { - a[k] = a[less]; - a[less++] = pivot1; - } - } while (a[great] == pivot2) { great--; } - for (int k = great - 1; k >= less; k--) { - if (a[k] == pivot2) { + for (int k = less + 1; k <= great; ) { + float ak = a[k]; + if (ak == pivot1) { + a[k++] = a[less]; + a[less++] = pivot1; + } else if (ak == pivot2) { a[k] = a[great]; a[great--] = pivot2; + } else { + k++; } } } @@ -1687,7 +1754,6 @@ final class DualPivotQuicksort { for (int k = left; k <= n; k++) { double ak = a[k]; - if (ak == 0.0d && NEGATIVE_ZERO == Double.doubleToLongBits(ak)) { a[k] = 0.0d; numNegativeZeros++; @@ -1763,7 +1829,6 @@ final class DualPivotQuicksort { for (int k = left + 1; k <= right; k++) { double ak = a[k]; int j; - for (j = k - 1; j >= left && ak < a[j]; j--) { a[j + 1] = a[j]; } @@ -1791,16 +1856,20 @@ final class DualPivotQuicksort { int e4 = e3 + sixth; int e2 = e3 - sixth; - // Sort these elements in place using a 5-element sorting network - if (a[e1] > a[e2]) { double t = a[e1]; a[e1] = a[e2]; a[e2] = t; } - if (a[e4] > a[e5]) { double t = a[e4]; a[e4] = a[e5]; a[e5] = t; } - if (a[e1] > a[e3]) { double t = a[e1]; a[e1] = a[e3]; a[e3] = t; } - if (a[e2] > a[e3]) { double t = a[e2]; a[e2] = a[e3]; a[e3] = t; } - if (a[e1] > a[e4]) { double t = a[e1]; a[e1] = a[e4]; a[e4] = t; } - if (a[e3] > a[e4]) { double t = a[e3]; a[e3] = a[e4]; a[e4] = t; } - if (a[e2] > a[e5]) { double t = a[e2]; a[e2] = a[e5]; a[e5] = t; } - if (a[e2] > a[e3]) { double t = a[e2]; a[e2] = a[e3]; a[e3] = t; } - if (a[e4] > a[e5]) { double t = a[e4]; a[e4] = a[e5]; a[e5] = t; } + // Sort these elements using a 5-element sorting network + double ae1 = a[e1], ae2 = a[e2], ae3 = a[e3], ae4 = a[e4], ae5 = a[e5]; + + if (ae1 > ae2) { double t = ae1; ae1 = ae2; ae2 = t; } + if (ae4 > ae5) { double t = ae4; ae4 = ae5; ae5 = t; } + if (ae1 > ae3) { double t = ae1; ae1 = ae3; ae3 = t; } + if (ae2 > ae3) { double t = ae2; ae2 = ae3; ae3 = t; } + if (ae1 > ae4) { double t = ae1; ae1 = ae4; ae4 = t; } + if (ae3 > ae4) { double t = ae3; ae3 = ae4; ae4 = t; } + if (ae2 > ae5) { double t = ae2; ae2 = ae5; ae5 = t; } + if (ae2 > ae3) { double t = ae2; ae2 = ae3; ae3 = t; } + if (ae4 > ae5) { double t = ae4; ae4 = ae5; ae5 = t; } + + a[e1] = ae1; a[e3] = ae3; a[e5] = ae5; /* * Use the second and fourth of the five sorted elements as pivots. @@ -1813,8 +1882,8 @@ final class DualPivotQuicksort { * the pivots are swapped back into their final positions, and * excluded from subsequent sorting. */ - double pivot1 = a[e2]; a[e2] = a[left]; - double pivot2 = a[e4]; a[e4] = a[right]; + double pivot1 = ae2; a[e2] = a[left]; + double pivot2 = ae4; a[e4] = a[right]; /* * Partitioning @@ -1843,21 +1912,25 @@ final class DualPivotQuicksort { * * Pointer k is the first index of ?-part */ + outer: for (int k = less; k <= great; k++) { double ak = a[k]; - if (ak < pivot1) { - a[k] = a[less]; - a[less++] = ak; + if (k > less) { + a[k] = a[less]; + a[less] = ak; + } + less++; } else if (ak > pivot2) { - while (a[great] > pivot2 && k < great) { - great--; + while (a[great] > pivot2) { + if (k == great--) { + break outer; + } } a[k] = a[great]; a[great--] = ak; - ak = a[k]; - if (ak < pivot1) { + if ((ak = a[k]) < pivot1) { a[k] = a[less]; a[less++] = ak; } @@ -1885,24 +1958,28 @@ final class DualPivotQuicksort { * * Pointer k is the first index of ?-part */ + outer: for (int k = less; k <= great; k++) { double ak = a[k]; - if (ak == pivot1) { - continue; + continue; } if (ak < pivot1) { - a[k] = a[less]; - a[less++] = ak; - } else { + if (k > less) { + a[k] = a[less]; + a[less] = ak; + } + less++; + } else { // a[k] > pivot while (a[great] > pivot1) { - great--; + if (k == great--) { + break outer; + } } a[k] = a[great]; a[great--] = ak; - ak = a[k]; - if (ak < pivot1) { + if ((ak = a[k]) < pivot1) { a[k] = a[less]; a[less++] = ak; } @@ -1934,19 +2011,19 @@ final class DualPivotQuicksort { while (a[less] == pivot1) { less++; } - for (int k = less + 1; k <= great; k++) { - if (a[k] == pivot1) { - a[k] = a[less]; - a[less++] = pivot1; - } - } while (a[great] == pivot2) { great--; } - for (int k = great - 1; k >= less; k--) { - if (a[k] == pivot2) { + for (int k = less + 1; k <= great; ) { + double ak = a[k]; + if (ak == pivot1) { + a[k++] = a[less]; + a[less++] = pivot1; + } else if (ak == pivot2) { a[k] = a[great]; a[great--] = pivot2; + } else { + k++; } } } diff --git a/src/share/classes/javax/print/attribute/standard/PrinterStateReasons.java b/src/share/classes/javax/print/attribute/standard/PrinterStateReasons.java index 14225b90e46f6d1bb68ba379faf015dd2d4c1c60..2b0e8d2ab0c081aeed37d7b1c13967baaf88765b 100644 --- a/src/share/classes/javax/print/attribute/standard/PrinterStateReasons.java +++ b/src/share/classes/javax/print/attribute/standard/PrinterStateReasons.java @@ -65,7 +65,7 @@ import javax.print.attribute.PrintServiceAttribute; * PrinterStateReason PrinterStateReason} objects to an existing * PrinterStateReasons object and remove them again. However, like class * {@link java.util.HashMap java.util.HashMap}, class PrinterStateReasons is - * bot multiple thread safe. If a PrinterStateReasons object will be used by + * not multiple thread safe. If a PrinterStateReasons object will be used by * multiple threads, be sure to synchronize its operations (e.g., using a * synchronized map view obtained from class {@link java.util.Collections * java.util.Collections}). diff --git a/src/share/classes/javax/security/auth/Subject.java b/src/share/classes/javax/security/auth/Subject.java index ecc66fbe055a8d1c519e8df5ff357d1c01c1f4cc..1e404d6db1da219ce9f8ce8975888cc7f54e0411 100644 --- a/src/share/classes/javax/security/auth/Subject.java +++ b/src/share/classes/javax/security/auth/Subject.java @@ -40,7 +40,6 @@ import java.security.PrivilegedExceptionAction; import java.security.PrivilegedActionException; import java.security.ProtectionDomain; import sun.security.util.ResourcesMgr; -import sun.security.util.SecurityConstants; /** *

A Subject represents a grouping of related information @@ -239,7 +238,7 @@ public final class Subject implements java.io.Serializable { public void setReadOnly() { java.lang.SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm.checkPermission(new AuthPermission("setReadOnly")); + sm.checkPermission(AuthPermissionHolder.SET_READ_ONLY_PERMISSION); } this.readOnly = true; @@ -285,7 +284,7 @@ public final class Subject implements java.io.Serializable { java.lang.SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm.checkPermission(new AuthPermission("getSubject")); + sm.checkPermission(AuthPermissionHolder.GET_SUBJECT_PERMISSION); } if (acc == null) { @@ -343,7 +342,7 @@ public final class Subject implements java.io.Serializable { java.lang.SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm.checkPermission(SecurityConstants.DO_AS_PERMISSION); + sm.checkPermission(AuthPermissionHolder.DO_AS_PERMISSION); } if (action == null) throw new NullPointerException @@ -402,7 +401,7 @@ public final class Subject implements java.io.Serializable { java.lang.SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm.checkPermission(SecurityConstants.DO_AS_PERMISSION); + sm.checkPermission(AuthPermissionHolder.DO_AS_PERMISSION); } if (action == null) @@ -456,7 +455,7 @@ public final class Subject implements java.io.Serializable { java.lang.SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm.checkPermission(SecurityConstants.DO_AS_PRIVILEGED_PERMISSION); + sm.checkPermission(AuthPermissionHolder.DO_AS_PRIVILEGED_PERMISSION); } if (action == null) @@ -520,7 +519,7 @@ public final class Subject implements java.io.Serializable { java.lang.SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm.checkPermission(SecurityConstants.DO_AS_PRIVILEGED_PERMISSION); + sm.checkPermission(AuthPermissionHolder.DO_AS_PRIVILEGED_PERMISSION); } if (action == null) @@ -1044,16 +1043,13 @@ public final class Subject implements java.io.Serializable { if (sm != null) { switch (which) { case Subject.PRINCIPAL_SET: - sm.checkPermission(new AuthPermission - ("modifyPrincipals")); + sm.checkPermission(AuthPermissionHolder.MODIFY_PRINCIPALS_PERMISSION); break; case Subject.PUB_CREDENTIAL_SET: - sm.checkPermission(new AuthPermission - ("modifyPublicCredentials")); + sm.checkPermission(AuthPermissionHolder.MODIFY_PUBLIC_CREDENTIALS_PERMISSION); break; default: - sm.checkPermission(new AuthPermission - ("modifyPrivateCredentials")); + sm.checkPermission(AuthPermissionHolder.MODIFY_PRIVATE_CREDENTIALS_PERMISSION); break; } } @@ -1073,16 +1069,13 @@ public final class Subject implements java.io.Serializable { if (sm != null) { switch (which) { case Subject.PRINCIPAL_SET: - sm.checkPermission - (new AuthPermission("modifyPrincipals")); + sm.checkPermission(AuthPermissionHolder.MODIFY_PRINCIPALS_PERMISSION); break; case Subject.PUB_CREDENTIAL_SET: - sm.checkPermission - (new AuthPermission("modifyPublicCredentials")); + sm.checkPermission(AuthPermissionHolder.MODIFY_PUBLIC_CREDENTIALS_PERMISSION); break; default: - sm.checkPermission - (new AuthPermission("modifyPrivateCredentials")); + sm.checkPermission(AuthPermissionHolder.MODIFY_PRIVATE_CREDENTIALS_PERMISSION); break; } } @@ -1405,4 +1398,27 @@ public final class Subject implements java.io.Serializable { return set.add(o); } } + + static class AuthPermissionHolder { + static final AuthPermission DO_AS_PERMISSION = + new AuthPermission("doAs"); + + static final AuthPermission DO_AS_PRIVILEGED_PERMISSION = + new AuthPermission("doAsPrivileged"); + + static final AuthPermission SET_READ_ONLY_PERMISSION = + new AuthPermission("setReadOnly"); + + static final AuthPermission GET_SUBJECT_PERMISSION = + new AuthPermission("getSubject"); + + static final AuthPermission MODIFY_PRINCIPALS_PERMISSION = + new AuthPermission("modifyPrincipals"); + + static final AuthPermission MODIFY_PUBLIC_CREDENTIALS_PERMISSION = + new AuthPermission("modifyPublicCredentials"); + + static final AuthPermission MODIFY_PRIVATE_CREDENTIALS_PERMISSION = + new AuthPermission("modifyPrivateCredentials"); + } } diff --git a/src/share/classes/javax/swing/JComponent.java b/src/share/classes/javax/swing/JComponent.java index f0be74509f99e93ed5aaec6bf2fbaecb5e962b63..37f7e7d47307da81e9aa15ba02f542780e345f1f 100644 --- a/src/share/classes/javax/swing/JComponent.java +++ b/src/share/classes/javax/swing/JComponent.java @@ -795,7 +795,6 @@ public abstract class JComponent extends Container implements Serializable, * @see java.awt.Container#paint */ protected void paintChildren(Graphics g) { - boolean isJComponent; Graphics sg = g; synchronized(getTreeLock()) { @@ -826,12 +825,21 @@ public abstract class JComponent extends Container implements Serializable, } } boolean printing = getFlag(IS_PRINTING); + final Window window = SwingUtilities.getWindowAncestor(this); + final boolean isWindowOpaque = window == null || window.isOpaque(); for (; i >= 0 ; i--) { Component comp = getComponent(i); - isJComponent = (comp instanceof JComponent); - if (comp != null && - (isJComponent || isLightweightComponent(comp)) && - (comp.isVisible() == true)) { + if (comp == null) { + continue; + } + + final boolean isJComponent = comp instanceof JComponent; + + // Enable painting of heavyweights in non-opaque windows. + // See 6884960 + if ((!isWindowOpaque || isJComponent || + isLightweightComponent(comp)) && comp.isVisible()) + { Rectangle cr; cr = comp.getBounds(tmpRect); @@ -887,6 +895,8 @@ public abstract class JComponent extends Container implements Serializable, } } } else { + // The component is either lightweight, or + // heavyweight in a non-opaque window if (!printing) { comp.paint(cg); } @@ -4868,7 +4878,9 @@ public abstract class JComponent extends Container implements Serializable, * @see #revalidate * @see java.awt.Component#invalidate * @see java.awt.Container#validate + * @see java.awt.Container#isValidateRoot */ + @Override public boolean isValidateRoot() { return false; } diff --git a/src/share/classes/javax/swing/JEditorPane.java b/src/share/classes/javax/swing/JEditorPane.java index 4dfbf92488ea19183bbf62437b4d7899ee382e56..eaf61f1e60e33d38d1d648efe86c6d77d466ebdd 100644 --- a/src/share/classes/javax/swing/JEditorPane.java +++ b/src/share/classes/javax/swing/JEditorPane.java @@ -1330,7 +1330,7 @@ public class JEditorPane extends JTextComponent { */ public Dimension getPreferredSize() { Dimension d = super.getPreferredSize(); - JViewport port = SwingUtilities2.getViewport(this); + JViewport port = SwingUtilities.getParentViewport(this); if (port != null) { TextUI ui = getUI(); int prefWidth = d.width; @@ -1452,7 +1452,7 @@ public class JEditorPane extends JTextComponent { * match its own, false otherwise */ public boolean getScrollableTracksViewportWidth() { - JViewport port = SwingUtilities2.getViewport(this); + JViewport port = SwingUtilities.getParentViewport(this); if (port != null) { TextUI ui = getUI(); int w = port.getWidth(); @@ -1474,7 +1474,7 @@ public class JEditorPane extends JTextComponent { * false otherwise */ public boolean getScrollableTracksViewportHeight() { - JViewport port = SwingUtilities2.getViewport(this); + JViewport port = SwingUtilities.getParentViewport(this); if (port != null) { TextUI ui = getUI(); int h = port.getHeight(); diff --git a/src/share/classes/javax/swing/JList.java b/src/share/classes/javax/swing/JList.java index 796ac11ba6c91060e7f016179cae6bbef3cc9f00..6c06c5ea6827a245dddd804e8d8fc4accc3fae3c 100644 --- a/src/share/classes/javax/swing/JList.java +++ b/src/share/classes/javax/swing/JList.java @@ -2722,7 +2722,7 @@ public class JList extends JComponent implements Scrollable, Accessible getVisibleRowCount() <= 0) { return true; } - JViewport port = SwingUtilities2.getViewport(this); + JViewport port = SwingUtilities.getParentViewport(this); if (port != null) { return port.getWidth() > getPreferredSize().width; } @@ -2748,7 +2748,7 @@ public class JList extends JComponent implements Scrollable, Accessible getVisibleRowCount() <= 0) { return true; } - JViewport port = SwingUtilities2.getViewport(this); + JViewport port = SwingUtilities.getParentViewport(this); if (port != null) { return port.getHeight() > getPreferredSize().height; } diff --git a/src/share/classes/javax/swing/JRootPane.java b/src/share/classes/javax/swing/JRootPane.java index a210c3791c4e889e21ef2b2cd56ae4256b064f40..f6964f728ef73809f5c9cb91e2ad4d083b1e3c16 100644 --- a/src/share/classes/javax/swing/JRootPane.java +++ b/src/share/classes/javax/swing/JRootPane.java @@ -725,8 +725,10 @@ public class JRootPane extends JComponent implements Accessible { * because both classes override isValidateRoot to return true. * * @see JComponent#isValidateRoot + * @see java.awt.Container#isValidateRoot * @return true */ + @Override public boolean isValidateRoot() { return true; } diff --git a/src/share/classes/javax/swing/JScrollPane.java b/src/share/classes/javax/swing/JScrollPane.java index b2be43cd15fc8fed68cff816399266e945f28828..b813d4fccdc0747857874c3dfc8df0f1757f0bab 100644 --- a/src/share/classes/javax/swing/JScrollPane.java +++ b/src/share/classes/javax/swing/JScrollPane.java @@ -453,10 +453,12 @@ public class JScrollPane extends JComponent implements ScrollPaneConstants, Acce * @see java.awt.Container#validate * @see JComponent#revalidate * @see JComponent#isValidateRoot + * @see java.awt.Container#isValidateRoot * * @beaninfo * hidden: true */ + @Override public boolean isValidateRoot() { return true; } diff --git a/src/share/classes/javax/swing/JSplitPane.java b/src/share/classes/javax/swing/JSplitPane.java index b5d8ec7d2b513997df020fb823acf83e2c2c85f4..f3baff66492b2d23590f6067b118e72403023dce 100644 --- a/src/share/classes/javax/swing/JSplitPane.java +++ b/src/share/classes/javax/swing/JSplitPane.java @@ -947,10 +947,12 @@ public class JSplitPane extends JComponent implements Accessible * * @return true * @see JComponent#revalidate + * @see java.awt.Container#isValidateRoot * * @beaninfo * hidden: true */ + @Override public boolean isValidateRoot() { return true; } diff --git a/src/share/classes/javax/swing/JTable.java b/src/share/classes/javax/swing/JTable.java index 521f17ab8a5d9bf4b6451c08452d8d8a941e58e4..5489c380f1a143124855ca094604fc0db38e4467 100644 --- a/src/share/classes/javax/swing/JTable.java +++ b/src/share/classes/javax/swing/JTable.java @@ -57,6 +57,7 @@ import sun.swing.SwingUtilities2; import sun.swing.SwingUtilities2.Section; import static sun.swing.SwingUtilities2.Section.*; import sun.swing.PrintingStatus; +import sun.swing.SwingLazyValue; /** * The JTable is used to display and edit regular two-dimensional tables @@ -718,7 +719,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable * @see #addNotify */ protected void configureEnclosingScrollPane() { - JViewport port = SwingUtilities2.getViewport(this); + JViewport port = SwingUtilities.getParentViewport(this); if (port != null) { Container gp = port.getParent(); if (gp instanceof JScrollPane) { @@ -727,7 +728,8 @@ public class JTable extends JComponent implements TableModelListener, Scrollable // example, the rowHeaderView of the scrollPane - // an implementor of fixed columns might do this. JViewport viewport = scrollPane.getViewport(); - if (viewport == null || viewport.getView() != this) { + if (viewport == null || + SwingUtilities.getUnwrappedView(viewport) != this) { return; } scrollPane.setColumnHeaderView(getTableHeader()); @@ -750,7 +752,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable * from configureEnclosingScrollPane() and updateUI() in a safe manor. */ private void configureEnclosingScrollPaneUI() { - JViewport port = SwingUtilities2.getViewport(this); + JViewport port = SwingUtilities.getParentViewport(this); if (port != null) { Container gp = port.getParent(); if (gp instanceof JScrollPane) { @@ -759,7 +761,8 @@ public class JTable extends JComponent implements TableModelListener, Scrollable // example, the rowHeaderView of the scrollPane - // an implementor of fixed columns might do this. JViewport viewport = scrollPane.getViewport(); - if (viewport == null || viewport.getView() != this) { + if (viewport == null || + SwingUtilities.getUnwrappedView(viewport) != this) { return; } // scrollPane.getViewport().setBackingStoreEnabled(true); @@ -819,7 +822,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable * @since 1.3 */ protected void unconfigureEnclosingScrollPane() { - JViewport port = SwingUtilities2.getViewport(this); + JViewport port = SwingUtilities.getParentViewport(this); if (port != null) { Container gp = port.getParent(); if (gp instanceof JScrollPane) { @@ -828,7 +831,8 @@ public class JTable extends JComponent implements TableModelListener, Scrollable // example, the rowHeaderView of the scrollPane - // an implementor of fixed columns might do this. JViewport viewport = scrollPane.getViewport(); - if (viewport == null || viewport.getView() != this) { + if (viewport == null || + SwingUtilities.getUnwrappedView(viewport) != this) { return; } scrollPane.setColumnHeaderView(null); @@ -5215,7 +5219,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable * @see #getFillsViewportHeight */ public boolean getScrollableTracksViewportHeight() { - JViewport port = SwingUtilities2.getViewport(this); + JViewport port = SwingUtilities.getParentViewport(this); return getFillsViewportHeight() && port != null && port.getHeight() > getPreferredSize().height; @@ -5316,7 +5320,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable } private void setLazyValue(Hashtable h, Class c, String s) { - h.put(c, new UIDefaults.ProxyLazyValue(s)); + h.put(c, new SwingLazyValue(s)); } private void setLazyRenderer(Class c, String s) { diff --git a/src/share/classes/javax/swing/JTextField.java b/src/share/classes/javax/swing/JTextField.java index de408914d2222c156ba4530bda43237b00b3f4af..24a3408d1b4a98b947919f33a680a0ebed1a9b2f 100644 --- a/src/share/classes/javax/swing/JTextField.java +++ b/src/share/classes/javax/swing/JTextField.java @@ -288,9 +288,11 @@ public class JTextField extends JTextComponent implements SwingConstants { * * @see JComponent#revalidate * @see JComponent#isValidateRoot + * @see java.awt.Container#isValidateRoot */ + @Override public boolean isValidateRoot() { - return SwingUtilities2.getViewport(this) == null; + return SwingUtilities.getParentViewport(this) == null; } diff --git a/src/share/classes/javax/swing/JTree.java b/src/share/classes/javax/swing/JTree.java index 1b200f78591a476b0e10f1555af558fe08ae57b7..55815b81dc26ae851921d8278ff202558d97f0d7 100644 --- a/src/share/classes/javax/swing/JTree.java +++ b/src/share/classes/javax/swing/JTree.java @@ -3498,7 +3498,7 @@ public class JTree extends JComponent implements Scrollable, Accessible * @see Scrollable#getScrollableTracksViewportWidth */ public boolean getScrollableTracksViewportWidth() { - JViewport port = SwingUtilities2.getViewport(this); + JViewport port = SwingUtilities.getParentViewport(this); if (port != null) { return port.getWidth() > getPreferredSize().width; } @@ -3515,7 +3515,7 @@ public class JTree extends JComponent implements Scrollable, Accessible * @see Scrollable#getScrollableTracksViewportHeight */ public boolean getScrollableTracksViewportHeight() { - JViewport port = SwingUtilities2.getViewport(this); + JViewport port = SwingUtilities.getParentViewport(this); if (port != null) { return port.getHeight() > getPreferredSize().height; } diff --git a/src/share/classes/javax/swing/JViewport.java b/src/share/classes/javax/swing/JViewport.java index 734e80a05570d03e004aad8a37ee557811b592d0..5073a891af4e76db0ae31d3b532f116d483e65d9 100644 --- a/src/share/classes/javax/swing/JViewport.java +++ b/src/share/classes/javax/swing/JViewport.java @@ -469,49 +469,12 @@ public class JViewport extends JComponent implements Accessible * is the synchronous version of a revalidate. */ private void validateView() { - Component validateRoot = null; + Component validateRoot = SwingUtilities.getValidateRoot(this, false); - /* Find the first JComponent ancestor of this component whose - * isValidateRoot() method returns true. - */ - for(Component c = this; c != null; c = c.getParent()) { - if ((c instanceof CellRendererPane) || (c.getPeer() == null)) { - return; - } - if ((c instanceof JComponent) && - (((JComponent)c).isValidateRoot())) { - validateRoot = c; - break; - } - } - - // If no validateRoot, nothing to validate from. if (validateRoot == null) { return; } - // Make sure all ancestors are visible. - Component root = null; - - for(Component c = validateRoot; c != null; c = c.getParent()) { - // We don't check isVisible here, otherwise if the component - // is contained in something like a JTabbedPane when the - // component is made visible again it won't have scrolled - // to the correct location. - if (c.getPeer() == null) { - return; - } - if ((c instanceof Window) || (c instanceof Applet)) { - root = c; - break; - } - } - - // Make sure there is a Window ancestor. - if (root == null) { - return; - } - // Validate the root. validateRoot.validate(); diff --git a/src/share/classes/javax/swing/RepaintManager.java b/src/share/classes/javax/swing/RepaintManager.java index a988b99fbd35d6a0b45d061a28410bac51a9f8a7..c8607d2e4b99042daaa42dda75cf00c9f8900b76 100644 --- a/src/share/classes/javax/swing/RepaintManager.java +++ b/src/share/classes/javax/swing/RepaintManager.java @@ -310,47 +310,13 @@ public class RepaintManager delegate.addInvalidComponent(invalidComponent); return; } - Component validateRoot = null; + Component validateRoot = + SwingUtilities.getValidateRoot(invalidComponent, true); - /* Find the first JComponent ancestor of this component whose - * isValidateRoot() method returns true. - */ - for(Component c = invalidComponent; c != null; c = c.getParent()) { - if ((c instanceof CellRendererPane) || (c.getPeer() == null)) { - return; - } - if ((c instanceof JComponent) && (((JComponent)c).isValidateRoot())) { - validateRoot = c; - break; - } - } - - /* There's no validateRoot to apply validate to, so we're done. - */ if (validateRoot == null) { return; } - /* If the validateRoot and all of its ancestors aren't visible - * then we don't do anything. While we're walking up the tree - * we find the root Window or Applet. - */ - Component root = null; - - for(Component c = validateRoot; c != null; c = c.getParent()) { - if (!c.isVisible() || (c.getPeer() == null)) { - return; - } - if ((c instanceof Window) || (c instanceof Applet)) { - root = c; - break; - } - } - - if (root == null) { - return; - } - /* Lazily create the invalidateComponents vector and add the * validateRoot if it's not there already. If this validateRoot * is already in the vector, we're done. diff --git a/src/share/classes/javax/swing/SwingUtilities.java b/src/share/classes/javax/swing/SwingUtilities.java index d7a26a0dd729555011a93a6ead80acf5c54f6b87..1221c4bce748a9f78a0c4fb48091fa7764d60527 100644 --- a/src/share/classes/javax/swing/SwingUtilities.java +++ b/src/share/classes/javax/swing/SwingUtilities.java @@ -1967,4 +1967,114 @@ public class SwingUtilities implements SwingConstants SwingUtilities.updateComponentTreeUI(component); } } + + /** + * Looks for the first ancestor of the {@code component} + * which is not an instance of {@link JLayer}. + * If this ancestor is an instance of {@code JViewport}, + * this {@code JViewport} is returned, otherwise returns {@code null}. + * The following way of obtaining the parent {@code JViewport} + * is not recommended any more: + *

+     * JViewport port = null;
+     * Container parent = component.getParent();
+     * // not recommended any more
+     * if(parent instanceof JViewport) {
+     *     port = (JViewport) parent;
+     * }
+     * 
+ * Here is the way to go: + *
+     * // the correct way:
+     * JViewport port = SwingUtilities.getParentViewport(component);
+     * 
+ * @param component {@code Component} to get the parent {@code JViewport} of. + * @return the {@code JViewport} instance for the {@code component} + * or {@code null} + * @throws NullPointerException if {@code component} is {@code null} + * + * @since 1.7 + */ + public static JViewport getParentViewport(Component component) { + do { + component = component.getParent(); + if (component instanceof JViewport) { + return (JViewport) component; + } + } while(component instanceof JLayer); + return null; + } + + /** + * Returns the first {@code JViewport}'s descendant + * which is not an instance of {@code JLayer} or {@code null}. + * + * If the {@code viewport}'s view component is not a {@code JLayer}, + * this method is equal to {@link JViewport#getView()} + * otherwise {@link JLayer#getView()} will be recursively tested + * + * @return the first {@code JViewport}'s descendant + * which is not an instance of {@code JLayer} or {@code null}. + * + * @throws NullPointerException if {@code viewport} is {@code null} + * @see JViewport#getView() + * @see JLayer + */ + static Component getUnwrappedView(JViewport viewport) { + Component view = viewport.getView(); + while (view instanceof JLayer) { + view = ((JLayer)view).getView(); + } + return view; + } + + /** + * Retrieves the validate root of a given container. + * + * If the container is contained within a {@code CellRendererPane}, this + * method returns {@code null} due to the synthetic nature of the {@code + * CellRendererPane}. + *

+ * The component hierarchy must be displayable up to the toplevel component + * (either a {@code Frame} or an {@code Applet} object.) Otherwise this + * method returns {@code null}. + *

+ * If the {@code visibleOnly} argument is {@code true}, the found validate + * root and all its parents up to the toplevel component must also be + * visible. Otherwise this method returns {@code null}. + * + * @return the validate root of the given container or null + * @see java.awt.Component#isDisplayable() + * @see java.awt.Component#isVisible() + * @since 1.7 + */ + static Container getValidateRoot(Container c, boolean visibleOnly) { + Container root = null; + + for (; c != null; c = c.getParent()) + { + if (!c.isDisplayable() || c instanceof CellRendererPane) { + return null; + } + if (c.isValidateRoot()) { + root = c; + break; + } + } + + if (root == null) { + return null; + } + + for (; c != null; c = c.getParent()) { + if (!c.isDisplayable() || (visibleOnly && !c.isVisible())) { + return null; + } + if (c instanceof Window || c instanceof Applet) { + return root; + } + } + + return null; + } } diff --git a/src/share/classes/javax/swing/filechooser/FileSystemView.java b/src/share/classes/javax/swing/filechooser/FileSystemView.java index 9f969796bddfdd64b1a26801a519298d9d67ce46..7c7ef7b668697a712703bae9bd5ceb38ce0a9888 100644 --- a/src/share/classes/javax/swing/filechooser/FileSystemView.java +++ b/src/share/classes/javax/swing/filechooser/FileSystemView.java @@ -33,7 +33,8 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.text.MessageFormat; -import java.util.Vector; +import java.util.List; +import java.util.ArrayList; import java.lang.ref.WeakReference; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeEvent; @@ -173,22 +174,27 @@ public abstract class FileSystemView { * @since 1.4 */ public String getSystemDisplayName(File f) { - String name = null; - if (f != null) { - name = f.getName(); - if (!name.equals("..") && !name.equals(".") && - (useSystemExtensionHiding || - !isFileSystem(f) || - isFileSystemRoot(f)) && - ((f instanceof ShellFolder) || - f.exists())) { + if (f == null) { + return null; + } + + String name = f.getName(); + + if (!name.equals("..") && !name.equals(".") && + (useSystemExtensionHiding || !isFileSystem(f) || isFileSystemRoot(f)) && + (f instanceof ShellFolder || f.exists())) { + try { name = getShellFolder(f).getDisplayName(); - if (name == null || name.length() == 0) { - name = f.getPath(); // e.g. "/" - } + } catch (FileNotFoundException e) { + return null; + } + + if (name == null || name.length() == 0) { + name = f.getPath(); // e.g. "/" } } + return name; } @@ -222,17 +228,25 @@ public abstract class FileSystemView { * @since 1.4 */ public Icon getSystemIcon(File f) { - if (f != null) { - ShellFolder sf = getShellFolder(f); - Image img = sf.getIcon(false); - if (img != null) { - return new ImageIcon(img, sf.getFolderType()); - } else { - return UIManager.getIcon(f.isDirectory() ? "FileView.directoryIcon" : "FileView.fileIcon"); - } - } else { + if (f == null) { return null; } + + ShellFolder sf; + + try { + sf = getShellFolder(f); + } catch (FileNotFoundException e) { + return null; + } + + Image img = sf.getIcon(false); + + if (img != null) { + return new ImageIcon(img, sf.getFolderType()); + } else { + return UIManager.getIcon(f.isDirectory() ? "FileView.directoryIcon" : "FileView.fileIcon"); + } } /** @@ -446,24 +460,28 @@ public abstract class FileSystemView { * Gets the list of shown (i.e. not hidden) files. */ public File[] getFiles(File dir, boolean useFileHiding) { - Vector files = new Vector(); - + List files = new ArrayList(); // add all files in dir - File[] names; - if (!(dir instanceof ShellFolder)) { + if (!(dir instanceof ShellFolder)) { + try { dir = getShellFolder(dir); + } catch (FileNotFoundException e) { + return new File[0]; } + } - names = ((ShellFolder)dir).listFiles(!useFileHiding); - File f; + File[] names = ((ShellFolder) dir).listFiles(!useFileHiding); - int nameCount = (names == null) ? 0 : names.length; - for (int i = 0; i < nameCount; i++) { + if (names == null) { + return new File[0]; + } + + for (File f : names) { if (Thread.currentThread().isInterrupted()) { break; } - f = names[i]; + if (!(f instanceof ShellFolder)) { if (isFileSystemRoot(f)) { f = createFileSystemRoot(f); @@ -481,7 +499,7 @@ public abstract class FileSystemView { } } if (!useFileHiding || !isHiddenFile(f)) { - files.addElement(f); + files.add(f); } } @@ -497,42 +515,50 @@ public abstract class FileSystemView { * null if dir is null */ public File getParentDirectory(File dir) { - if (dir != null && dir.exists()) { - ShellFolder sf = getShellFolder(dir); - File psf = sf.getParentFile(); - if (psf != null) { - if (isFileSystem(psf)) { - File f = psf; - if (f != null && !f.exists()) { - // This could be a node under "Network Neighborhood". - File ppsf = psf.getParentFile(); - if (ppsf == null || !isFileSystem(ppsf)) { - // We're mostly after the exists() override for windows below. - f = createFileSystemRoot(f); - } - } - return f; - } else { - return psf; + if (dir == null || !dir.exists()) { + return null; + } + + ShellFolder sf; + + try { + sf = getShellFolder(dir); + } catch (FileNotFoundException e) { + return null; + } + + File psf = sf.getParentFile(); + + if (psf == null) { + return null; + } + + if (isFileSystem(psf)) { + File f = psf; + if (!f.exists()) { + // This could be a node under "Network Neighborhood". + File ppsf = psf.getParentFile(); + if (ppsf == null || !isFileSystem(ppsf)) { + // We're mostly after the exists() override for windows below. + f = createFileSystemRoot(f); } } + return f; + } else { + return psf; } - return null; } - ShellFolder getShellFolder(File f) { - if (!(f instanceof ShellFolder) - && !(f instanceof FileSystemRoot) - && isFileSystemRoot(f)) { - + /** + * Throws {@code FileNotFoundException} if file not found or current thread was interrupted + */ + ShellFolder getShellFolder(File f) throws FileNotFoundException { + if (!(f instanceof ShellFolder) && !(f instanceof FileSystemRoot) && isFileSystemRoot(f)) { f = createFileSystemRoot(f); } + try { return ShellFolder.getShellFolder(f); - } catch (FileNotFoundException e) { - System.err.println("FileSystemView.getShellFolder: f="+f); - e.printStackTrace(); - return null; } catch (InternalError e) { System.err.println("FileSystemView.getShellFolder: f="+f); e.printStackTrace(); @@ -596,9 +622,9 @@ class UnixFileSystemView extends FileSystemView { // Unix - using OpenWindows' default folder name. Can't find one for Motif/CDE. newFolder = createFileObject(containingDir, newFolderString); int i = 1; - while (newFolder.exists() && (i < 100)) { + while (newFolder.exists() && i < 100) { newFolder = createFileObject(containingDir, MessageFormat.format( - newFolderNextString, new Object[] { new Integer(i) })); + newFolderNextString, new Integer(i))); i++; } @@ -612,7 +638,7 @@ class UnixFileSystemView extends FileSystemView { } public boolean isFileSystemRoot(File dir) { - return (dir != null && dir.getAbsolutePath().equals("/")); + return dir != null && dir.getAbsolutePath().equals("/"); } public boolean isDrive(File dir) { @@ -654,7 +680,7 @@ class WindowsFileSystemView extends FileSystemView { public File getChild(File parent, String fileName) { if (fileName.startsWith("\\") - && !(fileName.startsWith("\\\\")) + && !fileName.startsWith("\\\\") && isFileSystem(parent)) { //Path is relative to the root of parent's drive @@ -677,9 +703,13 @@ class WindowsFileSystemView extends FileSystemView { * The Windows implementation gets information from the ShellFolder class. */ public String getSystemTypeDescription(File f) { - if (f != null) { + if (f == null) { + return null; + } + + try { return getShellFolder(f).getFolderType(); - } else { + } catch (FileNotFoundException e) { return null; } } @@ -701,9 +731,9 @@ class WindowsFileSystemView extends FileSystemView { // Using NT's default folder name File newFolder = createFileObject(containingDir, newFolderString); int i = 2; - while (newFolder.exists() && (i < 100)) { + while (newFolder.exists() && i < 100) { newFolder = createFileObject(containingDir, MessageFormat.format( - newFolderNextString, new Object[] { new Integer(i) })); + newFolderNextString, new Integer(i))); i++; } @@ -727,7 +757,7 @@ class WindowsFileSystemView extends FileSystemView { } }); - return (path != null && (path.equals("A:\\") || path.equals("B:\\"))); + return path != null && (path.equals("A:\\") || path.equals("B:\\")); } /** diff --git a/src/share/classes/javax/swing/plaf/LayerUI.java b/src/share/classes/javax/swing/plaf/LayerUI.java index cf64687421a9606add6adcc07102eef7bc9bc45a..7f2967bf465553e453a60b3f4225f878e71789ff 100644 --- a/src/share/classes/javax/swing/plaf/LayerUI.java +++ b/src/share/classes/javax/swing/plaf/LayerUI.java @@ -71,33 +71,410 @@ public class LayerUI * Subclasses should override this method and use * the specified {@code Graphics} object to * render the content of the component. + *

+ * If {@code g} is not an instance of {@code Graphics2D}, + * this method is no-op. * * @param g the {@code Graphics} context in which to paint; * @param c the component being painted; - * it can be safely cast to the {@code JLayer} + * it can be safely cast to {@code JLayer} + * + * @see #configureGraphics(Graphics2D, JLayer) + * @see #paintLayer(Graphics2D, JLayer) */ - @Override public void paint(Graphics g, JComponent c) { - c.paint(g); + if (g instanceof Graphics2D) { + Graphics2D g2 = (Graphics2D) g.create(); + JLayer l = (JLayer) c; + configureGraphics(g2, l); + paintLayer(g2, l); + g2.dispose(); + } + } + + /** + * This method is called by the {@link #paint} method prior to + * {@link #paintLayer} to configure the {@code Graphics2D} object. + * The default implementation is empty. + * + * @param g2 the {@code Graphics2D} object to configure + * @param l the {@code JLayer} being painted + * + * @see #paintLayer(Graphics2D, JLayer) + */ + protected void configureGraphics(Graphics2D g2, JLayer l) { + } + + /** + * Called by the {@link #paint} method, + * subclasses should override this method + * to perform any custom painting operations. + *

+ * The default implementation paints the passed {@code JLayer} as is. + * + * @param g2 the {@code Graphics2D} context in which to paint + * @param l the {@code JLayer} being painted + * + * @see #configureGraphics(Graphics2D, JLayer) + */ + protected void paintLayer(Graphics2D g2, JLayer l) { + l.paint(g2); } /** * Dispatches {@code AWTEvent}s for {@code JLayer} - * and all it subcomponents to this {@code LayerUI} instance. - *

- * To enable the {@code AWTEvent} of the particular type, - * you call {@link javax.swing.JLayer#setLayerEventMask} + * and all its subcomponents to this {@code LayerUI} instance. + *

+ * To enable the {@code AWTEvent}s of a particular type, + * you call {@link JLayer#setLayerEventMask} * in {@link #installUI(javax.swing.JComponent)} * and set the layer event mask to {@code 0} - * in {@link #uninstallUI(javax.swing.JComponent)} after that + * in {@link #uninstallUI(javax.swing.JComponent)} after that. + * By default this method calls the appropriate + * {@code process<event type>Event} + * method for the given class of event. * * @param e the event to be dispatched * @param l the layer this LayerUI is set to * * @see JLayer#setLayerEventMask(long) - * @see javax.swing.JLayer#getLayerEventMask() + * @see #installUI(javax.swing.JComponent) + * @see #uninstallUI(javax.swing.JComponent) + * @see #processComponentEvent + * @see #processFocusEvent + * @see #processKeyEvent + * @see #processMouseEvent + * @see #processMouseMotionEvent + * @see #processInputMethodEvent + * @see #processHierarchyEvent + * @see #processMouseWheelEvent */ public void eventDispatched(AWTEvent e, JLayer l){ + if (e instanceof FocusEvent) { + processFocusEvent((FocusEvent)e, l); + + } else if (e instanceof MouseEvent) { + switch(e.getID()) { + case MouseEvent.MOUSE_PRESSED: + case MouseEvent.MOUSE_RELEASED: + case MouseEvent.MOUSE_CLICKED: + case MouseEvent.MOUSE_ENTERED: + case MouseEvent.MOUSE_EXITED: + processMouseEvent((MouseEvent)e, l); + break; + case MouseEvent.MOUSE_MOVED: + case MouseEvent.MOUSE_DRAGGED: + processMouseMotionEvent((MouseEvent)e, l); + break; + case MouseEvent.MOUSE_WHEEL: + processMouseWheelEvent((MouseWheelEvent)e, l); + break; + } + } else if (e instanceof KeyEvent) { + processKeyEvent((KeyEvent)e, l); + } else if (e instanceof ComponentEvent) { + processComponentEvent((ComponentEvent)e, l); + } else if (e instanceof InputMethodEvent) { + processInputMethodEvent((InputMethodEvent)e, l); + } else if (e instanceof HierarchyEvent) { + switch (e.getID()) { + case HierarchyEvent.HIERARCHY_CHANGED: + processHierarchyEvent((HierarchyEvent)e, l); + break; + case HierarchyEvent.ANCESTOR_MOVED: + case HierarchyEvent.ANCESTOR_RESIZED: + processHierarchyBoundsEvent((HierarchyEvent)e, l); + break; + } + } + } + + /** + * Processes component events occurring on the {@link JLayer} + * or any of its subcomponents. + *

+ * This method is not called unless component events are + * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to. + * Component events are enabled in the overridden {@link #installUI} method + * and should be disabled in the {@link #uninstallUI} method after that. + *

+     * public void installUI(JComponent c) {
+     *    super.installUI(c);
+     *    JLayer l = (JLayer) c;
+     *    l.setLayerEventMask(AWTEvent.COMPONENT_EVENT_MASK);
+     * }
+     *
+     * public void unistallUI(JComponent c) {
+     *     super.uninstallUI(c);
+     *     JLayer l = (JLayer) c;
+     *     l.setLayerEventMask(0);
+     * }
+     * 
+ * + * @param e the {@code ComponentEvent} to be processed + * @param l the layer this {@code LayerUI} instance is set to + * + * @see JLayer#setLayerEventMask(long) + * @see #installUI(javax.swing.JComponent) + * @see #uninstallUI(javax.swing.JComponent) + */ + protected void processComponentEvent(ComponentEvent e, JLayer l) { + } + + /** + * Processes focus events occurring on the {@link JLayer} + * or any of its subcomponents. + *

+ * This method is not called unless focus events are + * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to. + * Focus events are enabled in the overridden {@link #installUI} method + * and should be disabled in the {@link #uninstallUI} method after that. + *

+     * public void installUI(JComponent c) {
+     *    super.installUI(c);
+     *    JLayer l = (JLayer) c;
+     *    l.setLayerEventMask(AWTEvent.FOCUS_EVENT_MASK);
+     * }
+     *
+     * public void unistallUI(JComponent c) {
+     *     super.uninstallUI(c);
+     *     JLayer l = (JLayer) c;
+     *     l.setLayerEventMask(0);
+     * }
+     * 
+ * + * @param e the {@code FocusEvent} to be processed + * @param l the layer this {@code LayerUI} instance is set to + * + * @see JLayer#setLayerEventMask(long) + * @see #installUI(javax.swing.JComponent) + * @see #uninstallUI(javax.swing.JComponent) + */ + protected void processFocusEvent(FocusEvent e, JLayer l) { + } + + /** + * Processes key events occurring on the {@link JLayer} + * or any of its subcomponents. + *

+ * This method is not called unless key events are + * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to. + * Key events are enabled in the overridden {@link #installUI} method + * and should be disabled in the {@link #uninstallUI} method after that. + *

+     * public void installUI(JComponent c) {
+     *    super.installUI(c);
+     *    JLayer l = (JLayer) c;
+     *    l.setLayerEventMask(AWTEvent.KEY_EVENT_MASK);
+     * }
+     *
+     * public void unistallUI(JComponent c) {
+     *     super.uninstallUI(c);
+     *     JLayer l = (JLayer) c;
+     *     l.setLayerEventMask(0);
+     * }
+     * 
+ * + * @param e the {@code KeyEvent} to be processed + * @param l the layer this {@code LayerUI} instance is set to + * + * @see JLayer#setLayerEventMask(long) + * @see #installUI(javax.swing.JComponent) + * @see #uninstallUI(javax.swing.JComponent) + */ + protected void processKeyEvent(KeyEvent e, JLayer l) { + } + + /** + * Processes mouse events occurring on the {@link JLayer} + * or any of its subcomponents. + *

+ * This method is not called unless mouse events are + * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to. + * Mouse events are enabled in the overridden {@link #installUI} method + * and should be disabled in the {@link #uninstallUI} method after that. + *

+     * public void installUI(JComponent c) {
+     *    super.installUI(c);
+     *    JLayer l = (JLayer) c;
+     *    l.setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK);
+     * }
+     *
+     * public void unistallUI(JComponent c) {
+     *     super.uninstallUI(c);
+     *     JLayer l = (JLayer) c;
+     *     l.setLayerEventMask(0);
+     * }
+     * 
+ * + * @param e the {@code MouseEvent} to be processed + * @param l the layer this {@code LayerUI} instance is set to + * + * @see JLayer#setLayerEventMask(long) + * @see #installUI(javax.swing.JComponent) + * @see #uninstallUI(javax.swing.JComponent) + */ + protected void processMouseEvent(MouseEvent e, JLayer l) { + } + + /** + * Processes mouse motion event occurring on the {@link JLayer} + * or any of its subcomponents. + *

+ * This method is not called unless mouse motion events are + * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to. + * Mouse motion events are enabled in the overridden {@link #installUI} method + * and should be disabled in the {@link #uninstallUI} method after that. + *

+     * public void installUI(JComponent c) {
+     *    super.installUI(c);
+     *    JLayer l = (JLayer) c;
+     *    l.setLayerEventMask(AWTEvent.MOUSE_MOTION_EVENT_MASK);
+     * }
+     *
+     * public void unistallUI(JComponent c) {
+     *     super.uninstallUI(c);
+     *     JLayer l = (JLayer) c;
+     *     l.setLayerEventMask(0);
+     * }
+     * 
+ * + * @param e the {@code MouseEvent} to be processed + * @param l the layer this {@code LayerUI} instance is set to + * + * @see JLayer#setLayerEventMask(long) + * @see #installUI(javax.swing.JComponent) + * @see #uninstallUI(javax.swing.JComponent) + */ + protected void processMouseMotionEvent(MouseEvent e, JLayer l) { + } + + /** + * Processes mouse wheel event occurring on the {@link JLayer} + * or any of its subcomponents. + *

+ * This method is not called unless mouse wheel events are + * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to. + * Mouse wheel events are enabled in the overridden {@link #installUI} method + * and should be disabled in the {@link #uninstallUI} method after that. + *

+     * public void installUI(JComponent c) {
+     *    super.installUI(c);
+     *    JLayer l = (JLayer) c;
+     *    l.setLayerEventMask(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
+     * }
+     *
+     * public void unistallUI(JComponent c) {
+     *     super.uninstallUI(c);
+     *     JLayer l = (JLayer) c;
+     *     l.setLayerEventMask(0);
+     * }
+     * 
+ * + * @param e the {@code MouseEvent} to be processed + * @param l the layer this {@code LayerUI} instance is set to + * + * @see JLayer#setLayerEventMask(long) + * @see #installUI(javax.swing.JComponent) + * @see #uninstallUI(javax.swing.JComponent) + */ + protected void processMouseWheelEvent(MouseWheelEvent e, JLayer l) { + } + + /** + * Processes input event occurring on the {@link JLayer} + * or any of its subcomponents. + *

+ * This method is not called unless input events are + * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to. + * Input events are enabled in the overridden {@link #installUI} method + * and should be disabled in the {@link #uninstallUI} method after that. + *

+     * public void installUI(JComponent c) {
+     *    super.installUI(c);
+     *    JLayer l = (JLayer) c;
+     *    l.setLayerEventMask(AWTEvent.INPUT_METHOD_EVENT_MASK);
+     * }
+     *
+     * public void unistallUI(JComponent c) {
+     *     super.uninstallUI(c);
+     *     JLayer l = (JLayer) c;
+     *     l.setLayerEventMask(0);
+     * }
+     * 
+ * + * @param e the {@code InputMethodEvent} to be processed + * @param l the layer this {@code LayerUI} instance is set to + * + * @see JLayer#setLayerEventMask(long) + * @see #installUI(javax.swing.JComponent) + * @see #uninstallUI(javax.swing.JComponent) + */ + protected void processInputMethodEvent(InputMethodEvent e, JLayer l) { + } + + /** + * Processes hierarchy event occurring on the {@link JLayer} + * or any of its subcomponents. + *

+ * This method is not called unless hierarchy events are + * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to. + * Hierarchy events are enabled in the overridden {@link #installUI} method + * and should be disabled in the {@link #uninstallUI} method after that. + *

+     * public void installUI(JComponent c) {
+     *    super.installUI(c);
+     *    JLayer l = (JLayer) c;
+     *    l.setLayerEventMask(AWTEvent.HIERARCHY_EVENT_MASK);
+     * }
+     *
+     * public void unistallUI(JComponent c) {
+     *     super.uninstallUI(c);
+     *     JLayer l = (JLayer) c;
+     *     l.setLayerEventMask(0);
+     * }
+     * 
+ * + * @param e the {@code HierarchyEvent} to be processed + * @param l the layer this {@code LayerUI} instance is set to + * + * @see JLayer#setLayerEventMask(long) + * @see #installUI(javax.swing.JComponent) + * @see #uninstallUI(javax.swing.JComponent) + */ + protected void processHierarchyEvent(HierarchyEvent e, JLayer l) { + } + + /** + * Processes hierarchy bounds event occurring on the {@link JLayer} + * or any of its subcomponents. + *

+ * This method is not called unless hierarchy bounds events are + * enabled for the {@code JLayer} objects, this {@code LayerUI} is set to. + * Hierarchy bounds events are enabled in the overridden {@link #installUI} + * method and should be disabled in the {@link #uninstallUI} method after that. + *

+     * public void installUI(JComponent c) {
+     *    super.installUI(c);
+     *    JLayer l = (JLayer) c;
+     *    l.setLayerEventMask(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK);
+     * }
+     *
+     * public void unistallUI(JComponent c) {
+     *     super.uninstallUI(c);
+     *     JLayer l = (JLayer) c;
+     *     l.setLayerEventMask(0);
+     * }
+     * 
+ * + * @param e the {@code HierarchyEvent} to be processed + * @param l the layer this {@code LayerUI} instance is set to + * + * @see JLayer#setLayerEventMask(long) + * @see #installUI(javax.swing.JComponent) + * @see #uninstallUI(javax.swing.JComponent) + */ + protected void processHierarchyBoundsEvent(HierarchyEvent e, JLayer l) { } /** @@ -250,14 +627,29 @@ public class LayerUI propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue); } + /** + * Repaints all {@code JLayer} instances this {@code LayerUI} is set to. + * Call this method when the state of this {@code LayerUI} is changed + * and the visual appearance of its {@code JLayer} objects needs to be updated. + * + * @see Component#repaint() + */ + protected void repaintLayer() { + firePropertyChange("dirty", null, null); + } + /** * Notifies the {@code LayerUI} when any of its property are changed - * and enables updating every {@code JLayer} this {@code LayerUI} instance is set to. + * and enables updating every {@code JLayer} + * this {@code LayerUI} instance is set to. * * @param evt the PropertyChangeEvent generated by this {@code LayerUI} * @param l the {@code JLayer} this LayerUI is set to */ public void applyPropertyChange(PropertyChangeEvent evt, JLayer l) { + if ("dirty".equals(evt.getPropertyName())) { + l.repaint(); + } } /** diff --git a/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java b/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java index 1e5d80f8ea24bcd48d302437490f7aeab8f1672f..77709a94401336d4bf5ae813fc52e91c8b8da95e 100644 --- a/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java +++ b/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java @@ -486,7 +486,7 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh } if (remSize > 0 && addSize == 0) { fireIntervalRemoved(BasicDirectoryModel.this, remStart, remStart + remSize - 1); - } else if (addSize > 0 && remSize == 0 && fileCache.size() > addSize) { + } else if (addSize > 0 && remSize == 0 && addStart + addSize <= fileCache.size()) { fireIntervalAdded(BasicDirectoryModel.this, addStart, addStart + addSize - 1); } else { fireContentsChanged(); diff --git a/src/share/classes/javax/swing/plaf/metal/OceanTheme.java b/src/share/classes/javax/swing/plaf/metal/OceanTheme.java index 2aa299fe5cc60845d22fb52442191fb727aca0dd..2e1a8b2b4bf4cb75020ca5cae9984b7b932599ca 100644 --- a/src/share/classes/javax/swing/plaf/metal/OceanTheme.java +++ b/src/share/classes/javax/swing/plaf/metal/OceanTheme.java @@ -32,6 +32,7 @@ import javax.swing.*; import javax.swing.plaf.*; import sun.swing.SwingUtilities2; import sun.swing.PrintColorUIResource; +import sun.swing.SwingLazyValue; /** * The default theme for the {@code MetalLookAndFeel}. @@ -128,7 +129,7 @@ public class OceanTheme extends DefaultMetalTheme { * @throws NullPointerException if {@code table} is {@code null} */ public void addCustomEntriesToTable(UIDefaults table) { - Object focusBorder = new UIDefaults.ProxyLazyValue( + Object focusBorder = new SwingLazyValue( "javax.swing.plaf.BorderUIResource$LineBorderUIResource", new Object[] {getPrimary1()}); // .30 0 DDE8F3 white secondary2 diff --git a/src/share/classes/javax/swing/plaf/synth/SynthTableUI.java b/src/share/classes/javax/swing/plaf/synth/SynthTableUI.java index 1b8cf9894465b4c8f915973d8176c014cb96d407..dcd6b6275bf4c969571e386cb7136945eb7fe1d5 100644 --- a/src/share/classes/javax/swing/plaf/synth/SynthTableUI.java +++ b/src/share/classes/javax/swing/plaf/synth/SynthTableUI.java @@ -638,7 +638,7 @@ class SynthTableUI extends BasicTableUI implements SynthUI, if ((b == null || b instanceof UIResource || component instanceof SynthBooleanTableCellRenderer) && !table.isCellSelected(row, column)) { - if (alternateColor != null && row % 2 == 0) { + if (alternateColor != null && row % 2 != 0) { component.setBackground(alternateColor); } } diff --git a/src/share/classes/javax/swing/table/DefaultTableCellRenderer.java b/src/share/classes/javax/swing/table/DefaultTableCellRenderer.java index 07e7265c9bf6d6bcee3b78efa4ec40e36e2b46db..0c2b6a97367f4a101bf1fa0d5c09d87d1a2bafab 100644 --- a/src/share/classes/javax/swing/table/DefaultTableCellRenderer.java +++ b/src/share/classes/javax/swing/table/DefaultTableCellRenderer.java @@ -214,8 +214,9 @@ public class DefaultTableCellRenderer extends JLabel : table.getBackground(); if (background == null || background instanceof javax.swing.plaf.UIResource) { Color alternateColor = DefaultLookup.getColor(this, ui, "Table.alternateRowColor"); - if (alternateColor != null && row % 2 == 0) + if (alternateColor != null && row % 2 != 0) { background = alternateColor; + } } super.setForeground(unselectedForeground != null ? unselectedForeground diff --git a/src/share/classes/javax/swing/text/JTextComponent.java b/src/share/classes/javax/swing/text/JTextComponent.java index 371afda48b049020ac985b62b64e7417acf7abd9..25ddaf9e3cc4dd4e992266dc8406a04678d9fdd2 100644 --- a/src/share/classes/javax/swing/text/JTextComponent.java +++ b/src/share/classes/javax/swing/text/JTextComponent.java @@ -2069,7 +2069,7 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A * width to match its own */ public boolean getScrollableTracksViewportWidth() { - JViewport port = SwingUtilities2.getViewport(this); + JViewport port = SwingUtilities.getParentViewport(this); if (port != null) { return port.getWidth() > getPreferredSize().width; } @@ -2090,7 +2090,7 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A * to match its own */ public boolean getScrollableTracksViewportHeight() { - JViewport port = SwingUtilities2.getViewport(this); + JViewport port = SwingUtilities.getParentViewport(this); if (port != null) { return (port.getHeight() > getPreferredSize().height); } diff --git a/src/share/classes/org/ietf/jgss/GSSContext.java b/src/share/classes/org/ietf/jgss/GSSContext.java index 5fb769dc523ab75fef8ad883f3e9633c16fca23c..e8eb70275807d16ad854100b2f4982fdd8518d80 100644 --- a/src/share/classes/org/ietf/jgss/GSSContext.java +++ b/src/share/classes/org/ietf/jgss/GSSContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2001 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2009 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 @@ -678,7 +678,7 @@ public interface GSSContext { * are not definitive then the method will attempt to treat all * available bytes as part of the token.

* - * Other than the possible blocking behaviour described above, this + * Other than the possible blocking behavior described above, this * method is equivalent to the byte array based {@link #unwrap(byte[], * int, int, MessageProp) unwrap} method.

* @@ -826,7 +826,7 @@ public interface GSSContext { * are not definitive then the method will attempt to treat all * available bytes as part of the token.

* - * Other than the possible blocking behaviour described above, this + * Other than the possible blocking behavior described above, this * method is equivalent to the byte array based {@link #verifyMIC(byte[], * int, int, byte[], int, int, MessageProp) verifyMIC} method.

* @@ -917,7 +917,7 @@ public interface GSSContext { * getMutualAuthState} method.

* * @param state a boolean value indicating whether mutual - * authentication shouls be used or not. + * authentication should be used or not. * @see #getMutualAuthState() * * @throws GSSException containing the following @@ -928,7 +928,7 @@ public interface GSSContext { /** * Requests that replay detection be enabled for the - * per-message security services after context establishemnt. This + * per-message security services after context establishment. This * request can only be made on the context initiator's side and it has * to be done prior to the first call to * initSecContext. During context establishment replay @@ -958,7 +958,7 @@ public interface GSSContext { /** * Requests that sequence checking be enabled for the - * per-message security services after context establishemnt. This + * per-message security services after context establishment. This * request can only be made on the context initiator's side and it has * to be done prior to the first call to * initSecContext. During context establishment sequence diff --git a/src/share/classes/sun/awt/datatransfer/DataTransferer.java b/src/share/classes/sun/awt/datatransfer/DataTransferer.java index 521e691024c5ef6e4732938dbedfeceda1a9e0a4..277d3bd9e28a48c0bd92eac5c31526845e246774 100644 --- a/src/share/classes/sun/awt/datatransfer/DataTransferer.java +++ b/src/share/classes/sun/awt/datatransfer/DataTransferer.java @@ -63,8 +63,6 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.rmi.MarshalledObject; - import java.security.AccessControlContext; import java.security.AccessControlException; import java.security.AccessController; @@ -493,6 +491,13 @@ public abstract class DataTransferer { } } + /** + * Returns {@code true} if the given type is a java.rmi.Remote. + */ + public static boolean isRemote(Class type) { + return RMI.isRemote(type); + } + /** * Returns an Iterator which traverses a SortedSet of Strings which are * a total order of the standard character sets supported by the JRE. The @@ -1360,7 +1365,7 @@ search: // Source data is an RMI object } else if (flavor.isRepresentationClassRemote()) { - MarshalledObject mo = new MarshalledObject(obj); + Object mo = RMI.newMarshalledObject(obj); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(mo); oos.close(); @@ -1671,7 +1676,7 @@ search: try { byte[] ba = inputStreamToByteArray(str); ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(ba)); - Object ret = ((MarshalledObject)(ois.readObject())).get(); + Object ret = RMI.getMarshalledObject(ois.readObject()); ois.close(); str.close(); return ret; @@ -2669,8 +2674,12 @@ search: Integer.valueOf(0)); nonTextRepresentationsMap.put(java.io.Serializable.class, Integer.valueOf(1)); - nonTextRepresentationsMap.put(java.rmi.Remote.class, - Integer.valueOf(2)); + + Class remoteClass = RMI.remoteClass(); + if (remoteClass != null) { + nonTextRepresentationsMap.put(remoteClass, + Integer.valueOf(2)); + } nonTextRepresentations = Collections.unmodifiableMap(nonTextRepresentationsMap); @@ -2900,4 +2909,95 @@ search: } } } + + /** + * A class that provides access to java.rmi.Remote and java.rmi.MarshalledObject + * without creating a static dependency. + */ + private static class RMI { + private static final Class remoteClass = getClass("java.rmi.Remote"); + private static final Class marshallObjectClass = + getClass("java.rmi.MarshalledObject"); + private static final Constructor marshallCtor = + getConstructor(marshallObjectClass, Object.class); + private static final Method marshallGet = + getMethod(marshallObjectClass, "get"); + + private static Class getClass(String name) { + try { + return Class.forName(name, true, null); + } catch (ClassNotFoundException e) { + return null; + } + } + + private static Constructor getConstructor(Class c, Class... types) { + try { + return (c == null) ? null : c.getDeclaredConstructor(types); + } catch (NoSuchMethodException x) { + throw new AssertionError(x); + } + } + + private static Method getMethod(Class c, String name, Class... types) { + try { + return (c == null) ? null : c.getMethod(name, types); + } catch (NoSuchMethodException e) { + throw new AssertionError(e); + } + } + + /** + * Returns {@code true} if the given class is java.rmi.Remote. + */ + static boolean isRemote(Class c) { + return (remoteClass == null) ? null : remoteClass.isAssignableFrom(c); + } + + /** + * Returns java.rmi.Remote.class if RMI is present; otherwise {@code null}. + */ + static Class remoteClass() { + return remoteClass; + } + + /** + * Returns a new MarshalledObject containing the serialized representation + * of the given object. + */ + static Object newMarshalledObject(Object obj) throws IOException { + try { + return marshallCtor.newInstance(obj); + } catch (InstantiationException x) { + throw new AssertionError(x); + } catch (IllegalAccessException x) { + throw new AssertionError(x); + } catch (InvocationTargetException x) { + Throwable cause = x.getCause(); + if (cause instanceof IOException) + throw (IOException)cause; + throw new AssertionError(x); + } + } + + /** + * Returns a new copy of the contained marshalled object. + */ + static Object getMarshalledObject(Object obj) + throws IOException, ClassNotFoundException + { + try { + return marshallGet.invoke(obj); + } catch (IllegalAccessException x) { + throw new AssertionError(x); + } catch (InvocationTargetException x) { + Throwable cause = x.getCause(); + if (cause instanceof IOException) + throw (IOException)cause; + if (cause instanceof ClassNotFoundException) + throw (ClassNotFoundException)cause; + throw new AssertionError(x); + } + } + } } diff --git a/src/share/classes/sun/awt/im/InputMethodManager.java b/src/share/classes/sun/awt/im/InputMethodManager.java index caba8d6a15263d4b4ffd4356bf4030e68c251985..9ee45e28e5339ddcf60d0677969049e60a6f70dc 100644 --- a/src/share/classes/sun/awt/im/InputMethodManager.java +++ b/src/share/classes/sun/awt/im/InputMethodManager.java @@ -358,7 +358,9 @@ class ExecutableInputMethodManager extends InputMethodManager AppContext requesterAppContext = SunToolkit.targetToAppContext(requester); synchronized (lock) { SunToolkit.postEvent(requesterAppContext, event); - lock.wait(); + while (!event.isDispatched()) { + lock.wait(); + } } Throwable eventThrowable = event.getThrowable(); diff --git a/src/share/classes/sun/awt/shell/ShellFolder.java b/src/share/classes/sun/awt/shell/ShellFolder.java index cf3c78933849048a44d5ba1506b25ed32d37c337..c5b2296b2b754eb2781ac35eeb042997bcdc3ddc 100644 --- a/src/share/classes/sun/awt/shell/ShellFolder.java +++ b/src/share/classes/sun/awt/shell/ShellFolder.java @@ -201,6 +201,8 @@ public abstract class ShellFolder extends File { private static ShellFolderManager shellFolderManager; + private static Invoker invoker; + static { String managerClassName = (String)Toolkit.getDefaultToolkit(). getDesktopProperty("Shell.shellFolderManager"); @@ -225,6 +227,8 @@ public abstract class ShellFolder extends File { throw new Error ("Could not access Shell Folder Manager: " + managerClass.getName()); } + + invoker = shellFolderManager.createInvoker(); } /** @@ -486,21 +490,6 @@ public abstract class ShellFolder extends File { return null; } - private static Invoker invoker; - - /** - * Provides the single access point to the {@link Invoker}. It is guaranteed that the value - * returned by this method will be always the same. - * - * @return the singleton instance of {@link Invoker} - */ - public static Invoker getInvoker() { - if (invoker == null) { - invoker = shellFolderManager.createInvoker(); - } - return invoker; - } - /** * Invokes the {@code task} which doesn't throw checked exceptions * from its {@code call} method. If invokation is interrupted then Thread.currentThread().isInterrupted() will @@ -522,7 +511,7 @@ public abstract class ShellFolder extends File { public static T invoke(Callable task, Class exceptionClass) throws InterruptedException, E { try { - return getInvoker().invoke(task); + return invoker.invoke(task); } catch (Exception e) { if (e instanceof RuntimeException) { // Rethrow unchecked exceptions diff --git a/src/share/classes/sun/font/Font2D.java b/src/share/classes/sun/font/Font2D.java index c344ebb70076c004770ae78fe7c908f95aaaf423..3a930d6502e601d529e4d0e3a029019f6052530e 100644 --- a/src/share/classes/sun/font/Font2D.java +++ b/src/share/classes/sun/font/Font2D.java @@ -320,21 +320,6 @@ public abstract class Font2D { lastFontStrike = new SoftReference(strike); StrikeCache.refStrike(strike); return strike; - } else { - /* We have found a cleared reference that has not yet - * been removed by the disposer. - * If we make this reference unreachable by removing it - * from the map,or overwriting it with a new reference to - * a new strike, then it is possible it may never be - * enqueued for disposal. That is the implication of - * the docs for java.lang.ref. So on finding a cleared - * reference, we need to dispose the native resources, - * if they haven't already been freed. - * The reference object needs to have a reference to - * the disposer instance for this to occur. - */ - ((StrikeCache.DisposableStrike)strikeRef) - .getDisposer().dispose(); } } /* When we create a new FontStrike instance, we *must* diff --git a/src/share/classes/sun/font/FontDesignMetrics.java b/src/share/classes/sun/font/FontDesignMetrics.java index 929c0d21dd8d42b9d03ad4dde3fbadc73970d9fc..e81c397fdea60ea3a7809cba1c21d83ca6248d9d 100644 --- a/src/share/classes/sun/font/FontDesignMetrics.java +++ b/src/share/classes/sun/font/FontDesignMetrics.java @@ -171,7 +171,7 @@ public final class FontDesignMetrics extends FontMetrics { * out we can clear the keys from the table. */ private static class KeyReference extends SoftReference - implements DisposerRecord { + implements DisposerRecord, Disposer.PollDisposable { static ReferenceQueue queue = Disposer.getQueue(); diff --git a/src/share/classes/sun/font/FontStrikeDisposer.java b/src/share/classes/sun/font/FontStrikeDisposer.java index 7245cc3736f0ac0c5cef8b4b2808e2e3d5f80edf..3ee33eccea61cb6a0f5d1e8f6582814c2cf13a93 100644 --- a/src/share/classes/sun/font/FontStrikeDisposer.java +++ b/src/share/classes/sun/font/FontStrikeDisposer.java @@ -25,6 +25,7 @@ package sun.font; +import sun.java2d.Disposer; import sun.java2d.DisposerRecord; /* @@ -49,7 +50,8 @@ import sun.java2d.DisposerRecord; * entries would be removed much more promptly than we need. */ -class FontStrikeDisposer implements DisposerRecord { +class FontStrikeDisposer + implements DisposerRecord, Disposer.PollDisposable { Font2D font2D; FontStrikeDesc desc; diff --git a/src/share/classes/sun/font/StrikeCache.java b/src/share/classes/sun/font/StrikeCache.java index 945b01f867ec3d4fbb814b97a98f735500b38b24..9e5b02a865031a9d1606d80768f6ff0103a82d50 100644 --- a/src/share/classes/sun/font/StrikeCache.java +++ b/src/share/classes/sun/font/StrikeCache.java @@ -254,9 +254,20 @@ public final class StrikeCache { // because they may be accessed on that thread at the time of the // disposal (for example, when the accel. cache is invalidated) - // REMIND: this look a bit heavyweight, but should be ok - // because strike disposal is a relatively infrequent operation, - // more worrisome is the necessity of getting a GC here. + // Whilst this is a bit heavyweight, in most applications + // strike disposal is a relatively infrequent operation, so it + // doesn't matter. But in some tests that use vast numbers + // of strikes, the switching back and forth is measurable. + // So the "pollRemove" call is added to batch up the work. + // If we are polling we know we've already been called back + // and can directly dispose the record. + // Also worrisome is the necessity of getting a GC here. + + if (Disposer.pollingQueue) { + doDispose(disposer); + return; + } + RenderQueue rq = null; GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); @@ -277,6 +288,7 @@ public final class StrikeCache { rq.flushAndInvokeNow(new Runnable() { public void run() { doDispose(disposer); + Disposer.pollRemove(); } }); } finally { diff --git a/src/share/classes/sun/java2d/Disposer.java b/src/share/classes/sun/java2d/Disposer.java index bf9ea8ad71a7b7146dbf4bbe19520aa64cb81ce1..4433a278d5d12d4792d8b93357a2d72dad96c6fc 100644 --- a/src/share/classes/sun/java2d/Disposer.java +++ b/src/share/classes/sun/java2d/Disposer.java @@ -29,6 +29,7 @@ import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.ref.PhantomReference; import java.lang.ref.WeakReference; +import java.util.ArrayList; import java.util.Hashtable; /** @@ -146,6 +147,7 @@ public class Disposer implements Runnable { rec.dispose(); obj = null; rec = null; + clearDeferredRecords(); } catch (Exception e) { System.out.println("Exception while removing reference: " + e); e.printStackTrace(); @@ -153,6 +155,85 @@ public class Disposer implements Runnable { } } + /* + * This is a marker interface that, if implemented, means it + * doesn't acquire any special locks, and is safe to + * be disposed in the poll loop on whatever thread + * which happens to be the Toolkit thread, is in use. + */ + public static interface PollDisposable { + }; + + private static ArrayList deferredRecords = null; + + private static void clearDeferredRecords() { + if (deferredRecords == null || deferredRecords.isEmpty()) { + return; + } + for (int i=0;i(5); + } + deferredRecords.add(rec); + } + } + } catch (Exception e) { + System.out.println("Exception while removing reference: " + e); + e.printStackTrace(); + } finally { + pollingQueue = false; + } + } + private static native void initIDs(); /* diff --git a/src/share/classes/sun/java2d/SunGraphics2D.java b/src/share/classes/sun/java2d/SunGraphics2D.java index c63db02e75673be2538d1401b8ec62295db0ad86..951876eb23753a1c55b90083d6178fc1e6e6ef96 100644 --- a/src/share/classes/sun/java2d/SunGraphics2D.java +++ b/src/share/classes/sun/java2d/SunGraphics2D.java @@ -257,7 +257,6 @@ public final class SunGraphics2D font = defaultFont; } - loops = sd.getRenderLoops(this); setDevClip(sd.getBounds()); invalidatePipe(); } @@ -367,6 +366,7 @@ public final class SunGraphics2D shapepipe = invalidpipe; textpipe = invalidpipe; imagepipe = invalidpipe; + loops = null; } public void validatePipe() { diff --git a/src/share/classes/sun/java2d/SurfaceData.java b/src/share/classes/sun/java2d/SurfaceData.java index 65a04c23220c726a9981d5d85d045cff35387a8d..95ef18c85f4231af965664dd5d7c1e19ee2c15fe 100644 --- a/src/share/classes/sun/java2d/SurfaceData.java +++ b/src/share/classes/sun/java2d/SurfaceData.java @@ -69,6 +69,7 @@ import sun.java2d.pipe.DrawImagePipe; import sun.java2d.pipe.DrawImage; import sun.awt.SunHints; import sun.awt.image.SurfaceManager; +import sun.java2d.pipe.LoopBasedPipe; /** * This class provides various pieces of information relevant to a @@ -506,7 +507,6 @@ public abstract class SurfaceData sg2d.textpipe = solidTextRenderer; } sg2d.shapepipe = colorPrimitives; - sg2d.loops = getRenderLoops(sg2d); // assert(sg2d.surfaceData == this); } } else if (sg2d.compositeState == sg2d.COMP_CUSTOM) { @@ -603,9 +603,18 @@ public abstract class SurfaceData sg2d.textpipe = getTextPipe(sg2d, false /* AA==OFF */); sg2d.shapepipe = colorPrimitives; - sg2d.loops = getRenderLoops(sg2d); // assert(sg2d.surfaceData == this); } + + // check for loops + if (sg2d.textpipe instanceof LoopBasedPipe || + sg2d.shapepipe instanceof LoopBasedPipe || + sg2d.fillpipe instanceof LoopBasedPipe || + sg2d.drawpipe instanceof LoopBasedPipe || + sg2d.imagepipe instanceof LoopBasedPipe) + { + sg2d.loops = getRenderLoops(sg2d); + } } /* Return the text pipe to be used based on the graphics AA hint setting, diff --git a/src/share/classes/sun/java2d/pipe/AATextRenderer.java b/src/share/classes/sun/java2d/pipe/AATextRenderer.java index 389db9cbefdfbe41d4ffc34a36b57eb905036d01..602e5be5ef80340a8823863b6948b9d094b60982 100644 --- a/src/share/classes/sun/java2d/pipe/AATextRenderer.java +++ b/src/share/classes/sun/java2d/pipe/AATextRenderer.java @@ -34,8 +34,9 @@ import sun.font.GlyphList; * a solid source colour to an opaque destination. */ -public class AATextRenderer extends GlyphListLoopPipe { - +public class AATextRenderer extends GlyphListLoopPipe + implements LoopBasedPipe +{ protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) { sg2d.loops.drawGlyphListAALoop.DrawGlyphListAA(sg2d, sg2d.surfaceData, gl); diff --git a/src/share/classes/sun/java2d/pipe/GlyphListLoopPipe.java b/src/share/classes/sun/java2d/pipe/GlyphListLoopPipe.java index cbe76016cf748c9670972911e9de2714a133a019..385a768cf9e9f4bb6ddbfc5e8d66143e1f2bbcd7 100644 --- a/src/share/classes/sun/java2d/pipe/GlyphListLoopPipe.java +++ b/src/share/classes/sun/java2d/pipe/GlyphListLoopPipe.java @@ -36,8 +36,9 @@ import sun.font.GlyphList; * the installed loop may not match the glyphvector. */ -public abstract class GlyphListLoopPipe extends GlyphListPipe { - +public abstract class GlyphListLoopPipe extends GlyphListPipe + implements LoopBasedPipe +{ protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl, int aaHint) { switch (aaHint) { diff --git a/test/tools/launcher/libraryCaller.h b/src/share/classes/sun/java2d/pipe/LoopBasedPipe.java similarity index 63% rename from test/tools/launcher/libraryCaller.h rename to src/share/classes/sun/java2d/pipe/LoopBasedPipe.java index df2ce33f8b665934012580356ceeb8142b1c793f..34b9067335c4564dd67bf1fc42f769edaada6dda 100644 --- a/test/tools/launcher/libraryCaller.h +++ b/src/share/classes/sun/java2d/pipe/LoopBasedPipe.java @@ -1,11 +1,12 @@ - /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 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. + * 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 @@ -22,25 +23,15 @@ * have any questions. */ -/* DO NOT EDIT THIS FILE - it is machine generated */ - -#include -/* Header for class libraryCaller */ +package sun.java2d.pipe; -#ifndef _Included_libraryCaller -#define _Included_libraryCaller -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: libraryCaller - * Method: number - * Signature: ()I +/** + * This is a marker interface used by Pipes that need RenderLoops. + * RenderLoops are validated in SurfaceData when a pipe is recognised to + * implement this interface. + * + * @author Mario Torre */ -JNIEXPORT jint JNICALL Java_libraryCaller_number - (JNIEnv *, jclass); +public interface LoopBasedPipe { -#ifdef __cplusplus } -#endif -#endif diff --git a/src/share/classes/sun/java2d/pipe/LoopPipe.java b/src/share/classes/sun/java2d/pipe/LoopPipe.java index 93334e56fac5098859b7a66c92e00df46871edd9..a7d2c1dae23e26f7e7200225859ced9fbf305c9b 100644 --- a/src/share/classes/sun/java2d/pipe/LoopPipe.java +++ b/src/share/classes/sun/java2d/pipe/LoopPipe.java @@ -46,7 +46,8 @@ import sun.awt.SunHints; public class LoopPipe implements PixelDrawPipe, PixelFillPipe, - ShapeDrawPipe + ShapeDrawPipe, + LoopBasedPipe { final static RenderingEngine RenderEngine = RenderingEngine.getInstance(); diff --git a/src/share/classes/sun/java2d/pipe/SolidTextRenderer.java b/src/share/classes/sun/java2d/pipe/SolidTextRenderer.java index 52d1a709a531232f48ad3cb56ac0344190c9315c..bb8778aba93a9334f8218ff53a29f8d11f69029e 100644 --- a/src/share/classes/sun/java2d/pipe/SolidTextRenderer.java +++ b/src/share/classes/sun/java2d/pipe/SolidTextRenderer.java @@ -35,8 +35,9 @@ import sun.font.GlyphList; * a solid source colour to an opaque destination. */ -public class SolidTextRenderer extends GlyphListLoopPipe { - +public class SolidTextRenderer extends GlyphListLoopPipe + implements LoopBasedPipe +{ protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) { sg2d.loops.drawGlyphListLoop.DrawGlyphList(sg2d, sg2d.surfaceData, gl); } diff --git a/src/share/classes/sun/java2d/pipe/SpanShapeRenderer.java b/src/share/classes/sun/java2d/pipe/SpanShapeRenderer.java index 574ebed818842409068d5a2156c9db7fbd577578..a02b761c8dcf97f12215b58373ca47b84a1e35d3 100644 --- a/src/share/classes/sun/java2d/pipe/SpanShapeRenderer.java +++ b/src/share/classes/sun/java2d/pipe/SpanShapeRenderer.java @@ -65,7 +65,9 @@ public abstract class SpanShapeRenderer implements ShapeDrawPipe { } } - public static class Simple extends SpanShapeRenderer { + public static class Simple extends SpanShapeRenderer + implements LoopBasedPipe + { public Object startSequence(SunGraphics2D sg, Shape s, Rectangle devR, int[] bbox) { return sg; diff --git a/src/share/classes/sun/java2d/pisces/Renderer.java b/src/share/classes/sun/java2d/pisces/Renderer.java index 3ada6c73600118ebf22387cffda6a2333b381ca7..2aba41121611d35314763e1b0263063362ff7f19 100644 --- a/src/share/classes/sun/java2d/pisces/Renderer.java +++ b/src/share/classes/sun/java2d/pisces/Renderer.java @@ -775,10 +775,12 @@ public class Renderer extends LineSink { // Free sorting arrays if larger than maximum size private void crossingListFinished() { - if (crossings.length > DEFAULT_CROSSINGS_SIZE) { + if (crossings != null && crossings.length > DEFAULT_CROSSINGS_SIZE) { crossings = new int[DEFAULT_CROSSINGS_SIZE]; } - if (crossingIndices.length > DEFAULT_INDICES_SIZE) { + if (crossingIndices != null && + crossingIndices.length > DEFAULT_INDICES_SIZE) + { crossingIndices = new int[DEFAULT_INDICES_SIZE]; } } diff --git a/src/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java b/src/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java index dd4a39bd875ce78ee51855952e3e61b2cbf8850e..af0c9726ad9e06ba1515bc12611ec618db2f27a5 100644 --- a/src/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java +++ b/src/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java @@ -25,6 +25,7 @@ package sun.net.www.protocol.http.spnego; +import com.sun.security.jgss.ExtendedGSSContext; import java.io.IOException; import org.ietf.jgss.GSSContext; @@ -100,15 +101,10 @@ public class NegotiatorImpl extends Negotiator { null, GSSContext.DEFAULT_LIFETIME); - // In order to support credential delegation in HTTP/SPNEGO, - // we always request it before initSecContext. The current - // implementation will check the OK-AS-DELEGATE flag inside - // the service ticket of the web server, and only enable - // delegation when this flag is set. This check is only - // performed when the GSS caller is CALLER_HTTP_NEGOTIATE, - // so all other normal GSS-API calls are not affected. - - context.requestCredDeleg(true); + // Always respect delegation policy in HTTP/SPNEGO. + if (context instanceof ExtendedGSSContext) { + ((ExtendedGSSContext)context).requestDelegPolicy(true); + } oneToken = context.initSecContext(new byte[0], 0, 0); } diff --git a/src/share/classes/sun/security/jgss/GSSContextImpl.java b/src/share/classes/sun/security/jgss/GSSContextImpl.java index de703ef4dedba60c655e48a6c0b3f64197535e4e..210ba5b869ae59d721567961a8e9628696492a60 100644 --- a/src/share/classes/sun/security/jgss/GSSContextImpl.java +++ b/src/share/classes/sun/security/jgss/GSSContextImpl.java @@ -89,7 +89,8 @@ import com.sun.security.jgss.*; */ class GSSContextImpl implements ExtendedGSSContext { - private GSSManagerImpl gssManager = null; + private final GSSManagerImpl gssManager; + private final boolean initiator; // private flags for the context state private static final int PRE_INIT = 1; @@ -99,14 +100,12 @@ class GSSContextImpl implements ExtendedGSSContext { // instance variables private int currentState = PRE_INIT; - private boolean initiator; private GSSContextSpi mechCtxt = null; private Oid mechOid = null; private ObjectIdentifier objId = null; private GSSCredentialImpl myCred = null; - private GSSCredentialImpl delegCred = null; private GSSNameImpl srcName = null; private GSSNameImpl targName = null; @@ -121,6 +120,7 @@ class GSSContextImpl implements ExtendedGSSContext { private boolean reqSequenceDetState = true; private boolean reqCredDelegState = false; private boolean reqAnonState = false; + private boolean reqDelegPolicyState = false; /** * Creates a GSSContextImp on the context initiator's side. @@ -221,6 +221,7 @@ class GSSContextImpl implements ExtendedGSSContext { mechCtxt.requestSequenceDet(reqSequenceDetState); mechCtxt.requestAnonymity(reqAnonState); mechCtxt.setChannelBinding(channelBindings); + mechCtxt.requestDelegPolicy(reqDelegPolicyState); objId = new ObjectIdentifier(mechOid.toString()); @@ -465,42 +466,42 @@ class GSSContextImpl implements ExtendedGSSContext { } public void requestMutualAuth(boolean state) throws GSSException { - if (mechCtxt == null) + if (mechCtxt == null && initiator) reqMutualAuthState = state; } public void requestReplayDet(boolean state) throws GSSException { - if (mechCtxt == null) + if (mechCtxt == null && initiator) reqReplayDetState = state; } public void requestSequenceDet(boolean state) throws GSSException { - if (mechCtxt == null) + if (mechCtxt == null && initiator) reqSequenceDetState = state; } public void requestCredDeleg(boolean state) throws GSSException { - if (mechCtxt == null) + if (mechCtxt == null && initiator) reqCredDelegState = state; } public void requestAnonymity(boolean state) throws GSSException { - if (mechCtxt == null) + if (mechCtxt == null && initiator) reqAnonState = state; } public void requestConf(boolean state) throws GSSException { - if (mechCtxt == null) + if (mechCtxt == null && initiator) reqConfState = state; } public void requestInteg(boolean state) throws GSSException { - if (mechCtxt == null) + if (mechCtxt == null && initiator) reqIntegState = state; } public void requestLifetime(int lifetime) throws GSSException { - if (mechCtxt == null) + if (mechCtxt == null && initiator) reqLifetime = lifetime; } @@ -630,6 +631,8 @@ class GSSContextImpl implements ExtendedGSSContext { targName = null; } + // ExtendedGSSContext methods: + @Override public Object inquireSecContext(InquireType type) throws GSSException { SecurityManager security = System.getSecurityManager(); @@ -641,4 +644,18 @@ class GSSContextImpl implements ExtendedGSSContext { } return mechCtxt.inquireSecContext(type); } + + @Override + public void requestDelegPolicy(boolean state) throws GSSException { + if (mechCtxt == null && initiator) + reqDelegPolicyState = state; + } + + @Override + public boolean getDelegPolicyState() { + if (mechCtxt != null) + return mechCtxt.getDelegPolicyState(); + else + return reqDelegPolicyState; + } } diff --git a/src/share/classes/sun/security/jgss/krb5/InitialToken.java b/src/share/classes/sun/security/jgss/krb5/InitialToken.java index 2f0b834c1b91cb118f2000fb348fcc939cb20621..ed7eb8c6e18fbbe434cea569a27548aeb38e153f 100644 --- a/src/share/classes/sun/security/jgss/krb5/InitialToken.java +++ b/src/share/classes/sun/security/jgss/krb5/InitialToken.java @@ -85,32 +85,39 @@ abstract class InitialToken extends Krb5Token { int size = CHECKSUM_LENGTH_SIZE + CHECKSUM_BINDINGS_SIZE + CHECKSUM_FLAGS_SIZE; + if (!tgt.isForwardable()) { + context.setCredDelegState(false); + context.setDelegPolicyState(false); + } else if (context.getCredDelegState()) { + if (context.getDelegPolicyState()) { + if (!serviceTicket.checkDelegate()) { + // delegation not permitted by server policy, mark it + context.setDelegPolicyState(false); + } + } + } else if (context.getDelegPolicyState()) { + if (serviceTicket.checkDelegate()) { + context.setCredDelegState(true); + } else { + context.setDelegPolicyState(false); + } + } + if (context.getCredDelegState()) { - if (context.getCaller() instanceof HttpCaller && - !serviceTicket.getFlags()[Krb5.TKT_OPTS_DELEGATE]) { - // When the caller is HTTP/SPNEGO and OK-AS-DELEGATE - // is not present in the service ticket, delegation - // is disabled. - context.setCredDelegState(false); - } else if (!tgt.isForwardable()) { - // XXX log this resetting of delegation state - context.setCredDelegState(false); + KrbCred krbCred = null; + CipherHelper cipherHelper = + context.getCipherHelper(serviceTicket.getSessionKey()); + if (useNullKey(cipherHelper)) { + krbCred = new KrbCred(tgt, serviceTicket, + EncryptionKey.NULL_KEY); } else { - KrbCred krbCred = null; - CipherHelper cipherHelper = - context.getCipherHelper(serviceTicket.getSessionKey()); - if (useNullKey(cipherHelper)) { - krbCred = new KrbCred(tgt, serviceTicket, - EncryptionKey.NULL_KEY); - } else { - krbCred = new KrbCred(tgt, serviceTicket, - serviceTicket.getSessionKey()); - } - krbCredMessage = krbCred.getMessage(); - size += CHECKSUM_DELEG_OPT_SIZE + - CHECKSUM_DELEG_LGTH_SIZE + - krbCredMessage.length; + krbCred = new KrbCred(tgt, serviceTicket, + serviceTicket.getSessionKey()); } + krbCredMessage = krbCred.getMessage(); + size += CHECKSUM_DELEG_OPT_SIZE + + CHECKSUM_DELEG_LGTH_SIZE + + krbCredMessage.length; } checksumBytes = new byte[size]; @@ -296,6 +303,7 @@ abstract class InitialToken extends Krb5Token { return delegCreds; } + // Only called by acceptor public void setContextFlags(Krb5Context context) { // default for cred delegation is false if ((flags & CHECKSUM_DELEG_FLAG) > 0) diff --git a/src/share/classes/sun/security/jgss/krb5/Krb5Context.java b/src/share/classes/sun/security/jgss/krb5/Krb5Context.java index 4fe1e80f5f94afca5173933ce397374cfc1ec78c..8810ed606f9350f6bbfb644038185fa22ebce315 100644 --- a/src/share/classes/sun/security/jgss/krb5/Krb5Context.java +++ b/src/share/classes/sun/security/jgss/krb5/Krb5Context.java @@ -78,6 +78,7 @@ class Krb5Context implements GSSContextSpi { private boolean sequenceDetState = true; private boolean confState = true; private boolean integState = true; + private boolean delegPolicyState = false; private int mySeqNumber; private int peerSeqNumber; @@ -299,6 +300,21 @@ class Krb5Context implements GSSContextSpi { return sequenceDetState || replayDetState; } + /** + * Requests that the deleg policy be respected. + */ + public final void requestDelegPolicy(boolean value) { + if (state == STATE_NEW && isInitiator()) + delegPolicyState = value; + } + + /** + * Is deleg policy respected? + */ + public final boolean getDelegPolicyState() { + return delegPolicyState; + } + /* * Anonymity is a little different in that after an application * requests anonymity it will want to know whether the mechanism @@ -422,6 +438,10 @@ class Krb5Context implements GSSContextSpi { integState = state; } + final void setDelegPolicyState(boolean state) { + delegPolicyState = state; + } + /** * Sets the channel bindings to be used during context * establishment. diff --git a/src/share/classes/sun/security/jgss/spi/GSSContextSpi.java b/src/share/classes/sun/security/jgss/spi/GSSContextSpi.java index 5bf359a1f8ccf1d776a6ef8272a8b88d28e28aaf..aaf4eebc29fbd3ee7e8063ad9978b811f7df063b 100644 --- a/src/share/classes/sun/security/jgss/spi/GSSContextSpi.java +++ b/src/share/classes/sun/security/jgss/spi/GSSContextSpi.java @@ -124,6 +124,8 @@ public interface GSSContextSpi { public void requestInteg(boolean state) throws GSSException; + public void requestDelegPolicy(boolean state) throws GSSException; + public void setChannelBinding(ChannelBinding cb) throws GSSException; public boolean getCredDelegState(); @@ -136,6 +138,8 @@ public interface GSSContextSpi { public boolean getAnonymityState(); + public boolean getDelegPolicyState(); + public boolean isTransferable() throws GSSException; public boolean isProtReady(); diff --git a/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java b/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java index a436092f1bb6b4f98e0373b2960a6df648a78729..b002082d8cb1a99c7262bafab1737343490bb54e 100644 --- a/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java +++ b/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java @@ -63,6 +63,7 @@ public class SpNegoContext implements GSSContextSpi { private boolean sequenceDetState = true; private boolean confState = true; private boolean integState = true; + private boolean delegPolicyState = false; private GSSNameSpi peerName = null; private GSSNameSpi myName = null; @@ -153,6 +154,14 @@ public class SpNegoContext implements GSSContextSpi { integState = value; } + /** + * Requests that deleg policy be respected. + */ + public final void requestDelegPolicy(boolean value) throws GSSException { + if (state == STATE_NEW && isInitiator()) + delegPolicyState = value; + } + /** * Is integrity available? */ @@ -160,6 +169,19 @@ public class SpNegoContext implements GSSContextSpi { return integState; } + /** + * Is deleg policy respected? + */ + public final boolean getDelegPolicyState() { + if (isInitiator() && mechContext != null && + mechContext instanceof ExtendedGSSContext && + (state == STATE_IN_PROCESS || state == STATE_DONE)) { + return ((ExtendedGSSContext)mechContext).getDelegPolicyState(); + } else { + return delegPolicyState; + } + } + /** * Requests that credential delegation be done during context * establishment. @@ -173,7 +195,7 @@ public class SpNegoContext implements GSSContextSpi { * Is credential delegation enabled? */ public final boolean getCredDelegState() { - if (mechContext != null && + if (isInitiator() && mechContext != null && (state == STATE_IN_PROCESS || state == STATE_DONE)) { return mechContext.getCredDelegState(); } else { @@ -201,30 +223,6 @@ public class SpNegoContext implements GSSContextSpi { return mutualAuthState; } - final void setCredDelegState(boolean state) { - credDelegState = state; - } - - final void setMutualAuthState(boolean state) { - mutualAuthState = state; - } - - final void setReplayDetState(boolean state) { - replayDetState = state; - } - - final void setSequenceDetState(boolean state) { - sequenceDetState = state; - } - - final void setConfState(boolean state) { - confState = state; - } - - final void setIntegState(boolean state) { - integState = state; - } - /** * Returns the mechanism oid. * @@ -319,14 +317,9 @@ public class SpNegoContext implements GSSContextSpi { mechToken = GSS_initSecContext(null); errorCode = GSSException.DEFECTIVE_TOKEN; - byte[] micToken = null; - if (!GSSUtil.useMSInterop()) { - // calculate MIC only in normal mode - micToken = generateMechListMIC(DER_mechTypes); - } // generate SPNEGO token initToken = new NegTokenInit(DER_mechTypes, getContextFlags(), - mechToken, micToken); + mechToken, null); if (DEBUG) { System.out.println("SpNegoContext.initSecContext: " + "sending token of type = " + @@ -585,15 +578,9 @@ public class SpNegoContext implements GSSContextSpi { "negotiated result = " + negoResult); } - // calculate MIC only in normal mode - byte[] micToken = null; - if (!GSSUtil.useMSInterop() && valid) { - micToken = generateMechListMIC(DER_mechTypes); - } - // generate SPNEGO token NegTokenTarg targToken = new NegTokenTarg(negoResult.ordinal(), - mech_wanted, accept_token, micToken); + mech_wanted, accept_token, null); if (DEBUG) { System.out.println("SpNegoContext.acceptSecContext: " + "sending token of type = " + @@ -653,6 +640,10 @@ public class SpNegoContext implements GSSContextSpi { throw gssException; } + if (state == STATE_DONE) { + // now set the context flags for acceptor + setContextFlags(); + } return retVal; } @@ -703,36 +694,39 @@ public class SpNegoContext implements GSSContextSpi { return out; } + // Only called on acceptor side. On the initiator side, most flags + // are already set at request. For those that might get chanegd, + // state from mech below is used. private void setContextFlags() { if (mechContext != null) { // default for cred delegation is false if (mechContext.getCredDelegState()) { - setCredDelegState(true); + credDelegState = true; } // default for the following are true if (!mechContext.getMutualAuthState()) { - setMutualAuthState(false); + mutualAuthState = false; } if (!mechContext.getReplayDetState()) { - setReplayDetState(false); + replayDetState = false; } if (!mechContext.getSequenceDetState()) { - setSequenceDetState(false); + sequenceDetState = false; } if (!mechContext.getIntegState()) { - setIntegState(false); + integState = false; } if (!mechContext.getConfState()) { - setConfState(false); + confState = false; } } } /** - * generate MIC on mechList + * generate MIC on mechList. Not used at the moment. */ - private byte[] generateMechListMIC(byte[] mechTypes) + /*private byte[] generateMechListMIC(byte[] mechTypes) throws GSSException { // sanity check the required input @@ -769,7 +763,7 @@ public class SpNegoContext implements GSSContextSpi { } } return mic; - } + }*/ /** * verify MIC on MechList @@ -837,6 +831,10 @@ public class SpNegoContext implements GSSContextSpi { mechContext.requestMutualAuth(mutualAuthState); mechContext.requestReplayDet(replayDetState); mechContext.requestSequenceDet(sequenceDetState); + if (mechContext instanceof ExtendedGSSContext) { + ((ExtendedGSSContext)mechContext).requestDelegPolicy( + delegPolicyState); + } } // pass token @@ -1202,5 +1200,5 @@ public class SpNegoContext implements GSSContextSpi { "inquireSecContext not supported by underlying mech."); } } - } + diff --git a/src/share/classes/sun/security/jgss/spnego/SpNegoMechFactory.java b/src/share/classes/sun/security/jgss/spnego/SpNegoMechFactory.java index ae12d6b3a7854a61966011f099164ac64ff7cfdb..72b77ac716625ab8452541ae07c1556f94aaae10 100644 --- a/src/share/classes/sun/security/jgss/spnego/SpNegoMechFactory.java +++ b/src/share/classes/sun/security/jgss/spnego/SpNegoMechFactory.java @@ -57,6 +57,12 @@ public final class SpNegoMechFactory implements MechanismFactory { GSSName.NT_HOSTBASED_SERVICE, GSSName.NT_EXPORT_NAME}; + // The default underlying mech of SPNEGO, must not be SPNEGO itself. + private static final Oid DEFAULT_SPNEGO_MECH_OID = + ProviderList.DEFAULT_MECH_OID.equals(GSS_SPNEGO_MECH_OID)? + GSSUtil.GSS_KRB5_MECH_OID: + ProviderList.DEFAULT_MECH_OID; + // Use an instance of a GSSManager whose provider list // does not include native provider final GSSManagerImpl manager; @@ -100,18 +106,27 @@ public final class SpNegoMechFactory implements MechanismFactory { availableMechs[j++] = mechs[i]; } } + // Move the preferred mech to first place + for (int i=0; i>> Credentials acquireServiceCreds: " + + "global OK-AS-DELEGATE turned off at " + + newTgt.getServer()); + } + okAsDelegate = false; + } if (DEBUG) { @@ -283,6 +293,9 @@ rs. System.out.println(">>> Credentials acquireServiceCreds: returning creds:"); Credentials.printDebug(theCreds); } + if (!okAsDelegate) { + theCreds.resetDelegate(); + } return theCreds; } throw new KrbApErrException(Krb5.KRB_AP_ERR_GEN_CRED, diff --git a/src/share/classes/sun/security/provider/certpath/OCSPChecker.java b/src/share/classes/sun/security/provider/certpath/OCSPChecker.java index 499a5912aca40022c639e1c42139cc8a91262418..3d17803f765d236c1c1c131838d868eecc000962 100644 --- a/src/share/classes/sun/security/provider/certpath/OCSPChecker.java +++ b/src/share/classes/sun/security/provider/certpath/OCSPChecker.java @@ -335,10 +335,13 @@ class OCSPChecker extends PKIXCertPathChecker { response = OCSP.check(Collections.singletonList(certId), uri, responderCert, pkixParams.getDate()); } catch (Exception e) { - // Wrap all exceptions in CertPathValidatorException so that - // we can fallback to CRLs, if enabled. - throw new CertPathValidatorException - ("Unable to send OCSP request", e); + if (e instanceof CertPathValidatorException) { + throw (CertPathValidatorException) e; + } else { + // Wrap exceptions in CertPathValidatorException so that + // we can fallback to CRLs, if enabled. + throw new CertPathValidatorException(e); + } } RevocationStatus rs = (RevocationStatus) response.getSingleResponse(certId); diff --git a/src/share/classes/sun/security/util/SecurityConstants.java b/src/share/classes/sun/security/util/SecurityConstants.java index 89c6fd7fdea445fa4dea06c28114e18cf539c3fd..8ba512390b10e46892047576e2f297f853a369d1 100644 --- a/src/share/classes/sun/security/util/SecurityConstants.java +++ b/src/share/classes/sun/security/util/SecurityConstants.java @@ -33,7 +33,6 @@ import java.security.Permission; import java.security.BasicPermission; import java.security.SecurityPermission; import java.security.AllPermission; -import javax.security.auth.AuthPermission; /** * Permission constants and string constants used to create permissions @@ -259,12 +258,4 @@ public final class SecurityConstants { // java.lang.SecurityManager public static final SocketPermission LOCAL_LISTEN_PERMISSION = new SocketPermission("localhost:1024-", SOCKET_LISTEN_ACTION); - - // javax.security.auth.Subject - public static final AuthPermission DO_AS_PERMISSION = - new AuthPermission("doAs"); - - // javax.security.auth.Subject - public static final AuthPermission DO_AS_PRIVILEGED_PERMISSION = - new AuthPermission("doAsPrivileged"); } diff --git a/src/share/classes/sun/security/validator/PKIXValidator.java b/src/share/classes/sun/security/validator/PKIXValidator.java index 1cc6a4ee5a4367eb108adf0a9f5e854227f78b86..eb12ef2200241b0b11c81c8c113589559e655b97 100644 --- a/src/share/classes/sun/security/validator/PKIXValidator.java +++ b/src/share/classes/sun/security/validator/PKIXValidator.java @@ -150,9 +150,17 @@ public final class PKIXValidator extends Validator { ("null or zero-length certificate chain"); } if (TRY_VALIDATOR) { - // check if chain contains trust anchor + // check that chain is in correct order and check if chain contains + // trust anchor + X500Principal prevIssuer = null; for (int i = 0; i < chain.length; i++) { - if (trustedCerts.contains(chain[i])) { + X509Certificate cert = chain[i]; + if (i != 0 && + !cert.getSubjectX500Principal().equals(prevIssuer)) { + // chain is not ordered correctly, call builder instead + return doBuild(chain, otherCerts); + } + if (trustedCerts.contains(cert)) { if (i == 0) { return new X509Certificate[] {chain[0]}; } @@ -161,6 +169,7 @@ public final class PKIXValidator extends Validator { System.arraycopy(chain, 0, newChain, 0, i); return doValidate(newChain); } + prevIssuer = cert.getIssuerX500Principal(); } // apparently issued by trust anchor? @@ -303,5 +312,4 @@ public final class PKIXValidator extends Validator { ("PKIX path building failed: " + e.toString(), e); } } - } diff --git a/src/share/classes/sun/swing/SwingLazyValue.java b/src/share/classes/sun/swing/SwingLazyValue.java index f5587282abb89cf1aca3a7f412dcbef56cc18e92..02236ddff738c8dcb5257be307060018c8c88a6c 100644 --- a/src/share/classes/sun/swing/SwingLazyValue.java +++ b/src/share/classes/sun/swing/SwingLazyValue.java @@ -26,6 +26,9 @@ package sun.swing; import java.lang.reflect.Constructor; import java.lang.reflect.Method; +import java.lang.reflect.AccessibleObject; +import java.security.AccessController; +import java.security.PrivilegedAction; import javax.swing.UIDefaults; /** @@ -65,13 +68,15 @@ public class SwingLazyValue implements UIDefaults.LazyValue { if (methodName != null) { Class[] types = getClassArray(args); Method m = c.getMethod(methodName, types); + makeAccessible(m); return m.invoke(c, args); } else { Class[] types = getClassArray(args); Constructor constructor = c.getConstructor(types); + makeAccessible(constructor); return constructor.newInstance(args); } - } catch(Exception e) { + } catch (Exception e) { // Ideally we would throw an exception, unfortunately // often times there are errors as an initial look and // feel is loaded before one can be switched. Perhaps a @@ -81,6 +86,15 @@ public class SwingLazyValue implements UIDefaults.LazyValue { return null; } + private void makeAccessible(final AccessibleObject object) { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { + object.setAccessible(true); + return null; + } + }); + } + private Class[] getClassArray(Object[] args) { Class[] types = null; if (args!=null) { diff --git a/src/share/classes/sun/swing/SwingUtilities2.java b/src/share/classes/sun/swing/SwingUtilities2.java index 60681d56fbc951f2aa1db1105d0acdca58606f41..5b835bfec54def2784100183d5aaba3bba6d856b 100644 --- a/src/share/classes/sun/swing/SwingUtilities2.java +++ b/src/share/classes/sun/swing/SwingUtilities2.java @@ -1807,22 +1807,4 @@ public class SwingUtilities2 { boolean three) { return liesIn(rect, p, false, false, three); } - - /** - * Returns the {@code JViewport} instance for the {@code component} - * or {@code null}. - * - * @return the {@code JViewport} instance for the {@code component} - * or {@code null} - * @throws NullPointerException if {@code component} is {@code null} - */ - public static JViewport getViewport(Component component) { - do { - component = component.getParent(); - if (component instanceof JViewport) { - return (JViewport) component; - } - } while(component instanceof JLayer); - return null; - } } diff --git a/src/share/classes/sun/tracing/MultiplexProviderFactory.java b/src/share/classes/sun/tracing/MultiplexProviderFactory.java index 6ede31ec158b73539225e268910a0aedd8b8ae0a..14c27c76d869f5da00205395315f85081bcae0aa 100644 --- a/src/share/classes/sun/tracing/MultiplexProviderFactory.java +++ b/src/share/classes/sun/tracing/MultiplexProviderFactory.java @@ -30,7 +30,6 @@ import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.HashSet; import java.util.Set; -import java.util.logging.Logger; import com.sun.tracing.ProviderFactory; import com.sun.tracing.Provider; @@ -65,13 +64,7 @@ public class MultiplexProviderFactory extends ProviderFactory { providers.add(factory.createProvider(cls)); } MultiplexProvider provider = new MultiplexProvider(cls, providers); - try { - provider.init(); - } catch (Exception e) { - // Probably a permission problem (can't get declared members) - Logger.getAnonymousLogger().warning( - "Could not initialize tracing provider: " + e.getMessage()); - } + provider.init(); return provider.newProxyInstance(); } } diff --git a/src/share/classes/sun/tracing/NullProviderFactory.java b/src/share/classes/sun/tracing/NullProviderFactory.java index f567acabb324818dee82611fa554d9bb061c32b9..5416fe35e53bc69fcda0eba09f388682e61c7150 100644 --- a/src/share/classes/sun/tracing/NullProviderFactory.java +++ b/src/share/classes/sun/tracing/NullProviderFactory.java @@ -26,7 +26,6 @@ package sun.tracing; import java.lang.reflect.Method; -import java.util.logging.Logger; import com.sun.tracing.ProviderFactory; import com.sun.tracing.Provider; @@ -53,13 +52,7 @@ public class NullProviderFactory extends ProviderFactory { */ public T createProvider(Class cls) { NullProvider provider = new NullProvider(cls); - try { - provider.init(); - } catch (Exception e) { - // Probably a permission problem (can't get declared members) - Logger.getAnonymousLogger().warning( - "Could not initialize tracing provider: " + e.getMessage()); - } + provider.init(); return provider.newProxyInstance(); } } diff --git a/src/share/classes/sun/tracing/PrintStreamProviderFactory.java b/src/share/classes/sun/tracing/PrintStreamProviderFactory.java index 53013041653479f7833dcb8c09cc4baffeca4c54..cca6bb58df53d37f9467d75a1ef1e4dfa3d21fae 100644 --- a/src/share/classes/sun/tracing/PrintStreamProviderFactory.java +++ b/src/share/classes/sun/tracing/PrintStreamProviderFactory.java @@ -28,7 +28,6 @@ package sun.tracing; import java.lang.reflect.Method; import java.io.PrintStream; import java.util.HashMap; -import java.util.logging.Logger; import com.sun.tracing.ProviderFactory; import com.sun.tracing.Provider; @@ -54,13 +53,7 @@ public class PrintStreamProviderFactory extends ProviderFactory { public T createProvider(Class cls) { PrintStreamProvider provider = new PrintStreamProvider(cls, stream); - try { - provider.init(); - } catch (Exception e) { - // Probably a permission problem (can't get declared members) - Logger.getAnonymousLogger().warning( - "Could not initialize tracing provider: " + e.getMessage()); - } + provider.init(); return provider.newProxyInstance(); } } diff --git a/src/share/classes/sun/tracing/ProviderSkeleton.java b/src/share/classes/sun/tracing/ProviderSkeleton.java index 0178fe46ed85a45510be09b7b7537caae0349548..dd7cbb1976a43a9a27a815d93beeccf028c536a5 100644 --- a/src/share/classes/sun/tracing/ProviderSkeleton.java +++ b/src/share/classes/sun/tracing/ProviderSkeleton.java @@ -32,6 +32,8 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.AnnotatedElement; import java.lang.annotation.Annotation; import java.util.HashMap; +import java.security.AccessController; +import java.security.PrivilegedAction; import com.sun.tracing.Provider; import com.sun.tracing.Probe; @@ -99,7 +101,13 @@ public abstract class ProviderSkeleton implements InvocationHandler, Provider { * It is up to the factory implementations to call this after construction. */ public void init() { - for (Method m : providerType.getDeclaredMethods()) { + Method[] methods = AccessController.doPrivileged(new PrivilegedAction() { + public Method[] run() { + return providerType.getDeclaredMethods(); + } + }); + + for (Method m : methods) { if ( m.getReturnType() != Void.TYPE ) { throw new IllegalArgumentException( "Return value of method is not void"); diff --git a/src/share/classes/sun/tracing/dtrace/DTraceProviderFactory.java b/src/share/classes/sun/tracing/dtrace/DTraceProviderFactory.java index 3148f6f6db4ee7fb7773d751621dcd16c0beadfa..ce921d88eebe91f35cf121dd4e02735e08c574ff 100644 --- a/src/share/classes/sun/tracing/dtrace/DTraceProviderFactory.java +++ b/src/share/classes/sun/tracing/dtrace/DTraceProviderFactory.java @@ -29,7 +29,6 @@ import java.util.Map; import java.util.Set; import java.util.HashMap; import java.util.HashSet; -import java.util.logging.Logger; import java.security.Permission; import com.sun.tracing.ProviderFactory; @@ -80,15 +79,8 @@ public final class DTraceProviderFactory extends ProviderFactory { DTraceProvider jsdt = new DTraceProvider(cls); T proxy = jsdt.newProxyInstance(); jsdt.setProxy(proxy); - try { - jsdt.init(); - new Activation(jsdt.getModuleName(), new DTraceProvider[] { jsdt }); - } catch (Exception e) { - // Probably a permission problem (can't get declared members) - Logger.getAnonymousLogger().warning( - "Could not initialize tracing provider: " + e.getMessage()); - jsdt.dispose(); - } + jsdt.init(); + new Activation(jsdt.getModuleName(), new DTraceProvider[] { jsdt }); return proxy; } diff --git a/src/share/classes/sun/util/CoreResourceBundleControl-XLocales.java b/src/share/classes/sun/util/CoreResourceBundleControl-XLocales.java.template similarity index 100% rename from src/share/classes/sun/util/CoreResourceBundleControl-XLocales.java rename to src/share/classes/sun/util/CoreResourceBundleControl-XLocales.java.template diff --git a/src/share/classes/sun/util/LocaleDataMetaInfo-XLocales.java b/src/share/classes/sun/util/LocaleDataMetaInfo-XLocales.java.template similarity index 100% rename from src/share/classes/sun/util/LocaleDataMetaInfo-XLocales.java rename to src/share/classes/sun/util/LocaleDataMetaInfo-XLocales.java.template diff --git a/src/share/classes/sun/util/resources/TimeZoneNames.java b/src/share/classes/sun/util/resources/TimeZoneNames.java index 7f2c570cceab6df37314d9ab84018cc3c36ac859..ef9dfdc8c5a2bd458bc3b30334dfb56dba1a57ff 100644 --- a/src/share/classes/sun/util/resources/TimeZoneNames.java +++ b/src/share/classes/sun/util/resources/TimeZoneNames.java @@ -141,6 +141,8 @@ public final class TimeZoneNames extends TimeZoneNamesBundle { "Malaysia Summer Time", "MYST"}; String NORONHA[] = new String[] {"Fernando de Noronha Time", "FNT", "Fernando de Noronha Summer Time", "FNST"}; + String NOVT[] = new String[] {"Novosibirsk Time", "NOVT", + "Novosibirsk Summer Time", "NOVST"}; String NPT[] = new String[] {"Nepal Time", "NPT", "Nepal Summer Time", "NPST"}; String NST[] = new String[] {"Newfoundland Standard Time", "NST", @@ -441,7 +443,8 @@ public final class TimeZoneNames extends TimeZoneNamesBundle { {"America/Winnipeg", CST}, {"America/Yakutat", AKST}, {"America/Yellowknife", MST}, - {"Antarctica/Casey", WST_AUS}, + {"Antarctica/Casey", new String[] {"Casey Time", "CAST", + "Casey Summer Time", "CAST"}}, {"Antarctica/Davis", new String[] {"Davis Time", "DAVT", "Davis Summer Time", "DAVST"}}, {"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville Time", "DDUT", @@ -529,8 +532,8 @@ public final class TimeZoneNames extends TimeZoneNamesBundle { "Philippines Summer Time", "PHST"}}, {"Asia/Muscat", GST}, {"Asia/Nicosia", EET}, - {"Asia/Novosibirsk", new String[] {"Novosibirsk Time", "NOVT", - "Novosibirsk Summer Time", "NOVST"}}, + {"Asia/Novokuznetsk", NOVT}, + {"Asia/Novosibirsk", NOVT}, {"Asia/Oral", new String[] {"Oral Time", "ORAT", "Oral Summer Time", "ORAST"}}, {"Asia/Omsk", new String[] {"Omsk Time", "OMST", diff --git a/src/share/classes/sun/util/resources/TimeZoneNames_de.java b/src/share/classes/sun/util/resources/TimeZoneNames_de.java index 7ff10f89df545133ab21b175dd3d869c6f5296f9..896d72a5c532c9126049c80840dde32c479ce5ac 100644 --- a/src/share/classes/sun/util/resources/TimeZoneNames_de.java +++ b/src/share/classes/sun/util/resources/TimeZoneNames_de.java @@ -141,6 +141,8 @@ public final class TimeZoneNames_de extends TimeZoneNamesBundle { "Malaysische Sommerzeit", "MYST"}; String NORONHA[] = new String[] {"Fernando de Noronha Zeit", "FNT", "Fernando de Noronha Sommerzeit", "FNST"}; + String NOVT[] = new String[] {"Nowosibirsker Zeit", "NOVT", + "Nowosibirsker Sommerzeit", "NOVST"}; String NPT[] = new String[] {"Nepalesische Zeit", "NPT", "Nepalesische Sommerzeit", "NPST"}; String NST[] = new String[] {"Neufundland Normalzeit", "NST", @@ -441,7 +443,6 @@ public final class TimeZoneNames_de extends TimeZoneNamesBundle { {"America/Winnipeg", CST}, {"America/Yakutat", AKST}, {"America/Yellowknife", MST}, - {"Antarctica/Casey", WST_AUS}, {"Antarctica/Davis", new String[] {"Davis Zeit", "DAVT", "Davis Sommerzeit", "DAVST"}}, {"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville Zeit", "DDUT", @@ -529,8 +530,8 @@ public final class TimeZoneNames_de extends TimeZoneNamesBundle { "Philippinische Sommerzeit", "PHST"}}, {"Asia/Muscat", GST}, {"Asia/Nicosia", EET}, - {"Asia/Novosibirsk", new String[] {"Nowosibirsker Zeit", "NOVT", - "Nowosibirsker Sommerzeit", "NOVST"}}, + {"Asia/Novokuznetsk", NOVT}, + {"Asia/Novosibirsk", NOVT}, {"Asia/Oral", new String[] {"Oral Zeit", "ORAT", "Oral Sommerzeit", "ORAST"}}, {"Asia/Omsk", new String[] {"Omsk Zeit", "OMST", diff --git a/src/share/classes/sun/util/resources/TimeZoneNames_es.java b/src/share/classes/sun/util/resources/TimeZoneNames_es.java index 9e1ffa8397cbd89f4e4c01e42942ca8994c198ba..20605d1187a332dde3f255583b07a12ef8aa650b 100644 --- a/src/share/classes/sun/util/resources/TimeZoneNames_es.java +++ b/src/share/classes/sun/util/resources/TimeZoneNames_es.java @@ -141,6 +141,8 @@ public final class TimeZoneNames_es extends TimeZoneNamesBundle { "Hora de verano de Malasia", "MYST"}; String NORONHA[] = new String[] {"Hora de Fernando de Noronha", "FNT", "Hora de verano de Fernando de Noronha", "FNST"}; + String NOVT[] = new String[] {"Hora de Novosibirsk", "NOVT", + "Hora de verano de Novosibirsk", "NOVST"}; String NPT[] = new String[] {"Hora de Nepal", "NPT", "Hora de verano de Nepal", "NPST"}; String NST[] = new String[] {"Hora est\u00e1ndar de Terranova", "NST", @@ -441,7 +443,6 @@ public final class TimeZoneNames_es extends TimeZoneNamesBundle { {"America/Winnipeg", CST}, {"America/Yakutat", AKST}, {"America/Yellowknife", MST}, - {"Antarctica/Casey", WST_AUS}, {"Antarctica/Davis", new String[] {"Hora de Davis", "DAVT", "Hora de verano de Davis", "DAVST"}}, {"Antarctica/DumontDUrville", new String[] {"Hora de Dumont-d'Urville", "DDUT", @@ -529,8 +530,9 @@ public final class TimeZoneNames_es extends TimeZoneNamesBundle { "Hora de verano de Filipinas", "PHST"}}, {"Asia/Muscat", GST}, {"Asia/Nicosia", EET}, - {"Asia/Novosibirsk", new String[] {"Hora de Novosibirsk", "NOVT", - "Hora de verano de Novosibirsk", "NOVST"}}, + + {"Asia/Novokuznetsk", NOVT}, + {"Asia/Novosibirsk", NOVT}, {"Asia/Oral", new String[] {"Hora de Uralsk", "ORAT", "Hora de verano de Uralsk", "ORAST"}}, {"Asia/Omsk", new String[] {"Hora de Omsk", "OMST", diff --git a/src/share/classes/sun/util/resources/TimeZoneNames_fr.java b/src/share/classes/sun/util/resources/TimeZoneNames_fr.java index 941bc4e972a8e694e3fe49dc0f498810b440e5f3..e3f8205584a730e79a2bc7a26ad35989418aae5e 100644 --- a/src/share/classes/sun/util/resources/TimeZoneNames_fr.java +++ b/src/share/classes/sun/util/resources/TimeZoneNames_fr.java @@ -141,6 +141,8 @@ public final class TimeZoneNames_fr extends TimeZoneNamesBundle { "Heure d'\u00e9t\u00e9 de Malaisie", "MYST"}; String NORONHA[] = new String[] {"Heure de Fernando de Noronha", "FNT", "Heure d'\u00e9t\u00e9 de Fernando de Noronha", "FNST"}; + String NOVT[] = new String[] {"Heure de Novossibirsk", "NOVT", + "Heure d'\u00e9t\u00e9 de Novossibirsk", "NOVST"}; String NPT[] = new String[] {"Heure du N\u00e9pal", "NPT", "Heure d'\u00e9t\u00e9 du N\u00e9pal", "NPST"}; String NST[] = new String[] {"Heure normale de Terre-Neuve", "NST", @@ -441,7 +443,6 @@ public final class TimeZoneNames_fr extends TimeZoneNamesBundle { {"America/Winnipeg", CST}, {"America/Yakutat", AKST}, {"America/Yellowknife", MST}, - {"Antarctica/Casey", WST_AUS}, {"Antarctica/Davis", new String[] {"Heure de Davis", "DAVT", "Heure d'\u00e9t\u00e9 de Davis", "DAVST"}}, {"Antarctica/DumontDUrville", new String[] {"Heure de Dumont-d'Urville", "DDUT", @@ -529,8 +530,8 @@ public final class TimeZoneNames_fr extends TimeZoneNamesBundle { "Heure d'\u00e9t\u00e9 des Philippines", "PHST"}}, {"Asia/Muscat", GST}, {"Asia/Nicosia", EET}, - {"Asia/Novosibirsk", new String[] {"Heure de Novossibirsk", "NOVT", - "Heure d'\u00e9t\u00e9 de Novossibirsk", "NOVST"}}, + {"Asia/Novokuznetsk", NOVT}, + {"Asia/Novosibirsk", NOVT}, {"Asia/Oral", new String[] {"Heure d'Oral", "ORAT", "Heure d'\u00e9t\u00e9 d'Oral", "ORAST"}}, {"Asia/Omsk", new String[] {"Heure d'Omsk", "OMST", diff --git a/src/share/classes/sun/util/resources/TimeZoneNames_it.java b/src/share/classes/sun/util/resources/TimeZoneNames_it.java index 499f0fe2d954b1cbd2d5f238acf1a5ec041f2db2..e464618f2af92eed9bb5719bcb633b97eb5bc24b 100644 --- a/src/share/classes/sun/util/resources/TimeZoneNames_it.java +++ b/src/share/classes/sun/util/resources/TimeZoneNames_it.java @@ -141,6 +141,8 @@ public final class TimeZoneNames_it extends TimeZoneNamesBundle { "Ora estiva della Malaysia", "MYST"}; String NORONHA[] = new String[] {"Ora di Fernando de Noronha", "FNT", "Ora estiva di Fernando de Noronha", "FNST"}; + String NOVT[] = new String[] {"Ora di Novosibirsk", "NOVT", + "Ora estiva di Novosibirsk", "NOVST"}; String NPT[] = new String[] {"Ora del Nepal", "NPT", "Ora estiva del Nepal", "NPST"}; String NST[] = new String[] {"Ora solare di Terranova", "NST", @@ -441,7 +443,6 @@ public final class TimeZoneNames_it extends TimeZoneNamesBundle { {"America/Winnipeg", CST}, {"America/Yakutat", AKST}, {"America/Yellowknife", MST}, - {"Antarctica/Casey", WST_AUS}, {"Antarctica/Davis", new String[] {"Ora di Davis", "DAVT", "Ora estiva di Davis", "DAVST"}}, {"Antarctica/DumontDUrville", new String[] {"Ora di Dumont-d'Urville", "DDUT", @@ -529,8 +530,8 @@ public final class TimeZoneNames_it extends TimeZoneNamesBundle { "Ora estiva delle Filippine", "PHST"}}, {"Asia/Muscat", GST}, {"Asia/Nicosia", EET}, - {"Asia/Novosibirsk", new String[] {"Ora di Novosibirsk", "NOVT", - "Ora estiva di Novosibirsk", "NOVST"}}, + {"Asia/Novokuznetsk", NOVT}, + {"Asia/Novosibirsk", NOVT}, {"Asia/Oral", new String[] {"Ora di Oral", "ORAT", "Ora estiva di Oral", "ORAST"}}, {"Asia/Omsk", new String[] {"Ora di Omsk", "OMST", diff --git a/src/share/classes/sun/util/resources/TimeZoneNames_ja.java b/src/share/classes/sun/util/resources/TimeZoneNames_ja.java index 583a0a4e1c889cf1ec245b0c4350d76c6fdc1955..1292e4b8045b59e1914d8319425c3af1f578c170 100644 --- a/src/share/classes/sun/util/resources/TimeZoneNames_ja.java +++ b/src/share/classes/sun/util/resources/TimeZoneNames_ja.java @@ -141,6 +141,8 @@ public final class TimeZoneNames_ja extends TimeZoneNamesBundle { "\u30de\u30ec\u30fc\u30b7\u30a2\u590f\u6642\u9593", "MYST"}; String NORONHA[] = new String[] {"\u30d5\u30a7\u30eb\u30ca\u30f3\u30c9\u30fb\u30c7\u30fb\u30ce\u30ed\u30fc\u30cb\u30e3\u6642\u9593", "FNT", "\u30d5\u30a7\u30eb\u30ca\u30f3\u30c9\u30fb\u30c7\u30fb\u30ce\u30ed\u30fc\u30cb\u30e3\u590f\u6642\u9593", "FNST"}; + String NOVT[] = new String[] {"\u30ce\u30dc\u30b7\u30d3\u30eb\u30b9\u30af\u6642\u9593", "NOVT", + "\u30ce\u30dc\u30b7\u30d3\u30eb\u30b9\u30af\u590f\u6642\u9593", "NOVST"}; String NPT[] = new String[] {"\u30cd\u30d1\u30fc\u30eb\u6642\u9593", "NPT", "\u30cd\u30d1\u30fc\u30eb\u590f\u6642\u9593", "NPST"}; String NST[] = new String[] {"\u30cb\u30e5\u30fc\u30d5\u30a1\u30f3\u30c9\u30e9\u30f3\u30c9\u6a19\u6e96\u6642", "NST", @@ -441,7 +443,6 @@ public final class TimeZoneNames_ja extends TimeZoneNamesBundle { {"America/Winnipeg", CST}, {"America/Yakutat", AKST}, {"America/Yellowknife", MST}, - {"Antarctica/Casey", WST_AUS}, {"Antarctica/Davis", new String[] {"\u30c7\u30a4\u30d3\u30b9\u6642\u9593", "DAVT", "\u30c7\u30a4\u30d3\u30b9\u590f\u6642\u9593", "DAVST"}}, {"Antarctica/DumontDUrville", new String[] {"\u30c7\u30e5\u30e2\u30f3\u30c7\u30e5\u30eb\u30f4\u30a3\u30eb\u6642\u9593", "DDUT", @@ -529,8 +530,8 @@ public final class TimeZoneNames_ja extends TimeZoneNamesBundle { "\u30d5\u30a3\u30ea\u30d4\u30f3\u590f\u6642\u9593", "PHST"}}, {"Asia/Muscat", GST}, {"Asia/Nicosia", EET}, - {"Asia/Novosibirsk", new String[] {"\u30ce\u30dc\u30b7\u30d3\u30eb\u30b9\u30af\u6642\u9593", "NOVT", - "\u30ce\u30dc\u30b7\u30d3\u30eb\u30b9\u30af\u590f\u6642\u9593", "NOVST"}}, + {"Asia/Novokuznetsk", NOVT}, + {"Asia/Novosibirsk", NOVT}, {"Asia/Oral", new String[] {"\u30aa\u30e9\u30eb\u6642\u9593", "ORAT", "\u30aa\u30e9\u30eb\u590f\u6642\u9593", "ORAST"}}, {"Asia/Omsk", new String[] {"\u30aa\u30e0\u30b9\u30af\u6642\u9593", "OMST", diff --git a/src/share/classes/sun/util/resources/TimeZoneNames_ko.java b/src/share/classes/sun/util/resources/TimeZoneNames_ko.java index 3e179dad3a81a432347c27bd15ac30e8a21a13a4..f69e08b250eb62135da6934b8307113206e1f85b 100644 --- a/src/share/classes/sun/util/resources/TimeZoneNames_ko.java +++ b/src/share/classes/sun/util/resources/TimeZoneNames_ko.java @@ -141,6 +141,8 @@ public final class TimeZoneNames_ko extends TimeZoneNamesBundle { "\ub9d0\ub808\uc774\uc2dc\uc544 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "MYST"}; String NORONHA[] = new String[] {"Fernando de Noronha \uc2dc\uac04", "FNT", "Fernando de Noronha \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "FNST"}; + String NOVT[] = new String[] {"\ub178\ube0c\uc2dc\ube4c\uc2a4\ud06c \uc2dc\uac04", "NOVT", + "\ub178\ube0c\uc2dc\ube4c\uc2a4\ud06c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "NOVST"}; String NPT[] = new String[] {"\ub124\ud314 \uc2dc\uac04", "NPT", "\ub124\ud314 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "NPST"}; String NST[] = new String[] {"\ub274\ud380\ub4e4\ub79c\ub4dc \ud45c\uc900\uc2dc", "NST", @@ -441,7 +443,6 @@ public final class TimeZoneNames_ko extends TimeZoneNamesBundle { {"America/Winnipeg", CST}, {"America/Yakutat", AKST}, {"America/Yellowknife", MST}, - {"Antarctica/Casey", WST_AUS}, {"Antarctica/Davis", new String[] {"Davis \uc2dc\uac04", "DAVT", "Davis \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "DAVST"}}, {"Antarctica/DumontDUrville", new String[] {"\ub4a4\ubabd \ub4a4\ub974\ube4c \uc2dc\uac04", "DDUT", @@ -529,8 +530,8 @@ public final class TimeZoneNames_ko extends TimeZoneNamesBundle { "\ud544\ub9ac\ud540 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "PHST"}}, {"Asia/Muscat", GST}, {"Asia/Nicosia", EET}, - {"Asia/Novosibirsk", new String[] {"\ub178\ube0c\uc2dc\ube4c\uc2a4\ud06c \uc2dc\uac04", "NOVT", - "\ub178\ube0c\uc2dc\ube4c\uc2a4\ud06c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "NOVST"}}, + {"Asia/Novokuznetsk", NOVT}, + {"Asia/Novosibirsk", NOVT}, {"Asia/Oral", new String[] {"Oral \ud45c\uc900\uc2dc", "ORAT", "Oral \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "ORAST"}}, {"Asia/Omsk", new String[] {"Omsk \uc2dc\uac04", "OMST", diff --git a/src/share/classes/sun/util/resources/TimeZoneNames_sv.java b/src/share/classes/sun/util/resources/TimeZoneNames_sv.java index ab13cd9216bcc9fbb1c6dd3707fb333ae24feb02..35ce2d11c5170dd19ada97f65d4b2fd53fcee656 100644 --- a/src/share/classes/sun/util/resources/TimeZoneNames_sv.java +++ b/src/share/classes/sun/util/resources/TimeZoneNames_sv.java @@ -141,6 +141,8 @@ public final class TimeZoneNames_sv extends TimeZoneNamesBundle { "Malaysia, sommartid", "MYST"}; String NORONHA[] = new String[] {"Fernando de Noronha, normaltid", "FNT", "Fernando de Noronha, sommartid", "FNST"}; + String NOVT[] = new String[] {"Novosibirsk, normaltid", "NOVT", + "Novosibirsk, sommartid", "NOVST"}; String NPT[] = new String[] {"Nepal, normaltid", "NPT", "Nepal, sommartid", "NPST"}; String NST[] = new String[] {"Newfoundland, normaltid", "NST", @@ -441,7 +443,6 @@ public final class TimeZoneNames_sv extends TimeZoneNamesBundle { {"America/Winnipeg", CST}, {"America/Yakutat", AKST}, {"America/Yellowknife", MST}, - {"Antarctica/Casey", WST_AUS}, {"Antarctica/Davis", new String[] {"Davis, normaltid", "DAVT", "Davis, sommartid", "DAVST"}}, {"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville, normaltid", "DDUT", @@ -529,8 +530,8 @@ public final class TimeZoneNames_sv extends TimeZoneNamesBundle { "Filippinerna, sommartid", "PHST"}}, {"Asia/Muscat", GST}, {"Asia/Nicosia", EET}, - {"Asia/Novosibirsk", new String[] {"Novosibirsk, normaltid", "NOVT", - "Novosibirsk, sommartid", "NOVST"}}, + {"Asia/Novokuznetsk", NOVT}, + {"Asia/Novosibirsk", NOVT}, {"Asia/Oral", new String[] {"Oral, normaltid", "ORAT", "Oral, sommartid", "ORAST"}}, {"Asia/Omsk", new String[] {"Omsk, normaltid", "OMST", diff --git a/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java b/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java index e0dc1ec7ea3c746310886694ee30a61f9eabb3d5..70cdbd0a9879551e5f070f023e2aacbcaf9158b4 100644 --- a/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java +++ b/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java @@ -141,6 +141,8 @@ public final class TimeZoneNames_zh_CN extends TimeZoneNamesBundle { "\u9a6c\u6765\u897f\u4e9a\u590f\u4ee4\u65f6", "MYST"}; String NORONHA[] = new String[] {"\u8d39\u5c14\u5357\u591a\u5fb7\u8bfa\u7f57\u5c3c\u4e9a\u65f6\u95f4", "FNT", "\u8d39\u5c14\u5357\u591a\u5fb7\u8bfa\u7f57\u5c3c\u4e9a\u590f\u4ee4\u65f6", "FNST"}; + String NOVT[] = new String[] {"Novosibirsk \u65f6\u95f4", "NOVT", + "Novosibirsk \u590f\u4ee4\u65f6", "NOVST"}; String NPT[] = new String[] {"\u5c3c\u6cca\u5c14\u65f6\u95f4", "NPT", "\u5c3c\u6cca\u5c14\u590f\u4ee4\u65f6", "NPST"}; String NST[] = new String[] {"\u7ebd\u82ac\u5170\u6807\u51c6\u65f6\u95f4", "NST", @@ -441,7 +443,6 @@ public final class TimeZoneNames_zh_CN extends TimeZoneNamesBundle { {"America/Winnipeg", CST}, {"America/Yakutat", AKST}, {"America/Yellowknife", MST}, - {"Antarctica/Casey", WST_AUS}, {"Antarctica/Davis", new String[] {"\u6234\u7ef4\u65af\u65f6\u95f4", "DAVT", "\u6234\u7ef4\u65af\u590f\u4ee4\u65f6", "DAVST"}}, {"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville \u65f6\u95f4", "DDUT", @@ -529,8 +530,8 @@ public final class TimeZoneNames_zh_CN extends TimeZoneNamesBundle { "\u83f2\u5f8b\u5bbe\u590f\u4ee4\u65f6", "PHST"}}, {"Asia/Muscat", GST}, {"Asia/Nicosia", EET}, - {"Asia/Novosibirsk", new String[] {"Novosibirsk \u65f6\u95f4", "NOVT", - "Novosibirsk \u590f\u4ee4\u65f6", "NOVST"}}, + {"Asia/Novokuznetsk", NOVT}, + {"Asia/Novosibirsk", NOVT}, {"Asia/Oral", new String[] {"Oral \u65f6\u95f4", "ORAT", "Oral \u590f\u4ee4\u65f6", "ORAST"}}, {"Asia/Omsk", new String[] {"\u9102\u6728\u65af\u514b\u65f6\u95f4", "OMST", diff --git a/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java b/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java index 73dd22cad1e45b044e00aa211008067c0ea21aa4..f5b89286ed07754a72a75222cbc030ddf674b57d 100644 --- a/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java +++ b/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java @@ -141,6 +141,8 @@ public final class TimeZoneNames_zh_TW extends TimeZoneNamesBundle { "\u99ac\u4f86\u897f\u4e9e\u590f\u4ee4\u6642\u9593", "MYST"}; String NORONHA[] = new String[] {"\u8cbb\u723e\u5357\u591a-\u8fea\u8afe\u7f85\u5c3c\u4e9e\u6642\u9593", "FNT", "\u8cbb\u723e\u5357\u591a-\u8fea\u8afe\u7f85\u5c3c\u4e9e\u590f\u4ee4\u6642\u9593", "FNST"}; + String NOVT[] = new String[] {"Novosibirsk \u6642\u9593", "NOVT", + "Novosibirsk \u590f\u4ee4\u6642\u9593", "NOVST"}; String NPT[] = new String[] {"\u5c3c\u6cca\u723e\u6642\u9593", "NPT", "\u5c3c\u6cca\u723e\u590f\u4ee4\u6642\u9593", "NPST"}; String NST[] = new String[] {"\u7d10\u82ac\u862d\u6a19\u6e96\u6642\u9593", "NST", @@ -441,7 +443,6 @@ public final class TimeZoneNames_zh_TW extends TimeZoneNamesBundle { {"America/Winnipeg", CST}, {"America/Yakutat", AKST}, {"America/Yellowknife", MST}, - {"Antarctica/Casey", WST_AUS}, {"Antarctica/Davis", new String[] {"\u81fa\u7dad\u65af\u6642\u9593", "DAVT", "\u81fa\u7dad\u65af\u590f\u4ee4\u6642\u9593", "DAVST"}}, {"Antarctica/DumontDUrville", new String[] {"Dumont-d'Urville \u6642\u9593", "DDUT", @@ -529,8 +530,8 @@ public final class TimeZoneNames_zh_TW extends TimeZoneNamesBundle { "\u83f2\u5f8b\u8cd3\u590f\u4ee4\u6642\u9593", "PHST"}}, {"Asia/Muscat", GST}, {"Asia/Nicosia", EET}, - {"Asia/Novosibirsk", new String[] {"Novosibirsk \u6642\u9593", "NOVT", - "Novosibirsk \u590f\u4ee4\u6642\u9593", "NOVST"}}, + {"Asia/Novokuznetsk", NOVT}, + {"Asia/Novosibirsk", NOVT}, {"Asia/Oral", new String[] {"\u6b50\u4f5b\u6642\u9593", "ORAT", "\u6b50\u4f5b\u590f\u4ee4\u6642\u9593", "ORAST"}}, {"Asia/Omsk", new String[] {"\u6b50\u59c6\u65af\u514b (Omsk) \u6642\u9593", "OMST", diff --git a/src/share/native/sun/awt/image/jpeg/imageioJPEG.c b/src/share/native/sun/awt/image/jpeg/imageioJPEG.c index 3897ddc86c6dfda9ea3cd1e790d019e638ad4a63..001d7de936fac125d99e0e643925445262304b9e 100644 --- a/src/share/native/sun/awt/image/jpeg/imageioJPEG.c +++ b/src/share/native/sun/awt/image/jpeg/imageioJPEG.c @@ -1460,6 +1460,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_initJPEGImageReader JNU_ThrowByName( env, "java/lang/OutOfMemoryError", "Initializing Reader"); + free(cinfo); return 0; } @@ -1496,6 +1497,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_initJPEGImageReader JNU_ThrowByName(env, "java/lang/OutOfMemoryError", "Initializing Reader"); + imageio_dispose((j_common_ptr)cinfo); return 0; } cinfo->src->bytes_in_buffer = 0; @@ -1512,6 +1514,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_initJPEGImageReader JNU_ThrowByName( env, "java/lang/OutOfMemoryError", "Initializing Reader"); + imageio_dispose((j_common_ptr)cinfo); return 0; } return (jlong) ret; @@ -2450,8 +2453,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_initJPEGImageWriter JNU_ThrowByName( env, "java/lang/OutOfMemoryError", "Initializing Writer"); - free(cinfo); - free(jerr); + imageio_dispose((j_common_ptr)cinfo); return 0; } @@ -2469,8 +2471,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_initJPEGImageWriter JNU_ThrowByName( env, "java/lang/OutOfMemoryError", "Initializing Writer"); - free(cinfo); - free(jerr); + imageio_dispose((j_common_ptr)cinfo); return 0; } return (jlong) ret; diff --git a/src/share/native/sun/awt/medialib/awt_ImagingLib.c b/src/share/native/sun/awt/medialib/awt_ImagingLib.c index 157827fef29b105239e913872854a3c7c98cc02e..07f9187ffc88120242e9841e7270355c5f059388 100644 --- a/src/share/native/sun/awt/medialib/awt_ImagingLib.c +++ b/src/share/native/sun/awt/medialib/awt_ImagingLib.c @@ -960,21 +960,15 @@ Java_sun_awt_image_ImagingLib_transformRaster(JNIEnv *env, jobject this, mlib_filter filter; unsigned int *dP; - if ((srcRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) { - JNU_ThrowOutOfMemoryError(env, "Out of memory"); - return -1; - } - - if ((dstRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) { - JNU_ThrowOutOfMemoryError(env, "Out of memory"); - free(srcRasterP); - return -1; - } - /* This function requires a lot of local refs ??? Is 64 enough ??? */ if ((*env)->EnsureLocalCapacity(env, 64) < 0) return 0; + if (s_nomlib) return 0; + if (s_timeIt) { + (*start_timer)(3600); + } + switch(interpType) { case java_awt_image_AffineTransformOp_TYPE_BILINEAR: filter = MLIB_BILINEAR; @@ -990,9 +984,15 @@ Java_sun_awt_image_ImagingLib_transformRaster(JNIEnv *env, jobject this, return -1; } - if (s_nomlib) return 0; - if (s_timeIt) { - (*start_timer)(3600); + if ((srcRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) { + JNU_ThrowOutOfMemoryError(env, "Out of memory"); + return -1; + } + + if ((dstRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) { + JNU_ThrowOutOfMemoryError(env, "Out of memory"); + free(srcRasterP); + return -1; } if ((*env)->GetArrayLength(env, jmatrix) < 6) { @@ -1215,6 +1215,9 @@ Java_sun_awt_image_ImagingLib_lookupByteBI(JNIEnv *env, jobject this, } if (tbl == NULL || table == NULL || jtable == NULL) { + if (tbl != NULL) free(tbl); + if (table != NULL) free(table); + if (jtable != NULL) free(jtable); awt_freeParsedImage(srcImageP, TRUE); awt_freeParsedImage(dstImageP, TRUE); JNU_ThrowNullPointerException(env, "NULL LUT"); @@ -1224,6 +1227,11 @@ Java_sun_awt_image_ImagingLib_lookupByteBI(JNIEnv *env, jobject this, for (i=0; i < jlen; i++) { jtable[i] = (*env)->GetObjectArrayElement(env, jtableArrays, i); if (jtable[i] == NULL) { + free(tbl); + free(table); + free(jtable); + awt_freeParsedImage(srcImageP, TRUE); + awt_freeParsedImage(dstImageP, TRUE); return 0; } } @@ -1232,6 +1240,9 @@ Java_sun_awt_image_ImagingLib_lookupByteBI(JNIEnv *env, jobject this, FALSE, &hint); if (nbands < 1) { /* Can't handle any custom images */ + free(tbl); + free(table); + free(jtable); awt_freeParsedImage(srcImageP, TRUE); awt_freeParsedImage(dstImageP, TRUE); return 0; @@ -1240,12 +1251,18 @@ Java_sun_awt_image_ImagingLib_lookupByteBI(JNIEnv *env, jobject this, /* Allocate the arrays */ if (allocateArray(env, srcImageP, &src, &sdata, TRUE, FALSE, FALSE) < 0) { /* Must be some problem */ + free(tbl); + free(table); + free(jtable); awt_freeParsedImage(srcImageP, TRUE); awt_freeParsedImage(dstImageP, TRUE); return 0; } if (allocateArray(env, dstImageP, &dst, &ddata, FALSE, FALSE, FALSE) < 0) { /* Must be some problem */ + free(tbl); + free(table); + free(jtable); freeArray(env, srcImageP, src, sdata, NULL, NULL, NULL); awt_freeParsedImage(srcImageP, TRUE); awt_freeParsedImage(dstImageP, TRUE); @@ -1284,6 +1301,9 @@ Java_sun_awt_image_ImagingLib_lookupByteBI(JNIEnv *env, jobject this, (jbyte *) table[j], JNI_ABORT); } + free(tbl); + free(table); + free(jtable); freeArray(env, srcImageP, src, sdata, NULL, NULL, NULL); awt_freeParsedImage(srcImageP, TRUE); awt_freeParsedImage(dstImageP, TRUE); @@ -1413,12 +1433,15 @@ Java_sun_awt_image_ImagingLib_lookupByteRaster(JNIEnv *env, /* Parse the source raster - reject custom images */ if ((status = awt_parseRaster(env, jsrc, srcRasterP)) <= 0) { + free(srcRasterP); + free(dstRasterP); return 0; } /* Parse the destination image - reject custom images */ if ((status = awt_parseRaster(env, jdst, dstRasterP)) <= 0) { awt_freeParsedRaster(srcRasterP, TRUE); + free(dstRasterP); return 0; } diff --git a/src/share/native/sun/font/freetypeScaler.c b/src/share/native/sun/font/freetypeScaler.c index 4028d4d97c4bb68abdd41452bfdd373c848235a0..93baaea47cd4e05d2ed0a4891d940d277e5ac6c9 100644 --- a/src/share/native/sun/font/freetypeScaler.c +++ b/src/share/native/sun/font/freetypeScaler.c @@ -102,9 +102,21 @@ Java_sun_font_FreetypeFontScaler_initIDs( } static void freeNativeResources(JNIEnv *env, FTScalerInfo* scalerInfo) { + void *stream; + if (scalerInfo == NULL) return; + //apparently Done_Face will only close the stream + // but will not relase the memory of stream structure. + // We need to free it explicitly to avoid leak. + //Direct access to the stream field might be not ideal solution as + // it is considred to be "private". + //Alternatively we could have stored pointer to the structure + // in the scalerInfo but this will increase size of the structure + // for no good reason + stream = scalerInfo->face->stream; + FT_Done_Face(scalerInfo->face); FT_Done_FreeType(scalerInfo->library); @@ -116,6 +128,10 @@ static void freeNativeResources(JNIEnv *env, FTScalerInfo* scalerInfo) { free(scalerInfo->fontData); } + if (stream != NULL) { + free(stream); + } + free(scalerInfo); } diff --git a/src/solaris/bin/java_md.c b/src/solaris/bin/java_md.c index 73efc1090fddb70c1e82ef639f8bcf9cef8ebe76..7c68ed0831632a057c030c52200962224f23a151 100644 --- a/src/solaris/bin/java_md.c +++ b/src/solaris/bin/java_md.c @@ -1,5 +1,5 @@ /* - * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2009 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,9 +51,9 @@ * two data models and cohabitation of jre/jdk bits with both data * models is supported, then DUAL_MODE is defined. When DUAL_MODE is * defined, the architecture names for the narrow and wide version of - * the architecture are defined in LIBARCH64NAME and LIBARCH32NAME. Currently - * only Solaris on sparc/sparcv9 and i586/amd64 is DUAL_MODE; linux - * i586/amd64 could be defined as DUAL_MODE but that is not the + * the architecture are defined in LIBARCH64NAME and LIBARCH32NAME. + * Currently only Solaris on sparc/sparcv9 and i586/amd64 is DUAL_MODE; + * linux i586/amd64 could be defined as DUAL_MODE but that is not the * current policy. */ @@ -103,49 +103,56 @@ static char *execname = NULL; * platform independent routine SelectVersion. This may result in * the exec of the specified launcher version. * - * Typically, the launcher execs at least once to ensure a suitable - * LD_LIBRARY_PATH is in effect for the process. The first exec - * screens out all the data model options; leaving the choice of data - * model implicit in the binary selected to run. However, in case no - * exec is done, the data model options are screened out before the vm - * is invoked. + * Previously the launcher modified the LD_LIBRARY_PATH appropriately for the + * desired data model path, regardless if data models matched or not. The + * launcher subsequently exec'ed the desired executable, in order to make the + * LD_LIBRARY_PATH path available for the runtime linker. This is no longer the + * case, the launcher dlopens the target libjvm.so. All other required + * libraries are loaded by the runtime linker, by virtue of the $ORIGIN paths + * baked into the shared libraries, by the build infrastructure at compile time. * - * incoming argv ------------------------------ - * | | - * \|/ | - * CheckJVMType | - * (removes -client, -server, etc.) | - * \|/ - * CreateExecutionEnvironment - * (removes -d32 and -d64, - * determines desired data model, - * sets up LD_LIBRARY_PATH, - * and exec's) - * | - * -------------------------------------------- + * Main + * (incoming argv) + * | + * \|/ + * SelectVersion + * (selects the JRE version, note: not data model) + * | + * \|/ + * CreateExecutionEnvironment + * (determines desired data model) + * | * | * \|/ - * exec child 1 incoming argv ----------------- + * Have Desired Model ? --> NO --> Is Dual-Mode ? --> NO --> Exit(with error) + * | | + * | | + * | \|/ + * | YES + * | | * | | - * \|/ | - * CheckJVMType | - * (removes -client, -server, etc.) | * | \|/ - * | CreateExecutionEnvironment - * | (verifies desired data model - * | is running and acceptable - * | LD_LIBRARY_PATH; - * | no-op in child) + * | CheckJvmType + * | (removes -client, -server etc.) + * | | + * | | + * \|/ \|/ + * YES (find the desired executable and exec child) + * | | + * | | + * \|/ \|/ + * CheckJvmType Main + * (removes -client, -server, etc.) + * | * | * \|/ * TranslateDashJArgs... * (Prepare to pass args to vm) * | * | - * | * \|/ * ParseArguments - * (ignores -d32 and -d64, + * (removes -d32 and -d64 if any, * processes version options, * creates argument list for vm, * etc.) @@ -199,17 +206,13 @@ CreateExecutionEnvironment(int *_argcp, /* Compute/set the name of the executable */ SetExecname(*_argvp); - /* Set the LD_LIBRARY_PATH environment variable, check data model - flags, and exec process, if needed */ + /* Check data model flags, and exec process, if needed */ { char *arch = (char *)GetArch(); /* like sparc or sparcv9 */ char * jvmtype = NULL; int argc = *_argcp; char **argv = original_argv; - char *runpath = NULL; /* existing effective LD_LIBRARY_PATH - setting */ - int running = CURRENT_DATA_MODEL; int wanted = running; /* What data mode is being @@ -217,18 +220,8 @@ CreateExecutionEnvironment(int *_argcp, fine unless another model is asked for */ - char* new_runpath = NULL; /* desired new LD_LIBRARY_PATH string */ - char* newpath = NULL; /* path on new LD_LIBRARY_PATH */ - char* lastslash = NULL; - - char** newenvp = NULL; /* current environment */ - char** newargv = NULL; int newargc = 0; -#ifdef __solaris__ - char* dmpath = NULL; /* data model specific LD_LIBRARY_PATH, - Solaris only */ -#endif /* * Starting in 1.5, all unix platforms accept the -d32 and -d64 @@ -306,6 +299,11 @@ CreateExecutionEnvironment(int *_argcp, JLI_ReportErrorMessage(CFG_ERROR8, jvmtype, jvmpath); exit(4); } + /* + * we seem to have everything we need, so without further ado + * we return back. + */ + return; } else { /* do the same speculatively or exit */ #ifdef DUAL_MODE if (running != wanted) { @@ -335,190 +333,6 @@ CreateExecutionEnvironment(int *_argcp, #endif } - /* - * We will set the LD_LIBRARY_PATH as follows: - * - * o $JVMPATH (directory portion only) - * o $JRE/lib/$LIBARCHNAME - * o $JRE/../lib/$LIBARCHNAME - * - * followed by the user's previous effective LD_LIBRARY_PATH, if - * any. - */ - -#ifdef __solaris__ - /* - * Starting in Solaris 7, ld.so.1 supports three LD_LIBRARY_PATH - * variables: - * - * 1. LD_LIBRARY_PATH -- used for 32 and 64 bit searches if - * data-model specific variables are not set. - * - * 2. LD_LIBRARY_PATH_64 -- overrides and replaces LD_LIBRARY_PATH - * for 64-bit binaries. - * - * 3. LD_LIBRARY_PATH_32 -- overrides and replaces LD_LIBRARY_PATH - * for 32-bit binaries. - * - * The vm uses LD_LIBRARY_PATH to set the java.library.path system - * property. To shield the vm from the complication of multiple - * LD_LIBRARY_PATH variables, if the appropriate data model - * specific variable is set, we will act as if LD_LIBRARY_PATH had - * the value of the data model specific variant and the data model - * specific variant will be unset. Note that the variable for the - * *wanted* data model must be used (if it is set), not simply the - * current running data model. - */ - - switch(wanted) { - case 0: - if(running == 32) { - dmpath = getenv("LD_LIBRARY_PATH_32"); - wanted = 32; - } - else { - dmpath = getenv("LD_LIBRARY_PATH_64"); - wanted = 64; - } - break; - - case 32: - dmpath = getenv("LD_LIBRARY_PATH_32"); - break; - - case 64: - dmpath = getenv("LD_LIBRARY_PATH_64"); - break; - - default: - JLI_ReportErrorMessage(JRE_ERROR3, __LINE__); - exit(1); /* unknown value in wanted */ - break; - } - - /* - * If dmpath is NULL, the relevant data model specific variable is - * not set and normal LD_LIBRARY_PATH should be used. - */ - if( dmpath == NULL) { - runpath = getenv("LD_LIBRARY_PATH"); - } - else { - runpath = dmpath; - } -#else - /* - * If not on Solaris, assume only a single LD_LIBRARY_PATH - * variable. - */ - runpath = getenv("LD_LIBRARY_PATH"); -#endif /* __solaris__ */ - -#ifdef __linux - /* - * On linux, if a binary is running as sgid or suid, glibc sets - * LD_LIBRARY_PATH to the empty string for security purposes. (In - * contrast, on Solaris the LD_LIBRARY_PATH variable for a - * privileged binary does not lose its settings; but the dynamic - * linker does apply more scrutiny to the path.) The launcher uses - * the value of LD_LIBRARY_PATH to prevent an exec loop. - * Therefore, if we are running sgid or suid, this function's - * setting of LD_LIBRARY_PATH will be ineffective and we should - * return from the function now. Getting the right libraries to - * be found must be handled through other mechanisms. - */ - if((getgid() != getegid()) || (getuid() != geteuid()) ) { - return; - } -#endif - - /* runpath contains current effective LD_LIBRARY_PATH setting */ - - jvmpath = JLI_StringDup(jvmpath); - new_runpath = JLI_MemAlloc( ((runpath!=NULL)?JLI_StrLen(runpath):0) + - 2*JLI_StrLen(jrepath) + 2*JLI_StrLen(arch) + - JLI_StrLen(jvmpath) + 52); - newpath = new_runpath + JLI_StrLen("LD_LIBRARY_PATH="); - - - /* - * Create desired LD_LIBRARY_PATH value for target data model. - */ - { - /* remove the name of the .so from the JVM path */ - lastslash = JLI_StrRChr(jvmpath, '/'); - if (lastslash) - *lastslash = '\0'; - - - /* jvmpath, ((running != wanted)?((wanted==64)?"/"LIBARCH64NAME:"/.."):""), */ - - sprintf(new_runpath, "LD_LIBRARY_PATH=" - "%s:" - "%s/lib/%s:" - "%s/../lib/%s", - jvmpath, -#ifdef DUAL_MODE - jrepath, GetArchPath(wanted), - jrepath, GetArchPath(wanted) -#else - jrepath, arch, - jrepath, arch -#endif - ); - - - /* - * Check to make sure that the prefix of the current path is the - * desired environment variable setting. - */ - if (runpath != NULL && - JLI_StrNCmp(newpath, runpath, JLI_StrLen(newpath))==0 && - (runpath[JLI_StrLen(newpath)] == 0 || runpath[JLI_StrLen(newpath)] == ':') && - (running == wanted) /* data model does not have to be changed */ -#ifdef __solaris__ - && (dmpath == NULL) /* data model specific variables not set */ -#endif - ) { - - return; - - } - } - - /* - * Place the desired environment setting onto the prefix of - * LD_LIBRARY_PATH. Note that this prevents any possible infinite - * loop of execv() because we test for the prefix, above. - */ - if (runpath != 0) { - JLI_StrCat(new_runpath, ":"); - JLI_StrCat(new_runpath, runpath); - } - - if( putenv(new_runpath) != 0) { - exit(1); /* problem allocating memory; LD_LIBRARY_PATH not set - properly */ - } - - /* - * Unix systems document that they look at LD_LIBRARY_PATH only - * once at startup, so we have to re-exec the current executable - * to get the changed environment variable to have an effect. - */ - -#ifdef __solaris__ - /* - * If dmpath is not NULL, remove the data model specific string - * in the environment for the exec'ed child. - */ - - if( dmpath != NULL) - (void)UnsetEnv((wanted==32)?"LD_LIBRARY_PATH_32":"LD_LIBRARY_PATH_64"); -#endif - - newenvp = environ; - { char *newexec = execname; #ifdef DUAL_MODE @@ -549,17 +363,16 @@ CreateExecutionEnvironment(int *_argcp, argv[0] = newexec; } #endif - + JLI_TraceLauncher("TRACER_MARKER:About to EXEC\n"); (void)fflush(stdout); (void)fflush(stderr); - execve(newexec, argv, newenvp); + execv(newexec, argv); JLI_ReportErrorMessageSys(JRE_ERROR4, newexec); #ifdef DUAL_MODE if (running != wanted) { JLI_ReportErrorMessage(JRE_ERROR5, wanted, running); # ifdef __solaris__ - # ifdef __sparc JLI_ReportErrorMessage(JRE_ERROR6); # else @@ -570,13 +383,11 @@ CreateExecutionEnvironment(int *_argcp, #endif } - exit(1); } } - /* * On Solaris VM choosing is done by the launcher (java.c). */ @@ -1123,6 +934,7 @@ ExecJRE(char *jre, char **argv) printf(" %s", argv[i]); printf("\n"); } + JLI_TraceLauncher("TRACER_MARKER:About to EXEC\n"); (void)fflush(stdout); (void)fflush(stderr); execv(wanted, argv); diff --git a/src/solaris/classes/sun/awt/X11/XDropTargetRegistry.java b/src/solaris/classes/sun/awt/X11/XDropTargetRegistry.java index 509a5e3274555e5f95881397438e8a130f4bd5ea..96040316391b8550310a409124b1a5c2a29050d4 100644 --- a/src/solaris/classes/sun/awt/X11/XDropTargetRegistry.java +++ b/src/solaris/classes/sun/awt/X11/XDropTargetRegistry.java @@ -534,71 +534,71 @@ final class XDropTargetRegistry { return entry.getSite(x, y); } + /* + * Note: this method should be called under AWT lock. + */ public void registerDropSite(long window) { + assert XToolkit.isAWTLockHeldByCurrentThread(); + if (window == 0) { throw new IllegalArgumentException(); } XDropTargetEventProcessor.activate(); - XToolkit.awtLock(); - try { - long toplevel = getToplevelWindow(window); - - /* - * No window with WM_STATE property is found. - * Since the window can be a plugin window reparented to the browser - * toplevel, we cannot determine which window will eventually have - * WM_STATE property set. So we schedule a timer callback that will - * periodically attempt to find an ancestor with WM_STATE and - * register the drop site appropriately. - */ - if (toplevel == 0) { - addDelayedRegistrationEntry(window); - return; - } + long toplevel = getToplevelWindow(window); - if (toplevel == window) { - Iterator dropTargetProtocols = - XDragAndDropProtocols.getDropTargetProtocols(); + /* + * No window with WM_STATE property is found. + * Since the window can be a plugin window reparented to the browser + * toplevel, we cannot determine which window will eventually have + * WM_STATE property set. So we schedule a timer callback that will + * periodically attempt to find an ancestor with WM_STATE and + * register the drop site appropriately. + */ + if (toplevel == 0) { + addDelayedRegistrationEntry(window); + return; + } - while (dropTargetProtocols.hasNext()) { - XDropTargetProtocol dropTargetProtocol = - (XDropTargetProtocol)dropTargetProtocols.next(); - dropTargetProtocol.registerDropTarget(toplevel); - } - } else { - registerEmbeddedDropSite(toplevel, window); + if (toplevel == window) { + Iterator dropTargetProtocols = + XDragAndDropProtocols.getDropTargetProtocols(); + + while (dropTargetProtocols.hasNext()) { + XDropTargetProtocol dropTargetProtocol = + (XDropTargetProtocol)dropTargetProtocols.next(); + dropTargetProtocol.registerDropTarget(toplevel); } - } finally { - XToolkit.awtUnlock(); + } else { + registerEmbeddedDropSite(toplevel, window); } } + /* + * Note: this method should be called under AWT lock. + */ public void unregisterDropSite(long window) { + assert XToolkit.isAWTLockHeldByCurrentThread(); + if (window == 0) { throw new IllegalArgumentException(); } - XToolkit.awtLock(); - try { - long toplevel = getToplevelWindow(window); + long toplevel = getToplevelWindow(window); - if (toplevel == window) { - Iterator dropProtocols = - XDragAndDropProtocols.getDropTargetProtocols(); + if (toplevel == window) { + Iterator dropProtocols = + XDragAndDropProtocols.getDropTargetProtocols(); - removeDelayedRegistrationEntry(window); + removeDelayedRegistrationEntry(window); - while (dropProtocols.hasNext()) { - XDropTargetProtocol dropProtocol = (XDropTargetProtocol)dropProtocols.next(); - dropProtocol.unregisterDropTarget(window); - } - } else { - unregisterEmbeddedDropSite(toplevel, window); + while (dropProtocols.hasNext()) { + XDropTargetProtocol dropProtocol = (XDropTargetProtocol)dropProtocols.next(); + dropProtocol.unregisterDropTarget(window); } - } finally { - XToolkit.awtUnlock(); + } else { + unregisterEmbeddedDropSite(toplevel, window); } } diff --git a/src/solaris/classes/sun/awt/X11/XWindow.java b/src/solaris/classes/sun/awt/X11/XWindow.java index 8c44c3280823c32281223e5b224f26964b148ac3..58d1fe8bd7c37e14fa1a216c9ee32c8d6aacebe2 100644 --- a/src/solaris/classes/sun/awt/X11/XWindow.java +++ b/src/solaris/classes/sun/awt/X11/XWindow.java @@ -1509,4 +1509,24 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { return new XAtomList(); } + /** + * Indicates if the window is currently in the FSEM. + * Synchronization: state lock. + */ + private boolean fullScreenExclusiveModeState = false; + + // Implementation of the X11ComponentPeer + @Override + public void setFullScreenExclusiveModeState(boolean state) { + synchronized (getStateLock()) { + fullScreenExclusiveModeState = state; + } + } + + public final boolean isFullScreenExclusiveMode() { + synchronized (getStateLock()) { + return fullScreenExclusiveModeState; + } + } + } diff --git a/src/solaris/classes/sun/awt/X11/XWindowPeer.java b/src/solaris/classes/sun/awt/X11/XWindowPeer.java index f87ec27c56542758eb113fe6862848fdc114364e..52e7a531188e0aed3cb067153efa3996d88adf30 100644 --- a/src/solaris/classes/sun/awt/X11/XWindowPeer.java +++ b/src/solaris/classes/sun/awt/X11/XWindowPeer.java @@ -1079,31 +1079,39 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, updateSecurityWarningVisibility(); } + @Override + public void setFullScreenExclusiveModeState(boolean state) { + super.setFullScreenExclusiveModeState(state); + updateSecurityWarningVisibility(); + } + public void updateSecurityWarningVisibility() { if (warningWindow == null) { return; } - boolean show = false; - - int state = getWMState(); - if (!isVisible()) { return; // The warning window should already be hidden. } - // getWMState() always returns 0 (Withdrawn) for simple windows. Hence - // we ignore the state for such windows. - if (isVisible() && (state == XUtilConstants.NormalState || isSimpleWindow())) { - if (XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() == - getTarget()) - { - show = true; - } + boolean show = false; - if (isMouseAbove() || warningWindow.isMouseAbove()) - { - show = true; + if (!isFullScreenExclusiveMode()) { + int state = getWMState(); + + // getWMState() always returns 0 (Withdrawn) for simple windows. Hence + // we ignore the state for such windows. + if (isVisible() && (state == XUtilConstants.NormalState || isSimpleWindow())) { + if (XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() == + getTarget()) + { + show = true; + } + + if (isMouseAbove() || warningWindow.isMouseAbove()) + { + show = true; + } } } @@ -1756,25 +1764,36 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, } } + // should be synchronized on awtLock private int dropTargetCount = 0; - public synchronized void addDropTarget() { - if (dropTargetCount == 0) { - long window = getWindow(); - if (window != 0) { - XDropTargetRegistry.getRegistry().registerDropSite(window); + public void addDropTarget() { + XToolkit.awtLock(); + try { + if (dropTargetCount == 0) { + long window = getWindow(); + if (window != 0) { + XDropTargetRegistry.getRegistry().registerDropSite(window); + } } + dropTargetCount++; + } finally { + XToolkit.awtUnlock(); } - dropTargetCount++; } - public synchronized void removeDropTarget() { - dropTargetCount--; - if (dropTargetCount == 0) { - long window = getWindow(); - if (window != 0) { - XDropTargetRegistry.getRegistry().unregisterDropSite(window); + public void removeDropTarget() { + XToolkit.awtLock(); + try { + dropTargetCount--; + if (dropTargetCount == 0) { + long window = getWindow(); + if (window != 0) { + XDropTargetRegistry.getRegistry().unregisterDropSite(window); + } } + } finally { + XToolkit.awtUnlock(); } } void addRootPropertyEventDispatcher() { @@ -1837,13 +1856,18 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, } } - protected synchronized void updateDropTarget() { - if (dropTargetCount > 0) { - long window = getWindow(); - if (window != 0) { - XDropTargetRegistry.getRegistry().unregisterDropSite(window); - XDropTargetRegistry.getRegistry().registerDropSite(window); + protected void updateDropTarget() { + XToolkit.awtLock(); + try { + if (dropTargetCount > 0) { + long window = getWindow(); + if (window != 0) { + XDropTargetRegistry.getRegistry().unregisterDropSite(window); + XDropTargetRegistry.getRegistry().registerDropSite(window); + } } + } finally { + XToolkit.awtUnlock(); } } diff --git a/src/solaris/classes/sun/awt/X11ComponentPeer.java b/src/solaris/classes/sun/awt/X11ComponentPeer.java index a4a0750689473c0069b441cf79048b452a187e50..24b24809285af0e52b8131af2e511c0ac7f45bd9 100644 --- a/src/solaris/classes/sun/awt/X11ComponentPeer.java +++ b/src/solaris/classes/sun/awt/X11ComponentPeer.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2009 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,4 +39,5 @@ public interface X11ComponentPeer { Rectangle getBounds(); Graphics getGraphics(); Object getTarget(); + void setFullScreenExclusiveModeState(boolean state); } diff --git a/src/solaris/classes/sun/awt/X11GraphicsDevice.java b/src/solaris/classes/sun/awt/X11GraphicsDevice.java index 81491abeea359bab34dfa0064219ac1fe67134b7..115320bb0564020976100d096284b7f1636d62ca 100644 --- a/src/solaris/classes/sun/awt/X11GraphicsDevice.java +++ b/src/solaris/classes/sun/awt/X11GraphicsDevice.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 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 @@ -306,12 +306,14 @@ public class X11GraphicsDevice X11ComponentPeer peer = (X11ComponentPeer)w.getPeer(); if (peer != null) { enterFullScreenExclusive(peer.getContentWindow()); + peer.setFullScreenExclusiveModeState(true); } } private static void exitFullScreenExclusive(Window w) { X11ComponentPeer peer = (X11ComponentPeer)w.getPeer(); if (peer != null) { + peer.setFullScreenExclusiveModeState(false); exitFullScreenExclusive(peer.getContentWindow()); } } diff --git a/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java b/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java index f613c11883179c94d88455288abf65d623395775..943f6e73a063c3d67e79b3ab1a7584a5793a083c 100644 --- a/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java +++ b/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java @@ -388,7 +388,10 @@ public abstract class X11SurfaceData extends SurfaceData { // if a GlyphVector overrides the AA setting. // We use getRenderLoops() rather than setting solidloops // directly so that we get the appropriate loops in XOR mode. - sg2d.loops = getRenderLoops(sg2d); + if (sg2d.loops == null) { + // assert(some pipe will always be a LoopBasedPipe) + sg2d.loops = getRenderLoops(sg2d); + } } else { super.validatePipe(sg2d); } diff --git a/src/solaris/native/sun/awt/awt_GraphicsEnv.c b/src/solaris/native/sun/awt/awt_GraphicsEnv.c index 7afdf1681c62c89e725f05162b8e0b6dad1bc8ee..ef4fa15afa59642322366a86382f687813a39084 100644 --- a/src/solaris/native/sun/awt/awt_GraphicsEnv.c +++ b/src/solaris/native/sun/awt/awt_GraphicsEnv.c @@ -1654,6 +1654,7 @@ Java_sun_awt_X11GraphicsEnvironment_getXineramaCenterPoint(JNIEnv *env, #ifndef HEADLESS #define BIT_DEPTH_MULTI java_awt_DisplayMode_BIT_DEPTH_MULTI +#define REFRESH_RATE_UNKNOWN java_awt_DisplayMode_REFRESH_RATE_UNKNOWN typedef Status (*XRRQueryVersionType) (Display *dpy, int *major_versionp, int *minor_versionp); @@ -1680,6 +1681,9 @@ typedef Status Rotation rotation, short rate, Time timestamp); +typedef Rotation + (*XRRConfigRotationsType)(XRRScreenConfiguration *config, + Rotation *current_rotation); static XRRQueryVersionType awt_XRRQueryVersion; static XRRGetScreenInfoType awt_XRRGetScreenInfo; @@ -1689,6 +1693,7 @@ static XRRConfigCurrentRateType awt_XRRConfigCurrentRate; static XRRConfigSizesType awt_XRRConfigSizes; static XRRConfigCurrentConfigurationType awt_XRRConfigCurrentConfiguration; static XRRSetScreenConfigAndRateType awt_XRRSetScreenConfigAndRate; +static XRRConfigRotationsType awt_XRRConfigRotations; #define LOAD_XRANDR_FUNC(f) \ do { \ @@ -1755,6 +1760,7 @@ X11GD_InitXrandrFuncs(JNIEnv *env) LOAD_XRANDR_FUNC(XRRConfigSizes); LOAD_XRANDR_FUNC(XRRConfigCurrentConfiguration); LOAD_XRANDR_FUNC(XRRSetScreenConfigAndRate); + LOAD_XRANDR_FUNC(XRRConfigRotations); return JNI_TRUE; } @@ -1765,6 +1771,7 @@ X11GD_CreateDisplayMode(JNIEnv *env, jint width, jint height, { jclass displayModeClass; jmethodID cid; + jint validRefreshRate = refreshRate; displayModeClass = (*env)->FindClass(env, "java/awt/DisplayMode"); if (JNU_IsNull(env, displayModeClass)) { @@ -1780,8 +1787,13 @@ X11GD_CreateDisplayMode(JNIEnv *env, jint width, jint height, return NULL; } + // early versions of xrandr may report "empty" rates (6880694) + if (validRefreshRate <= 0) { + validRefreshRate = REFRESH_RATE_UNKNOWN; + } + return (*env)->NewObject(env, displayModeClass, cid, - width, height, bitDepth, refreshRate); + width, height, bitDepth, validRefreshRate); } static void @@ -1926,8 +1938,7 @@ Java_sun_awt_X11GraphicsDevice_getCurrentDisplayMode curRate = awt_XRRConfigCurrentRate(config); if ((sizes != NULL) && - (curSizeIndex < nsizes) && - (curRate > 0)) + (curSizeIndex < nsizes)) { XRRScreenSize curSize = sizes[curSizeIndex]; displayMode = X11GD_CreateDisplayMode(env, @@ -2004,6 +2015,7 @@ Java_sun_awt_X11GraphicsDevice_configDisplayMode jboolean success = JNI_FALSE; XRRScreenConfiguration *config; Drawable root; + Rotation currentRotation = RR_Rotate_0; AWT_LOCK(); @@ -2015,6 +2027,7 @@ Java_sun_awt_X11GraphicsDevice_configDisplayMode short chosenRate = -1; int nsizes; XRRScreenSize *sizes = awt_XRRConfigSizes(config, &nsizes); + awt_XRRConfigRotations(config, ¤tRotation); if (sizes != NULL) { int i, j; @@ -2048,7 +2061,7 @@ Java_sun_awt_X11GraphicsDevice_configDisplayMode Status status = awt_XRRSetScreenConfigAndRate(awt_display, config, root, chosenSizeIndex, - RR_Rotate_0, + currentRotation, chosenRate, CurrentTime); diff --git a/src/solaris/native/sun/awt/awt_GraphicsEnv.h b/src/solaris/native/sun/awt/awt_GraphicsEnv.h index 224c55404444c8faf80a8da30a4bd8cba5d80108..330b605143d1d557fb9061b9cefbaba9ce99d2a7 100644 --- a/src/solaris/native/sun/awt/awt_GraphicsEnv.h +++ b/src/solaris/native/sun/awt/awt_GraphicsEnv.h @@ -42,6 +42,10 @@ #include #include #include +#ifndef X_ShmAttach +#include +#include +#endif extern int XShmQueryExtension(); diff --git a/src/solaris/native/sun/awt/gtk2_interface.c b/src/solaris/native/sun/awt/gtk2_interface.c index 1afeeef173b292515b6ee55ab846078eb0842970..e6ede30682402feef6bbfaf8ee791e69407a36ff 100644 --- a/src/solaris/native/sun/awt/gtk2_interface.c +++ b/src/solaris/native/sun/awt/gtk2_interface.c @@ -637,13 +637,13 @@ gboolean gtk2_load() if (gtk_modules_env && strstr (gtk_modules_env, "atk-bridge") || gtk_modules_env && strstr (gtk_modules_env, "gail")) { - gchar *tmp_env = strdup (gtk_modules_env); /* the new env will be smaller than the old one */ gchar *s, *new_env = malloc (sizeof(ENV_PREFIX)+strlen (gtk_modules_env)); if (new_env != NULL ) { /* careful, strtok modifies its args */ + gchar *tmp_env = strdup (gtk_modules_env); strcpy(new_env, ENV_PREFIX); /* strip out 'atk-bridge' and 'gail' */ diff --git a/src/solaris/native/sun/xawt/XToolkit.c b/src/solaris/native/sun/xawt/XToolkit.c index 6ce5876c54478972fa18dd670bda76388714adb9..a4323b31995cd919fa7dbe8db5879b374addbfe3 100644 --- a/src/solaris/native/sun/xawt/XToolkit.c +++ b/src/solaris/native/sun/xawt/XToolkit.c @@ -677,7 +677,7 @@ JNIEXPORT jstring JNICALL Java_sun_awt_X11_XToolkit_getEnv jstring ret = NULL; keystr = JNU_GetStringPlatformChars(env, key, NULL); - if (key) { + if (keystr) { ptr = getenv(keystr); if (ptr) { ret = JNU_NewStringPlatform(env, (const char *) ptr); diff --git a/src/windows/classes/sun/awt/Win32GraphicsDevice.java b/src/windows/classes/sun/awt/Win32GraphicsDevice.java index 8a0960bc6d8d57755bc4abc728b4665bc5eb7a96..4be644c2f7176d962cac504cde485abf5b7a4a6c 100644 --- a/src/windows/classes/sun/awt/Win32GraphicsDevice.java +++ b/src/windows/classes/sun/awt/Win32GraphicsDevice.java @@ -353,6 +353,7 @@ public class Win32GraphicsDevice extends GraphicsDevice implements } WWindowPeer peer = (WWindowPeer)old.getPeer(); if (peer != null) { + peer.setFullScreenExclusiveModeState(false); // we used to destroy the buffers on exiting fs mode, this // is no longer needed since fs change will cause a surface // data replacement @@ -370,12 +371,15 @@ public class Win32GraphicsDevice extends GraphicsDevice implements addFSWindowListener(w); // Enter full screen exclusive mode. WWindowPeer peer = (WWindowPeer)w.getPeer(); - synchronized(peer) { - enterFullScreenExclusive(screen, peer); - // Note: removed replaceSurfaceData() call because - // changing the window size or making it visible - // will cause this anyway, and both of these events happen - // as part of switching into fullscreen mode. + if (peer != null) { + synchronized(peer) { + enterFullScreenExclusive(screen, peer); + // Note: removed replaceSurfaceData() call because + // changing the window size or making it visible + // will cause this anyway, and both of these events happen + // as part of switching into fullscreen mode. + } + peer.setFullScreenExclusiveModeState(true); } // fix for 4868278 diff --git a/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java b/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java index 36636aef64cf6f8db82a5c807d25b43ac718b777..f9b2f4c42802929ebbdfb6f8e79ac017ee7ed783 100644 --- a/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java +++ b/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java @@ -524,7 +524,7 @@ final class Win32ShellFolder2 extends ShellFolder { // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details private static native int compareIDs(long pParentIShellFolder, long pidl1, long pidl2); - private Boolean cachedIsFileSystem; + private volatile Boolean cachedIsFileSystem; /** * @return Whether this is a file system shell folder @@ -693,29 +693,32 @@ final class Win32ShellFolder2 extends ShellFolder { ArrayList list = new ArrayList(); long pEnumObjects = getEnumObjects(includeHiddenFiles); if (pEnumObjects != 0) { - long childPIDL; - int testedAttrs = ATTRIB_FILESYSTEM | ATTRIB_FILESYSANCESTOR; - do { - childPIDL = getNextChild(pEnumObjects); - boolean releasePIDL = true; - if (childPIDL != 0 && - (getAttributes0(pIShellFolder, childPIDL, testedAttrs) & testedAttrs) != 0) { - Win32ShellFolder2 childFolder; - if (Win32ShellFolder2.this.equals(desktop) - && personal != null - && pidlsEqual(pIShellFolder, childPIDL, personal.disposer.relativePIDL)) { - childFolder = personal; - } else { - childFolder = new Win32ShellFolder2(Win32ShellFolder2.this, childPIDL); - releasePIDL = false; + try { + long childPIDL; + int testedAttrs = ATTRIB_FILESYSTEM | ATTRIB_FILESYSANCESTOR; + do { + childPIDL = getNextChild(pEnumObjects); + boolean releasePIDL = true; + if (childPIDL != 0 && + (getAttributes0(pIShellFolder, childPIDL, testedAttrs) & testedAttrs) != 0) { + Win32ShellFolder2 childFolder; + if (Win32ShellFolder2.this.equals(desktop) + && personal != null + && pidlsEqual(pIShellFolder, childPIDL, personal.disposer.relativePIDL)) { + childFolder = personal; + } else { + childFolder = new Win32ShellFolder2(Win32ShellFolder2.this, childPIDL); + releasePIDL = false; + } + list.add(childFolder); } - list.add(childFolder); - } - if (releasePIDL) { - releasePIDL(childPIDL); - } - } while (childPIDL != 0 && !Thread.currentThread().isInterrupted()); - releaseEnumObjects(pEnumObjects); + if (releasePIDL) { + releasePIDL(childPIDL); + } + } while (childPIDL != 0 && !Thread.currentThread().isInterrupted()); + } finally { + releaseEnumObjects(pEnumObjects); + } } return Thread.currentThread().isInterrupted() ? new File[0] @@ -759,7 +762,7 @@ final class Win32ShellFolder2 extends ShellFolder { }, InterruptedException.class); } - private Boolean cachedIsLink; + private volatile Boolean cachedIsLink; /** * @return Whether this shell folder is a link diff --git a/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java b/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java index 97cc532d36937a56de21dc4ccef2d48e7dca1dc9..b7639fa77bbda34c41d72871fdadfd53651974d3 100644 --- a/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java +++ b/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java @@ -79,9 +79,12 @@ public class Win32ShellFolderManager2 extends ShellFolderManager { // Shouldn't happen but watch for it anyway throw new FileNotFoundException("File " + file.getAbsolutePath() + " not found"); } - Win32ShellFolder2 folder = createShellFolderFromRelativePIDL(parent, pIDL); - Win32ShellFolder2.releasePIDL(pIDL); - return folder; + + try { + return createShellFolderFromRelativePIDL(parent, pIDL); + } finally { + Win32ShellFolder2.releasePIDL(pIDL); + } } static Win32ShellFolder2 createShellFolderFromRelativePIDL(Win32ShellFolder2 parent, long pIDL) @@ -269,7 +272,7 @@ public class Win32ShellFolderManager2 extends ShellFolderManager { Arrays.sort(secondLevelFolders); for (File secondLevelFolder : secondLevelFolders) { Win32ShellFolder2 folder = (Win32ShellFolder2) secondLevelFolder; - if (!folder.isFileSystem() || folder.isDirectory()) { + if (!folder.isFileSystem() || (folder.isDirectory() && !folder.isLink())) { folders.add(folder); // Add third level for "My Computer" if (folder.equals(drives)) { diff --git a/src/windows/classes/sun/awt/windows/WComponentPeer.java b/src/windows/classes/sun/awt/windows/WComponentPeer.java index 4b73c2e4fe7850d503920ed2f1b413dc6643ddea..e5c51d7b77f384bd64dea5eb8813e219ee3055a2 100644 --- a/src/windows/classes/sun/awt/windows/WComponentPeer.java +++ b/src/windows/classes/sun/awt/windows/WComponentPeer.java @@ -550,8 +550,34 @@ public abstract class WComponentPeer extends WObjectPeer final static Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12); public Graphics getGraphics() { + if (isDisposed()) { + return null; + } + + Component target = (Component)getTarget(); + Window window = SunToolkit.getContainingWindow(target); + if (window != null && !window.isOpaque()) { + // Non-opaque windows do not support heavyweight children. + // Redirect all painting to the Window's Graphics instead. + // The caller is responsible for calling the + // WindowPeer.updateWindow() after painting has finished. + int x = 0, y = 0; + for (Component c = target; c != window; c = c.getParent()) { + x += c.getX(); + y += c.getY(); + } + + Graphics g = + ((WWindowPeer)window.getPeer()).getTranslucentGraphics(); + + g.translate(x, y); + g.clipRect(0, 0, target.getWidth(), target.getHeight()); + + return g; + } + SurfaceData surfaceData = this.surfaceData; - if (!isDisposed() && surfaceData != null) { + if (surfaceData != null) { /* Fix for bug 4746122. Color and Font shouldn't be null */ Color bgColor = background; if (bgColor == null) { diff --git a/src/windows/classes/sun/awt/windows/WWindowPeer.java b/src/windows/classes/sun/awt/windows/WWindowPeer.java index 009593ac3cf3bc12171d98ea52d91c053d3c7924..6189738da206ddf56b5c95ce90c8f848b087c560 100644 --- a/src/windows/classes/sun/awt/windows/WWindowPeer.java +++ b/src/windows/classes/sun/awt/windows/WWindowPeer.java @@ -510,6 +510,9 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer, private native int getScreenImOn(); + // Used in Win32GraphicsDevice. + public final native void setFullScreenExclusiveModeState(boolean state); + /* * ----END DISPLAY CHANGE SUPPORT---- */ @@ -575,11 +578,17 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer, } } + public final Graphics getTranslucentGraphics() { + synchronized (getStateLock()) { + return isOpaque ? null : painter.getBackBuffer(false).getGraphics(); + } + } + @Override public Graphics getGraphics() { synchronized (getStateLock()) { if (!isOpaque) { - return painter.getBackBuffer(false).getGraphics(); + return getTranslucentGraphics(); } } return super.getGraphics(); diff --git a/src/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java b/src/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java index e246a7fc63d13a1ee819bb97164b61c64d59e806..c55b54d9f6b1e0fb54783f8b21bfad31a4a42d97 100644 --- a/src/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java +++ b/src/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java @@ -210,7 +210,10 @@ public class GDIWindowSurfaceData extends SurfaceData { // if a GlyphVector overrides the AA setting. // We use getRenderLoops() rather than setting solidloops // directly so that we get the appropriate loops in XOR mode. - sg2d.loops = getRenderLoops(sg2d); + if (sg2d.loops == null) { + // assert(some pipe will always be a LoopBasedPipe) + sg2d.loops = getRenderLoops(sg2d); + } } else { super.validatePipe(sg2d); } diff --git a/src/windows/native/sun/windows/awt_PrintControl.cpp b/src/windows/native/sun/windows/awt_PrintControl.cpp index cc562ec0056999411a4b4837c0a09515251b653c..b68bb5f3bdd7328a7b27fff3eb04ef996e38de87 100644 --- a/src/windows/native/sun/windows/awt_PrintControl.cpp +++ b/src/windows/native/sun/windows/awt_PrintControl.cpp @@ -687,7 +687,7 @@ BOOL AwtPrintControl::InitPrintDialog(JNIEnv *env, // Now, set-up the struct for the real calls to ::PrintDlg and ::CreateDC pd.hwndOwner = hwndOwner; - pd.Flags = PD_ENABLEPRINTHOOK | PD_RETURNDC; + pd.Flags = PD_ENABLEPRINTHOOK | PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE; pd.lpfnPrintHook = (LPPRINTHOOKPROC)PrintDlgHook; if (env->CallBooleanMethod(printCtrl, AwtPrintControl::getCollateID)) { diff --git a/src/windows/native/sun/windows/awt_TrayIcon.cpp b/src/windows/native/sun/windows/awt_TrayIcon.cpp index 9165314bbc567ac4e8bbe98ad0e71c14c494d650..6b4f8b6bcfca6e0f071f9947ad6a20b9ce6ca3ca 100644 --- a/src/windows/native/sun/windows/awt_TrayIcon.cpp +++ b/src/windows/native/sun/windows/awt_TrayIcon.cpp @@ -59,7 +59,7 @@ struct DisplayMessageStruct { }; typedef struct tagBitmapheader { - BITMAPINFOHEADER bmiHeader; + BITMAPV5HEADER bmiHeader; DWORD dwMasks[256]; } Bitmapheader, *LPBITMAPHEADER; @@ -638,12 +638,12 @@ void AwtTrayIcon::UnlinkObjects() HBITMAP AwtTrayIcon::CreateBMP(HWND hW,int* imageData,int nSS, int nW, int nH) { - Bitmapheader bmhHeader; + Bitmapheader bmhHeader = {0}; HDC hDC; char *ptrImageData; HBITMAP hbmpBitmap; HBITMAP hBitmap; - int nNumChannels = 3; + int nNumChannels = 4; if (!hW) { hW = ::GetDesktopWindow(); @@ -653,14 +653,20 @@ HBITMAP AwtTrayIcon::CreateBMP(HWND hW,int* imageData,int nSS, int nW, int nH) return NULL; } - memset(&bmhHeader, 0, sizeof(Bitmapheader)); - bmhHeader.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmhHeader.bmiHeader.biWidth = nW; - bmhHeader.bmiHeader.biHeight = -nH; - bmhHeader.bmiHeader.biPlanes = 1; + bmhHeader.bmiHeader.bV5Size = sizeof(BITMAPV5HEADER); + bmhHeader.bmiHeader.bV5Width = nW; + bmhHeader.bmiHeader.bV5Height = -nH; + bmhHeader.bmiHeader.bV5Planes = 1; - bmhHeader.bmiHeader.biBitCount = 24; - bmhHeader.bmiHeader.biCompression = BI_RGB; + bmhHeader.bmiHeader.bV5BitCount = 32; + bmhHeader.bmiHeader.bV5Compression = BI_BITFIELDS; + + // The following mask specification specifies a supported 32 BPP + // alpha format for Windows XP. + bmhHeader.bmiHeader.bV5RedMask = 0x00FF0000; + bmhHeader.bmiHeader.bV5GreenMask = 0x0000FF00; + bmhHeader.bmiHeader.bV5BlueMask = 0x000000FF; + bmhHeader.bmiHeader.bV5AlphaMask = 0xFF000000; hbmpBitmap = ::CreateDIBSection(hDC, (BITMAPINFO*)&(bmhHeader), DIB_RGB_COLORS, @@ -674,6 +680,7 @@ HBITMAP AwtTrayIcon::CreateBMP(HWND hW,int* imageData,int nSS, int nW, int nH) } for (int nOutern = 0; nOutern < nH; nOutern++) { for (int nInner = 0; nInner < nSS; nInner++) { + dstPtr[3] = (*srcPtr >> 0x18) & 0xFF; dstPtr[2] = (*srcPtr >> 0x10) & 0xFF; dstPtr[1] = (*srcPtr >> 0x08) & 0xFF; dstPtr[0] = *srcPtr & 0xFF; diff --git a/src/windows/native/sun/windows/awt_Window.cpp b/src/windows/native/sun/windows/awt_Window.cpp index 4c902c3fb47b97973d0336c8ac3b739fbc4b3c19..8bb5c90021939c326d2d2a5966477fda3be60d37 100644 --- a/src/windows/native/sun/windows/awt_Window.cpp +++ b/src/windows/native/sun/windows/awt_Window.cpp @@ -143,6 +143,11 @@ struct RepositionSecurityWarningStruct { jobject window; }; +struct SetFullScreenExclusiveModeStateStruct { + jobject window; + jboolean isFSEMState; +}; + /************************************************************************ * AwtWindow fields @@ -915,7 +920,9 @@ void AwtWindow::UpdateSecurityWarningVisibility() bool show = false; - if (IsVisible() && currentWmSizeState != SIZE_MINIMIZED) { + if (IsVisible() && currentWmSizeState != SIZE_MINIMIZED && + !isFullScreenExclusiveMode()) + { if (AwtComponent::GetFocusedWindow() == GetHWnd()) { show = true; } @@ -2954,6 +2961,25 @@ void AwtWindow::_UpdateWindow(void* param) delete uws; } +void AwtWindow::_SetFullScreenExclusiveModeState(void *param) +{ + JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); + + SetFullScreenExclusiveModeStateStruct * data = + (SetFullScreenExclusiveModeStateStruct*)param; + jobject self = data->window; + jboolean state = data->isFSEMState; + + PDATA pData; + JNI_CHECK_PEER_GOTO(self, ret); + AwtWindow *window = (AwtWindow *)pData; + + window->setFullScreenExclusiveModeState(state != 0); + + ret: + env->DeleteGlobalRef(self); + delete data; +} extern "C" { @@ -3333,6 +3359,29 @@ Java_sun_awt_windows_WWindowPeer_getScreenImOn(JNIEnv *env, jobject self) CATCH_BAD_ALLOC_RET(-1); } +/* + * Class: sun_awt_windows_WWindowPeer + * Method: setFullScreenExclusiveModeState + * Signature: (Z)V + */ +JNIEXPORT void JNICALL +Java_sun_awt_windows_WWindowPeer_setFullScreenExclusiveModeState(JNIEnv *env, + jobject self, jboolean state) +{ + TRY; + + SetFullScreenExclusiveModeStateStruct *data = + new SetFullScreenExclusiveModeStateStruct; + data->window = env->NewGlobalRef(self); + data->isFSEMState = state; + + AwtToolkit::GetInstance().SyncCall( + AwtWindow::_SetFullScreenExclusiveModeState, data); + // global ref and data are deleted in the invoked method + + CATCH_BAD_ALLOC; +} + /* * Class: sun_awt_windows_WWindowPeer * Method: modalDisable diff --git a/src/windows/native/sun/windows/awt_Window.h b/src/windows/native/sun/windows/awt_Window.h index 1d238b44dac1df0390039fd167f8f1479c1ac215..001062835e3a733ea369580f01eb2e503e7c017a 100644 --- a/src/windows/native/sun/windows/awt_Window.h +++ b/src/windows/native/sun/windows/awt_Window.h @@ -229,6 +229,7 @@ public: static void _SetOpaque(void* param); static void _UpdateWindow(void* param); static void _RepositionSecurityWarning(void* param); + static void _SetFullScreenExclusiveModeState(void* param); inline static BOOL IsResizing() { return sm_resizing; @@ -331,6 +332,16 @@ private: static void SetLayered(HWND window, bool layered); static bool IsLayered(HWND window); + BOOL fullScreenExclusiveModeState; + inline void setFullScreenExclusiveModeState(BOOL isEntered) { + fullScreenExclusiveModeState = isEntered; + UpdateSecurityWarningVisibility(); + } + inline BOOL isFullScreenExclusiveMode() { + return fullScreenExclusiveModeState; + } + + public: void UpdateSecurityWarningVisibility(); static bool IsWarningWindow(HWND hWnd); diff --git a/test/Makefile b/test/Makefile index 602d8fc0a91f103e6744b04c1c5f1aeb1657a73a..25f0dc1ed6fcb3b32e218d4eda4a2fa2f462e4d3 100644 --- a/test/Makefile +++ b/test/Makefile @@ -282,11 +282,23 @@ STATS_TXT = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)")/$(STATS_TXT_NAME) RUNLIST = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)")/runlist.txt PASSLIST = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)")/passlist.txt FAILLIST = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)")/faillist.txt +EXITCODE = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)")/exitcode.txt + +TESTEXIT = \ + if [ ! -s $(EXITCODE) ] ; then \ + $(ECHO) "ERROR: EXITCODE file not filled in."; \ + $(ECHO) "1" > $(EXITCODE); \ + fi ; \ + testExitCode=`$(CAT) $(EXITCODE)`; \ + $(ECHO) "EXIT CODE: $${testExitCode}"; \ + exit ${testExitCode} + BUNDLE_UP_AND_EXIT = \ ( \ - exitCode=$$? && \ + jtregExitCode=$$? && \ _summary="$(SUMMARY_TXT)"; \ - $(RM) -f $(STATS_TXT) $(RUNLIST) $(PASSLIST) $(FAILLIST); \ + $(RM) -f $(STATS_TXT) $(RUNLIST) $(PASSLIST) $(FAILLIST) $(EXITCODE); \ + $(ECHO) "$${jtregExitCode}" > $(EXITCODE); \ if [ -r "$${_summary}" ] ; then \ $(ECHO) "Summary: $${_summary}" > $(STATS_TXT); \ $(EXPAND) $${_summary} | $(EGREP) -v ' Not run\.' > $(RUNLIST); \ @@ -297,10 +309,13 @@ BUNDLE_UP_AND_EXIT = \ $(EGREP) ' Error\.' $(RUNLIST); \ $(EGREP) -v ' Passed\.' $(RUNLIST) ) \ | $(SORT) | $(UNIQ) > $(FAILLIST); \ - if [ $${exitCode} != 0 -o -s $(FAILLIST) ] ; then \ + if [ $${jtregExitCode} != 0 -o -s $(FAILLIST) ] ; then \ $(EXPAND) $(FAILLIST) \ | $(CUT) -d' ' -f1 \ | $(SED) -e 's@^@FAILED: @' >> $(STATS_TXT); \ + if [ $${jtregExitCode} = 0 ] ; then \ + jtregExitCode=1; \ + fi; \ fi; \ runc="`$(CAT) $(RUNLIST) | $(WC) -l | $(AWK) '{print $$1;}'`"; \ passc="`$(CAT) $(PASSLIST) | $(WC) -l | $(AWK) '{print $$1;}'`"; \ @@ -312,8 +327,8 @@ BUNDLE_UP_AND_EXIT = \ $(ECHO) "Missing file: $${_summary}" >> $(STATS_TXT); \ fi; \ $(CAT) $(STATS_TXT); \ - $(ZIP_UP_RESULTS) && $(KILL_DISPLAY) && \ - exit $${exitCode} \ + $(ZIP_UP_RESULTS) && $(KILL_DISPLAY) ; \ + $(TESTEXIT) \ ) ################################################################ @@ -337,9 +352,11 @@ clean: # jtreg tests # Expect JT_HOME to be set for jtreg tests. (home for jtreg) -JT_HOME = $(SLASH_JAVA)/re/jtreg/4.0/promoted/latest/binaries/jtreg -ifdef JPRT_JTREG_HOME - JT_HOME = $(JPRT_JTREG_HOME) +ifndef JT_HOME + JT_HOME = $(SLASH_JAVA)/re/jtreg/4.0/promoted/latest/binaries/jtreg + ifdef JPRT_JTREG_HOME + JT_HOME = $(JPRT_JTREG_HOME) + endif endif # Expect JPRT to set TESTDIRS to the jtreg test dirs @@ -361,21 +378,22 @@ endif # Some tests annoy me and fail frequently PROBLEM_LIST=ProblemList.txt +PROBLEM_LISTS=$(PROBLEM_LIST) $(wildcard closed/$(PROBLEM_LIST)) EXCLUDELIST=$(ABS_TEST_OUTPUT_DIR)/excludelist.txt # Create exclude list for this platform and arch ifdef NO_EXCLUDES -$(EXCLUDELIST): $(PROBLEM_LIST) $(TESTDIRS) +$(EXCLUDELIST): $(PROBLEM_LISTS) $(TESTDIRS) @$(ECHO) "NOTHING_EXCLUDED" > $@ else -$(EXCLUDELIST): $(PROBLEM_LIST) $(TESTDIRS) +$(EXCLUDELIST): $(PROBLEM_LISTS) $(TESTDIRS) @$(RM) $@ $@.temp1 $@.temp2 - @( ( $(EGREP) -- '$(OS_NAME)-all' $< ) ;\ - ( $(EGREP) -- '$(OS_NAME)-$(OS_ARCH)' $< ) ;\ - ( $(EGREP) -- '$(OS_NAME)-$(OS_VERSION)' $< ) ;\ - ( $(EGREP) -- 'generic-$(OS_ARCH)' $< ) ;\ - ( $(EGREP) -- 'generic-all' $< ) ;\ - ( $(ECHO) "#") ;\ + @(($(CAT) $(PROBLEM_LISTS) | $(EGREP) -- '$(OS_NAME)-all' ) ;\ + ($(CAT) $(PROBLEM_LISTS) | $(EGREP) -- '$(OS_NAME)-$(OS_ARCH)' ) ;\ + ($(CAT) $(PROBLEM_LISTS) | $(EGREP) -- '$(OS_NAME)-$(OS_VERSION)') ;\ + ($(CAT) $(PROBLEM_LISTS) | $(EGREP) -- 'generic-$(OS_ARCH)' ) ;\ + ($(CAT) $(PROBLEM_LISTS) | $(EGREP) -- 'generic-all' ) ;\ + ($(ECHO) "#") ;\ ) | $(SED) -e 's@^[\ ]*@@' \ | $(EGREP) -v '^#' > $@.temp1 @for tdir in $(TESTDIRS) ; do \ @@ -386,14 +404,18 @@ $(EXCLUDELIST): $(PROBLEM_LIST) $(TESTDIRS) @$(ECHO) "Excluding list contains `$(EXPAND) $@ | $(WC) -l` items" endif +# Select list of directories that exist +define TestDirs +$(foreach i,$1,$(wildcard ${i})) $(foreach i,$1,$(wildcard closed/${i})) +endef # Running batches of tests with or without samevm define RunSamevmBatch -$(ECHO) "Running tests in samevm mode: $?" -$(MAKE) TESTDIRS="$?" USE_JTREG_SAMEVM=true UNIQUE_DIR=$@ jtreg_tests +$(ECHO) "Running tests in samevm mode: $(call TestDirs, $?)" +$(MAKE) TESTDIRS="$(call TestDirs, $?)" USE_JTREG_SAMEVM=true UNIQUE_DIR=$@ jtreg_tests endef define RunOthervmBatch -$(ECHO) "Running tests in othervm mode: $?" -$(MAKE) TESTDIRS="$?" USE_JTREG_SAMEVM=false UNIQUE_DIR=$@ jtreg_tests +$(ECHO) "Running tests in othervm mode: $(call TestDirs, $?)" +$(MAKE) TESTDIRS="$(call TestDirs, $?)" USE_JTREG_SAMEVM=false UNIQUE_DIR=$@ jtreg_tests endef define SummaryInfo $(ECHO) "Summary for: $?" @@ -428,6 +450,9 @@ JDK_ALL_TARGETS += jdk_beans3 jdk_beans3: java/beans/XMLEncoder $(call RunOthervmBatch) +jdk_beans: jdk_beans1 jdk_beans2 jdk_beans3 + @$(SummaryInfo) + # Stable samevm testruns (minus items from PROBLEM_LIST) JDK_ALL_TARGETS += jdk_io jdk_io: java/io @@ -450,6 +475,9 @@ JDK_ALL_TARGETS += jdk_management2 jdk_management2: com/sun/jmx com/sun/management sun/management $(call RunOthervmBatch) +jdk_management: jdk_management1 jdk_management2 + @$(SummaryInfo) + # Stable samevm testruns (minus items from PROBLEM_LIST) JDK_ALL_TARGETS += jdk_math jdk_math: java/math @@ -482,6 +510,9 @@ JDK_ALL_TARGETS += jdk_nio3 jdk_nio3: com/sun/nio sun/nio $(call RunOthervmBatch) +jdk_nio: jdk_nio1 jdk_nio2 jdk_nio3 + @$(SummaryInfo) + # Stable othervm testruns (minus items from PROBLEM_LIST) # Using samevm has serious problems with these tests JDK_ALL_TARGETS += jdk_rmi @@ -502,6 +533,9 @@ JDK_ALL_TARGETS += jdk_security3 jdk_security3: com/sun/security lib/security javax/security sun/security $(call RunOthervmBatch) +jdk_security: jdk_security1 jdk_security2 jdk_security3 + @$(SummaryInfo) + # Stable othervm testruns (minus items from PROBLEM_LIST) # Using samevm has problems, and doesn't help performance as much as others. JDK_ALL_TARGETS += jdk_swing @@ -517,11 +551,14 @@ jdk_text: java/text sun/text # Using samevm has serious problems with these tests JDK_ALL_TARGETS += jdk_tools1 jdk_tools1: com/sun/jdi - $(call RunOthervmBatch) + $(call RunSamevmBatch) JDK_ALL_TARGETS += jdk_tools2 jdk_tools2: com/sun/tools sun/jvmstat sun/tools tools vm com/sun/servicetag com/sun/tracing $(call RunOthervmBatch) +jdk_tools: jdk_tools1 jdk_tools2 + @$(SummaryInfo) + # Stable samevm testruns (minus items from PROBLEM_LIST) JDK_ALL_TARGETS += jdk_util jdk_util: java/util sun/util @@ -576,7 +613,7 @@ jtreg_tests: prep $(PRODUCT_HOME) $(JTREG) $(EXCLUDELIST) $(JTREG_TEST_OPTIONS) \ $(TESTDIRS) \ ) ; $(BUNDLE_UP_AND_EXIT) \ - ) 2>&1 | $(TEE) $(ABS_TEST_OUTPUT_DIR)/output.txt + ) 2>&1 | $(TEE) $(ABS_TEST_OUTPUT_DIR)/output.txt ; $(TESTEXIT) PHONY_LIST += jtreg_tests diff --git a/test/ProblemList.txt b/test/ProblemList.txt index 9a366c1ba8f526d6991bd70dc8b57a4d48da8a73..f145a246fc7ed237ca96f3727f086f3f7c567a6e 100644 --- a/test/ProblemList.txt +++ b/test/ProblemList.txt @@ -344,6 +344,9 @@ java/io/StreamTokenizer/Comment.java generic-all # Some of these tests (like java/lang/management) may just need to be marked # othervm, but that is partially speculation. +# Samevm failure on OpenSolaris, security manager? +java/lang/ClassLoader/UninitializedParent.java generic-all + # Times out on solaris 10 sparc java/lang/ClassLoader/Assert.java generic-all @@ -538,6 +541,18 @@ javax/imageio/plugins/jpeg/ReadAsGrayTest.java generic-all # Missing close on file wbmp*, windows samevm javax/imageio/plugins/wbmp/CanDecodeTest.java generic-all +# Failures on OpenSolaris, cannot read input files? samevm issues? +javax/imageio/metadata/BooleanAttributes.java generic-all +javax/imageio/plugins/bmp/BMPSubsamplingTest.java generic-all +javax/imageio/plugins/bmp/TopDownTest.java generic-all +javax/imageio/plugins/gif/EncodeSubImageTest.java generic-all +javax/imageio/plugins/gif/GifTransparencyTest.java generic-all +javax/imageio/plugins/png/GrayPngTest.java generic-all +javax/imageio/plugins/png/ItxtUtf8Test.java generic-all +javax/imageio/plugins/png/MergeStdCommentTest.java generic-all +javax/imageio/plugins/png/ShortHistogramTest.java generic-all +javax/imageio/plugins/shared/BitDepth.java generic-all + # Exclude all javax/print tests, even if they passed, they may need samevm work # Times out on solaris-sparc, sparcv9, x64 -server, some on i586 -client @@ -878,6 +893,10 @@ java/rmi/server/UnicastRemoteObject/unexportObject/UnexportLeak.java generic-all # jdk_security +# Fails on OpenSolaris, IOException: Attempt to obtain kerberos service ticket +# for host/`hostname`@RABBIT.HOLE failed! +sun/security/krb5/auto/SSL.java generic-all + # Run too slow on Solaris 10 sparc sun/security/ssl/com/sun/net/ssl/internal/ssl/InputRecord/SSLSocketTimeoutNulls.java solaris-sparc sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ClientTimeout.java solaris-sparc @@ -1073,9 +1092,6 @@ java/text/Bidi/Bug6665028.java linux-x64 # So most if not all tools tests are now being run with "othervm" mode. # Some of these tools tests have a tendency to use fixed ports, bad idea. -# Solaris 10 client x86, java.lang.IndexOutOfBoundsException resumer Interrupted -com/sun/jdi/SimulResumerTest.java generic-all - # Output of jps differs from expected output. # Invalid argument count on solaris-sparc and x64 sun/tools/jstatd/jstatdPort.sh generic-all @@ -1087,12 +1103,17 @@ sun/tools/jps/jps-lm.sh generic-all sun/tools/jps/jps-Vvml_2.sh generic-all sun/tools/jps/jps-m_2.sh generic-all +# Fails on OpenSolaris "Could not synchronize with target" +sun/tools/jps/jps-Defaults.sh generic-all +sun/tools/jps/jps-V_2.sh generic-all +sun/tools/jps/jps-Vm_2.sh generic-all +sun/tools/jps/jps-Vvm.sh generic-all +sun/tools/jps/jps-Vvml.sh generic-all +sun/tools/jps/jps-m.sh generic-all + # Server name error, port 2098 problem? sun/tools/jstatd/jstatdServerName.sh generic-all -# Solaris, handshake failed, othervm mode -com/sun/jdi/RedefineException.sh generic-all - # These tests fail on solaris sparc, all the time com/sun/servicetag/DeleteServiceTag.java generic-all com/sun/servicetag/DuplicateNotFound.java generic-all @@ -1117,9 +1138,6 @@ sun/jvmstat/monitor/MonitoredVm/CR6672135.java generic-all # Unexpected Monitor Exception, solaris sparc -client sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.sh generic-all -# Probably should be samevm, but seem to cause errors even in othervm at times -sun/tools/jhat/HatHeapDump1Test.java generic-all - # Problems on windows, jmap.exe hangs? (these run jmap) sun/tools/jmap/Basic.sh windows-all @@ -1129,9 +1147,6 @@ sun/tools/jstatd/jstatdDefaults.sh solaris-all # Solaris sparcv9, jps output does not match, x64 different sun/tools/jstatd/jstatdExternalRegistry.sh solaris-all -# Probably should be samevm, but seem to cause errors even in othervm at times -sun/tools/native2ascii/NativeErrors.java generic-all - # Solaris 10 sparc 32bit -client, java.lang.AssertionError: Some tests failed tools/jar/JarEntryTime.java generic-all diff --git a/test/com/sun/jdi/BadHandshakeTest.java b/test/com/sun/jdi/BadHandshakeTest.java index d5ecd0a73b84d7a07c7f94912c6b13c421309043..e03aeb1001c93bed58b16a3f0adab95d62970c1c 100644 --- a/test/com/sun/jdi/BadHandshakeTest.java +++ b/test/com/sun/jdi/BadHandshakeTest.java @@ -110,8 +110,11 @@ public class BadHandshakeTest { String exe = System.getProperty("java.home") + File.separator + "bin" + File.separator; String arch = System.getProperty("os.arch"); - if (arch.equals("sparcv9")) { + String osname = System.getProperty("os.name"); + if (osname.equals("SunOS") && arch.equals("sparcv9")) { exe += "sparcv9/java"; + } else if (osname.equals("SunOS") && arch.equals("amd64")) { + exe += "amd64/java"; } else { exe += "java"; } diff --git a/test/com/sun/jdi/DoubleAgentTest.java b/test/com/sun/jdi/DoubleAgentTest.java index 77c72cb08fddd26990e781a9d5e1989586d0fb77..bb06b89b9e2ea408802f2b1330e53f1a57957077 100644 --- a/test/com/sun/jdi/DoubleAgentTest.java +++ b/test/com/sun/jdi/DoubleAgentTest.java @@ -92,8 +92,11 @@ public class DoubleAgentTest { String exe = System.getProperty("java.home") + File.separator + "bin" + File.separator; String arch = System.getProperty("os.arch"); - if (arch.equals("sparcv9")) { + String osname = System.getProperty("os.name"); + if (osname.equals("SunOS") && arch.equals("sparcv9")) { exe += "sparcv9/java"; + } else if (osname.equals("SunOS") && arch.equals("amd64")) { + exe += "amd64/java"; } else { exe += "java"; } diff --git a/test/com/sun/jdi/ExclusiveBind.java b/test/com/sun/jdi/ExclusiveBind.java index ca2ba0229ec0d7019f6476f6f8ec612a7fa1924a..c3690e62e402231188f50539ca1bb3f4a3d1eeb8 100644 --- a/test/com/sun/jdi/ExclusiveBind.java +++ b/test/com/sun/jdi/ExclusiveBind.java @@ -99,8 +99,11 @@ public class ExclusiveBind { String exe = System.getProperty("java.home") + File.separator + "bin" + File.separator; String arch = System.getProperty("os.arch"); - if (arch.equals("sparcv9")) { + String osname = System.getProperty("os.name"); + if (osname.equals("SunOS") && arch.equals("sparcv9")) { exe += "sparcv9/java"; + } else if (osname.equals("SunOS") && arch.equals("amd64")) { + exe += "amd64/java"; } else { exe += "java"; } diff --git a/test/com/sun/jdi/JITDebug.sh b/test/com/sun/jdi/JITDebug.sh index 33aaa471fd33342b86a0843dc4474dae2ce4ad38..637c6deabd304986ffe0131e1c585ebbef1b13e3 100644 --- a/test/com/sun/jdi/JITDebug.sh +++ b/test/com/sun/jdi/JITDebug.sh @@ -103,10 +103,10 @@ if [ -z "${TESTJAVA}" ] ; then #if running standalone (no test harness of any kind), compile the #support files and the test case ${TESTJAVA}/bin/javac -d ${TESTCLASSES} \ - -classpath "$TESTJAVA/lib/tools.jar${PATHSEP}." \ + -classpath "$TESTJAVA/lib/tools.jar${PATHSEP}${TESTSRC}" \ TestScaffold.java VMConnection.java TargetListener.java TargetAdapter.java ${TESTJAVA}/bin/javac -d ${TESTCLASSES} \ - -classpath "$TESTJAVA/lib/tools.jar${PATHSEP}." -g \ + -classpath "$TESTJAVA/lib/tools.jar${PATHSEP}${TESTSRC}" -g \ JITDebug.java fi echo "JDK under test is: $TESTJAVA" diff --git a/test/com/sun/jdi/RepStep.java b/test/com/sun/jdi/RepStep.java index da058b2a3e11e92d776b0269f498d91021af208d..840ebb38427f7899116bd7c551cc037a60f2f4d6 100644 --- a/test/com/sun/jdi/RepStep.java +++ b/test/com/sun/jdi/RepStep.java @@ -29,7 +29,7 @@ * @run compile -g RepStepTarg.java * @run build VMConnection RepStep * - * @run main RepStep + * @run main/othervm RepStep * * @summary RepStep detects missed step events due to lack of * frame pop events (in back-end). diff --git a/test/com/sun/jdi/RunToExit.java b/test/com/sun/jdi/RunToExit.java index 947bcb26f976602aff825bdd68956ecedbf80ca2..c5f11f724a2f380af27d32d776c9609b833500fd 100644 --- a/test/com/sun/jdi/RunToExit.java +++ b/test/com/sun/jdi/RunToExit.java @@ -26,7 +26,7 @@ * @summary Test that with server=y, when VM runs to System.exit() no error happens * * @build VMConnection RunToExit Exit0 - * @run main RunToExit + * @run main/othervm RunToExit */ import java.io.InputStream; import java.io.IOException; @@ -115,8 +115,11 @@ public class RunToExit { String exe = System.getProperty("java.home") + File.separator + "bin" + File.separator; String arch = System.getProperty("os.arch"); - if (arch.equals("sparcv9")) { + String osname = System.getProperty("os.name"); + if (osname.equals("SunOS") && arch.equals("sparcv9")) { exe += "sparcv9/java"; + } else if (osname.equals("SunOS") && arch.equals("amd64")) { + exe += "amd64/java"; } else { exe += "java"; } diff --git a/test/com/sun/jdi/ShellScaffold.sh b/test/com/sun/jdi/ShellScaffold.sh index 855ba8ba0924c54df6e57c765a238ed14d856a2f..6d35af52dd87dcf083f73e941a2aa25d433123c9 100644 --- a/test/com/sun/jdi/ShellScaffold.sh +++ b/test/com/sun/jdi/ShellScaffold.sh @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2002-2009 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 @@ -194,7 +194,7 @@ findPid() # Return 0 if $1 is the pid of a running process. if [ -z "$isWin98" ] ; then if [ "$osname" = SunOS ] ; then - #Solaris and OpenSolaris use pgrep and not ps in psCmd + # Solaris and OpenSolaris use pgrep and not ps in psCmd findPidCmd="$psCmd" else # Never use plain 'ps', which requires a "controlling terminal" @@ -298,15 +298,15 @@ EOF # On linux, core files take a long time, and can leave # zombie processes if [ "$osname" = SunOS ] ; then - #Experiments show Solaris '/usr/ucb/ps -axwww' and - #'/usr/bin/pgrep -f -l' provide the same small amount of the - #argv string (PRARGSZ=80 in /usr/include/sys/procfs.h) - # 1) This seems to have been working OK in ShellScaffold. - # 2) OpenSolaris does not provide /usr/ucb/ps, so use pgrep - # instead - #The alternative would be to use /usr/bin/pargs [pid] to get - #all the args for a process, splice them back into one - #long string, then grep. + # Experiments show Solaris '/usr/ucb/ps -axwww' and + # '/usr/bin/pgrep -f -l' provide the same small amount of the + # argv string (PRARGSZ=80 in /usr/include/sys/procfs.h) + # 1) This seems to have been working OK in ShellScaffold. + # 2) OpenSolaris does not provide /usr/ucb/ps, so use pgrep + # instead + # The alternative would be to use /usr/bin/pargs [pid] to get + # all the args for a process, splice them back into one + # long string, then grep. UU=`/usr/xpg4/bin/id -u -n` psCmd="pgrep -f -l -U $UU" else @@ -519,7 +519,7 @@ cmd() # if jdb got a cont cmd that caused the debuggee # to run to completion, jdb can be gone before # we get here. - echo quit >& 2 + echo "--Sending cmd: quit" >& 2 echo quit # See 6562090. Maybe there is a way that the exit # can cause jdb to not get the quit. @@ -531,7 +531,7 @@ cmd() # because after starting jdb, we waited # for the prompt. fileSize=`wc -c $jdbOutFile | awk '{ print $1 }'` - echo $* >&2 + echo "--Sending cmd: " $* >&2 # jjh: We have a few intermittent failures here. # It is as if every so often, jdb doesn't @@ -558,12 +558,85 @@ cmd() # seen the ]. echo $* - # wait for jdb output to appear + # Now we have to wait for the next jdb prompt. We wait for a pattern + # to appear in the last line of jdb output. Normally, the prompt is + # + # 1) ^main[89] @ + # + # where ^ means start of line, and @ means end of file with no end of line + # and 89 is the current command counter. But we have complications e.g., + # the following jdb output can appear: + # + # 2) a[89] = 10 + # + # The above form is an array assignment and not a prompt. + # + # 3) ^main[89] main[89] ... + # + # This occurs if the next cmd is one that causes no jdb output, e.g., + # 'trace methods'. + # + # 4) ^main[89] [main[89]] .... > @ + # + # jdb prints a > as a prompt after something like a cont. + # Thus, even though the above is the last 'line' in the file, it + # isn't the next prompt we are waiting for after the cont completes. + # HOWEVER, sometimes we see this for a cont command: + # + # ^main[89] $ + # + # + # 5) ^main[89] > @ + # + # i.e., the > prompt comes out AFTER the prompt we we need to wait for. + # + # So, how do we know when the next prompt has appeared?? + # 1. Search for + # main[89] $ + # This will handle cases 1, 2, 3 + # 2. This leaves cases 4 and 5. + # + # What if we wait for 4 more chars to appear and then search for + # + # main[89] [>]$ + # + # on the last line? + # + # a. if we are currently at + # + # ^main[89] main[89] @ + # + # and a 'trace methods comes in, we will wait until at least + # + # ^main[89] main[89] main@ + # + # and then the search will find the new prompt when it completes. + # + # b. if we are currently at + # + # ^main[89] main[89] @ + # + # and the first form of cont comes in, then we will see + # + # ^main[89] main[89] > $ + # ^x@ + # + # where x is the first char of the msg output when the bkpt is hit + # and we will start our search, which will find the prompt + # when it comes out after the bkpt output, with or without the + # trailing > + # + + # wait for 4 new chars to appear in the jdb output count=0 + desiredFileSize=`expr $fileSize + 4` msg1=`echo At start: cmd/size/waiting : $* / $fileSize / \`date\`` while [ 1 = 1 ] ; do newFileSize=`wc -c $jdbOutFile | awk '{ print $1 } '` - if [ "$fileSize" != "$newFileSize" ] ; then + #echo jj: desired = $desiredFileSize, new = $newFileSize >& 2 + + done=`expr $newFileSize \>= $desiredFileSize` + if [ $done = 1 ] ; then break fi sleep ${sleep_seconds} @@ -573,14 +646,19 @@ cmd() echo "--DEBUG: jdb $$ didn't responded to command in $count secs: $*" >& 2 echo "--DEBUG:" $msg1 >& 2 echo "--DEBUG: "done size/waiting : / $newFileSize / `date` >& 2 - $psCmd | sed -e '/com.sun.javatest/d' -e '/nsk/d' >& 2 + echo "-- $jdbOutFile follows-------------------------------" >& 2 + cat $jdbOutFile >& 2 + echo "------------------------------------------" >& 2 + dojstack + #$psCmd | sed -e '/com.sun.javatest/d' -e '/nsk/d' >& 2 if [ $count = 60 ] ; then dofail "jdb never responded to command: $*" fi fi done - - waitForJdbMsg '^.*\[[0-9]*\] $' 1 allowExit + # Note that this assumes just these chars in thread names. + waitForJdbMsg '[a-zA-Z0-9_-][a-zA-Z0-9_-]*\[[1-9][0-9]*\] [ >]*$' \ + 1 allowExit } setBkpts() @@ -596,15 +674,19 @@ setBkpts() runToBkpt() { cmd run + # Don't need to do this - the above waits for the next prompt which comes out + # AFTER the Breakpoint hit message. # Wait for jdb to hit the bkpt - waitForJdbMsg "Breakpoint hit" 5 + #waitForJdbMsg "Breakpoint hit" 5 } contToBkpt() { cmd cont + # Don't need to do this - the above waits for the next prompt which comes out + # AFTER the Breakpoint hit message. # Wait for jdb to hit the bkpt - waitForJdbMsg "Breakpoint hit" 5 + #waitForJdbMsg "Breakpoint hit" 5 } @@ -618,7 +700,7 @@ waitForJdbMsg() nlines=$2 allowExit="$3" myCount=0 - timeLimit=40 # wait a max of 40 secs for a response from a jdb command + timeLimit=40 # wait a max of this many secs for a response from a jdb command while [ 1 = 1 ] ; do if [ -r $jdbOutFile ] ; then # Something here causes jdb to complain about Unrecognized cmd on x86. @@ -654,8 +736,11 @@ waitForJdbMsg() myCount=`expr $myCount + ${sleep_seconds}` if [ $myCount -gt $timeLimit ] ; then + echo "--Fail: waitForJdbMsg timed out after $timeLimit seconds, looking for /$1/, in $nlines lines; exitting" >> $failFile + echo "vv jdbOutFile vvvvvvvvvvvvvvvvvvvvvvvvvvvv" >& 2 + cat $jdbOutFile >& 2 + echo "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" >& 2 dojstack - echo "--Fail: waitForJdbMsg timed out after $timeLimit seconds; exitting" >> $failFile exit 1 fi done @@ -865,35 +950,29 @@ grepForString() # get inserted into the string we are searching for # so ignore those chars. if [ -z "$3" ] ; then - case "$2" in - *\>*) - # Target string contains a > so we better - # not ignore it - $grep -s "$2" $1 > $devnull 2>&1 - stat=$? - ;; - *) - # Target string does not contain a >. - # Ignore > and '> ' in the file. - cat $1 | sed -e 's@> @@g' -e 's@>@@g' | $grep -s "$2" > $devnull 2>&1 - stat=$? - esac + theCmd=cat else - case "$2" in - *\>*) - # Target string contains a > so we better - # not ignore it - tail -$3 $1 | $grep -s "$2" > $devnull 2>&1 - stat=$? - ;; - *) - # Target string does not contain a >. - # Ignore > and '> ' in the file. - tail -$3 $1 | sed -e 's@> @@g' -e 's@>@@g' | $grep -s "$2" > $devnull 2>&1 - stat=$? - ;; - esac + theCmd="tail -$3" + fi + case "$2" in + *\>*) + # Target string contains a > so we better + # not ignore it + $theCmd $1 | $grep -s "$2" > $devnull 2>&1 + return $? + ;; + esac + # Target string does not contain a >. + # Ignore > and '> ' in the file. + # NOTE: if $1 does not end with a new line, piping it to sed doesn't include the + # chars on the last line. Detect this case, and add a new line. + cp $1 $1.tmp + if [ `tail -1 $1.tmp | wc -l | sed -e 's@ @@g'` = 0 ] ; then + echo >> $1.tmp fi + $theCmd $1.tmp | sed -e 's@> @@g' -e 's@>@@g' | $grep -s "$2" > $devnull 2>&1 + stat=$? + rm -f $1.tmp return $stat } diff --git a/test/com/sun/jdi/SimulResumerTest.java b/test/com/sun/jdi/SimulResumerTest.java index cf7568e8be0912f7089f3a9252adf5f400460045..c0f54f806d8987f6f03f73e2a4c0210f53f27e82 100644 --- a/test/com/sun/jdi/SimulResumerTest.java +++ b/test/com/sun/jdi/SimulResumerTest.java @@ -30,7 +30,7 @@ * * @run build TestScaffold VMConnection TargetListener TargetAdapter * @run compile -g SimulResumerTest.java - * @run main SimulResumerTest + * @run main/othervm SimulResumerTest */ import com.sun.jdi.*; import com.sun.jdi.event.*; diff --git a/test/com/sun/jdi/Solaris32AndSolaris64Test.sh b/test/com/sun/jdi/Solaris32AndSolaris64Test.sh index c1b4491a706f33f824641a824161cd08da91f818..c70dd465c3aed3b83d436cee6b3452d094ff6019 100644 --- a/test/com/sun/jdi/Solaris32AndSolaris64Test.sh +++ b/test/com/sun/jdi/Solaris32AndSolaris64Test.sh @@ -164,10 +164,10 @@ fi if [ -n "${STANDALONE}" ] ; then #if running standalone, compile the support files ${TESTJAVA}/bin/javac -d ${TESTCLASSES} \ - -classpath "$TESTJAVA/lib/tools.jar${PATHSEP}." \ + -classpath "$TESTJAVA/lib/tools.jar${PATHSEP}${TESTSRC}" \ TestScaffold.java VMConnection.java TargetListener.java TargetAdapter.java ${TESTJAVA}/bin/javac -d ${TESTCLASSES} \ - -classpath "$TESTJAVA/lib/tools.jar${PATHSEP}." -g \ + -classpath "$TESTJAVA/lib/tools.jar${PATHSEP}${TESTSRC}" -g \ FetchLocals.java DataModelTest.java fi diff --git a/test/com/sun/jdi/VMConnection.java b/test/com/sun/jdi/VMConnection.java index 5d5f9e13bb679b7f94e47c2fa816c5d30af091f0..bc07e034691a3818209f6c041db0b1b8186be1a4 100644 --- a/test/com/sun/jdi/VMConnection.java +++ b/test/com/sun/jdi/VMConnection.java @@ -57,6 +57,7 @@ class VMConnection { if (testClasses == null) { return retVal; } + retVal += "-classpath " + testClasses + " "; File myFile = new File(testClasses, "@debuggeeVMOptions"); if (!myFile.canRead()) { @@ -97,7 +98,7 @@ class VMConnection { if (line.length() != 0 && !line.startsWith("#")) { System.out.println("-- Added debuggeeVM options from file " + wholePath + ": " + line); - retVal = line; + retVal += line; break; } // Else, read he next line. diff --git a/test/com/sun/jdi/connect/spi/DebugUsingCustomConnector.java b/test/com/sun/jdi/connect/spi/DebugUsingCustomConnector.java index d8c939e58c44c1f97b5ea6e768777f45e2bed475..3073093f7405b537d2f3371c9bfbe67b29ab43c3 100644 --- a/test/com/sun/jdi/connect/spi/DebugUsingCustomConnector.java +++ b/test/com/sun/jdi/connect/spi/DebugUsingCustomConnector.java @@ -28,7 +28,7 @@ * This tests launches a debuggee using a custom LaunchingConnector. * * @build DebugUsingCustomConnector SimpleLaunchingConnector Foo NullTransportService - * @run main DebugUsingCustomConnector + * @run main/othervm DebugUsingCustomConnector */ import com.sun.jdi.*; import com.sun.jdi.connect.*; diff --git a/test/com/sun/jdi/connect/spi/GeneratedConnectors.java b/test/com/sun/jdi/connect/spi/GeneratedConnectors.java index d4926396ebed05a34bf2122e4dc2e27b92aa6a2b..e9dba8332ff259e58ed07c72aad7aca83a37fbdd 100644 --- a/test/com/sun/jdi/connect/spi/GeneratedConnectors.java +++ b/test/com/sun/jdi/connect/spi/GeneratedConnectors.java @@ -31,7 +31,7 @@ * created and that they have an "address" argument. * * @build GeneratedConnectors NullTransportService - * @run main GeneratedConnectors + * @run main/othervm GeneratedConnectors */ import com.sun.jdi.*; diff --git a/test/com/sun/jdi/connect/spi/SimpleLaunchingConnector.java b/test/com/sun/jdi/connect/spi/SimpleLaunchingConnector.java index 86154d5091df90d7ce53ecf0b92d56716010cb2c..82bc3b07b9696cbc7a25f4f6b37ee65b608d9e57 100644 --- a/test/com/sun/jdi/connect/spi/SimpleLaunchingConnector.java +++ b/test/com/sun/jdi/connect/spi/SimpleLaunchingConnector.java @@ -145,13 +145,18 @@ public class SimpleLaunchingConnector implements LaunchingConnector { String exe = System.getProperty("java.home") + File.separator + "bin" + File.separator; String arch = System.getProperty("os.arch"); - if (arch.equals("sparcv9")) { + String osname = System.getProperty("os.name"); + if (osname.equals("SunOS") && arch.equals("sparcv9")) { exe += "sparcv9/java"; + } else if (osname.equals("SunOS") && arch.equals("amd64")) { + exe += "amd64/java"; } else { exe += "java"; } String cmd = exe + " -Xdebug -Xrunjdwp:transport=dt_socket,timeout=15000,address=" + - key.address() + "" + className; + key.address() + + " -classpath " + System.getProperty("test.classes") + + " " + className; Process process = Runtime.getRuntime().exec(cmd); Connection conn = ts.accept(key, 30*1000, 9*1000); ts.stopListening(key); diff --git a/test/com/sun/jdi/redefine/RedefineTest.java b/test/com/sun/jdi/redefine/RedefineTest.java index e5980d59fd658bd52f1a8cc186bf569fada954a7..809e9db1b84980e971e7c83b449393a99e4c3434 100644 --- a/test/com/sun/jdi/redefine/RedefineTest.java +++ b/test/com/sun/jdi/redefine/RedefineTest.java @@ -34,7 +34,7 @@ * @run build TestScaffold VMConnection TargetListener TargetAdapter * @run compile -g RedefineTest.java * @run shell RedefineSetUp.sh - * @run main RedefineTest + * @run main/othervm RedefineTest */ import com.sun.jdi.*; import com.sun.jdi.event.*; diff --git a/test/com/sun/tracing/BasicWithSecurityMgr.java b/test/com/sun/tracing/BasicWithSecurityMgr.java new file mode 100644 index 0000000000000000000000000000000000000000..547eb09445b52d168ce9464bc52ed0989ce8dc59 --- /dev/null +++ b/test/com/sun/tracing/BasicWithSecurityMgr.java @@ -0,0 +1,149 @@ +/* + * 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 6899605 + * @summary Basic unit test for tracing framework with security manager + * enabled + */ + +import com.sun.tracing.*; +import java.lang.reflect.Method; + +@ProviderName("NamedProvider") +interface BasicProvider extends Provider { + void plainProbe(); + void probeWithArgs(int a, float f, String s, Long l); + @ProbeName("namedProbe") void probeWithName(); + void overloadedProbe(); + void overloadedProbe(int i); +} + +interface InvalidProvider extends Provider { + int nonVoidProbe(); +} + +public class BasicWithSecurityMgr { + + public static ProviderFactory factory; + public static BasicProvider bp; + + public static void main(String[] args) throws Exception { + // enable security manager + System.setSecurityManager(new SecurityManager()); + + factory = ProviderFactory.getDefaultFactory(); + if (factory != null) { + bp = factory.createProvider(BasicProvider.class); + } + + testProviderFactory(); + testProbe(); + testProvider(); + } + + static void fail(String s) throws Exception { + throw new Exception(s); + } + + static void testProviderFactory() throws Exception { + if (factory == null) { + fail("ProviderFactory.getDefaultFactory: Did not create factory"); + } + if (bp == null) { + fail("ProviderFactory.createProvider: Did not create provider"); + } + try { + factory.createProvider(null); + fail("ProviderFactory.createProvider: Did not throw NPE for null"); + } catch (NullPointerException e) {} + + try { + factory.createProvider(InvalidProvider.class); + fail("Factory.createProvider: Should error with non-void probes"); + } catch (IllegalArgumentException e) {} + } + + public static void testProvider() throws Exception { + + // These just shouldn't throw any exeptions: + bp.plainProbe(); + bp.probeWithArgs(42, (float)3.14, "spam", new Long(2L)); + bp.probeWithArgs(42, (float)3.14, null, null); + bp.probeWithName(); + bp.overloadedProbe(); + bp.overloadedProbe(42); + + Method m = BasicProvider.class.getMethod("plainProbe"); + Probe p = bp.getProbe(m); + if (p == null) { + fail("Provider.getProbe: Did not return probe"); + } + + Method m2 = BasicWithSecurityMgr.class.getMethod("testProvider"); + p = bp.getProbe(m2); + if (p != null) { + fail("Provider.getProbe: Got probe with invalid spec"); + } + + bp.dispose(); + // These just shouldn't throw any exeptions: + bp.plainProbe(); + bp.probeWithArgs(42, (float)3.14, "spam", new Long(2L)); + bp.probeWithArgs(42, (float)3.14, null, null); + bp.probeWithName(); + bp.overloadedProbe(); + bp.overloadedProbe(42); + + if (bp.getProbe(m) != null) { + fail("Provider.getProbe: Should return null after dispose()"); + } + + bp.dispose(); // just to make sure nothing bad happens + } + + static void testProbe() throws Exception { + Method m = BasicProvider.class.getMethod("plainProbe"); + Probe p = bp.getProbe(m); + p.isEnabled(); // just make sure it doesn't do anything bad + p.trigger(); + + try { + p.trigger(0); + fail("Probe.trigger: too many arguments not caught"); + } catch (IllegalArgumentException e) {} + + p = bp.getProbe(BasicProvider.class.getMethod( + "probeWithArgs", int.class, float.class, String.class, Long.class)); + try { + p.trigger(); + fail("Probe.trigger: too few arguments not caught"); + } catch (IllegalArgumentException e) {} + + try { + p.trigger((float)3.14, (float)3.14, "", new Long(0L)); + fail("Probe.trigger: wrong type primitive arguments not caught"); + } catch (IllegalArgumentException e) {} + } +} diff --git a/test/java/awt/Container/ValidateRoot/InvalidateMustRespectValidateRoots.java b/test/java/awt/Container/ValidateRoot/InvalidateMustRespectValidateRoots.java new file mode 100644 index 0000000000000000000000000000000000000000..7bf34012dd9155b0257c5eeda5c865cb5292a8da --- /dev/null +++ b/test/java/awt/Container/ValidateRoot/InvalidateMustRespectValidateRoots.java @@ -0,0 +1,114 @@ +/* + * Copyright 2009 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 6852592 + @summary invalidate() must stop when it encounters a validate root + @author anthony.petrov@sun.com + @run main InvalidateMustRespectValidateRoots +*/ + +import javax.swing.*; +import java.awt.event.*; + +public class InvalidateMustRespectValidateRoots { + private static volatile JRootPane rootPane; + + public static void main(String args[]) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + // The JRootPane is a validate root. We'll check if + // invalidate() stops on the root pane, or goes further + // up to the frame. + JFrame frame = new JFrame(); + final JButton button = new JButton(); + + frame.add(button); + + // To enable running the test manually: use the Ctrl-Shift-F1 + // to print the component hierarchy to the console + button.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ev) { + if (button.isValid()) { + button.invalidate(); + } else { + button.revalidate(); + } + } + }); + + rootPane = frame.getRootPane(); + + // Now the component hierarchy looks like: + // frame + // --> rootPane + // --> layered pane + // --> content pane + // --> button + + // Make all components valid first via showing the frame + // We have to make the frame visible. Otherwise revalidate() is + // useless (see RepaintManager.addInvalidComponent()). + frame.pack(); // To enable running this test manually + frame.setVisible(true); + + if (!frame.isValid()) { + throw new RuntimeException( + "setVisible(true) failed to validate the frame"); + } + + // Now invalidate the button + button.invalidate(); + + // Check if the 'valid' status is what we expect it to be + if (rootPane.isValid()) { + throw new RuntimeException( + "invalidate() failed to invalidate the root pane"); + } + + if (!frame.isValid()) { + throw new RuntimeException( + "invalidate() invalidated the frame"); + } + + // Now validate the hierarchy again + button.revalidate(); + + // Now let the validation happen on the EDT + } + }); + + Thread.sleep(1000); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + // Check if the root pane finally became valid + if (!rootPane.isValid()) { + throw new RuntimeException( + "revalidate() failed to validate the hierarchy"); + } + } + }); + } +} diff --git a/test/java/awt/event/InvocationEvent/InvocationEventTest.java b/test/java/awt/event/InvocationEvent/InvocationEventTest.java new file mode 100644 index 0000000000000000000000000000000000000000..5fb83d10acf2aeabed6609c9b0d0c980af7db66b --- /dev/null +++ b/test/java/awt/event/InvocationEvent/InvocationEventTest.java @@ -0,0 +1,68 @@ +/* + * Copyright 2009 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 6852111 + @summary Unhandled 'spurious wakeup' in java.awt.EventQueue.invokeAndWait() + @author dmitry.cherepanov@sun.com: area=awt.event + @run main InvocationEventTest +*/ + +/** + * InvocationEventTest.java + * + * summary: Tests new isDispatched method of the InvocationEvent class + */ + +import java.awt.*; +import java.awt.event.*; + +public class InvocationEventTest +{ + public static void main(String []s) throws Exception + { + Toolkit tk = Toolkit.getDefaultToolkit(); + Runnable runnable = new Runnable() { + public void run() { + } + }; + Object lock = new Object(); + InvocationEvent event = new InvocationEvent(tk, runnable, lock, true); + + if (event.isDispatched()) { + throw new RuntimeException(" Initially, the event shouldn't be dispatched "); + } + + synchronized(lock) { + tk.getSystemEventQueue().postEvent(event); + while(!event.isDispatched()) { + lock.wait(); + } + } + + if(!event.isDispatched()) { + throw new RuntimeException(" Finally, the event should be dispatched "); + } + } +} diff --git a/test/java/awt/font/NumericShaper/EqualsTest.java b/test/java/awt/font/NumericShaper/EqualsTest.java new file mode 100644 index 0000000000000000000000000000000000000000..b71bacf42fe5d1953d3b5dbcebae96969145a02d --- /dev/null +++ b/test/java/awt/font/NumericShaper/EqualsTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2009 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 6842557 + * @summary confirm that an instance which is created with new Enum ranges is + * equivalent to another instance which is created with equivalent traditional + * ranges or the same Enum ranges. + */ + +import java.awt.font.NumericShaper; +import java.util.EnumSet; +import static java.awt.font.NumericShaper.*; + +public class EqualsTest { + public static void main(String[] args) { + NumericShaper ns1 = getContextualShaper(ARABIC | TAMIL, TAMIL); + NumericShaper ns2 = getContextualShaper( + EnumSet.of(Range.ARABIC, Range.TAMIL), + Range.TAMIL); + NumericShaper ns3 = getContextualShaper( + EnumSet.of(Range.ARABIC, Range.TAMIL), + Range.TAMIL); + NumericShaper ns4 = getContextualShaper( + EnumSet.of(Range.ARABIC, Range.TAMIL), + Range.ARABIC); + + if (!ns1.equals(ns2)) { + throw new RuntimeException("ns1 != ns2: ns1=" + ns1 + ", ns2=" + ns2); + } + if (!ns2.equals(ns1)) { + throw new RuntimeException("ns2 != ns1: ns1=" + ns1 + ", ns2=" + ns2); + } + if (!ns2.equals(ns3)) { + throw new RuntimeException("ns2 != ns3: ns2=" + ns2 + ", ns3=" + ns3); + } + if (ns1.equals(ns4)) { + throw new RuntimeException("ns1 == ns4: ns1=" + ns1 + ", ns4=" + ns4); + } + if (ns2.equals(ns4)) { + throw new RuntimeException("ns2 == ns4: ns2=" + ns2 + ", ns4=" + ns4); + } + } +} diff --git a/test/java/awt/font/NumericShaper/MTTest.java b/test/java/awt/font/NumericShaper/MTTest.java new file mode 100644 index 0000000000000000000000000000000000000000..e2598c3c36d7f89a58a9a1886521d695728bd573 --- /dev/null +++ b/test/java/awt/font/NumericShaper/MTTest.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2009 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 6843181 + * @summary Confirm that NumericShaper is thread-safe. + * @run main/timeout=300/othervm MTTest + */ + +import java.awt.font.NumericShaper; +import java.util.Arrays; +import java.util.EnumSet; +import static java.awt.font.NumericShaper.*; + +public class MTTest { + static volatile boolean runrun = true; + static volatile boolean err = false; + + final static String text = "-123 (English) 456.00 (Arabic) \u0641\u0642\u0643 -789 (Thai) \u0e01\u0e33 01.23"; + static char[] t1, t2; + static NumericShaper ns1, ns2, ns3, ns4; + + public static void main(String[] args) { + System.out.println(" original: " + text); + ns1 = getContextualShaper(EnumSet.of(Range.ARABIC), Range.ARABIC); + t1 = text.toCharArray(); + ns1.shape(t1, 0, t1.length); + System.out.println("expected t1: " + String.valueOf(t1)); + + ns2 = getContextualShaper(EnumSet.of(Range.THAI), Range.THAI); + t2 = text.toCharArray(); + ns2.shape(t2, 0, t2.length); + System.out.println("expected t2: " + String.valueOf(t2)); + + ns3 = getContextualShaper(ARABIC, ARABIC); + ns4 = getContextualShaper(THAI, THAI); + + Thread th1 = new Thread(new Work(ns1, t1)); + Thread th2 = new Thread(new Work(ns2, t2)); + Thread th3 = new Thread(new Work(ns1, t1)); + Thread th4 = new Thread(new Work(ns2, t2)); + Thread th5 = new Thread(new Work(ns3, t1)); + Thread th6 = new Thread(new Work(ns4, t2)); + Thread th7 = new Thread(new Work(ns3, t1)); + Thread th8 = new Thread(new Work(ns4, t2)); + + th1.start(); + th2.start(); + th3.start(); + th4.start(); + th5.start(); + th6.start(); + th7.start(); + th8.start(); + + try { + for (int i = 0; runrun && i < 180; i++) { + Thread.sleep(1000); // 1 seconds + } + runrun = false; + th1.join(); + th2.join(); + th3.join(); + th4.join(); + th5.join(); + th6.join(); + th7.join(); + th8.join(); + } + catch (InterruptedException e) { + } + + if (err) { + throw new RuntimeException("Thread-safe test failed."); + } + } + + private static class Work implements Runnable { + NumericShaper ns; + char[] expectedText; + + Work(NumericShaper ns, char[] expectedText) { + this.ns = ns; + this.expectedText = expectedText; + + } + + public void run() { + int count = 0; + while (runrun) { + char[] t = text.toCharArray(); + try { + count++; + ns.shape(t, 0, t.length); + } catch (Exception e) { + System.err.println("Error: Unexpected exception: " + e); + runrun = false; + err = true; + return; + } + if (!Arrays.equals(t, expectedText)) { + System.err.println("Error: shape() returned unexpected value: "); + System.err.println("count = " + count); + System.err.println(" expected: " + String.valueOf(expectedText)); + System.err.println(" got: " + String.valueOf(t)); + runrun = false; + err = true; + return; + } + } + } + } +} diff --git a/test/java/awt/font/NumericShaper/ShapingTest.java b/test/java/awt/font/NumericShaper/ShapingTest.java new file mode 100644 index 0000000000000000000000000000000000000000..047e67f12d344f1264b5f9ab0b854b632506077f --- /dev/null +++ b/test/java/awt/font/NumericShaper/ShapingTest.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2009 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 6842557 + * @summary confirm that shaping works as expected. (Mainly for new characters which were added in Unicode 5) + * used where appropriate. + */ + +import java.awt.font.NumericShaper; +import java.util.EnumSet; +import static java.awt.font.NumericShaper.*; + +public class ShapingTest { + public static void main(String[] args) { + NumericShaper ns_old = getContextualShaper(ARABIC | TAMIL | ETHIOPIC, + EUROPEAN); + NumericShaper ns_new = getContextualShaper(EnumSet.of( + Range.ARABIC, Range.TAMIL, Range.ETHIOPIC), + Range.EUROPEAN); + + boolean err = false; + + String[][] data = { + // Arabic "October 10" + {"\u0623\u0643\u062a\u0648\u0628\u0631 10", + "\u0623\u0643\u062a\u0648\u0628\u0631 \u0661\u0660"}, + + // Tamil "Year 2009" + {"\u0b86\u0ba3\u0bcd\u0b9f\u0bc1 2009", + "\u0b86\u0ba3\u0bcd\u0b9f\u0bc1 \u0be8\u0be6\u0be6\u0bef"}, + // "\u0be800\u0bef is returned by pre-JDK7 because Tamil zero was not + // included in Unicode 4.0.0. + + // Ethiopic "Syllable 2009" + {"\u1200 2009", + "\u1200 \u136a00\u1371"}, + // Ethiopic zero doesn't exist even in Unicode 5.1.0. + }; + + for (int i = 0; i < data.length; i++) { + String expected = data[i][1]; + + char[] text = data[i][0].toCharArray(); + ns_old.shape(text, 0, text.length); + String got = new String(text); + + if (!expected.equals(got)) { + err = true; + System.err.println("Error with traditional range."); + System.err.println(" text = " + data[i][0]); + System.err.println(" got = " + got); + System.err.println(" expected = " + expected); + } else { + System.err.println("OK with traditional range."); + System.err.println(" text = " + data[i][0]); + System.err.println(" got = " + got); + System.err.println(" expected = " + expected); + } + + text = data[i][0].toCharArray(); + ns_new.shape(text, 0, text.length); + got = new String(text); + + if (!expected.equals(got)) { + err = true; + System.err.println("Error with new Enum range."); + System.err.println(" text = " + data[i][0]); + System.err.println(" got = " + got); + System.err.println(" expected = " + expected); + } else { + System.err.println("OK with new Enum range."); + System.err.println(" text = " + data[i][0]); + System.err.println(" got = " + got); + System.err.println(" expected = " + expected); + } + } + + if (err) { + throw new RuntimeException("shape() returned unexpected value."); + } + } + +} diff --git a/test/java/net/CookieHandler/TestHttpCookie.java b/test/java/net/CookieHandler/TestHttpCookie.java index f1f89f8daab06db686d807c8374274afbf624210..df0dd74cdb7f780bf77b821083dfefa7b96872a7 100644 --- a/test/java/net/CookieHandler/TestHttpCookie.java +++ b/test/java/net/CookieHandler/TestHttpCookie.java @@ -24,7 +24,7 @@ /** * @test * @summary Unit test for java.net.HttpCookie - * @bug 6244040 6277796 6277801 6277808 6294071 6692802 6790677 + * @bug 6244040 6277796 6277801 6277808 6294071 6692802 6790677 6901170 * @author Edward Wang */ @@ -335,6 +335,9 @@ public class TestHttpCookie { // bug 6277801 test("set-cookie: CUSTOMER=WILE_E_COYOTE; path=/; expires=Wednesday, 09-Nov-99 23:12:40 GMT; path=\"/acme\"") .n("CUSTOMER").v("WILE_E_COYOTE").p("/").ver(0); + + // bug 6901170 + test("set-cookie: CUSTOMER=WILE_E_COYOTE; version='1'").ver(1); } static void misc() { diff --git a/test/java/util/Formatter/Basic-X.java b/test/java/util/Formatter/Basic-X.java.template similarity index 100% rename from test/java/util/Formatter/Basic-X.java rename to test/java/util/Formatter/Basic-X.java.template diff --git a/test/java/util/Formatter/genBasic.sh b/test/java/util/Formatter/genBasic.sh index 2c352ad39cf0b817718bd06f76a0963ef18206b3..819afe7cd392558172ea668b3a9f003b5a7bdad7 100644 --- a/test/java/util/Formatter/genBasic.sh +++ b/test/java/util/Formatter/genBasic.sh @@ -27,10 +27,10 @@ javac -d . ../../../../make/tools/src/build/tools/spp/Spp.java gen() { # if [ $3 = "true" ] -# then $SPP -K$1 -Dtype=$1 -DType=$2 -KprimBasic$2.java -# else $SPP -K$1 -Dtype=$1 -DType=$2 -K$3 Basic$2.java +# then $SPP -K$1 -Dtype=$1 -DType=$2 -KprimBasic$2.java +# else $SPP -K$1 -Dtype=$1 -DType=$2 -K$3 Basic$2.java # fi - java build.tools.spp.Spp -K$1 -Dtype=$1 -DType=$2 -K$3 -K$4 -K$5 -K$6 Basic$2.java + java build.tools.spp.Spp -K$1 -Dtype=$1 -DType=$2 -K$3 -K$4 -K$5 -K$6 Basic$2.java } gen boolean Boolean prim "" "" "" diff --git a/test/javax/swing/JFileChooser/6550546/bug6550546.java b/test/javax/swing/JFileChooser/6550546/bug6550546.java new file mode 100644 index 0000000000000000000000000000000000000000..84277edf54aac05434a3715a0276a262341fea41 --- /dev/null +++ b/test/javax/swing/JFileChooser/6550546/bug6550546.java @@ -0,0 +1,57 @@ +/* + * Copyright 2009 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 6550546 + @summary Win LAF: JFileChooser -> Look in Drop down should not display any shortcuts created on desktop + @author Pavel Porvatov + @run main bug6550546 +*/ + +import sun.awt.OSInfo; +import sun.awt.shell.ShellFolder; + +import javax.swing.*; +import java.io.File; + +public class bug6550546 { + public static void main(String[] args) throws Exception { + if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) { + System.out.println("The test is suitable only for Windows, skipped."); + + return; + } + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + File[] files = (File[]) ShellFolder.get("fileChooserComboBoxFolders"); + + for (File file : files) { + if (file instanceof ShellFolder && ((ShellFolder) file).isLink()) { + throw new RuntimeException("Link shouldn't be in FileChooser combobox, " + file.getPath()); + } + } + } + }); + } +} diff --git a/test/javax/swing/JFileChooser/6741890/bug6741890.java b/test/javax/swing/JFileChooser/6741890/bug6741890.java new file mode 100644 index 0000000000000000000000000000000000000000..1e670e704044db0a7fe9ba5030aea8e1c7129309 --- /dev/null +++ b/test/javax/swing/JFileChooser/6741890/bug6741890.java @@ -0,0 +1,107 @@ +/* + * Copyright 2009 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 6741890 + @summary Deadlock in Win32ShellFolderManager2 + @author Pavel Porvatov + @run main bug6741890 +*/ + +import sun.awt.shell.ShellFolder; +import sun.awt.OSInfo; + +import java.io.File; +import java.lang.reflect.Field; +import java.util.concurrent.Callable; + +public class bug6741890 { + /** + * This mux is used to prevent NPE in the isLink and isFileSystem methods + */ + private static final Object mux = new Object(); + + private static final int COUNT = 100000; + + public static void main(String[] args) throws Exception { + if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) { + System.out.println("The test is applicable only for Windows. Skipped."); + + return; + } + + String tmpDir = System.getProperty("java.io.tmpdir"); + + if (tmpDir.length() == 0) { //'java.io.tmpdir' isn't guaranteed to be defined + tmpDir = System.getProperty("user.home"); + } + + final ShellFolder tmpFile = ShellFolder.getShellFolder(new File(tmpDir)); + + System.out.println("Temp directory: " + tmpDir); + + System.out.println("Stress test was run"); + + Thread thread = new Thread() { + public void run() { + while (!isInterrupted()) { + ShellFolder.invoke(new Callable() { + public Void call() throws Exception { + synchronized (mux) { + tmpFile.isFileSystem(); + tmpFile.isLink(); + } + + return null; + } + }); + } + } + }; + + thread.start(); + + for (int i = 0; i < COUNT; i++) { + synchronized (mux) { + clearField(tmpFile, "cachedIsLink"); + clearField(tmpFile, "cachedIsFileSystem"); + } + + tmpFile.isFileSystem(); + tmpFile.isLink(); + } + + thread.interrupt(); + thread.join(); + + System.out.println("Test passed successfully"); + } + + private static void clearField(Object o, String fieldName) throws Exception { + Field field = o.getClass().getDeclaredField(fieldName); + + field.setAccessible(true); + + field.set(o, null); + } +} diff --git a/test/javax/swing/JFileChooser/6868611/bug6868611.java b/test/javax/swing/JFileChooser/6868611/bug6868611.java new file mode 100644 index 0000000000000000000000000000000000000000..fa555c7659b262e0d2611400779b34c049ef43ef --- /dev/null +++ b/test/javax/swing/JFileChooser/6868611/bug6868611.java @@ -0,0 +1,93 @@ +/* + * Copyright 2009 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 6868611 + @summary FileSystemView throws NullPointerException + @author Pavel Porvatov + @run main bug6868611 +*/ + +import javax.swing.*; +import javax.swing.filechooser.FileSystemView; +import java.io.File; + +public class bug6868611 { + private static final int COUNT = 1000; + + public static void main(String[] args) throws Exception { + String tempDirProp = System.getProperty("java.io.tmpdir"); + + final String tempDir = tempDirProp == null || !new File(tempDirProp).isDirectory() ? + System.getProperty("user.home") : tempDirProp; + + System.out.println("Temp directory: " + tempDir); + + // Create 1000 files + for (int i = 0; i < 1000; i++) { + new File(tempDir, "temp" + i).createNewFile(); + } + + // Init default FileSystemView + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + FileSystemView.getFileSystemView().getFiles(new File(tempDir), false); + } + }); + + for (int i = 0; i < COUNT; i++) { + Thread thread = new MyThread(tempDir); + + thread.start(); + + Thread.sleep((long) (Math.random() * 100)); + + thread.interrupt(); + + if (i % 100 == 0) { + System.out.print("*"); + } + } + + System.out.println(); + + // Remove 1000 files + for (int i = 0; i < 1000; i++) { + new File(tempDir, "temp" + i).delete(); + } + } + + private static class MyThread extends Thread { + private final String dir; + + private MyThread(String dir) { + this.dir = dir; + } + + public void run() { + FileSystemView fileSystemView = FileSystemView.getFileSystemView(); + + fileSystemView.getFiles(new File(dir), false); + } + } +} diff --git a/test/tools/launcher/libraryCaller.java b/test/javax/swing/UIDefaults/6795356/SwingLazyValueTest.java similarity index 64% rename from test/tools/launcher/libraryCaller.java rename to test/javax/swing/UIDefaults/6795356/SwingLazyValueTest.java index f938a2fce233ce4dfdad84513cb1d0d0849d1437..4211e53cd8ef6d022d4826a99a1226607082a19a 100644 --- a/test/tools/launcher/libraryCaller.java +++ b/test/javax/swing/UIDefaults/6795356/SwingLazyValueTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 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 @@ -21,26 +21,24 @@ * have any questions. */ - /* - * - * - * Used by SolarisRunpath.sh to help test if the launcher fully - * respects Solaris LD_LIBRARY_PATH semantics. The ./lib directory is - * structured so that the results of the dynamically linked number - * method varies depending on the value the data model dependent - * LD_LIBRARY_PATH variable. + * @test + * @bug 6795356 + * @summary Checks that SwingLazyValue class correclty works + * @author Alexander Potochkin + * @run main SwingLazyValueTest */ +import sun.swing.SwingLazyValue; +import javax.swing.*; -class libraryCaller { - static { - System.loadLibrary("library"); - } - static native int number(); +public class SwingLazyValueTest { - public static void main(String argv[]) { - System.out.println(number()); + public static void main(String[] args) throws Exception { + if(new SwingLazyValue("javax.swing.JTable$DoubleRenderer"). + createValue(null) == null) { + throw new RuntimeException("SwingLazyValue doesn't work"); + } } } diff --git a/test/tools/launcher/libraryCaller.c b/test/javax/swing/UIDefaults/6795356/TableTest.java similarity index 54% rename from test/tools/launcher/libraryCaller.c rename to test/javax/swing/UIDefaults/6795356/TableTest.java index e77f402b799f86e02d2b65146f4c7f04a4e9c6a8..6002f816979a7c72cf566a03b4c214b52a164735 100644 --- a/test/tools/launcher/libraryCaller.c +++ b/test/javax/swing/UIDefaults/6795356/TableTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 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 @@ -22,35 +22,31 @@ */ /* - * - * - * Indictly used by SolarisRunpath.sh; this file is used to generate - * the shared objects: - * - * ./lib/sparc/lib32/liblibrary.so - * ./lib/sparc/lib32/lib32/liblibrary.so - * - * ./lib/sparc/lib64/liblibrary.so - * ./lib/sparc/lib64/lib64/liblibrary.so - * - * ./lib/i386/lib32/liblibrary.so - * ./lib/i386/lib32/lib32/liblibrary.so - * - * The function defined below returns either 0 or the size of an - * integer in the data model used to compile the file (32 for ILP; 64 - * for LP). The libraries in ./lib/$ARCH/lib$DM return 0; those in - * ./lib/$ARCH/lib$DM/lib$DM return 32 or 64. + * @test + * @bug 6795356 + * @summary Checks that SwingLazyValue class correclty works + * @author Alexander Potochkin + * @run main/othervm TableTest */ +import sun.applet.AppletSecurity; + +import javax.swing.*; +import javax.swing.table.TableCellEditor; +import java.awt.*; -#include -#include "libraryCaller.h" +public class TableTest { -#ifndef RETURN_VALUE -#define RETURN_VALUE 0 -#endif + public static void main(String[] args) throws Exception { -JNIEXPORT jint JNICALL Java_libraryCaller_number -(JNIEnv *je, jclass jc) { - return RETURN_VALUE; + KeyboardFocusManager.getCurrentKeyboardFocusManager(); + System.setSecurityManager(new AppletSecurity()); + + JTable table = new JTable(); + TableCellEditor de = table.getDefaultEditor(Double.class); + if (de == null) { + throw new RuntimeException("Table default editor is null"); + } + } } + diff --git a/test/javax/swing/UIDefaults/6795356/bug6795356.java b/test/javax/swing/UIDefaults/6795356/bug6795356.java new file mode 100644 index 0000000000000000000000000000000000000000..89e33f1cf82c5f5456b8f28b322363d2970f03f4 --- /dev/null +++ b/test/javax/swing/UIDefaults/6795356/bug6795356.java @@ -0,0 +1,100 @@ +/* + * Copyright 2009 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 6795356 + * @summary Leak caused by javax.swing.UIDefaults.ProxyLazyValue.acc + * @author Alexander Potochkin + * @run main bug6795356 + */ + +import java.lang.ref.WeakReference; +import java.security.ProtectionDomain; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.AccessControlContext; +import java.util.LinkedList; +import java.util.List; +import javax.swing.*; + +public class bug6795356 { + volatile static WeakReference weakRef; + + public static void main(String[] args) throws Exception { + + ProtectionDomain domain = new ProtectionDomain(null, null); + + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + + // this initialize ProxyLazyValues + UIManager.getLookAndFeel(); + + return null; + } + }, new AccessControlContext(new ProtectionDomain[]{domain})); + + weakRef = new WeakReference(domain); + domain = null; + + // Generate OutOfMemory and check the weak ref + generateOOME(); + + if (weakRef.get() != null) { + throw new RuntimeException("Memory leak found!"); + } + System.out.println("Test passed"); + } + + static void generateOOME() { + List bigLeak = new LinkedList(); + boolean oome = false; + System.out.print("Filling the heap"); + try { + for(int i = 0; true ; i++) { + // Now, use up all RAM + bigLeak.add(new byte[1024 * 1024]); + System.out.print("."); + + // Give the GC a change at that weakref + if (i % 10 == 0) { + System.gc(); + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } catch (OutOfMemoryError e) { + bigLeak = null; + oome = true; + } + System.out.println(""); + if (!oome) { + throw new RuntimeException("Problem with test case - never got OOME"); + } + System.out.println("Got OOME"); + } +} diff --git a/test/sun/java2d/pisces/Renderer/TestNPE.java b/test/sun/java2d/pisces/Renderer/TestNPE.java new file mode 100644 index 0000000000000000000000000000000000000000..440860c9272a52641cfb7c65024846596ad5a955 --- /dev/null +++ b/test/sun/java2d/pisces/Renderer/TestNPE.java @@ -0,0 +1,59 @@ +/* + * Copyright 2009 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 6887494 + * + * @summary Verifies that no NullPointerException is thrown in Pisces Renderer + * under certain circumstances. + * + * @run main TestNPE + */ + +import java.awt.*; +import java.awt.geom.*; +import java.awt.image.BufferedImage; + +public class TestNPE { + + private static void paint(Graphics g) { + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setClip(0, 0, 0, 0); + g2d.setTransform( + new AffineTransform(4.0f, 0.0f, 0.0f, 4.0f, -1248.0f, -744.0f)); + g2d.draw(new Line2D.Float(131.21428571428572f, 33.0f, + 131.21428571428572f, 201.0f)); + } + + public static void main(String[] args) { + BufferedImage im = new BufferedImage(100, 100, + BufferedImage.TYPE_INT_ARGB); + + // Trigger exception in main thread. + Graphics g = im.getGraphics(); + paint(g); + } +} diff --git a/test/sun/security/jgss/spnego/NoSpnegoAsDefMech.java b/test/sun/security/jgss/spnego/NoSpnegoAsDefMech.java new file mode 100644 index 0000000000000000000000000000000000000000..2f23de385fe1f8f432ddc33f5fbe2540415b6c66 --- /dev/null +++ b/test/sun/security/jgss/spnego/NoSpnegoAsDefMech.java @@ -0,0 +1,43 @@ +/* + * Copyright 2009 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 6770883 + * @summary Infinite loop if SPNEGO specified as sun.security.jgss.mechanism + */ + +import org.ietf.jgss.*; +import sun.security.jgss.*; + +public class NoSpnegoAsDefMech { + + public static void main(String[] argv) throws Exception { + System.setProperty("sun.security.jgss.mechanism", GSSUtil.GSS_SPNEGO_MECH_OID.toString()); + try { + GSSManager.getInstance().createName("service@host", GSSName.NT_HOSTBASED_SERVICE, new Oid("1.3.6.1.5.5.2")); + } catch (GSSException e) { + // This is OK, for example, krb5.conf is missing or other problems + } + } +} diff --git a/test/sun/security/krb5/auto/Context.java b/test/sun/security/krb5/auto/Context.java index 140623f83103117ee371be9a3f6904800fcc1f47..3187e99d87e2ff87c883086ab39ca8d8cb93bb43 100644 --- a/test/sun/security/krb5/auto/Context.java +++ b/test/sun/security/krb5/auto/Context.java @@ -72,7 +72,7 @@ import com.sun.security.jgss.AuthorizationDataEntry; public class Context { private Subject s; - private GSSContext x; + private ExtendedGSSContext x; private boolean f; // context established? private String name; private GSSCredential cred; // see static method delegated(). @@ -147,8 +147,8 @@ public class Context { @Override public byte[] run(Context me, byte[] dummy) throws Exception { GSSManager m = GSSManager.getInstance(); - me.x = m.createContext( - target.indexOf('@') < 0 ? + me.x = (ExtendedGSSContext)m.createContext( + target.indexOf('@') < 0 ? m.createName(target, null) : m.createName(target, GSSName.NT_HOSTBASED_SERVICE), mech, @@ -170,7 +170,7 @@ public class Context { @Override public byte[] run(Context me, byte[] dummy) throws Exception { GSSManager m = GSSManager.getInstance(); - me.x = m.createContext(m.createCredential( + me.x = (ExtendedGSSContext)m.createContext(m.createCredential( null, GSSCredential.INDEFINITE_LIFETIME, mech, @@ -193,7 +193,7 @@ public class Context { * * @return the GSSContext object */ - public GSSContext x() { + public ExtendedGSSContext x() { return x; } @@ -255,6 +255,11 @@ public class Context { if (x.getSequenceDetState()) { sb.append("seq det, "); } + if (x instanceof ExtendedGSSContext) { + if (((ExtendedGSSContext)x).getDelegPolicyState()) { + sb.append("deleg policy, "); + } + } System.out.println("Context status of " + name + ": " + sb.toString()); System.out.println(x.getSrcName() + " -> " + x.getTargName()); } catch (Exception e) { diff --git a/test/sun/security/krb5/auto/KDC.java b/test/sun/security/krb5/auto/KDC.java index 586d8b23e61d71aad61b70d4a1eb2695ba34baec..169094c779ba8a9421826a5d7db9dc232d31aea4 100644 --- a/test/sun/security/krb5/auto/KDC.java +++ b/test/sun/security/krb5/auto/KDC.java @@ -63,6 +63,14 @@ import sun.security.util.DerValue; * settings after calling a KDC method, call Config.refresh() to * make sure your changes are reflected in the Config object. * + * System properties recognized: + *
    + *
  • test.kdc.save.ccache + *
+ * Support policies: + *
    + *
  • ok-as-delegate + *
* Issues and TODOs: *
    *
  1. Generates krb5.conf to be used on another machine, currently the kdc is @@ -151,7 +159,7 @@ public class KDC { * A standalone KDC server. */ public static void main(String[] args) throws Exception { - KDC kdc = create("RABBIT.HOLE", "kdc.rabbit,hole", 0, false); + KDC kdc = create("RABBIT.HOLE", "kdc.rabbit.hole", 0, false); kdc.addPrincipal("dummy", "bogus".toCharArray()); kdc.addPrincipal("foo", "bar".toCharArray()); kdc.addPrincipalRandKey("krbtgt/RABBIT.HOLE"); @@ -426,14 +434,17 @@ public class KDC { * @throws sun.security.krb5.KrbException when the principal is not inside * the database. */ - private char[] getPassword(PrincipalName p) throws KrbException { + private char[] getPassword(PrincipalName p, boolean server) + throws KrbException { String pn = p.toString(); if (p.getRealmString() == null) { pn = pn + "@" + getRealm(); } char[] pass = passwords.get(pn); if (pass == null) { - throw new KrbException(Krb5.KDC_ERR_C_PRINCIPAL_UNKNOWN); + throw new KrbException(server? + Krb5.KDC_ERR_S_PRINCIPAL_UNKNOWN: + Krb5.KDC_ERR_C_PRINCIPAL_UNKNOWN); } return pass; } @@ -457,10 +468,12 @@ public class KDC { * Returns the key for a given principal of the given encryption type * @param p the principal * @param etype the encryption type + * @param server looking for a server principal? * @return the key * @throws sun.security.krb5.KrbException for unknown/unsupported etype */ - private EncryptionKey keyForUser(PrincipalName p, int etype) throws KrbException { + private EncryptionKey keyForUser(PrincipalName p, int etype, boolean server) + throws KrbException { try { // Do not call EncryptionKey.acquireSecretKeys(), otherwise // the krb5.conf config file would be loaded. @@ -469,22 +482,71 @@ public class KDC { Integer kvno = null; // For service whose password ending with a number, use it as kvno if (p.toString().indexOf('/') >= 0) { - char[] pass = getPassword(p); + char[] pass = getPassword(p, server); if (Character.isDigit(pass[pass.length-1])) { kvno = pass[pass.length-1] - '0'; } } return new EncryptionKey((byte[]) stringToKey.invoke( - null, getPassword(p), getSalt(p), null, etype), + null, getPassword(p, server), getSalt(p), null, etype), etype, kvno); } catch (InvocationTargetException ex) { KrbException ke = (KrbException)ex.getCause(); throw ke; + } catch (KrbException ke) { + throw ke; } catch (Exception e) { throw new RuntimeException(e); // should not happen } } + private Map policies = new HashMap(); + + public void setPolicy(String rule, String value) { + if (value == null) { + policies.remove(rule); + } else { + policies.put(rule, value); + } + } + /** + * If the provided client/server pair matches a rule + * + * A system property named test.kdc.policy.RULE will be consulted. + * If it's unset, returns false. If its value is "", any pair is + * matched. Otherwise, it should contains the server name matched. + * + * TODO: client name is not used currently. + * + * @param c client name + * @param s server name + * @param rule rule name + * @return if a match is found + */ + private boolean configMatch(String c, String s, String rule) { + String policy = policies.get(rule); + boolean result = false; + if (policy == null) { + result = false; + } else if (policy.length() == 0) { + result = true; + } else { + String[] names = policy.split("\\s+"); + for (String name: names) { + if (name.equals(s)) { + result = true; + break; + } + } + } + if (result) { + System.out.printf(">>>> Policy match result (%s vs %s on %s) %b\n", + c, s, rule, result); + } + return result; + } + + /** * Processes an incoming request and generates a response. * @param in the request @@ -530,7 +592,7 @@ public class KDC { tkt = apReq.ticket; etype = tkt.encPart.getEType(); tkt.sname.setRealm(tkt.realm); - EncryptionKey kkey = keyForUser(tkt.sname, etype); + EncryptionKey kkey = keyForUser(tkt.sname, etype, true); byte[] bb = tkt.encPart.decrypt(kkey, KeyUsage.KU_TICKET); DerInputStream derIn = new DerInputStream(bb); DerValue der = derIn.getDerValue(); @@ -541,7 +603,7 @@ public class KDC { throw new KrbException(Krb5.KDC_ERR_PADATA_TYPE_NOSUPP); } } - EncryptionKey skey = keyForUser(body.sname, etype); + EncryptionKey skey = keyForUser(body.sname, etype, true); if (skey == null) { throw new KrbException(Krb5.KDC_ERR_SUMTYPE_NOSUPP); // TODO } @@ -581,6 +643,10 @@ public class KDC { if (body.kdcOptions.get(KDCOptions.ALLOW_POSTDATE)) { bFlags[Krb5.TKT_OPTS_MAY_POSTDATE] = true; } + + if (configMatch("", body.sname.getNameString(), "ok-as-delegate")) { + bFlags[Krb5.TKT_OPTS_DELEGATE] = true; + } bFlags[Krb5.TKT_OPTS_INITIAL] = true; TicketFlags tFlags = new TicketFlags(bFlags); @@ -671,8 +737,8 @@ public class KDC { eTypes = (int[])f.get(body); int eType = eTypes[0]; - EncryptionKey ckey = keyForUser(body.cname, eType); - EncryptionKey skey = keyForUser(body.sname, eType); + EncryptionKey ckey = keyForUser(body.cname, eType, false); + EncryptionKey skey = keyForUser(body.sname, eType, true); if (ckey == null) { throw new KrbException(Krb5.KDC_ERR_ETYPE_NOSUPP); } diff --git a/test/sun/security/krb5/auto/OkAsDelegate.java b/test/sun/security/krb5/auto/OkAsDelegate.java new file mode 100644 index 0000000000000000000000000000000000000000..fee677b536b8a39f603afe93fa5696a35176296f --- /dev/null +++ b/test/sun/security/krb5/auto/OkAsDelegate.java @@ -0,0 +1,104 @@ +/* + * Copyright 2009 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 com.sun.security.jgss.ExtendedGSSContext; +import org.ietf.jgss.GSSCredential; +import org.ietf.jgss.GSSException; +import org.ietf.jgss.Oid; +import sun.security.jgss.GSSUtil; +import sun.security.krb5.Config; + +public class OkAsDelegate { + + public static void main(String[] args) + throws Exception { + OkAsDelegate ok = new OkAsDelegate(); + ok.go( + Boolean.valueOf(args[0]), // FORWARDABLE in krb5.conf on? + Boolean.valueOf(args[1]), // requestDelegState + Boolean.valueOf(args[2]), // requestDelegPolicyState + Boolean.valueOf(args[3]), // DelegState in response + Boolean.valueOf(args[4]), // DelegPolicyState in response + Boolean.valueOf(args[5]) // getDelegCred OK? + ); + } + + void go( + boolean forwardable, + boolean requestDelegState, + boolean requestDelegPolicyState, + boolean delegState, + boolean delegPolicyState, + boolean delegated + ) throws Exception { + OneKDC kdc = new OneKDC(null); + kdc.setPolicy("ok-as-delegate", + System.getProperty("test.kdc.policy.ok-as-delegate")); + kdc.writeJAASConf(); + if (!forwardable) { + // The default OneKDC always includes "forwardable = true" + // in krb5.conf, override it. + KDC.saveConfig(OneKDC.KRB5_CONF, kdc, + "default_keytab_name = " + OneKDC.KTAB); + Config.refresh(); + } + + Context c, s; + c = Context.fromJAAS("client"); + s = Context.fromJAAS("server"); + + Oid mech = GSSUtil.GSS_KRB5_MECH_OID; + if (System.getProperty("test.spnego") != null) { + mech = GSSUtil.GSS_SPNEGO_MECH_OID; + } + c.startAsClient(OneKDC.SERVER, mech); + ExtendedGSSContext cx = (ExtendedGSSContext)c.x(); + cx.requestCredDeleg(requestDelegState); + cx.requestDelegPolicy(requestDelegPolicyState); + s.startAsServer(mech); + ExtendedGSSContext sx = (ExtendedGSSContext)s.x(); + + Context.handshake(c, s); + + if (cx.getCredDelegState() != delegState) { + throw new Exception("Initiator cred state error"); + } + if (sx.getCredDelegState() != delegState) { + throw new Exception("Acceptor cred state error"); + } + if (cx.getDelegPolicyState() != delegPolicyState) { + throw new Exception("Initiator cred policy state error"); + } + + GSSCredential cred = null; + try { + cred = s.x().getDelegCred(); + } catch (GSSException e) { + // leave cred as null + } + + if (delegated != (cred != null)) { + throw new Exception("get cred error"); + } + } +} diff --git a/test/sun/security/krb5/auto/OkAsDelegateXRealm.java b/test/sun/security/krb5/auto/OkAsDelegateXRealm.java new file mode 100644 index 0000000000000000000000000000000000000000..54c181fc8f61f93e785e4a7628ec338b5efb0761 --- /dev/null +++ b/test/sun/security/krb5/auto/OkAsDelegateXRealm.java @@ -0,0 +1,156 @@ +/* + * Copyright 2009 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 com.sun.security.jgss.ExtendedGSSContext; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.security.Security; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import org.ietf.jgss.GSSContext; +import org.ietf.jgss.GSSCredential; +import org.ietf.jgss.GSSException; +import org.ietf.jgss.GSSManager; +import org.ietf.jgss.GSSName; +import sun.security.jgss.GSSUtil; +import sun.security.krb5.Config; + +public class OkAsDelegateXRealm implements CallbackHandler { + + /** + * @param args boolean if the program should succeed + */ + public static void main(String[] args) + throws Exception { + + // Create and start the KDCs. Here we have 3 realms: R1, R2 and R3. + // R1 is trusted by R2, and R2 trusted by R3. + KDC kdc1 = KDC.create("R1"); + kdc1.setPolicy("ok-as-delegate", + System.getProperty("test.kdc.policy.ok-as-delegate")); + kdc1.addPrincipal("dummy", "bogus".toCharArray()); + kdc1.addPrincipalRandKey("krbtgt/R1"); + kdc1.addPrincipal("krbtgt/R2@R1", "r1->r2".toCharArray()); + + KDC kdc2 = KDC.create("R2"); + kdc2.setPolicy("ok-as-delegate", + System.getProperty("test.kdc.policy.ok-as-delegate")); + kdc2.addPrincipalRandKey("krbtgt/R2"); + kdc2.addPrincipal("krbtgt/R2@R1", "r1->r2".toCharArray()); + kdc2.addPrincipal("krbtgt/R3@R2", "r2->r3".toCharArray()); + + KDC kdc3 = KDC.create("R3"); + kdc3.setPolicy("ok-as-delegate", + System.getProperty("test.kdc.policy.ok-as-delegate")); + kdc3.addPrincipalRandKey("krbtgt/R3"); + kdc3.addPrincipal("krbtgt/R3@R2", "r2->r3".toCharArray()); + kdc3.addPrincipalRandKey("host/host.r3.local"); + + KDC.saveConfig("krb5-localkdc.conf", kdc1, kdc2, kdc3, + "forwardable=true", + "[capaths]", + "R1 = {", + " R2 = .", + " R3 = R2", + "}", + "[domain_realm]", + ".r3.local=R3" + ); + + System.setProperty("java.security.krb5.conf", "krb5-localkdc.conf"); + kdc3.writeKtab("localkdc.ktab"); + + FileOutputStream fos = new FileOutputStream("jaas-localkdc.conf"); + + // Defines the client and server on R1 and R3 respectively. + fos.write(("com.sun.security.jgss.krb5.initiate {\n" + + " com.sun.security.auth.module.Krb5LoginModule\n" + + " required\n" + + " principal=dummy\n" + + " doNotPrompt=false\n" + + " useTicketCache=false\n" + + " ;\n};\n" + + "com.sun.security.jgss.krb5.accept {\n" + + " com.sun.security.auth.module.Krb5LoginModule required\n" + + " principal=\"host/host.r3.local@R3\"\n" + + " useKeyTab=true\n" + + " keyTab=localkdc.ktab\n" + + " isInitiator=false\n" + + " storeKey=true;\n};\n" + + "\n").getBytes()); + fos.close(); + + Security.setProperty("auth.login.defaultCallbackHandler", + "OkAsDelegateXRealm"); + + System.setProperty("java.security.auth.login.config", "jaas-localkdc.conf"); + + new File("krb5-localkdc.conf").deleteOnExit(); + new File("localkdc.ktab").deleteOnExit(); + new File("jaas-localkdc.conf").deleteOnExit(); + Config.refresh(); + + Context c = Context.fromJAAS("com.sun.security.jgss.krb5.initiate"); + Context s = Context.fromJAAS("com.sun.security.jgss.krb5.accept"); + + // Test twice. The frist time the whole cross realm process is tried, + // the second time the cached service ticket is used. This is to make sure + // the behaviors are the same, especailly for the case when one of the + // cross-realm TGTs does not have OK-AS-DELEGATE on. + + for (int i=0; i<2; i++) { + c.startAsClient("host@host.r3.local", GSSUtil.GSS_KRB5_MECH_OID); + s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID); + c.x().requestDelegPolicy(true); + + Context.handshake(c, s); + boolean succeed = true; + try { + s.x().getDelegCred(); + } catch (GSSException gsse) { + succeed = false; + } + if (succeed != Boolean.parseBoolean(args[0])) { + throw new Exception("Test fail at round #" + i); + } + } + } + + @Override + public void handle(Callback[] callbacks) + throws IOException, UnsupportedCallbackException { + for (Callback callback : callbacks) { + if (callback instanceof NameCallback) { + ((NameCallback) callback).setName("dummy"); + } + if (callback instanceof PasswordCallback) { + ((PasswordCallback) callback).setPassword("bogus".toCharArray()); + } + } + } +} + diff --git a/test/sun/security/krb5/auto/ok-as-delegate-xrealm.sh b/test/sun/security/krb5/auto/ok-as-delegate-xrealm.sh new file mode 100644 index 0000000000000000000000000000000000000000..850dae3e443f7fcb197762c9105b794a08e01515 --- /dev/null +++ b/test/sun/security/krb5/auto/ok-as-delegate-xrealm.sh @@ -0,0 +1,79 @@ +# +# Copyright 2009 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 6853328 +# @summary Support OK-AS-DELEGATE flag +# @run shell/timeout=600 ok-as-delegate-xrealm.sh +# + +if [ "${TESTSRC}" = "" ] ; then + TESTSRC=`dirname $0` +fi + +if [ "${TESTJAVA}" = "" ] ; then + JAVAC_CMD=`which javac` + TESTJAVA=`dirname $JAVAC_CMD`/.. +fi + +# set platform-dependent variables +OS=`uname -s` +case "$OS" in + Windows_* ) + FS="\\" + SEP=";" + ;; + CYGWIN* ) + FS="/" + SEP=";" + ;; + * ) + FS="/" + SEP=":" + ;; +esac + +${TESTJAVA}${FS}bin${FS}javac -XDignore.symbol.file -d . \ + ${TESTSRC}${FS}OkAsDelegateXRealm.java \ + ${TESTSRC}${FS}KDC.java \ + ${TESTSRC}${FS}OneKDC.java \ + ${TESTSRC}${FS}Action.java \ + ${TESTSRC}${FS}Context.java \ + || exit 10 + +# Add $TESTSRC to classpath so that customized nameservice can be used +J="${TESTJAVA}${FS}bin${FS}java -cp $TESTSRC${SEP}." + +# KDC no OK-AS-DELEGATE, fail +$J OkAsDelegateXRealm false || exit 1 + +# KDC set OK-AS-DELEGATE for all, succeed +$J -Dtest.kdc.policy.ok-as-delegate OkAsDelegateXRealm true || exit 2 + +# KDC set OK-AS-DELEGATE for host/host.r3.local only, fail +$J -Dtest.kdc.policy.ok-as-delegate=host/host.r3.local OkAsDelegateXRealm false || exit 3 + +# KDC set OK-AS-DELEGATE for all, succeed +$J "-Dtest.kdc.policy.ok-as-delegate=host/host.r3.local krbtgt/R2 krbtgt/R3" OkAsDelegateXRealm true || exit 4 + +exit 0 diff --git a/test/sun/security/krb5/auto/ok-as-delegate.sh b/test/sun/security/krb5/auto/ok-as-delegate.sh new file mode 100644 index 0000000000000000000000000000000000000000..1647e1561f54b61def80b9461654e59c6ba2f783 --- /dev/null +++ b/test/sun/security/krb5/auto/ok-as-delegate.sh @@ -0,0 +1,118 @@ +# +# Copyright 2009 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 6853328 +# @summary Support OK-AS-DELEGATE flag +# @run shell/timeout=600 ok-as-delegate.sh +# + +if [ "${TESTSRC}" = "" ] ; then + TESTSRC=`dirname $0` +fi + +if [ "${TESTJAVA}" = "" ] ; then + JAVAC_CMD=`which javac` + TESTJAVA=`dirname $JAVAC_CMD`/.. +fi + +# set platform-dependent variables +OS=`uname -s` +case "$OS" in + Windows_* ) + FS="\\" + SEP=";" + ;; + CYGWIN* ) + FS="/" + SEP=";" + ;; + * ) + FS="/" + SEP=":" + ;; +esac + +${TESTJAVA}${FS}bin${FS}javac -XDignore.symbol.file -d . \ + ${TESTSRC}${FS}OkAsDelegate.java \ + ${TESTSRC}${FS}KDC.java \ + ${TESTSRC}${FS}OneKDC.java \ + ${TESTSRC}${FS}Action.java \ + ${TESTSRC}${FS}Context.java \ + || exit 10 + +# Testing Kerberos 5 + +# Add $TESTSRC to classpath so that customized nameservice can be used +J="${TESTJAVA}${FS}bin${FS}java -cp $TESTSRC${SEP}. OkAsDelegate" +JOK="${TESTJAVA}${FS}bin${FS}java -cp $TESTSRC${SEP}. -Dtest.kdc.policy.ok-as-delegate OkAsDelegate" + +# FORWARDABLE ticket not allowed, always fail +$J false true true false false false || exit 1 + +# Service ticket no OK-AS-DELEGATE + +# Request nothing, gain nothing +$J true false false false false false || exit 2 +# Request deleg policy, gain nothing +$J true false true false false false || exit 3 +# Request deleg, granted +$J true true false true false true || exit 4 +# Request deleg and deleg policy, granted, with info not by policy +$J true true true true false true || exit 5 + +# Service ticket has OK-AS-DELEGATE + +# Request deleg policy, granted +$JOK true false true true true true || exit 6 +# Request deleg and deleg policy, granted, with info by policy +$JOK true true true true true true || exit 7 + +# Testing SPNEGO + +# Add $TESTSRC to classpath so that customized nameservice can be used +J="${TESTJAVA}${FS}bin${FS}java -cp $TESTSRC${SEP}. -Dtest.spnego OkAsDelegate" +JOK="${TESTJAVA}${FS}bin${FS}java -cp $TESTSRC${SEP}. -Dtest.spnego -Dtest.kdc.policy.ok-as-delegate OkAsDelegate" + +# FORWARDABLE ticket not allowed, always fail +$J false true true false false false || exit 11 + +# Service ticket no OK-AS-DELEGATE + +# Request nothing, gain nothing +$J true false false false false false || exit 12 +# Request deleg policy, gain nothing +$J true false true false false false || exit 13 +# Request deleg, granted +$J true true false true false true || exit 14 +# Request deleg and deleg policy, granted, with info not by policy +$J true true true true false true || exit 15 + +# Service ticket has OK-AS-DELEGATE + +# Request deleg policy, granted +$JOK true false true true true true || exit 16 +# Request deleg and deleg policy, granted, with info by policy +$JOK true true true true true true || exit 17 + +exit 0 diff --git a/test/sun/tools/jhat/HatRun.java b/test/sun/tools/jhat/HatRun.java index cac66e57d8c2c67b023410ff8c4d7cf05dc7cce0..cb1e41b248ec5903ce921060f6e3217f6be0b85d 100644 --- a/test/sun/tools/jhat/HatRun.java +++ b/test/sun/tools/jhat/HatRun.java @@ -186,11 +186,13 @@ public class HatRun { */ int nvm_options = 0; if ( vm_options != null ) nvm_options = vm_options.length; - String cmd[] = new String[1 + (d64?1:0) + 5 + nvm_options]; + String cmd[] = new String[1 + (d64?1:0) + 7 + nvm_options]; int i,j; i = 0; cmd[i++] = java; + cmd[i++] = "-cp"; + cmd[i++] = cdir; cmd[i++] = "-Dtest.classes=" + cdir; if ( d64 ) { cmd[i++] = "-d64"; diff --git a/test/sun/tools/native2ascii/NativeErrors.java b/test/sun/tools/native2ascii/NativeErrors.java index 460a9f158cf12f6448e15c3da40f3c8842a5fe1d..c0fbad160e07e5ab196724831508fd74d1b7950d 100644 --- a/test/sun/tools/native2ascii/NativeErrors.java +++ b/test/sun/tools/native2ascii/NativeErrors.java @@ -59,15 +59,28 @@ public class NativeErrors { in = new BufferedReader(new InputStreamReader(p.getInputStream())); checkResult(in, "err.bad.arg"); - command = getComString("test123"); + File f0 = new File(System.getProperty("test.src", "."), "test123"); + String path0 = f0.getPath(); + if ( f0.exists() ) { + throw new Error("Input file should not exist: " + path0); + } + + command = getComString(path0); p = Runtime.getRuntime().exec(command); in = new BufferedReader(new InputStreamReader(p.getInputStream())); checkResult(in, "err.cannot.read"); File f1 = new File(System.getProperty("test.src", "."), "test1"); - File f2 = new File(System.getProperty("test.src", "."), "test2"); + File f2 = File.createTempFile("test2", ".tmp"); String path1 = f1.getPath(); String path2 = f2.getPath(); + if ( !f1.exists() ) { + throw new Error("Missing input file: " + path1); + } + if ( !f2.setWritable(false) ) { + throw new Error("Output file cannot be made read only: " + path2); + } + f2.deleteOnExit(); command = getComString(path1, path2); p = Runtime.getRuntime().exec(command); @@ -80,7 +93,9 @@ public class NativeErrors { throws Exception { String errorReceived; errorReceived = in.readLine(); + assert errorReceived != null : "First readline cannot be null"; errorExpected = rsrc.getString(errorExpected); + assert errorExpected != null : "Expected message cannot be null"; StringBuffer error = new StringBuffer(errorExpected); int start = errorExpected.indexOf("{0}"); if (start >= 0) { @@ -128,6 +143,7 @@ public class NativeErrors { f = new File(path); if (!f.exists()) throw new RuntimeException("Cannot find native2ascii at "+path); + System.out.println("Using native2ascii at "+path); } return path; } diff --git a/test/sun/tools/native2ascii/test2 b/test/sun/tools/native2ascii/test2 deleted file mode 100644 index 9a669e9ced5f3476d59c5e1b331c77155bc162e0..0000000000000000000000000000000000000000 --- a/test/sun/tools/native2ascii/test2 +++ /dev/null @@ -1 +0,0 @@ -This file exists as a non-writable placeholder for NativeErrors.java diff --git a/test/tools/launcher/Arrrghs.java b/test/tools/launcher/Arrrghs.java index 4853b90516624ea19d4ef20ecde3b558fbc3f86f..b7ba2737dfa2aba2126e3a19b2c8245d1f7888e1 100644 --- a/test/tools/launcher/Arrrghs.java +++ b/test/tools/launcher/Arrrghs.java @@ -25,7 +25,7 @@ * @test * @bug 5030233 6214916 6356475 6571029 6684582 6742159 4459600 6758881 * @summary Argument parsing validation. - * @compile Arrrghs.java TestHelper.java + * @compile -XDignore.symbol.file Arrrghs.java TestHelper.java * @run main Arrrghs */ diff --git a/test/tools/launcher/ExecutionEnvironment.java b/test/tools/launcher/ExecutionEnvironment.java new file mode 100644 index 0000000000000000000000000000000000000000..217de4670e0ea6765de946522fc98b66ce6dc605 --- /dev/null +++ b/test/tools/launcher/ExecutionEnvironment.java @@ -0,0 +1,358 @@ +/* + * Copyright 2009 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 4780570 4731671 6354700 6367077 6670965 4882974 + * @summary Checks for LD_LIBRARY_PATH and execution on *nixes + * @compile -XDignore.symbol.file ExecutionEnvironment.java TestHelper.java + * @run main ExecutionEnvironment + */ + +/* + * This test tests for various things as follows: + * Ensures that: + * 1. uneccessary execs do not occur + * 2. the environment is pristine, users environment variable wrt. + * LD_LIBRARY_PATH if set are not modified in any way. + * 3. the correct vm is chosen with -server and -client options + * 4. the VM on Solaris correctly interprets the LD_LIBRARY_PATH32 + * and LD_LIBRARY_PATH64 variables if set by the user, ie. + * i. on 32 bit systems: + * a. if LD_LIBRARY_PATH32 is set it will override LD_LIBRARY_PATH + * b. LD_LIBRARY_PATH64 is ignored if set + * ii. on 64 bit systems: + * a. if LD_LIBRARY_PATH64 is set it will override LD_LIBRARY_PATH + * b. LD_LIBRARY_PATH32 is ignored if set + * 5. no extra symlink exists on Solaris ie. + * jre/lib/$arch/libjvm.so -> client/libjvm.so + * TODO: + * a. perhaps we need to add a test to audit all environment variables are + * in pristine condition after the launch, there may be a few that the + * launcher may add as implementation details. + * b. add a pldd for solaris to ensure only one libjvm.so is linked + */ +import java.io.File; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +public class ExecutionEnvironment { + static final String LD_LIBRARY_PATH = "LD_LIBRARY_PATH"; + static final String LD_LIBRARY_PATH_32 = LD_LIBRARY_PATH + "_32"; + static final String LD_LIBRARY_PATH_64 = LD_LIBRARY_PATH + "_64"; + + // Note: these paths need not exist on the filesytem + static final String LD_LIBRARY_PATH_VALUE = "/Bridge/On/The/River/Kwai"; + static final String LD_LIBRARY_PATH_32_VALUE = "/Lawrence/Of/Arabia"; + static final String LD_LIBRARY_PATH_64_VALUE = "/A/Passage/To/India"; + + static final String JLDEBUG_KEY = "_JAVA_LAUNCHER_DEBUG"; + static final String EXPECTED_MARKER = "TRACER_MARKER:About to EXEC"; + + static final String[] LD_PATH_STRINGS = { + LD_LIBRARY_PATH + "=" + LD_LIBRARY_PATH_VALUE, + LD_LIBRARY_PATH_32 + "=" + LD_LIBRARY_PATH_32_VALUE, + LD_LIBRARY_PATH_64 + "=" + LD_LIBRARY_PATH_64_VALUE + }; + + static final File testJarFile = new File("EcoFriendly.jar"); + + static int errors = 0; + static int passes = 0; + + private static void createTestJar() { + try { + List codeList = new ArrayList(); + codeList.add("static void printValue(String name, boolean property) {\n"); + codeList.add(" String value = (property) ? System.getProperty(name) : System.getenv(name);\n"); + codeList.add(" System.out.println(name + \"=\" + value);\n"); + codeList.add("}\n"); + codeList.add("public static void main(String... args) {\n"); + codeList.add(" System.out.println(\"Execute test:\");\n"); + codeList.add(" printValue(\"os.name\", true);\n"); + codeList.add(" printValue(\"os.arch\", true);\n"); + codeList.add(" printValue(\"os.version\", true);\n"); + codeList.add(" printValue(\"sun.arch.data.model\", true);\n"); + codeList.add(" printValue(\"java.library.path\", true);\n"); + codeList.add(" printValue(\"" + LD_LIBRARY_PATH + "\", false);\n"); + codeList.add(" printValue(\"" + LD_LIBRARY_PATH_32 + "\", false);\n"); + codeList.add(" printValue(\"" + LD_LIBRARY_PATH_64 + "\", false);\n"); + codeList.add("}\n"); + String[] clist = new String[codeList.size()]; + TestHelper.createJar(testJarFile, codeList.toArray(clist)); + } catch (FileNotFoundException fnfe) { + throw new RuntimeException(fnfe); + } + } + + /* + * tests if the launcher pollutes the LD_LIBRARY_PATH variables ie. there + * should not be any new variables or pollution/mutations of any kind, the + * environment should be pristine. + */ + private static void ensureEcoFriendly() { + TestHelper.TestResult tr = null; + + Map env = new HashMap(); + for (String x : LD_PATH_STRINGS) { + String pairs[] = x.split("="); + env.put(pairs[0], pairs[1]); + } + + tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar", + testJarFile.getAbsolutePath()); + + if (!tr.isNotZeroOutput()) { + throw new RuntimeException("Error: No output at all. Did the test execute ?"); + } + + for (String x : LD_PATH_STRINGS) { + if (!tr.contains(x)) { + System.out.println("FAIL: did not get <" + x + ">"); + System.out.println(tr); + errors++; + } else { + passes++; + } + } + } + + /* + * ensures that there are no execs as long as we are in the same + * data model + */ + static void ensureNoExec() { + Map env = new HashMap(); + env.put(JLDEBUG_KEY, "true"); + TestHelper.TestResult tr = + TestHelper.doExec(env, TestHelper.javaCmd, "-version"); + if (tr.testOutput.contains(EXPECTED_MARKER)) { + System.out.println("FAIL: EnsureNoExecs: found expected warning <" + + EXPECTED_MARKER + + "> the process execing ?"); + errors++; + } else { + passes++; + } + return; + } + + /* + * This test ensures that LD_LIBRARY_PATH* values are interpreted by the VM + * and the expected java.library.path behaviour. + * For Generic platforms (All *nixes): + * * All LD_LIBRARY_PATH variable should be on java.library.path + * For Solaris 32-bit + * * The LD_LIBRARY_PATH_32 should override LD_LIBRARY_PATH if specified + * For Solaris 64-bit + * * The LD_LIBRARY_PATH_64 should override LD_LIBRARY_PATH if specified + */ + + static void verifyJavaLibraryPath() { + TestHelper.TestResult tr = null; + + Map env = new HashMap(); + + + if (TestHelper.isLinux) { + for (String x : LD_PATH_STRINGS) { + String pairs[] = x.split("="); + env.put(pairs[0], pairs[1]); + } + + tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar", + testJarFile.getAbsolutePath()); + verifyJavaLibraryPathGeneric(tr); + } else { + // no override + env.clear(); + env.put(LD_LIBRARY_PATH, LD_LIBRARY_PATH_VALUE); + tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar", + testJarFile.getAbsolutePath()); + verifyJavaLibraryPathGeneric(tr); + + env.clear(); + for (String x : LD_PATH_STRINGS) { + String pairs[] = x.split("="); + env.put(pairs[0], pairs[1]); + } + + // verify the override occurs, since we know the invocation always + // uses by default is 32-bit, therefore we also set the test + // expectation to be the same. + tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar", + testJarFile.getAbsolutePath()); + verifyJavaLibraryPathOverride(tr, true); + + // try changing the model from 32 to 64 bit + if (TestHelper.java64Cmd != null && TestHelper.is32Bit) { + // verify the override occurs + env.clear(); + for (String x : LD_PATH_STRINGS) { + String pairs[] = x.split("="); + env.put(pairs[0], pairs[1]); + } + tr = TestHelper.doExec(env, TestHelper.javaCmd, "-d64", "-jar", + testJarFile.getAbsolutePath()); + verifyJavaLibraryPathOverride(tr, false); + + // no override + env.clear(); + env.put(LD_LIBRARY_PATH, LD_LIBRARY_PATH_VALUE); + tr = TestHelper.doExec(env, TestHelper.javaCmd, "-jar", + testJarFile.getAbsolutePath()); + verifyJavaLibraryPathGeneric(tr); + } + + // try changing the model from 64 to 32 bit + if (TestHelper.java64Cmd != null && TestHelper.is64Bit) { + // verify the override occurs + env.clear(); + for (String x : LD_PATH_STRINGS) { + String pairs[] = x.split("="); + env.put(pairs[0], pairs[1]); + } + tr = TestHelper.doExec(env, TestHelper.java64Cmd, "-d32", "-jar", + testJarFile.getAbsolutePath()); + verifyJavaLibraryPathOverride(tr, true); + + // no override + env.clear(); + env.put(LD_LIBRARY_PATH, LD_LIBRARY_PATH_VALUE); + tr = TestHelper.doExec(env, TestHelper.java64Cmd, "-d32", "-jar", + testJarFile.getAbsolutePath()); + verifyJavaLibraryPathGeneric(tr); + } + } + } + + private static void verifyJavaLibraryPathGeneric(TestHelper.TestResult tr) { + if (!tr.matches("java.library.path=.*" + LD_LIBRARY_PATH_VALUE + ".*")) { + System.out.print("FAIL: verifyJavaLibraryPath: "); + System.out.println(" java.library.path does not contain " + + LD_LIBRARY_PATH_VALUE); + System.out.println(tr); + errors++; + } else { + passes++; + } + } + + private static void verifyJavaLibraryPathOverride(TestHelper.TestResult tr, + boolean is32Bit) { + // make sure the 32/64 bit value exists + if (!tr.matches("java.library.path=.*" + + (is32Bit ? LD_LIBRARY_PATH_32_VALUE : LD_LIBRARY_PATH_64_VALUE) + ".*")) { + System.out.print("FAIL: verifyJavaLibraryPathOverride: "); + System.out.println(" java.library.path does not contain " + + (is32Bit ? LD_LIBRARY_PATH_32_VALUE : LD_LIBRARY_PATH_64_VALUE)); + System.out.println(tr); + errors++; + } else { + passes++; + } + // make sure the generic value is absent + if (tr.matches("java.library.path=.*" + LD_LIBRARY_PATH_VALUE + ".*")) { + System.out.print("FAIL: verifyJavaLibraryPathOverride: "); + System.out.println(" java.library.path contains " + + LD_LIBRARY_PATH_VALUE); + System.out.println(tr); + errors++; + } else { + passes++; + } + } + + /* + * ensures we have indeed exec'ed the correct vm of choice, all VMs support + * -server, however 32-bit VMs support -client and -server. + */ + static void verifyVmSelection() { + + TestHelper.TestResult tr = null; + + if (TestHelper.is32Bit) { + tr = TestHelper.doExec(TestHelper.javaCmd, "-client", "-version"); + if (!tr.matches("Java.*Client VM.*")) { + System.out.println("FAIL: the expected vm -client did launch"); + System.out.println(tr); + errors++; + } else { + passes++; + } + } + tr = TestHelper.doExec(TestHelper.javaCmd, "-server", "-version"); + if (!tr.matches("Java.*Server VM.*")) { + System.out.println("FAIL: the expected vm -server did launch"); + System.out.println(tr); + errors++; + } else { + passes++; + } + } + + /* + * checks to see there is no extra libjvm.so than needed + */ + static void verifyNoSymLink() { + if (TestHelper.is64Bit) { + return; + } + + File symLink = null; + String libPathPrefix = TestHelper.isSDK ? "jre/lib" : "/lib"; + symLink = new File(TestHelper.JAVAHOME, libPathPrefix + + TestHelper.getJreArch() + "/libjvm.so"); + if (symLink.exists()) { + System.out.println("FAIL: The symlink exists " + + symLink.getAbsolutePath()); + errors++; + } else { + passes++; + } + } + + public static void main(String... args) throws Exception { + if (TestHelper.isWindows) { + System.out.println("Warning: noop on windows"); + return; + } + // create our test jar first + createTestJar(); + ensureNoExec(); + verifyVmSelection(); + ensureEcoFriendly(); + verifyJavaLibraryPath(); + verifyNoSymLink(); + if (errors > 0) { + throw new Exception("ExecutionEnvironment: FAIL: with " + + errors + " errors and passes " + passes ); + } else { + System.out.println("ExecutionEnvironment: PASS " + passes); + } + } +} diff --git a/test/tools/launcher/SolarisDataModel.sh b/test/tools/launcher/SolarisDataModel.sh deleted file mode 100644 index 36398d7fe3913f7fe5f650591aa5f8aeee1a262c..0000000000000000000000000000000000000000 --- a/test/tools/launcher/SolarisDataModel.sh +++ /dev/null @@ -1,219 +0,0 @@ -# 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 4780570 -# @run shell SolarisDataModel.sh -# @summary Verify Solaris SPARC -d32 and -d64 options work with preset LD_LIBRARY_PATH -# @author Joseph D. Darcy - -# Test to see if presetting LD_LIBRARY_PATH affects the treatment of -# -d32 and -d64 options; also checks that -d options result in the -# desired data model. - -# If the test is not being run on a Solaris SPARC box SPARC the test -# succeeds immediately. - -OS=`uname -s`; - -case "$OS" in - SunOS ) - # ARCH should be sparc or i386 - ARCH=`uname -p` - case "$ARCH" in - sparc) - PATHSEP=":" - ;; - - * ) - echo "Non-SPARC Solaris environment; test vacuously succeeds." - exit 0 - esac - ;; - - * ) - echo "Not a Solaris SPARC environment; test vacuously succeeds." - exit 0; - ;; -esac - - -# Verify directory context variables are set -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 -fi - -if [ "${TESTSRC}" = "" ] -then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 -fi - - -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi - - -JAVAC="$TESTJAVA/bin/javac" - -# Create our little Java tests on the fly -( printf "public class GetDataModel {" - printf " public static void main(String argv[]) {" - printf " System.out.println(System.getProperty(\"sun.arch.data.model\", \"none\"));" - printf " }" - printf "}" -) > GetDataModel.java - -$JAVAC GetDataModel.java - -( printf "public class GetLdLibraryPath {" - printf " public static void main(String argv[]) {" - printf " System.out.println(System.getProperty(\"java.library.path\"));" - printf " }" - printf "}" -) > GetLdLibraryPath.java - -$JAVAC GetLdLibraryPath.java - - - -# All preconditions are met; run the tests - - -# Construct path to 32-bit Java executable -JAVA="$TESTJAVA/bin/java -classpath $TESTCLASSES${PATHSEP}." - - -# Construct path to 64-bit Java executable, might not exist -JAVA64="$TESTJAVA/bin/sparcv9/java -classpath $TESTCLASSES${PATHSEP}." -JAVA64FILE="$TESTJAVA/bin/sparcv9/java" - - -# java -d32 tests - -LD_LIBRARY_PATH="" -export LD_LIBRARY_PATH - -DM=`$JAVA -d32 GetDataModel` -case "$DM" in - 32 ) - ;; - - * ) - echo "The combination \"java -d32\" failed." - echo $DM - exit 1 -esac - -# Rerun test with LD_LIBRARY_PATH preset -LD_LIBRARY_PATH=`$JAVA GetLdLibraryPath`; -DM=`$JAVA -d32 GetDataModel` -case "$DM" in - 32 ) - ;; - - * ) - echo "The combination \"java -d32\" failed with preset LD_LIBRARY_PATH." - echo $DM - exit 1 -esac - -# Reset LD_LIBRARY_PATH -LD_LIBRARY_PATH= - - -# Test for 64-bit executable - -if [ -f $JAVA64FILE ]; then - - DM=`$JAVA -d64 GetDataModel` - case "$DM" in - 64 ) - ;; - - * ) - echo "The combination \"java -d64\" failed." - exit 1 - esac - - DM=`$JAVA64 -d32 GetDataModel` - case "$DM" in - 32 ) - ;; - - * ) - echo "The combination \"sparcv9/java -d32\" failed." - exit 1 - esac - - DM=`$JAVA64 -d64 GetDataModel` - case "$DM" in - 64 ) - ;; - - * ) - echo "The combination \"sparcv9/java -d64\" failed." - exit 1 - esac - - # Rerun tests with LD_LIBRARY_PATH preset - LD_LIBRARY_PATH=`$JAVA GetLdLibraryPath`; - echo "Presetting LD_LIBRARY_PATH" - - DM=`$JAVA -d64 GetDataModel` - case "$DM" in - 64 ) - ;; - - * ) - echo "The combination \"java -d64\" failed with preset LD_LIBRARY_PATH." - exit 1 - esac - - DM=`$JAVA64 -d32 GetDataModel` - case "$DM" in - 32 ) - ;; - - * ) - echo "The combination \"sparcv9/java -d32\" failed with preset LD_LIBRARY_PATH." - exit 1 - esac - - DM=`$JAVA64 -d64 GetDataModel` - case "$DM" in - 64 ) - ;; - - * ) - echo "The combination \"sparcv9/java -d64\" failed with preset LD_LIBRARY_PATH." - exit 1 - esac - -else - echo "Warning: no 64-bit components found; only java -d32 tests have been run." -fi -exit 0; diff --git a/test/tools/launcher/SolarisRunpath.sh b/test/tools/launcher/SolarisRunpath.sh deleted file mode 100644 index 26dd964f6548709bc267b13977865ceebfd722f4..0000000000000000000000000000000000000000 --- a/test/tools/launcher/SolarisRunpath.sh +++ /dev/null @@ -1,221 +0,0 @@ -# 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 4731671 -# @build libraryCaller -# @run shell SolarisRunpath.sh -# @summary Verify that Solaris LD_LIBRARY_PATH rules are followed -# @author Joseph D. Darcy - -# The launcher has been updated to properly take account of Solaris -# LD_LIBRARY_PATH rules when constructing the runpath for the Java -# executable. That is, data model dependent LD_LIBRARY_PATH variables -# are tested for and override LD_LIBRARY_PATH if present. The current -# launcher design relies on LD_LIBRARY_PATH settings to ensure the -# proper jre/jdk libraries are opening during program execution. In -# the future, this dependence might be removed by having the vm -# explicitly dlopen the needed files. If that change occurs, this -# test will be harmless but no long relevant. - -# A more robust test for Solaris SPARC would set the different -# LD_LIBRARY_PATH variables while also varying the -d[32|64] options -# to make sure the LD_LIBRARY_PATH of the *target* data model were -# being respected. That is "java -d64" should use the 64-bit -# LD_LIBRARY_PATH while "java -d32" should use the 32-bit -# LD_LIBRARY_PATH regardless of the data model of the "java" binary. -# However, by default builds do not contain both 32 and 64 bit -# components so such a test would often not be applicable. - - -# If the test is not being run on a Solaris box, SPARC or x86, the -# test succeeds immediately. - -OS=`uname -s`; - -case "$OS" in - SunOS ) - PATHSEP=":" - ;; - - * ) - echo "Not a Solaris environment; test vacuously succeeds." - exit 0; - ;; -esac - -# Verify directory context variables are set -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 -fi - -if [ "${TESTSRC}" = "" ] -then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 -fi - - -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi - -# Construct paths to default Java executables -JAVAC="$TESTJAVA/bin/javac" - - -# Create our little Java test on the fly -( printf "public class GetDataModel {" - printf " public static void main(String argv[]) {" - printf " System.out.println(System.getProperty(\"sun.arch.data.model\", \"none\"));" - printf " }" - printf "}" -) > GetDataModel.java - -$JAVAC GetDataModel.java - - -# ARCH should be sparc or i386 -ARCH=`uname -p` -case "$ARCH" in - sparc | i386 ) - ;; - - * ) - echo "Unrecognized architecture; test fails." - exit 1 -esac - -# The following construction may not work as desired in a -# 64-bit build. -JAVA="$TESTJAVA/bin/java -classpath $TESTCLASSES${PATHSEP}." - -# Determine data model -DM=`$JAVA GetDataModel` - -# verify DM is 32 or 64 -case "$DM" in - 32 ) - ODM=64; - ;; - - 64 ) - ODM=32; - ;; - - * ) - echo "Unknown data model \"$DM\"; test fails." - exit 1 -esac - -# -------------------- Test 1 -------------------- - -LD_LIBRARY_PATH=$TESTSRC/lib/$ARCH/lib$DM -export LD_LIBRARY_PATH -unset LD_LIBRARY_PATH_32 -unset LD_LIBRARY_PATH_64 - -# With plain LD_LIBRARY_PATH, result should always be 0 -RESULT=`$JAVA libraryCaller` -if [ "${RESULT}" != "0" ]; -then - echo "Not using LD_LIBRARY_PATH; test fails." - exit 1 -fi - -# The following two tests sets both data model dependent -# LD_LIBRARY_PATH variables individually. - -# -------------------- Test 2 -------------------- - -# Set opposite data model variable; should return same result -# as plain LD_LIBRARY_PATH. - -if [ "${DM}" = "32" ]; then - LD_LIBRARY_PATH_64=$TESTSRC/lib/$ARCH/lib$DM/lib$DM - export LD_LIBRARY_PATH_64 -else - LD_LIBRARY_PATH_32=$TESTSRC/lib/$ARCH/lib$DM/lib$DM - export LD_LIBRARY_PATH_32 -fi - -RESULT=`$JAVA libraryCaller` -if [ "${RESULT}" != "0" ]; -then - echo "Using LD_LIBRARY_PATH_$ODM for $DM binary;" - echo "test fails." - exit 1 -fi - -unset LD_LIBRARY_PATH_32 -unset LD_LIBRARY_PATH_64 - -# -------------------- Test 3 -------------------- - -# Set appropriate data model variable; result should match -# data model. -if [ "${DM}" = "32" ]; then - LD_LIBRARY_PATH_32=$TESTSRC/lib/$ARCH/lib$DM/lib$DM - export LD_LIBRARY_PATH_32 -else - LD_LIBRARY_PATH_64=$TESTSRC/lib/$ARCH/lib$DM/lib$DM - export LD_LIBRARY_PATH_64 -fi - -RESULT=`$JAVA libraryCaller` -if [ "${RESULT}" != "$DM" ]; -then - echo "Data model dependent LD_LIBRARY_PATH_$DM" - echo "not overriding LD_LIBRARY_PATH; test fails." - exit 1 -fi - -unset LD_LIBRARY_PATH -unset LD_LIBRARY_PATH_32 -unset LD_LIBRARY_PATH_64 - -# -------------------- Test 4 -------------------- - -# Have only data model dependent LD_LIBRARY_PATH set; result -# should match data model. - -if [ "${DM}" = "32" ]; then - LD_LIBRARY_PATH_32=$TESTSRC/lib/$ARCH/lib$DM/lib$DM - export LD_LIBRARY_PATH_32 -else - LD_LIBRARY_PATH_64=$TESTSRC/lib/$ARCH/lib$DM/lib$DM - export LD_LIBRARY_PATH_64 -fi - -RESULT=`$JAVA libraryCaller` -if [ "${RESULT}" != "$DM" ]; -then - echo "Not using data-model dependent LD_LIBRARY_PATH; test fails." - exit 1 -fi - -# All tests have passed -exit 0 diff --git a/test/tools/launcher/TestHelper.java b/test/tools/launcher/TestHelper.java index fb63114b6d582864263766e257506e0b139fcdf3..da7b084dfd7c48e02d9e635ed125e63a391dd6a3 100644 --- a/test/tools/launcher/TestHelper.java +++ b/test/tools/launcher/TestHelper.java @@ -39,18 +39,36 @@ import javax.tools.JavaCompiler; */ public enum TestHelper { INSTANCE; - static final String JAVAHOME = System.getProperty("java.home", "."); + static final String JAVAHOME = System.getProperty("java.home"); static final boolean isSDK = JAVAHOME.endsWith("jre"); static final String javaCmd; + static final String java64Cmd; static final String javacCmd; static final JavaCompiler compiler; - static final boolean debug = Boolean.getBoolean("Arrrghs.Debug"); + static final boolean debug = Boolean.getBoolean("TestHelper.Debug"); static final boolean isWindows = System.getProperty("os.name", "unknown").startsWith("Windows"); + static final boolean is64Bit = + System.getProperty("sun.arch.data.model").equals("64"); + static final boolean is32Bit = + System.getProperty("sun.arch.data.model").equals("32"); + static final boolean isSolaris = + System.getProperty("os.name", "unknown").startsWith("SunOS"); + static final boolean isLinux = + System.getProperty("os.name", "unknown").startsWith("Linux"); + static final boolean isDualMode = isSolaris; + static final boolean isSparc = System.getProperty("os.arch").startsWith("sparc"); + static int testExitValue = 0; static { + if (is64Bit && is32Bit) { + throw new RuntimeException("arch model cannot be both 32 and 64 bit"); + } + if (!is64Bit && !is32Bit) { + throw new RuntimeException("arch model is not 32 or 64 bit ?"); + } compiler = ToolProvider.getSystemJavaCompiler(); File binDir = (isSDK) ? new File((new File(JAVAHOME)).getParentFile(), "bin") : new File(JAVAHOME, "bin"); @@ -69,6 +87,33 @@ public enum TestHelper { if (!javacCmdFile.canExecute()) { throw new RuntimeException("java <" + javacCmd + "> must exist"); } + if (isSolaris) { + File sparc64BinDir = new File(binDir,isSparc ? "sparcv9" : "amd64"); + File java64CmdFile= new File(sparc64BinDir, "java"); + if (java64CmdFile.exists() && java64CmdFile.canExecute()) { + java64Cmd = java64CmdFile.getAbsolutePath(); + } else { + java64Cmd = null; + } + } else { + java64Cmd = null; + } + } + + /* + * usually the jre/lib/arch-name is the same as os.arch, except for x86. + */ + static String getJreArch() { + String arch = System.getProperty("os.arch"); + return arch.equals("x86") ? "i386" : arch; + } + + /* + * A convenience method to create a jar with jar file name and defs + */ + static void createJar(File jarName, String... mainDefs) + throws FileNotFoundException{ + createJar(null, jarName, new File("Foo"), mainDefs); } /* @@ -123,16 +168,23 @@ public enum TestHelper { } } + static TestResult doExec(String...cmds) { + return doExec(null, cmds); + } + /* * A method which executes a java cmd and returns the results in a container */ - static TestResult doExec(String...cmds) { + static TestResult doExec(Map envToSet, String...cmds) { String cmdStr = ""; for (String x : cmds) { cmdStr = cmdStr.concat(x + " "); } ProcessBuilder pb = new ProcessBuilder(cmds); Map env = pb.environment(); + if (envToSet != null) { + env.putAll(envToSet); + } BufferedReader rdr = null; try { List outputList = new ArrayList(); @@ -163,21 +215,25 @@ public enum TestHelper { List testOutput; public TestResult(String str, int rv, List oList) { - status = new StringBuilder(str); + status = new StringBuilder("Executed command: " + str + "\n"); exitValue = rv; testOutput = oList; } + void appendStatus(String x) { + status = status.append(" " + x + "\n"); + } + void checkNegative() { if (exitValue == 0) { - status = status.append(" Error: test must not return 0 exit value"); + appendStatus("Error: test must not return 0 exit value"); testExitValue++; } } void checkPositive() { if (exitValue != 0) { - status = status.append(" Error: test did not return 0 exit value"); + appendStatus("Error: test did not return 0 exit value"); testExitValue++; } } @@ -188,7 +244,7 @@ public enum TestHelper { boolean isZeroOutput() { if (!testOutput.isEmpty()) { - status = status.append(" Error: No message from cmd please"); + appendStatus("Error: No message from cmd please"); testExitValue++; return false; } @@ -197,19 +253,20 @@ public enum TestHelper { boolean isNotZeroOutput() { if (testOutput.isEmpty()) { - status = status.append(" Error: Missing message"); + appendStatus("Error: Missing message"); testExitValue++; return false; } return true; } + @Override public String toString() { - if (debug) { - for (String x : testOutput) { - status = status.append(x + "\n"); - } + status = status.append("++++Test Output Begin++++\n"); + for (String x : testOutput) { + appendStatus(x); } + status = status.append("++++Test Output End++++\n"); return status.toString(); } @@ -219,7 +276,18 @@ public enum TestHelper { return true; } } - status = status.append(" Error: string <" + str + "> not found "); + appendStatus("Error: string <" + str + "> not found"); + testExitValue++; + return false; + } + + boolean matches(String stringToMatch) { + for (String x : testOutput) { + if (x.matches(stringToMatch)) { + return true; + } + } + appendStatus("Error: string <" + stringToMatch + "> not found"); testExitValue++; return false; }